fix(test): add arm64 encoding tests for Go 1.26 coverage compatibility
Assisted-by: MiMo V2.5 Pro
This commit is contained in:
@@ -365,6 +365,199 @@ func TestArm64ResolvePseudo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64FPSel tests FP conditional select encoding.
|
||||
func TestArm64FPSel(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
FCSELD GE, F10, F11, F12
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
// FCSELD should be 4 bytes + RET 4 bytes = 8
|
||||
if img.Funcs[0].Size != 8 {
|
||||
t.Errorf("size: got %d, want 8", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64FPCvt tests FP conversion encoding.
|
||||
func TestArm64FPCvt(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
FCVTZSD F4, R0
|
||||
SCVTFD R4, F8
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
if img.Funcs[0].Size != 12 {
|
||||
t.Errorf("size: got %d, want 12", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64CSEL tests conditional select encoding.
|
||||
func TestArm64CSEL(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
CSEL EQ, R0, R1, R2
|
||||
CSET NE, R3
|
||||
CINC GE, R4, R5
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
if img.Funcs[0].Size != 16 {
|
||||
t.Errorf("size: got %d, want 16", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64CRC32 tests CRC32 encoding.
|
||||
func TestArm64CRC32(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
CRC32B R0, R2
|
||||
CRC32W R6, R8
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
if img.Funcs[0].Size != 12 {
|
||||
t.Errorf("size: got %d, want 12", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64Bitfield tests bitfield/shift encoding.
|
||||
func TestArm64Bitfield(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
ASR $4, R0, R1
|
||||
LSL $12, R4, R5
|
||||
EXTR $8, R0, R1, R2
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
if img.Funcs[0].Size != 16 {
|
||||
t.Errorf("size: got %d, want 16", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64SIMD tests SIMD encoding (via the instruction table).
|
||||
func TestArm64SIMD(t *testing.T) {
|
||||
// Verify SIMD instructions are in the table.
|
||||
for _, mnem := range []string{"VADD", "VSUB", "VMUL"} {
|
||||
if _, ok := a64InstrTable[mnem]; !ok {
|
||||
t.Errorf("%s not in instruction table", mnem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64LoadImm64 tests 64-bit immediate loading.
|
||||
func TestArm64LoadImm64(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
MOVD $0x123456789ABCDEF0, R0
|
||||
MOVD $0, R1
|
||||
MOVD $1, R2
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
// $0x123456789ABCDEF0 needs 4 MOVZ/MOVK instructions (16 bytes)
|
||||
// $0 is 1 instruction (4 bytes)
|
||||
// $1 is 1 bitmask instruction (4 bytes)
|
||||
// RET is 1 instruction (4 bytes)
|
||||
if img.Funcs[0].Size != 28 {
|
||||
t.Errorf("size: got %d, want 28", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64BranchCond tests conditional branch encoding.
|
||||
func TestArm64BranchCond(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
TEXT ·f(SB), NOSPLIT, $0-0
|
||||
BEQ done
|
||||
BNE done
|
||||
BGE done
|
||||
BLT done
|
||||
ADD R4, R5
|
||||
done:
|
||||
RET
|
||||
`
|
||||
f, errs := parser.Parse("test_arm64.s", src)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileARM64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileARM64: %v", err)
|
||||
}
|
||||
// 4 branches + 1 ADD + 1 RET = 24 bytes
|
||||
if img.Funcs[0].Size != 24 {
|
||||
t.Errorf("size: got %d, want 24", img.Funcs[0].Size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64Errors tests error paths.
|
||||
func TestArm64Errors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
src string
|
||||
}{
|
||||
{"bad mnemonic", "TEXT ·f(SB), NOSPLIT, $0-0\n\tINVALID\tR4\n\tRET\n"},
|
||||
{"bad label", "TEXT ·f(SB), NOSPLIT, $0-0\n\tB\tnosuch\n\tRET\n"},
|
||||
{"bad register", "TEXT ·f(SB), NOSPLIT, $0-0\n\tADD\tR99, R0\n\tRET\n"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f, errs := parser.Parse("test_arm64.s", tt.src)
|
||||
if len(errs) > 0 {
|
||||
return
|
||||
}
|
||||
_, err := AssembleFileARM64(f)
|
||||
if err == nil {
|
||||
t.Error("expected error, got nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// leWord reads a little-endian uint32 from b.
|
||||
func leWord(b []byte) uint32 {
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
|
||||
Reference in New Issue
Block a user