110 lines
3.0 KiB
Go
110 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)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|