Files
gasm-sdk/asm/rendered_text_test.go
T

51 lines
1.6 KiB
Go
Raw Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package asm
import (
"encoding/hex"
"strings"
"testing"
"sourcedock.dev/petrbalvin/gasm-sdk/parser"
)
// TestRenderedTextEncodes pins the encoder against the disassembler's
// renderings: every line here is a text the toolchain's own decoder prints
// for bytes its assembler produced (the disasm package's parity fixtures),
// so assembling the printed text must reproduce those bytes. Each row was
// read back through the toolchain's decoder; the hex is the fixture's.
func TestRenderedTextEncodes(t *testing.T) {
for _, tt := range []struct {
text string
want string
}{
// The segment-absolute rendering lowers to the FS-prefixed disp32
// absolute, exactly what the 0(FS) spelling encodes.
{"MOVQ FS:0, DX", "64488b142500000000"},
2026-10-07 02:10:21 +02:00
// The bank-crossing quadword move takes the prefix by direction: the
// MMX source carries F3, the XMM source F2.
{"MOVQ2DQ M2, X11", "f3440fd6da"},
} {
src := "TEXT \u00b7k(SB), NOSPLIT, $0\n\t" + tt.text + "\n\tRET\n"
f, errs := parser.Parse("k.s", src)
if len(errs) > 0 {
t.Errorf("%s: parse: %v", tt.text, errs[0])
continue
}
img, err := AssembleFile(f)
if err != nil {
t.Errorf("%s: assemble: %v", tt.text, err)
continue
}
fn := img.Funcs[0]
code := img.Code[fn.Offset : fn.Offset+fn.Size]
// The no-fallthrough rule appends the RET; the pinned instruction is
// the prefix.
got := hex.EncodeToString(code)
if !strings.HasPrefix(got, tt.want) {
t.Errorf("%s: bytes %s, want prefix %s", tt.text, got, tt.want)
}
}
}