Files
gasm-sdk/asm/amd64_x87_test.go
T
petrbalvin f0b08ccea0 feat(asm): encode the amd64 x87 family
The x87 stack controls, the D8/DC arithmetic pair, the conditional moves,
the register compares, FADDDP, the memory loads and the FXSAVE pair, each
pinned byte for byte against go tool asm through every corpus line the
toolchain's own amd64enc.s carries for the family (78 lines).

Assisted-by: GLM 5.3 Flash
2026-10-06 23:59:47 +02:00

111 lines
3.0 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package asm
import "testing"
// amd64X87Corpus holds every line the Go toolchain's own
// amd64enc.s carries for the x87 family (stack controls, the arithmetic pair, the compares, the memory loads and the FXSAVE pair), with the bytes go tool asm
// emits for each: the differential ground truth the family is proven
// against, line for line.
var amd64X87Corpus = []struct {
line string
want string
}{
{"F2XM1", "d9 f0"},
{"FABS", "d9 e1"},
{"FADDD F2, F0", "d8 c2"},
{"FADDD F3, F0", "d8 c3"},
{"FADDD F0, F2", "dc c2"},
{"FADDD F0, F3", "dc c3"},
{"FADDD (BX), F0", "dc 03"},
{"FADDD (R11), F0", "41 dc 03"},
{"FADDDP F0, F2", "de c2"},
{"FADDDP F0, F3", "de c3"},
{"FBLD (BX)", "df 23"},
{"FBLD (R11)", "41 df 23"},
{"FBSTP (BX)", "df 33"},
{"FBSTP (R11)", "41 df 33"},
{"FCHS", "d9 e0"},
{"FCMOVB F2, F0", "da c2"},
{"FCMOVB F3, F0", "da c3"},
{"FCMOVBE F2, F0", "da d2"},
{"FCMOVBE F3, F0", "da d3"},
{"FCMOVE F2, F0", "da ca"},
{"FCMOVE F3, F0", "da cb"},
{"FCMOVNB F2, F0", "db c2"},
{"FCMOVNB F3, F0", "db c3"},
{"FCMOVNBE F2, F0", "db d2"},
{"FCMOVNBE F3, F0", "db d3"},
{"FCMOVNE F2, F0", "db ca"},
{"FCMOVNE F3, F0", "db cb"},
{"FCMOVNU F2, F0", "db da"},
{"FCMOVNU F3, F0", "db db"},
{"FCMOVU F2, F0", "da da"},
{"FCMOVU F3, F0", "da db"},
{"FCOMD F2, F0", "d8 d2"},
{"FCOMD F3, F0", "d8 d3"},
{"FCOMD (BX), F0", "dc 13"},
{"FCOMD (R11), F0", "41 dc 13"},
{"FCOMI F2, F0", "db f2"},
{"FCOMI F3, F0", "db f3"},
{"FCOMIP F2, F0", "df f2"},
{"FCOMIP F3, F0", "df f3"},
{"FCOS", "d9 ff"},
{"FDECSTP", "d9 f6"},
{"FDIVD F2, F0", "d8 f2"},
{"FDIVD F3, F0", "d8 f3"},
{"FDIVD F0, F2", "dc fa"},
{"FDIVD F0, F3", "dc fb"},
{"FDIVD (BX), F0", "dc 33"},
{"FDIVD (R11), F0", "41 dc 33"},
{"FINCSTP", "d9 f7"},
{"FLD1", "d9 e8"},
{"FLDCW (BX)", "d9 2b"},
{"FLDCW (R11)", "41 d9 2b"},
{"FLDL2E", "d9 ea"},
{"FLDL2T", "d9 e9"},
{"FLDLG2", "d9 ec"},
{"FLDPI", "d9 eb"},
{"FNOP", "d9 d0"},
{"FPATAN", "d9 f3"},
{"FPREM", "d9 f8"},
{"FPREM1", "d9 f5"},
{"FPTAN", "d9 f2"},
{"FRNDINT", "d9 fc"},
{"FSCALE", "d9 fd"},
{"FSIN", "d9 fe"},
{"FSINCOS", "d9 fb"},
{"FSQRT", "d9 fa"},
{"FTST", "d9 e4"},
{"FXAM", "d9 e5"},
{"FXRSTOR (BX)", "0f ae 0b"},
{"FXRSTOR (R11)", "41 0f ae 0b"},
{"FXRSTOR64 (BX)", "48 0f ae 0b"},
{"FXRSTOR64 (R11)", "49 0f ae 0b"},
{"FXSAVE (BX)", "0f ae 03"},
{"FXSAVE (R11)", "41 0f ae 03"},
{"FXSAVE64 (BX)", "48 0f ae 03"},
{"FXSAVE64 (R11)", "49 0f ae 03"},
{"FXTRACT", "d9 f4"},
{"FYL2X", "d9 f1"},
{"FYL2XP1", "d9 f9"},
}
// TestAmd64X87Corpus assembles every corpus line and requires the same bytes
// go tool asm emits for it.
func TestAmd64X87Corpus(t *testing.T) {
for _, tc := range amd64X87Corpus {
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)
}
}
}