blob: ea062e7d7d799f4c4495383adbb84e5f951f9d4e [file] [log] [blame]
Jim Stichnoth6da4cef2015-06-11 13:26:33 -07001//===- subzero/src/IceTargetLoweringMIPS32.h - MIPS32 lowering ---*- C++-*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the TargetLoweringMIPS32 class, which implements the
Andrew Scull9612d322015-07-06 14:53:25 -070012/// TargetLowering interface for the MIPS 32-bit architecture.
13///
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070014//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
17#define SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
18
John Porto53611e22015-12-30 07:30:10 -080019#include "IceAssemblerMIPS32.h"
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070020#include "IceDefs.h"
21#include "IceInstMIPS32.h"
22#include "IceRegistersMIPS32.h"
23#include "IceTargetLowering.h"
24
25namespace Ice {
John Porto4a566862016-01-04 09:33:41 -080026namespace MIPS32 {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070027
28class TargetMIPS32 : public TargetLowering {
29 TargetMIPS32() = delete;
30 TargetMIPS32(const TargetMIPS32 &) = delete;
31 TargetMIPS32 &operator=(const TargetMIPS32 &) = delete;
32
33public:
John Porto53611e22015-12-30 07:30:10 -080034 ~TargetMIPS32() override = default;
35
Karl Schimpf5403f5d2016-01-15 11:07:46 -080036 static void staticInit(GlobalContext *Ctx);
Jim Stichnoth467ffe52016-03-29 15:01:06 -070037 static bool shouldBePooled(const Constant *C) {
38 (void)C;
39 return false;
40 }
John Porto53611e22015-12-30 07:30:10 -080041 static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
42 return makeUnique<TargetMIPS32>(Func);
43 }
44
45 std::unique_ptr<::Ice::Assembler> createAssembler() const override {
46 return makeUnique<MIPS32::AssemblerMIPS32>();
47 }
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070048
49 void translateOm1() override;
50 void translateO2() override;
Reed Kotler04bca5a2016-02-03 14:40:47 -080051 bool doBranchOpt(Inst *Instr, const CfgNode *NextNode) override;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070052
53 SizeT getNumRegisters() const override { return RegMIPS32::Reg_NUM; }
Jim Stichnoth8aa39662016-02-10 11:20:30 -080054 Variable *getPhysicalRegister(RegNumT RegNum,
55 Type Ty = IceType_void) override;
Jim Stichnoth467ffe52016-03-29 15:01:06 -070056 const char *getRegName(RegNumT RegNum, Type Ty) const override;
John Portoe82b5602016-02-24 15:58:55 -080057 SmallBitVector getRegisterSet(RegSetMask Include,
58 RegSetMask Exclude) const override;
59 const SmallBitVector &
Jim Stichnothc59288b2015-11-09 11:38:40 -080060 getRegistersForVariable(const Variable *Var) const override {
61 RegClass RC = Var->getRegClass();
62 assert(RC < RC_Target);
63 return TypeToRegisterSet[RC];
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070064 }
John Portoe82b5602016-02-24 15:58:55 -080065 const SmallBitVector &
Jim Stichnothb40595a2016-01-29 06:14:31 -080066 getAllRegistersForVariable(const Variable *Var) const override {
67 RegClass RC = Var->getRegClass();
68 assert(RC < RC_Target);
69 return TypeToRegisterSetUnfiltered[RC];
70 }
John Portoe82b5602016-02-24 15:58:55 -080071 const SmallBitVector &getAliasesForRegister(RegNumT Reg) const override {
John Portobb0a5fe2015-09-04 11:23:41 -070072 return RegisterAliases[Reg];
73 }
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070074 bool hasFramePointer() const override { return UsesFramePointer; }
David Sehre39d0ca2015-11-06 11:25:41 -080075 void setHasFramePointer() override { UsesFramePointer = true; }
Jim Stichnoth8aa39662016-02-10 11:20:30 -080076 RegNumT getStackReg() const override { return RegMIPS32::Reg_SP; }
77 RegNumT getFrameReg() const override { return RegMIPS32::Reg_FP; }
78 RegNumT getFrameOrStackReg() const override {
David Sehr2f3b8ec2015-11-16 16:51:39 -080079 return UsesFramePointer ? getFrameReg() : getStackReg();
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070080 }
81 size_t typeWidthInBytesOnStack(Type Ty) const override {
Andrew Scull57e12682015-09-16 11:30:19 -070082 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16
83 // are rounded up to 4 bytes.
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070084 return (typeWidthInBytes(Ty) + 3) & ~3;
85 }
David Sehre39d0ca2015-11-06 11:25:41 -080086 uint32_t getStackAlignment() const override {
87 // TODO(sehr): what is the stack alignment?
88 return 1;
89 }
David Sehr2f3b8ec2015-11-16 16:51:39 -080090 void reserveFixedAllocaArea(size_t Size, size_t Align) override {
91 // TODO(sehr): Implement fixed stack layout.
92 (void)Size;
93 (void)Align;
94 llvm::report_fatal_error("Not yet implemented");
95 }
96 int32_t getFrameFixedAllocaOffset() const override {
97 // TODO(sehr): Implement fixed stack layout.
98 llvm::report_fatal_error("Not yet implemented");
99 return 0;
100 }
Andrew Scull87f80c12015-07-20 10:19:16 -0700101
Andrew Scull6d47bcd2015-09-17 17:10:05 -0700102 bool shouldSplitToVariable64On32(Type Ty) const override {
103 return Ty == IceType_i64;
104 }
105
Andrew Scull87f80c12015-07-20 10:19:16 -0700106 // TODO(ascull): what is the best size of MIPS?
107 SizeT getMinJumpTableSize() const override { return 3; }
Andrew Scull86df4e92015-07-30 13:54:44 -0700108 void emitJumpTable(const Cfg *Func,
109 const InstJumpTable *JumpTable) const override;
Andrew Scull87f80c12015-07-20 10:19:16 -0700110
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700111 void emitVariable(const Variable *Var) const override;
112
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700113 void emit(const ConstantInteger32 *C) const final {
Jan Voungfb792842015-06-11 15:27:50 -0700114 (void)C;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700115 llvm::report_fatal_error("Not yet implemented");
116 }
117 void emit(const ConstantInteger64 *C) const final {
Jan Voungfb792842015-06-11 15:27:50 -0700118 (void)C;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700119 llvm::report_fatal_error("Not yet implemented");
120 }
121 void emit(const ConstantFloat *C) const final {
Jan Voungfb792842015-06-11 15:27:50 -0700122 (void)C;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700123 llvm::report_fatal_error("Not yet implemented");
124 }
125 void emit(const ConstantDouble *C) const final {
Jan Voungfb792842015-06-11 15:27:50 -0700126 (void)C;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700127 llvm::report_fatal_error("Not yet implemented");
128 }
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800129 void emit(const ConstantUndef *C) const final {
130 (void)C;
131 llvm::report_fatal_error("Not yet implemented");
132 }
133 void emit(const ConstantRelocatable *C) const final {
134 (void)C;
135 llvm::report_fatal_error("Not yet implemented");
136 }
Reed Kotler37af5b02015-11-05 17:07:19 -0800137
138 // The following are helpers that insert lowered MIPS32 instructions with
139 // minimal syntactic overhead, so that the lowering code can look as close to
140 // assembly as practical.
141 void _add(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800142 Context.insert<InstMIPS32Add>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800143 }
144
Reed Kotler00e36042016-02-01 20:52:19 -0800145 void _addu(Variable *Dest, Variable *Src0, Variable *Src1) {
146 Context.insert<InstMIPS32Addu>(Dest, Src0, Src1);
147 }
148
Reed Kotler37af5b02015-11-05 17:07:19 -0800149 void _and(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800150 Context.insert<InstMIPS32And>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800151 }
152
Reed Kotler3fe4b572016-02-23 18:59:43 -0800153 void _br(CfgNode *Target) { Context.insert<InstMIPS32Br>(Target); }
154
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700155 void _ret(Variable *RA, Variable *Src0 = nullptr) {
John Porto1d937a82015-12-17 06:19:34 -0800156 Context.insert<InstMIPS32Ret>(RA, Src0);
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700157 }
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700158
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700159 void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) {
John Porto1d937a82015-12-17 06:19:34 -0800160 Context.insert<InstMIPS32Addiu>(Dest, Src, Imm);
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700161 }
162
163 void _lui(Variable *Dest, uint32_t Imm) {
John Porto1d937a82015-12-17 06:19:34 -0800164 Context.insert<InstMIPS32Lui>(Dest, Imm);
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700165 }
166
167 void _mov(Variable *Dest, Operand *Src0) {
168 assert(Dest != nullptr);
169 // Variable* Src0_ = llvm::dyn_cast<Variable>(Src0);
170 if (llvm::isa<ConstantRelocatable>(Src0)) {
John Porto1d937a82015-12-17 06:19:34 -0800171 Context.insert<InstMIPS32La>(Dest, Src0);
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700172 } else {
John Porto1d937a82015-12-17 06:19:34 -0800173 auto *Instr = Context.insert<InstMIPS32Mov>(Dest, Src0);
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700174 if (Instr->isMultiDest()) {
175 // If Instr is multi-dest, then Dest must be a Variable64On32. We add a
176 // fake-def for Instr.DestHi here.
177 assert(llvm::isa<Variable64On32>(Dest));
John Porto1d937a82015-12-17 06:19:34 -0800178 Context.insert<InstFakeDef>(Instr->getDestHi());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700179 }
180 }
181 }
182
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800183 void _mfhi(Variable *Dest, Operand *Src) {
184 Context.insert<InstMIPS32Mfhi>(Dest, Src);
185 }
186
187 void _mflo(Variable *Dest, Operand *Src) {
188 Context.insert<InstMIPS32Mflo>(Dest, Src);
189 }
190
191 void _mthi(Variable *Dest, Operand *Src) {
192 Context.insert<InstMIPS32Mthi>(Dest, Src);
193 }
194
195 void _mtlo(Variable *Dest, Operand *Src) {
196 Context.insert<InstMIPS32Mtlo>(Dest, Src);
197 }
198
Reed Kotler37af5b02015-11-05 17:07:19 -0800199 void _mul(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800200 Context.insert<InstMIPS32Mul>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800201 }
202
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800203 void _mult(Variable *Dest, Variable *Src0, Variable *Src1) {
204 Context.insert<InstMIPS32Mult>(Dest, Src0, Src1);
205 }
206
207 void _multu(Variable *Dest, Variable *Src0, Variable *Src1) {
208 Context.insert<InstMIPS32Multu>(Dest, Src0, Src1);
209 }
210
Reed Kotler37af5b02015-11-05 17:07:19 -0800211 void _or(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800212 Context.insert<InstMIPS32Or>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800213 }
214
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700215 void _ori(Variable *Dest, Variable *Src, uint32_t Imm) {
John Porto1d937a82015-12-17 06:19:34 -0800216 Context.insert<InstMIPS32Ori>(Dest, Src, Imm);
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700217 }
218
Reed Kotler37af5b02015-11-05 17:07:19 -0800219 void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800220 Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800221 }
222
Reed Kotler00e36042016-02-01 20:52:19 -0800223 void _sltu(Variable *Dest, Variable *Src0, Variable *Src1) {
224 Context.insert<InstMIPS32Sltu>(Dest, Src0, Src1);
225 }
226
227 void _subu(Variable *Dest, Variable *Src0, Variable *Src1) {
228 Context.insert<InstMIPS32Subu>(Dest, Src0, Src1);
229 }
230
Reed Kotler37af5b02015-11-05 17:07:19 -0800231 void _xor(Variable *Dest, Variable *Src0, Variable *Src1) {
John Porto1d937a82015-12-17 06:19:34 -0800232 Context.insert<InstMIPS32Xor>(Dest, Src0, Src1);
Reed Kotler37af5b02015-11-05 17:07:19 -0800233 }
234
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700235 void lowerArguments() override;
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700236
237 /// Operand legalization helpers. To deal with address mode constraints,
238 /// the helpers will create a new Operand and emit instructions that
239 /// guarantee that the Operand kind is one of those indicated by the
240 /// LegalMask (a bitmask of allowed kinds). If the input Operand is known
241 /// to already meet the constraints, it may be simply returned as the result,
242 /// without creating any new instructions or operands.
243 enum OperandLegalization {
244 Legal_None = 0,
245 Legal_Reg = 1 << 0, // physical register, not stack location
246 Legal_Imm = 1 << 1,
247 Legal_Mem = 1 << 2,
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800248 Legal_Default = ~Legal_None
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700249 };
250 typedef uint32_t LegalMask;
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800251 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800252 RegNumT RegNum = RegNumT());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700253
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800254 Variable *legalizeToVar(Operand *From, RegNumT RegNum = RegNumT());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700255
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800256 Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700257
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800258 Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
Reed Kotler953568f2016-02-17 05:37:01 -0800259
260 Variable *I32Reg(RegNumT RegNum = RegNumT()) {
261 return makeReg(IceType_i32, RegNum);
262 }
263
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700264 static Type stackSlotType();
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800265 Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700266
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700267 void addProlog(CfgNode *Node) override;
268 void addEpilog(CfgNode *Node) override;
269
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700270 // Ensure that a 64-bit Variable has been split into 2 32-bit
271 // Variables, creating them if necessary. This is needed for all
272 // I64 operations.
273 void split64(Variable *Var);
274 Operand *loOperand(Operand *Operand);
275 Operand *hiOperand(Operand *Operand);
276
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800277 Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700278
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700279protected:
280 explicit TargetMIPS32(Cfg *Func);
281
282 void postLower() override;
283
Reed Kotler04bca5a2016-02-03 14:40:47 -0800284 void lowerAlloca(const InstAlloca *Instr) override;
285 void lowerArithmetic(const InstArithmetic *Instr) override;
286 void lowerInt64Arithmetic(const InstArithmetic *Instr, Variable *Dest,
Reed Kotler00e36042016-02-01 20:52:19 -0800287 Operand *Src0, Operand *Src1);
Reed Kotler04bca5a2016-02-03 14:40:47 -0800288 void lowerAssign(const InstAssign *Instr) override;
289 void lowerBr(const InstBr *Instr) override;
Eric Holk67c7c412016-04-15 13:05:37 -0700290 void lowerBreakpoint(const InstBreakpoint *Instr) override;
Reed Kotler04bca5a2016-02-03 14:40:47 -0800291 void lowerCall(const InstCall *Instr) override;
292 void lowerCast(const InstCast *Instr) override;
293 void lowerExtractElement(const InstExtractElement *Instr) override;
294 void lowerFcmp(const InstFcmp *Instr) override;
295 void lowerIcmp(const InstIcmp *Instr) override;
296 void lowerIntrinsicCall(const InstIntrinsicCall *Instr) override;
297 void lowerInsertElement(const InstInsertElement *Instr) override;
298 void lowerLoad(const InstLoad *Instr) override;
299 void lowerPhi(const InstPhi *Instr) override;
300 void lowerRet(const InstRet *Instr) override;
301 void lowerSelect(const InstSelect *Instr) override;
302 void lowerStore(const InstStore *Instr) override;
303 void lowerSwitch(const InstSwitch *Instr) override;
304 void lowerUnreachable(const InstUnreachable *Instr) override;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700305 void prelowerPhis() override;
John Portof4198542015-11-20 14:17:23 -0800306 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override {
307 (void)Instr;
308 return 0;
309 }
John Porto5e0a8a72015-11-20 13:50:36 -0800310 void genTargetHelperCallFor(Inst *Instr) override { (void)Instr; }
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700311 void doAddressOptLoad() override;
312 void doAddressOptStore() override;
Qining Luaee5fa82015-08-20 14:59:03 -0700313 void randomlyInsertNop(float Probability,
314 RandomNumberGenerator &RNG) override;
315 void
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800316 makeRandomRegisterPermutation(llvm::SmallVectorImpl<RegNumT> &Permutation,
John Portoe82b5602016-02-24 15:58:55 -0800317 const SmallBitVector &ExcludeRegisters,
Qining Luaee5fa82015-08-20 14:59:03 -0700318 uint64_t Salt) const override;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700319
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700320 bool UsesFramePointer = false;
321 bool NeedsStackAlignment = false;
John Portoe82b5602016-02-24 15:58:55 -0800322 static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM];
323 static SmallBitVector TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
324 static SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM];
325 SmallBitVector RegsUsed;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700326 VarList PhysicalRegisters[IceType_NUM];
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700327
328private:
John Porto53611e22015-12-30 07:30:10 -0800329 ENABLE_MAKE_UNIQUE;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700330};
331
John Porto0f86d032015-06-15 07:44:27 -0700332class TargetDataMIPS32 final : public TargetDataLowering {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700333 TargetDataMIPS32() = delete;
334 TargetDataMIPS32(const TargetDataMIPS32 &) = delete;
335 TargetDataMIPS32 &operator=(const TargetDataMIPS32 &) = delete;
336
337public:
Jan Voungfb792842015-06-11 15:27:50 -0700338 static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
339 return std::unique_ptr<TargetDataLowering>(new TargetDataMIPS32(Ctx));
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700340 }
341
John Porto8b1a7052015-06-17 13:20:08 -0700342 void lowerGlobals(const VariableDeclarationList &Vars,
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700343 const std::string &SectionSuffix) override;
John Porto0f86d032015-06-15 07:44:27 -0700344 void lowerConstants() override;
Andrew Scull86df4e92015-07-30 13:54:44 -0700345 void lowerJumpTables() override;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700346
347protected:
348 explicit TargetDataMIPS32(GlobalContext *Ctx);
349
350private:
Jim Stichnothe587d942015-06-22 15:49:04 -0700351 ~TargetDataMIPS32() override = default;
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700352 template <typename T> static void emitConstantPool(GlobalContext *Ctx);
353};
354
Jan Voungfb792842015-06-11 15:27:50 -0700355class TargetHeaderMIPS32 final : public TargetHeaderLowering {
356 TargetHeaderMIPS32() = delete;
357 TargetHeaderMIPS32(const TargetHeaderMIPS32 &) = delete;
358 TargetHeaderMIPS32 &operator=(const TargetHeaderMIPS32 &) = delete;
359
360public:
361 static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
362 return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderMIPS32(Ctx));
363 }
364
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700365 void lower() override;
366
Jan Voungfb792842015-06-11 15:27:50 -0700367protected:
368 explicit TargetHeaderMIPS32(GlobalContext *Ctx);
369
370private:
371 ~TargetHeaderMIPS32() = default;
372};
373
John Porto4a566862016-01-04 09:33:41 -0800374} // end of namespace MIPS32
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700375} // end of namespace Ice
376
377#endif // SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H