tests: fix 141_riscv_asm AMO crash, restore full test coverage

Replace raw-register AMO asm with proper inline-asm constraints
for all three operands (rd, rs2, rs1).  Use long long for .d-word
AMO variants with pre-set values (xd=0xCAFEBABECAFEBABE,
val=0xDEADBEEFDEADBEEF) to avoid uninitialized-data issues.

Restore csr_pseudo_main printf output and re-enable amo_main()
in the test (was commented out as 'crash on qemu').

Use GEN = $(GEN-TCC) since GCC and TCC produce different fcsr
initial values on riscv64.
This commit is contained in:
Meng Zhuo 2026-05-07 11:39:02 +08:00
parent 44977b0de8
commit a672babc6f
3 changed files with 26 additions and 25 deletions

View File

@ -240,29 +240,29 @@ int csr_pseudo_main(void)
asm volatile("csrr %0, 0x003" : "=r"(old)); asm volatile("csrr %0, 0x003" : "=r"(old));
asm volatile("csrr %0, 0x003" : "=r"(tmp)); asm volatile("csrr %0, 0x003" : "=r"(tmp));
//printf("csrr fcsr=%x\n", (unsigned)tmp); printf("csrr fcsr=%x\n", (unsigned)tmp);
asm volatile("csrw 0x003, %0" : : "r"(0xE0)); asm volatile("csrw 0x003, %0" : : "r"(0xE0));
asm volatile("csrr %0, 0x003" : "=r"(tmp)); asm volatile("csrr %0, 0x003" : "=r"(tmp));
//printf("csrw: wrote e0 got %x\n", (unsigned)tmp); printf("csrw: wrote e0 got %x\n", (unsigned)tmp);
if (tmp != 0xE0) { printf("FAIL: csrw\n"); ok = 0; } if (tmp != 0xE0) { printf("FAIL: csrw\n"); ok = 0; }
asm volatile("csrw 0x003, %0" : : "r"(old)); asm volatile("csrw 0x003, %0" : : "r"(old));
asm volatile("csrwi 0x003, 0x10"); asm volatile("csrwi 0x003, 0x10");
asm volatile("csrr %0, 0x003" : "=r"(tmp)); asm volatile("csrr %0, 0x003" : "=r"(tmp));
//printf("csrwi: wrote 0x10 got %x\n", (unsigned)tmp); printf("csrwi: wrote 0x10 got %x\n", (unsigned)tmp);
if (tmp != 0x10) { printf("FAIL: csrwi\n"); ok = 0; } if (tmp != 0x10) { printf("FAIL: csrwi\n"); ok = 0; }
asm volatile("csrw 0x003, %0" : : "r"(old)); asm volatile("csrw 0x003, %0" : : "r"(old));
asm volatile("csrsi 0x003, 0x03"); asm volatile("csrsi 0x003, 0x03");
asm volatile("csrr %0, 0x003" : "=r"(tmp)); asm volatile("csrr %0, 0x003" : "=r"(tmp));
//printf("csrsi: old|3=%x\n", (unsigned)tmp); printf("csrsi: old|3=%x\n", (unsigned)tmp);
if ((old | 0x03) != tmp) { printf("FAIL: csrsi\n"); ok = 0; } if ((old | 0x03) != tmp) { printf("FAIL: csrsi\n"); ok = 0; }
asm volatile("csrw 0x003, %0" : : "r"(old)); asm volatile("csrw 0x003, %0" : : "r"(old));
asm volatile("csrci 0x003, 0x03"); asm volatile("csrci 0x003, 0x03");
asm volatile("csrr %0, 0x003" : "=r"(tmp)); asm volatile("csrr %0, 0x003" : "=r"(tmp));
//printf("csrci: old&~3=%x\n", (unsigned)tmp); printf("csrci: old&~3=%x\n", (unsigned)tmp);
if ((old & ~0x03) != tmp) { printf("FAIL: csrci\n"); ok = 0; } if ((old & ~0x03) != tmp) { printf("FAIL: csrci\n"); ok = 0; }
asm volatile("csrw 0x003, %0" : : "r"(old)); asm volatile("csrw 0x003, %0" : : "r"(old));
@ -297,34 +297,30 @@ int fp_cmp_cvt_main(void)
int amo_main(void) int amo_main(void)
{ {
/* AMO base (all funct5 now match GNU as) */ int x = 0, r;
asm volatile("amoadd.w a0, a1, (sp)"); long long xd = 0xCAFEBABECAFEBABELL, rd, val = 0xDEADBEEFDEADBEEFLL;
asm volatile("amoswap.w a0, a1, (sp)"); asm("amoadd.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amoand.w a0, a1, (sp)"); asm("amoswap.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amoor.d a0, a1, (sp)"); asm("amoand.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amoxor.w a0, a1, (sp)"); asm("amoor.d %0, %2, (%1)" : "=r"(rd) : "r"(&xd), "r"(val));
asm volatile("amomax.w a0, a1, (sp)"); asm("amoxor.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amomaxu.d a0, a1, (sp)"); asm("amomax.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amomin.w a0, a1, (sp)"); asm("amomaxu.d %0, %2, (%1)" : "=r"(rd) : "r"(&xd), "r"(val));
asm volatile("amominu.d a0, a1, (sp)"); asm("amomin.w %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm("amominu.d %0, %2, (%1)" : "=r"(rd) : "r"(&xd), "r"(val));
/* AMO aq/rl ordering suffixes */ asm("amoadd.w.aq %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amoadd.w.aq a0, a1, (sp)"); asm("amoadd.w.rl %0, %2, (%1)" : "=r"(r) : "r"(&x), "r"(val));
asm volatile("amoadd.w.rl a0, a1, (sp)"); asm("amoadd.d.aqrl %0, %2, (%1)" : "=r"(rd) : "r"(&xd), "r"(val));
asm volatile("amoadd.d.aqrl a0, a1, (sp)");
return 1; return 1;
} }
int fcvt_round_main(void) int fcvt_round_main(void)
{ {
/* fcvt with optional rounding mode operand (GNU as syntax) */
asm volatile("fcvt.w.s a0, fa0, rne"); asm volatile("fcvt.w.s a0, fa0, rne");
asm volatile("fcvt.w.s a0, fa0, rtz"); asm volatile("fcvt.w.s a0, fa0, rtz");
asm volatile("fcvt.w.s a0, fa0, rup"); asm volatile("fcvt.w.s a0, fa0, rup");
asm volatile("fcvt.w.d a0, fa0, rne"); asm volatile("fcvt.w.d a0, fa0, rne");
asm volatile("fcvt.w.d a0, fa0, rtz"); asm volatile("fcvt.w.d a0, fa0, rtz");
return 1; return 1;
} }
@ -336,7 +332,7 @@ int main()
ok &= test_farith(); ok &= test_farith();
ok &= csr_pseudo_main(); ok &= csr_pseudo_main();
ok &= fp_cmp_cvt_main(); ok &= fp_cmp_cvt_main();
//ok &= amo_main(); //crash on qemu ok &= amo_main();
ok &= fcvt_round_main(); ok &= fcvt_round_main();
printf("%s\n", ok ? "PASS" : "FAIL"); printf("%s\n", ok ? "PASS" : "FAIL");
return !ok; return !ok;

View File

@ -1 +1,6 @@
csrr fcsr=1
csrw: wrote e0 got e0
csrwi: wrote 0x10 got 10
csrsi: old|3=3
csrci: old&~3=0
PASS PASS

View File

@ -135,7 +135,7 @@ endif
128_run_atexit.test: FLAGS += -dt 128_run_atexit.test: FLAGS += -dt
132_bound_test.test: FLAGS += -b 132_bound_test.test: FLAGS += -b
140_arm64_extasm.test: GEN = $(GEN-TCC) 140_arm64_extasm.test: GEN = $(GEN-TCC)
141_riscv_asm.test: FLAGS += -bt 141_riscv_asm.test: GEN = $(GEN-TCC)
# Filter source directory in warnings/errors (out-of-tree builds) # Filter source directory in warnings/errors (out-of-tree builds)
FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'