diff --git a/dynasm/dasm_riscv.lua b/dynasm/dasm_riscv.lua index 56ca226..6c7bf7b 100644 --- a/dynasm/dasm_riscv.lua +++ b/dynasm/dasm_riscv.lua @@ -79,6 +79,7 @@ local action_names = { "STOP", "SECTION", "ESC", "REL_EXT", "ALIGN", "REL_LG", "LABEL_LG", "REL_PC", "LABEL_PC", "IMM", "IMMS", + "VREG" } -- Maximum number of section buffer positions for dasm_put(). @@ -612,7 +613,7 @@ local function parse_gpr(expr) end local vreg = match(expr, "^Rx(%b())$") if vreg then - waction("VREG", vreg) + waction("VREG", 0, vreg) return 0 end werror("bad register name `"..expr.."'") diff --git a/ir_riscv64.dasc b/ir_riscv64.dasc index 71a851e..ae8918a 100644 --- a/ir_riscv64.dasc +++ b/ir_riscv64.dasc @@ -92,6 +92,11 @@ static bool aarch64_may_encode_logical_imm(uint64_t value, uint32_t type_size) return 0; } +static bool riscv64_may_encode_i_type_addr_offset(int64_t offset, uint32_t type_size) +{ + return (uintptr_t)(offset) % type_size == 0 && (uintptr_t)(offset) < 0xfff; +} + static bool aarch64_may_encode_addr_offset(int64_t offset, uint32_t type_size) { return (uintptr_t)(offset) % type_size == 0 && (uintptr_t)(offset) < 0xfff * type_size; @@ -837,26 +842,30 @@ static void ir_emit_load_mem_int(ir_ctx *ctx, ir_type type, ir_reg reg, ir_reg b ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - if (aarch64_may_encode_addr_offset(offset, ir_type_size[type])) { + if (riscv64_may_encode_i_type_addr_offset(offset, ir_type_size[type])) { switch (ir_type_size[type]) { case 8: - | ldr Rx(reg), [Rx(base_reg), #offset] + | ld Rx(reg), offset(Rx(base_reg)) break; case 4: - | ldr Rw(reg), [Rx(base_reg), #offset] + if (IR_IS_TYPE_SIGNED(type)) { + | lw Rx(reg), offset(Rx(base_reg)) + } else { + | lwu Rx(reg), offset(Rx(base_reg)) + } break; case 2: if (IR_IS_TYPE_SIGNED(type)) { - | ldrsh Rw(reg), [Rx(base_reg), #offset] + | lh Rx(reg), offset(Rx(base_reg)) } else { - | ldrh Rw(reg), [Rx(base_reg), #offset] + | lhu Rx(reg), offset(Rx(base_reg)) } break; case 1: if (IR_IS_TYPE_SIGNED(type)) { - | ldrsb Rw(reg), [Rx(base_reg), #offset] + | lb Rx(reg), offset(Rx(base_reg)) } else { - | ldrb Rw(reg), [Rx(base_reg), #offset] + | lbu Rx(reg), offset(Rx(base_reg)) } break; default: