blob: 10bba972b0c8e28151b5bd3f02436cbd9139787c [file] [log] [blame]
Wesley Pecka70f28c2010-02-23 19:15:24 +00001//===- MBlazeInstrInfo.cpp - MBlaze Instruction Information -----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the MBlaze implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MBlazeInstrInfo.h"
15#include "MBlazeTargetMachine.h"
16#include "MBlazeMachineFunction.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "MBlazeGenInstrInfo.inc"
22
23using namespace llvm;
24
25MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
26 : TargetInstrInfoImpl(MBlazeInsts, array_lengthof(MBlazeInsts)),
27 TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
28
29static bool isZeroImm(const MachineOperand &op) {
30 return op.isImm() && op.getImm() == 0;
31}
32
Wesley Pecka70f28c2010-02-23 19:15:24 +000033/// isLoadFromStackSlot - If the specified machine instruction is a direct
34/// load from a stack slot, return the virtual or physical register number of
35/// the destination along with the FrameIndex of the loaded stack slot. If
36/// not, return 0. This predicate must return 0 if the instruction has
37/// any side effects other than loading from the stack slot.
38unsigned MBlazeInstrInfo::
39isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
40 if (MI->getOpcode() == MBlaze::LWI) {
Wesley Peck41400da2010-11-12 23:30:17 +000041 if ((MI->getOperand(1).isFI()) && // is a stack slot
42 (MI->getOperand(2).isImm()) && // the imm is zero
43 (isZeroImm(MI->getOperand(2)))) {
44 FrameIndex = MI->getOperand(1).getIndex();
Wesley Pecka70f28c2010-02-23 19:15:24 +000045 return MI->getOperand(0).getReg();
46 }
47 }
48
49 return 0;
50}
51
52/// isStoreToStackSlot - If the specified machine instruction is a direct
53/// store to a stack slot, return the virtual or physical register number of
54/// the source reg along with the FrameIndex of the loaded stack slot. If
55/// not, return 0. This predicate must return 0 if the instruction has
56/// any side effects other than storing to the stack slot.
57unsigned MBlazeInstrInfo::
58isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
59 if (MI->getOpcode() == MBlaze::SWI) {
Wesley Peck41400da2010-11-12 23:30:17 +000060 if ((MI->getOperand(1).isFI()) && // is a stack slot
61 (MI->getOperand(2).isImm()) && // the imm is zero
62 (isZeroImm(MI->getOperand(2)))) {
63 FrameIndex = MI->getOperand(1).getIndex();
Wesley Pecka70f28c2010-02-23 19:15:24 +000064 return MI->getOperand(0).getReg();
65 }
66 }
67 return 0;
68}
69
70/// insertNoop - If data hazard condition is found insert the target nop
71/// instruction.
72void MBlazeInstrInfo::
73insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000074 DebugLoc DL;
Wesley Pecka70f28c2010-02-23 19:15:24 +000075 BuildMI(MBB, MI, DL, get(MBlaze::NOP));
76}
77
Jakob Stoklund Olesene6afcf82010-07-11 06:53:27 +000078void MBlazeInstrInfo::
79copyPhysReg(MachineBasicBlock &MBB,
80 MachineBasicBlock::iterator I, DebugLoc DL,
81 unsigned DestReg, unsigned SrcReg,
82 bool KillSrc) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000083 llvm::BuildMI(MBB, I, DL, get(MBlaze::ADD), DestReg)
Jakob Stoklund Olesene6afcf82010-07-11 06:53:27 +000084 .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
Wesley Pecka70f28c2010-02-23 19:15:24 +000085}
86
87void MBlazeInstrInfo::
88storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
89 unsigned SrcReg, bool isKill, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +000090 const TargetRegisterClass *RC,
91 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000092 DebugLoc DL;
93 BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
Wesley Peck41400da2010-11-12 23:30:17 +000094 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
Wesley Pecka70f28c2010-02-23 19:15:24 +000095}
96
97void MBlazeInstrInfo::
98loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
99 unsigned DestReg, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000100 const TargetRegisterClass *RC,
101 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000102 DebugLoc DL;
103 BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
Wesley Peck41400da2010-11-12 23:30:17 +0000104 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000105}
106
Wesley Pecka70f28c2010-02-23 19:15:24 +0000107//===----------------------------------------------------------------------===//
108// Branch Analysis
109//===----------------------------------------------------------------------===//
110unsigned MBlazeInstrInfo::
111InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
112 MachineBasicBlock *FBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000113 const SmallVectorImpl<MachineOperand> &Cond,
114 DebugLoc DL) const {
Wesley Pecka70f28c2010-02-23 19:15:24 +0000115 // Can only insert uncond branches so far.
116 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
Stuart Hastings3bf91252010-06-17 22:43:56 +0000117 BuildMI(&MBB, DL, get(MBlaze::BRI)).addMBB(TBB);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000118 return 1;
119}
120
121/// getGlobalBaseReg - Return a virtual register initialized with the
122/// the global base register value. Output instructions required to
123/// initialize the register in the function entry block, if necessary.
124///
125unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
126 MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
127 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
128 if (GlobalBaseReg != 0)
129 return GlobalBaseReg;
130
131 // Insert the set of GlobalBaseReg into the first MBB of the function
132 MachineBasicBlock &FirstMBB = MF->front();
133 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
134 MachineRegisterInfo &RegInfo = MF->getRegInfo();
135 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
136
Wesley Peck4da992a2010-10-21 19:48:38 +0000137 GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::GPRRegisterClass);
Jakob Stoklund Olesen3ecf1f02010-07-10 22:43:03 +0000138 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
139 GlobalBaseReg).addReg(MBlaze::R20);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000140 RegInfo.addLiveIn(MBlaze::R20);
141
142 MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
143 return GlobalBaseReg;
144}