From 5c2240a896775ab44f93b2335e340a4f96701d24 Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Sun, 3 May 2026 00:14:41 +0800 Subject: [PATCH] riscv64-asm: remove long long 'not implemented' errors in inline asm On RV64, long long (64-bit) fits in a single general-purpose register. The existing load/store calls already handle 64-bit values correctly. The 'not implemented' errors were vestigial from 32-bit architectures where long long requires a register pair. Removing these errors allows inline asm to accept 64-bit integer operands on RV64, which is important since this is the native register width. --- riscv64-asm.c | 9 ++-- tests/tests2/142_riscv_asm_longlong.c | 57 ++++++++++++++++++++++ tests/tests2/142_riscv_asm_longlong.expect | 1 + tests/tests2/Makefile | 5 ++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 tests/tests2/142_riscv_asm_longlong.c create mode 100644 tests/tests2/142_riscv_asm_longlong.expect diff --git a/riscv64-asm.c b/riscv64-asm.c index e15e8068..b3916ab3 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -1837,9 +1837,8 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, } else { load(tcc_ireg(op->reg), op->vt); } - if (op->is_llong) { - tcc_error("long long not implemented"); - } + /* RV64: long long fits in a single 64-bit register; + the load/store above already handles it correctly */ } } } @@ -1867,9 +1866,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, } else { store(tcc_ireg(op->reg), op->vt); } - if (op->is_llong) { - tcc_error("long long not implemented"); - } + /* RV64: long long fits in a single 64-bit register */ } } } diff --git a/tests/tests2/142_riscv_asm_longlong.c b/tests/tests2/142_riscv_asm_longlong.c new file mode 100644 index 00000000..8c9cee03 --- /dev/null +++ b/tests/tests2/142_riscv_asm_longlong.c @@ -0,0 +1,57 @@ +#include + +/* P1.1: riscv64 inline asm with 64-bit immediate (li). + Tests that long long immediates assemble correctly, + including the lui+addi sequence for large constants. */ + +#ifdef __riscv + +long long test_li_small(void) +{ + long long r; + asm("li %0, 42" : "=r"(r)); + return r; +} + +long long test_li_large(void) +{ + long long r; + asm("li %0, 0x123456789ABCDEF0" : "=r"(r)); + return r; +} + +long long test_li_negative(void) +{ + long long r; + asm("li %0, -1" : "=r"(r)); + return r; +} + +int main(void) +{ + int ok = 1; + + if (test_li_small() != 42) { + printf("FAIL: li small\n"); + ok = 0; + } + if (test_li_large() != 0x123456789ABCDEF0LL) { + printf("FAIL: li large\n"); + ok = 0; + } + if (test_li_negative() != -1) { + printf("FAIL: li negative\n"); + ok = 0; + } + + printf("%s\n", ok ? "PASS" : "FAIL"); + return ok ? 0 : 1; +} + +#else +int main(void) +{ + printf("SKIP\n"); + return 0; +} +#endif diff --git a/tests/tests2/142_riscv_asm_longlong.expect b/tests/tests2/142_riscv_asm_longlong.expect new file mode 100644 index 00000000..7ef22e9a --- /dev/null +++ b/tests/tests2/142_riscv_asm_longlong.expect @@ -0,0 +1 @@ +PASS diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 620ed77e..40ed4238 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -19,6 +19,11 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) SKIP += 85_asm-outside-function.test # x86 asm SKIP += 127_asm_goto.test # hardcodes x86 asm endif +ifeq (,$(filter riscv64,$(ARCH))) + SKIP += 141_riscv_asm_pseudo.test # riscv64 asm + SKIP += 142_riscv_asm_longlong.test # riscv64 asm + SKIP += 143_riscv_asm_farith.test # riscv64 asm +endif ifeq ($(CONFIG_backtrace),no) SKIP += 113_btdll.test CONFIG_bcheck = no