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