feat(asm): the immediate multiply and arm64 indirect branches GOROOT writes
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -637,6 +637,20 @@ func encodeARM64Branch(mnem string, ops []*ast.Operand, pc int, offsets map[stri
|
||||
return a64wordLE(a64UncondBranch(opc, uint32(rn), 0)), nil
|
||||
}
|
||||
|
||||
// The bare spelling BL R9 is the same indirect branch: the parser reads
|
||||
// a bare identifier as a symbol, and one named for a register is an
|
||||
// indirect branch through it, which the toolchain accepts alongside the
|
||||
// parenthesised form (BL (R3) and BL R3 both encode BLR R3).
|
||||
if op.Addr.Sym != nil && op.Addr.Sym.Pseudo == "" && op.Addr.Base == "" && op.Addr.Index == "" {
|
||||
if rn := arm64RegNum(op.Addr.Sym.Name); rn >= 0 {
|
||||
opc := uint32(0) // BR
|
||||
if link {
|
||||
opc = 1 // BLR
|
||||
}
|
||||
return a64wordLE(a64UncondBranch(opc, uint32(rn), 0)), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Symbol reference: BL sym(SB), or B sym(SB) for a tail call, against a
|
||||
// relocation (R_CALLARM64 either way).
|
||||
if op.Addr.Sym != nil && op.Addr.Sym.Pseudo == "SB" {
|
||||
@@ -1454,6 +1468,15 @@ func encodeARM64Mov(instr *ast.Instr, mnem string, wb string, fi arm64FrameInfo,
|
||||
}
|
||||
return encodeARM64SBAddr(src.Imm.Sym, rd, relocs), nil
|
||||
}
|
||||
// Immediate → memory: only storing zero is encodable (the ZR
|
||||
// register); the toolchain rejects any other immediate-to-memory
|
||||
// combination ("illegal combination").
|
||||
if isMemOperand(dst) {
|
||||
if arm64Imm64(src) != 0 {
|
||||
return nil, fmt.Errorf("%s: illegal combination: an immediate store must be zero", mnem)
|
||||
}
|
||||
return encodeARM64MemOp(mnem, dst, 31, false, fi, "")
|
||||
}
|
||||
rd := arm64RegNum(operandRegName(dst))
|
||||
if rd < 0 {
|
||||
return nil, fmt.Errorf("%s $imm: invalid destination register", mnem)
|
||||
|
||||
Reference in New Issue
Block a user