OLD | NEW |
1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===// | 1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file contains a pass that expands pseudo instructions into target | 10 // This file contains a pass that expands pseudo instructions into target |
11 // instructions to allow proper scheduling, if-conversion, and other late | 11 // instructions to allow proper scheduling, if-conversion, and other late |
12 // optimizations. This pass should be run after register allocation but before | 12 // optimizations. This pass should be run after register allocation but before |
13 // the post-regalloc scheduling pass. | 13 // the post-regalloc scheduling pass. |
14 // | 14 // |
15 //===----------------------------------------------------------------------===// | 15 //===----------------------------------------------------------------------===// |
16 | 16 |
17 #include "ARM.h" | 17 #include "ARM.h" |
18 #include "ARMBaseInstrInfo.h" | 18 #include "ARMBaseInstrInfo.h" |
19 #include "ARMBaseRegisterInfo.h" | 19 #include "ARMBaseRegisterInfo.h" |
20 #include "ARMConstantPoolValue.h" | 20 #include "ARMConstantPoolValue.h" |
21 #include "ARMMachineFunctionInfo.h" | 21 #include "ARMMachineFunctionInfo.h" |
22 #include "MCTargetDesc/ARMAddressingModes.h" | 22 #include "MCTargetDesc/ARMAddressingModes.h" |
23 #include "llvm/CodeGen/MachineFrameInfo.h" | 23 #include "llvm/CodeGen/MachineFrameInfo.h" |
24 #include "llvm/CodeGen/MachineFunctionPass.h" | 24 #include "llvm/CodeGen/MachineFunctionPass.h" |
25 #include "llvm/CodeGen/MachineInstrBundle.h" | 25 #include "llvm/CodeGen/MachineInstrBundle.h" |
26 #include "llvm/CodeGen/MachineInstrBuilder.h" | 26 #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 27 #include "llvm/Target/TargetOptions.h" // @LOCALMOD for llvm::TLSUseCall |
27 #include "llvm/IR/GlobalValue.h" | 28 #include "llvm/IR/GlobalValue.h" |
28 #include "llvm/Support/CommandLine.h" | 29 #include "llvm/Support/CommandLine.h" |
29 #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove! | 30 #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove! |
30 #include "llvm/Target/TargetFrameLowering.h" | 31 #include "llvm/Target/TargetFrameLowering.h" |
31 #include "llvm/Target/TargetRegisterInfo.h" | 32 #include "llvm/Target/TargetRegisterInfo.h" |
32 using namespace llvm; | 33 using namespace llvm; |
33 | 34 |
34 #define DEBUG_TYPE "arm-pseudo" | 35 #define DEBUG_TYPE "arm-pseudo" |
35 | 36 |
36 static cl::opt<bool> | 37 static cl::opt<bool> |
37 VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, | 38 VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, |
38 cl::desc("Verify machine code after expanding ARM pseudos")); | 39 cl::desc("Verify machine code after expanding ARM pseudos")); |
39 | 40 |
40 namespace { | 41 namespace { |
41 class ARMExpandPseudo : public MachineFunctionPass { | 42 class ARMExpandPseudo : public MachineFunctionPass { |
42 public: | 43 public: |
43 static char ID; | 44 static char ID; |
44 ARMExpandPseudo() : MachineFunctionPass(ID) {} | 45 ARMExpandPseudo() : MachineFunctionPass(ID) {} |
45 | 46 |
46 const ARMBaseInstrInfo *TII; | 47 const ARMBaseInstrInfo *TII; |
47 const TargetRegisterInfo *TRI; | 48 const TargetRegisterInfo *TRI; |
48 const ARMSubtarget *STI; | 49 const ARMSubtarget *STI; |
49 ARMFunctionInfo *AFI; | 50 ARMFunctionInfo *AFI; |
| 51 bool IsRelocPIC; // @LOCALMOD |
50 | 52 |
51 bool runOnMachineFunction(MachineFunction &Fn) override; | 53 bool runOnMachineFunction(MachineFunction &Fn) override; |
52 | 54 |
53 const char *getPassName() const override { | 55 const char *getPassName() const override { |
54 return "ARM pseudo instruction expansion pass"; | 56 return "ARM pseudo instruction expansion pass"; |
55 } | 57 } |
56 | 58 |
57 private: | 59 private: |
58 void TransferImpOps(MachineInstr &OldMI, | 60 void TransferImpOps(MachineInstr &OldMI, |
59 MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI); | 61 MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI); |
60 bool ExpandMI(MachineBasicBlock &MBB, | 62 bool ExpandMI(MachineBasicBlock &MBB, |
61 MachineBasicBlock::iterator MBBI); | 63 MachineBasicBlock::iterator MBBI); |
62 bool ExpandMBB(MachineBasicBlock &MBB); | 64 bool ExpandMBB(MachineBasicBlock &MBB); |
63 void ExpandVLD(MachineBasicBlock::iterator &MBBI); | 65 void ExpandVLD(MachineBasicBlock::iterator &MBBI); |
64 void ExpandVST(MachineBasicBlock::iterator &MBBI); | 66 void ExpandVST(MachineBasicBlock::iterator &MBBI); |
65 void ExpandLaneOp(MachineBasicBlock::iterator &MBBI); | 67 void ExpandLaneOp(MachineBasicBlock::iterator &MBBI); |
66 void ExpandVTBL(MachineBasicBlock::iterator &MBBI, | 68 void ExpandVTBL(MachineBasicBlock::iterator &MBBI, |
67 unsigned Opc, bool IsExt); | 69 unsigned Opc, bool IsExt); |
68 void ExpandMOV32BitImm(MachineBasicBlock &MBB, | 70 void ExpandMOV32BitImm(MachineBasicBlock &MBB, |
69 MachineBasicBlock::iterator &MBBI); | 71 MachineBasicBlock::iterator &MBBI); |
| 72 // @LOCALMOD-BEGIN |
| 73 void AddPICADD_MOVi16_PICID(MachineInstr &MI, |
| 74 MachineBasicBlock &MBB, |
| 75 MachineBasicBlock::iterator &MBBI, |
| 76 bool NotThumb, |
| 77 unsigned PredReg, ARMCC::CondCodes Pred, |
| 78 unsigned DstReg, bool DstIsDead, |
| 79 MachineInstrBuilder &LO16, |
| 80 MachineInstrBuilder &HI16); |
| 81 // @LOCALMOD-END |
70 }; | 82 }; |
71 char ARMExpandPseudo::ID = 0; | 83 char ARMExpandPseudo::ID = 0; |
72 } | 84 } |
73 | 85 |
74 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to | 86 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to |
75 /// the instructions created from the expansion. | 87 /// the instructions created from the expansion. |
76 void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI, | 88 void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI, |
77 MachineInstrBuilder &UseMI, | 89 MachineInstrBuilder &UseMI, |
78 MachineInstrBuilder &DefMI) { | 90 MachineInstrBuilder &DefMI) { |
79 const MCInstrDesc &Desc = OldMI.getDesc(); | 91 const MCInstrDesc &Desc = OldMI.getDesc(); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 else if (!SrcIsUndef) | 498 else if (!SrcIsUndef) |
487 MIB.addReg(SrcReg, RegState::Implicit); // Add implicit uses for src reg. | 499 MIB.addReg(SrcReg, RegState::Implicit); // Add implicit uses for src reg. |
488 TransferImpOps(MI, MIB, MIB); | 500 TransferImpOps(MI, MIB, MIB); |
489 | 501 |
490 // Transfer memoperands. | 502 // Transfer memoperands. |
491 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 503 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
492 | 504 |
493 MI.eraseFromParent(); | 505 MI.eraseFromParent(); |
494 } | 506 } |
495 | 507 |
| 508 // @LOCALMOD-BEGIN |
| 509 // AddPICADD_MOVi16_PICID - Inserts a PICADD into the given basic block, |
| 510 // and adds the PC label ID (of the PICADD) as an operand of the LO16 / HI16 |
| 511 // MOVs. The ID operand will follow the "Immediate" operand (assumes that |
| 512 // operand is already added). |
| 513 void ARMExpandPseudo::AddPICADD_MOVi16_PICID(MachineInstr &MI, |
| 514 MachineBasicBlock &MBB, |
| 515 MachineBasicBlock::iterator &MBBI, |
| 516 bool NotThumb, |
| 517 unsigned PredReg, ARMCC::CondCodes Pred, |
| 518 unsigned DstReg, bool DstIsDead, |
| 519 MachineInstrBuilder &LO16, |
| 520 MachineInstrBuilder &HI16) { |
| 521 // Throw in a PICADD, and tack on the PC label ID to the MOVT/MOVWs |
| 522 MachineFunction &MF = *MI.getParent()->getParent(); |
| 523 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 524 |
| 525 // Make a unique ID for this PC by pulling from pool of constPoolIDs |
| 526 unsigned PC_ID = AFI->createPICLabelUId(); |
| 527 MachineInstrBuilder PicADD = |
| 528 BuildMI(MBB, MBBI, MI.getDebugLoc(), |
| 529 TII->get(NotThumb ? ARM::PICADD : ARM::tPICADD)) |
| 530 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) |
| 531 .addReg(DstReg) |
| 532 .addImm(PC_ID) |
| 533 .addImm(Pred) |
| 534 .addReg(PredReg); |
| 535 (void)PicADD; // squelch unused warning. |
| 536 |
| 537 // Add the PC label ID after what would have been an absolute address. |
| 538 LO16 = LO16.addImm(PC_ID); |
| 539 HI16 = HI16.addImm(PC_ID); |
| 540 } |
| 541 // @LOCALMOD-END |
| 542 |
496 /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ | 543 /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ |
497 /// register operands to real instructions with D register operands. | 544 /// register operands to real instructions with D register operands. |
498 void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) { | 545 void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) { |
499 MachineInstr &MI = *MBBI; | 546 MachineInstr &MI = *MBBI; |
500 MachineBasicBlock &MBB = *MI.getParent(); | 547 MachineBasicBlock &MBB = *MI.getParent(); |
501 | 548 |
502 const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode()); | 549 const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode()); |
503 assert(TableEntry && "NEONLdStTable lookup failed"); | 550 assert(TableEntry && "NEONLdStTable lookup failed"); |
504 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing; | 551 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing; |
505 unsigned NumRegs = TableEntry->NumRegs; | 552 unsigned NumRegs = TableEntry->NumRegs; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 730 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
684 LO16.addImm(Pred).addReg(PredReg).addReg(0); | 731 LO16.addImm(Pred).addReg(PredReg).addReg(0); |
685 HI16.addImm(Pred).addReg(PredReg).addReg(0); | 732 HI16.addImm(Pred).addReg(PredReg).addReg(0); |
686 TransferImpOps(MI, LO16, HI16); | 733 TransferImpOps(MI, LO16, HI16); |
687 MI.eraseFromParent(); | 734 MI.eraseFromParent(); |
688 return; | 735 return; |
689 } | 736 } |
690 | 737 |
691 unsigned LO16Opc = 0; | 738 unsigned LO16Opc = 0; |
692 unsigned HI16Opc = 0; | 739 unsigned HI16Opc = 0; |
693 if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) { | 740 // @LOCALMOD |
| 741 bool isThumb2 = (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm); |
| 742 if (isThumb2) { |
694 LO16Opc = ARM::t2MOVi16; | 743 LO16Opc = ARM::t2MOVi16; |
695 HI16Opc = ARM::t2MOVTi16; | 744 HI16Opc = ARM::t2MOVTi16; |
696 } else { | 745 } else { |
697 LO16Opc = ARM::MOVi16; | 746 LO16Opc = ARM::MOVi16; |
698 HI16Opc = ARM::MOVTi16; | 747 HI16Opc = ARM::MOVTi16; |
699 } | 748 } |
700 | 749 |
| 750 // @LOCALMOD-BEGIN |
| 751 // If constant pools are "disabled" (actually, moved to rodata), then |
| 752 // many addresses (e.g., the addresses of what used to be the "pools") |
| 753 // may not be materialized in a pc-relative manner, because MOVT / MOVW |
| 754 // are used to materialize the addresses. |
| 755 // We need to know if it matters that references are pc-relative |
| 756 // (e.g., to be PIC). |
| 757 // See the comments on MOVi16PIC / MOVTi16PIC for more details. |
| 758 const bool ShouldUseMOV16PIC = !STI->useConstIslands() && IsRelocPIC && |
| 759 (MO.isCPI() || MO.isJTI() || MO.isGlobal()); // TODO check this list. |
| 760 if (ShouldUseMOV16PIC) { |
| 761 if (isThumb2) |
| 762 llvm_unreachable("FIXME: add PIC versions of t2MOVi16"); |
| 763 LO16Opc = ARM::MOVi16PIC; |
| 764 HI16Opc = ARM::MOVTi16PIC; |
| 765 } |
| 766 // @LOCALMOD-END |
| 767 |
701 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg); | 768 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg); |
702 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc)) | 769 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc)) |
703 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) | 770 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) |
704 .addReg(DstReg); | 771 .addReg(DstReg, RegState::Kill); // @LOCALMOD |
705 | 772 |
706 switch (MO.getType()) { | 773 switch (MO.getType()) { |
707 case MachineOperand::MO_Immediate: { | 774 case MachineOperand::MO_Immediate: { |
708 unsigned Imm = MO.getImm(); | 775 unsigned Imm = MO.getImm(); |
709 unsigned Lo16 = Imm & 0xffff; | 776 unsigned Lo16 = Imm & 0xffff; |
710 unsigned Hi16 = (Imm >> 16) & 0xffff; | 777 unsigned Hi16 = (Imm >> 16) & 0xffff; |
711 LO16 = LO16.addImm(Lo16); | 778 LO16 = LO16.addImm(Lo16); |
712 HI16 = HI16.addImm(Hi16); | 779 HI16 = HI16.addImm(Hi16); |
713 break; | 780 break; |
714 } | 781 } |
715 case MachineOperand::MO_ExternalSymbol: { | 782 case MachineOperand::MO_ExternalSymbol: { |
716 const char *ES = MO.getSymbolName(); | 783 const char *ES = MO.getSymbolName(); |
717 unsigned TF = MO.getTargetFlags(); | 784 unsigned TF = MO.getTargetFlags(); |
718 LO16 = LO16.addExternalSymbol(ES, TF | ARMII::MO_LO16); | 785 LO16 = LO16.addExternalSymbol(ES, TF | ARMII::MO_LO16); |
719 HI16 = HI16.addExternalSymbol(ES, TF | ARMII::MO_HI16); | 786 HI16 = HI16.addExternalSymbol(ES, TF | ARMII::MO_HI16); |
720 break; | 787 break; |
721 } | 788 } |
722 default: { | 789 default: { |
| 790 if (MO.isGlobal()) { // @LOCALMOD |
723 const GlobalValue *GV = MO.getGlobal(); | 791 const GlobalValue *GV = MO.getGlobal(); |
724 unsigned TF = MO.getTargetFlags(); | 792 unsigned TF = MO.getTargetFlags(); |
725 LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); | 793 LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); |
726 HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); | 794 HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); |
| 795 // @LOCALMOD-START - support for jumptable addresses and CPI |
| 796 } else if (MO.isCPI()) { |
| 797 int i = MO.getIndex(); |
| 798 unsigned TF = MO.getTargetFlags(); |
| 799 LO16 = LO16.addConstantPoolIndex(i, MO.getOffset(), TF|ARMII::MO_LO16); |
| 800 HI16 = HI16.addConstantPoolIndex(i, MO.getOffset(), TF|ARMII::MO_HI16); |
| 801 } else if (MO.isJTI()){ |
| 802 unsigned TF = MO.getTargetFlags(); |
| 803 LO16 = LO16.addJumpTableIndex(MO.getIndex(), TF | ARMII::MO_LO16); |
| 804 HI16 = HI16.addJumpTableIndex(MO.getIndex(), TF | ARMII::MO_HI16); |
| 805 } else { |
| 806 assert (0 && "unexpected operand"); |
| 807 } |
| 808 // @LOCALMOD-END |
727 break; | 809 break; |
728 } | 810 } |
729 } | 811 } |
730 | 812 |
| 813 // @LOCALMOD-BEGIN |
| 814 if (ShouldUseMOV16PIC) { |
| 815 AddPICADD_MOVi16_PICID(MI, MBB, MBBI, !isThumb2, |
| 816 PredReg, Pred, DstReg, DstIsDead, LO16, HI16); |
| 817 } |
| 818 // @LOCALMOD-END |
731 LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 819 LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
732 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 820 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
733 LO16.addImm(Pred).addReg(PredReg); | 821 LO16.addImm(Pred).addReg(PredReg); |
734 HI16.addImm(Pred).addReg(PredReg); | 822 HI16.addImm(Pred).addReg(PredReg); |
735 | 823 |
736 if (RequiresBundling) | 824 if (RequiresBundling) |
737 finalizeBundle(MBB, &*LO16, &*MBBI); | 825 finalizeBundle(MBB, &*LO16, &*MBBI); |
738 | 826 |
739 TransferImpOps(MI, LO16, HI16); | 827 TransferImpOps(MI, LO16, HI16); |
740 MI.eraseFromParent(); | 828 MI.eraseFromParent(); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 MI.getOperand(0).getReg()) | 1008 MI.getOperand(0).getReg()) |
921 .addOperand(MI.getOperand(1)) | 1009 .addOperand(MI.getOperand(1)) |
922 .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))) | 1010 .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))) |
923 .addReg(0); | 1011 .addReg(0); |
924 TransferImpOps(MI, MIB, MIB); | 1012 TransferImpOps(MI, MIB, MIB); |
925 MI.eraseFromParent(); | 1013 MI.eraseFromParent(); |
926 return true; | 1014 return true; |
927 } | 1015 } |
928 case ARM::tTPsoft: | 1016 case ARM::tTPsoft: |
929 case ARM::TPsoft: { | 1017 case ARM::TPsoft: { |
| 1018 // @LOCALMOD-BEGIN |
| 1019 if (!STI->isTargetNaCl() || llvm::TLSUseCall) { |
930 MachineInstrBuilder MIB; | 1020 MachineInstrBuilder MIB; |
931 if (Opcode == ARM::tTPsoft) | 1021 if (Opcode == ARM::tTPsoft) |
932 MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), | 1022 MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), |
933 TII->get( ARM::tBL)) | 1023 TII->get( ARM::tBL)) |
934 .addImm((unsigned)ARMCC::AL).addReg(0) | 1024 .addImm((unsigned)ARMCC::AL).addReg(0) |
935 .addExternalSymbol("__aeabi_read_tp", 0); | 1025 .addExternalSymbol("__aeabi_read_tp", 0); |
936 else | 1026 else |
937 MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), | 1027 MIB = BuildMI_NoImp(MBB, MBBI, MI.getDebugLoc(), // @LOCALMOD |
938 TII->get( ARM::BL)) | 1028 TII->get( ARM::BL)) |
939 .addExternalSymbol("__aeabi_read_tp", 0); | 1029 .addExternalSymbol("__aeabi_read_tp", 0); |
940 | 1030 |
941 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 1031 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
942 TransferImpOps(MI, MIB, MIB); | 1032 TransferImpOps(MI, MIB, MIB); |
| 1033 } else { |
| 1034 // Inline version for native client. |
| 1035 // See native_client/src/untrusted/nacl/aeabi_read_tp.S |
| 1036 // .nexe builds use this version, while irt builds use a call to |
| 1037 // __aeabi_read_tp. |
| 1038 // ldr r0, [r9, #0] |
| 1039 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), |
| 1040 TII->get(ARM::LDRi12), ARM::R0) |
| 1041 .addReg(ARM::R9) |
| 1042 .addImm(0)); |
| 1043 } |
| 1044 // @LOCALMOD-END |
943 MI.eraseFromParent(); | 1045 MI.eraseFromParent(); |
944 return true; | 1046 return true; |
945 } | 1047 } |
946 case ARM::tLDRpci_pic: | 1048 case ARM::tLDRpci_pic: |
947 case ARM::t2LDRpci_pic: { | 1049 case ARM::t2LDRpci_pic: { |
948 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) | 1050 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) |
949 ? ARM::tLDRpci : ARM::t2LDRpci; | 1051 ? ARM::tLDRpci : ARM::t2LDRpci; |
950 unsigned DstReg = MI.getOperand(0).getReg(); | 1052 unsigned DstReg = MI.getOperand(0).getReg(); |
951 bool DstIsDead = MI.getOperand(0).isDead(); | 1053 bool DstIsDead = MI.getOperand(0).isDead(); |
952 MachineInstrBuilder MIB1 = | 1054 MachineInstrBuilder MIB1 = |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 case ARM::VST4LNd32Pseudo_UPD: | 1420 case ARM::VST4LNd32Pseudo_UPD: |
1319 case ARM::VST4LNq16Pseudo_UPD: | 1421 case ARM::VST4LNq16Pseudo_UPD: |
1320 case ARM::VST4LNq32Pseudo_UPD: | 1422 case ARM::VST4LNq32Pseudo_UPD: |
1321 ExpandLaneOp(MBBI); | 1423 ExpandLaneOp(MBBI); |
1322 return true; | 1424 return true; |
1323 | 1425 |
1324 case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true; | 1426 case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true; |
1325 case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true; | 1427 case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true; |
1326 case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true; | 1428 case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true; |
1327 case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true; | 1429 case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true; |
| 1430 |
| 1431 // @LOCALMOD-BEGIN |
| 1432 case ARM::ARMeh_return: { |
| 1433 // This pseudo instruction is generated as part of the lowering of |
| 1434 // ISD::EH_RETURN (c.f. ARMISelLowering.cpp) |
| 1435 // we convert it to a stack increment by OffsetReg and |
| 1436 // indirect jump to TargetReg |
| 1437 unsigned PredReg = 0; |
| 1438 ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg); |
| 1439 unsigned OffsetReg = MI.getOperand(0).getReg(); |
| 1440 unsigned TargetReg = MI.getOperand(1).getReg(); |
| 1441 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ADDrr), ARM::SP) |
| 1442 .addReg(OffsetReg) |
| 1443 .addReg(ARM::SP) |
| 1444 .addImm(Pred) |
| 1445 .addReg(PredReg) |
| 1446 .addReg(0); |
| 1447 |
| 1448 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BX)) |
| 1449 .addReg(TargetReg); |
| 1450 MI.eraseFromParent(); |
| 1451 return true; |
| 1452 } |
| 1453 case ARM::MOVGOTAddr : { |
| 1454 // Expand the pseudo-inst that requests for the GOT address |
| 1455 // to be materialized into a register. We use MOVW/MOVT for this. |
| 1456 // See ARMISelLowering.cpp for a comment on the strategy. |
| 1457 unsigned PredReg = 0; |
| 1458 ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg); |
| 1459 unsigned DstReg = MI.getOperand(0).getReg(); |
| 1460 bool DstIsDead = MI.getOperand(0).isDead(); |
| 1461 MachineInstrBuilder LO16, HI16; |
| 1462 |
| 1463 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), |
| 1464 TII->get(ARM::MOVi16PIC), |
| 1465 DstReg) |
| 1466 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", ARMII::MO_LO16); |
| 1467 |
| 1468 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), |
| 1469 TII->get(ARM::MOVTi16PIC)) |
| 1470 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) |
| 1471 .addReg(DstReg) |
| 1472 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", ARMII::MO_HI16); |
| 1473 |
| 1474 AddPICADD_MOVi16_PICID(MI, MBB, MBBI, true, |
| 1475 PredReg, Pred, DstReg, DstIsDead, LO16, HI16); |
| 1476 |
| 1477 (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
| 1478 (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
| 1479 LO16.addImm(Pred).addReg(PredReg); |
| 1480 HI16.addImm(Pred).addReg(PredReg); |
| 1481 TransferImpOps(MI, LO16, HI16); |
| 1482 MI.eraseFromParent(); |
| 1483 return true; |
| 1484 } |
| 1485 // @LOCALMOD-END |
1328 } | 1486 } |
1329 } | 1487 } |
1330 | 1488 |
1331 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { | 1489 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { |
1332 bool Modified = false; | 1490 bool Modified = false; |
1333 | 1491 |
1334 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); | 1492 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); |
1335 while (MBBI != E) { | 1493 while (MBBI != E) { |
1336 MachineBasicBlock::iterator NMBBI = std::next(MBBI); | 1494 MachineBasicBlock::iterator NMBBI = std::next(MBBI); |
1337 Modified |= ExpandMI(MBB, MBBI); | 1495 Modified |= ExpandMI(MBB, MBBI); |
1338 MBBI = NMBBI; | 1496 MBBI = NMBBI; |
1339 } | 1497 } |
1340 | 1498 |
1341 return Modified; | 1499 return Modified; |
1342 } | 1500 } |
1343 | 1501 |
1344 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { | 1502 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { |
1345 const TargetMachine &TM = MF.getTarget(); | 1503 const TargetMachine &TM = MF.getTarget(); |
1346 TII = static_cast<const ARMBaseInstrInfo *>( | 1504 TII = static_cast<const ARMBaseInstrInfo *>( |
1347 TM.getSubtargetImpl()->getInstrInfo()); | 1505 TM.getSubtargetImpl()->getInstrInfo()); |
1348 TRI = TM.getSubtargetImpl()->getRegisterInfo(); | 1506 TRI = TM.getSubtargetImpl()->getRegisterInfo(); |
1349 STI = &TM.getSubtarget<ARMSubtarget>(); | 1507 STI = &TM.getSubtarget<ARMSubtarget>(); |
1350 AFI = MF.getInfo<ARMFunctionInfo>(); | 1508 AFI = MF.getInfo<ARMFunctionInfo>(); |
| 1509 IsRelocPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_; |
1351 | 1510 |
1352 bool Modified = false; | 1511 bool Modified = false; |
1353 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; | 1512 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; |
1354 ++MFI) | 1513 ++MFI) |
1355 Modified |= ExpandMBB(*MFI); | 1514 Modified |= ExpandMBB(*MFI); |
1356 if (VerifyARMPseudo) | 1515 if (VerifyARMPseudo) |
1357 MF.verify(this, "After expanding ARM pseudo instructions."); | 1516 MF.verify(this, "After expanding ARM pseudo instructions."); |
1358 return Modified; | 1517 return Modified; |
1359 } | 1518 } |
1360 | 1519 |
1361 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction | 1520 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction |
1362 /// expansion pass. | 1521 /// expansion pass. |
1363 FunctionPass *llvm::createARMExpandPseudoPass() { | 1522 FunctionPass *llvm::createARMExpandPseudoPass() { |
1364 return new ARMExpandPseudo(); | 1523 return new ARMExpandPseudo(); |
1365 } | 1524 } |
OLD | NEW |