fix(asm): bound the riscv64 shift immediate at the instruction width

SLLI $64 assembled with the amount silently masked into the six-bit
field where the toolchain rejects it, and the word forms took 0-63 where
they take 0-31.  Both families now validate against their own width and
the check reads the immediate at full width, so a value the source
spelled beyond int32 cannot wrap into the range; the boundary is pinned
in a test.

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 00:47:27 +02:00
1 parent c3540f0549
commit d82ef33fa9
2 files changed
+59 -5

No files matched your search

+29
View File
@@ -1389,3 +1389,32 @@ func TestRISCV_rawDataRange(t *testing.T) {
}
})
}
// TestRISCV_shiftImmediateRange pins the shift immediate at the toolchain's
// validation boundary: 0-63 on the doubleword forms, 0-31 on the word forms,
// values beyond rejected on sight rather than masked into the field.
func TestRISCV_shiftImmediateRange(t *testing.T) {
asmOne := func(t *testing.T, stmt string) error {
t.Helper()
fn := firstTextRISCV(t, "#include \"textflag.h\"\nTEXT ·s(SB), NOSPLIT, $0\n\t"+stmt+"\n\tRET\n")
_, _, _, _, _, _, err := assembleRISCV(fn)
return err
}
for _, s := range []string{
"SLLI $63, X5, X6", "SLLI $0, X5, X6", "SRLI $63, X5", "SRAI $1, X5, X6",
"SLLIW $31, X5, X6", "SRLIW $31, X5", "SRAIW $1, X5, X6",
} {
if err := asmOne(t, s); err != nil {
t.Errorf("%s must assemble: %v", s, err)
}
}
for _, s := range []string{
"SLLI $64, X5, X6", "SLLI $-1, X5", "SLLI $0x100000000, X5, X6",
"SRLI $64, X5", "SRAI $-1, X5, X6",
"SLLIW $32, X5, X6", "SRLIW $-1, X5", "SRAIW $32, X5, X6",
} {
if err := asmOne(t, s); err == nil {
t.Errorf("%s must be rejected, as go tool asm rejects it", s)
}
}
}