XSAVE, XSAVEOPT, XSAVEC and XSAVES with their restore twins, plain and 64, each pinned byte for byte against go tool asm through every corpus line the toolchain's own amd64enc.s carries for the family (24 lines). The toolchain emits XSAVEOPT without the manual's 0x66 prefix; the bytes are the oracle, so the family carries none. Assisted-by: GLM 5.3 Flash
57 lines
1.8 KiB
Go
57 lines
1.8 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package asm
|
|
|
|
import "testing"
|
|
|
|
// amd64XsaveCorpus holds every line the Go toolchain's own
|
|
// amd64enc.s carries for the XSAVE family (XSAVE, XSAVEOPT, XSAVEC, XSAVES and the restores, plain and 64), with the bytes go tool asm
|
|
// emits for each: the differential ground truth the family is proven
|
|
// against, line for line.
|
|
var amd64XsaveCorpus = []struct {
|
|
line string
|
|
want string
|
|
}{
|
|
{"XRSTOR (BX)", "0f ae 2b"},
|
|
{"XRSTOR (R11)", "41 0f ae 2b"},
|
|
{"XRSTOR64 (BX)", "48 0f ae 2b"},
|
|
{"XRSTOR64 (R11)", "49 0f ae 2b"},
|
|
{"XRSTORS (BX)", "0f c7 1b"},
|
|
{"XRSTORS (R11)", "41 0f c7 1b"},
|
|
{"XRSTORS64 (BX)", "48 0f c7 1b"},
|
|
{"XRSTORS64 (R11)", "49 0f c7 1b"},
|
|
{"XSAVE (BX)", "0f ae 23"},
|
|
{"XSAVE (R11)", "41 0f ae 23"},
|
|
{"XSAVE64 (BX)", "48 0f ae 23"},
|
|
{"XSAVE64 (R11)", "49 0f ae 23"},
|
|
{"XSAVEC (BX)", "0f c7 23"},
|
|
{"XSAVEC (R11)", "41 0f c7 23"},
|
|
{"XSAVEC64 (BX)", "48 0f c7 23"},
|
|
{"XSAVEC64 (R11)", "49 0f c7 23"},
|
|
{"XSAVEOPT (BX)", "0f ae 33"},
|
|
{"XSAVEOPT (R11)", "41 0f ae 33"},
|
|
{"XSAVEOPT64 (BX)", "48 0f ae 33"},
|
|
{"XSAVEOPT64 (R11)", "49 0f ae 33"},
|
|
{"XSAVES (BX)", "0f c7 2b"},
|
|
{"XSAVES (R11)", "41 0f c7 2b"},
|
|
{"XSAVES64 (BX)", "48 0f c7 2b"},
|
|
{"XSAVES64 (R11)", "49 0f c7 2b"},
|
|
}
|
|
|
|
// TestAmd64XsaveCorpus assembles every corpus line and requires the same bytes
|
|
// go tool asm emits for it.
|
|
func TestAmd64XsaveCorpus(t *testing.T) {
|
|
for _, tc := range amd64XsaveCorpus {
|
|
fn := firstText(t, "TEXT ·p(SB), 4, $0\n\t"+tc.line+"\n")
|
|
code, _, err := Assemble(fn)
|
|
if err != nil {
|
|
t.Errorf("%s: %v", tc.line, err)
|
|
continue
|
|
}
|
|
if got := hexBytes(code); got != tc.want {
|
|
t.Errorf("%s: got %s, want %s", tc.line, got, tc.want)
|
|
}
|
|
}
|
|
}
|