RISCV: Correct auipc imm; clarify signed imm error; add imm negative t… (#1378)

RISCV: Correct auipc imm; claify signed imm error; add imm negative tests. Allow fitted int asm imm const in uints; add rv regs
This commit is contained in:
Chuck Benedict
2024-08-25 02:19:30 -07:00
committed by GitHub
parent a870881fff
commit e1bbab3831
5 changed files with 81 additions and 9 deletions

View File

@@ -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" };

View File

@@ -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");

View File

@@ -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)
{
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);

View File

@@ -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.
}
}

View File

@@ -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)
"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)