← board

RISC-V (RV32) text-assembler (EmitAsmRv32) for cleaner riscv32 codegen

Motivation

ir_codegen_riscv32.inc (432 lines) emits RV32 through hand calls to the typed rv32_* encoders. Same readability/maintenance win as the other targets, and RISC-V is the roadmap endgame (bare-metal RISC-V; also the ESP32-C3 path, [[project_esp32_stage1]]). Smallest backend, so a low-risk conversion.

Cheapest of the cross emitters — typed layer already exists

Unlike aarch64/arm32 (no encoder layer), compiler/rv32enc.inc is already a full typed rv32_* / EmitRType/IType/SType/BType/UType/JType layer — exactly the xtensa situation (xtensaenc.inc). So EmitAsmRv32 is the same job as EmitAsmXtensa: a text front-end over the existing typed encoders, no new encoding machinery. Mirror compiler/asmtext_xtensa.inc.

Operand model (clean, fixed-width 32-bit, no ModRM)

mnem rd, rs1, rs2 / mnem rd, rs1, imm. Registers x0..x31 + ABI aliases (zero ra sp gp tp t0.. a0.. s0..). Loads/stores base+imm lw a0, 8(sp) (RISC-V imm(reg) form, not bracketed). Markers % value hole (imm/offset/ branch, range-checked per format), .name: label, @data/@glob reloc (auipc+addi/lw pair — call out as the one multi-instruction case).

Scope (incremental — mix freely)

  1. Cover what converted blocks use first: add sub and or xor sll srl sra (R) + addi andi ori xori slli (I), lui auipc, lw lh lb lbu lhu/sw sh sb, jal jalr, branches beq bne blt bge bltu bgeu, ecall, nop/ret pseudo. Grow on demand.
  2. Labels + branch/jump offset resolution back+forward (B-type ±4 KB, J-type ±1 MB; mind the scrambled immediate bit layout the Emit*Type already handle — pass the byte offset, let the encoder scramble).
  3. Convert ≥1 real branch/label-bearing block. Leave dynamic blocks on the typed rv32_* calls.

Landmines

Acceptance

Deferred

Compressed (C) 16-bit encodings, float (F/D) instructions beyond block needs, the full ir_codegen_riscv32.inc conversion.

Log