feat(arch): add the {1toN} broadcast to the packed amd64 memory sources
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
9c1392dfc3
commit
ccb155437e
4 files changed
+218
-32
No files matched your search
@@ -76,6 +76,8 @@ func TestAmd64ExtMemoryRejects(t *testing.T) {
|
||||
"arrangement"},
|
||||
{"predicate qualifier on the memory operand", ExtOperand{Kind: ExtMem, Reg: 8, Qual: ExtQualZeroing},
|
||||
"predicate qualifier"},
|
||||
{"broadcast on an entry that takes none", ExtBroadcast(8, 0),
|
||||
"takes none"},
|
||||
} {
|
||||
_, _, err := in.amd64Memory(tt.op, 1)
|
||||
if err == nil {
|
||||
@@ -86,6 +88,57 @@ func TestAmd64ExtMemoryRejects(t *testing.T) {
|
||||
t.Errorf("%s: error %q lacks %q", tt.name, err, tt.quote)
|
||||
}
|
||||
}
|
||||
// The broadcast spelling passes the flag gate on an entry that carries
|
||||
// Bcast and then meets the same base and displacement checks.
|
||||
bcast := ExtInstr{Name: "TEST", Bcast: true}
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
op ExtOperand
|
||||
quote string
|
||||
}{
|
||||
{"broadcast base beyond r15", ExtOperand{Kind: ExtMem, Reg: 16, Imm: 0, Broadcast: true},
|
||||
"outside 0-15"},
|
||||
{"broadcast displacement past the signed 32-bit ceiling", ExtBroadcast(8, 1<<31),
|
||||
"outside the signed 32-bit range"},
|
||||
{"broadcast base under r0", ExtBroadcast(-1, 0),
|
||||
"outside 0-15"},
|
||||
} {
|
||||
if _, _, err := bcast.amd64Memory(tt.op, 1); err == nil {
|
||||
t.Errorf("%s: validation succeeded, want an error", tt.name)
|
||||
} else if !strings.Contains(err.Error(), tt.quote) {
|
||||
t.Errorf("%s: error %q lacks %q", tt.name, err, tt.quote)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAmd64ExtBroadcastEncoding pins the broadcast layer over the memory
|
||||
// encoding: EVEX.b, bit 4 of byte three, set on the VADDPH 512-bit template
|
||||
// while the ModR/M mod bits, the SIB byte and the displacement choices keep
|
||||
// the plain semantics amd64EncodeMemory chooses.
|
||||
func TestAmd64ExtBroadcastEncoding(t *testing.T) {
|
||||
add := []byte{0x62, 0x05, 0x04, 0x40, 0x58, 0xC0}
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
base int
|
||||
disp int64
|
||||
want string
|
||||
}{
|
||||
{"zero displacement keeps the mod-00 form under the broadcast bit", 9, 0,
|
||||
"624514505831"},
|
||||
{"disp8 semantics unchanged", 1, 127,
|
||||
"6265145058717f"},
|
||||
{"disp32 semantics unchanged", 2, 8128,
|
||||
"6265145058b2c01f0000"},
|
||||
{"RBP keeps the forced displacement", 5, 0,
|
||||
"62651450587500"},
|
||||
{"RSP keeps the SIB byte", 12, 0,
|
||||
"62451450583424"},
|
||||
} {
|
||||
got := amd64EncodeBroadcast(add, 30, 29, tt.base, tt.disp)
|
||||
if hex.EncodeToString(got) != tt.want {
|
||||
t.Errorf("%s:\n got %x\n want %s", tt.name, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAmd64ExtMemoryVocabulary pins the names the shared layer gives the
|
||||
|
||||
Reference in new issue
Block a user