fix(asm): close the oracle parity gaps in frame addressing and calls

This commit is contained in:
2026-09-14 23:25:14 +02:00
parent 70218e84ba
commit 40476546df
18 changed files with 456 additions and 60 deletions
+13 -10
View File
@@ -146,10 +146,18 @@ func splitHi(v int32) int32 {
return high
}
// riscvAddressInX31 materialises hi(v) into X31 and leaves the caller to add
// the low part, matching the toolchain's large-frame addressing: C.LUI (or
// LUI) X31, hi; C.ADD (or ADD) X31, SP.
// riscvAddressInX31 materialises hi(v) into X31 against the stack pointer,
// matching the toolchain's large-frame addressing: C.LUI (or LUI) X31, hi;
// C.ADD (or ADD) X31, SP.
func riscvAddressInX31(v int32) []byte {
return riscvAddressInX31WithBase(v, 2)
}
// riscvAddressInX31WithBase materialises hi(v) into X31 against an arbitrary
// base register: LUI (or C.LUI) X31, hi; C.ADD X31, rs1. The CR rs2 field
// carries the full 5-bit register, so the compressed form is always
// available.
func riscvAddressInX31WithBase(v int32, rs1 int) []byte {
hi := splitHi(v)
var out []byte
if hi >= -32 && hi <= 31 {
@@ -158,13 +166,8 @@ func riscvAddressInX31(v int32) []byte {
} else {
out = append(out, wordLE(riscvUType(riscvEnc{0x37, 0x0, 0x00}, 31, hi<<12))...)
}
if hi >= -32 && hi <= 31 {
c := rvcCR(0x9, 31, 2)
out = append(out, byte(c), byte(c>>8))
} else {
out = append(out, wordLE(riscvRType(riscvEnc{0x33, 0x0, 0x00}, 31, 2, 31))...)
}
return out
c := rvcCR(0x9, 31, uint32(rs1))
return append(out, byte(c), byte(c>>8))
}
// riscvAddToSP adds v to SP through X31 for the values imm12 cannot carry: