feat(arch): the shift-immediate tsz:imm3 scheme

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 21:39:45 +02:00
1 parent 718181e7a7
commit eda8b16c5f
4 files changed
+555 -2

No files matched your search

+81
View File
@@ -956,3 +956,84 @@ func TestArm64AssembleExtensionGatherRefusals(t *testing.T) {
}
}
}
// TestArm64AssembleExtensionShiftImmGolden drives the shift-immediate
// classes through the full assembler: every corpus line of the three
// families, corpus text in, corpus word out. The narrowing and widening
// three-vector shifts and the predicated saturating left shifts carry the
// amount in the class's tsz:imm3 fields, whose tsz bits double as the
// arrangement spelling.
func TestArm64AssembleExtensionShiftImmGolden(t *testing.T) {
tests := []struct {
stmt string
want uint32
}{
{"ZSHRNB $9, Z7.S, Z23.H", 0x453710f7},
{"ZSHRNT $9, Z7.S, Z23.H", 0x453714f7},
{"ZRSHRNB $9, Z7.S, Z23.H", 0x453718f7},
{"ZRSHRNT $9, Z7.S, Z23.H", 0x45371cf7},
{"ZSQSHRNB $9, Z7.S, Z23.H", 0x453720f7},
{"ZSQSHRNT $9, Z7.S, Z23.H", 0x453724f7},
{"ZSQRSHRNB $9, Z7.S, Z23.H", 0x453728f7},
{"ZSQRSHRNT $9, Z7.S, Z23.H", 0x45372cf7},
{"ZSQSHRUNB $9, Z7.S, Z23.H", 0x453700f7},
{"ZSQSHRUNT $9, Z7.S, Z23.H", 0x453704f7},
{"ZUQSHRNB $9, Z7.S, Z23.H", 0x453730f7},
{"ZUQSHRNT $9, Z7.S, Z23.H", 0x453734f7},
{"ZUQRSHRNB $9, Z7.S, Z23.H", 0x453738f7},
{"ZUQRSHRNT $9, Z7.S, Z23.H", 0x45373cf7},
{"ZSSHLLB $5, Z22.S, Z10.D", 0x4545a2ca},
{"ZSSHLLT $5, Z22.S, Z10.D", 0x4545a6ca},
{"ZUSHLLB $5, Z22.S, Z10.D", 0x4545aaca},
{"ZUSHLLT $5, Z22.S, Z10.D", 0x4545aeca},
{"ZSQSHL $6, Z23.B, P1.M, Z23.B", 0x040685d7},
{"ZSQSHLU $6, Z23.B, P1.M, Z23.B", 0x040f85d7},
{"ZUQSHL $6, Z23.B, P1.M, Z23.B", 0x040785d7},
// Width extensions beyond the corpus lines.
{"ZSHRNB $8, Z6.H, Z22.B", 0x452810d6},
{"ZSQSHRNT $16, Z5.D, Z4.S", 0x457024a4},
{"ZSSHLLB $0, Z3.B, Z2.H", 0x4508a062},
{"ZSQSHL $20, Z8.S, P4.M, Z8.S", 0x04469288},
}
for _, tt := range tests {
words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
if len(words) != 2 {
t.Fatalf("%s: got %d words, want the statement and RET", tt.stmt, len(words))
}
if words[0] != tt.want {
t.Errorf("%s:\n got %08x\n want %08x", tt.stmt, words[0], tt.want)
}
if words[1] != 0xd65f03c0 {
t.Errorf("%s: RET encoded %08x", tt.stmt, words[1])
}
}
}
// TestArm64AssembleExtensionShiftImmRefusals pins the diagnostics the
// shift-immediate statements get from the layer: the element-step pairs
// the classes take, the amount ranges and the read-back and qualifier
// rules of the predicated class.
func TestArm64AssembleExtensionShiftImmRefusals(t *testing.T) {
tests := []struct {
stmt string
want string
}{
{"ZSHRNB $9, Z7.S, Z23.S", "one element step below"},
{"ZSHRNB $9, Z7.S, Z23.B", "one element step below"},
{"ZSHRNB $17, Z7.S, Z23.H", "outside the range 1..16"},
{"ZSHRNB $0, Z7.S, Z23.H", "outside the range 1..16"},
{"ZSHRNB $9, LSL #8, Z7.S, Z23.H", "takes no LSL shift"},
{"ZSSHLLB $32, Z22.S, Z10.D", "outside the range 0..31"},
{"ZSSHLLB $5, Z22.S, Z10.Q", "one element step above .S"},
{"ZSQSHL $6, Z23.B, P1.Z, Z23.B", "/M"},
{"ZSQSHL $6, Z23.B, P1.M, Z22.B", "the same register Zdn"},
{"ZSQSHL $6, Z23.Q, P1.M, Z23.Q", "no size encoding"},
{"ZSQSHL $8, Z23.B, P1.M, Z23.B", "outside the range 1..7"},
}
for _, tt := range tests {
got := assembleArm64SrcError(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
if !strings.Contains(got, tt.want) {
t.Errorf("%s: error %q does not name %q", tt.stmt, got, tt.want)
}
}
}
+26 -2
View File
@@ -492,12 +492,36 @@ func TestExtensionNamesARM64(t *testing.T) {
"ZST1D",
"ZST1H",
"ZST1W",
// The shift-immediate classes: the narrowing and widening
// three-vector shifts and the predicated saturating left shifts,
// in first-occurrence order.
"ZSQSHRUNB",
"ZSQSHRUNT",
"ZSHRNB",
"ZSHRNT",
"ZRSHRNB",
"ZRSHRNT",
"ZSQSHRNB",
"ZSQSHRNT",
"ZSQRSHRNB",
"ZSQRSHRNT",
"ZUQSHRNB",
"ZUQSHRNT",
"ZUQRSHRNB",
"ZUQRSHRNT",
"ZSSHLLB",
"ZSSHLLT",
"ZUSHLLB",
"ZUSHLLT",
"ZSQSHL",
"ZSQSHLU",
"ZUQSHL",
}
got := ExtensionNames(arch.ARM64)
if strings.Join(got, ",") != strings.Join(want, ",") {
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
}
if n := len(arch.Extensions(arch.ARM64)); n != 507 {
t.Errorf("the family registers %d instructions, want 507", n)
if n := len(arch.Extensions(arch.ARM64)); n != 528 {
t.Errorf("the family registers %d instructions, want 528", n)
}
}