OSDN Git Service

Introduce the ability to insert IACA (Intel Architecture Code Analyzer) marks.
[android-x86/external-swiftshader.git] / src / IceInstX86BaseImpl.h
1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- 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 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the InstX86Base class and its descendants.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H
16 #define SUBZERO_SRC_ICEINSTX86BASEIMPL_H
17
18 #include "IceInstX86Base.h"
19
20 #include "IceAssemblerX86Base.h"
21 #include "IceCfg.h"
22 #include "IceCfgNode.h"
23 #include "IceDefs.h"
24 #include "IceInst.h"
25 #include "IceOperand.h"
26 #include "IceTargetLowering.h"
27
28 namespace Ice {
29
30 namespace X86Internal {
31
32 template <class Machine>
33 const char *InstX86Base<Machine>::getWidthString(Type Ty) {
34   return Traits::TypeAttributes[Ty].WidthString;
35 }
36
37 template <class Machine>
38 const char *InstX86Base<Machine>::getFldString(Type Ty) {
39   return Traits::TypeAttributes[Ty].FldString;
40 }
41
42 template <class Machine>
43 typename InstX86Base<Machine>::Traits::Cond::BrCond
44 InstX86Base<Machine>::getOppositeCondition(typename Traits::Cond::BrCond Cond) {
45   return Traits::InstBrAttributes[Cond].Opposite;
46 }
47
48 template <class Machine>
49 InstX86FakeRMW<Machine>::InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
50                                         InstArithmetic::OpKind Op,
51                                         Variable *Beacon)
52     : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr),
53       Op(Op) {
54   this->addSource(Data);
55   this->addSource(Addr);
56   this->addSource(Beacon);
57 }
58
59 template <class Machine>
60 InstX86AdjustStack<Machine>::InstX86AdjustStack(Cfg *Func, SizeT Amount,
61                                                 Variable *Esp)
62     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Adjuststack, 1, Esp),
63       Amount(Amount) {
64   this->addSource(Esp);
65 }
66
67 template <class Machine>
68 InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1,
69                                 Operand *Source2)
70     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) {
71   this->addSource(Source1);
72   this->addSource(Source2);
73 }
74
75 template <class Machine>
76 InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1,
77                                   Variable *Source2)
78     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shld, 3, Dest) {
79   this->addSource(Dest);
80   this->addSource(Source1);
81   this->addSource(Source2);
82 }
83
84 template <class Machine>
85 InstX86Shrd<Machine>::InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
86                                   Variable *Source2)
87     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shrd, 3, Dest) {
88   this->addSource(Dest);
89   this->addSource(Source1);
90   this->addSource(Source2);
91 }
92
93 template <class Machine>
94 InstX86Label<Machine>::InstX86Label(
95     Cfg *Func, typename InstX86Base<Machine>::Traits::TargetLowering *Target)
96     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Label, 0, nullptr),
97       Number(Target->makeNextLabelNumber()) {}
98
99 template <class Machine>
100 IceString InstX86Label<Machine>::getName(const Cfg *Func) const {
101   return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
102 }
103
104 template <class Machine>
105 InstX86Br<Machine>::InstX86Br(
106     Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
107     const InstX86Label<Machine> *Label,
108     typename InstX86Base<Machine>::Traits::Cond::BrCond Condition, Mode Kind)
109     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Br, 0, nullptr),
110       Condition(Condition), TargetTrue(TargetTrue), TargetFalse(TargetFalse),
111       Label(Label), Kind(Kind) {}
112
113 template <class Machine>
114 bool InstX86Br<Machine>::optimizeBranch(const CfgNode *NextNode) {
115   // If there is no next block, then there can be no fallthrough to
116   // optimize.
117   if (NextNode == nullptr)
118     return false;
119   // Intra-block conditional branches can't be optimized.
120   if (Label)
121     return false;
122   // If there is no fallthrough node, such as a non-default case label
123   // for a switch instruction, then there is no opportunity to
124   // optimize.
125   if (getTargetFalse() == nullptr)
126     return false;
127
128   // Unconditional branch to the next node can be removed.
129   if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None &&
130       getTargetFalse() == NextNode) {
131     assert(getTargetTrue() == nullptr);
132     this->setDeleted();
133     return true;
134   }
135   // If the fallthrough is to the next node, set fallthrough to nullptr
136   // to indicate.
137   if (getTargetFalse() == NextNode) {
138     TargetFalse = nullptr;
139     return true;
140   }
141   // If TargetTrue is the next node, and TargetFalse is not nullptr
142   // (which was already tested above), then invert the branch
143   // condition, swap the targets, and set new fallthrough to nullptr.
144   if (getTargetTrue() == NextNode) {
145     assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
146     Condition = this->getOppositeCondition(Condition);
147     TargetTrue = getTargetFalse();
148     TargetFalse = nullptr;
149     return true;
150   }
151   return false;
152 }
153
154 template <class Machine>
155 bool InstX86Br<Machine>::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
156   bool Found = false;
157   if (TargetFalse == OldNode) {
158     TargetFalse = NewNode;
159     Found = true;
160   }
161   if (TargetTrue == OldNode) {
162     TargetTrue = NewNode;
163     Found = true;
164   }
165   return Found;
166 }
167
168 template <class Machine>
169 InstX86Jmp<Machine>::InstX86Jmp(Cfg *Func, Operand *Target)
170     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Jmp, 1, nullptr) {
171   this->addSource(Target);
172 }
173
174 template <class Machine>
175 InstX86Call<Machine>::InstX86Call(Cfg *Func, Variable *Dest,
176                                   Operand *CallTarget)
177     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Call, 1, Dest) {
178   this->HasSideEffects = true;
179   this->addSource(CallTarget);
180 }
181
182 template <class Machine>
183 InstX86Cmov<Machine>::InstX86Cmov(
184     Cfg *Func, Variable *Dest, Operand *Source,
185     typename InstX86Base<Machine>::Traits::Cond::BrCond Condition)
186     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmov, 2, Dest),
187       Condition(Condition) {
188   // The final result is either the original Dest, or Source, so mark
189   // both as sources.
190   this->addSource(Dest);
191   this->addSource(Source);
192 }
193
194 template <class Machine>
195 InstX86Cmpps<Machine>::InstX86Cmpps(
196     Cfg *Func, Variable *Dest, Operand *Source,
197     typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition)
198     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmpps, 2, Dest),
199       Condition(Condition) {
200   this->addSource(Dest);
201   this->addSource(Source);
202 }
203
204 template <class Machine>
205 InstX86Cmpxchg<Machine>::InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr,
206                                         Variable *Eax, Variable *Desired,
207                                         bool Locked)
208     : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3,
209                                    llvm::dyn_cast<Variable>(DestOrAddr),
210                                    Locked) {
211   assert(Eax->getRegNum() ==
212          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
213   this->addSource(DestOrAddr);
214   this->addSource(Eax);
215   this->addSource(Desired);
216 }
217
218 template <class Machine>
219 InstX86Cmpxchg8b<Machine>::InstX86Cmpxchg8b(
220     Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Addr,
221     Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked)
222     : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 5,
223                                    nullptr, Locked) {
224   assert(Edx->getRegNum() ==
225          InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
226   assert(Eax->getRegNum() ==
227          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
228   assert(Ecx->getRegNum() ==
229          InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
230   assert(Ebx->getRegNum() ==
231          InstX86Base<Machine>::Traits::RegisterSet::Reg_ebx);
232   this->addSource(Addr);
233   this->addSource(Edx);
234   this->addSource(Eax);
235   this->addSource(Ecx);
236   this->addSource(Ebx);
237 }
238
239 template <class Machine>
240 InstX86Cvt<Machine>::InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source,
241                                 CvtVariant Variant)
242     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cvt, 1, Dest),
243       Variant(Variant) {
244   this->addSource(Source);
245 }
246
247 template <class Machine>
248 InstX86Icmp<Machine>::InstX86Icmp(Cfg *Func, Operand *Src0, Operand *Src1)
249     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Icmp, 2, nullptr) {
250   this->addSource(Src0);
251   this->addSource(Src1);
252 }
253
254 template <class Machine>
255 InstX86Ucomiss<Machine>::InstX86Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1)
256     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ucomiss, 2, nullptr) {
257   this->addSource(Src0);
258   this->addSource(Src1);
259 }
260
261 template <class Machine>
262 InstX86UD2<Machine>::InstX86UD2(Cfg *Func)
263     : InstX86Base<Machine>(Func, InstX86Base<Machine>::UD2, 0, nullptr) {}
264
265 template <class Machine>
266 InstX86Test<Machine>::InstX86Test(Cfg *Func, Operand *Src1, Operand *Src2)
267     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Test, 2, nullptr) {
268   this->addSource(Src1);
269   this->addSource(Src2);
270 }
271
272 template <class Machine>
273 InstX86Mfence<Machine>::InstX86Mfence(Cfg *Func)
274     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mfence, 0, nullptr) {
275   this->HasSideEffects = true;
276 }
277
278 template <class Machine>
279 InstX86Store<Machine>::InstX86Store(
280     Cfg *Func, Operand *Value,
281     typename InstX86Base<Machine>::Traits::X86Operand *Mem)
282     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Store, 2, nullptr) {
283   this->addSource(Value);
284   this->addSource(Mem);
285 }
286
287 template <class Machine>
288 InstX86StoreP<Machine>::InstX86StoreP(
289     Cfg *Func, Variable *Value,
290     typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
291     : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreP, 2, nullptr) {
292   this->addSource(Value);
293   this->addSource(Mem);
294 }
295
296 template <class Machine>
297 InstX86StoreQ<Machine>::InstX86StoreQ(
298     Cfg *Func, Variable *Value,
299     typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
300     : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreQ, 2, nullptr) {
301   this->addSource(Value);
302   this->addSource(Mem);
303 }
304
305 template <class Machine>
306 InstX86Nop<Machine>::InstX86Nop(Cfg *Func, InstX86Nop::NopVariant Variant)
307     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Nop, 0, nullptr),
308       Variant(Variant) {}
309
310 template <class Machine>
311 InstX86Fld<Machine>::InstX86Fld(Cfg *Func, Operand *Src)
312     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fld, 1, nullptr) {
313   this->addSource(Src);
314 }
315
316 template <class Machine>
317 InstX86Fstp<Machine>::InstX86Fstp(Cfg *Func, Variable *Dest)
318     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fstp, 0, Dest) {}
319
320 template <class Machine>
321 InstX86Pop<Machine>::InstX86Pop(Cfg *Func, Variable *Dest)
322     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Pop, 0, Dest) {
323   // A pop instruction affects the stack pointer and so it should not
324   // be allowed to be automatically dead-code eliminated.  (The
325   // corresponding push instruction doesn't need this treatment
326   // because it has no dest variable and therefore won't be dead-code
327   // eliminated.)  This is needed for late-stage liveness analysis
328   // (e.g. asm-verbose mode).
329   this->HasSideEffects = true;
330 }
331
332 template <class Machine>
333 InstX86Push<Machine>::InstX86Push(Cfg *Func, Variable *Source)
334     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Push, 1, nullptr) {
335   this->addSource(Source);
336 }
337
338 template <class Machine>
339 InstX86Ret<Machine>::InstX86Ret(Cfg *Func, Variable *Source)
340     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ret, Source ? 1 : 0,
341                            nullptr) {
342   if (Source)
343     this->addSource(Source);
344 }
345
346 template <class Machine>
347 InstX86Setcc<Machine>::InstX86Setcc(
348     Cfg *Func, Variable *Dest,
349     typename InstX86Base<Machine>::Traits::Cond::BrCond Cond)
350     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Setcc, 0, Dest),
351       Condition(Cond) {}
352
353 template <class Machine>
354 InstX86Xadd<Machine>::InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source,
355                                   bool Locked)
356     : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Xadd, 2,
357                                    llvm::dyn_cast<Variable>(Dest), Locked) {
358   this->addSource(Dest);
359   this->addSource(Source);
360 }
361
362 template <class Machine>
363 InstX86Xchg<Machine>::InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source)
364     : InstX86Base<Machine>(Func, InstX86Base<Machine>::Xchg, 2,
365                            llvm::dyn_cast<Variable>(Dest)) {
366   this->addSource(Dest);
367   this->addSource(Source);
368 }
369
370 template <class Machine>
371 InstX86IacaStart<Machine>::InstX86IacaStart(Cfg *Func)
372     : InstX86Base<Machine>(Func, InstX86Base<Machine>::IacaStart, 0, nullptr) {
373   assert(Func->getContext()->getFlags().getAllowIacaMarks());
374 }
375
376 template <class Machine>
377 InstX86IacaEnd<Machine>::InstX86IacaEnd(Cfg *Func)
378     : InstX86Base<Machine>(Func, InstX86Base<Machine>::IacaEnd, 0, nullptr) {
379   assert(Func->getContext()->getFlags().getAllowIacaMarks());
380 }
381
382 // ======================== Dump routines ======================== //
383
384 template <class Machine>
385 void InstX86Base<Machine>::dump(const Cfg *Func) const {
386   if (!BuildDefs::dump())
387     return;
388   Ostream &Str = Func->getContext()->getStrDump();
389   Str << "[" << Traits::TargetName << "] ";
390   Inst::dump(Func);
391 }
392
393 template <class Machine>
394 void InstX86FakeRMW<Machine>::dump(const Cfg *Func) const {
395   if (!BuildDefs::dump())
396     return;
397   Ostream &Str = Func->getContext()->getStrDump();
398   Type Ty = getData()->getType();
399   Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *";
400   getAddr()->dump(Func);
401   Str << ", ";
402   getData()->dump(Func);
403   Str << ", beacon=";
404   getBeacon()->dump(Func);
405 }
406
407 template <class Machine>
408 void InstX86Label<Machine>::emit(const Cfg *Func) const {
409   if (!BuildDefs::dump())
410     return;
411   Ostream &Str = Func->getContext()->getStrEmit();
412   Str << getName(Func) << ":";
413 }
414
415 template <class Machine>
416 void InstX86Label<Machine>::emitIAS(const Cfg *Func) const {
417   typename InstX86Base<Machine>::Traits::Assembler *Asm =
418       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
419   Asm->bindLocalLabel(Number);
420 }
421
422 template <class Machine>
423 void InstX86Label<Machine>::dump(const Cfg *Func) const {
424   if (!BuildDefs::dump())
425     return;
426   Ostream &Str = Func->getContext()->getStrDump();
427   Str << getName(Func) << ":";
428 }
429
430 template <class Machine> void InstX86Br<Machine>::emit(const Cfg *Func) const {
431   if (!BuildDefs::dump())
432     return;
433   Ostream &Str = Func->getContext()->getStrEmit();
434   Str << "\t";
435
436   if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
437     Str << "jmp";
438   } else {
439     Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].EmitString;
440   }
441
442   if (Label) {
443     Str << "\t" << Label->getName(Func);
444   } else {
445     if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
446       Str << "\t" << getTargetFalse()->getAsmName();
447     } else {
448       Str << "\t" << getTargetTrue()->getAsmName();
449       if (getTargetFalse()) {
450         Str << "\n\tjmp\t" << getTargetFalse()->getAsmName();
451       }
452     }
453   }
454 }
455
456 template <class Machine>
457 void InstX86Br<Machine>::emitIAS(const Cfg *Func) const {
458   typename InstX86Base<Machine>::Traits::Assembler *Asm =
459       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
460   if (Label) {
461     class Label *L = Asm->getOrCreateLocalLabel(Label->getNumber());
462     if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
463       Asm->jmp(L, isNear());
464     } else {
465       Asm->j(Condition, L, isNear());
466     }
467   } else {
468     if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
469       class Label *L =
470           Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
471       assert(!getTargetTrue());
472       Asm->jmp(L, isNear());
473     } else {
474       class Label *L =
475           Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
476       Asm->j(Condition, L, isNear());
477       if (getTargetFalse()) {
478         class Label *L2 =
479             Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
480         Asm->jmp(L2, isNear());
481       }
482     }
483   }
484 }
485
486 template <class Machine> void InstX86Br<Machine>::dump(const Cfg *Func) const {
487   if (!BuildDefs::dump())
488     return;
489   Ostream &Str = Func->getContext()->getStrDump();
490   Str << "br ";
491
492   if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
493     Str << "label %"
494         << (Label ? Label->getName(Func) : getTargetFalse()->getName());
495     return;
496   }
497
498   Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition]
499              .DisplayString;
500   if (Label) {
501     Str << ", label %" << Label->getName(Func);
502   } else {
503     Str << ", label %" << getTargetTrue()->getName();
504     if (getTargetFalse()) {
505       Str << ", label %" << getTargetFalse()->getName();
506     }
507   }
508
509   Str << " // (" << (isNear() ? "near" : "far") << " jump)";
510 }
511
512 template <class Machine> void InstX86Jmp<Machine>::emit(const Cfg *Func) const {
513   if (!BuildDefs::dump())
514     return;
515   Ostream &Str = Func->getContext()->getStrEmit();
516   assert(this->getSrcSize() == 1);
517   Str << "\tjmp\t*";
518   getJmpTarget()->emit(Func);
519 }
520
521 template <class Machine>
522 void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const {
523   // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS().
524   typename InstX86Base<Machine>::Traits::Assembler *Asm =
525       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
526   Operand *Target = getJmpTarget();
527   if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
528     if (Var->hasReg()) {
529       Asm->jmp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
530           Var->getRegNum()));
531     } else {
532       // The jmp instruction with a memory operand should be possible
533       // to encode, but it isn't a valid sandboxed instruction, and
534       // there shouldn't be a register allocation issue to jump
535       // through a scratch register, so we don't really need to bother
536       // implementing it.
537       llvm::report_fatal_error("Assembler can't jmp to memory operand");
538     }
539   } else if (const auto Mem = llvm::dyn_cast<
540                  typename InstX86Base<Machine>::Traits::X86OperandMem>(
541                  Target)) {
542     (void)Mem;
543     assert(Mem->getSegmentRegister() ==
544            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
545     llvm::report_fatal_error("Assembler can't jmp to memory operand");
546   } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
547     assert(CR->getOffset() == 0 && "We only support jumping to a function");
548     Asm->jmp(CR);
549   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
550     // NaCl trampoline calls refer to an address within the sandbox directly.
551     // This is usually only needed for non-IRT builds and otherwise not
552     // very portable or stable. Usually this is only done for "calls"
553     // and not jumps.
554     // TODO(jvoung): Support this when there is a lowering that
555     // actually triggers this case.
556     (void)Imm;
557     llvm::report_fatal_error("Unexpected jmp to absolute address");
558   } else {
559     llvm::report_fatal_error("Unexpected operand type");
560   }
561 }
562
563 template <class Machine> void InstX86Jmp<Machine>::dump(const Cfg *Func) const {
564   if (!BuildDefs::dump())
565     return;
566   Ostream &Str = Func->getContext()->getStrDump();
567   Str << "jmp ";
568   getJmpTarget()->dump(Func);
569 }
570
571 template <class Machine>
572 void InstX86Call<Machine>::emit(const Cfg *Func) const {
573   if (!BuildDefs::dump())
574     return;
575   Ostream &Str = Func->getContext()->getStrEmit();
576   assert(this->getSrcSize() == 1);
577   Str << "\tcall\t";
578   if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) {
579     // Emit without a leading '$'.
580     Str << CI->getValue();
581   } else if (const auto CallTarget =
582                  llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
583     CallTarget->emitWithoutPrefix(Func->getTarget());
584   } else {
585     Str << "*";
586     getCallTarget()->emit(Func);
587   }
588   Func->getTarget()->resetStackAdjustment();
589 }
590
591 template <class Machine>
592 void InstX86Call<Machine>::emitIAS(const Cfg *Func) const {
593   typename InstX86Base<Machine>::Traits::Assembler *Asm =
594       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
595   Operand *Target = getCallTarget();
596   if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
597     if (Var->hasReg()) {
598       Asm->call(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
599           Var->getRegNum()));
600     } else {
601       Asm->call(
602           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
603               Func->getTarget())
604               ->stackVarToAsmOperand(Var));
605     }
606   } else if (const auto Mem = llvm::dyn_cast<
607                  typename InstX86Base<Machine>::Traits::X86OperandMem>(
608                  Target)) {
609     assert(Mem->getSegmentRegister() ==
610            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
611     Asm->call(Mem->toAsmAddress(Asm));
612   } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
613     assert(CR->getOffset() == 0 && "We only support calling a function");
614     Asm->call(CR);
615   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
616     Asm->call(Immediate(Imm->getValue()));
617   } else {
618     llvm_unreachable("Unexpected operand type");
619   }
620   Func->getTarget()->resetStackAdjustment();
621 }
622
623 template <class Machine>
624 void InstX86Call<Machine>::dump(const Cfg *Func) const {
625   if (!BuildDefs::dump())
626     return;
627   Ostream &Str = Func->getContext()->getStrDump();
628   if (this->getDest()) {
629     this->dumpDest(Func);
630     Str << " = ";
631   }
632   Str << "call ";
633   getCallTarget()->dump(Func);
634 }
635
636 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for
637 // shift instructions, in order to be syntactically valid.  The
638 // this->Opcode parameter needs to be char* and not IceString because of
639 // template issues.
640 template <class Machine>
641 void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst,
642                                           const Cfg *Func, bool ShiftHack) {
643   if (!BuildDefs::dump())
644     return;
645   Ostream &Str = Func->getContext()->getStrEmit();
646   assert(Inst->getSrcSize() == 2);
647   Operand *Dest = Inst->getDest();
648   if (Dest == nullptr)
649     Dest = Inst->getSrc(0);
650   assert(Dest == Inst->getSrc(0));
651   Operand *Src1 = Inst->getSrc(1);
652   Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType())
653       << "\t";
654   const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
655   if (ShiftHack && ShiftReg &&
656       ShiftReg->getRegNum() ==
657           InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx)
658     Str << "%cl";
659   else
660     Src1->emit(Func);
661   Str << ", ";
662   Dest->emit(Func);
663 }
664
665 template <class Machine>
666 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
667                     const typename InstX86Base<
668                         Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) {
669   typename InstX86Base<Machine>::Traits::Assembler *Asm =
670       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
671   if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
672     if (Var->hasReg()) {
673       // We cheat a little and use GPRRegister even for byte operations.
674       typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
675           InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
676               Ty, Var->getRegNum());
677       (Asm->*(Emitter.Reg))(Ty, VarReg);
678     } else {
679       typename InstX86Base<Machine>::Traits::Address StackAddr(
680           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
681               Func->getTarget())
682               ->stackVarToAsmOperand(Var));
683       (Asm->*(Emitter.Addr))(Ty, StackAddr);
684     }
685   } else if (const auto Mem = llvm::dyn_cast<
686                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) {
687     Mem->emitSegmentOverride(Asm);
688     (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
689   } else {
690     llvm_unreachable("Unexpected operand type");
691   }
692 }
693
694 template <class Machine, bool VarCanBeByte, bool SrcCanBeByte>
695 void emitIASRegOpTyGPR(
696     const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
697     const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
698         &Emitter) {
699   typename InstX86Base<Machine>::Traits::Assembler *Asm =
700       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
701   assert(Var->hasReg());
702   // We cheat a little and use GPRRegister even for byte operations.
703   typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
704       VarCanBeByte
705           ? InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
706                 Ty, Var->getRegNum())
707           : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
708                 Var->getRegNum());
709   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
710     if (SrcVar->hasReg()) {
711       typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
712           SrcCanBeByte
713               ? InstX86Base<Machine>::Traits::RegisterSet::
714                     getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
715               : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
716                     SrcVar->getRegNum());
717       (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
718     } else {
719       typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
720           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
721               Func->getTarget())
722               ->stackVarToAsmOperand(SrcVar);
723       (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
724     }
725   } else if (const auto Mem = llvm::dyn_cast<
726                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
727     Mem->emitSegmentOverride(Asm);
728     (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
729   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
730     (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
731   } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
732     AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
733     (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup));
734   } else if (const auto Split = llvm::dyn_cast<
735                  typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) {
736     (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
737   } else {
738     llvm_unreachable("Unexpected operand type");
739   }
740 }
741
742 template <class Machine>
743 void emitIASAddrOpTyGPR(
744     const Cfg *Func, Type Ty,
745     const typename InstX86Base<Machine>::Traits::Address &Addr,
746     const Operand *Src,
747     const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
748         &Emitter) {
749   typename InstX86Base<Machine>::Traits::Assembler *Asm =
750       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
751   // Src can only be Reg or Immediate.
752   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
753     assert(SrcVar->hasReg());
754     typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
755         InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
756             Ty, SrcVar->getRegNum());
757     (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
758   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
759     (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue()));
760   } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
761     AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
762     (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup));
763   } else {
764     llvm_unreachable("Unexpected operand type");
765   }
766 }
767
768 template <class Machine>
769 void emitIASAsAddrOpTyGPR(
770     const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
771     const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
772         &Emitter) {
773   if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
774     assert(!Op0Var->hasReg());
775     typename InstX86Base<Machine>::Traits::Address StackAddr(
776         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
777             Func->getTarget())
778             ->stackVarToAsmOperand(Op0Var));
779     emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter);
780   } else if (const auto Op0Mem = llvm::dyn_cast<
781                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) {
782     typename InstX86Base<Machine>::Traits::Assembler *Asm =
783         Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
784     Op0Mem->emitSegmentOverride(Asm);
785     emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1,
786                                 Emitter);
787   } else if (const auto Split = llvm::dyn_cast<
788                  typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) {
789     emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1,
790                                 Emitter);
791   } else {
792     llvm_unreachable("Unexpected operand type");
793   }
794 }
795
796 template <class Machine>
797 void InstX86Base<Machine>::emitIASGPRShift(
798     const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
799     const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp
800         &Emitter) {
801   typename InstX86Base<Machine>::Traits::Assembler *Asm =
802       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
803   // Technically, the Dest Var can be mem as well, but we only use Reg.
804   // We can extend this to check Dest if we decide to use that form.
805   assert(Var->hasReg());
806   // We cheat a little and use GPRRegister even for byte operations.
807   typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
808       InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
809           Ty, Var->getRegNum());
810   // Src must be reg == ECX or an Imm8.
811   // This is asserted by the assembler.
812   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
813     assert(SrcVar->hasReg());
814     typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
815         InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
816             Ty, SrcVar->getRegNum());
817     (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
818   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
819     (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
820   } else {
821     llvm_unreachable("Unexpected operand type");
822   }
823 }
824
825 template <class Machine>
826 void emitIASGPRShiftDouble(
827     const Cfg *Func, const Variable *Dest, const Operand *Src1Op,
828     const Operand *Src2Op,
829     const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftD
830         &Emitter) {
831   typename InstX86Base<Machine>::Traits::Assembler *Asm =
832       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
833   // Dest can be reg or mem, but we only use the reg variant.
834   assert(Dest->hasReg());
835   typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg =
836       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
837           Dest->getRegNum());
838   // SrcVar1 must be reg.
839   const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
840   assert(SrcVar1->hasReg());
841   typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
842       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
843           SrcVar1->getRegNum());
844   Type Ty = SrcVar1->getType();
845   // Src2 can be the implicit CL register or an immediate.
846   if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
847     (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
848                                 Immediate(Imm->getValue()));
849   } else {
850     assert(llvm::cast<Variable>(Src2Op)->getRegNum() ==
851            InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
852     (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
853   }
854 }
855
856 template <class Machine>
857 void emitIASXmmShift(
858     const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
859     const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp
860         &Emitter) {
861   typename InstX86Base<Machine>::Traits::Assembler *Asm =
862       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
863   assert(Var->hasReg());
864   typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
865       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
866           Var->getRegNum());
867   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
868     if (SrcVar->hasReg()) {
869       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
870           InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
871               SrcVar->getRegNum());
872       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
873     } else {
874       typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
875           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
876               Func->getTarget())
877               ->stackVarToAsmOperand(SrcVar);
878       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
879     }
880   } else if (const auto Mem = llvm::dyn_cast<
881                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
882     assert(Mem->getSegmentRegister() ==
883            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
884     (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
885   } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
886     (Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue()));
887   } else {
888     llvm_unreachable("Unexpected operand type");
889   }
890 }
891
892 template <class Machine>
893 void emitIASRegOpTyXMM(
894     const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
895     const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
896         &Emitter) {
897   typename InstX86Base<Machine>::Traits::Assembler *Asm =
898       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
899   assert(Var->hasReg());
900   typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
901       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
902           Var->getRegNum());
903   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
904     if (SrcVar->hasReg()) {
905       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
906           InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
907               SrcVar->getRegNum());
908       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
909     } else {
910       typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
911           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
912               Func->getTarget())
913               ->stackVarToAsmOperand(SrcVar);
914       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
915     }
916   } else if (const auto Mem = llvm::dyn_cast<
917                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
918     assert(Mem->getSegmentRegister() ==
919            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
920     (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
921   } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
922     (Asm->*(Emitter.XmmAddr))(
923         Ty, VarReg,
924         InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
925   } else {
926     llvm_unreachable("Unexpected operand type");
927   }
928 }
929
930 template <class Machine, typename DReg_t, typename SReg_t,
931           DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
932 void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest,
933                       const Operand *Src,
934                       const typename InstX86Base<Machine>::Traits::Assembler::
935                           template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) {
936   typename InstX86Base<Machine>::Traits::Assembler *Asm =
937       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
938   assert(Dest->hasReg());
939   DReg_t DestReg = destEnc(Dest->getRegNum());
940   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
941     if (SrcVar->hasReg()) {
942       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
943       (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
944     } else {
945       typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
946           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
947               Func->getTarget())
948               ->stackVarToAsmOperand(SrcVar);
949       (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
950     }
951   } else if (const auto Mem = llvm::dyn_cast<
952                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
953     Mem->emitSegmentOverride(Asm);
954     (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
955   } else {
956     llvm_unreachable("Unexpected operand type");
957   }
958 }
959
960 template <class Machine, typename DReg_t, typename SReg_t,
961           DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
962 void emitIASThreeOpImmOps(
963     const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
964     const Operand *Src1,
965     const typename InstX86Base<Machine>::Traits::Assembler::
966         template ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
967   typename InstX86Base<Machine>::Traits::Assembler *Asm =
968       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
969   // This only handles Dest being a register, and Src1 being an immediate.
970   assert(Dest->hasReg());
971   DReg_t DestReg = destEnc(Dest->getRegNum());
972   Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
973   if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) {
974     if (SrcVar->hasReg()) {
975       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
976       (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
977     } else {
978       typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
979           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
980               Func->getTarget())
981               ->stackVarToAsmOperand(SrcVar);
982       (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
983     }
984   } else if (const auto Mem = llvm::dyn_cast<
985                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) {
986     Mem->emitSegmentOverride(Asm);
987     (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm),
988                                  Imm);
989   } else {
990     llvm_unreachable("Unexpected operand type");
991   }
992 }
993
994 template <class Machine>
995 void emitIASMovlikeXMM(
996     const Cfg *Func, const Variable *Dest, const Operand *Src,
997     const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterMovOps
998         Emitter) {
999   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1000       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1001   if (Dest->hasReg()) {
1002     typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
1003         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1004             Dest->getRegNum());
1005     if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
1006       if (SrcVar->hasReg()) {
1007         (Asm->*(Emitter.XmmXmm))(
1008             DestReg, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1009                          SrcVar->getRegNum()));
1010       } else {
1011         typename InstX86Base<Machine>::Traits::Address StackAddr(
1012             static_cast<typename InstX86Base<Machine>::Traits::TargetLowering
1013                             *>(Func->getTarget())
1014                 ->stackVarToAsmOperand(SrcVar));
1015         (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
1016       }
1017     } else if (const auto SrcMem = llvm::dyn_cast<
1018                    typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
1019       assert(SrcMem->getSegmentRegister() ==
1020              InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
1021       (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
1022     } else {
1023       llvm_unreachable("Unexpected operand type");
1024     }
1025   } else {
1026     typename InstX86Base<Machine>::Traits::Address StackAddr(
1027         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1028             Func->getTarget())
1029             ->stackVarToAsmOperand(Dest));
1030     // Src must be a register in this case.
1031     const auto SrcVar = llvm::cast<Variable>(Src);
1032     assert(SrcVar->hasReg());
1033     (Asm->*(Emitter.AddrXmm))(
1034         StackAddr, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1035                        SrcVar->getRegNum()));
1036   }
1037 }
1038
1039 template <class Machine>
1040 void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const {
1041   if (!BuildDefs::dump())
1042     return;
1043   Ostream &Str = Func->getContext()->getStrEmit();
1044   assert(this->getSrcSize() == 1);
1045   Type Ty = this->getSrc(0)->getType();
1046   assert(isScalarFloatingType(Ty));
1047   Str << "\tsqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
1048       << "\t";
1049   this->getSrc(0)->emit(Func);
1050   Str << ", ";
1051   this->getDest()->emit(Func);
1052 }
1053
1054 template <class Machine>
1055 void InstX86Addss<Machine>::emit(const Cfg *Func) const {
1056   if (!BuildDefs::dump())
1057     return;
1058   char buf[30];
1059   snprintf(
1060       buf, llvm::array_lengthof(buf), "add%s",
1061       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1062           .SdSsString);
1063   this->emitTwoAddress(buf, this, Func);
1064 }
1065
1066 template <class Machine>
1067 void InstX86Padd<Machine>::emit(const Cfg *Func) const {
1068   if (!BuildDefs::dump())
1069     return;
1070   char buf[30];
1071   snprintf(
1072       buf, llvm::array_lengthof(buf), "padd%s",
1073       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1074           .PackString);
1075   this->emitTwoAddress(buf, this, Func);
1076 }
1077
1078 template <class Machine>
1079 void InstX86Pmull<Machine>::emit(const Cfg *Func) const {
1080   if (!BuildDefs::dump())
1081     return;
1082   char buf[30];
1083   bool TypesAreValid = this->getDest()->getType() == IceType_v4i32 ||
1084                        this->getDest()->getType() == IceType_v8i16;
1085   bool InstructionSetIsValid =
1086       this->getDest()->getType() == IceType_v8i16 ||
1087       static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1088           Func->getTarget())
1089               ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
1090   (void)TypesAreValid;
1091   (void)InstructionSetIsValid;
1092   assert(TypesAreValid);
1093   assert(InstructionSetIsValid);
1094   snprintf(
1095       buf, llvm::array_lengthof(buf), "pmull%s",
1096       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1097           .PackString);
1098   this->emitTwoAddress(buf, this, Func);
1099 }
1100
1101 template <class Machine>
1102 void InstX86Pmull<Machine>::emitIAS(const Cfg *Func) const {
1103   Type Ty = this->getDest()->getType();
1104   bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16;
1105   bool InstructionSetIsValid =
1106       Ty == IceType_v8i16 ||
1107       static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1108           Func->getTarget())
1109               ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
1110   (void)TypesAreValid;
1111   (void)InstructionSetIsValid;
1112   assert(TypesAreValid);
1113   assert(InstructionSetIsValid);
1114   assert(this->getSrcSize() == 2);
1115   Type ElementTy = typeElementType(Ty);
1116   emitIASRegOpTyXMM<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1),
1117                              this->Emitter);
1118 }
1119
1120 template <class Machine>
1121 void InstX86Subss<Machine>::emit(const Cfg *Func) const {
1122   if (!BuildDefs::dump())
1123     return;
1124   char buf[30];
1125   snprintf(
1126       buf, llvm::array_lengthof(buf), "sub%s",
1127       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1128           .SdSsString);
1129   this->emitTwoAddress(buf, this, Func);
1130 }
1131
1132 template <class Machine>
1133 void InstX86Psub<Machine>::emit(const Cfg *Func) const {
1134   if (!BuildDefs::dump())
1135     return;
1136   char buf[30];
1137   snprintf(
1138       buf, llvm::array_lengthof(buf), "psub%s",
1139       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1140           .PackString);
1141   this->emitTwoAddress(buf, this, Func);
1142 }
1143
1144 template <class Machine>
1145 void InstX86Mulss<Machine>::emit(const Cfg *Func) const {
1146   if (!BuildDefs::dump())
1147     return;
1148   char buf[30];
1149   snprintf(
1150       buf, llvm::array_lengthof(buf), "mul%s",
1151       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1152           .SdSsString);
1153   this->emitTwoAddress(buf, this, Func);
1154 }
1155
1156 template <class Machine>
1157 void InstX86Pmuludq<Machine>::emit(const Cfg *Func) const {
1158   if (!BuildDefs::dump())
1159     return;
1160   assert(this->getSrc(0)->getType() == IceType_v4i32 &&
1161          this->getSrc(1)->getType() == IceType_v4i32);
1162   this->emitTwoAddress(this->Opcode, this, Func);
1163 }
1164
1165 template <class Machine>
1166 void InstX86Divss<Machine>::emit(const Cfg *Func) const {
1167   if (!BuildDefs::dump())
1168     return;
1169   char buf[30];
1170   snprintf(
1171       buf, llvm::array_lengthof(buf), "div%s",
1172       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1173           .SdSsString);
1174   this->emitTwoAddress(buf, this, Func);
1175 }
1176
1177 template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const {
1178   if (!BuildDefs::dump())
1179     return;
1180   Ostream &Str = Func->getContext()->getStrEmit();
1181   assert(this->getSrcSize() == 3);
1182   Operand *Src1 = this->getSrc(1);
1183   Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
1184   Src1->emit(Func);
1185 }
1186
1187 template <class Machine>
1188 void InstX86Div<Machine>::emitIAS(const Cfg *Func) const {
1189   assert(this->getSrcSize() == 3);
1190   const Operand *Src = this->getSrc(1);
1191   Type Ty = Src->getType();
1192   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
1193       Emitter = {&InstX86Base<Machine>::Traits::Assembler::div,
1194                  &InstX86Base<Machine>::Traits::Assembler::div};
1195   emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
1196 }
1197
1198 template <class Machine>
1199 void InstX86Idiv<Machine>::emit(const Cfg *Func) const {
1200   if (!BuildDefs::dump())
1201     return;
1202   Ostream &Str = Func->getContext()->getStrEmit();
1203   assert(this->getSrcSize() == 3);
1204   Operand *Src1 = this->getSrc(1);
1205   Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
1206   Src1->emit(Func);
1207 }
1208
1209 template <class Machine>
1210 void InstX86Idiv<Machine>::emitIAS(const Cfg *Func) const {
1211   assert(this->getSrcSize() == 3);
1212   const Operand *Src = this->getSrc(1);
1213   Type Ty = Src->getType();
1214   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
1215       Emitter = {&InstX86Base<Machine>::Traits::Assembler::idiv,
1216                  &InstX86Base<Machine>::Traits::Assembler::idiv};
1217   emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
1218 }
1219
1220 // pblendvb and blendvps take xmm0 as a final implicit argument.
1221 template <class Machine>
1222 void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
1223                            const Cfg *Func) {
1224   if (!BuildDefs::dump())
1225     return;
1226   Ostream &Str = Func->getContext()->getStrEmit();
1227   assert(Inst->getSrcSize() == 3);
1228   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1229          InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
1230   Str << "\t" << Opcode << "\t";
1231   Inst->getSrc(1)->emit(Func);
1232   Str << ", ";
1233   Inst->getDest()->emit(Func);
1234 }
1235
1236 template <class Machine>
1237 void emitIASVariableBlendInst(
1238     const Inst *Inst, const Cfg *Func,
1239     const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
1240         &Emitter) {
1241   assert(Inst->getSrcSize() == 3);
1242   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1243          InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
1244   const Variable *Dest = Inst->getDest();
1245   const Operand *Src = Inst->getSrc(1);
1246   emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter);
1247 }
1248
1249 template <class Machine>
1250 void InstX86Blendvps<Machine>::emit(const Cfg *Func) const {
1251   if (!BuildDefs::dump())
1252     return;
1253   assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1254              Func->getTarget())
1255              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
1256   emitVariableBlendInst<Machine>(this->Opcode, this, Func);
1257 }
1258
1259 template <class Machine>
1260 void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const {
1261   assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1262              Func->getTarget())
1263              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
1264   static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
1265       Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps,
1266                  &InstX86Base<Machine>::Traits::Assembler::blendvps};
1267   emitIASVariableBlendInst<Machine>(this, Func, Emitter);
1268 }
1269
1270 template <class Machine>
1271 void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const {
1272   if (!BuildDefs::dump())
1273     return;
1274   assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1275              Func->getTarget())
1276              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
1277   emitVariableBlendInst<Machine>(this->Opcode, this, Func);
1278 }
1279
1280 template <class Machine>
1281 void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const {
1282   assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1283              Func->getTarget())
1284              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
1285   static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
1286       Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb,
1287                  &InstX86Base<Machine>::Traits::Assembler::pblendvb};
1288   emitIASVariableBlendInst<Machine>(this, Func, Emitter);
1289 }
1290
1291 template <class Machine>
1292 void InstX86Imul<Machine>::emit(const Cfg *Func) const {
1293   if (!BuildDefs::dump())
1294     return;
1295   Ostream &Str = Func->getContext()->getStrEmit();
1296   assert(this->getSrcSize() == 2);
1297   Variable *Dest = this->getDest();
1298   if (isByteSizedArithType(Dest->getType())) {
1299     // The 8-bit version of imul only allows the form "imul r/m8".
1300     const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
1301     (void)Src0Var;
1302     assert(Src0Var &&
1303            Src0Var->getRegNum() ==
1304                InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1305     Str << "\timulb\t";
1306     this->getSrc(1)->emit(Func);
1307   } else if (llvm::isa<Constant>(this->getSrc(1))) {
1308     Str << "\timul" << this->getWidthString(Dest->getType()) << "\t";
1309     this->getSrc(1)->emit(Func);
1310     Str << ", ";
1311     this->getSrc(0)->emit(Func);
1312     Str << ", ";
1313     Dest->emit(Func);
1314   } else {
1315     this->emitTwoAddress("imul", this, Func);
1316   }
1317 }
1318
1319 template <class Machine>
1320 void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const {
1321   assert(this->getSrcSize() == 2);
1322   const Variable *Var = this->getDest();
1323   Type Ty = Var->getType();
1324   const Operand *Src = this->getSrc(1);
1325   if (isByteSizedArithType(Ty)) {
1326     // The 8-bit version of imul only allows the form "imul r/m8".
1327     const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
1328     (void)Src0Var;
1329     assert(Src0Var &&
1330            Src0Var->getRegNum() ==
1331                InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1332     static const typename InstX86Base<
1333         Machine>::Traits::Assembler::GPREmitterOneOp Emitter = {
1334         &InstX86Base<Machine>::Traits::Assembler::imul,
1335         &InstX86Base<Machine>::Traits::Assembler::imul};
1336     emitIASOpTyGPR<Machine>(Func, Ty, this->getSrc(1), Emitter);
1337   } else {
1338     // We only use imul as a two-address instruction even though
1339     // there is a 3 operand version when one of the operands is a constant.
1340     assert(Var == this->getSrc(0));
1341     static const typename InstX86Base<
1342         Machine>::Traits::Assembler::GPREmitterRegOp Emitter = {
1343         &InstX86Base<Machine>::Traits::Assembler::imul,
1344         &InstX86Base<Machine>::Traits::Assembler::imul,
1345         &InstX86Base<Machine>::Traits::Assembler::imul};
1346     emitIASRegOpTyGPR<Machine>(Func, Ty, Var, Src, Emitter);
1347   }
1348 }
1349
1350 template <class Machine>
1351 void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const {
1352   assert(this->getSrcSize() == 3);
1353   assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1354              Func->getTarget())
1355              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
1356   const Variable *Dest = this->getDest();
1357   assert(Dest == this->getSrc(0));
1358   Type Ty = Dest->getType();
1359   static const typename InstX86Base<Machine>::Traits::Assembler::
1360       template ThreeOpImmEmitter<
1361           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1362           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
1363           Emitter = {&InstX86Base<Machine>::Traits::Assembler::insertps,
1364                      &InstX86Base<Machine>::Traits::Assembler::insertps};
1365   emitIASThreeOpImmOps<
1366       Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1367       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1368       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
1369       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
1370       Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
1371 }
1372
1373 template <class Machine>
1374 void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const {
1375   if (!BuildDefs::dump())
1376     return;
1377   Ostream &Str = Func->getContext()->getStrEmit();
1378   assert(this->getSrcSize() == 1);
1379   Operand *Src0 = this->getSrc(0);
1380   assert(llvm::isa<Variable>(Src0));
1381   assert(llvm::cast<Variable>(Src0)->getRegNum() ==
1382          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1383   switch (Src0->getType()) {
1384   default:
1385     llvm_unreachable("unexpected source type!");
1386     break;
1387   case IceType_i8:
1388     assert(this->getDest()->getRegNum() ==
1389            InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1390     Str << "\tcbtw";
1391     break;
1392   case IceType_i16:
1393     assert(this->getDest()->getRegNum() ==
1394            InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
1395     Str << "\tcwtd";
1396     break;
1397   case IceType_i32:
1398     assert(this->getDest()->getRegNum() ==
1399            InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
1400     Str << "\tcltd";
1401     break;
1402   }
1403 }
1404
1405 template <class Machine>
1406 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const {
1407   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1408       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1409   assert(this->getSrcSize() == 1);
1410   Operand *Src0 = this->getSrc(0);
1411   assert(llvm::isa<Variable>(Src0));
1412   assert(llvm::cast<Variable>(Src0)->getRegNum() ==
1413          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1414   switch (Src0->getType()) {
1415   default:
1416     llvm_unreachable("unexpected source type!");
1417     break;
1418   case IceType_i8:
1419     assert(this->getDest()->getRegNum() ==
1420            InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1421     Asm->cbw();
1422     break;
1423   case IceType_i16:
1424     assert(this->getDest()->getRegNum() ==
1425            InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
1426     Asm->cwd();
1427     break;
1428   case IceType_i32:
1429     assert(this->getDest()->getRegNum() ==
1430            InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
1431     Asm->cdq();
1432     break;
1433   }
1434 }
1435
1436 template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const {
1437   if (!BuildDefs::dump())
1438     return;
1439   Ostream &Str = Func->getContext()->getStrEmit();
1440   assert(this->getSrcSize() == 2);
1441   assert(llvm::isa<Variable>(this->getSrc(0)));
1442   assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
1443          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1444   assert(
1445       this->getDest()->getRegNum() ==
1446       InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
1447   Str << "\tmul" << this->getWidthString(this->getDest()->getType()) << "\t";
1448   this->getSrc(1)->emit(Func);
1449 }
1450
1451 template <class Machine>
1452 void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const {
1453   assert(this->getSrcSize() == 2);
1454   assert(llvm::isa<Variable>(this->getSrc(0)));
1455   assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
1456          InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
1457   assert(
1458       this->getDest()->getRegNum() ==
1459       InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
1460   const Operand *Src = this->getSrc(1);
1461   Type Ty = Src->getType();
1462   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
1463       Emitter = {&InstX86Base<Machine>::Traits::Assembler::mul,
1464                  &InstX86Base<Machine>::Traits::Assembler::mul};
1465   emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
1466 }
1467
1468 template <class Machine> void InstX86Mul<Machine>::dump(const Cfg *Func) const {
1469   if (!BuildDefs::dump())
1470     return;
1471   Ostream &Str = Func->getContext()->getStrDump();
1472   this->dumpDest(Func);
1473   Str << " = mul." << this->getDest()->getType() << " ";
1474   this->dumpSources(Func);
1475 }
1476
1477 template <class Machine>
1478 void InstX86Shld<Machine>::emit(const Cfg *Func) const {
1479   if (!BuildDefs::dump())
1480     return;
1481   Ostream &Str = Func->getContext()->getStrEmit();
1482   Variable *Dest = this->getDest();
1483   assert(this->getSrcSize() == 3);
1484   assert(Dest == this->getSrc(0));
1485   Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t";
1486   if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
1487     (void)ShiftReg;
1488     assert(ShiftReg->getRegNum() ==
1489            InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
1490     Str << "%cl";
1491   } else {
1492     this->getSrc(2)->emit(Func);
1493   }
1494   Str << ", ";
1495   this->getSrc(1)->emit(Func);
1496   Str << ", ";
1497   Dest->emit(Func);
1498 }
1499
1500 template <class Machine>
1501 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const {
1502   assert(this->getSrcSize() == 3);
1503   assert(this->getDest() == this->getSrc(0));
1504   const Variable *Dest = this->getDest();
1505   const Operand *Src1 = this->getSrc(1);
1506   const Operand *Src2 = this->getSrc(2);
1507   static const typename InstX86Base<
1508       Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
1509       &InstX86Base<Machine>::Traits::Assembler::shld,
1510       &InstX86Base<Machine>::Traits::Assembler::shld};
1511   emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
1512 }
1513
1514 template <class Machine>
1515 void InstX86Shld<Machine>::dump(const Cfg *Func) const {
1516   if (!BuildDefs::dump())
1517     return;
1518   Ostream &Str = Func->getContext()->getStrDump();
1519   this->dumpDest(Func);
1520   Str << " = shld." << this->getDest()->getType() << " ";
1521   this->dumpSources(Func);
1522 }
1523
1524 template <class Machine>
1525 void InstX86Shrd<Machine>::emit(const Cfg *Func) const {
1526   if (!BuildDefs::dump())
1527     return;
1528   Ostream &Str = Func->getContext()->getStrEmit();
1529   Variable *Dest = this->getDest();
1530   assert(this->getSrcSize() == 3);
1531   assert(Dest == this->getSrc(0));
1532   Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t";
1533   if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
1534     (void)ShiftReg;
1535     assert(ShiftReg->getRegNum() ==
1536            InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
1537     Str << "%cl";
1538   } else {
1539     this->getSrc(2)->emit(Func);
1540   }
1541   Str << ", ";
1542   this->getSrc(1)->emit(Func);
1543   Str << ", ";
1544   Dest->emit(Func);
1545 }
1546
1547 template <class Machine>
1548 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const {
1549   assert(this->getSrcSize() == 3);
1550   assert(this->getDest() == this->getSrc(0));
1551   const Variable *Dest = this->getDest();
1552   const Operand *Src1 = this->getSrc(1);
1553   const Operand *Src2 = this->getSrc(2);
1554   static const typename InstX86Base<
1555       Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
1556       &InstX86Base<Machine>::Traits::Assembler::shrd,
1557       &InstX86Base<Machine>::Traits::Assembler::shrd};
1558   emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
1559 }
1560
1561 template <class Machine>
1562 void InstX86Shrd<Machine>::dump(const Cfg *Func) const {
1563   if (!BuildDefs::dump())
1564     return;
1565   Ostream &Str = Func->getContext()->getStrDump();
1566   this->dumpDest(Func);
1567   Str << " = shrd." << this->getDest()->getType() << " ";
1568   this->dumpSources(Func);
1569 }
1570
1571 template <class Machine>
1572 void InstX86Cmov<Machine>::emit(const Cfg *Func) const {
1573   if (!BuildDefs::dump())
1574     return;
1575   Ostream &Str = Func->getContext()->getStrEmit();
1576   Variable *Dest = this->getDest();
1577   Str << "\t";
1578   assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
1579   assert(this->getDest()->hasReg());
1580   Str << "cmov"
1581       << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
1582       << this->getWidthString(Dest->getType()) << "\t";
1583   this->getSrc(1)->emit(Func);
1584   Str << ", ";
1585   Dest->emit(Func);
1586 }
1587
1588 template <class Machine>
1589 void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const {
1590   assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
1591   assert(this->getDest()->hasReg());
1592   assert(this->getSrcSize() == 2);
1593   Operand *Src = this->getSrc(1);
1594   Type SrcTy = Src->getType();
1595   assert(SrcTy == IceType_i16 || SrcTy == IceType_i32);
1596   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1597       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1598   if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
1599     if (SrcVar->hasReg()) {
1600       Asm->cmov(SrcTy, Condition,
1601                 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
1602                     this->getDest()->getRegNum()),
1603                 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
1604                     SrcVar->getRegNum()));
1605     } else {
1606       Asm->cmov(
1607           SrcTy, Condition,
1608           InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
1609               this->getDest()->getRegNum()),
1610           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1611               Func->getTarget())
1612               ->stackVarToAsmOperand(SrcVar));
1613     }
1614   } else if (const auto Mem = llvm::dyn_cast<
1615                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
1616     assert(Mem->getSegmentRegister() ==
1617            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
1618     Asm->cmov(SrcTy, Condition,
1619               InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
1620                   this->getDest()->getRegNum()),
1621               Mem->toAsmAddress(Asm));
1622   } else {
1623     llvm_unreachable("Unexpected operand type");
1624   }
1625 }
1626
1627 template <class Machine>
1628 void InstX86Cmov<Machine>::dump(const Cfg *Func) const {
1629   if (!BuildDefs::dump())
1630     return;
1631   Ostream &Str = Func->getContext()->getStrDump();
1632   Str << "cmov"
1633       << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
1634       << ".";
1635   Str << this->getDest()->getType() << " ";
1636   this->dumpDest(Func);
1637   Str << ", ";
1638   this->dumpSources(Func);
1639 }
1640
1641 template <class Machine>
1642 void InstX86Cmpps<Machine>::emit(const Cfg *Func) const {
1643   if (!BuildDefs::dump())
1644     return;
1645   Ostream &Str = Func->getContext()->getStrEmit();
1646   assert(this->getSrcSize() == 2);
1647   assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
1648   Str << "\t";
1649   Str << "cmp"
1650       << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
1651       << "ps"
1652       << "\t";
1653   this->getSrc(1)->emit(Func);
1654   Str << ", ";
1655   this->getDest()->emit(Func);
1656 }
1657
1658 template <class Machine>
1659 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const {
1660   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1661       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1662   assert(this->getSrcSize() == 2);
1663   assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
1664   // Assuming there isn't any load folding for cmpps, and vector constants
1665   // are not allowed in PNaCl.
1666   assert(llvm::isa<Variable>(this->getSrc(1)));
1667   const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
1668   if (SrcVar->hasReg()) {
1669     Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1670                    this->getDest()->getRegNum()),
1671                InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1672                    SrcVar->getRegNum()),
1673                Condition);
1674   } else {
1675     typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
1676         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
1677             Func->getTarget())
1678             ->stackVarToAsmOperand(SrcVar);
1679     Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
1680                    this->getDest()->getRegNum()),
1681                SrcStackAddr, Condition);
1682   }
1683 }
1684
1685 template <class Machine>
1686 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const {
1687   if (!BuildDefs::dump())
1688     return;
1689   Ostream &Str = Func->getContext()->getStrDump();
1690   assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
1691   this->dumpDest(Func);
1692   Str << " = cmp"
1693       << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
1694       << "ps"
1695       << "\t";
1696   this->dumpSources(Func);
1697 }
1698
1699 template <class Machine>
1700 void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const {
1701   if (!BuildDefs::dump())
1702     return;
1703   Ostream &Str = Func->getContext()->getStrEmit();
1704   assert(this->getSrcSize() == 3);
1705   if (this->Locked) {
1706     Str << "\tlock";
1707   }
1708   Str << "\tcmpxchg" << this->getWidthString(this->getSrc(0)->getType())
1709       << "\t";
1710   this->getSrc(2)->emit(Func);
1711   Str << ", ";
1712   this->getSrc(0)->emit(Func);
1713 }
1714
1715 template <class Machine>
1716 void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const {
1717   assert(this->getSrcSize() == 3);
1718   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1719       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1720   Type Ty = this->getSrc(0)->getType();
1721   const auto Mem =
1722       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
1723           this->getSrc(0));
1724   assert(Mem->getSegmentRegister() ==
1725          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
1726   const typename InstX86Base<Machine>::Traits::Address Addr =
1727       Mem->toAsmAddress(Asm);
1728   const auto VarReg = llvm::cast<Variable>(this->getSrc(2));
1729   assert(VarReg->hasReg());
1730   const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
1731       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
1732           VarReg->getRegNum());
1733   Asm->cmpxchg(Ty, Addr, Reg, this->Locked);
1734 }
1735
1736 template <class Machine>
1737 void InstX86Cmpxchg<Machine>::dump(const Cfg *Func) const {
1738   if (!BuildDefs::dump())
1739     return;
1740   Ostream &Str = Func->getContext()->getStrDump();
1741   if (this->Locked) {
1742     Str << "lock ";
1743   }
1744   Str << "cmpxchg." << this->getSrc(0)->getType() << " ";
1745   this->dumpSources(Func);
1746 }
1747
1748 template <class Machine>
1749 void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const {
1750   if (!BuildDefs::dump())
1751     return;
1752   Ostream &Str = Func->getContext()->getStrEmit();
1753   assert(this->getSrcSize() == 5);
1754   if (this->Locked) {
1755     Str << "\tlock";
1756   }
1757   Str << "\tcmpxchg8b\t";
1758   this->getSrc(0)->emit(Func);
1759 }
1760
1761 template <class Machine>
1762 void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const {
1763   assert(this->getSrcSize() == 5);
1764   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1765       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1766   const auto Mem =
1767       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
1768           this->getSrc(0));
1769   assert(Mem->getSegmentRegister() ==
1770          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
1771   const typename InstX86Base<Machine>::Traits::Address Addr =
1772       Mem->toAsmAddress(Asm);
1773   Asm->cmpxchg8b(Addr, this->Locked);
1774 }
1775
1776 template <class Machine>
1777 void InstX86Cmpxchg8b<Machine>::dump(const Cfg *Func) const {
1778   if (!BuildDefs::dump())
1779     return;
1780   Ostream &Str = Func->getContext()->getStrDump();
1781   if (this->Locked) {
1782     Str << "lock ";
1783   }
1784   Str << "cmpxchg8b ";
1785   this->dumpSources(Func);
1786 }
1787
1788 template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const {
1789   if (!BuildDefs::dump())
1790     return;
1791   Ostream &Str = Func->getContext()->getStrEmit();
1792   assert(this->getSrcSize() == 1);
1793   Str << "\tcvt";
1794   if (isTruncating())
1795     Str << "t";
1796   Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
1797                                                           ->getType()]
1798              .CvtString << "2"
1799       << InstX86Base<
1800              Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1801              .CvtString << "\t";
1802   this->getSrc(0)->emit(Func);
1803   Str << ", ";
1804   this->getDest()->emit(Func);
1805 }
1806
1807 template <class Machine>
1808 void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
1809   assert(this->getSrcSize() == 1);
1810   const Variable *Dest = this->getDest();
1811   const Operand *Src = this->getSrc(0);
1812   Type DestTy = Dest->getType();
1813   Type SrcTy = Src->getType();
1814   switch (Variant) {
1815   case Si2ss: {
1816     assert(isScalarIntegerType(SrcTy));
1817     assert(typeWidthInBytes(SrcTy) <= 4);
1818     assert(isScalarFloatingType(DestTy));
1819     static const typename InstX86Base<Machine>::Traits::Assembler::
1820         template CastEmitterRegOp<
1821             typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1822             typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
1823             Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss,
1824                        &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss};
1825     emitIASCastRegOp<
1826         Machine,
1827         typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1828         typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
1829         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
1830         InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
1831         Func, DestTy, Dest, Src, Emitter);
1832     return;
1833   }
1834   case Tss2si: {
1835     assert(isScalarFloatingType(SrcTy));
1836     assert(isScalarIntegerType(DestTy));
1837     assert(typeWidthInBytes(DestTy) <= 4);
1838     static const typename InstX86Base<Machine>::Traits::Assembler::
1839         template CastEmitterRegOp<
1840             typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
1841             typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
1842             Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si,
1843                        &InstX86Base<Machine>::Traits::Assembler::cvttss2si};
1844     emitIASCastRegOp<
1845         Machine,
1846         typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
1847         typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
1848         InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
1849         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
1850         Func, SrcTy, Dest, Src, Emitter);
1851     return;
1852   }
1853   case Float2float: {
1854     assert(isScalarFloatingType(SrcTy));
1855     assert(isScalarFloatingType(DestTy));
1856     assert(DestTy != SrcTy);
1857     static const typename InstX86Base<
1858         Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
1859         &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float,
1860         &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float};
1861     emitIASRegOpTyXMM<Machine>(Func, SrcTy, Dest, Src, Emitter);
1862     return;
1863   }
1864   case Dq2ps: {
1865     assert(isVectorIntegerType(SrcTy));
1866     assert(isVectorFloatingType(DestTy));
1867     static const typename InstX86Base<
1868         Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
1869         &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps,
1870         &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps};
1871     emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
1872     return;
1873   }
1874   case Tps2dq: {
1875     assert(isVectorFloatingType(SrcTy));
1876     assert(isVectorIntegerType(DestTy));
1877     static const typename InstX86Base<
1878         Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
1879         &InstX86Base<Machine>::Traits::Assembler::cvttps2dq,
1880         &InstX86Base<Machine>::Traits::Assembler::cvttps2dq};
1881     emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
1882     return;
1883   }
1884   }
1885 }
1886
1887 template <class Machine> void InstX86Cvt<Machine>::dump(const Cfg *Func) const {
1888   if (!BuildDefs::dump())
1889     return;
1890   Ostream &Str = Func->getContext()->getStrDump();
1891   this->dumpDest(Func);
1892   Str << " = cvt";
1893   if (isTruncating())
1894     Str << "t";
1895   Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
1896                                                           ->getType()]
1897              .CvtString << "2"
1898       << InstX86Base<
1899              Machine>::Traits::TypeAttributes[this->getDest()->getType()]
1900              .CvtString << " ";
1901   this->dumpSources(Func);
1902 }
1903
1904 template <class Machine>
1905 void InstX86Icmp<Machine>::emit(const Cfg *Func) const {
1906   if (!BuildDefs::dump())
1907     return;
1908   Ostream &Str = Func->getContext()->getStrEmit();
1909   assert(this->getSrcSize() == 2);
1910   Str << "\tcmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
1911   this->getSrc(1)->emit(Func);
1912   Str << ", ";
1913   this->getSrc(0)->emit(Func);
1914 }
1915
1916 template <class Machine>
1917 void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const {
1918   assert(this->getSrcSize() == 2);
1919   const Operand *Src0 = this->getSrc(0);
1920   const Operand *Src1 = this->getSrc(1);
1921   Type Ty = Src0->getType();
1922   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
1923       RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::cmp,
1924                     &InstX86Base<Machine>::Traits::Assembler::cmp,
1925                     &InstX86Base<Machine>::Traits::Assembler::cmp};
1926   static const typename InstX86Base<
1927       Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
1928       &InstX86Base<Machine>::Traits::Assembler::cmp,
1929       &InstX86Base<Machine>::Traits::Assembler::cmp};
1930   if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
1931     if (SrcVar0->hasReg()) {
1932       emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
1933       return;
1934     }
1935   }
1936   emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
1937 }
1938
1939 template <class Machine>
1940 void InstX86Icmp<Machine>::dump(const Cfg *Func) const {
1941   if (!BuildDefs::dump())
1942     return;
1943   Ostream &Str = Func->getContext()->getStrDump();
1944   Str << "cmp." << this->getSrc(0)->getType() << " ";
1945   this->dumpSources(Func);
1946 }
1947
1948 template <class Machine>
1949 void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const {
1950   if (!BuildDefs::dump())
1951     return;
1952   Ostream &Str = Func->getContext()->getStrEmit();
1953   assert(this->getSrcSize() == 2);
1954   Str << "\tucomi"
1955       << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
1956                                                           ->getType()]
1957              .SdSsString << "\t";
1958   this->getSrc(1)->emit(Func);
1959   Str << ", ";
1960   this->getSrc(0)->emit(Func);
1961 }
1962
1963 template <class Machine>
1964 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const {
1965   assert(this->getSrcSize() == 2);
1966   // Currently src0 is always a variable by convention, to avoid having
1967   // two memory operands.
1968   assert(llvm::isa<Variable>(this->getSrc(0)));
1969   const auto Src0Var = llvm::cast<Variable>(this->getSrc(0));
1970   Type Ty = Src0Var->getType();
1971   static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
1972       Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss,
1973                  &InstX86Base<Machine>::Traits::Assembler::ucomiss};
1974   emitIASRegOpTyXMM<Machine>(Func, Ty, Src0Var, this->getSrc(1), Emitter);
1975 }
1976
1977 template <class Machine>
1978 void InstX86Ucomiss<Machine>::dump(const Cfg *Func) const {
1979   if (!BuildDefs::dump())
1980     return;
1981   Ostream &Str = Func->getContext()->getStrDump();
1982   Str << "ucomiss." << this->getSrc(0)->getType() << " ";
1983   this->dumpSources(Func);
1984 }
1985
1986 template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const {
1987   if (!BuildDefs::dump())
1988     return;
1989   Ostream &Str = Func->getContext()->getStrEmit();
1990   assert(this->getSrcSize() == 0);
1991   Str << "\tud2";
1992 }
1993
1994 template <class Machine>
1995 void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const {
1996   typename InstX86Base<Machine>::Traits::Assembler *Asm =
1997       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
1998   Asm->ud2();
1999 }
2000
2001 template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const {
2002   if (!BuildDefs::dump())
2003     return;
2004   Ostream &Str = Func->getContext()->getStrDump();
2005   Str << "ud2";
2006 }
2007
2008 template <class Machine>
2009 void InstX86Test<Machine>::emit(const Cfg *Func) const {
2010   if (!BuildDefs::dump())
2011     return;
2012   Ostream &Str = Func->getContext()->getStrEmit();
2013   assert(this->getSrcSize() == 2);
2014   Str << "\ttest" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
2015   this->getSrc(1)->emit(Func);
2016   Str << ", ";
2017   this->getSrc(0)->emit(Func);
2018 }
2019
2020 template <class Machine>
2021 void InstX86Test<Machine>::emitIAS(const Cfg *Func) const {
2022   assert(this->getSrcSize() == 2);
2023   const Operand *Src0 = this->getSrc(0);
2024   const Operand *Src1 = this->getSrc(1);
2025   Type Ty = Src0->getType();
2026   // The Reg/Addr form of test is not encodeable.
2027   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
2028       RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::test, nullptr,
2029                     &InstX86Base<Machine>::Traits::Assembler::test};
2030   static const typename InstX86Base<
2031       Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
2032       &InstX86Base<Machine>::Traits::Assembler::test,
2033       &InstX86Base<Machine>::Traits::Assembler::test};
2034   if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
2035     if (SrcVar0->hasReg()) {
2036       emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
2037       return;
2038     }
2039   }
2040   llvm_unreachable("Nothing actually generates this so it's untested");
2041   emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
2042 }
2043
2044 template <class Machine>
2045 void InstX86Test<Machine>::dump(const Cfg *Func) const {
2046   if (!BuildDefs::dump())
2047     return;
2048   Ostream &Str = Func->getContext()->getStrDump();
2049   Str << "test." << this->getSrc(0)->getType() << " ";
2050   this->dumpSources(Func);
2051 }
2052
2053 template <class Machine>
2054 void InstX86Mfence<Machine>::emit(const Cfg *Func) const {
2055   if (!BuildDefs::dump())
2056     return;
2057   Ostream &Str = Func->getContext()->getStrEmit();
2058   assert(this->getSrcSize() == 0);
2059   Str << "\tmfence";
2060 }
2061
2062 template <class Machine>
2063 void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const {
2064   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2065       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2066   Asm->mfence();
2067 }
2068
2069 template <class Machine>
2070 void InstX86Mfence<Machine>::dump(const Cfg *Func) const {
2071   if (!BuildDefs::dump())
2072     return;
2073   Ostream &Str = Func->getContext()->getStrDump();
2074   Str << "mfence";
2075 }
2076
2077 template <class Machine>
2078 void InstX86Store<Machine>::emit(const Cfg *Func) const {
2079   if (!BuildDefs::dump())
2080     return;
2081   Ostream &Str = Func->getContext()->getStrEmit();
2082   assert(this->getSrcSize() == 2);
2083   Type Ty = this->getSrc(0)->getType();
2084   Str << "\tmov" << this->getWidthString(Ty)
2085       << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
2086   this->getSrc(0)->emit(Func);
2087   Str << ", ";
2088   this->getSrc(1)->emit(Func);
2089 }
2090
2091 template <class Machine>
2092 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const {
2093   assert(this->getSrcSize() == 2);
2094   const Operand *Dest = this->getSrc(1);
2095   const Operand *Src = this->getSrc(0);
2096   Type DestTy = Dest->getType();
2097   if (isScalarFloatingType(DestTy)) {
2098     // Src must be a register, since Dest is a Mem operand of some kind.
2099     const auto SrcVar = llvm::cast<Variable>(Src);
2100     assert(SrcVar->hasReg());
2101     typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
2102         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2103             SrcVar->getRegNum());
2104     typename InstX86Base<Machine>::Traits::Assembler *Asm =
2105         Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2106     if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
2107       assert(!DestVar->hasReg());
2108       typename InstX86Base<Machine>::Traits::Address StackAddr(
2109           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2110               Func->getTarget())
2111               ->stackVarToAsmOperand(DestVar));
2112       Asm->movss(DestTy, StackAddr, SrcReg);
2113     } else {
2114       const auto DestMem =
2115           llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
2116               Dest);
2117       assert(DestMem->getSegmentRegister() ==
2118              InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
2119       Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
2120     }
2121     return;
2122   } else {
2123     assert(isScalarIntegerType(DestTy));
2124     static const typename InstX86Base<
2125         Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
2126         &InstX86Base<Machine>::Traits::Assembler::mov,
2127         &InstX86Base<Machine>::Traits::Assembler::mov};
2128     emitIASAsAddrOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRAddrEmitter);
2129   }
2130 }
2131
2132 template <class Machine>
2133 void InstX86Store<Machine>::dump(const Cfg *Func) const {
2134   if (!BuildDefs::dump())
2135     return;
2136   Ostream &Str = Func->getContext()->getStrDump();
2137   Str << "mov." << this->getSrc(0)->getType() << " ";
2138   this->getSrc(1)->dump(Func);
2139   Str << ", ";
2140   this->getSrc(0)->dump(Func);
2141 }
2142
2143 template <class Machine>
2144 void InstX86StoreP<Machine>::emit(const Cfg *Func) const {
2145   if (!BuildDefs::dump())
2146     return;
2147   Ostream &Str = Func->getContext()->getStrEmit();
2148   assert(this->getSrcSize() == 2);
2149   assert(isVectorType(this->getSrc(1)->getType()));
2150   Str << "\tmovups\t";
2151   this->getSrc(0)->emit(Func);
2152   Str << ", ";
2153   this->getSrc(1)->emit(Func);
2154 }
2155
2156 template <class Machine>
2157 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const {
2158   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2159       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2160   assert(this->getSrcSize() == 2);
2161   const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
2162   const auto DestMem =
2163       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
2164           this->getSrc(1));
2165   assert(DestMem->getSegmentRegister() ==
2166          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
2167   assert(SrcVar->hasReg());
2168   Asm->movups(DestMem->toAsmAddress(Asm),
2169               InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2170                   SrcVar->getRegNum()));
2171 }
2172
2173 template <class Machine>
2174 void InstX86StoreP<Machine>::dump(const Cfg *Func) const {
2175   if (!BuildDefs::dump())
2176     return;
2177   Ostream &Str = Func->getContext()->getStrDump();
2178   Str << "storep." << this->getSrc(0)->getType() << " ";
2179   this->getSrc(1)->dump(Func);
2180   Str << ", ";
2181   this->getSrc(0)->dump(Func);
2182 }
2183
2184 template <class Machine>
2185 void InstX86StoreQ<Machine>::emit(const Cfg *Func) const {
2186   if (!BuildDefs::dump())
2187     return;
2188   Ostream &Str = Func->getContext()->getStrEmit();
2189   assert(this->getSrcSize() == 2);
2190   assert(this->getSrc(1)->getType() == IceType_i64 ||
2191          this->getSrc(1)->getType() == IceType_f64 ||
2192          isVectorType(this->getSrc(1)->getType()));
2193   Str << "\tmovq\t";
2194   this->getSrc(0)->emit(Func);
2195   Str << ", ";
2196   this->getSrc(1)->emit(Func);
2197 }
2198
2199 template <class Machine>
2200 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const {
2201   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2202       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2203   assert(this->getSrcSize() == 2);
2204   const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
2205   const auto DestMem =
2206       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
2207           this->getSrc(1));
2208   assert(DestMem->getSegmentRegister() ==
2209          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
2210   assert(SrcVar->hasReg());
2211   Asm->movq(DestMem->toAsmAddress(Asm),
2212             InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2213                 SrcVar->getRegNum()));
2214 }
2215
2216 template <class Machine>
2217 void InstX86StoreQ<Machine>::dump(const Cfg *Func) const {
2218   if (!BuildDefs::dump())
2219     return;
2220   Ostream &Str = Func->getContext()->getStrDump();
2221   Str << "storeq." << this->getSrc(0)->getType() << " ";
2222   this->getSrc(1)->dump(Func);
2223   Str << ", ";
2224   this->getSrc(0)->dump(Func);
2225 }
2226
2227 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const {
2228   if (!BuildDefs::dump())
2229     return;
2230   Ostream &Str = Func->getContext()->getStrEmit();
2231   assert(this->getSrcSize() == 1);
2232   assert(this->getDest()->hasReg());
2233   Str << "\tleal\t";
2234   Operand *Src0 = this->getSrc(0);
2235   if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
2236     Type Ty = Src0Var->getType();
2237     // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
2238     // acceptable type.
2239     Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func);
2240   } else {
2241     Src0->emit(Func);
2242   }
2243   Str << ", ";
2244   this->getDest()->emit(Func);
2245 }
2246
2247 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const {
2248   if (!BuildDefs::dump())
2249     return;
2250   Ostream &Str = Func->getContext()->getStrEmit();
2251   assert(this->getSrcSize() == 1);
2252   Operand *Src = this->getSrc(0);
2253   Type SrcTy = Src->getType();
2254   Type DestTy = this->getDest()->getType();
2255   Str << "\tmov"
2256       << (!isScalarFloatingType(DestTy)
2257               ? this->getWidthString(SrcTy)
2258               : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString)
2259       << "\t";
2260   // For an integer truncation operation, src is wider than dest.
2261   // Ideally, we use a mov instruction whose data width matches the
2262   // narrower dest.  This is a problem if e.g. src is a register like
2263   // esi or si where there is no 8-bit version of the register.  To be
2264   // safe, we instead widen the dest to match src.  This works even
2265   // for stack-allocated dest variables because typeWidthOnStack()
2266   // pads to a 4-byte boundary even if only a lower portion is used.
2267   // TODO: This assert disallows usages such as copying a floating point
2268   // value between a vector and a scalar (which movss is used for).
2269   // Clean this up.
2270   assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) ==
2271          Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
2272   Src->emit(Func);
2273   Str << ", ";
2274   this->getDest()->asType(SrcTy)->emit(Func);
2275 }
2276
2277 template <class Machine>
2278 void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const {
2279   assert(this->getSrcSize() == 1);
2280   const Variable *Dest = this->getDest();
2281   const Operand *Src = this->getSrc(0);
2282   Type DestTy = Dest->getType();
2283   Type SrcTy = Src->getType();
2284   // Mov can be used for GPRs or XMM registers. Also, the type does not
2285   // necessarily match (Mov can be used for bitcasts). However, when
2286   // the type does not match, one of the operands must be a register.
2287   // Thus, the strategy is to find out if Src or Dest are a register,
2288   // then use that register's type to decide on which emitter set to use.
2289   // The emitter set will include reg-reg movs, but that case should
2290   // be unused when the types don't match.
2291   static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
2292       XmmRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::movss,
2293                        &InstX86Base<Machine>::Traits::Assembler::movss};
2294   static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
2295       GPRRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::mov,
2296                        &InstX86Base<Machine>::Traits::Assembler::mov,
2297                        &InstX86Base<Machine>::Traits::Assembler::mov};
2298   static const typename InstX86Base<
2299       Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
2300       &InstX86Base<Machine>::Traits::Assembler::mov,
2301       &InstX86Base<Machine>::Traits::Assembler::mov};
2302   // For an integer truncation operation, src is wider than dest.
2303   // Ideally, we use a mov instruction whose data width matches the
2304   // narrower dest.  This is a problem if e.g. src is a register like
2305   // esi or si where there is no 8-bit version of the register.  To be
2306   // safe, we instead widen the dest to match src.  This works even
2307   // for stack-allocated dest variables because typeWidthOnStack()
2308   // pads to a 4-byte boundary even if only a lower portion is used.
2309   // TODO: This assert disallows usages such as copying a floating point
2310   // value between a vector and a scalar (which movss is used for).
2311   // Clean this up.
2312   assert(
2313       Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) ==
2314       Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
2315   if (Dest->hasReg()) {
2316     if (isScalarFloatingType(DestTy)) {
2317       emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter);
2318       return;
2319     } else {
2320       assert(isScalarIntegerType(DestTy));
2321       // Widen DestTy for truncation (see above note). We should only do this
2322       // when both Src and Dest are integer types.
2323       if (isScalarIntegerType(SrcTy)) {
2324         DestTy = SrcTy;
2325       }
2326       emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter);
2327       return;
2328     }
2329   } else {
2330     // Dest must be Stack and Src *could* be a register. Use Src's type
2331     // to decide on the emitters.
2332     typename InstX86Base<Machine>::Traits::Address StackAddr(
2333         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2334             Func->getTarget())
2335             ->stackVarToAsmOperand(Dest));
2336     if (isScalarFloatingType(SrcTy)) {
2337       // Src must be a register.
2338       const auto SrcVar = llvm::cast<Variable>(Src);
2339       assert(SrcVar->hasReg());
2340       typename InstX86Base<Machine>::Traits::Assembler *Asm =
2341           Func->getAssembler<
2342               typename InstX86Base<Machine>::Traits::Assembler>();
2343       Asm->movss(SrcTy, StackAddr,
2344                  InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2345                      SrcVar->getRegNum()));
2346       return;
2347     } else {
2348       // Src can be a register or immediate.
2349       assert(isScalarIntegerType(SrcTy));
2350       emitIASAddrOpTyGPR<Machine>(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
2351       return;
2352     }
2353     return;
2354   }
2355 }
2356
2357 template <class Machine>
2358 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
2359   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2360       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2361   assert(this->getSrcSize() == 1);
2362   const Variable *Dest = this->getDest();
2363   const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
2364   // For insert/extract element (one of Src/Dest is an Xmm vector and
2365   // the other is an int type).
2366   if (SrcVar->getType() == IceType_i32) {
2367     assert(isVectorType(Dest->getType()));
2368     assert(Dest->hasReg());
2369     typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
2370         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2371             Dest->getRegNum());
2372     if (SrcVar->hasReg()) {
2373       Asm->movd(DestReg,
2374                 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
2375                     SrcVar->getRegNum()));
2376     } else {
2377       typename InstX86Base<Machine>::Traits::Address StackAddr(
2378           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2379               Func->getTarget())
2380               ->stackVarToAsmOperand(SrcVar));
2381       Asm->movd(DestReg, StackAddr);
2382     }
2383   } else {
2384     assert(isVectorType(SrcVar->getType()));
2385     assert(SrcVar->hasReg());
2386     assert(Dest->getType() == IceType_i32);
2387     typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
2388         InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2389             SrcVar->getRegNum());
2390     if (Dest->hasReg()) {
2391       Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
2392                     Dest->getRegNum()),
2393                 SrcReg);
2394     } else {
2395       typename InstX86Base<Machine>::Traits::Address StackAddr(
2396           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2397               Func->getTarget())
2398               ->stackVarToAsmOperand(Dest));
2399       Asm->movd(StackAddr, SrcReg);
2400     }
2401   }
2402 }
2403
2404 template <class Machine>
2405 void InstX86Movp<Machine>::emit(const Cfg *Func) const {
2406   if (!BuildDefs::dump())
2407     return;
2408   // TODO(wala,stichnot): movups works with all vector operands, but
2409   // there exist other instructions (movaps, movdqa, movdqu) that may
2410   // perform better, depending on the data type and alignment of the
2411   // operands.
2412   Ostream &Str = Func->getContext()->getStrEmit();
2413   assert(this->getSrcSize() == 1);
2414   Str << "\tmovups\t";
2415   this->getSrc(0)->emit(Func);
2416   Str << ", ";
2417   this->getDest()->emit(Func);
2418 }
2419
2420 template <class Machine>
2421 void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const {
2422   assert(this->getSrcSize() == 1);
2423   assert(isVectorType(this->getDest()->getType()));
2424   const Variable *Dest = this->getDest();
2425   const Operand *Src = this->getSrc(0);
2426   static const typename InstX86Base<
2427       Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
2428       &InstX86Base<Machine>::Traits::Assembler::movups,
2429       &InstX86Base<Machine>::Traits::Assembler::movups,
2430       &InstX86Base<Machine>::Traits::Assembler::movups};
2431   emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
2432 }
2433
2434 template <class Machine>
2435 void InstX86Movq<Machine>::emit(const Cfg *Func) const {
2436   if (!BuildDefs::dump())
2437     return;
2438   Ostream &Str = Func->getContext()->getStrEmit();
2439   assert(this->getSrcSize() == 1);
2440   assert(this->getDest()->getType() == IceType_i64 ||
2441          this->getDest()->getType() == IceType_f64);
2442   Str << "\tmovq\t";
2443   this->getSrc(0)->emit(Func);
2444   Str << ", ";
2445   this->getDest()->emit(Func);
2446 }
2447
2448 template <class Machine>
2449 void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const {
2450   assert(this->getSrcSize() == 1);
2451   assert(this->getDest()->getType() == IceType_i64 ||
2452          this->getDest()->getType() == IceType_f64);
2453   const Variable *Dest = this->getDest();
2454   const Operand *Src = this->getSrc(0);
2455   static const typename InstX86Base<
2456       Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
2457       &InstX86Base<Machine>::Traits::Assembler::movq,
2458       &InstX86Base<Machine>::Traits::Assembler::movq,
2459       &InstX86Base<Machine>::Traits::Assembler::movq};
2460   emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
2461 }
2462
2463 template <class Machine>
2464 void InstX86MovssRegs<Machine>::emitIAS(const Cfg *Func) const {
2465   // This is Binop variant is only intended to be used for reg-reg moves
2466   // where part of the Dest register is untouched.
2467   assert(this->getSrcSize() == 2);
2468   const Variable *Dest = this->getDest();
2469   assert(Dest == this->getSrc(0));
2470   const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
2471   assert(Dest->hasReg() && SrcVar->hasReg());
2472   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2473       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2474   Asm->movss(IceType_f32,
2475              InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2476                  Dest->getRegNum()),
2477              InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2478                  SrcVar->getRegNum()));
2479 }
2480
2481 template <class Machine>
2482 void InstX86Movsx<Machine>::emitIAS(const Cfg *Func) const {
2483   assert(this->getSrcSize() == 1);
2484   const Variable *Dest = this->getDest();
2485   const Operand *Src = this->getSrc(0);
2486   // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
2487   // we just use the full register for Dest to avoid having an
2488   // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
2489   Type SrcTy = Src->getType();
2490   assert(typeWidthInBytes(Dest->getType()) > 1);
2491   assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
2492   emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
2493                                           this->Emitter);
2494 }
2495
2496 template <class Machine>
2497 void InstX86Movzx<Machine>::emitIAS(const Cfg *Func) const {
2498   assert(this->getSrcSize() == 1);
2499   const Variable *Dest = this->getDest();
2500   const Operand *Src = this->getSrc(0);
2501   Type SrcTy = Src->getType();
2502   assert(typeWidthInBytes(Dest->getType()) > 1);
2503   assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
2504   emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
2505                                           this->Emitter);
2506 }
2507
2508 template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const {
2509   if (!BuildDefs::dump())
2510     return;
2511   Ostream &Str = Func->getContext()->getStrEmit();
2512   // TODO: Emit the right code for each variant.
2513   Str << "\tnop\t# variant = " << Variant;
2514 }
2515
2516 template <class Machine>
2517 void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const {
2518   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2519       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2520   // TODO: Emit the right code for the variant.
2521   Asm->nop();
2522 }
2523
2524 template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const {
2525   if (!BuildDefs::dump())
2526     return;
2527   Ostream &Str = Func->getContext()->getStrDump();
2528   Str << "nop (variant = " << Variant << ")";
2529 }
2530
2531 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const {
2532   if (!BuildDefs::dump())
2533     return;
2534   Ostream &Str = Func->getContext()->getStrEmit();
2535   assert(this->getSrcSize() == 1);
2536   Type Ty = this->getSrc(0)->getType();
2537   SizeT Width = typeWidthInBytes(Ty);
2538   const auto Var = llvm::dyn_cast<Variable>(this->getSrc(0));
2539   if (Var && Var->hasReg()) {
2540     // This is a physical xmm register, so we need to spill it to a
2541     // temporary stack slot.
2542     Str << "\tsubl\t$" << Width << ", %esp"
2543         << "\n";
2544     Str << "\tmov"
2545         << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
2546     Var->emit(Func);
2547     Str << ", (%esp)\n";
2548     Str << "\tfld" << this->getFldString(Ty) << "\t"
2549         << "(%esp)\n";
2550     Str << "\taddl\t$" << Width << ", %esp";
2551     return;
2552   }
2553   Str << "\tfld" << this->getFldString(Ty) << "\t";
2554   this->getSrc(0)->emit(Func);
2555 }
2556
2557 template <class Machine>
2558 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const {
2559   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2560       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2561   assert(this->getSrcSize() == 1);
2562   const Operand *Src = this->getSrc(0);
2563   Type Ty = Src->getType();
2564   if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
2565     if (Var->hasReg()) {
2566       // This is a physical xmm register, so we need to spill it to a
2567       // temporary stack slot.
2568       Immediate Width(typeWidthInBytes(Ty));
2569       Asm->sub(IceType_i32,
2570                InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
2571                Width);
2572       typename InstX86Base<Machine>::Traits::Address StackSlot =
2573           typename InstX86Base<Machine>::Traits::Address(
2574               InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0);
2575       Asm->movss(Ty, StackSlot,
2576                  InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2577                      Var->getRegNum()));
2578       Asm->fld(Ty, StackSlot);
2579       Asm->add(IceType_i32,
2580                InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
2581                Width);
2582     } else {
2583       typename InstX86Base<Machine>::Traits::Address StackAddr(
2584           static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2585               Func->getTarget())
2586               ->stackVarToAsmOperand(Var));
2587       Asm->fld(Ty, StackAddr);
2588     }
2589   } else if (const auto Mem = llvm::dyn_cast<
2590                  typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
2591     assert(Mem->getSegmentRegister() ==
2592            InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
2593     Asm->fld(Ty, Mem->toAsmAddress(Asm));
2594   } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
2595     Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
2596   } else {
2597     llvm_unreachable("Unexpected operand type");
2598   }
2599 }
2600
2601 template <class Machine> void InstX86Fld<Machine>::dump(const Cfg *Func) const {
2602   if (!BuildDefs::dump())
2603     return;
2604   Ostream &Str = Func->getContext()->getStrDump();
2605   Str << "fld." << this->getSrc(0)->getType() << " ";
2606   this->dumpSources(Func);
2607 }
2608
2609 template <class Machine>
2610 void InstX86Fstp<Machine>::emit(const Cfg *Func) const {
2611   if (!BuildDefs::dump())
2612     return;
2613   Ostream &Str = Func->getContext()->getStrEmit();
2614   assert(this->getSrcSize() == 0);
2615   // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2616   // "partially" delete the fstp if the Dest is unused.
2617   // Even if Dest is unused, the fstp should be kept for the SideEffects
2618   // of popping the stack.
2619   if (!this->getDest()) {
2620     Str << "\tfstp\tst(0)";
2621     return;
2622   }
2623   Type Ty = this->getDest()->getType();
2624   size_t Width = typeWidthInBytes(Ty);
2625   if (!this->getDest()->hasReg()) {
2626     Str << "\tfstp" << this->getFldString(Ty) << "\t";
2627     this->getDest()->emit(Func);
2628     return;
2629   }
2630   // Dest is a physical (xmm) register, so st(0) needs to go through
2631   // memory.  Hack this by creating a temporary stack slot, spilling
2632   // st(0) there, loading it into the xmm register, and deallocating
2633   // the stack slot.
2634   Str << "\tsubl\t$" << Width << ", %esp\n";
2635   Str << "\tfstp" << this->getFldString(Ty) << "\t"
2636       << "(%esp)\n";
2637   Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
2638       << "\t"
2639       << "(%esp), ";
2640   this->getDest()->emit(Func);
2641   Str << "\n";
2642   Str << "\taddl\t$" << Width << ", %esp";
2643 }
2644
2645 template <class Machine>
2646 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const {
2647   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2648       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2649   assert(this->getSrcSize() == 0);
2650   const Variable *Dest = this->getDest();
2651   // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2652   // "partially" delete the fstp if the Dest is unused.
2653   // Even if Dest is unused, the fstp should be kept for the SideEffects
2654   // of popping the stack.
2655   if (!Dest) {
2656     Asm->fstp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedSTReg(0));
2657     return;
2658   }
2659   Type Ty = Dest->getType();
2660   if (!Dest->hasReg()) {
2661     typename InstX86Base<Machine>::Traits::Address StackAddr(
2662         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2663             Func->getTarget())
2664             ->stackVarToAsmOperand(Dest));
2665     Asm->fstp(Ty, StackAddr);
2666   } else {
2667     // Dest is a physical (xmm) register, so st(0) needs to go through
2668     // memory.  Hack this by creating a temporary stack slot, spilling
2669     // st(0) there, loading it into the xmm register, and deallocating
2670     // the stack slot.
2671     Immediate Width(typeWidthInBytes(Ty));
2672     Asm->sub(IceType_i32,
2673              InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width);
2674     typename InstX86Base<Machine>::Traits::Address StackSlot =
2675         typename InstX86Base<Machine>::Traits::Address(
2676             InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0);
2677     Asm->fstp(Ty, StackSlot);
2678     Asm->movss(Ty, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
2679                        Dest->getRegNum()),
2680                StackSlot);
2681     Asm->add(IceType_i32,
2682              InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width);
2683   }
2684 }
2685
2686 template <class Machine>
2687 void InstX86Fstp<Machine>::dump(const Cfg *Func) const {
2688   if (!BuildDefs::dump())
2689     return;
2690   Ostream &Str = Func->getContext()->getStrDump();
2691   this->dumpDest(Func);
2692   Str << " = fstp." << this->getDest()->getType() << ", st(0)";
2693 }
2694
2695 template <class Machine>
2696 void InstX86Pcmpeq<Machine>::emit(const Cfg *Func) const {
2697   if (!BuildDefs::dump())
2698     return;
2699   char buf[30];
2700   snprintf(
2701       buf, llvm::array_lengthof(buf), "pcmpeq%s",
2702       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
2703           .PackString);
2704   this->emitTwoAddress(buf, this, Func);
2705 }
2706
2707 template <class Machine>
2708 void InstX86Pcmpgt<Machine>::emit(const Cfg *Func) const {
2709   if (!BuildDefs::dump())
2710     return;
2711   char buf[30];
2712   snprintf(
2713       buf, llvm::array_lengthof(buf), "pcmpgt%s",
2714       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
2715           .PackString);
2716   this->emitTwoAddress(buf, this, Func);
2717 }
2718
2719 template <class Machine>
2720 void InstX86Pextr<Machine>::emit(const Cfg *Func) const {
2721   if (!BuildDefs::dump())
2722     return;
2723   Ostream &Str = Func->getContext()->getStrEmit();
2724   assert(this->getSrcSize() == 2);
2725   // pextrb and pextrd are SSE4.1 instructions.
2726   assert(this->getSrc(0)->getType() == IceType_v8i16 ||
2727          this->getSrc(0)->getType() == IceType_v8i1 ||
2728          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2729              Func->getTarget())
2730                  ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
2731   Str << "\t" << this->Opcode
2732       << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
2733                                                           ->getType()]
2734              .PackString << "\t";
2735   this->getSrc(1)->emit(Func);
2736   Str << ", ";
2737   this->getSrc(0)->emit(Func);
2738   Str << ", ";
2739   Variable *Dest = this->getDest();
2740   // pextrw must take a register dest. There is an SSE4.1 version that takes
2741   // a memory dest, but we aren't using it. For uniformity, just restrict
2742   // them all to have a register dest for now.
2743   assert(Dest->hasReg());
2744   Dest->asType(IceType_i32)->emit(Func);
2745 }
2746
2747 template <class Machine>
2748 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const {
2749   assert(this->getSrcSize() == 2);
2750   // pextrb and pextrd are SSE4.1 instructions.
2751   const Variable *Dest = this->getDest();
2752   Type DispatchTy = Dest->getType();
2753   assert(DispatchTy == IceType_i16 ||
2754          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2755              Func->getTarget())
2756                  ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
2757   // pextrw must take a register dest. There is an SSE4.1 version that takes
2758   // a memory dest, but we aren't using it. For uniformity, just restrict
2759   // them all to have a register dest for now.
2760   assert(Dest->hasReg());
2761   // pextrw's Src(0) must be a register (both SSE4.1 and SSE2).
2762   assert(llvm::cast<Variable>(this->getSrc(0))->hasReg());
2763   static const typename InstX86Base<Machine>::Traits::Assembler::
2764       template ThreeOpImmEmitter<
2765           typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
2766           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
2767           Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr};
2768   emitIASThreeOpImmOps<
2769       Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
2770       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2771       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
2772       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
2773       Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter);
2774 }
2775
2776 template <class Machine>
2777 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const {
2778   if (!BuildDefs::dump())
2779     return;
2780   Ostream &Str = Func->getContext()->getStrEmit();
2781   assert(this->getSrcSize() == 3);
2782   // pinsrb and pinsrd are SSE4.1 instructions.
2783   assert(this->getDest()->getType() == IceType_v8i16 ||
2784          this->getDest()->getType() == IceType_v8i1 ||
2785          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2786              Func->getTarget())
2787                  ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
2788   Str << "\t" << this->Opcode
2789       << InstX86Base<
2790              Machine>::Traits::TypeAttributes[this->getDest()->getType()]
2791              .PackString << "\t";
2792   this->getSrc(2)->emit(Func);
2793   Str << ", ";
2794   Operand *Src1 = this->getSrc(1);
2795   if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
2796     // If src1 is a register, it should always be r32.
2797     if (Src1Var->hasReg()) {
2798       Src1Var->asType(IceType_i32)->emit(Func);
2799     } else {
2800       Src1Var->emit(Func);
2801     }
2802   } else {
2803     Src1->emit(Func);
2804   }
2805   Str << ", ";
2806   this->getDest()->emit(Func);
2807 }
2808
2809 template <class Machine>
2810 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const {
2811   assert(this->getSrcSize() == 3);
2812   assert(this->getDest() == this->getSrc(0));
2813   // pinsrb and pinsrd are SSE4.1 instructions.
2814   const Operand *Src0 = this->getSrc(1);
2815   Type DispatchTy = Src0->getType();
2816   assert(DispatchTy == IceType_i16 ||
2817          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2818              Func->getTarget())
2819                  ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
2820   // If src1 is a register, it should always be r32 (this should fall out
2821   // from the encodings for ByteRegs overlapping the encodings for r32),
2822   // but we have to trust the regalloc to not choose "ah", where it
2823   // doesn't overlap.
2824   static const typename InstX86Base<Machine>::Traits::Assembler::
2825       template ThreeOpImmEmitter<
2826           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2827           typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
2828           Emitter = {&InstX86Base<Machine>::Traits::Assembler::pinsr,
2829                      &InstX86Base<Machine>::Traits::Assembler::pinsr};
2830   emitIASThreeOpImmOps<
2831       Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2832       typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
2833       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
2834       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
2835       Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter);
2836 }
2837
2838 template <class Machine>
2839 void InstX86Pshufd<Machine>::emitIAS(const Cfg *Func) const {
2840   assert(this->getSrcSize() == 2);
2841   const Variable *Dest = this->getDest();
2842   Type Ty = Dest->getType();
2843   static const typename InstX86Base<Machine>::Traits::Assembler::
2844       template ThreeOpImmEmitter<
2845           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2846           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
2847           Emitter = {&InstX86Base<Machine>::Traits::Assembler::pshufd,
2848                      &InstX86Base<Machine>::Traits::Assembler::pshufd};
2849   emitIASThreeOpImmOps<
2850       Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2851       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2852       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
2853       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
2854       Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
2855 }
2856
2857 template <class Machine>
2858 void InstX86Shufps<Machine>::emitIAS(const Cfg *Func) const {
2859   assert(this->getSrcSize() == 3);
2860   const Variable *Dest = this->getDest();
2861   assert(Dest == this->getSrc(0));
2862   Type Ty = Dest->getType();
2863   static const typename InstX86Base<Machine>::Traits::Assembler::
2864       template ThreeOpImmEmitter<
2865           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2866           typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
2867           Emitter = {&InstX86Base<Machine>::Traits::Assembler::shufps,
2868                      &InstX86Base<Machine>::Traits::Assembler::shufps};
2869   emitIASThreeOpImmOps<
2870       Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2871       typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
2872       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
2873       InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
2874       Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
2875 }
2876
2877 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const {
2878   if (!BuildDefs::dump())
2879     return;
2880   Ostream &Str = Func->getContext()->getStrEmit();
2881   assert(this->getSrcSize() == 0);
2882   Str << "\tpop\t";
2883   this->getDest()->emit(Func);
2884 }
2885
2886 template <class Machine>
2887 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const {
2888   assert(this->getSrcSize() == 0);
2889   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2890       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2891   if (this->getDest()->hasReg()) {
2892     Asm->popl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
2893         this->getDest()->getRegNum()));
2894   } else {
2895     Asm->popl(
2896         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
2897             Func->getTarget())
2898             ->stackVarToAsmOperand(this->getDest()));
2899   }
2900 }
2901
2902 template <class Machine> void InstX86Pop<Machine>::dump(const Cfg *Func) const {
2903   if (!BuildDefs::dump())
2904     return;
2905   Ostream &Str = Func->getContext()->getStrDump();
2906   this->dumpDest(Func);
2907   Str << " = pop." << this->getDest()->getType() << " ";
2908 }
2909
2910 template <class Machine>
2911 void InstX86AdjustStack<Machine>::emit(const Cfg *Func) const {
2912   if (!BuildDefs::dump())
2913     return;
2914   Ostream &Str = Func->getContext()->getStrEmit();
2915   Str << "\tsubl\t$" << Amount << ", %esp";
2916   Func->getTarget()->updateStackAdjustment(Amount);
2917 }
2918
2919 template <class Machine>
2920 void InstX86AdjustStack<Machine>::emitIAS(const Cfg *Func) const {
2921   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2922       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2923   Asm->sub(IceType_i32,
2924            InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
2925            Immediate(Amount));
2926   Func->getTarget()->updateStackAdjustment(Amount);
2927 }
2928
2929 template <class Machine>
2930 void InstX86AdjustStack<Machine>::dump(const Cfg *Func) const {
2931   if (!BuildDefs::dump())
2932     return;
2933   Ostream &Str = Func->getContext()->getStrDump();
2934   Str << "esp = sub.i32 esp, " << Amount;
2935 }
2936
2937 template <class Machine>
2938 void InstX86Push<Machine>::emit(const Cfg *Func) const {
2939   if (!BuildDefs::dump())
2940     return;
2941   Ostream &Str = Func->getContext()->getStrEmit();
2942   assert(this->getSrcSize() == 1);
2943   // Push is currently only used for saving GPRs.
2944   const auto Var = llvm::cast<Variable>(this->getSrc(0));
2945   assert(Var->hasReg());
2946   Str << "\tpush\t";
2947   Var->emit(Func);
2948 }
2949
2950 template <class Machine>
2951 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const {
2952   assert(this->getSrcSize() == 1);
2953   // Push is currently only used for saving GPRs.
2954   const auto Var = llvm::cast<Variable>(this->getSrc(0));
2955   assert(Var->hasReg());
2956   typename InstX86Base<Machine>::Traits::Assembler *Asm =
2957       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2958   Asm->pushl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
2959       Var->getRegNum()));
2960 }
2961
2962 template <class Machine>
2963 void InstX86Push<Machine>::dump(const Cfg *Func) const {
2964   if (!BuildDefs::dump())
2965     return;
2966   Ostream &Str = Func->getContext()->getStrDump();
2967   Str << "push." << this->getSrc(0)->getType() << " ";
2968   this->dumpSources(Func);
2969 }
2970
2971 template <class Machine>
2972 void InstX86Psll<Machine>::emit(const Cfg *Func) const {
2973   if (!BuildDefs::dump())
2974     return;
2975   assert(this->getDest()->getType() == IceType_v8i16 ||
2976          this->getDest()->getType() == IceType_v8i1 ||
2977          this->getDest()->getType() == IceType_v4i32 ||
2978          this->getDest()->getType() == IceType_v4i1);
2979   char buf[30];
2980   snprintf(
2981       buf, llvm::array_lengthof(buf), "psll%s",
2982       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
2983           .PackString);
2984   this->emitTwoAddress(buf, this, Func);
2985 }
2986
2987 template <class Machine>
2988 void InstX86Psra<Machine>::emit(const Cfg *Func) const {
2989   if (!BuildDefs::dump())
2990     return;
2991   assert(this->getDest()->getType() == IceType_v8i16 ||
2992          this->getDest()->getType() == IceType_v8i1 ||
2993          this->getDest()->getType() == IceType_v4i32 ||
2994          this->getDest()->getType() == IceType_v4i1);
2995   char buf[30];
2996   snprintf(
2997       buf, llvm::array_lengthof(buf), "psra%s",
2998       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
2999           .PackString);
3000   this->emitTwoAddress(buf, this, Func);
3001 }
3002
3003 template <class Machine>
3004 void InstX86Psrl<Machine>::emit(const Cfg *Func) const {
3005   if (!BuildDefs::dump())
3006     return;
3007   char buf[30];
3008   snprintf(
3009       buf, llvm::array_lengthof(buf), "psrl%s",
3010       InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
3011           .PackString);
3012   this->emitTwoAddress(buf, this, Func);
3013 }
3014
3015 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const {
3016   if (!BuildDefs::dump())
3017     return;
3018   Ostream &Str = Func->getContext()->getStrEmit();
3019   Str << "\tret";
3020 }
3021
3022 template <class Machine>
3023 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const {
3024   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3025       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3026   Asm->ret();
3027 }
3028
3029 template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const {
3030   if (!BuildDefs::dump())
3031     return;
3032   Ostream &Str = Func->getContext()->getStrDump();
3033   Type Ty =
3034       (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType());
3035   Str << "ret." << Ty << " ";
3036   this->dumpSources(Func);
3037 }
3038
3039 template <class Machine>
3040 void InstX86Setcc<Machine>::emit(const Cfg *Func) const {
3041   if (!BuildDefs::dump())
3042     return;
3043   Ostream &Str = Func->getContext()->getStrEmit();
3044   Str << "\tset"
3045       << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
3046       << "\t";
3047   this->Dest->emit(Func);
3048 }
3049
3050 template <class Machine>
3051 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const {
3052   assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
3053   assert(this->getDest()->getType() == IceType_i1);
3054   assert(this->getSrcSize() == 0);
3055   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3056       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3057   if (this->getDest()->hasReg())
3058     Asm->setcc(Condition,
3059                InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteReg(
3060                    this->getDest()->getRegNum()));
3061   else
3062     Asm->setcc(
3063         Condition,
3064         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
3065             Func->getTarget())
3066             ->stackVarToAsmOperand(this->getDest()));
3067   return;
3068 }
3069
3070 template <class Machine>
3071 void InstX86Setcc<Machine>::dump(const Cfg *Func) const {
3072   if (!BuildDefs::dump())
3073     return;
3074   Ostream &Str = Func->getContext()->getStrDump();
3075   Str << "setcc."
3076       << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
3077       << " ";
3078   this->dumpDest(Func);
3079 }
3080
3081 template <class Machine>
3082 void InstX86Xadd<Machine>::emit(const Cfg *Func) const {
3083   if (!BuildDefs::dump())
3084     return;
3085   Ostream &Str = Func->getContext()->getStrEmit();
3086   if (this->Locked) {
3087     Str << "\tlock";
3088   }
3089   Str << "\txadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
3090   this->getSrc(1)->emit(Func);
3091   Str << ", ";
3092   this->getSrc(0)->emit(Func);
3093 }
3094
3095 template <class Machine>
3096 void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const {
3097   assert(this->getSrcSize() == 2);
3098   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3099       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3100   Type Ty = this->getSrc(0)->getType();
3101   const auto Mem =
3102       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
3103           this->getSrc(0));
3104   assert(Mem->getSegmentRegister() ==
3105          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
3106   const typename InstX86Base<Machine>::Traits::Address Addr =
3107       Mem->toAsmAddress(Asm);
3108   const auto VarReg = llvm::cast<Variable>(this->getSrc(1));
3109   assert(VarReg->hasReg());
3110   const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
3111       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
3112           VarReg->getRegNum());
3113   Asm->xadd(Ty, Addr, Reg, this->Locked);
3114 }
3115
3116 template <class Machine>
3117 void InstX86Xadd<Machine>::dump(const Cfg *Func) const {
3118   if (!BuildDefs::dump())
3119     return;
3120   Ostream &Str = Func->getContext()->getStrDump();
3121   if (this->Locked) {
3122     Str << "lock ";
3123   }
3124   Type Ty = this->getSrc(0)->getType();
3125   Str << "xadd." << Ty << " ";
3126   this->dumpSources(Func);
3127 }
3128
3129 template <class Machine>
3130 void InstX86Xchg<Machine>::emit(const Cfg *Func) const {
3131   if (!BuildDefs::dump())
3132     return;
3133   Ostream &Str = Func->getContext()->getStrEmit();
3134   Str << "\txchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
3135   this->getSrc(1)->emit(Func);
3136   Str << ", ";
3137   this->getSrc(0)->emit(Func);
3138 }
3139
3140 template <class Machine>
3141 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const {
3142   assert(this->getSrcSize() == 2);
3143   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3144       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3145   Type Ty = this->getSrc(0)->getType();
3146   const auto Mem =
3147       llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
3148           this->getSrc(0));
3149   assert(Mem->getSegmentRegister() ==
3150          InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
3151   const typename InstX86Base<Machine>::Traits::Address Addr =
3152       Mem->toAsmAddress(Asm);
3153   const auto VarReg = llvm::cast<Variable>(this->getSrc(1));
3154   assert(VarReg->hasReg());
3155   const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
3156       InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
3157           VarReg->getRegNum());
3158   Asm->xchg(Ty, Addr, Reg);
3159 }
3160
3161 template <class Machine>
3162 void InstX86Xchg<Machine>::dump(const Cfg *Func) const {
3163   if (!BuildDefs::dump())
3164     return;
3165   Ostream &Str = Func->getContext()->getStrDump();
3166   Type Ty = this->getSrc(0)->getType();
3167   Str << "xchg." << Ty << " ";
3168   this->dumpSources(Func);
3169 }
3170
3171 template <class Machine>
3172 void InstX86IacaStart<Machine>::emit(const Cfg *Func) const {
3173   if (!BuildDefs::dump())
3174     return;
3175   Ostream &Str = Func->getContext()->getStrEmit();
3176   Str << "\t# IACA_START\n"
3177       << "\t.byte 0x0F, 0x0B\n"
3178       << "\tmovl\t$111, %ebx\n"
3179       << "\t.byte 0x64, 0x67, 0x90";
3180 }
3181
3182 template <class Machine>
3183 void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const {
3184   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3185       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3186   Asm->iaca_start();
3187 }
3188
3189 template <class Machine>
3190 void InstX86IacaStart<Machine>::dump(const Cfg *Func) const {
3191   if (!BuildDefs::dump())
3192     return;
3193   Ostream &Str = Func->getContext()->getStrDump();
3194   Str << "IACA_START";
3195 }
3196
3197 template <class Machine>
3198 void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const {
3199   if (!BuildDefs::dump())
3200     return;
3201   Ostream &Str = Func->getContext()->getStrEmit();
3202   Str << "\t# IACA_END\n"
3203       << "\tmovl\t$222, %ebx\n"
3204       << "\t.byte 0x64, 0x67, 0x90\n"
3205       << "\t.byte 0x0F, 0x0B";
3206 }
3207
3208 template <class Machine>
3209 void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const {
3210   typename InstX86Base<Machine>::Traits::Assembler *Asm =
3211       Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
3212   Asm->iaca_end();
3213 }
3214
3215 template <class Machine>
3216 void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const {
3217   if (!BuildDefs::dump())
3218     return;
3219   Ostream &Str = Func->getContext()->getStrDump();
3220   Str << "IACA_END";
3221 }
3222
3223 } // end of namespace X86Internal
3224
3225 } // end of namespace Ice
3226
3227 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H