blob: 9d9a5f07d8647210743a4820f337c3bb38f658ac [file] [log] [blame]
Alex Bradbury89718422017-10-19 21:37:38 +00001//===-- RISCVInstrInfo.cpp - RISCV 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 RISCV implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "RISCVInstrInfo.h"
15#include "RISCV.h"
16#include "RISCVSubtarget.h"
17#include "RISCVTargetMachine.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/TargetRegistry.h"
25
26#define GET_INSTRINFO_CTOR_DTOR
27#include "RISCVGenInstrInfo.inc"
28
29using namespace llvm;
30
Alex Bradburya3376752017-11-08 13:41:21 +000031RISCVInstrInfo::RISCVInstrInfo()
32 : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP) {}
Alex Bradburycfa62912017-11-08 12:20:01 +000033
34void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
35 MachineBasicBlock::iterator MBBI,
36 const DebugLoc &DL, unsigned DstReg,
37 unsigned SrcReg, bool KillSrc) const {
38 assert(RISCV::GPRRegClass.contains(DstReg, SrcReg) &&
39 "Impossible reg-to-reg copy");
40
41 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
42 .addReg(SrcReg, getKillRegState(KillSrc))
43 .addImm(0);
44}
Alex Bradbury74913e12017-11-08 13:31:40 +000045
46void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator I,
48 unsigned SrcReg, bool IsKill, int FI,
49 const TargetRegisterClass *RC,
50 const TargetRegisterInfo *TRI) const {
51 DebugLoc DL;
52 if (I != MBB.end())
53 DL = I->getDebugLoc();
54
Alex Bradbury87a54d62017-12-07 12:45:05 +000055 if (RISCV::GPRRegClass.hasSubClassEq(RC))
Alex Bradbury74913e12017-11-08 13:31:40 +000056 BuildMI(MBB, I, DL, get(RISCV::SW))
57 .addReg(SrcReg, getKillRegState(IsKill))
58 .addFrameIndex(FI)
59 .addImm(0);
60 else
61 llvm_unreachable("Can't store this register to stack slot");
62}
63
64void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
65 MachineBasicBlock::iterator I,
66 unsigned DstReg, int FI,
67 const TargetRegisterClass *RC,
68 const TargetRegisterInfo *TRI) const {
69 DebugLoc DL;
70 if (I != MBB.end())
71 DL = I->getDebugLoc();
72
Alex Bradbury87a54d62017-12-07 12:45:05 +000073 if (RISCV::GPRRegClass.hasSubClassEq(RC))
Alex Bradbury74913e12017-11-08 13:31:40 +000074 BuildMI(MBB, I, DL, get(RISCV::LW), DstReg).addFrameIndex(FI).addImm(0);
75 else
76 llvm_unreachable("Can't load this register from stack slot");
77}
Alex Bradbury9fea4882018-01-10 19:53:46 +000078
79void RISCVInstrInfo::movImm32(MachineBasicBlock &MBB,
80 MachineBasicBlock::iterator MBBI,
81 const DebugLoc &DL, unsigned DstReg, uint64_t Val,
82 MachineInstr::MIFlag Flag) const {
83 assert(isInt<32>(Val) && "Can only materialize 32-bit constants");
84
85 // TODO: If the value can be materialized using only one instruction, only
86 // insert a single instruction.
87
88 uint64_t Hi20 = ((Val + 0x800) >> 12) & 0xfffff;
89 uint64_t Lo12 = SignExtend64<12>(Val);
90 BuildMI(MBB, MBBI, DL, get(RISCV::LUI), DstReg)
91 .addImm(Hi20)
92 .setMIFlag(Flag);
93 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
94 .addReg(DstReg, RegState::Kill)
95 .addImm(Lo12)
96 .setMIFlag(Flag);
97}
Alex Bradburye027c932018-01-10 20:47:00 +000098
99// The contents of values added to Cond are not examined outside of
100// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
101// push BranchOpcode, Reg1, Reg2.
102static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
103 SmallVectorImpl<MachineOperand> &Cond) {
104 // Block ends with fall-through condbranch.
105 assert(LastInst.getDesc().isConditionalBranch() &&
106 "Unknown conditional branch");
107 Target = LastInst.getOperand(2).getMBB();
108 Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
109 Cond.push_back(LastInst.getOperand(0));
110 Cond.push_back(LastInst.getOperand(1));
111}
112
113static unsigned getOppositeBranchOpcode(int Opc) {
114 switch (Opc) {
115 default:
116 llvm_unreachable("Unrecognized conditional branch");
117 case RISCV::BEQ:
118 return RISCV::BNE;
119 case RISCV::BNE:
120 return RISCV::BEQ;
121 case RISCV::BLT:
122 return RISCV::BGE;
123 case RISCV::BGE:
124 return RISCV::BLT;
125 case RISCV::BLTU:
126 return RISCV::BGEU;
127 case RISCV::BGEU:
128 return RISCV::BLTU;
129 }
130}
131
132bool RISCVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
133 MachineBasicBlock *&TBB,
134 MachineBasicBlock *&FBB,
135 SmallVectorImpl<MachineOperand> &Cond,
136 bool AllowModify) const {
137 TBB = FBB = nullptr;
138 Cond.clear();
139
140 // If the block has no terminators, it just falls into the block after it.
141 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
142 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
143 return false;
144
145 // Count the number of terminators and find the first unconditional or
146 // indirect branch.
147 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
148 int NumTerminators = 0;
149 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
150 J++) {
151 NumTerminators++;
152 if (J->getDesc().isUnconditionalBranch() ||
153 J->getDesc().isIndirectBranch()) {
154 FirstUncondOrIndirectBr = J.getReverse();
155 }
156 }
157
158 // If AllowModify is true, we can erase any terminators after
159 // FirstUncondOrIndirectBR.
160 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
161 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
162 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
163 NumTerminators--;
164 }
165 I = FirstUncondOrIndirectBr;
166 }
167
168 // We can't handle blocks that end in an indirect branch.
169 if (I->getDesc().isIndirectBranch())
170 return true;
171
172 // We can't handle blocks with more than 2 terminators.
173 if (NumTerminators > 2)
174 return true;
175
176 // Handle a single unconditional branch.
177 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
178 TBB = I->getOperand(0).getMBB();
179 return false;
180 }
181
182 // Handle a single conditional branch.
183 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
184 parseCondBranch(*I, TBB, Cond);
185 return false;
186 }
187
188 // Handle a conditional branch followed by an unconditional branch.
189 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
190 I->getDesc().isUnconditionalBranch()) {
191 parseCondBranch(*std::prev(I), TBB, Cond);
192 FBB = I->getOperand(0).getMBB();
193 return false;
194 }
195
196 // Otherwise, we can't handle this.
197 return true;
198}
199
200unsigned RISCVInstrInfo::removeBranch(MachineBasicBlock &MBB,
201 int *BytesRemoved) const {
202 assert(!BytesRemoved && "Code size not handled");
203 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
204 if (I == MBB.end())
205 return 0;
206
207 if (!I->getDesc().isUnconditionalBranch() &&
208 !I->getDesc().isConditionalBranch())
209 return 0;
210
211 // Remove the branch.
212 I->eraseFromParent();
213
214 I = MBB.end();
215
216 if (I == MBB.begin())
217 return 1;
218 --I;
219 if (!I->getDesc().isConditionalBranch())
220 return 1;
221
222 // Remove the branch.
223 I->eraseFromParent();
224 return 2;
225}
226
227// Inserts a branch into the end of the specific MachineBasicBlock, returning
228// the number of instructions inserted.
229unsigned RISCVInstrInfo::insertBranch(
230 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
231 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
232 assert(!BytesAdded && "Code size not handled.");
233
234 // Shouldn't be a fall through.
235 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
236 assert((Cond.size() == 3 || Cond.size() == 0) &&
237 "RISCV branch conditions have two components!");
238
239 // Unconditional branch.
240 if (Cond.empty()) {
241 BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
242 return 1;
243 }
244
245 // Either a one or two-way conditional branch.
246 unsigned Opc = Cond[0].getImm();
247 BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).add(Cond[2]).addMBB(TBB);
248
249 // One-way conditional branch.
250 if (!FBB)
251 return 1;
252
253 // Two-way conditional branch.
254 BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
255 return 2;
256}
257
258bool RISCVInstrInfo::reverseBranchCondition(
259 SmallVectorImpl<MachineOperand> &Cond) const {
260 assert((Cond.size() == 3) && "Invalid branch condition!");
261 Cond[0].setImm(getOppositeBranchOpcode(Cond[0].getImm()));
262 return false;
263}