1249259Sdim//===-- MipsConstantIslandPass.cpp - Emit Pc Relative loads----------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// 11249259Sdim// This pass is used to make Pc relative loads of constants. 12249259Sdim// For now, only Mips16 will use this. While it has the same name and 13249259Sdim// uses many ideas from the LLVM ARM Constant Island Pass, it's not intended 14249259Sdim// to reuse any of the code from the ARM version. 15249259Sdim// 16249259Sdim// Loading constants inline is expensive on Mips16 and it's in general better 17249259Sdim// to place the constant nearby in code space and then it can be loaded with a 18249259Sdim// simple 16 bit load instruction. 19249259Sdim// 20249259Sdim// The constants can be not just numbers but addresses of functions and labels. 21249259Sdim// This can be particularly helpful in static relocation mode for embedded 22249259Sdim// non linux targets. 23249259Sdim// 24249259Sdim// 25249259Sdim 26249259Sdim#define DEBUG_TYPE "mips-constant-islands" 27249259Sdim 28249259Sdim#include "Mips.h" 29249259Sdim#include "MCTargetDesc/MipsBaseInfo.h" 30249259Sdim#include "MipsTargetMachine.h" 31249259Sdim#include "llvm/ADT/Statistic.h" 32249259Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 33249259Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 34249259Sdim#include "llvm/IR/Function.h" 35249259Sdim#include "llvm/Support/CommandLine.h" 36249259Sdim#include "llvm/Support/MathExtras.h" 37249259Sdim#include "llvm/Target/TargetInstrInfo.h" 38249259Sdim#include "llvm/Target/TargetMachine.h" 39249259Sdim#include "llvm/Target/TargetRegisterInfo.h" 40249259Sdim 41249259Sdimusing namespace llvm; 42249259Sdim 43249259Sdimnamespace { 44249259Sdim typedef MachineBasicBlock::iterator Iter; 45249259Sdim typedef MachineBasicBlock::reverse_iterator ReverseIter; 46249259Sdim 47249259Sdim class MipsConstantIslands : public MachineFunctionPass { 48249259Sdim 49249259Sdim public: 50249259Sdim static char ID; 51249259Sdim MipsConstantIslands(TargetMachine &tm) 52249259Sdim : MachineFunctionPass(ID), TM(tm), 53249259Sdim TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), 54249259Sdim IsPIC(TM.getRelocationModel() == Reloc::PIC_), 55249259Sdim ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()) {} 56249259Sdim 57249259Sdim virtual const char *getPassName() const { 58249259Sdim return "Mips Constant Islands"; 59249259Sdim } 60249259Sdim 61249259Sdim bool runOnMachineFunction(MachineFunction &F); 62249259Sdim 63249259Sdim private: 64249259Sdim 65249259Sdim 66249259Sdim const TargetMachine &TM; 67249259Sdim const MipsInstrInfo *TII; 68249259Sdim bool IsPIC; 69249259Sdim unsigned ABI; 70249259Sdim 71249259Sdim }; 72249259Sdim 73249259Sdim char MipsConstantIslands::ID = 0; 74249259Sdim} // end of anonymous namespace 75249259Sdim 76249259Sdim/// createMipsLongBranchPass - Returns a pass that converts branches to long 77249259Sdim/// branches. 78249259SdimFunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) { 79249259Sdim return new MipsConstantIslands(tm); 80249259Sdim} 81249259Sdim 82249259Sdimbool MipsConstantIslands::runOnMachineFunction(MachineFunction &F) { 83251662Sdim // The intention is for this to be a mips16 only pass for now 84251662Sdim // FIXME: 85251662Sdim // if (!TM.getSubtarget<MipsSubtarget>().inMips16Mode()) 86251662Sdim // return false; 87251662Sdim return false; 88249259Sdim} 89249259Sdim 90