CallOpc = (isDirect || Subtarget->hasV5TOps())
? ARMISD::CALL : ARMISD::CALL_NOLINK;
}
- if (CallOpc == ARMISD::CALL_NOLINK) {
- // On CALL_NOLINK we must move PC to LR
+ if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb()) {
+ // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK
Chain = DAG.getCopyToReg(Chain, ARM::LR,
- DAG.getRegister(ARM::PC, MVT::i32), InFlag);
+ DAG.getNode(ISD::UNDEF, MVT::i32), InFlag);
InFlag = Chain.getValue(1);
}
: I<ops, AddrMode3, Size4Bytes, IndexModeNone, asm, "", pattern>;
class AI4<dag ops, string asm, list<dag> pattern>
: I<ops, AddrMode4, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AIx2<dag ops, string asm, list<dag> pattern>
+ : I<ops, AddrModeNone, Size8Bytes, IndexModeNone, asm, "", pattern>;
class AI1x2<dag ops, string asm, list<dag> pattern>
: I<ops, AddrMode1, Size8Bytes, IndexModeNone, asm, "", pattern>;
[(ARMcall GPR:$dst)]>, Requires<[IsARM, HasV5T]>;
let Uses = [LR] in {
// ARMv4T
- def BX : AI<(ops GPR:$dst, variable_ops),
- "bx $dst",
- [(ARMcall_nolink GPR:$dst)]>;
+ def BX : AIx2<(ops GPR:$dst, variable_ops),
+ "mov lr, pc\n\tbx $dst",
+ [(ARMcall_nolink GPR:$dst)]>;
}
}
def tBLXr : TI<(ops GPR:$dst, variable_ops),
"blx $dst",
[(ARMtcall GPR:$dst)]>, Requires<[HasV5T]>;
- let Uses = [LR] in {
- // ARMv4T
- def tBX : TI<(ops GPR:$dst, variable_ops),
- "bx $dst",
+ // ARMv4T
+ def tBX : TIx2<(ops GPR:$dst, variable_ops),
+ "cpy lr, pc\n\tbx $dst",
[(ARMcall_nolink GPR:$dst)]>;
- }
}
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {