1259698Sdim//=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// When the compiler is invoked with no small data, for instance, with the -G0 11259698Sdim// command line option, then all CONST32_* opcodes should be broken down into 12259698Sdim// appropriate LO and HI instructions. This splitting is done by this pass. 13259698Sdim// The only reason this is not done in the DAG lowering itself is that there 14259698Sdim// is no simple way of getting the register allocator to allot the same hard 15259698Sdim// register to the result of LO and HI instructions. This pass is always 16259698Sdim// scheduled after register allocation. 17259698Sdim// 18259698Sdim//===----------------------------------------------------------------------===// 19259698Sdim 20259698Sdim#define DEBUG_TYPE "xfer" 21259698Sdim 22259698Sdim#include "HexagonTargetMachine.h" 23259698Sdim#include "HexagonSubtarget.h" 24259698Sdim#include "HexagonMachineFunctionInfo.h" 25259698Sdim#include "llvm/ADT/Statistic.h" 26259698Sdim#include "llvm/CodeGen/LatencyPriorityQueue.h" 27259698Sdim#include "llvm/CodeGen/MachineDominators.h" 28259698Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 29259698Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 30259698Sdim#include "llvm/CodeGen/MachineLoopInfo.h" 31259698Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 32259698Sdim#include "llvm/CodeGen/Passes.h" 33259698Sdim#include "llvm/CodeGen/ScheduleDAGInstrs.h" 34259698Sdim#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 35259698Sdim#include "llvm/CodeGen/SchedulerRegistry.h" 36259698Sdim#include "llvm/Target/TargetMachine.h" 37259698Sdim#include "llvm/Target/TargetInstrInfo.h" 38259698Sdim#include "llvm/Target/TargetRegisterInfo.h" 39259698Sdim#include "llvm/Support/Compiler.h" 40259698Sdim#include "llvm/Support/Debug.h" 41259698Sdim#include "llvm/Support/CommandLine.h" 42259698Sdim#include "llvm/Support/MathExtras.h" 43259698Sdim#include <map> 44259698Sdim 45259698Sdimusing namespace llvm; 46259698Sdim 47259698Sdimnamespace { 48259698Sdim 49259698Sdimclass HexagonSplitConst32AndConst64 : public MachineFunctionPass { 50259698Sdim const HexagonTargetMachine& QTM; 51259698Sdim const HexagonSubtarget &QST; 52259698Sdim 53259698Sdim public: 54259698Sdim static char ID; 55259698Sdim HexagonSplitConst32AndConst64(const HexagonTargetMachine& TM) 56259698Sdim : MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {} 57259698Sdim 58259698Sdim const char *getPassName() const { 59259698Sdim return "Hexagon Split Const32s and Const64s"; 60259698Sdim } 61259698Sdim bool runOnMachineFunction(MachineFunction &Fn); 62259698Sdim}; 63259698Sdim 64259698Sdim 65259698Sdimchar HexagonSplitConst32AndConst64::ID = 0; 66259698Sdim 67259698Sdim 68259698Sdimbool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { 69259698Sdim 70259698Sdim const TargetInstrInfo *TII = QTM.getInstrInfo(); 71259698Sdim 72259698Sdim // Loop over all of the basic blocks 73259698Sdim for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 74259698Sdim MBBb != MBBe; ++MBBb) { 75259698Sdim MachineBasicBlock* MBB = MBBb; 76259698Sdim // Traverse the basic block 77259698Sdim MachineBasicBlock::iterator MII = MBB->begin(); 78259698Sdim MachineBasicBlock::iterator MIE = MBB->end (); 79259698Sdim while (MII != MIE) { 80259698Sdim MachineInstr *MI = MII; 81259698Sdim int Opc = MI->getOpcode(); 82259698Sdim if (Opc == Hexagon::CONST32_set) { 83259698Sdim int DestReg = MI->getOperand(0).getReg(); 84259698Sdim MachineOperand &Symbol = MI->getOperand (1); 85259698Sdim 86259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 87259698Sdim TII->get(Hexagon::LO), DestReg).addOperand(Symbol); 88259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 89259698Sdim TII->get(Hexagon::HI), DestReg).addOperand(Symbol); 90259698Sdim // MBB->erase returns the iterator to the next instruction, which is the 91259698Sdim // one we want to process next 92259698Sdim MII = MBB->erase (MI); 93259698Sdim continue; 94259698Sdim } 95259698Sdim else if (Opc == Hexagon::CONST32_set_jt) { 96259698Sdim int DestReg = MI->getOperand(0).getReg(); 97259698Sdim MachineOperand &Symbol = MI->getOperand (1); 98259698Sdim 99259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 100259698Sdim TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol); 101259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 102259698Sdim TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol); 103259698Sdim // MBB->erase returns the iterator to the next instruction, which is the 104259698Sdim // one we want to process next 105259698Sdim MII = MBB->erase (MI); 106259698Sdim continue; 107259698Sdim } 108259698Sdim else if (Opc == Hexagon::CONST32_Label) { 109259698Sdim int DestReg = MI->getOperand(0).getReg(); 110259698Sdim MachineOperand &Symbol = MI->getOperand (1); 111259698Sdim 112259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 113259698Sdim TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol); 114259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 115259698Sdim TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol); 116259698Sdim // MBB->erase returns the iterator to the next instruction, which is the 117259698Sdim // one we want to process next 118259698Sdim MII = MBB->erase (MI); 119259698Sdim continue; 120259698Sdim } 121259698Sdim else if (Opc == Hexagon::CONST32_Int_Real) { 122259698Sdim int DestReg = MI->getOperand(0).getReg(); 123259698Sdim int64_t ImmValue = MI->getOperand(1).getImm (); 124259698Sdim 125259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 126259698Sdim TII->get(Hexagon::LOi), DestReg).addImm(ImmValue); 127259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 128259698Sdim TII->get(Hexagon::HIi), DestReg).addImm(ImmValue); 129259698Sdim MII = MBB->erase (MI); 130259698Sdim continue; 131259698Sdim } 132259698Sdim else if (Opc == Hexagon::CONST64_Int_Real) { 133259698Sdim int DestReg = MI->getOperand(0).getReg(); 134259698Sdim int64_t ImmValue = MI->getOperand(1).getImm (); 135259698Sdim unsigned DestLo = 136259698Sdim QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg); 137259698Sdim unsigned DestHi = 138259698Sdim QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg); 139259698Sdim 140259698Sdim int32_t LowWord = (ImmValue & 0xFFFFFFFF); 141259698Sdim int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF; 142259698Sdim 143259698Sdim // Lower Registers Lower Half 144259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 145259698Sdim TII->get(Hexagon::LOi), DestLo).addImm(LowWord); 146259698Sdim // Lower Registers Higher Half 147259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 148259698Sdim TII->get(Hexagon::HIi), DestLo).addImm(LowWord); 149259698Sdim // Higher Registers Lower Half 150259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 151259698Sdim TII->get(Hexagon::LOi), DestHi).addImm(HighWord); 152259698Sdim // Higher Registers Higher Half. 153259698Sdim BuildMI (*MBB, MII, MI->getDebugLoc(), 154259698Sdim TII->get(Hexagon::HIi), DestHi).addImm(HighWord); 155259698Sdim MII = MBB->erase (MI); 156259698Sdim continue; 157259698Sdim } 158259698Sdim ++MII; 159259698Sdim } 160259698Sdim } 161259698Sdim 162259698Sdim return true; 163259698Sdim} 164259698Sdim 165259698Sdim} 166259698Sdim 167259698Sdim//===----------------------------------------------------------------------===// 168259698Sdim// Public Constructor Functions 169259698Sdim//===----------------------------------------------------------------------===// 170259698Sdim 171259698SdimFunctionPass * 172259698Sdimllvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) { 173259698Sdim return new HexagonSplitConst32AndConst64(TM); 174259698Sdim} 175