| Index: lib/Target/ARM/ARMExpandPseudoInsts.cpp
|
| diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
|
| index 2d805185e6cdd19a5d54dcc74a308fafe6dfa042..fd5de81a8ddfd626e7dc926d6040130821711112 100644
|
| --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
|
| +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
|
| @@ -24,6 +24,7 @@
|
| #include "llvm/CodeGen/MachineFunctionPass.h"
|
| #include "llvm/CodeGen/MachineInstrBundle.h"
|
| #include "llvm/CodeGen/MachineInstrBuilder.h"
|
| +#include "llvm/Target/TargetOptions.h" // @LOCALMOD for llvm::TLSUseCall
|
| #include "llvm/IR/GlobalValue.h"
|
| #include "llvm/Support/CommandLine.h"
|
| #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove!
|
| @@ -47,6 +48,7 @@ namespace {
|
| const TargetRegisterInfo *TRI;
|
| const ARMSubtarget *STI;
|
| ARMFunctionInfo *AFI;
|
| + bool IsRelocPIC; // @LOCALMOD
|
|
|
| bool runOnMachineFunction(MachineFunction &Fn) override;
|
|
|
| @@ -67,6 +69,16 @@ namespace {
|
| unsigned Opc, bool IsExt);
|
| void ExpandMOV32BitImm(MachineBasicBlock &MBB,
|
| MachineBasicBlock::iterator &MBBI);
|
| + // @LOCALMOD-BEGIN
|
| + void AddPICADD_MOVi16_PICID(MachineInstr &MI,
|
| + MachineBasicBlock &MBB,
|
| + MachineBasicBlock::iterator &MBBI,
|
| + bool NotThumb,
|
| + unsigned PredReg, ARMCC::CondCodes Pred,
|
| + unsigned DstReg, bool DstIsDead,
|
| + MachineInstrBuilder &LO16,
|
| + MachineInstrBuilder &HI16);
|
| + // @LOCALMOD-END
|
| };
|
| char ARMExpandPseudo::ID = 0;
|
| }
|
| @@ -493,6 +505,41 @@ void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
|
| MI.eraseFromParent();
|
| }
|
|
|
| +// @LOCALMOD-BEGIN
|
| +// AddPICADD_MOVi16_PICID - Inserts a PICADD into the given basic block,
|
| +// and adds the PC label ID (of the PICADD) as an operand of the LO16 / HI16
|
| +// MOVs. The ID operand will follow the "Immediate" operand (assumes that
|
| +// operand is already added).
|
| +void ARMExpandPseudo::AddPICADD_MOVi16_PICID(MachineInstr &MI,
|
| + MachineBasicBlock &MBB,
|
| + MachineBasicBlock::iterator &MBBI,
|
| + bool NotThumb,
|
| + unsigned PredReg, ARMCC::CondCodes Pred,
|
| + unsigned DstReg, bool DstIsDead,
|
| + MachineInstrBuilder &LO16,
|
| + MachineInstrBuilder &HI16) {
|
| + // Throw in a PICADD, and tack on the PC label ID to the MOVT/MOVWs
|
| + MachineFunction &MF = *MI.getParent()->getParent();
|
| + ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
| +
|
| + // Make a unique ID for this PC by pulling from pool of constPoolIDs
|
| + unsigned PC_ID = AFI->createPICLabelUId();
|
| + MachineInstrBuilder PicADD =
|
| + BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| + TII->get(NotThumb ? ARM::PICADD : ARM::tPICADD))
|
| + .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
|
| + .addReg(DstReg)
|
| + .addImm(PC_ID)
|
| + .addImm(Pred)
|
| + .addReg(PredReg);
|
| + (void)PicADD; // squelch unused warning.
|
| +
|
| + // Add the PC label ID after what would have been an absolute address.
|
| + LO16 = LO16.addImm(PC_ID);
|
| + HI16 = HI16.addImm(PC_ID);
|
| +}
|
| +// @LOCALMOD-END
|
| +
|
| /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
|
| /// register operands to real instructions with D register operands.
|
| void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
|
| @@ -690,7 +737,9 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
|
|
|
| unsigned LO16Opc = 0;
|
| unsigned HI16Opc = 0;
|
| - if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
|
| + // @LOCALMOD
|
| + bool isThumb2 = (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm);
|
| + if (isThumb2) {
|
| LO16Opc = ARM::t2MOVi16;
|
| HI16Opc = ARM::t2MOVTi16;
|
| } else {
|
| @@ -698,10 +747,28 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
|
| HI16Opc = ARM::MOVTi16;
|
| }
|
|
|
| + // @LOCALMOD-BEGIN
|
| + // If constant pools are "disabled" (actually, moved to rodata), then
|
| + // many addresses (e.g., the addresses of what used to be the "pools")
|
| + // may not be materialized in a pc-relative manner, because MOVT / MOVW
|
| + // are used to materialize the addresses.
|
| + // We need to know if it matters that references are pc-relative
|
| + // (e.g., to be PIC).
|
| + // See the comments on MOVi16PIC / MOVTi16PIC for more details.
|
| + const bool ShouldUseMOV16PIC = !STI->useConstIslands() && IsRelocPIC &&
|
| + (MO.isCPI() || MO.isJTI() || MO.isGlobal()); // TODO check this list.
|
| + if (ShouldUseMOV16PIC) {
|
| + if (isThumb2)
|
| + llvm_unreachable("FIXME: add PIC versions of t2MOVi16");
|
| + LO16Opc = ARM::MOVi16PIC;
|
| + HI16Opc = ARM::MOVTi16PIC;
|
| + }
|
| + // @LOCALMOD-END
|
| +
|
| LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
|
| HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
|
| .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
|
| - .addReg(DstReg);
|
| + .addReg(DstReg, RegState::Kill); // @LOCALMOD
|
|
|
| switch (MO.getType()) {
|
| case MachineOperand::MO_Immediate: {
|
| @@ -720,14 +787,35 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
|
| break;
|
| }
|
| default: {
|
| + if (MO.isGlobal()) { // @LOCALMOD
|
| const GlobalValue *GV = MO.getGlobal();
|
| unsigned TF = MO.getTargetFlags();
|
| LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
|
| HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
|
| + // @LOCALMOD-START - support for jumptable addresses and CPI
|
| + } else if (MO.isCPI()) {
|
| + int i = MO.getIndex();
|
| + unsigned TF = MO.getTargetFlags();
|
| + LO16 = LO16.addConstantPoolIndex(i, MO.getOffset(), TF|ARMII::MO_LO16);
|
| + HI16 = HI16.addConstantPoolIndex(i, MO.getOffset(), TF|ARMII::MO_HI16);
|
| + } else if (MO.isJTI()){
|
| + unsigned TF = MO.getTargetFlags();
|
| + LO16 = LO16.addJumpTableIndex(MO.getIndex(), TF | ARMII::MO_LO16);
|
| + HI16 = HI16.addJumpTableIndex(MO.getIndex(), TF | ARMII::MO_HI16);
|
| + } else {
|
| + assert (0 && "unexpected operand");
|
| + }
|
| + // @LOCALMOD-END
|
| break;
|
| }
|
| }
|
|
|
| + // @LOCALMOD-BEGIN
|
| + if (ShouldUseMOV16PIC) {
|
| + AddPICADD_MOVi16_PICID(MI, MBB, MBBI, !isThumb2,
|
| + PredReg, Pred, DstReg, DstIsDead, LO16, HI16);
|
| + }
|
| + // @LOCALMOD-END
|
| LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
| HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
| LO16.addImm(Pred).addReg(PredReg);
|
| @@ -927,6 +1015,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
|
| }
|
| case ARM::tTPsoft:
|
| case ARM::TPsoft: {
|
| + // @LOCALMOD-BEGIN
|
| + if (!STI->isTargetNaCl() || llvm::TLSUseCall) {
|
| MachineInstrBuilder MIB;
|
| if (Opcode == ARM::tTPsoft)
|
| MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| @@ -934,12 +1024,24 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
|
| .addImm((unsigned)ARMCC::AL).addReg(0)
|
| .addExternalSymbol("__aeabi_read_tp", 0);
|
| else
|
| - MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| + MIB = BuildMI_NoImp(MBB, MBBI, MI.getDebugLoc(), // @LOCALMOD
|
| TII->get( ARM::BL))
|
| .addExternalSymbol("__aeabi_read_tp", 0);
|
|
|
| MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
| TransferImpOps(MI, MIB, MIB);
|
| + } else {
|
| + // Inline version for native client.
|
| + // See native_client/src/untrusted/nacl/aeabi_read_tp.S
|
| + // .nexe builds use this version, while irt builds use a call to
|
| + // __aeabi_read_tp.
|
| + // ldr r0, [r9, #0]
|
| + AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| + TII->get(ARM::LDRi12), ARM::R0)
|
| + .addReg(ARM::R9)
|
| + .addImm(0));
|
| + }
|
| + // @LOCALMOD-END
|
| MI.eraseFromParent();
|
| return true;
|
| }
|
| @@ -1325,6 +1427,62 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
|
| case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true;
|
| case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true;
|
| case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true;
|
| +
|
| + // @LOCALMOD-BEGIN
|
| + case ARM::ARMeh_return: {
|
| + // This pseudo instruction is generated as part of the lowering of
|
| + // ISD::EH_RETURN (c.f. ARMISelLowering.cpp)
|
| + // we convert it to a stack increment by OffsetReg and
|
| + // indirect jump to TargetReg
|
| + unsigned PredReg = 0;
|
| + ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
|
| + unsigned OffsetReg = MI.getOperand(0).getReg();
|
| + unsigned TargetReg = MI.getOperand(1).getReg();
|
| + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ADDrr), ARM::SP)
|
| + .addReg(OffsetReg)
|
| + .addReg(ARM::SP)
|
| + .addImm(Pred)
|
| + .addReg(PredReg)
|
| + .addReg(0);
|
| +
|
| + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BX))
|
| + .addReg(TargetReg);
|
| + MI.eraseFromParent();
|
| + return true;
|
| + }
|
| + case ARM::MOVGOTAddr : {
|
| + // Expand the pseudo-inst that requests for the GOT address
|
| + // to be materialized into a register. We use MOVW/MOVT for this.
|
| + // See ARMISelLowering.cpp for a comment on the strategy.
|
| + unsigned PredReg = 0;
|
| + ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
|
| + unsigned DstReg = MI.getOperand(0).getReg();
|
| + bool DstIsDead = MI.getOperand(0).isDead();
|
| + MachineInstrBuilder LO16, HI16;
|
| +
|
| + LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| + TII->get(ARM::MOVi16PIC),
|
| + DstReg)
|
| + .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", ARMII::MO_LO16);
|
| +
|
| + HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
| + TII->get(ARM::MOVTi16PIC))
|
| + .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
|
| + .addReg(DstReg)
|
| + .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", ARMII::MO_HI16);
|
| +
|
| + AddPICADD_MOVi16_PICID(MI, MBB, MBBI, true,
|
| + PredReg, Pred, DstReg, DstIsDead, LO16, HI16);
|
| +
|
| + (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
| + (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
| + LO16.addImm(Pred).addReg(PredReg);
|
| + HI16.addImm(Pred).addReg(PredReg);
|
| + TransferImpOps(MI, LO16, HI16);
|
| + MI.eraseFromParent();
|
| + return true;
|
| + }
|
| + // @LOCALMOD-END
|
| }
|
| }
|
|
|
| @@ -1348,6 +1506,7 @@ bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
|
| TRI = TM.getSubtargetImpl()->getRegisterInfo();
|
| STI = &TM.getSubtarget<ARMSubtarget>();
|
| AFI = MF.getInfo<ARMFunctionInfo>();
|
| + IsRelocPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
|
|
|
| bool Modified = false;
|
| for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
|
|
|