blob: 1506e020edf1aa014823760e1e3452b4fd9fab0b [file] [log] [blame]
Reed Kotlerd00d48d2015-07-08 09:49:07 -07001//===- subzero/src/IceInstMips32.cpp - Mips32 instruction implementation --===//
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//===----------------------------------------------------------------------===//
9//
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the InstMips32 and OperandMips32 classes, primarily the
Andrew Scull57e12682015-09-16 11:30:19 -070012/// constructors and the dump()/emit() methods.
Reed Kotlerd00d48d2015-07-08 09:49:07 -070013///
14//===----------------------------------------------------------------------===//
Reed Kotlerd00d48d2015-07-08 09:49:07 -070015#include "IceAssemblerMIPS32.h"
16#include "IceCfg.h"
17#include "IceCfgNode.h"
18#include "IceInst.h"
19#include "IceInstMIPS32.h"
20#include "IceOperand.h"
21#include "IceRegistersMIPS32.h"
22#include "IceTargetLoweringMIPS32.h"
Jim Stichnothac8da5c2015-10-21 06:57:46 -070023#include <limits>
Reed Kotlerd00d48d2015-07-08 09:49:07 -070024
25namespace Ice {
John Porto4a566862016-01-04 09:33:41 -080026namespace MIPS32 {
Reed Kotlerd00d48d2015-07-08 09:49:07 -070027
Sagar Thakur5cce7612016-05-24 06:25:50 -070028const struct InstMIPS32CondAttributes_ {
29 CondMIPS32::Cond Opposite;
30 const char *EmitString;
31} InstMIPS32CondAttributes[] = {
32#define X(tag, opp, emit) \
33 { CondMIPS32::opp, emit } \
34 ,
35 ICEINSTMIPS32COND_TABLE
36#undef X
37};
38
Jim Stichnothac8da5c2015-10-21 06:57:46 -070039bool OperandMIPS32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
40 (void)SignExt;
41 (void)Ty;
42 if ((std::numeric_limits<int16_t>::min() <= Offset) &&
43 (Offset <= std::numeric_limits<int16_t>::max()))
44 return true;
45 return false;
46}
47
48OperandMIPS32Mem::OperandMIPS32Mem(Cfg *Func, Type Ty, Variable *Base,
Mohit Bhakkadd1e97772016-07-07 05:07:35 -070049 Operand *ImmOffset, AddrMode Mode)
Jim Stichnothac8da5c2015-10-21 06:57:46 -070050 : OperandMIPS32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Mode(Mode) {
51 // The Neg modes are only needed for Reg +/- Reg.
52 (void)Func;
53 // assert(!isNegAddrMode());
54 NumVars = 1;
55 Vars = &this->Base;
56}
57
Jan Voung3469b022015-07-09 10:32:31 -070058const char *InstMIPS32::getWidthString(Type Ty) {
59 (void)Ty;
60 return "TBD";
61}
Reed Kotlerd00d48d2015-07-08 09:49:07 -070062
Srdjan Obucina53d05682016-09-10 08:25:37 -070063template <> const char *InstMIPS32Abs_d::Opcode = "abs.d";
64template <> const char *InstMIPS32Abs_s::Opcode = "abs.s";
Jaydeep Patil130aca72016-10-28 05:30:54 -070065template <> const char *InstMIPS32Addi::Opcode = "addi";
Reed Kotler37af5b02015-11-05 17:07:19 -080066template <> const char *InstMIPS32Add::Opcode = "add";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -070067template <> const char *InstMIPS32Add_d::Opcode = "add.d";
68template <> const char *InstMIPS32Add_s::Opcode = "add.s";
Srdjan Obucina418135a2016-06-02 06:47:06 -070069template <> const char *InstMIPS32Addiu::Opcode = "addiu";
Reed Kotler00e36042016-02-01 20:52:19 -080070template <> const char *InstMIPS32Addu::Opcode = "addu";
Reed Kotler37af5b02015-11-05 17:07:19 -080071template <> const char *InstMIPS32And::Opcode = "and";
Sagar Thakur38dcb592016-05-09 11:57:59 -070072template <> const char *InstMIPS32Andi::Opcode = "andi";
Srdjan Obucinaf315f0d2016-09-13 05:46:30 -070073template <> const char *InstMIPS32C_eq_d::Opcode = "c.eq.d";
74template <> const char *InstMIPS32C_eq_s::Opcode = "c.eq.s";
75template <> const char *InstMIPS32C_ole_d::Opcode = "c.ole.d";
76template <> const char *InstMIPS32C_ole_s::Opcode = "c.ole.s";
77template <> const char *InstMIPS32C_olt_d::Opcode = "c.olt.d";
78template <> const char *InstMIPS32C_olt_s::Opcode = "c.olt.s";
79template <> const char *InstMIPS32C_ueq_d::Opcode = "c.ueq.d";
80template <> const char *InstMIPS32C_ueq_s::Opcode = "c.ueq.s";
81template <> const char *InstMIPS32C_ule_d::Opcode = "c.ule.d";
82template <> const char *InstMIPS32C_ule_s::Opcode = "c.ule.s";
83template <> const char *InstMIPS32C_ult_d::Opcode = "c.ult.d";
84template <> const char *InstMIPS32C_ult_s::Opcode = "c.ult.s";
85template <> const char *InstMIPS32C_un_d::Opcode = "c.un.d";
86template <> const char *InstMIPS32C_un_s::Opcode = "c.un.s";
Srdjan Obucinad27ce3d2016-09-22 12:56:12 -070087template <> const char *InstMIPS32Clz::Opcode = "clz";
Srdjan Obucina418135a2016-06-02 06:47:06 -070088template <> const char *InstMIPS32Cvt_d_l::Opcode = "cvt.d.l";
89template <> const char *InstMIPS32Cvt_d_s::Opcode = "cvt.d.s";
90template <> const char *InstMIPS32Cvt_d_w::Opcode = "cvt.d.w";
91template <> const char *InstMIPS32Cvt_s_d::Opcode = "cvt.s.d";
92template <> const char *InstMIPS32Cvt_s_l::Opcode = "cvt.s.l";
93template <> const char *InstMIPS32Cvt_s_w::Opcode = "cvt.s.w";
Srdjan Obucinaae93eee2016-05-18 11:31:15 -070094template <> const char *InstMIPS32Div::Opcode = "div";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -070095template <> const char *InstMIPS32Div_d::Opcode = "div.d";
96template <> const char *InstMIPS32Div_s::Opcode = "div.s";
Srdjan Obucinaae93eee2016-05-18 11:31:15 -070097template <> const char *InstMIPS32Divu::Opcode = "divu";
Srdjan Obucina418135a2016-06-02 06:47:06 -070098template <> const char *InstMIPS32La::Opcode = "la";
99template <> const char *InstMIPS32Ldc1::Opcode = "ldc1";
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800100template <> const char *InstMIPS32Ll::Opcode = "ll";
Srdjan Obucina418135a2016-06-02 06:47:06 -0700101template <> const char *InstMIPS32Lui::Opcode = "lui";
Sagar Thakur633394c2016-06-25 08:34:10 -0700102template <> const char *InstMIPS32Lw::Opcode = "lw";
Srdjan Obucina418135a2016-06-02 06:47:06 -0700103template <> const char *InstMIPS32Lwc1::Opcode = "lwc1";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700104template <> const char *InstMIPS32Mfc1::Opcode = "mfc1";
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800105template <> const char *InstMIPS32Mfhi::Opcode = "mfhi";
106template <> const char *InstMIPS32Mflo::Opcode = "mflo";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700107template <> const char *InstMIPS32Mov_d::Opcode = "mov.d";
108template <> const char *InstMIPS32Mov_s::Opcode = "mov.s";
Srdjan Obucinaf315f0d2016-09-13 05:46:30 -0700109template <> const char *InstMIPS32Movf::Opcode = "movf";
Srdjan Obucinad57ed5f2016-09-14 06:06:24 -0700110template <> const char *InstMIPS32Movn::Opcode = "movn";
111template <> const char *InstMIPS32Movn_d::Opcode = "movn.d";
112template <> const char *InstMIPS32Movn_s::Opcode = "movn.s";
Srdjan Obucinaf315f0d2016-09-13 05:46:30 -0700113template <> const char *InstMIPS32Movt::Opcode = "movt";
Srdjan Obucinad57ed5f2016-09-14 06:06:24 -0700114template <> const char *InstMIPS32Movz::Opcode = "movz";
115template <> const char *InstMIPS32Movz_d::Opcode = "movz.d";
116template <> const char *InstMIPS32Movz_s::Opcode = "movz.s";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700117template <> const char *InstMIPS32Mtc1::Opcode = "mtc1";
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800118template <> const char *InstMIPS32Mthi::Opcode = "mthi";
119template <> const char *InstMIPS32Mtlo::Opcode = "mtlo";
Reed Kotler37af5b02015-11-05 17:07:19 -0800120template <> const char *InstMIPS32Mul::Opcode = "mul";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700121template <> const char *InstMIPS32Mul_d::Opcode = "mul.d";
122template <> const char *InstMIPS32Mul_s::Opcode = "mul.s";
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800123template <> const char *InstMIPS32Mult::Opcode = "mult";
124template <> const char *InstMIPS32Multu::Opcode = "multu";
Srdjan Obucinacadda792016-09-22 11:24:44 -0700125template <> const char *InstMIPS32Nor::Opcode = "nor";
Reed Kotler37af5b02015-11-05 17:07:19 -0800126template <> const char *InstMIPS32Or::Opcode = "or";
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700127template <> const char *InstMIPS32Ori::Opcode = "ori";
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800128template <> const char *InstMIPS32Sc::Opcode = "sc";
Srdjan Obucina418135a2016-06-02 06:47:06 -0700129template <> const char *InstMIPS32Sdc1::Opcode = "sdc1";
Sagar Thakur38dcb592016-05-09 11:57:59 -0700130template <> const char *InstMIPS32Sll::Opcode = "sll";
Srdjan Obucinac2ee36a2016-05-17 13:16:02 -0700131template <> const char *InstMIPS32Sllv::Opcode = "sllv";
Sagar Thakur1a478b12016-04-25 08:39:19 -0700132template <> const char *InstMIPS32Slt::Opcode = "slt";
133template <> const char *InstMIPS32Slti::Opcode = "slti";
134template <> const char *InstMIPS32Sltiu::Opcode = "sltiu";
Reed Kotler00e36042016-02-01 20:52:19 -0800135template <> const char *InstMIPS32Sltu::Opcode = "sltu";
Srdjan Obucina53d05682016-09-10 08:25:37 -0700136template <> const char *InstMIPS32Sqrt_d::Opcode = "sqrt.d";
137template <> const char *InstMIPS32Sqrt_s::Opcode = "sqrt.s";
Sagar Thakur38dcb592016-05-09 11:57:59 -0700138template <> const char *InstMIPS32Sra::Opcode = "sra";
Srdjan Obucinac2ee36a2016-05-17 13:16:02 -0700139template <> const char *InstMIPS32Srav::Opcode = "srav";
140template <> const char *InstMIPS32Srl::Opcode = "srl";
141template <> const char *InstMIPS32Srlv::Opcode = "srlv";
Reed Kotler37af5b02015-11-05 17:07:19 -0800142template <> const char *InstMIPS32Sub::Opcode = "sub";
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700143template <> const char *InstMIPS32Sub_d::Opcode = "sub.d";
144template <> const char *InstMIPS32Sub_s::Opcode = "sub.s";
Reed Kotler00e36042016-02-01 20:52:19 -0800145template <> const char *InstMIPS32Subu::Opcode = "subu";
Mohit Bhakkadf3bc5cf2016-05-31 11:19:03 -0700146template <> const char *InstMIPS32Sw::Opcode = "sw";
Srdjan Obucina418135a2016-06-02 06:47:06 -0700147template <> const char *InstMIPS32Swc1::Opcode = "swc1";
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800148const char *InstMIPS32Sync::Opcode = "sync";
Jaydeep Patilcc6dea72016-09-19 16:48:34 -0700149template <> const char *InstMIPS32Teq::Opcode = "teq";
Srdjan Obucina418135a2016-06-02 06:47:06 -0700150template <> const char *InstMIPS32Trunc_l_d::Opcode = "trunc.l.d";
151template <> const char *InstMIPS32Trunc_l_s::Opcode = "trunc.l.s";
152template <> const char *InstMIPS32Trunc_w_d::Opcode = "trunc.w.d";
153template <> const char *InstMIPS32Trunc_w_s::Opcode = "trunc.w.s";
Reed Kotler37af5b02015-11-05 17:07:19 -0800154template <> const char *InstMIPS32Xor::Opcode = "xor";
Sagar Thakur1a478b12016-04-25 08:39:19 -0700155template <> const char *InstMIPS32Xori::Opcode = "xori";
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700156
Mohit Bhakkadd1e97772016-07-07 05:07:35 -0700157template <> void InstMIPS32Lui::emit(const Cfg *Func) const {
158 if (!BuildDefs::dump())
159 return;
160 Ostream &Str = Func->getContext()->getStrEmit();
161 assert(getSrcSize() == 1);
162 Str << "\t" << Opcode << "\t";
163 getDest()->emit(Func);
164 Str << ", ";
165 auto *Src0 = llvm::cast<Constant>(getSrc(0));
166 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
167 emitRelocOp(Str, Reloc);
168 Str << "(";
169 CR->emitWithoutPrefix(Func->getTarget());
170 Str << ")";
171 } else {
172 Src0->emit(Func);
173 }
174}
175
Reed Kotler3fe4b572016-02-23 18:59:43 -0800176InstMIPS32Br::InstMIPS32Br(Cfg *Func, const CfgNode *TargetTrue,
177 const CfgNode *TargetFalse,
Sagar Thakur5cce7612016-05-24 06:25:50 -0700178 const InstMIPS32Label *Label, CondMIPS32::Cond Cond)
Reed Kotler3fe4b572016-02-23 18:59:43 -0800179 : InstMIPS32(Func, InstMIPS32::Br, 0, nullptr), TargetTrue(TargetTrue),
Sagar Thakur5cce7612016-05-24 06:25:50 -0700180 TargetFalse(TargetFalse), Label(Label), Predicate(Cond) {}
181
182InstMIPS32Br::InstMIPS32Br(Cfg *Func, const CfgNode *TargetTrue,
183 const CfgNode *TargetFalse, Operand *Src0,
184 const InstMIPS32Label *Label, CondMIPS32::Cond Cond)
185 : InstMIPS32(Func, InstMIPS32::Br, 1, nullptr), TargetTrue(TargetTrue),
186 TargetFalse(TargetFalse), Label(Label), Predicate(Cond) {
187 addSource(Src0);
188}
189
190InstMIPS32Br::InstMIPS32Br(Cfg *Func, const CfgNode *TargetTrue,
191 const CfgNode *TargetFalse, Operand *Src0,
192 Operand *Src1, const InstMIPS32Label *Label,
193 CondMIPS32::Cond Cond)
194 : InstMIPS32(Func, InstMIPS32::Br, 2, nullptr), TargetTrue(TargetTrue),
195 TargetFalse(TargetFalse), Label(Label), Predicate(Cond) {
196 addSource(Src0);
197 addSource(Src1);
198}
Reed Kotler3fe4b572016-02-23 18:59:43 -0800199
Jaydeep Patil13f0ca32016-08-26 13:27:40 -0700200CondMIPS32::Cond InstMIPS32::getOppositeCondition(CondMIPS32::Cond Cond) {
201 return InstMIPS32CondAttributes[Cond].Opposite;
202}
203
204bool InstMIPS32Br::optimizeBranch(const CfgNode *NextNode) {
205 // If there is no next block, then there can be no fallthrough to optimize.
206 if (NextNode == nullptr)
207 return false;
208 // Intra-block conditional branches can't be optimized.
209 if (Label != nullptr)
210 return false;
211 // Unconditional branch to the next node can be removed.
212 if (isUnconditionalBranch() && getTargetFalse() == NextNode) {
213 assert(getTargetTrue() == nullptr);
214 setDeleted();
215 return true;
216 }
217 // If there is no fallthrough node, such as a non-default case label for a
218 // switch instruction, then there is no opportunity to optimize.
219 if (getTargetTrue() == nullptr)
220 return false;
221 // If the fallthrough is to the next node, set fallthrough to nullptr to
222 // indicate.
223 if (getTargetTrue() == NextNode) {
224 TargetTrue = nullptr;
225 return true;
226 }
227 // If TargetFalse is the next node, and TargetTrue is not nullptr
228 // then invert the branch condition, swap the targets, and set new
229 // fallthrough to nullptr.
230 if (getTargetFalse() == NextNode) {
231 assert(Predicate != CondMIPS32::AL);
232 setPredicate(getOppositeCondition(getPredicate()));
233 TargetFalse = getTargetTrue();
234 TargetTrue = nullptr;
235 return true;
236 }
237 return false;
238}
239
Jaydeep Patil8b322412016-08-18 22:43:43 -0700240bool InstMIPS32Br::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
241 bool Found = false;
242 if (TargetFalse == OldNode) {
243 TargetFalse = NewNode;
244 Found = true;
245 }
246 if (TargetTrue == OldNode) {
247 TargetTrue = NewNode;
248 Found = true;
249 }
250 return Found;
251}
252
Reed Kotler3fe4b572016-02-23 18:59:43 -0800253InstMIPS32Label::InstMIPS32Label(Cfg *Func, TargetMIPS32 *Target)
254 : InstMIPS32(Func, InstMIPS32::Label, 0, nullptr),
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700255 Number(Target->makeNextLabelNumber()) {
256 if (BuildDefs::dump()) {
257 Name = GlobalString::createWithString(
258 Func->getContext(),
259 ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number));
260 } else {
261 Name = GlobalString::createWithoutString(Func->getContext());
262 }
Reed Kotler3fe4b572016-02-23 18:59:43 -0800263}
264
265void InstMIPS32Label::dump(const Cfg *Func) const {
266 if (!BuildDefs::dump())
267 return;
268 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700269 Str << getLabelName() << ":";
Reed Kotler3fe4b572016-02-23 18:59:43 -0800270}
271
Jim Stichnoth09802a92016-02-24 07:05:12 -0800272void InstMIPS32Label::emit(const Cfg *Func) const {
273 if (!BuildDefs::dump())
274 return;
275 Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700276 Str << getLabelName() << ":";
Jim Stichnoth09802a92016-02-24 07:05:12 -0800277}
278
Reed Kotler3fe4b572016-02-23 18:59:43 -0800279void InstMIPS32Label::emitIAS(const Cfg *Func) const {
Jaydeep Patil58eeedf2016-09-26 20:48:18 -0700280 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
281 Asm->bindLocalLabel(this, Number);
Reed Kotler3fe4b572016-02-23 18:59:43 -0800282}
283
Reed Kotler00e36042016-02-01 20:52:19 -0800284InstMIPS32Call::InstMIPS32Call(Cfg *Func, Variable *Dest, Operand *CallTarget)
285 : InstMIPS32(Func, InstMIPS32::Call, 1, Dest) {
286 HasSideEffects = true;
287 addSource(CallTarget);
288}
289
Sagar Thakurb001cc42016-10-11 23:36:01 -0700290InstMIPS32Mov::InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src,
291 Operand *Src2)
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700292 : InstMIPS32(Func, InstMIPS32::Mov, 2, Dest) {
293 auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest);
294 auto *Src64 = llvm::dyn_cast<Variable64On32>(Src);
295
296 assert(Dest64 == nullptr || Src64 == nullptr);
297
Sagar Thakurb001cc42016-10-11 23:36:01 -0700298 if (Dest->getType() == IceType_f64 && Src2 != nullptr) {
299 addSource(Src);
300 addSource(Src2);
301 return;
302 }
303
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700304 if (Dest64 != nullptr) {
305 // this-> is needed below because there is a parameter named Dest.
306 this->Dest = Dest64->getLo();
307 DestHi = Dest64->getHi();
308 }
309
310 if (Src64 == nullptr) {
311 addSource(Src);
312 } else {
313 addSource(Src64->getLo());
314 addSource(Src64->getHi());
315 }
316}
317
Jaydeep Patil2bbda7f2017-01-10 21:48:58 -0800318InstMIPS32MovFP64ToI64::InstMIPS32MovFP64ToI64(Cfg *Func, Variable *Dst,
319 Operand *Src,
320 Int64Part Int64HiLo)
321 : InstMIPS32(Func, InstMIPS32::Mov_fp, 1, Dst), Int64HiLo(Int64HiLo) {
322 addSource(Src);
323}
324
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700325InstMIPS32Ret::InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source)
326 : InstMIPS32(Func, InstMIPS32::Ret, Source ? 2 : 1, nullptr) {
327 addSource(RA);
328 if (Source)
329 addSource(Source);
330}
331
Jan Voung3469b022015-07-09 10:32:31 -0700332// ======================== Dump routines ======================== //
333
334void InstMIPS32::dump(const Cfg *Func) const {
335 if (!BuildDefs::dump())
336 return;
337 Ostream &Str = Func->getContext()->getStrDump();
338 Str << "[MIPS32] ";
339 Inst::dump(Func);
340}
341
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700342void OperandMIPS32Mem::emit(const Cfg *Func) const {
343 if (!BuildDefs::dump())
344 return;
Mohit Bhakkadf3bc5cf2016-05-31 11:19:03 -0700345 Ostream &Str = Func->getContext()->getStrEmit();
Mohit Bhakkadd1e97772016-07-07 05:07:35 -0700346 Operand *Offset = getOffset();
347 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
Mohit Bhakkad6a661ce2016-07-13 07:32:37 -0700348 Str << "(";
Mohit Bhakkadd1e97772016-07-07 05:07:35 -0700349 CR->emitWithoutPrefix(Func->getTarget());
Mohit Bhakkad6a661ce2016-07-13 07:32:37 -0700350 Str << ")";
Mohit Bhakkadd1e97772016-07-07 05:07:35 -0700351 } else
352 Offset->emit(Func);
Mohit Bhakkadf3bc5cf2016-05-31 11:19:03 -0700353 Str << "(";
354 getBase()->emit(Func);
355 Str << ")";
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700356}
357
358void InstMIPS32::emitUnaryopGPR(const char *Opcode, const InstMIPS32 *Inst,
359 const Cfg *Func) {
360 if (!BuildDefs::dump())
361 return;
362 Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700363 Str << "\t" << Opcode << "\t";
364 Inst->getDest()->emit(Func);
365 Str << ", ";
366 Inst->getSrc(0)->emit(Func);
367}
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800368void InstMIPS32::emitUnaryopGPRFLoHi(const char *Opcode, const InstMIPS32 *Inst,
369 const Cfg *Func) {
370 if (!BuildDefs::dump())
371 return;
372 Ostream &Str = Func->getContext()->getStrEmit();
373 Str << "\t" << Opcode << "\t";
374 Inst->getDest()->emit(Func);
375}
376
377void InstMIPS32::emitUnaryopGPRTLoHi(const char *Opcode, const InstMIPS32 *Inst,
378 const Cfg *Func) {
379 if (!BuildDefs::dump())
380 return;
381 Ostream &Str = Func->getContext()->getStrEmit();
382 Str << "\t" << Opcode << "\t";
383 Inst->getSrc(0)->emit(Func);
384}
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700385
Reed Kotler37af5b02015-11-05 17:07:19 -0800386void InstMIPS32::emitThreeAddr(const char *Opcode, const InstMIPS32 *Inst,
387 const Cfg *Func) {
388 if (!BuildDefs::dump())
389 return;
390 Ostream &Str = Func->getContext()->getStrEmit();
391 assert(Inst->getSrcSize() == 2);
392 Str << "\t" << Opcode << "\t";
393 Inst->getDest()->emit(Func);
394 Str << ", ";
395 Inst->getSrc(0)->emit(Func);
396 Str << ", ";
397 Inst->getSrc(1)->emit(Func);
398}
399
Srdjan Obucina2f593bb2016-05-27 14:40:32 -0700400void InstMIPS32::emitTwoAddr(const char *Opcode, const InstMIPS32 *Inst,
401 const Cfg *Func) {
402 if (!BuildDefs::dump())
403 return;
404 Ostream &Str = Func->getContext()->getStrEmit();
405 assert(Inst->getSrcSize() == 1);
406 Str << "\t" << Opcode << "\t";
407 Inst->getDest()->emit(Func);
408 Str << ", ";
409 Inst->getSrc(0)->emit(Func);
410}
411
Reed Kotlera80cdbc2016-02-19 22:03:29 -0800412void InstMIPS32::emitThreeAddrLoHi(const char *Opcode, const InstMIPS32 *Inst,
413 const Cfg *Func) {
414 if (!BuildDefs::dump())
415 return;
416 Ostream &Str = Func->getContext()->getStrEmit();
417 assert(Inst->getSrcSize() == 2);
418 Str << "\t" << Opcode << "\t";
419 Inst->getSrc(0)->emit(Func);
420 Str << ", ";
421 Inst->getSrc(1)->emit(Func);
422}
423
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700424void InstMIPS32Ret::emit(const Cfg *Func) const {
Jan Voung3469b022015-07-09 10:32:31 -0700425 if (!BuildDefs::dump())
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700426 return;
427 assert(getSrcSize() > 0);
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800428 auto *RA = llvm::cast<Variable>(getSrc(0));
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700429 assert(RA->hasReg());
430 assert(RA->getRegNum() == RegMIPS32::Reg_RA);
431 Ostream &Str = Func->getContext()->getStrEmit();
432 Str << "\t"
Jim Stichnoth6106df82015-12-16 06:17:58 -0800433 "jr"
434 "\t";
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700435 RA->emit(Func);
436}
437
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700438void InstMIPS32Br::emitIAS(const Cfg *Func) const {
439 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil58eeedf2016-09-26 20:48:18 -0700440 if (Label != nullptr) {
441 // Intra-block branches are of kind bcc
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800442 if (isUnconditionalBranch()) {
443 Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()));
444 } else {
445 Asm->bcc(Predicate, getSrc(0), getSrc(1),
446 Asm->getOrCreateLocalLabel(Label->getNumber()));
447 }
Jaydeep Patil58eeedf2016-09-26 20:48:18 -0700448 } else if (isUnconditionalBranch()) {
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700449 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()));
450 } else {
451 switch (Predicate) {
452 default:
453 break;
454 case CondMIPS32::EQ:
455 case CondMIPS32::NE:
456 Asm->bcc(Predicate, getSrc(0), getSrc(1),
457 Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()));
458 break;
459 case CondMIPS32::EQZ:
460 case CondMIPS32::NEZ:
461 case CondMIPS32::LEZ:
462 case CondMIPS32::LTZ:
463 case CondMIPS32::GEZ:
464 case CondMIPS32::GTZ:
465 Asm->bzc(Predicate, getSrc(0),
466 Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()));
467 break;
468 }
Jaydeep Patil58eeedf2016-09-26 20:48:18 -0700469 if (getTargetTrue()) {
470 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()));
471 }
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700472 }
473}
474
Reed Kotler3fe4b572016-02-23 18:59:43 -0800475void InstMIPS32Br::emit(const Cfg *Func) const {
476 if (!BuildDefs::dump())
477 return;
478 Ostream &Str = Func->getContext()->getStrEmit();
479 Str << "\t"
Sagar Thakur5cce7612016-05-24 06:25:50 -0700480 "b" << InstMIPS32CondAttributes[Predicate].EmitString << "\t";
Jaydeep Patil29823f12016-08-31 05:10:03 -0700481 if (Label != nullptr) {
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800482 if (isUnconditionalBranch()) {
483 Str << Label->getLabelName();
484 } else {
485 getSrc(0)->emit(Func);
486 Str << ", ";
487 getSrc(1)->emit(Func);
488 Str << ", " << Label->getLabelName();
489 }
Reed Kotler3fe4b572016-02-23 18:59:43 -0800490 } else {
491 if (isUnconditionalBranch()) {
492 Str << getTargetFalse()->getAsmName();
493 } else {
Sagar Thakur5cce7612016-05-24 06:25:50 -0700494 switch (Predicate) {
495 default:
496 break;
497 case CondMIPS32::EQ:
498 case CondMIPS32::NE: {
499 getSrc(0)->emit(Func);
500 Str << ", ";
501 getSrc(1)->emit(Func);
502 Str << ", ";
503 break;
504 }
505 case CondMIPS32::EQZ:
506 case CondMIPS32::NEZ:
507 case CondMIPS32::LEZ:
508 case CondMIPS32::LTZ:
509 case CondMIPS32::GEZ:
510 case CondMIPS32::GTZ: {
511 getSrc(0)->emit(Func);
512 Str << ", ";
513 break;
514 }
515 }
516 Str << getTargetFalse()->getAsmName();
Jaydeep Patil13f0ca32016-08-26 13:27:40 -0700517 if (getTargetTrue()) {
518 Str << "\n\t"
519 << "b"
520 << "\t" << getTargetTrue()->getAsmName();
521 }
Sagar Thakur5cce7612016-05-24 06:25:50 -0700522 }
523 }
524}
525
526void InstMIPS32Br::dump(const Cfg *Func) const {
527 if (!BuildDefs::dump())
528 return;
529 Ostream &Str = Func->getContext()->getStrDump();
530 Str << "\t"
531 "b" << InstMIPS32CondAttributes[Predicate].EmitString << "\t";
532
Jaydeep Patil29823f12016-08-31 05:10:03 -0700533 if (Label != nullptr) {
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800534 if (isUnconditionalBranch()) {
535 Str << Label->getLabelName();
536 } else {
537 getSrc(0)->dump(Func);
538 Str << ", ";
539 getSrc(1)->dump(Func);
540 Str << ", " << Label->getLabelName();
541 }
Sagar Thakur5cce7612016-05-24 06:25:50 -0700542 } else {
543 if (isUnconditionalBranch()) {
544 Str << getTargetFalse()->getAsmName();
545 } else {
546 dumpSources(Func);
547 Str << ", ";
548 Str << getTargetFalse()->getAsmName();
Jaydeep Patil13f0ca32016-08-26 13:27:40 -0700549 if (getTargetTrue()) {
550 Str << "\n\t"
551 << "b"
552 << "\t" << getTargetTrue()->getAsmName();
553 }
Reed Kotler3fe4b572016-02-23 18:59:43 -0800554 }
555 }
556}
557
Reed Kotler00e36042016-02-01 20:52:19 -0800558void InstMIPS32Call::emit(const Cfg *Func) const {
559 if (!BuildDefs::dump())
560 return;
561 Ostream &Str = Func->getContext()->getStrEmit();
562 assert(getSrcSize() == 1);
563 if (llvm::isa<ConstantInteger32>(getCallTarget())) {
564 // This shouldn't happen (typically have to copy the full 32-bits to a
565 // register and do an indirect jump).
566 llvm::report_fatal_error("MIPS2Call to ConstantInteger32");
567 } else if (const auto *CallTarget =
568 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
Jaydeep Patil130aca72016-10-28 05:30:54 -0700569 // Calls only have 26-bits, but the linker should insert veneers to extend
Reed Kotler00e36042016-02-01 20:52:19 -0800570 // the range if needed.
571 Str << "\t"
572 "jal"
573 "\t";
574 CallTarget->emitWithoutPrefix(Func->getTarget());
575 } else {
576 Str << "\t"
Jaydeep Patil0c4c07d2016-11-01 23:53:52 -0700577 "jalr"
Reed Kotler00e36042016-02-01 20:52:19 -0800578 "\t";
579 getCallTarget()->emit(Func);
580 }
581}
582
583void InstMIPS32Call::emitIAS(const Cfg *Func) const {
Jaydeep Patil130aca72016-10-28 05:30:54 -0700584 assert(getSrcSize() == 1);
585 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil0c4c07d2016-11-01 23:53:52 -0700586 if (llvm::isa<ConstantInteger32>(getCallTarget())) {
587 llvm::report_fatal_error("MIPS32Call to ConstantInteger32");
588 } else if (const auto *CallTarget =
589 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
Jaydeep Patil130aca72016-10-28 05:30:54 -0700590 Asm->jal(CallTarget);
591 } else {
Jaydeep Patil0c4c07d2016-11-01 23:53:52 -0700592 const Operand *ImplicitRA = nullptr;
593 Asm->jalr(getCallTarget(), ImplicitRA);
Jaydeep Patil130aca72016-10-28 05:30:54 -0700594 }
Reed Kotler00e36042016-02-01 20:52:19 -0800595}
596
597void InstMIPS32Call::dump(const Cfg *Func) const {
598 if (!BuildDefs::dump())
599 return;
600 Ostream &Str = Func->getContext()->getStrDump();
601 if (getDest()) {
602 dumpDest(Func);
603 Str << " = ";
604 }
605 Str << "call ";
606 getCallTarget()->dump(Func);
607}
608
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700609void InstMIPS32Ret::emitIAS(const Cfg *Func) const {
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700610 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
611 auto *RA = llvm::cast<Variable>(getSrc(0));
612 assert(RA->hasReg());
613 assert(RA->getRegNum() == RegMIPS32::Reg_RA);
614 (void)RA;
615 Asm->ret();
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700616}
617
618void InstMIPS32Ret::dump(const Cfg *Func) const {
Jan Voung3469b022015-07-09 10:32:31 -0700619 if (!BuildDefs::dump())
Reed Kotlerd00d48d2015-07-08 09:49:07 -0700620 return;
621 Ostream &Str = Func->getContext()->getStrDump();
622 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType());
623 Str << "ret." << Ty << " ";
624 dumpSources(Func);
625}
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700626
627void InstMIPS32Mov::emit(const Cfg *Func) const {
628 if (!BuildDefs::dump())
629 return;
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700630
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700631 Ostream &Str = Func->getContext()->getStrEmit();
Reed Kotler37af5b02015-11-05 17:07:19 -0800632 Variable *Dest = getDest();
633 Operand *Src = getSrc(0);
Srdjan Obucina36847bd2016-07-06 15:58:07 -0700634 auto *SrcV = llvm::dyn_cast<Variable>(Src);
635
636 assert(!llvm::isa<Constant>(Src));
637
638 const char *ActualOpcode = nullptr;
639 const bool DestIsReg = Dest->hasReg();
Srdjan Obucina36847bd2016-07-06 15:58:07 -0700640 const bool SrcIsReg = (SrcV && SrcV->hasReg());
Srdjan Obucina36847bd2016-07-06 15:58:07 -0700641
642 // reg to reg
643 if (DestIsReg && SrcIsReg) {
Jaydeep Patild3297662016-09-13 22:52:27 -0700644 const Type DstType = Dest->getType();
645 const Type SrcType = Src->getType();
646
647 // move GP to/from FP
Srdjan Obucinad57ed5f2016-09-14 06:06:24 -0700648 if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
649 (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
Jaydeep Patild3297662016-09-13 22:52:27 -0700650 if (isScalarFloatingType(DstType)) {
651 Str << "\t"
652 "mtc1"
653 "\t";
654 getSrc(0)->emit(Func);
655 Str << ", ";
656 getDest()->emit(Func);
657 return;
658 }
659 ActualOpcode = "mfc1";
660 } else {
661 switch (Dest->getType()) {
662 case IceType_f32:
663 ActualOpcode = "mov.s";
664 break;
665 case IceType_f64:
666 ActualOpcode = "mov.d";
667 break;
668 case IceType_i1:
669 case IceType_i8:
670 case IceType_i16:
671 case IceType_i32:
672 ActualOpcode = "move";
673 break;
674 default:
675 UnimplementedError(getFlags());
676 return;
677 }
Srdjan Obucina36847bd2016-07-06 15:58:07 -0700678 }
679
680 assert(ActualOpcode);
681 Str << "\t" << ActualOpcode << "\t";
682 getDest()->emit(Func);
683 Str << ", ";
684 getSrc(0)->emit(Func);
685 return;
Reed Kotler37af5b02015-11-05 17:07:19 -0800686 }
687
Jaydeep Patil1d0690b2016-09-04 07:19:08 -0700688 llvm::report_fatal_error("Invalid mov instruction. Dest or Src is memory.");
Jim Stichnothac8da5c2015-10-21 06:57:46 -0700689}
690
Sagar Thakurb001cc42016-10-11 23:36:01 -0700691void InstMIPS32Mov::emitIAS(const Cfg *Func) const {
692 Variable *Dest = getDest();
693 Operand *Src = getSrc(0);
694 auto *SrcV = llvm::dyn_cast<Variable>(Src);
695 assert(!llvm::isa<Constant>(Src));
696 const bool DestIsReg = Dest->hasReg();
697 const bool SrcIsReg = (SrcV && SrcV->hasReg());
698
699 // reg to reg
700 if (DestIsReg && SrcIsReg) {
701 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
702 Asm->move(getDest(), getSrc(0));
703 return;
704 }
Jaydeep Patil130aca72016-10-28 05:30:54 -0700705
706 llvm::report_fatal_error("InstMIPS32Mov invalid operands");
Sagar Thakurb001cc42016-10-11 23:36:01 -0700707}
708
709void InstMIPS32Mov::dump(const Cfg *Func) const {
710 if (!BuildDefs::dump())
711 return;
712 assert(getSrcSize() == 1 || getSrcSize() == 2);
713 Ostream &Str = Func->getContext()->getStrDump();
714 Variable *Dest = getDest();
715 Variable *DestHi = getDestHi();
716 Dest->dump(Func);
717 if (DestHi) {
718 Str << ", ";
719 DestHi->dump(Func);
720 }
721 dumpOpcode(Str, " = mov", getDest()->getType());
722 Str << " ";
723 dumpSources(Func);
724}
725
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700726template <> void InstMIPS32Abs_d::emitIAS(const Cfg *Func) const {
727 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
728 Asm->abs_d(getDest(), getSrc(0));
729}
730
731template <> void InstMIPS32Abs_s::emitIAS(const Cfg *Func) const {
732 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
733 Asm->abs_s(getDest(), getSrc(0));
734}
735
Jaydeep Patil130aca72016-10-28 05:30:54 -0700736template <> void InstMIPS32Addi::emitIAS(const Cfg *Func) const {
737 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
738 Asm->addi(getDest(), getSrc(0), Imm);
739}
740
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700741template <> void InstMIPS32Add_d::emitIAS(const Cfg *Func) const {
742 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
743 Asm->add_d(getDest(), getSrc(0), getSrc(1));
744}
745
746template <> void InstMIPS32Add_s::emitIAS(const Cfg *Func) const {
747 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
748 Asm->add_s(getDest(), getSrc(0), getSrc(1));
749}
750
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700751template <> void InstMIPS32Addiu::emitIAS(const Cfg *Func) const {
752 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -0700753 if (Reloc == RO_No) {
754 Asm->addiu(getDest(), getSrc(0), Imm);
755 } else {
756 Asm->addiu(getDest(), getSrc(0), getSrc(1), Reloc);
757 }
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700758}
759
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700760template <> void InstMIPS32Addu::emitIAS(const Cfg *Func) const {
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700761 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700762 Asm->addu(getDest(), getSrc(0), getSrc(1));
Jaydeep Patil135f5db2016-08-29 05:14:05 -0700763}
764
765template <> void InstMIPS32And::emitIAS(const Cfg *Func) const {
766 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
767 Asm->and_(getDest(), getSrc(0), getSrc(1));
768}
769
770template <> void InstMIPS32Andi::emitIAS(const Cfg *Func) const {
771 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
772 Asm->andi(getDest(), getSrc(0), Imm);
773}
774
Srdjan Obucina8d16c1d2016-09-20 08:44:44 -0700775template <> void InstMIPS32C_eq_d::emitIAS(const Cfg *Func) const {
776 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
777 Asm->c_eq_d(getSrc(0), getSrc(1));
778}
779
780template <> void InstMIPS32C_eq_s::emitIAS(const Cfg *Func) const {
781 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
782 Asm->c_eq_s(getSrc(0), getSrc(1));
783}
784
785template <> void InstMIPS32C_ole_d::emitIAS(const Cfg *Func) const {
786 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
787 Asm->c_ole_d(getSrc(0), getSrc(1));
788}
789
790template <> void InstMIPS32C_ole_s::emitIAS(const Cfg *Func) const {
791 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
792 Asm->c_ole_s(getSrc(0), getSrc(1));
793}
794
795template <> void InstMIPS32C_olt_d::emitIAS(const Cfg *Func) const {
796 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
797 Asm->c_olt_d(getSrc(0), getSrc(1));
798}
799
800template <> void InstMIPS32C_olt_s::emitIAS(const Cfg *Func) const {
801 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
802 Asm->c_olt_s(getSrc(0), getSrc(1));
803}
804
805template <> void InstMIPS32C_ueq_d::emitIAS(const Cfg *Func) const {
806 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
807 Asm->c_ueq_d(getSrc(0), getSrc(1));
808}
809
810template <> void InstMIPS32C_ueq_s::emitIAS(const Cfg *Func) const {
811 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
812 Asm->c_ueq_s(getSrc(0), getSrc(1));
813}
814
815template <> void InstMIPS32C_ule_d::emitIAS(const Cfg *Func) const {
816 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
817 Asm->c_ule_d(getSrc(0), getSrc(1));
818}
819
820template <> void InstMIPS32C_ule_s::emitIAS(const Cfg *Func) const {
821 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
822 Asm->c_ule_s(getSrc(0), getSrc(1));
823}
824
825template <> void InstMIPS32C_ult_d::emitIAS(const Cfg *Func) const {
826 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
827 Asm->c_ult_d(getSrc(0), getSrc(1));
828}
829
830template <> void InstMIPS32C_ult_s::emitIAS(const Cfg *Func) const {
831 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
832 Asm->c_ult_s(getSrc(0), getSrc(1));
833}
834
835template <> void InstMIPS32C_un_d::emitIAS(const Cfg *Func) const {
836 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
837 Asm->c_un_d(getSrc(0), getSrc(1));
838}
839
840template <> void InstMIPS32C_un_s::emitIAS(const Cfg *Func) const {
841 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
842 Asm->c_un_s(getSrc(0), getSrc(1));
843}
844
Srdjan Obucinad27ce3d2016-09-22 12:56:12 -0700845template <> void InstMIPS32Clz::emitIAS(const Cfg *Func) const {
846 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
847 Asm->clz(getDest(), getSrc(0));
848}
849
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700850template <> void InstMIPS32Cvt_d_l::emitIAS(const Cfg *Func) const {
851 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
852 Asm->cvt_d_l(getDest(), getSrc(0));
853}
854
855template <> void InstMIPS32Cvt_d_s::emitIAS(const Cfg *Func) const {
856 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
857 Asm->cvt_d_s(getDest(), getSrc(0));
858}
859
860template <> void InstMIPS32Cvt_d_w::emitIAS(const Cfg *Func) const {
861 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
862 Asm->cvt_d_w(getDest(), getSrc(0));
863}
864
865template <> void InstMIPS32Cvt_s_d::emitIAS(const Cfg *Func) const {
866 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
867 Asm->cvt_s_d(getDest(), getSrc(0));
868}
869
870template <> void InstMIPS32Cvt_s_l::emitIAS(const Cfg *Func) const {
871 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
872 Asm->cvt_s_l(getDest(), getSrc(0));
873}
874
875template <> void InstMIPS32Cvt_s_w::emitIAS(const Cfg *Func) const {
876 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
877 Asm->cvt_s_w(getDest(), getSrc(0));
878}
879
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700880template <> void InstMIPS32Div::emitIAS(const Cfg *Func) const {
881 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -0700882 Asm->div(getSrc(0), getSrc(1));
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700883}
884
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700885template <> void InstMIPS32Div_d::emitIAS(const Cfg *Func) const {
886 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
887 Asm->div_d(getDest(), getSrc(0), getSrc(1));
888}
889
890template <> void InstMIPS32Div_s::emitIAS(const Cfg *Func) const {
891 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
892 Asm->div_s(getDest(), getSrc(0), getSrc(1));
893}
894
Srdjan Obucina6163c622016-09-27 20:38:30 -0700895template <> void InstMIPS32Divu::emitIAS(const Cfg *Func) const {
896 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -0700897 Asm->divu(getSrc(0), getSrc(1));
Srdjan Obucina6163c622016-09-27 20:38:30 -0700898}
899
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700900template <> void InstMIPS32Lui::emitIAS(const Cfg *Func) const {
901 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -0700902 Asm->lui(getDest(), getSrc(0), Reloc);
903}
904
905template <> void InstMIPS32Ldc1::emitIAS(const Cfg *Func) const {
906 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
907 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
908 Asm->ldc1(getDest(), Mem->getBase(), Mem->getOffset(), Reloc);
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700909}
910
Sagar Thakurbecb85f2016-11-18 12:15:46 -0800911template <> void InstMIPS32Ll::emitIAS(const Cfg *Func) const {
912 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
913 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
914 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
915 uint32_t Imm = static_cast<uint32_t>(Offset->getValue());
916 Asm->ll(getDest(), Mem->getBase(), Imm);
917}
918
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700919template <> void InstMIPS32Lw::emitIAS(const Cfg *Func) const {
920 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
921 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
922 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
923 uint32_t Imm = static_cast<uint32_t>(Offset->getValue());
924 Asm->lw(getDest(), Mem->getBase(), Imm);
925}
926
Jaydeep Patil130aca72016-10-28 05:30:54 -0700927template <> void InstMIPS32Lwc1::emitIAS(const Cfg *Func) const {
928 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
929 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
930 Asm->lwc1(getDest(), Mem->getBase(), Mem->getOffset(), Reloc);
931}
932
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700933template <> void InstMIPS32Mfc1::emitIAS(const Cfg *Func) const {
934 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
935 Asm->mfc1(getDest(), getSrc(0));
936}
937
938template <> void InstMIPS32Mflo::emit(const Cfg *Func) const {
939 if (!BuildDefs::dump())
940 return;
941 emitUnaryopGPRFLoHi(Opcode, this, Func);
942}
943
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700944template <> void InstMIPS32Mflo::emitIAS(const Cfg *Func) const {
945 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
946 Asm->mflo(getDest());
947}
948
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700949template <> void InstMIPS32Mfhi::emit(const Cfg *Func) const {
950 if (!BuildDefs::dump())
951 return;
952 emitUnaryopGPRFLoHi(Opcode, this, Func);
953}
954
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700955template <> void InstMIPS32Mfhi::emitIAS(const Cfg *Func) const {
956 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
957 Asm->mfhi(getDest());
958}
959
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700960template <> void InstMIPS32Mov_d::emitIAS(const Cfg *Func) const {
961 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
962 Asm->mov_d(getDest(), getSrc(0));
963}
964
965template <> void InstMIPS32Mov_s::emitIAS(const Cfg *Func) const {
966 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
967 Asm->mov_s(getDest(), getSrc(0));
968}
969
Srdjan Obucina8d16c1d2016-09-20 08:44:44 -0700970template <> void InstMIPS32Movf::emitIAS(const Cfg *Func) const {
971 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Stefan Maksimovicafe5fe22016-10-05 10:45:19 -0700972 Asm->movf(getDest(), getSrc(0), getSrc(1));
Srdjan Obucina8d16c1d2016-09-20 08:44:44 -0700973}
974
Srdjan Obucinad27ce3d2016-09-22 12:56:12 -0700975template <> void InstMIPS32Movn::emitIAS(const Cfg *Func) const {
976 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
977 Asm->movn(getDest(), getSrc(0), getSrc(1));
978}
979
Srdjan Obucina132ea7a2016-09-18 07:30:19 -0700980template <> void InstMIPS32Movn_d::emitIAS(const Cfg *Func) const {
981 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
982 Asm->movn_d(getDest(), getSrc(0), getSrc(1));
983}
984
985template <> void InstMIPS32Movn_s::emitIAS(const Cfg *Func) const {
986 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
987 Asm->movn_s(getDest(), getSrc(0), getSrc(1));
988}
989
Srdjan Obucina8d16c1d2016-09-20 08:44:44 -0700990template <> void InstMIPS32Movt::emitIAS(const Cfg *Func) const {
991 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Stefan Maksimovicafe5fe22016-10-05 10:45:19 -0700992 Asm->movt(getDest(), getSrc(0), getSrc(1));
Srdjan Obucina8d16c1d2016-09-20 08:44:44 -0700993}
994
Srdjan Obucinab0f09fc2016-09-27 20:43:11 -0700995template <> void InstMIPS32Movz::emitIAS(const Cfg *Func) const {
996 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
997 Asm->movz(getDest(), getSrc(0), getSrc(1));
998}
999
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001000template <> void InstMIPS32Movz_d::emitIAS(const Cfg *Func) const {
1001 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1002 Asm->movz_d(getDest(), getSrc(0), getSrc(1));
1003}
1004
1005template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const {
1006 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1007 Asm->movz_s(getDest(), getSrc(0), getSrc(1));
1008}
1009
Srdjan Obucina4c49b102016-09-26 20:12:17 -07001010template <> void InstMIPS32Mtc1::emit(const Cfg *Func) const {
1011 if (!BuildDefs::dump())
1012 return;
1013 Ostream &Str = Func->getContext()->getStrEmit();
1014 assert(getSrcSize() == 1);
1015 Str << "\t" << Opcode << "\t";
1016 getSrc(0)->emit(Func);
1017 Str << ", ";
1018 getDest()->emit(Func);
1019}
1020
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001021template <> void InstMIPS32Mtc1::emitIAS(const Cfg *Func) const {
1022 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -07001023 Asm->mtc1(getSrc(0), getDest());
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001024}
1025
1026template <> void InstMIPS32Mtlo::emit(const Cfg *Func) const {
1027 if (!BuildDefs::dump())
1028 return;
1029 emitUnaryopGPRTLoHi(Opcode, this, Func);
1030}
1031
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001032template <> void InstMIPS32Mtlo::emitIAS(const Cfg *Func) const {
1033 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1034 Asm->mtlo(getDest());
1035}
1036
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001037template <> void InstMIPS32Mthi::emit(const Cfg *Func) const {
1038 if (!BuildDefs::dump())
1039 return;
1040 emitUnaryopGPRTLoHi(Opcode, this, Func);
1041}
1042
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001043template <> void InstMIPS32Mthi::emitIAS(const Cfg *Func) const {
1044 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1045 Asm->mthi(getDest());
1046}
1047
1048template <> void InstMIPS32Mul::emitIAS(const Cfg *Func) const {
1049 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1050 Asm->mul(getDest(), getSrc(0), getSrc(1));
1051}
1052
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001053template <> void InstMIPS32Mul_d::emitIAS(const Cfg *Func) const {
1054 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1055 Asm->mul_d(getDest(), getSrc(0), getSrc(1));
1056}
1057
1058template <> void InstMIPS32Mul_s::emitIAS(const Cfg *Func) const {
1059 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1060 Asm->mul_s(getDest(), getSrc(0), getSrc(1));
1061}
1062
1063template <> void InstMIPS32Mult::emit(const Cfg *Func) const {
1064 if (!BuildDefs::dump())
1065 return;
1066 emitThreeAddrLoHi(Opcode, this, Func);
1067}
1068
Jaydeep Patil130aca72016-10-28 05:30:54 -07001069template <> void InstMIPS32Mult::emitIAS(const Cfg *Func) const {
1070 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1071 Asm->mult(getDest(), getSrc(0));
1072}
1073
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001074template <> void InstMIPS32Multu::emit(const Cfg *Func) const {
1075 if (!BuildDefs::dump())
1076 return;
1077 emitThreeAddrLoHi(Opcode, this, Func);
1078}
1079
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001080template <> void InstMIPS32Multu::emitIAS(const Cfg *Func) const {
1081 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Jaydeep Patil130aca72016-10-28 05:30:54 -07001082 Asm->multu(getSrc(0), getSrc(1));
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001083}
1084
Srdjan Obucinacadda792016-09-22 11:24:44 -07001085template <> void InstMIPS32Nor::emitIAS(const Cfg *Func) const {
1086 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1087 Asm->nor(getDest(), getSrc(0), getSrc(1));
1088}
1089
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001090template <> void InstMIPS32Or::emitIAS(const Cfg *Func) const {
1091 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1092 Asm->or_(getDest(), getSrc(0), getSrc(1));
1093}
1094
1095template <> void InstMIPS32Ori::emitIAS(const Cfg *Func) const {
1096 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1097 Asm->ori(getDest(), getSrc(0), Imm);
1098}
1099
Sagar Thakurbecb85f2016-11-18 12:15:46 -08001100template <> void InstMIPS32Sc::emitIAS(const Cfg *Func) const {
1101 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1102 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(1));
1103 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
1104 uint32_t Imm = static_cast<uint32_t>(Offset->getValue());
1105 Asm->sc(getSrc(0), Mem->getBase(), Imm);
1106}
1107
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001108template <> void InstMIPS32Sll::emitIAS(const Cfg *Func) const {
1109 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1110 Asm->sll(getDest(), getSrc(0), Imm);
1111}
1112
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001113template <> void InstMIPS32Sllv::emitIAS(const Cfg *Func) const {
1114 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1115 Asm->sllv(getDest(), getSrc(0), getSrc(1));
1116}
1117
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001118template <> void InstMIPS32Slt::emitIAS(const Cfg *Func) const {
1119 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1120 Asm->slt(getDest(), getSrc(0), getSrc(1));
1121}
1122
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001123template <> void InstMIPS32Slti::emitIAS(const Cfg *Func) const {
1124 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1125 Asm->slti(getDest(), getSrc(0), Imm);
1126}
1127
1128template <> void InstMIPS32Sltiu::emitIAS(const Cfg *Func) const {
1129 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1130 Asm->sltiu(getDest(), getSrc(0), Imm);
1131}
1132
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001133template <> void InstMIPS32Sltu::emitIAS(const Cfg *Func) const {
1134 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1135 Asm->sltu(getDest(), getSrc(0), getSrc(1));
1136}
1137
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001138template <> void InstMIPS32Sqrt_d::emitIAS(const Cfg *Func) const {
1139 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1140 Asm->sqrt_d(getDest(), getSrc(0));
1141}
1142
1143template <> void InstMIPS32Sqrt_s::emitIAS(const Cfg *Func) const {
1144 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1145 Asm->sqrt_s(getDest(), getSrc(0));
1146}
1147
1148template <> void InstMIPS32Sra::emitIAS(const Cfg *Func) const {
1149 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1150 Asm->sra(getDest(), getSrc(0), Imm);
1151}
1152
Srdjan Obucinafe93fdd2016-09-28 06:38:44 -07001153template <> void InstMIPS32Srav::emitIAS(const Cfg *Func) const {
1154 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1155 Asm->srav(getDest(), getSrc(0), getSrc(1));
1156}
1157
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001158template <> void InstMIPS32Srl::emitIAS(const Cfg *Func) const {
1159 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1160 Asm->srl(getDest(), getSrc(0), Imm);
1161}
1162
Srdjan Obucina623f8ce2016-09-26 20:03:20 -07001163template <> void InstMIPS32Srlv::emitIAS(const Cfg *Func) const {
1164 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1165 Asm->srlv(getDest(), getSrc(0), getSrc(1));
1166}
1167
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001168template <> void InstMIPS32Sub_d::emitIAS(const Cfg *Func) const {
1169 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1170 Asm->sub_d(getDest(), getSrc(0), getSrc(1));
1171}
1172
1173template <> void InstMIPS32Sub_s::emitIAS(const Cfg *Func) const {
1174 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1175 Asm->sub_s(getDest(), getSrc(0), getSrc(1));
1176}
1177
Srdjan Obucina0a7f99d2016-09-23 06:59:50 -07001178template <> void InstMIPS32Subu::emitIAS(const Cfg *Func) const {
1179 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1180 Asm->subu(getDest(), getSrc(0), getSrc(1));
1181}
1182
Jaydeep Patil130aca72016-10-28 05:30:54 -07001183template <> void InstMIPS32Sdc1::emitIAS(const Cfg *Func) const {
1184 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1185 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
1186 Asm->sdc1(getSrc(0), Mem->getBase(), Mem->getOffset(), Reloc);
1187}
1188
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001189template <> void InstMIPS32Sw::emitIAS(const Cfg *Func) const {
1190 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1191 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(1));
1192 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
1193 uint32_t Imm = static_cast<uint32_t>(Offset->getValue());
1194 Asm->sw(getSrc(0), Mem->getBase(), Imm);
1195}
1196
Jaydeep Patil130aca72016-10-28 05:30:54 -07001197template <> void InstMIPS32Swc1::emitIAS(const Cfg *Func) const {
1198 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1199 auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(getSrc(0));
1200 Asm->swc1(getSrc(0), Mem->getBase(), Mem->getOffset(), Reloc);
1201}
1202
Sagar Thakurbecb85f2016-11-18 12:15:46 -08001203void InstMIPS32Sync::emitIAS(const Cfg *Func) const {
1204 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1205 Asm->sync();
1206}
1207
Srdjan Obucina3b61d702016-09-20 06:49:52 -07001208template <> void InstMIPS32Teq::emitIAS(const Cfg *Func) const {
1209 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1210 Asm->teq(getSrc(0), getSrc(1), getTrapCode());
1211}
1212
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001213template <> void InstMIPS32Trunc_l_d::emitIAS(const Cfg *Func) const {
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001214 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Srdjan Obucina132ea7a2016-09-18 07:30:19 -07001215 Asm->trunc_l_d(getDest(), getSrc(0));
1216}
1217
1218template <> void InstMIPS32Trunc_l_s::emitIAS(const Cfg *Func) const {
1219 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1220 Asm->trunc_l_s(getDest(), getSrc(0));
1221}
1222
1223template <> void InstMIPS32Trunc_w_d::emitIAS(const Cfg *Func) const {
1224 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1225 Asm->trunc_w_d(getDest(), getSrc(0));
1226}
1227
1228template <> void InstMIPS32Trunc_w_s::emitIAS(const Cfg *Func) const {
1229 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1230 Asm->trunc_w_s(getDest(), getSrc(0));
1231}
1232
1233template <> void InstMIPS32Xor::emitIAS(const Cfg *Func) const {
1234 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1235 Asm->xor_(getDest(), getSrc(0), getSrc(1));
1236}
1237
1238template <> void InstMIPS32Xori::emitIAS(const Cfg *Func) const {
1239 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
1240 Asm->xori(getDest(), getSrc(0), Imm);
Jaydeep Patil135f5db2016-08-29 05:14:05 -07001241}
1242
John Porto4a566862016-01-04 09:33:41 -08001243} // end of namespace MIPS32
Jim Stichnothac8da5c2015-10-21 06:57:46 -07001244} // end of namespace Ice