diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index ab64a05f2b3ee..dd04719451e75 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -43,6 +43,8 @@ var arm64Jump = map[string]bool{ "CBNZ": true, "CBNZW": true, "JMP": true, + "TBNZ": true, + "TBZ": true, } func jumpArm64(word string) bool { diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 350314d824764..e83cd7286d216 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -390,6 +390,18 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) { } break } + if p.arch.Family == sys.ARM64 { + // Special 3-operand jumps. + // a[0] must be immediate constant; a[1] is a register. + if a[0].Type != obj.TYPE_CONST { + p.errorf("%s: expected immediate constant; found %s", op, obj.Dconv(prog, &a[0])) + return + } + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + target = &a[2] + break + } fallthrough default: diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 8d501965e928e..39859d980a14f 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -257,6 +257,8 @@ again: B foo(SB) // JMP foo(SB) BL foo(SB) // CALL foo(SB) BEQ 2(PC) + TBZ $1, R1, 2(PC) + TBNZ $2, R2, 2(PC) JMP foo(SB) CALL foo(SB)