1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
17 #define DEBUG_TYPE "arm-pseudo"
19 #include "ARMBaseInstrInfo.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 class ARMExpandPseudo : public MachineFunctionPass {
29 ARMExpandPseudo() : MachineFunctionPass(&ID) {}
31 const TargetInstrInfo *TII;
33 virtual bool runOnMachineFunction(MachineFunction &Fn);
35 virtual const char *getPassName() const {
36 return "ARM pseudo instruction expansion pass";
40 void TransferImpOps(MachineInstr &OldMI,
41 MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
42 bool ExpandMBB(MachineBasicBlock &MBB);
44 char ARMExpandPseudo::ID = 0;
47 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to
48 /// the instructions created from the expansion.
49 void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
50 MachineInstrBuilder &UseMI,
51 MachineInstrBuilder &DefMI) {
52 const TargetInstrDesc &Desc = OldMI.getDesc();
53 for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
55 const MachineOperand &MO = OldMI.getOperand(i);
56 assert(MO.isReg() && MO.getReg());
58 UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill()));
60 DefMI.addReg(MO.getReg(),
61 getDefRegState(true) | getDeadRegState(MO.isDead()));
65 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
66 bool Modified = false;
68 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
70 MachineInstr &MI = *MBBI;
71 MachineBasicBlock::iterator NMBBI = llvm::next(MBBI);
73 unsigned Opcode = MI.getOpcode();
76 case ARM::tLDRpci_pic:
77 case ARM::t2LDRpci_pic: {
78 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
79 ? ARM::tLDRpci : ARM::t2LDRpci;
80 unsigned DstReg = MI.getOperand(0).getReg();
81 bool DstIsDead = MI.getOperand(0).isDead();
82 MachineInstrBuilder MIB1 =
83 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
84 TII->get(NewLdOpc), DstReg)
85 .addOperand(MI.getOperand(1)));
86 (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
87 MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
88 TII->get(ARM::tPICADD))
89 .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
91 .addOperand(MI.getOperand(2));
92 TransferImpOps(MI, MIB1, MIB2);
98 case ARM::t2MOVi32imm: {
100 ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
101 unsigned DstReg = MI.getOperand(0).getReg();
102 bool DstIsDead = MI.getOperand(0).isDead();
103 const MachineOperand &MO = MI.getOperand(1);
104 MachineInstrBuilder LO16, HI16;
106 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
108 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
109 .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
113 unsigned Imm = MO.getImm();
114 unsigned Lo16 = Imm & 0xffff;
115 unsigned Hi16 = (Imm >> 16) & 0xffff;
116 LO16 = LO16.addImm(Lo16);
117 HI16 = HI16.addImm(Hi16);
119 const GlobalValue *GV = MO.getGlobal();
120 unsigned TF = MO.getTargetFlags();
121 LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
122 HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
124 (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
125 (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
126 LO16.addImm(Pred).addReg(PredReg);
127 HI16.addImm(Pred).addReg(PredReg);
128 TransferImpOps(MI, LO16, HI16);
129 MI.eraseFromParent();
139 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
140 TII = MF.getTarget().getInstrInfo();
142 bool Modified = false;
143 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
145 Modified |= ExpandMBB(*MFI);
149 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
151 FunctionPass *llvm::createARMExpandPseudoPass() {
152 return new ARMExpandPseudo();