feat(asm): encode indirect JMP and CALL on all four architectures

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-19 19:17:07 +02:00
parent 96e81cc98d
commit 23c001be51
24 changed files with 494 additions and 27 deletions
+31
View File
@@ -8,6 +8,7 @@ import (
"testing"
"sourcedock.dev/petrbalvin/gasm-devkit/arch"
"sourcedock.dev/petrbalvin/gasm-devkit/ast"
"sourcedock.dev/petrbalvin/gasm-devkit/parser"
)
@@ -495,3 +496,33 @@ TEXT ·f(SB), NOSPLIT, $0
t.Fatalf("amd64 must not be flagged: %+v", diags)
}
}
// TestHasIndirectBranchShape checks that a JMP/CALL through a register or
// memory suppresses reachability analysis, while a same-named label does not.
func TestHasIndirectBranchShape(t *testing.T) {
tab := arch.ForArch(arch.AMD64)
indirect := `TEXT ·f(SB), NOSPLIT, $0
JMP AX
RET
`
f, errs := parser.Parse("t_amd64.s", indirect)
if len(errs) > 0 {
t.Fatalf("parse: %v", errs)
}
if !hasIndirectBranch(f.Decls[0].(*ast.Text), tab) {
t.Error("JMP AX: indirect branch not detected")
}
label := `TEXT ·f(SB), NOSPLIT, $0
loop:
JMP loop
RET
`
f, errs = parser.Parse("t_amd64.s", label)
if len(errs) > 0 {
t.Fatalf("parse: %v", errs)
}
if hasIndirectBranch(f.Decls[0].(*ast.Text), tab) {
t.Error("JMP loop: label treated as an indirect branch")
}
}