Revert 95130.
[oota-llvm.git] / lib / Target / ARM / ARMExpandPseudoInsts.cpp
1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that expand pseudo instructions into target
11 // instructions to allow proper scheduling, if-conversion, and other late
12 // optimizations. This pass should be run after register allocation but before
13 // post- regalloc scheduling pass.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #define DEBUG_TYPE "arm-pseudo"
18 #include "ARM.h"
19 #include "ARMBaseInstrInfo.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22
23 using namespace llvm;
24
25 namespace {
26   class ARMExpandPseudo : public MachineFunctionPass {
27   public:
28     static char ID;
29     ARMExpandPseudo() : MachineFunctionPass(&ID) {}
30
31     const TargetInstrInfo *TII;
32
33     virtual bool runOnMachineFunction(MachineFunction &Fn);
34
35     virtual const char *getPassName() const {
36       return "ARM pseudo instruction expansion pass";
37     }
38
39   private:
40     bool ExpandMBB(MachineBasicBlock &MBB);
41   };
42   char ARMExpandPseudo::ID = 0;
43 }
44
45 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
46   bool Modified = false;
47
48   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
49   while (MBBI != E) {
50     MachineInstr &MI = *MBBI;
51     MachineBasicBlock::iterator NMBBI = llvm::next(MBBI);
52
53     unsigned Opcode = MI.getOpcode();
54     switch (Opcode) {
55     default: break;
56     case ARM::tLDRpci_pic: 
57     case ARM::t2LDRpci_pic: {
58       unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
59         ? ARM::tLDRpci : ARM::t2LDRpci;
60       unsigned DstReg = MI.getOperand(0).getReg();
61       if (!MI.getOperand(0).isDead()) {
62         MachineInstr *NewMI =
63           AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
64                                  TII->get(NewLdOpc), DstReg)
65                          .addOperand(MI.getOperand(1)));
66         NewMI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
67         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPICADD))
68           .addReg(DstReg, getDefRegState(true))
69           .addReg(DstReg)
70           .addOperand(MI.getOperand(2));
71       }
72       MI.eraseFromParent();
73       Modified = true;
74       break;
75     }
76     case ARM::t2MOVi32imm: {
77       unsigned DstReg = MI.getOperand(0).getReg();
78       if (!MI.getOperand(0).isDead()) {
79         const MachineOperand &MO = MI.getOperand(1);
80         MachineInstrBuilder LO16, HI16;
81
82         LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
83                        DstReg);
84         HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
85           .addReg(DstReg, getDefRegState(true)).addReg(DstReg);
86
87         if (MO.isImm()) {
88           unsigned Imm = MO.getImm();
89           unsigned Lo16 = Imm & 0xffff;
90           unsigned Hi16 = (Imm >> 16) & 0xffff;
91           LO16 = LO16.addImm(Lo16);
92           HI16 = HI16.addImm(Hi16);
93         } else {
94           GlobalValue *GV = MO.getGlobal();
95           unsigned TF = MO.getTargetFlags();
96           LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
97           HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
98           // FIXME: What's about memoperands?
99         }
100         AddDefaultPred(LO16);
101         AddDefaultPred(HI16);
102       }
103       MI.eraseFromParent();
104       Modified = true;
105     }
106     // FIXME: expand t2MOVi32imm
107     }
108     MBBI = NMBBI;
109   }
110
111   return Modified;
112 }
113
114 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
115   TII = MF.getTarget().getInstrInfo();
116
117   bool Modified = false;
118   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
119        ++MFI)
120     Modified |= ExpandMBB(*MFI);
121   return Modified;
122 }
123
124 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
125 /// expansion pass.
126 FunctionPass *llvm::createARMExpandPseudoPass() {
127   return new ARMExpandPseudo();
128 }