1*9880d681SAndroid Build Coastguard Worker //=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // When the compiler is invoked with no small data, for instance, with the -G0
11*9880d681SAndroid Build Coastguard Worker // command line option, then all CONST32_* opcodes should be broken down into
12*9880d681SAndroid Build Coastguard Worker // appropriate LO and HI instructions. This splitting is done by this pass.
13*9880d681SAndroid Build Coastguard Worker // The only reason this is not done in the DAG lowering itself is that there
14*9880d681SAndroid Build Coastguard Worker // is no simple way of getting the register allocator to allot the same hard
15*9880d681SAndroid Build Coastguard Worker // register to the result of LO and HI instructions. This pass is always
16*9880d681SAndroid Build Coastguard Worker // scheduled after register allocation.
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker #include "HexagonMachineFunctionInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "HexagonSubtarget.h"
22*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
23*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetObjectFile.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LatencyPriorityQueue.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAGInstrs.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SchedulerRegistry.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker using namespace llvm;
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "xfer"
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker namespace llvm {
45*9880d681SAndroid Build Coastguard Worker FunctionPass *createHexagonSplitConst32AndConst64();
46*9880d681SAndroid Build Coastguard Worker void initializeHexagonSplitConst32AndConst64Pass(PassRegistry&);
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker namespace {
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
52*9880d681SAndroid Build Coastguard Worker public:
53*9880d681SAndroid Build Coastguard Worker static char ID;
HexagonSplitConst32AndConst64()54*9880d681SAndroid Build Coastguard Worker HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {}
55*9880d681SAndroid Build Coastguard Worker
getPassName() const56*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override {
57*9880d681SAndroid Build Coastguard Worker return "Hexagon Split Const32s and Const64s";
58*9880d681SAndroid Build Coastguard Worker }
59*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &Fn) override;
getRequiredProperties() const60*9880d681SAndroid Build Coastguard Worker MachineFunctionProperties getRequiredProperties() const override {
61*9880d681SAndroid Build Coastguard Worker return MachineFunctionProperties().set(
62*9880d681SAndroid Build Coastguard Worker MachineFunctionProperties::Property::AllVRegsAllocated);
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker };
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker char HexagonSplitConst32AndConst64::ID = 0;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & Fn)70*9880d681SAndroid Build Coastguard Worker bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker const HexagonTargetObjectFile &TLOF =
73*9880d681SAndroid Build Coastguard Worker *static_cast<const HexagonTargetObjectFile *>(
74*9880d681SAndroid Build Coastguard Worker Fn.getTarget().getObjFileLowering());
75*9880d681SAndroid Build Coastguard Worker if (TLOF.isSmallDataEnabled())
76*9880d681SAndroid Build Coastguard Worker return true;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Fn.getSubtarget().getInstrInfo();
79*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker // Loop over all of the basic blocks
82*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
83*9880d681SAndroid Build Coastguard Worker MBBb != MBBe; ++MBBb) {
84*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = &*MBBb;
85*9880d681SAndroid Build Coastguard Worker // Traverse the basic block
86*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MII = MBB->begin();
87*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MIE = MBB->end ();
88*9880d681SAndroid Build Coastguard Worker while (MII != MIE) {
89*9880d681SAndroid Build Coastguard Worker MachineInstr &MI = *MII;
90*9880d681SAndroid Build Coastguard Worker int Opc = MI.getOpcode();
91*9880d681SAndroid Build Coastguard Worker if (Opc == Hexagon::CONST32_Int_Real &&
92*9880d681SAndroid Build Coastguard Worker MI.getOperand(1).isBlockAddress()) {
93*9880d681SAndroid Build Coastguard Worker int DestReg = MI.getOperand(0).getReg();
94*9880d681SAndroid Build Coastguard Worker MachineOperand &Symbol = MI.getOperand(1);
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::LO), DestReg)
97*9880d681SAndroid Build Coastguard Worker .addOperand(Symbol);
98*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::HI), DestReg)
99*9880d681SAndroid Build Coastguard Worker .addOperand(Symbol);
100*9880d681SAndroid Build Coastguard Worker // MBB->erase returns the iterator to the next instruction, which is the
101*9880d681SAndroid Build Coastguard Worker // one we want to process next
102*9880d681SAndroid Build Coastguard Worker MII = MBB->erase(&MI);
103*9880d681SAndroid Build Coastguard Worker continue;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker else if (Opc == Hexagon::CONST32_Int_Real ||
107*9880d681SAndroid Build Coastguard Worker Opc == Hexagon::CONST32_Float_Real) {
108*9880d681SAndroid Build Coastguard Worker int DestReg = MI.getOperand(0).getReg();
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker // We have to convert an FP immediate into its corresponding integer
111*9880d681SAndroid Build Coastguard Worker // representation
112*9880d681SAndroid Build Coastguard Worker int64_t ImmValue;
113*9880d681SAndroid Build Coastguard Worker if (Opc == Hexagon::CONST32_Float_Real) {
114*9880d681SAndroid Build Coastguard Worker APFloat Val = MI.getOperand(1).getFPImm()->getValueAPF();
115*9880d681SAndroid Build Coastguard Worker ImmValue = *Val.bitcastToAPInt().getRawData();
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker else
118*9880d681SAndroid Build Coastguard Worker ImmValue = MI.getOperand(1).getImm();
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
121*9880d681SAndroid Build Coastguard Worker DestReg)
122*9880d681SAndroid Build Coastguard Worker .addImm(ImmValue);
123*9880d681SAndroid Build Coastguard Worker MII = MBB->erase(&MI);
124*9880d681SAndroid Build Coastguard Worker continue;
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker else if (Opc == Hexagon::CONST64_Int_Real ||
127*9880d681SAndroid Build Coastguard Worker Opc == Hexagon::CONST64_Float_Real) {
128*9880d681SAndroid Build Coastguard Worker int DestReg = MI.getOperand(0).getReg();
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker // We have to convert an FP immediate into its corresponding integer
131*9880d681SAndroid Build Coastguard Worker // representation
132*9880d681SAndroid Build Coastguard Worker int64_t ImmValue;
133*9880d681SAndroid Build Coastguard Worker if (Opc == Hexagon::CONST64_Float_Real) {
134*9880d681SAndroid Build Coastguard Worker APFloat Val = MI.getOperand(1).getFPImm()->getValueAPF();
135*9880d681SAndroid Build Coastguard Worker ImmValue = *Val.bitcastToAPInt().getRawData();
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker else
138*9880d681SAndroid Build Coastguard Worker ImmValue = MI.getOperand(1).getImm();
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker unsigned DestLo = TRI->getSubReg(DestReg, Hexagon::subreg_loreg);
141*9880d681SAndroid Build Coastguard Worker unsigned DestHi = TRI->getSubReg(DestReg, Hexagon::subreg_hireg);
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker int32_t LowWord = (ImmValue & 0xFFFFFFFF);
144*9880d681SAndroid Build Coastguard Worker int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
147*9880d681SAndroid Build Coastguard Worker DestLo)
148*9880d681SAndroid Build Coastguard Worker .addImm(LowWord);
149*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
150*9880d681SAndroid Build Coastguard Worker DestHi)
151*9880d681SAndroid Build Coastguard Worker .addImm(HighWord);
152*9880d681SAndroid Build Coastguard Worker MII = MBB->erase(&MI);
153*9880d681SAndroid Build Coastguard Worker continue;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker ++MII;
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker }
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker return true;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
165*9880d681SAndroid Build Coastguard Worker // Public Constructor Functions
166*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker FunctionPass *
createHexagonSplitConst32AndConst64()169*9880d681SAndroid Build Coastguard Worker llvm::createHexagonSplitConst32AndConst64() {
170*9880d681SAndroid Build Coastguard Worker return new HexagonSplitConst32AndConst64();
171*9880d681SAndroid Build Coastguard Worker }
172