← board

IR_RTTI_REG and IR_RESOURCES have no riscv32 arm — anything that USES typinfo fails to compile

$ ./compiler/pascal26 --target=riscv32 test/test_class_of.pas /tmp/x
pascal26:664: error: target riscv32: unsupported node in IR codegen: rtti_reg
  in: ./compiler/../lib/rtl/typinfo.pas

x86-64 emits the -100 / -101 data-ref sentinels by hand; aarch64 has EmitLoadDataRefA64(0, -100) and (0, -101). riscv32 has neither arm, and neither did xtensa until 2026-08-30.

The blast radius is wider than "RTTI programs": the failing unit is lib/rtl/typinfo.pas itself, so any program that uses typinfo — directly or through streaming, LFM, or class of — cannot be compiled for riscv32. Six programs in the cross differential are blocked by it on xtensa; the same six are # SKIPped or absent for riscv32.

Fix

Two lines, mirroring aarch64:

    IR_RTTI_REG:  EmitLoadDataRefRISCV32(reg_a0, -100);
    IR_RESOURCES: EmitLoadDataRefRISCV32(reg_a0, -101);

Whoever takes it should check what surfaces underneath rather than closing on the compile: on xtensa these two lines exposed a missing in operator, which exposed a missing IR_SET_COPY, which exposed a by-value set parameter passed as one address word — a silent wrong-answer bug. typinfo.pas exercises all four, so a backend that has never compiled it has never run any of them.

Why it was filed rather than fixed

Found while porting the arm INTO ir_codegen_xtensa.inc. The port went from aarch64 precisely because riscv32 — the usual and closest donor — turned out not to have one, which is only visible if you check that the arm you are copying from exists. Track S holds ir_codegen_xtensa.inc, not ir_codegen_riscv32.inc, so this is filed for whoever holds Track A.

Bound

Object-level, at b859f44e51d6. One compile per program, error text taken verbatim. Not fixed and not attempted on riscv32; the claim that aarch64 and x86-64 have the arms is from reading their case labels. Whether riscv32 has the same in / set-family gaps underneath is UNMEASURED — the rtti_reg error stops the compile before they can surface, which is the point of the note above.

Resolved — frank-rust, 2026-08-31, fixedpoint 4456e3b467aa

Two arms in compiler/ir_codegen_riscv32.inc, before IR_SYSCALL:, mirroring aarch64 (ir_codegen_aarch64.inc:4072) and xtensa (ir_codegen_xtensa.inc:3451): a0 gets the registry / resource-table address via the -100 / -101 data-ref sentinels the linker fills in.

What surfaced underneath — the ticket's own instruction, answered by measurement

The ticket warned that on xtensa these two lines exposed a missing in, then a missing IR_SET_COPY, then a by-value set parameter passed as one address word. That cascade does not repeat on riscv32, and this is measured, not inferred from "riscv32 already has IR_SET_COPY":

A probe covering in, +/-/* on sets, = and <=, a 256-element byte set, a set of Char, and a by-value set parameter that mutates its own copy runs byte-identical on riscv32 and x86-64. So does test_class_of and four of the five typinfo programs.

test_rtti differs and it is NOT a defect

Two kinds of row differ. The pointer rows differ because the targets load at different bases — the prop-to-prop stride is 64 on both. InstanceSize reads 80 native, 64 riscv32.

The 64 is the 32-bit layout, measured: the same class compiled for i386 and arm32 prints the same nine numbers as riscv32 (ptr 4 / string 8 / Integer 4 / TAlign 4 / TAlignSet 32 / TMethod 8 / TObject 4 / TBase 12 / TChild 64), and aarch64 prints riscv32's 64-bit twin. test_rtti has no .expected and asserts none of this; it is an address-printing program, not a cross-target oracle.

The residual question, and who owns it

Not-a-defect is half a finding, so: six IR node kinds are still absent from riscv32IR_CLONE, IR_COSWITCH, IR_IMTADDR, IR_IO_LOCK, IR_IO_UNLOCK, IR_MULHI. Four cannot be reached (IR_MULHI errors at the emission site for non-64-bit targets; IR_IO_LOCK/UNLOCK are gated to x86-64/i386/aarch64/arm32; IR_IMTADDR has no emitter at all, and interface dispatch through a TInterfacedObject runs correctly on riscv32 anyway).

Two are reachable and are filed separately as bug-a-pxxcoswitch-and-pxxclone-are-missing-on-riscv32__pxxcoswitch(@a, @b) compiles for arm32 and x86-64 and gives unsupported node in IR codegen: coswitch on riscv32. Compile-time error, not a wrong answer.

(A methodological note worth keeping: the first pass of that node-coverage diff reported IR_WRITELN missing too. It is present as the trailing label of IR_WRITE, IR_WRITELN: — the grep anchored at line start and answered correctly about a different question. riscv32 obviously writes lines; that implausibility is the only reason it got checked.)

Log