1f4a2713aSLionel Sambuc //===-- Mips16RegisterInfo.cpp - MIPS16 Register Information --------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file contains the MIPS16 implementation of the TargetRegisterInfo class.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc
14f4a2713aSLionel Sambuc #include "Mips16RegisterInfo.h"
15f4a2713aSLionel Sambuc #include "Mips.h"
16f4a2713aSLionel Sambuc #include "Mips16InstrInfo.h"
17f4a2713aSLionel Sambuc #include "MipsAnalyzeImmediate.h"
18f4a2713aSLionel Sambuc #include "MipsInstrInfo.h"
19f4a2713aSLionel Sambuc #include "MipsMachineFunction.h"
20f4a2713aSLionel Sambuc #include "MipsSubtarget.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/BitVector.h"
22f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
23f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineFrameInfo.h"
24f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineFunction.h"
25f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineInstrBuilder.h"
26f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineRegisterInfo.h"
27f4a2713aSLionel Sambuc #include "llvm/IR/Constants.h"
28*0a6a1f1dSLionel Sambuc #include "llvm/IR/DebugInfo.h"
29f4a2713aSLionel Sambuc #include "llvm/IR/Function.h"
30f4a2713aSLionel Sambuc #include "llvm/IR/Type.h"
31f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
32f4a2713aSLionel Sambuc #include "llvm/Support/Debug.h"
33f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
34f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
35f4a2713aSLionel Sambuc #include "llvm/Target/TargetFrameLowering.h"
36f4a2713aSLionel Sambuc #include "llvm/Target/TargetInstrInfo.h"
37f4a2713aSLionel Sambuc #include "llvm/Target/TargetMachine.h"
38f4a2713aSLionel Sambuc #include "llvm/Target/TargetOptions.h"
39f4a2713aSLionel Sambuc
40f4a2713aSLionel Sambuc using namespace llvm;
41f4a2713aSLionel Sambuc
42*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "mips16-registerinfo"
43*0a6a1f1dSLionel Sambuc
Mips16RegisterInfo(const MipsSubtarget & ST)44f4a2713aSLionel Sambuc Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST)
45f4a2713aSLionel Sambuc : MipsRegisterInfo(ST) {}
46f4a2713aSLionel Sambuc
requiresRegisterScavenging(const MachineFunction & MF) const47f4a2713aSLionel Sambuc bool Mips16RegisterInfo::requiresRegisterScavenging
48f4a2713aSLionel Sambuc (const MachineFunction &MF) const {
49f4a2713aSLionel Sambuc return false;
50f4a2713aSLionel Sambuc }
requiresFrameIndexScavenging(const MachineFunction & MF) const51f4a2713aSLionel Sambuc bool Mips16RegisterInfo::requiresFrameIndexScavenging
52f4a2713aSLionel Sambuc (const MachineFunction &MF) const {
53f4a2713aSLionel Sambuc return false;
54f4a2713aSLionel Sambuc }
55f4a2713aSLionel Sambuc
useFPForScavengingIndex(const MachineFunction & MF) const56f4a2713aSLionel Sambuc bool Mips16RegisterInfo::useFPForScavengingIndex
57f4a2713aSLionel Sambuc (const MachineFunction &MF) const {
58f4a2713aSLionel Sambuc return false;
59f4a2713aSLionel Sambuc }
60f4a2713aSLionel Sambuc
saveScavengerRegister(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & UseMI,const TargetRegisterClass * RC,unsigned Reg) const61f4a2713aSLionel Sambuc bool Mips16RegisterInfo::saveScavengerRegister
62f4a2713aSLionel Sambuc (MachineBasicBlock &MBB,
63f4a2713aSLionel Sambuc MachineBasicBlock::iterator I,
64f4a2713aSLionel Sambuc MachineBasicBlock::iterator &UseMI,
65f4a2713aSLionel Sambuc const TargetRegisterClass *RC,
66f4a2713aSLionel Sambuc unsigned Reg) const {
67f4a2713aSLionel Sambuc DebugLoc DL;
68*0a6a1f1dSLionel Sambuc const TargetInstrInfo &TII = *MBB.getParent()->getSubtarget().getInstrInfo();
69f4a2713aSLionel Sambuc TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true);
70f4a2713aSLionel Sambuc TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true);
71f4a2713aSLionel Sambuc return true;
72f4a2713aSLionel Sambuc }
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc const TargetRegisterClass *
intRegClass(unsigned Size) const75f4a2713aSLionel Sambuc Mips16RegisterInfo::intRegClass(unsigned Size) const {
76f4a2713aSLionel Sambuc assert(Size == 4);
77f4a2713aSLionel Sambuc return &Mips::CPU16RegsRegClass;
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc
eliminateFI(MachineBasicBlock::iterator II,unsigned OpNo,int FrameIndex,uint64_t StackSize,int64_t SPOffset) const80f4a2713aSLionel Sambuc void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
81f4a2713aSLionel Sambuc unsigned OpNo, int FrameIndex,
82f4a2713aSLionel Sambuc uint64_t StackSize,
83f4a2713aSLionel Sambuc int64_t SPOffset) const {
84f4a2713aSLionel Sambuc MachineInstr &MI = *II;
85f4a2713aSLionel Sambuc MachineFunction &MF = *MI.getParent()->getParent();
86f4a2713aSLionel Sambuc MachineFrameInfo *MFI = MF.getFrameInfo();
87f4a2713aSLionel Sambuc
88f4a2713aSLionel Sambuc const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
89f4a2713aSLionel Sambuc int MinCSFI = 0;
90f4a2713aSLionel Sambuc int MaxCSFI = -1;
91f4a2713aSLionel Sambuc
92f4a2713aSLionel Sambuc if (CSI.size()) {
93f4a2713aSLionel Sambuc MinCSFI = CSI[0].getFrameIdx();
94f4a2713aSLionel Sambuc MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc
97f4a2713aSLionel Sambuc // The following stack frame objects are always
98f4a2713aSLionel Sambuc // referenced relative to $sp:
99f4a2713aSLionel Sambuc // 1. Outgoing arguments.
100f4a2713aSLionel Sambuc // 2. Pointer to dynamically allocated stack space.
101f4a2713aSLionel Sambuc // 3. Locations for callee-saved registers.
102f4a2713aSLionel Sambuc // Everything else is referenced relative to whatever register
103f4a2713aSLionel Sambuc // getFrameRegister() returns.
104f4a2713aSLionel Sambuc unsigned FrameReg;
105f4a2713aSLionel Sambuc
106f4a2713aSLionel Sambuc if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)
107f4a2713aSLionel Sambuc FrameReg = Mips::SP;
108f4a2713aSLionel Sambuc else {
109*0a6a1f1dSLionel Sambuc const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
110f4a2713aSLionel Sambuc if (TFI->hasFP(MF)) {
111f4a2713aSLionel Sambuc FrameReg = Mips::S0;
112f4a2713aSLionel Sambuc }
113f4a2713aSLionel Sambuc else {
114f4a2713aSLionel Sambuc if ((MI.getNumOperands()> OpNo+2) && MI.getOperand(OpNo+2).isReg())
115f4a2713aSLionel Sambuc FrameReg = MI.getOperand(OpNo+2).getReg();
116f4a2713aSLionel Sambuc else
117f4a2713aSLionel Sambuc FrameReg = Mips::SP;
118f4a2713aSLionel Sambuc }
119f4a2713aSLionel Sambuc }
120f4a2713aSLionel Sambuc // Calculate final offset.
121f4a2713aSLionel Sambuc // - There is no need to change the offset if the frame object
122f4a2713aSLionel Sambuc // is one of the
123f4a2713aSLionel Sambuc // following: an outgoing argument, pointer to a dynamically allocated
124f4a2713aSLionel Sambuc // stack space or a $gp restore location,
125f4a2713aSLionel Sambuc // - If the frame object is any of the following,
126f4a2713aSLionel Sambuc // its offset must be adjusted
127f4a2713aSLionel Sambuc // by adding the size of the stack:
128f4a2713aSLionel Sambuc // incoming argument, callee-saved register location or local variable.
129f4a2713aSLionel Sambuc int64_t Offset;
130f4a2713aSLionel Sambuc bool IsKill = false;
131f4a2713aSLionel Sambuc Offset = SPOffset + (int64_t)StackSize;
132f4a2713aSLionel Sambuc Offset += MI.getOperand(OpNo + 1).getImm();
133f4a2713aSLionel Sambuc
134f4a2713aSLionel Sambuc
135f4a2713aSLionel Sambuc DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
136f4a2713aSLionel Sambuc
137f4a2713aSLionel Sambuc if (!MI.isDebugValue() &&
138f4a2713aSLionel Sambuc !Mips16InstrInfo::validImmediate(MI.getOpcode(), FrameReg, Offset)) {
139f4a2713aSLionel Sambuc MachineBasicBlock &MBB = *MI.getParent();
140f4a2713aSLionel Sambuc DebugLoc DL = II->getDebugLoc();
141f4a2713aSLionel Sambuc unsigned NewImm;
142f4a2713aSLionel Sambuc const Mips16InstrInfo &TII =
143f4a2713aSLionel Sambuc *static_cast<const Mips16InstrInfo *>(
144*0a6a1f1dSLionel Sambuc MBB.getParent()->getSubtarget().getInstrInfo());
145f4a2713aSLionel Sambuc FrameReg = TII.loadImmediate(FrameReg, Offset, MBB, II, DL, NewImm);
146f4a2713aSLionel Sambuc Offset = SignExtend64<16>(NewImm);
147f4a2713aSLionel Sambuc IsKill = true;
148f4a2713aSLionel Sambuc }
149f4a2713aSLionel Sambuc MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
150f4a2713aSLionel Sambuc MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
151f4a2713aSLionel Sambuc
152f4a2713aSLionel Sambuc
153f4a2713aSLionel Sambuc }
154