From e1bbab38316d535382375e734ca276c81aff997f Mon Sep 17 00:00:00 2001 From: Chuck Benedict Date: Sun, 25 Aug 2024 02:19:30 -0700 Subject: [PATCH] =?UTF-8?q?RISCV:=20Correct=20auipc=20imm;=20clarify=20sig?= =?UTF-8?q?ned=20imm=20error;=20add=20imm=20negative=20t=E2=80=A6=20(#1378?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RISCV: Correct auipc imm; claify signed imm error; add imm negative tests. Allow fitted int asm imm const in uints; add rv regs --- src/compiler/asm/riscv.h | 12 +++++- src/compiler/asm_target.c | 4 +- src/compiler/sema_asm.c | 9 ++++- test/test_suite/asm/asm_imm_err_rv.c3 | 58 +++++++++++++++++++++++++++ test/test_suite/asm/asm_load_rv.c3t | 7 ++-- 5 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 test/test_suite/asm/asm_imm_err_rv.c3 diff --git a/src/compiler/asm/riscv.h b/src/compiler/asm/riscv.h index c63d69713..4bdecc0e1 100644 --- a/src/compiler/asm/riscv.h +++ b/src/compiler/asm/riscv.h @@ -67,7 +67,11 @@ typedef enum RISCV_F31, RISCV_MIE, RISCV_MSTATUS, - RISCV_MTVEC + RISCV_MTVEC, + RISCV_MCAUSE, + RISCV_MEPC, + RISCV_MTVAL, + RISCV_MSIP } RISCVClobbers; static const char *RISCVClobberNames[] = { @@ -138,6 +142,10 @@ static const char *RISCVClobberNames[] = { [RISCV_MIE] = "mie", [RISCV_MSTATUS] = "mstatus", [RISCV_MTVEC] = "mtvec", + [RISCV_MCAUSE] = "mcause", + [RISCV_MEPC] = "mepc", + [RISCV_MTVAL] = "mtval", + [RISCV_MSIP] = "msip", }; static const char *riscv_gp_integer_regs[] = { "$x0", "$x1", "$x2", "$x3", "$x4", @@ -160,5 +168,5 @@ static const char *riscv_float_regs[] = { "$f0", "$f1", "$f2", "$f3", "$f4", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" }; -static const char *riscv_machine_integer_regs[] = { "$mie", "$mstatus", "$mtvec" }; +static const char *riscv_machine_integer_regs[] = { "$mie", "$mstatus", "$mtvec", "$mcause", "$mepc", "$mtval", "$msip" }; diff --git a/src/compiler/asm_target.c b/src/compiler/asm_target.c index 574ff6500..d104fb136 100644 --- a/src/compiler/asm_target.c +++ b/src/compiler/asm_target.c @@ -323,7 +323,7 @@ static void init_asm_riscv(PlatformTarget *target) // load reg_instr(target, "li", "w:r64/mem, immi64"); reg_instr(target, "lui", "w:r64, immu20"); - reg_instr(target, "auipc", "w:r64, immi20"); + reg_instr(target, "auipc", "w:r64, immu20"); reg_instr(target, "mv", "w:r64/mem, r64/mem"); reg_instr(target, "ld", "w:r64/mem, mem"); reg_instr(target, "lw", "w:r64/mem, mem"); @@ -394,7 +394,7 @@ static void init_asm_riscv(PlatformTarget *target) // load reg_instr(target, "li", "w:r32/mem, immi32"); reg_instr(target, "lui", "w:r32, immu20"); - reg_instr(target, "auipc", "w:r32, immi20"); + reg_instr(target, "auipc", "w:r32, immu20"); reg_instr(target, "mv", "w:r32/mem, r32/mem"); reg_instr(target, "lw", "w:r32/mem, mem"); reg_instr(target, "lh", "w:r32/mem, mem"); diff --git a/src/compiler/sema_asm.c b/src/compiler/sema_asm.c index c9227dc7c..52e18ae44 100644 --- a/src/compiler/sema_asm.c +++ b/src/compiler/sema_asm.c @@ -21,7 +21,12 @@ static inline Type *max_supported_imm_int(bool is_signed, AsmArgType arg) if (is_signed) { unsigned bits = arg_bits_max(arg.imm_arg_ibits, 64); - if (!bits) return NULL; + if (!bits) + { + bits = arg_bits_max(arg.imm_arg_ubits, 64); + if (!bits) return NULL; + return type_int_unsigned_by_bitsize(next_highest_power_of_2(bits)); + } return type_int_signed_by_bitsize(next_highest_power_of_2(bits)); } unsigned bits = arg_bits_max(arg.imm_arg_ubits, 64); @@ -135,7 +140,7 @@ static inline bool sema_check_asm_arg_const_int(SemaContext *context, AsmInlineB return false; } Int i = int_expr->const_expr.ixx; - unsigned max_bits = arg_bits_max(is_signed ? arg_type.imm_arg_ibits : arg_type.imm_arg_ubits, 0); + unsigned max_bits = arg_bits_max(arg_type.imm_arg_ibits > arg_type.imm_arg_ubits ? arg_type.imm_arg_ibits : arg_type.imm_arg_ubits, 0); if (!type || !int_fits(i, type->type_kind) || !sema_check_npot_imm_fits(i, arg_type)) { SEMA_ERROR(expr, "'%s' expected %s limited to %d bits.", instr->name, type_quoted_error_string(type), max_bits); diff --git a/test/test_suite/asm/asm_imm_err_rv.c3 b/test/test_suite/asm/asm_imm_err_rv.c3 new file mode 100644 index 000000000..78728d56d --- /dev/null +++ b/test/test_suite/asm/asm_imm_err_rv.c3 @@ -0,0 +1,58 @@ +// #target: elf-riscv32 +module test; + +fn void test1() +{ + asm + { + andi $s1, $s2, -2049; // #error: 'andi' expected 'short' limited to 12 bits. + } +} + +fn void test2() +{ + asm + { + ori $t0, $t1, 2048; // #error: 'ori' expected 'short' limited to 12 bits. + } +} + +fn void test3() +{ + asm + { + slli $a0, $a1, 32u; // #error: 'slli' expected 'char' limited to 5 bits. + } +} + +fn void test4() +{ + asm + { + lui $a0, 0xFFFFFF; // #error: 'lui' expected 'uint' limited to 20 bits. + } +} + +fn void test5() +{ + asm + { + lui $a0, -1; // #error: 'lui' expected 'uint' limited to 20 bits. + } +} + +fn void test6() +{ + asm + { + auipc $a0, -1; // #error: 'auipc' expected 'uint' limited to 20 bits. + } +} + +fn void test7() +{ + asm + { + slli $a0, 1, 31u; // #error: 'slli' does not support a direct integer constant here. + } +} diff --git a/test/test_suite/asm/asm_load_rv.c3t b/test/test_suite/asm/asm_load_rv.c3t index e06c0d2b8..18aad2202 100644 --- a/test/test_suite/asm/asm_load_rv.c3t +++ b/test/test_suite/asm/asm_load_rv.c3t @@ -6,9 +6,10 @@ fn void main(String[] args) int x = 2; asm { - li $s1, -65536; + li $s1, -2147483648; lui $t0, 123456u; - auipc $x15, -123456; + auipc $x15, 123456u; + auipc $a0, 1; mv $a0, $a1; lw $a4, [&x]; lb $a5, [$a7 - 4]; @@ -17,4 +18,4 @@ fn void main(String[] args) /* #expect: test.ll -"li s1, -65536\0Alui t0, 123456\0Aauipc x15, -123456\0Amv a0, a1\0Alw a4, $0\0Alb a5, -4(a7)\0A", "*m,~{x5},~{x9},~{x10},~{x14},~{x15}"(ptr elementtype(i32) %x) \ No newline at end of file +"li s1, -2147483648\0Alui t0, 123456\0Aauipc x15, 123456\0Aauipc a0, 1\0Amv a0, a1\0Alw a4, $0\0Alb a5, -4(a7)\0A", "*m,~{x5},~{x9},~{x10},~{x14},~{x15}"(ptr elementtype(i32) %x) \ No newline at end of file