OSDN Git Service

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