• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- subzero/src/IceAssemblerX8632Impl.h - base x86 assembler -*- C++ -*-=//
2 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file.
5 //
6 // Modified by the Subzero authors.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //                        The Subzero Code Generator
11 //
12 // This file is distributed under the University of Illinois Open Source
13 // License. See LICENSE.TXT for details.
14 //
15 //===----------------------------------------------------------------------===//
16 //
17 /// \file
18 /// \brief Implements the AssemblerX8632 class.
19 //
20 //===----------------------------------------------------------------------===//
21 
22 #include "IceAssemblerX8632.h"
23 
24 #include "IceCfg.h"
25 #include "IceCfgNode.h"
26 #include "IceOperand.h"
27 #include "IceTargetLoweringX8632.h"
28 
29 namespace Ice {
30 namespace X8632 {
31 
AsmAddress(const Variable * Var,const TargetX8632 * Target)32 AsmAddress::AsmAddress(const Variable *Var, const TargetX8632 *Target) {
33   if (Var->hasReg())
34     llvm::report_fatal_error("Stack Variable has a register assigned");
35   if (Var->mustHaveReg()) {
36     llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
37                              ") has no register assigned - function " +
38                              Target->getFunc()->getFunctionName());
39   }
40   int32_t Offset = Var->getStackOffset();
41   auto BaseRegNum = Var->getBaseRegNum();
42   if (Var->getBaseRegNum().hasNoValue()) {
43     // If the stack pointer needs alignment, we must use the frame pointer
44     // for arguments. For locals, getFrameOrStackReg will return the stack
45     // pointer in this case.
46     if (Target->needsStackPointerAlignment() && Var->getIsArg()) {
47       assert(Target->hasFramePointer());
48       BaseRegNum = Target->getFrameReg();
49     } else {
50       BaseRegNum = Target->getFrameOrStackReg();
51     }
52   }
53 
54   GPRRegister Base = RegX8632::getEncodedGPR(BaseRegNum);
55 
56   if (Utils::IsInt(8, Offset)) {
57     SetModRM(1, Base);
58     if (Base == RegX8632::Encoded_Reg_esp)
59       SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
60     SetDisp8(Offset);
61   } else {
62     SetModRM(2, Base);
63     if (Base == RegX8632::Encoded_Reg_esp)
64       SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
65     SetDisp32(Offset);
66   }
67 }
68 
AsmAddress(const X86OperandMem * Mem,Ice::Assembler * Asm,const Ice::TargetLowering * Target)69 AsmAddress::AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
70                        const Ice::TargetLowering *Target) {
71   Mem->validateMemOperandPIC();
72   int32_t Disp = 0;
73   if (Mem->getBase() && Mem->getBase()->isRematerializable()) {
74     Disp += Mem->getBase()->getRematerializableOffset(Target);
75   }
76   // The index should never be rematerializable.  But if we ever allow it, then
77   // we should make sure the rematerialization offset is shifted by the Shift
78   // value.
79   assert(!Mem->getIndex() || !Mem->getIndex()->isRematerializable());
80 
81   AssemblerFixup *Fixup = nullptr;
82   // Determine the offset (is it relocatable?)
83   if (Mem->getOffset()) {
84     if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Mem->getOffset())) {
85       Disp += static_cast<int32_t>(CI->getValue());
86     } else if (const auto CR =
87                    llvm::dyn_cast<ConstantRelocatable>(Mem->getOffset())) {
88       Disp += CR->getOffset();
89       Fixup = Asm->createFixup(FK_Abs, CR);
90     } else {
91       llvm_unreachable("Unexpected offset type");
92     }
93   }
94 
95   // Now convert to the various possible forms.
96   if (Mem->getBase() && Mem->getIndex()) {
97     SetBaseIndex(RegX8632::getEncodedGPR(Mem->getBase()->getRegNum()),
98                  RegX8632::getEncodedGPR(Mem->getIndex()->getRegNum()),
99                  ScaleFactor(Mem->getShift()), Disp, Fixup);
100   } else if (Mem->getBase()) {
101     SetBase(RegX8632::getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
102   } else if (Mem->getIndex()) {
103     SetIndex(RegX8632::getEncodedGPR(Mem->getIndex()->getRegNum()),
104              ScaleFactor(Mem->getShift()), Disp, Fixup);
105   } else {
106     SetAbsolute(Disp, Fixup);
107   }
108 }
109 
AsmAddress(const VariableSplit * Split,const Cfg * Func)110 AsmAddress::AsmAddress(const VariableSplit *Split, const Cfg *Func) {
111   assert(!Split->getVar()->hasReg());
112   const ::Ice::TargetLowering *Target = Func->getTarget();
113   int32_t Offset = Split->getVar()->getStackOffset() + Split->getOffset();
114   SetBase(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), Offset,
115           AssemblerFixup::NoFixup);
116 }
117 
~AssemblerX8632()118 AssemblerX8632::~AssemblerX8632() {
119   if (BuildDefs::asserts()) {
120     for (const Label *Label : CfgNodeLabels) {
121       Label->finalCheck();
122     }
123     for (const Label *Label : LocalLabels) {
124       Label->finalCheck();
125     }
126   }
127 }
128 
alignFunction()129 void AssemblerX8632::alignFunction() {
130   const SizeT Align = 1 << getBundleAlignLog2Bytes();
131   SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
132   constexpr SizeT HltSize = 1;
133   while (BytesNeeded > 0) {
134     hlt();
135     BytesNeeded -= HltSize;
136   }
137 }
138 
getOrCreateLabel(SizeT Number,LabelVector & Labels)139 AssemblerX8632::Label *AssemblerX8632::getOrCreateLabel(SizeT Number,
140                                                         LabelVector &Labels) {
141   Label *L = nullptr;
142   if (Number == Labels.size()) {
143     L = new (this->allocate<Label>()) Label();
144     Labels.push_back(L);
145     return L;
146   }
147   if (Number > Labels.size()) {
148     Utils::reserveAndResize(Labels, Number + 1);
149   }
150   L = Labels[Number];
151   if (!L) {
152     L = new (this->allocate<Label>()) Label();
153     Labels[Number] = L;
154   }
155   return L;
156 }
157 
getCfgNodeLabel(SizeT NodeNumber)158 Ice::Label *AssemblerX8632::getCfgNodeLabel(SizeT NodeNumber) {
159   assert(NodeNumber < CfgNodeLabels.size());
160   return CfgNodeLabels[NodeNumber];
161 }
162 
163 AssemblerX8632::Label *
getOrCreateCfgNodeLabel(SizeT NodeNumber)164 AssemblerX8632::getOrCreateCfgNodeLabel(SizeT NodeNumber) {
165   return getOrCreateLabel(NodeNumber, CfgNodeLabels);
166 }
167 
getOrCreateLocalLabel(SizeT Number)168 AssemblerX8632::Label *AssemblerX8632::getOrCreateLocalLabel(SizeT Number) {
169   return getOrCreateLabel(Number, LocalLabels);
170 }
171 
bindCfgNodeLabel(const CfgNode * Node)172 void AssemblerX8632::bindCfgNodeLabel(const CfgNode *Node) {
173   assert(!getPreliminary());
174   Label *L = getOrCreateCfgNodeLabel(Node->getIndex());
175   this->bind(L);
176 }
177 
bindLocalLabel(SizeT Number)178 void AssemblerX8632::bindLocalLabel(SizeT Number) {
179   Label *L = getOrCreateLocalLabel(Number);
180   if (!getPreliminary())
181     this->bind(L);
182 }
183 
call(GPRRegister reg)184 void AssemblerX8632::call(GPRRegister reg) {
185   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
186   emitUint8(0xFF);
187   emitRegisterOperand(2, gprEncoding(reg));
188 }
189 
call(const AsmAddress & address)190 void AssemblerX8632::call(const AsmAddress &address) {
191   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
192   emitUint8(0xFF);
193   emitOperand(2, address);
194 }
195 
call(const ConstantRelocatable * label)196 void AssemblerX8632::call(const ConstantRelocatable *label) {
197   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
198   intptr_t call_start = Buffer.getPosition();
199   emitUint8(0xE8);
200   auto *Fixup = this->createFixup(FK_PcRel, label);
201   Fixup->set_addend(-4);
202   emitFixup(Fixup);
203   emitInt32(0);
204   assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
205   (void)call_start;
206 }
207 
call(const Immediate & abs_address)208 void AssemblerX8632::call(const Immediate &abs_address) {
209   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
210   intptr_t call_start = Buffer.getPosition();
211   emitUint8(0xE8);
212   auto *Fixup = this->createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
213   Fixup->set_addend(abs_address.value() - 4);
214   emitFixup(Fixup);
215   emitInt32(0);
216   assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
217   (void)call_start;
218 }
219 
pushl(GPRRegister reg)220 void AssemblerX8632::pushl(GPRRegister reg) {
221   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
222   emitUint8(0x50 + gprEncoding(reg));
223 }
224 
pushl(const Immediate & Imm)225 void AssemblerX8632::pushl(const Immediate &Imm) {
226   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
227   emitUint8(0x68);
228   emitInt32(Imm.value());
229 }
230 
pushl(const ConstantRelocatable * Label)231 void AssemblerX8632::pushl(const ConstantRelocatable *Label) {
232   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
233   emitUint8(0x68);
234   emitFixup(this->createFixup(FK_Abs, Label));
235   // In x86-32, the emitted value is an addend to the relocation. Therefore, we
236   // must emit a 0 (because we're pushing an absolute relocation.)
237   // In x86-64, the emitted value does not matter (the addend lives in the
238   // relocation record as an extra field.)
239   emitInt32(0);
240 }
241 
popl(GPRRegister reg)242 void AssemblerX8632::popl(GPRRegister reg) {
243   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
244   // Any type that would not force a REX prefix to be emitted can be provided
245   // here.
246   emitUint8(0x58 + gprEncoding(reg));
247 }
248 
popl(const AsmAddress & address)249 void AssemblerX8632::popl(const AsmAddress &address) {
250   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
251   emitUint8(0x8F);
252   emitOperand(0, address);
253 }
254 
pushal()255 void AssemblerX8632::pushal() {
256   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
257   emitUint8(0x60);
258 }
259 
popal()260 void AssemblerX8632::popal() {
261   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
262   emitUint8(0x61);
263 }
264 
setcc(BrCond condition,ByteRegister dst)265 void AssemblerX8632::setcc(BrCond condition, ByteRegister dst) {
266   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
267   emitUint8(0x0F);
268   emitUint8(0x90 + condition);
269   emitUint8(0xC0 + gprEncoding(dst));
270 }
271 
setcc(BrCond condition,const AsmAddress & address)272 void AssemblerX8632::setcc(BrCond condition, const AsmAddress &address) {
273   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
274   emitUint8(0x0F);
275   emitUint8(0x90 + condition);
276   emitOperand(0, address);
277 }
278 
mov(Type Ty,GPRRegister dst,const Immediate & imm)279 void AssemblerX8632::mov(Type Ty, GPRRegister dst, const Immediate &imm) {
280   assert(Ty != IceType_i64 && "i64 not supported yet.");
281   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
282   if (Ty == IceType_i16)
283     emitOperandSizeOverride();
284   if (isByteSizedType(Ty)) {
285     emitUint8(0xB0 + gprEncoding(dst));
286     emitUint8(imm.value() & 0xFF);
287   } else {
288     // TODO(jpp): When removing the assertion above ensure that in x86-64 we
289     // emit a 64-bit immediate.
290     emitUint8(0xB8 + gprEncoding(dst));
291     emitImmediate(Ty, imm);
292   }
293 }
294 
mov(Type Ty,GPRRegister dst,GPRRegister src)295 void AssemblerX8632::mov(Type Ty, GPRRegister dst, GPRRegister src) {
296   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
297   if (Ty == IceType_i16)
298     emitOperandSizeOverride();
299   if (isByteSizedType(Ty)) {
300     emitUint8(0x88);
301   } else {
302     emitUint8(0x89);
303   }
304   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
305 }
306 
mov(Type Ty,GPRRegister dst,const AsmAddress & src)307 void AssemblerX8632::mov(Type Ty, GPRRegister dst, const AsmAddress &src) {
308   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
309   if (Ty == IceType_i16)
310     emitOperandSizeOverride();
311   if (isByteSizedType(Ty)) {
312     emitUint8(0x8A);
313   } else {
314     emitUint8(0x8B);
315   }
316   emitOperand(gprEncoding(dst), src);
317 }
318 
mov(Type Ty,const AsmAddress & dst,GPRRegister src)319 void AssemblerX8632::mov(Type Ty, const AsmAddress &dst, GPRRegister src) {
320   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
321   if (Ty == IceType_i16)
322     emitOperandSizeOverride();
323   if (isByteSizedType(Ty)) {
324     emitUint8(0x88);
325   } else {
326     emitUint8(0x89);
327   }
328   emitOperand(gprEncoding(src), dst);
329 }
330 
mov(Type Ty,const AsmAddress & dst,const Immediate & imm)331 void AssemblerX8632::mov(Type Ty, const AsmAddress &dst, const Immediate &imm) {
332   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
333   if (Ty == IceType_i16)
334     emitOperandSizeOverride();
335   if (isByteSizedType(Ty)) {
336     emitUint8(0xC6);
337     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
338     emitOperand(0, dst, OffsetFromNextInstruction);
339     emitUint8(imm.value() & 0xFF);
340   } else {
341     emitUint8(0xC7);
342     const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4;
343     emitOperand(0, dst, OffsetFromNextInstruction);
344     emitImmediate(Ty, imm);
345   }
346 }
347 
movzx(Type SrcTy,GPRRegister dst,GPRRegister src)348 void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, GPRRegister src) {
349   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
350   bool ByteSized = isByteSizedType(SrcTy);
351   assert(ByteSized || SrcTy == IceType_i16);
352   emitUint8(0x0F);
353   emitUint8(ByteSized ? 0xB6 : 0xB7);
354   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
355 }
356 
movzx(Type SrcTy,GPRRegister dst,const AsmAddress & src)357 void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, const AsmAddress &src) {
358   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
359   bool ByteSized = isByteSizedType(SrcTy);
360   assert(ByteSized || SrcTy == IceType_i16);
361   emitUint8(0x0F);
362   emitUint8(ByteSized ? 0xB6 : 0xB7);
363   emitOperand(gprEncoding(dst), src);
364 }
365 
movsx(Type SrcTy,GPRRegister dst,GPRRegister src)366 void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, GPRRegister src) {
367   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
368   bool ByteSized = isByteSizedType(SrcTy);
369   assert(ByteSized || SrcTy == IceType_i16);
370   emitUint8(0x0F);
371   emitUint8(ByteSized ? 0xBE : 0xBF);
372   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
373 }
374 
movsx(Type SrcTy,GPRRegister dst,const AsmAddress & src)375 void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, const AsmAddress &src) {
376   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
377   bool ByteSized = isByteSizedType(SrcTy);
378   assert(ByteSized || SrcTy == IceType_i16);
379   emitUint8(0x0F);
380   emitUint8(ByteSized ? 0xBE : 0xBF);
381   emitOperand(gprEncoding(dst), src);
382 }
383 
lea(Type Ty,GPRRegister dst,const AsmAddress & src)384 void AssemblerX8632::lea(Type Ty, GPRRegister dst, const AsmAddress &src) {
385   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
386   assert(Ty == IceType_i16 || Ty == IceType_i32);
387   if (Ty == IceType_i16)
388     emitOperandSizeOverride();
389   emitUint8(0x8D);
390   emitOperand(gprEncoding(dst), src);
391 }
392 
cmov(Type Ty,BrCond cond,GPRRegister dst,GPRRegister src)393 void AssemblerX8632::cmov(Type Ty, BrCond cond, GPRRegister dst,
394                           GPRRegister src) {
395   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
396   if (Ty == IceType_i16)
397     emitOperandSizeOverride();
398   else
399     assert(Ty == IceType_i32);
400   emitUint8(0x0F);
401   emitUint8(0x40 + cond);
402   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
403 }
404 
cmov(Type Ty,BrCond cond,GPRRegister dst,const AsmAddress & src)405 void AssemblerX8632::cmov(Type Ty, BrCond cond, GPRRegister dst,
406                           const AsmAddress &src) {
407   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
408   if (Ty == IceType_i16)
409     emitOperandSizeOverride();
410   else
411     assert(Ty == IceType_i32);
412   emitUint8(0x0F);
413   emitUint8(0x40 + cond);
414   emitOperand(gprEncoding(dst), src);
415 }
416 
rep_movsb()417 void AssemblerX8632::rep_movsb() {
418   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
419   emitUint8(0xF3);
420   emitUint8(0xA4);
421 }
422 
movss(Type Ty,XmmRegister dst,const AsmAddress & src)423 void AssemblerX8632::movss(Type Ty, XmmRegister dst, const AsmAddress &src) {
424   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
425   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
426   emitUint8(0x0F);
427   emitUint8(0x10);
428   emitOperand(gprEncoding(dst), src);
429 }
430 
movss(Type Ty,const AsmAddress & dst,XmmRegister src)431 void AssemblerX8632::movss(Type Ty, const AsmAddress &dst, XmmRegister src) {
432   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
433   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
434   emitUint8(0x0F);
435   emitUint8(0x11);
436   emitOperand(gprEncoding(src), dst);
437 }
438 
movss(Type Ty,XmmRegister dst,XmmRegister src)439 void AssemblerX8632::movss(Type Ty, XmmRegister dst, XmmRegister src) {
440   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
441   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
442   emitUint8(0x0F);
443   emitUint8(0x11);
444   emitXmmRegisterOperand(src, dst);
445 }
446 
movd(Type SrcTy,XmmRegister dst,GPRRegister src)447 void AssemblerX8632::movd(Type SrcTy, XmmRegister dst, GPRRegister src) {
448   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
449   emitUint8(0x66);
450   emitUint8(0x0F);
451   emitUint8(0x6E);
452   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
453 }
454 
movd(Type SrcTy,XmmRegister dst,const AsmAddress & src)455 void AssemblerX8632::movd(Type SrcTy, XmmRegister dst, const AsmAddress &src) {
456   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
457   emitUint8(0x66);
458   emitUint8(0x0F);
459   emitUint8(0x6E);
460   emitOperand(gprEncoding(dst), src);
461 }
462 
movd(Type DestTy,GPRRegister dst,XmmRegister src)463 void AssemblerX8632::movd(Type DestTy, GPRRegister dst, XmmRegister src) {
464   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
465   emitUint8(0x66);
466   emitUint8(0x0F);
467   emitUint8(0x7E);
468   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
469 }
470 
movd(Type DestTy,const AsmAddress & dst,XmmRegister src)471 void AssemblerX8632::movd(Type DestTy, const AsmAddress &dst, XmmRegister src) {
472   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
473   emitUint8(0x66);
474   emitUint8(0x0F);
475   emitUint8(0x7E);
476   emitOperand(gprEncoding(src), dst);
477 }
478 
movq(XmmRegister dst,XmmRegister src)479 void AssemblerX8632::movq(XmmRegister dst, XmmRegister src) {
480   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
481   emitUint8(0xF3);
482   emitUint8(0x0F);
483   emitUint8(0x7E);
484   emitXmmRegisterOperand(dst, src);
485 }
486 
movq(const AsmAddress & dst,XmmRegister src)487 void AssemblerX8632::movq(const AsmAddress &dst, XmmRegister src) {
488   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
489   emitUint8(0x66);
490   emitUint8(0x0F);
491   emitUint8(0xD6);
492   emitOperand(gprEncoding(src), dst);
493 }
494 
movq(XmmRegister dst,const AsmAddress & src)495 void AssemblerX8632::movq(XmmRegister dst, const AsmAddress &src) {
496   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
497   emitUint8(0xF3);
498   emitUint8(0x0F);
499   emitUint8(0x7E);
500   emitOperand(gprEncoding(dst), src);
501 }
502 
addss(Type Ty,XmmRegister dst,XmmRegister src)503 void AssemblerX8632::addss(Type Ty, XmmRegister dst, XmmRegister src) {
504   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
505   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
506   emitUint8(0x0F);
507   emitUint8(0x58);
508   emitXmmRegisterOperand(dst, src);
509 }
510 
addss(Type Ty,XmmRegister dst,const AsmAddress & src)511 void AssemblerX8632::addss(Type Ty, XmmRegister dst, const AsmAddress &src) {
512   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
513   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
514   emitUint8(0x0F);
515   emitUint8(0x58);
516   emitOperand(gprEncoding(dst), src);
517 }
518 
subss(Type Ty,XmmRegister dst,XmmRegister src)519 void AssemblerX8632::subss(Type Ty, XmmRegister dst, XmmRegister src) {
520   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
521   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
522   emitUint8(0x0F);
523   emitUint8(0x5C);
524   emitXmmRegisterOperand(dst, src);
525 }
526 
subss(Type Ty,XmmRegister dst,const AsmAddress & src)527 void AssemblerX8632::subss(Type Ty, XmmRegister dst, const AsmAddress &src) {
528   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
529   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
530   emitUint8(0x0F);
531   emitUint8(0x5C);
532   emitOperand(gprEncoding(dst), src);
533 }
534 
mulss(Type Ty,XmmRegister dst,XmmRegister src)535 void AssemblerX8632::mulss(Type Ty, XmmRegister dst, XmmRegister src) {
536   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
537   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
538   emitUint8(0x0F);
539   emitUint8(0x59);
540   emitXmmRegisterOperand(dst, src);
541 }
542 
mulss(Type Ty,XmmRegister dst,const AsmAddress & src)543 void AssemblerX8632::mulss(Type Ty, XmmRegister dst, const AsmAddress &src) {
544   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
545   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
546   emitUint8(0x0F);
547   emitUint8(0x59);
548   emitOperand(gprEncoding(dst), src);
549 }
550 
divss(Type Ty,XmmRegister dst,XmmRegister src)551 void AssemblerX8632::divss(Type Ty, XmmRegister dst, XmmRegister src) {
552   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
553   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
554   emitUint8(0x0F);
555   emitUint8(0x5E);
556   emitXmmRegisterOperand(dst, src);
557 }
558 
divss(Type Ty,XmmRegister dst,const AsmAddress & src)559 void AssemblerX8632::divss(Type Ty, XmmRegister dst, const AsmAddress &src) {
560   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
561   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
562   emitUint8(0x0F);
563   emitUint8(0x5E);
564   emitOperand(gprEncoding(dst), src);
565 }
566 
fld(Type Ty,const AsmAddress & src)567 void AssemblerX8632::fld(Type Ty, const AsmAddress &src) {
568   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
569   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
570   emitOperand(0, src);
571 }
572 
fstp(Type Ty,const AsmAddress & dst)573 void AssemblerX8632::fstp(Type Ty, const AsmAddress &dst) {
574   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
575   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
576   emitOperand(3, dst);
577 }
578 
fstp(RegX8632::X87STRegister st)579 void AssemblerX8632::fstp(RegX8632::X87STRegister st) {
580   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
581   emitUint8(0xDD);
582   emitUint8(0xD8 + st);
583 }
584 
movaps(XmmRegister dst,XmmRegister src)585 void AssemblerX8632::movaps(XmmRegister dst, XmmRegister src) {
586   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
587   emitUint8(0x0F);
588   emitUint8(0x28);
589   emitXmmRegisterOperand(dst, src);
590 }
591 
movups(XmmRegister dst,XmmRegister src)592 void AssemblerX8632::movups(XmmRegister dst, XmmRegister src) {
593   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
594   emitUint8(0x0F);
595   emitUint8(0x10);
596   emitXmmRegisterOperand(dst, src);
597 }
598 
movups(XmmRegister dst,const AsmAddress & src)599 void AssemblerX8632::movups(XmmRegister dst, const AsmAddress &src) {
600   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
601   emitUint8(0x0F);
602   emitUint8(0x10);
603   emitOperand(gprEncoding(dst), src);
604 }
605 
movups(const AsmAddress & dst,XmmRegister src)606 void AssemblerX8632::movups(const AsmAddress &dst, XmmRegister src) {
607   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
608   emitUint8(0x0F);
609   emitUint8(0x11);
610   emitOperand(gprEncoding(src), dst);
611 }
612 
padd(Type Ty,XmmRegister dst,XmmRegister src)613 void AssemblerX8632::padd(Type Ty, XmmRegister dst, XmmRegister src) {
614   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
615   emitUint8(0x66);
616   emitUint8(0x0F);
617   if (isByteSizedArithType(Ty)) {
618     emitUint8(0xFC);
619   } else if (Ty == IceType_i16) {
620     emitUint8(0xFD);
621   } else {
622     emitUint8(0xFE);
623   }
624   emitXmmRegisterOperand(dst, src);
625 }
626 
padd(Type Ty,XmmRegister dst,const AsmAddress & src)627 void AssemblerX8632::padd(Type Ty, XmmRegister dst, const AsmAddress &src) {
628   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
629   emitUint8(0x66);
630   emitUint8(0x0F);
631   if (isByteSizedArithType(Ty)) {
632     emitUint8(0xFC);
633   } else if (Ty == IceType_i16) {
634     emitUint8(0xFD);
635   } else {
636     emitUint8(0xFE);
637   }
638   emitOperand(gprEncoding(dst), src);
639 }
640 
padds(Type Ty,XmmRegister dst,XmmRegister src)641 void AssemblerX8632::padds(Type Ty, XmmRegister dst, XmmRegister src) {
642   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
643   emitUint8(0x66);
644   emitUint8(0x0F);
645   if (isByteSizedArithType(Ty)) {
646     emitUint8(0xEC);
647   } else if (Ty == IceType_i16) {
648     emitUint8(0xED);
649   } else {
650     assert(false && "Unexpected padds operand type");
651   }
652   emitXmmRegisterOperand(dst, src);
653 }
654 
padds(Type Ty,XmmRegister dst,const AsmAddress & src)655 void AssemblerX8632::padds(Type Ty, XmmRegister dst, const AsmAddress &src) {
656   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
657   emitUint8(0x66);
658   emitUint8(0x0F);
659   if (isByteSizedArithType(Ty)) {
660     emitUint8(0xEC);
661   } else if (Ty == IceType_i16) {
662     emitUint8(0xED);
663   } else {
664     assert(false && "Unexpected padds operand type");
665   }
666   emitOperand(gprEncoding(dst), src);
667 }
668 
paddus(Type Ty,XmmRegister dst,XmmRegister src)669 void AssemblerX8632::paddus(Type Ty, XmmRegister dst, XmmRegister src) {
670   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
671   emitUint8(0x66);
672   emitUint8(0x0F);
673   if (isByteSizedArithType(Ty)) {
674     emitUint8(0xDC);
675   } else if (Ty == IceType_i16) {
676     emitUint8(0xDD);
677   } else {
678     assert(false && "Unexpected paddus operand type");
679   }
680   emitXmmRegisterOperand(dst, src);
681 }
682 
paddus(Type Ty,XmmRegister dst,const AsmAddress & src)683 void AssemblerX8632::paddus(Type Ty, XmmRegister dst, const AsmAddress &src) {
684   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
685   emitUint8(0x66);
686   emitUint8(0x0F);
687   if (isByteSizedArithType(Ty)) {
688     emitUint8(0xDC);
689   } else if (Ty == IceType_i16) {
690     emitUint8(0xDD);
691   } else {
692     assert(false && "Unexpected paddus operand type");
693   }
694   emitOperand(gprEncoding(dst), src);
695 }
696 
pand(Type,XmmRegister dst,XmmRegister src)697 void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst, XmmRegister src) {
698   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
699   emitUint8(0x66);
700   emitUint8(0x0F);
701   emitUint8(0xDB);
702   emitXmmRegisterOperand(dst, src);
703 }
704 
pand(Type,XmmRegister dst,const AsmAddress & src)705 void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst,
706                           const AsmAddress &src) {
707   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
708   emitUint8(0x66);
709   emitUint8(0x0F);
710   emitUint8(0xDB);
711   emitOperand(gprEncoding(dst), src);
712 }
713 
pandn(Type,XmmRegister dst,XmmRegister src)714 void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst, XmmRegister src) {
715   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
716   emitUint8(0x66);
717   emitUint8(0x0F);
718   emitUint8(0xDF);
719   emitXmmRegisterOperand(dst, src);
720 }
721 
pandn(Type,XmmRegister dst,const AsmAddress & src)722 void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst,
723                            const AsmAddress &src) {
724   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
725   emitUint8(0x66);
726   emitUint8(0x0F);
727   emitUint8(0xDF);
728   emitOperand(gprEncoding(dst), src);
729 }
730 
pmull(Type Ty,XmmRegister dst,XmmRegister src)731 void AssemblerX8632::pmull(Type Ty, XmmRegister dst, XmmRegister src) {
732   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
733   emitUint8(0x66);
734   emitUint8(0x0F);
735   if (Ty == IceType_i16) {
736     emitUint8(0xD5);
737   } else {
738     assert(Ty == IceType_i32);
739     emitUint8(0x38);
740     emitUint8(0x40);
741   }
742   emitXmmRegisterOperand(dst, src);
743 }
744 
pmull(Type Ty,XmmRegister dst,const AsmAddress & src)745 void AssemblerX8632::pmull(Type Ty, XmmRegister dst, const AsmAddress &src) {
746   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
747   emitUint8(0x66);
748   emitUint8(0x0F);
749   if (Ty == IceType_i16) {
750     emitUint8(0xD5);
751   } else {
752     assert(Ty == IceType_i32);
753     emitUint8(0x38);
754     emitUint8(0x40);
755   }
756   emitOperand(gprEncoding(dst), src);
757 }
758 
pmulhw(Type Ty,XmmRegister dst,XmmRegister src)759 void AssemblerX8632::pmulhw(Type Ty, XmmRegister dst, XmmRegister src) {
760   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
761   emitUint8(0x66);
762   emitUint8(0x0F);
763   assert(Ty == IceType_v8i16);
764   (void)Ty;
765   emitUint8(0xE5);
766   emitXmmRegisterOperand(dst, src);
767 }
768 
pmulhw(Type Ty,XmmRegister dst,const AsmAddress & src)769 void AssemblerX8632::pmulhw(Type Ty, XmmRegister dst, const AsmAddress &src) {
770   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
771   emitUint8(0x66);
772   emitUint8(0x0F);
773   assert(Ty == IceType_v8i16);
774   (void)Ty;
775   emitUint8(0xE5);
776   emitOperand(gprEncoding(dst), src);
777 }
778 
pmulhuw(Type Ty,XmmRegister dst,XmmRegister src)779 void AssemblerX8632::pmulhuw(Type Ty, XmmRegister dst, XmmRegister src) {
780   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
781   emitUint8(0x66);
782   emitUint8(0x0F);
783   assert(Ty == IceType_v8i16);
784   (void)Ty;
785   emitUint8(0xE4);
786   emitXmmRegisterOperand(dst, src);
787 }
788 
pmulhuw(Type Ty,XmmRegister dst,const AsmAddress & src)789 void AssemblerX8632::pmulhuw(Type Ty, XmmRegister dst, const AsmAddress &src) {
790   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
791   emitUint8(0x66);
792   emitUint8(0x0F);
793   assert(Ty == IceType_v8i16);
794   (void)Ty;
795   emitUint8(0xE4);
796   emitOperand(gprEncoding(dst), src);
797 }
798 
pmaddwd(Type Ty,XmmRegister dst,XmmRegister src)799 void AssemblerX8632::pmaddwd(Type Ty, XmmRegister dst, XmmRegister src) {
800   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
801   emitUint8(0x66);
802   emitUint8(0x0F);
803   assert(Ty == IceType_v8i16);
804   (void)Ty;
805   emitUint8(0xF5);
806   emitXmmRegisterOperand(dst, src);
807 }
808 
pmaddwd(Type Ty,XmmRegister dst,const AsmAddress & src)809 void AssemblerX8632::pmaddwd(Type Ty, XmmRegister dst, const AsmAddress &src) {
810   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
811   emitUint8(0x66);
812   emitUint8(0x0F);
813   assert(Ty == IceType_v8i16);
814   (void)Ty;
815   emitUint8(0xF5);
816   emitOperand(gprEncoding(dst), src);
817 }
818 
pmuludq(Type,XmmRegister dst,XmmRegister src)819 void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) {
820   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
821   emitUint8(0x66);
822   emitUint8(0x0F);
823   emitUint8(0xF4);
824   emitXmmRegisterOperand(dst, src);
825 }
826 
pmuludq(Type,XmmRegister dst,const AsmAddress & src)827 void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst,
828                              const AsmAddress &src) {
829   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
830   emitUint8(0x66);
831   emitUint8(0x0F);
832   emitUint8(0xF4);
833   emitOperand(gprEncoding(dst), src);
834 }
835 
por(Type,XmmRegister dst,XmmRegister src)836 void AssemblerX8632::por(Type /* Ty */, XmmRegister dst, XmmRegister src) {
837   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
838   emitUint8(0x66);
839   emitUint8(0x0F);
840   emitUint8(0xEB);
841   emitXmmRegisterOperand(dst, src);
842 }
843 
por(Type,XmmRegister dst,const AsmAddress & src)844 void AssemblerX8632::por(Type /* Ty */, XmmRegister dst,
845                          const AsmAddress &src) {
846   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
847   emitUint8(0x66);
848   emitUint8(0x0F);
849   emitUint8(0xEB);
850   emitOperand(gprEncoding(dst), src);
851 }
852 
psub(Type Ty,XmmRegister dst,XmmRegister src)853 void AssemblerX8632::psub(Type Ty, XmmRegister dst, XmmRegister src) {
854   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
855   emitUint8(0x66);
856   emitUint8(0x0F);
857   if (isByteSizedArithType(Ty)) {
858     emitUint8(0xF8);
859   } else if (Ty == IceType_i16) {
860     emitUint8(0xF9);
861   } else {
862     emitUint8(0xFA);
863   }
864   emitXmmRegisterOperand(dst, src);
865 }
866 
psub(Type Ty,XmmRegister dst,const AsmAddress & src)867 void AssemblerX8632::psub(Type Ty, XmmRegister dst, const AsmAddress &src) {
868   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
869   emitUint8(0x66);
870   emitUint8(0x0F);
871   if (isByteSizedArithType(Ty)) {
872     emitUint8(0xF8);
873   } else if (Ty == IceType_i16) {
874     emitUint8(0xF9);
875   } else {
876     emitUint8(0xFA);
877   }
878   emitOperand(gprEncoding(dst), src);
879 }
880 
psubs(Type Ty,XmmRegister dst,XmmRegister src)881 void AssemblerX8632::psubs(Type Ty, XmmRegister dst, XmmRegister src) {
882   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
883   emitUint8(0x66);
884   emitUint8(0x0F);
885   if (isByteSizedArithType(Ty)) {
886     emitUint8(0xE8);
887   } else if (Ty == IceType_i16) {
888     emitUint8(0xE9);
889   } else {
890     assert(false && "Unexpected psubs operand type");
891   }
892   emitXmmRegisterOperand(dst, src);
893 }
894 
psubs(Type Ty,XmmRegister dst,const AsmAddress & src)895 void AssemblerX8632::psubs(Type Ty, XmmRegister dst, const AsmAddress &src) {
896   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
897   emitUint8(0x66);
898   emitUint8(0x0F);
899   if (isByteSizedArithType(Ty)) {
900     emitUint8(0xE8);
901   } else if (Ty == IceType_i16) {
902     emitUint8(0xE9);
903   } else {
904     assert(false && "Unexpected psubs operand type");
905   }
906   emitOperand(gprEncoding(dst), src);
907 }
908 
psubus(Type Ty,XmmRegister dst,XmmRegister src)909 void AssemblerX8632::psubus(Type Ty, XmmRegister dst, XmmRegister src) {
910   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
911   emitUint8(0x66);
912   emitUint8(0x0F);
913   if (isByteSizedArithType(Ty)) {
914     emitUint8(0xD8);
915   } else if (Ty == IceType_i16) {
916     emitUint8(0xD9);
917   } else {
918     assert(false && "Unexpected psubus operand type");
919   }
920   emitXmmRegisterOperand(dst, src);
921 }
922 
psubus(Type Ty,XmmRegister dst,const AsmAddress & src)923 void AssemblerX8632::psubus(Type Ty, XmmRegister dst, const AsmAddress &src) {
924   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
925   emitUint8(0x66);
926   emitUint8(0x0F);
927   if (isByteSizedArithType(Ty)) {
928     emitUint8(0xD8);
929   } else if (Ty == IceType_i16) {
930     emitUint8(0xD9);
931   } else {
932     assert(false && "Unexpected psubus operand type");
933   }
934   emitOperand(gprEncoding(dst), src);
935 }
936 
pxor(Type,XmmRegister dst,XmmRegister src)937 void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst, XmmRegister src) {
938   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
939   emitUint8(0x66);
940   emitUint8(0x0F);
941   emitUint8(0xEF);
942   emitXmmRegisterOperand(dst, src);
943 }
944 
pxor(Type,XmmRegister dst,const AsmAddress & src)945 void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst,
946                           const AsmAddress &src) {
947   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
948   emitUint8(0x66);
949   emitUint8(0x0F);
950   emitUint8(0xEF);
951   emitOperand(gprEncoding(dst), src);
952 }
953 
psll(Type Ty,XmmRegister dst,XmmRegister src)954 void AssemblerX8632::psll(Type Ty, XmmRegister dst, XmmRegister src) {
955   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
956   emitUint8(0x66);
957   emitUint8(0x0F);
958   if (Ty == IceType_i16) {
959     emitUint8(0xF1);
960   } else {
961     assert(Ty == IceType_i32);
962     emitUint8(0xF2);
963   }
964   emitXmmRegisterOperand(dst, src);
965 }
966 
psll(Type Ty,XmmRegister dst,const AsmAddress & src)967 void AssemblerX8632::psll(Type Ty, XmmRegister dst, const AsmAddress &src) {
968   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
969   emitUint8(0x66);
970   emitUint8(0x0F);
971   if (Ty == IceType_i16) {
972     emitUint8(0xF1);
973   } else {
974     assert(Ty == IceType_i32);
975     emitUint8(0xF2);
976   }
977   emitOperand(gprEncoding(dst), src);
978 }
979 
psll(Type Ty,XmmRegister dst,const Immediate & imm)980 void AssemblerX8632::psll(Type Ty, XmmRegister dst, const Immediate &imm) {
981   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
982   assert(imm.is_int8());
983   emitUint8(0x66);
984   emitUint8(0x0F);
985   if (Ty == IceType_i16) {
986     emitUint8(0x71);
987   } else {
988     assert(Ty == IceType_i32);
989     emitUint8(0x72);
990   }
991   emitRegisterOperand(6, gprEncoding(dst));
992   emitUint8(imm.value() & 0xFF);
993 }
994 
psra(Type Ty,XmmRegister dst,XmmRegister src)995 void AssemblerX8632::psra(Type Ty, XmmRegister dst, XmmRegister src) {
996   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
997   emitUint8(0x66);
998   emitUint8(0x0F);
999   if (Ty == IceType_i16) {
1000     emitUint8(0xE1);
1001   } else {
1002     assert(Ty == IceType_i32);
1003     emitUint8(0xE2);
1004   }
1005   emitXmmRegisterOperand(dst, src);
1006 }
1007 
psra(Type Ty,XmmRegister dst,const AsmAddress & src)1008 void AssemblerX8632::psra(Type Ty, XmmRegister dst, const AsmAddress &src) {
1009   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1010   emitUint8(0x66);
1011   emitUint8(0x0F);
1012   if (Ty == IceType_i16) {
1013     emitUint8(0xE1);
1014   } else {
1015     assert(Ty == IceType_i32);
1016     emitUint8(0xE2);
1017   }
1018   emitOperand(gprEncoding(dst), src);
1019 }
1020 
psra(Type Ty,XmmRegister dst,const Immediate & imm)1021 void AssemblerX8632::psra(Type Ty, XmmRegister dst, const Immediate &imm) {
1022   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1023   assert(imm.is_int8());
1024   emitUint8(0x66);
1025   emitUint8(0x0F);
1026   if (Ty == IceType_i16) {
1027     emitUint8(0x71);
1028   } else {
1029     assert(Ty == IceType_i32);
1030     emitUint8(0x72);
1031   }
1032   emitRegisterOperand(4, gprEncoding(dst));
1033   emitUint8(imm.value() & 0xFF);
1034 }
1035 
psrl(Type Ty,XmmRegister dst,XmmRegister src)1036 void AssemblerX8632::psrl(Type Ty, XmmRegister dst, XmmRegister src) {
1037   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1038   emitUint8(0x66);
1039   emitUint8(0x0F);
1040   if (Ty == IceType_i16) {
1041     emitUint8(0xD1);
1042   } else if (Ty == IceType_f64) {
1043     emitUint8(0xD3);
1044   } else {
1045     assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1046     emitUint8(0xD2);
1047   }
1048   emitXmmRegisterOperand(dst, src);
1049 }
1050 
psrl(Type Ty,XmmRegister dst,const AsmAddress & src)1051 void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const AsmAddress &src) {
1052   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1053   emitUint8(0x66);
1054   emitUint8(0x0F);
1055   if (Ty == IceType_i16) {
1056     emitUint8(0xD1);
1057   } else if (Ty == IceType_f64) {
1058     emitUint8(0xD3);
1059   } else {
1060     assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1061     emitUint8(0xD2);
1062   }
1063   emitOperand(gprEncoding(dst), src);
1064 }
1065 
psrl(Type Ty,XmmRegister dst,const Immediate & imm)1066 void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const Immediate &imm) {
1067   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1068   assert(imm.is_int8());
1069   emitUint8(0x66);
1070   emitUint8(0x0F);
1071   if (Ty == IceType_i16) {
1072     emitUint8(0x71);
1073   } else if (Ty == IceType_f64) {
1074     emitUint8(0x73);
1075   } else {
1076     assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1077     emitUint8(0x72);
1078   }
1079   emitRegisterOperand(2, gprEncoding(dst));
1080   emitUint8(imm.value() & 0xFF);
1081 }
1082 
1083 // {add,sub,mul,div}ps are given a Ty parameter for consistency with
1084 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc.,
1085 // we can use the Ty parameter to decide on adding a 0x66 prefix.
1086 
addps(Type,XmmRegister dst,XmmRegister src)1087 void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1088   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1089   emitUint8(0x0F);
1090   emitUint8(0x58);
1091   emitXmmRegisterOperand(dst, src);
1092 }
1093 
addps(Type,XmmRegister dst,const AsmAddress & src)1094 void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst,
1095                            const AsmAddress &src) {
1096   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1097   emitUint8(0x0F);
1098   emitUint8(0x58);
1099   emitOperand(gprEncoding(dst), src);
1100 }
1101 
subps(Type,XmmRegister dst,XmmRegister src)1102 void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1103   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1104   emitUint8(0x0F);
1105   emitUint8(0x5C);
1106   emitXmmRegisterOperand(dst, src);
1107 }
1108 
subps(Type,XmmRegister dst,const AsmAddress & src)1109 void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst,
1110                            const AsmAddress &src) {
1111   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1112   emitUint8(0x0F);
1113   emitUint8(0x5C);
1114   emitOperand(gprEncoding(dst), src);
1115 }
1116 
divps(Type,XmmRegister dst,XmmRegister src)1117 void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1118   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1119   emitUint8(0x0F);
1120   emitUint8(0x5E);
1121   emitXmmRegisterOperand(dst, src);
1122 }
1123 
divps(Type,XmmRegister dst,const AsmAddress & src)1124 void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst,
1125                            const AsmAddress &src) {
1126   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1127   emitUint8(0x0F);
1128   emitUint8(0x5E);
1129   emitOperand(gprEncoding(dst), src);
1130 }
1131 
mulps(Type,XmmRegister dst,XmmRegister src)1132 void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1133   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1134   emitUint8(0x0F);
1135   emitUint8(0x59);
1136   emitXmmRegisterOperand(dst, src);
1137 }
1138 
mulps(Type,XmmRegister dst,const AsmAddress & src)1139 void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst,
1140                            const AsmAddress &src) {
1141   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1142   emitUint8(0x0F);
1143   emitUint8(0x59);
1144   emitOperand(gprEncoding(dst), src);
1145 }
1146 
minps(Type Ty,XmmRegister dst,XmmRegister src)1147 void AssemblerX8632::minps(Type Ty, XmmRegister dst, XmmRegister src) {
1148   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1149   if (!isFloat32Asserting32Or64(Ty))
1150     emitUint8(0x66);
1151   emitUint8(0x0F);
1152   emitUint8(0x5D);
1153   emitXmmRegisterOperand(dst, src);
1154 }
1155 
minps(Type Ty,XmmRegister dst,const AsmAddress & src)1156 void AssemblerX8632::minps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1157   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1158   if (!isFloat32Asserting32Or64(Ty))
1159     emitUint8(0x66);
1160   emitUint8(0x0F);
1161   emitUint8(0x5D);
1162   emitOperand(gprEncoding(dst), src);
1163 }
1164 
minss(Type Ty,XmmRegister dst,XmmRegister src)1165 void AssemblerX8632::minss(Type Ty, XmmRegister dst, XmmRegister src) {
1166   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1167   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1168   emitUint8(0x0F);
1169   emitUint8(0x5D);
1170   emitXmmRegisterOperand(dst, src);
1171 }
1172 
minss(Type Ty,XmmRegister dst,const AsmAddress & src)1173 void AssemblerX8632::minss(Type Ty, XmmRegister dst, const AsmAddress &src) {
1174   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1175   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1176   emitUint8(0x0F);
1177   emitUint8(0x5D);
1178   emitOperand(gprEncoding(dst), src);
1179 }
1180 
maxps(Type Ty,XmmRegister dst,XmmRegister src)1181 void AssemblerX8632::maxps(Type Ty, XmmRegister dst, XmmRegister src) {
1182   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1183   if (!isFloat32Asserting32Or64(Ty))
1184     emitUint8(0x66);
1185   emitUint8(0x0F);
1186   emitUint8(0x5F);
1187   emitXmmRegisterOperand(dst, src);
1188 }
1189 
maxps(Type Ty,XmmRegister dst,const AsmAddress & src)1190 void AssemblerX8632::maxps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1191   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1192   if (!isFloat32Asserting32Or64(Ty))
1193     emitUint8(0x66);
1194   emitUint8(0x0F);
1195   emitUint8(0x5F);
1196   emitOperand(gprEncoding(dst), src);
1197 }
1198 
maxss(Type Ty,XmmRegister dst,XmmRegister src)1199 void AssemblerX8632::maxss(Type Ty, XmmRegister dst, XmmRegister src) {
1200   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1201   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1202   emitUint8(0x0F);
1203   emitUint8(0x5F);
1204   emitXmmRegisterOperand(dst, src);
1205 }
1206 
maxss(Type Ty,XmmRegister dst,const AsmAddress & src)1207 void AssemblerX8632::maxss(Type Ty, XmmRegister dst, const AsmAddress &src) {
1208   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1209   emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1210   emitUint8(0x0F);
1211   emitUint8(0x5F);
1212   emitOperand(gprEncoding(dst), src);
1213 }
1214 
andnps(Type Ty,XmmRegister dst,XmmRegister src)1215 void AssemblerX8632::andnps(Type Ty, XmmRegister dst, XmmRegister src) {
1216   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1217   if (!isFloat32Asserting32Or64(Ty))
1218     emitUint8(0x66);
1219   emitUint8(0x0F);
1220   emitUint8(0x55);
1221   emitXmmRegisterOperand(dst, src);
1222 }
1223 
andnps(Type Ty,XmmRegister dst,const AsmAddress & src)1224 void AssemblerX8632::andnps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1225   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1226   if (!isFloat32Asserting32Or64(Ty))
1227     emitUint8(0x66);
1228   emitUint8(0x0F);
1229   emitUint8(0x55);
1230   emitOperand(gprEncoding(dst), src);
1231 }
1232 
andps(Type Ty,XmmRegister dst,XmmRegister src)1233 void AssemblerX8632::andps(Type Ty, XmmRegister dst, XmmRegister src) {
1234   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1235   if (!isFloat32Asserting32Or64(Ty))
1236     emitUint8(0x66);
1237   emitUint8(0x0F);
1238   emitUint8(0x54);
1239   emitXmmRegisterOperand(dst, src);
1240 }
1241 
andps(Type Ty,XmmRegister dst,const AsmAddress & src)1242 void AssemblerX8632::andps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1243   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1244   if (!isFloat32Asserting32Or64(Ty))
1245     emitUint8(0x66);
1246   emitUint8(0x0F);
1247   emitUint8(0x54);
1248   emitOperand(gprEncoding(dst), src);
1249 }
1250 
orps(Type Ty,XmmRegister dst,XmmRegister src)1251 void AssemblerX8632::orps(Type Ty, XmmRegister dst, XmmRegister src) {
1252   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1253   if (!isFloat32Asserting32Or64(Ty))
1254     emitUint8(0x66);
1255   emitUint8(0x0F);
1256   emitUint8(0x56);
1257   emitXmmRegisterOperand(dst, src);
1258 }
1259 
orps(Type Ty,XmmRegister dst,const AsmAddress & src)1260 void AssemblerX8632::orps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1261   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1262   if (!isFloat32Asserting32Or64(Ty))
1263     emitUint8(0x66);
1264   emitUint8(0x0F);
1265   emitUint8(0x56);
1266   emitOperand(gprEncoding(dst), src);
1267 }
1268 
blendvps(Type,XmmRegister dst,XmmRegister src)1269 void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1270   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1271   emitUint8(0x66);
1272   emitUint8(0x0F);
1273   emitUint8(0x38);
1274   emitUint8(0x14);
1275   emitXmmRegisterOperand(dst, src);
1276 }
1277 
blendvps(Type,XmmRegister dst,const AsmAddress & src)1278 void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst,
1279                               const AsmAddress &src) {
1280   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1281   emitUint8(0x66);
1282   emitUint8(0x0F);
1283   emitUint8(0x38);
1284   emitUint8(0x14);
1285   emitOperand(gprEncoding(dst), src);
1286 }
1287 
pblendvb(Type,XmmRegister dst,XmmRegister src)1288 void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1289   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1290   emitUint8(0x66);
1291   emitUint8(0x0F);
1292   emitUint8(0x38);
1293   emitUint8(0x10);
1294   emitXmmRegisterOperand(dst, src);
1295 }
1296 
pblendvb(Type,XmmRegister dst,const AsmAddress & src)1297 void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst,
1298                               const AsmAddress &src) {
1299   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1300   emitUint8(0x66);
1301   emitUint8(0x0F);
1302   emitUint8(0x38);
1303   emitUint8(0x10);
1304   emitOperand(gprEncoding(dst), src);
1305 }
1306 
cmpps(Type Ty,XmmRegister dst,XmmRegister src,CmppsCond CmpCondition)1307 void AssemblerX8632::cmpps(Type Ty, XmmRegister dst, XmmRegister src,
1308                            CmppsCond CmpCondition) {
1309   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1310   if (Ty == IceType_f64)
1311     emitUint8(0x66);
1312   emitUint8(0x0F);
1313   emitUint8(0xC2);
1314   emitXmmRegisterOperand(dst, src);
1315   emitUint8(CmpCondition);
1316 }
1317 
cmpps(Type Ty,XmmRegister dst,const AsmAddress & src,CmppsCond CmpCondition)1318 void AssemblerX8632::cmpps(Type Ty, XmmRegister dst, const AsmAddress &src,
1319                            CmppsCond CmpCondition) {
1320   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1321   if (Ty == IceType_f64)
1322     emitUint8(0x66);
1323   emitUint8(0x0F);
1324   emitUint8(0xC2);
1325   static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
1326   emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction);
1327   emitUint8(CmpCondition);
1328 }
1329 
sqrtps(XmmRegister dst)1330 void AssemblerX8632::sqrtps(XmmRegister dst) {
1331   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1332   emitUint8(0x0F);
1333   emitUint8(0x51);
1334   emitXmmRegisterOperand(dst, dst);
1335 }
1336 
rsqrtps(XmmRegister dst)1337 void AssemblerX8632::rsqrtps(XmmRegister dst) {
1338   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1339   emitUint8(0x0F);
1340   emitUint8(0x52);
1341   emitXmmRegisterOperand(dst, dst);
1342 }
1343 
reciprocalps(XmmRegister dst)1344 void AssemblerX8632::reciprocalps(XmmRegister dst) {
1345   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1346   emitUint8(0x0F);
1347   emitUint8(0x53);
1348   emitXmmRegisterOperand(dst, dst);
1349 }
1350 
movhlps(XmmRegister dst,XmmRegister src)1351 void AssemblerX8632::movhlps(XmmRegister dst, XmmRegister src) {
1352   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1353   emitUint8(0x0F);
1354   emitUint8(0x12);
1355   emitXmmRegisterOperand(dst, src);
1356 }
1357 
movlhps(XmmRegister dst,XmmRegister src)1358 void AssemblerX8632::movlhps(XmmRegister dst, XmmRegister src) {
1359   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1360   emitUint8(0x0F);
1361   emitUint8(0x16);
1362   emitXmmRegisterOperand(dst, src);
1363 }
1364 
unpcklps(XmmRegister dst,XmmRegister src)1365 void AssemblerX8632::unpcklps(XmmRegister dst, XmmRegister src) {
1366   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1367   emitUint8(0x0F);
1368   emitUint8(0x14);
1369   emitXmmRegisterOperand(dst, src);
1370 }
1371 
unpckhps(XmmRegister dst,XmmRegister src)1372 void AssemblerX8632::unpckhps(XmmRegister dst, XmmRegister src) {
1373   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1374   emitUint8(0x0F);
1375   emitUint8(0x15);
1376   emitXmmRegisterOperand(dst, src);
1377 }
1378 
unpcklpd(XmmRegister dst,XmmRegister src)1379 void AssemblerX8632::unpcklpd(XmmRegister dst, XmmRegister src) {
1380   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1381   emitUint8(0x66);
1382   emitUint8(0x0F);
1383   emitUint8(0x14);
1384   emitXmmRegisterOperand(dst, src);
1385 }
1386 
unpckhpd(XmmRegister dst,XmmRegister src)1387 void AssemblerX8632::unpckhpd(XmmRegister dst, XmmRegister src) {
1388   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1389   emitUint8(0x66);
1390   emitUint8(0x0F);
1391   emitUint8(0x15);
1392   emitXmmRegisterOperand(dst, src);
1393 }
1394 
set1ps(XmmRegister dst,GPRRegister tmp1,const Immediate & imm)1395 void AssemblerX8632::set1ps(XmmRegister dst, GPRRegister tmp1,
1396                             const Immediate &imm) {
1397   // Load 32-bit immediate value into tmp1.
1398   mov(IceType_i32, tmp1, imm);
1399   // Move value from tmp1 into dst.
1400   movd(IceType_i32, dst, tmp1);
1401   // Broadcast low lane into other three lanes.
1402   shufps(RexTypeIrrelevant, dst, dst, Immediate(0x0));
1403 }
1404 
pshufb(Type,XmmRegister dst,XmmRegister src)1405 void AssemblerX8632::pshufb(Type /* Ty */, XmmRegister dst, XmmRegister src) {
1406   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1407   emitUint8(0x66);
1408   emitUint8(0x0F);
1409   emitUint8(0x38);
1410   emitUint8(0x00);
1411   emitXmmRegisterOperand(dst, src);
1412 }
1413 
pshufb(Type,XmmRegister dst,const AsmAddress & src)1414 void AssemblerX8632::pshufb(Type /* Ty */, XmmRegister dst,
1415                             const AsmAddress &src) {
1416   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1417   emitUint8(0x66);
1418   emitUint8(0x0F);
1419   emitUint8(0x38);
1420   emitUint8(0x00);
1421   emitOperand(gprEncoding(dst), src);
1422 }
1423 
pshufd(Type,XmmRegister dst,XmmRegister src,const Immediate & imm)1424 void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst, XmmRegister src,
1425                             const Immediate &imm) {
1426   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1427   emitUint8(0x66);
1428   emitUint8(0x0F);
1429   emitUint8(0x70);
1430   emitXmmRegisterOperand(dst, src);
1431   assert(imm.is_uint8());
1432   emitUint8(imm.value());
1433 }
1434 
pshufd(Type,XmmRegister dst,const AsmAddress & src,const Immediate & imm)1435 void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst,
1436                             const AsmAddress &src, const Immediate &imm) {
1437   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1438   emitUint8(0x66);
1439   emitUint8(0x0F);
1440   emitUint8(0x70);
1441   static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
1442   emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction);
1443   assert(imm.is_uint8());
1444   emitUint8(imm.value());
1445 }
1446 
punpckl(Type Ty,XmmRegister Dst,XmmRegister Src)1447 void AssemblerX8632::punpckl(Type Ty, XmmRegister Dst, XmmRegister Src) {
1448   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1449   emitUint8(0x66);
1450   emitUint8(0x0F);
1451   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1452     emitUint8(0x62);
1453   } else if (Ty == IceType_v8i16) {
1454     emitUint8(0x61);
1455   } else if (Ty == IceType_v16i8) {
1456     emitUint8(0x60);
1457   } else {
1458     assert(false && "Unexpected vector unpack operand type");
1459   }
1460   emitXmmRegisterOperand(Dst, Src);
1461 }
1462 
punpckl(Type Ty,XmmRegister Dst,const AsmAddress & Src)1463 void AssemblerX8632::punpckl(Type Ty, XmmRegister Dst, const AsmAddress &Src) {
1464   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1465   emitUint8(0x66);
1466   emitUint8(0x0F);
1467   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1468     emitUint8(0x62);
1469   } else if (Ty == IceType_v8i16) {
1470     emitUint8(0x61);
1471   } else if (Ty == IceType_v16i8) {
1472     emitUint8(0x60);
1473   } else {
1474     assert(false && "Unexpected vector unpack operand type");
1475   }
1476   emitOperand(gprEncoding(Dst), Src);
1477 }
1478 
punpckh(Type Ty,XmmRegister Dst,XmmRegister Src)1479 void AssemblerX8632::punpckh(Type Ty, XmmRegister Dst, XmmRegister Src) {
1480   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1481   emitUint8(0x66);
1482   emitUint8(0x0F);
1483   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1484     emitUint8(0x6A);
1485   } else if (Ty == IceType_v8i16) {
1486     emitUint8(0x69);
1487   } else if (Ty == IceType_v16i8) {
1488     emitUint8(0x68);
1489   } else {
1490     assert(false && "Unexpected vector unpack operand type");
1491   }
1492   emitXmmRegisterOperand(Dst, Src);
1493 }
1494 
punpckh(Type Ty,XmmRegister Dst,const AsmAddress & Src)1495 void AssemblerX8632::punpckh(Type Ty, XmmRegister Dst, const AsmAddress &Src) {
1496   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1497   emitUint8(0x66);
1498   emitUint8(0x0F);
1499   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1500     emitUint8(0x6A);
1501   } else if (Ty == IceType_v8i16) {
1502     emitUint8(0x69);
1503   } else if (Ty == IceType_v16i8) {
1504     emitUint8(0x68);
1505   } else {
1506     assert(false && "Unexpected vector unpack operand type");
1507   }
1508   emitOperand(gprEncoding(Dst), Src);
1509 }
1510 
packss(Type Ty,XmmRegister Dst,XmmRegister Src)1511 void AssemblerX8632::packss(Type Ty, XmmRegister Dst, XmmRegister Src) {
1512   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1513   emitUint8(0x66);
1514   emitUint8(0x0F);
1515   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1516     emitUint8(0x6B);
1517   } else if (Ty == IceType_v8i16) {
1518     emitUint8(0x63);
1519   } else {
1520     assert(false && "Unexpected vector pack operand type");
1521   }
1522   emitXmmRegisterOperand(Dst, Src);
1523 }
1524 
packss(Type Ty,XmmRegister Dst,const AsmAddress & Src)1525 void AssemblerX8632::packss(Type Ty, XmmRegister Dst, const AsmAddress &Src) {
1526   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1527   emitUint8(0x66);
1528   emitUint8(0x0F);
1529   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1530     emitUint8(0x6B);
1531   } else if (Ty == IceType_v8i16) {
1532     emitUint8(0x63);
1533   } else {
1534     assert(false && "Unexpected vector pack operand type");
1535   }
1536   emitOperand(gprEncoding(Dst), Src);
1537 }
1538 
packus(Type Ty,XmmRegister Dst,XmmRegister Src)1539 void AssemblerX8632::packus(Type Ty, XmmRegister Dst, XmmRegister Src) {
1540   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1541   emitUint8(0x66);
1542   emitUint8(0x0F);
1543   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1544     emitUint8(0x38);
1545     emitUint8(0x2B);
1546   } else if (Ty == IceType_v8i16) {
1547     emitUint8(0x67);
1548   } else {
1549     assert(false && "Unexpected vector pack operand type");
1550   }
1551   emitXmmRegisterOperand(Dst, Src);
1552 }
1553 
packus(Type Ty,XmmRegister Dst,const AsmAddress & Src)1554 void AssemblerX8632::packus(Type Ty, XmmRegister Dst, const AsmAddress &Src) {
1555   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1556   emitUint8(0x66);
1557   emitUint8(0x0F);
1558   if (Ty == IceType_v4i32 || Ty == IceType_v4f32) {
1559     emitUint8(0x38);
1560     emitUint8(0x2B);
1561   } else if (Ty == IceType_v8i16) {
1562     emitUint8(0x67);
1563   } else {
1564     assert(false && "Unexpected vector pack operand type");
1565   }
1566   emitOperand(gprEncoding(Dst), Src);
1567 }
1568 
shufps(Type,XmmRegister dst,XmmRegister src,const Immediate & imm)1569 void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst, XmmRegister src,
1570                             const Immediate &imm) {
1571   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1572   emitUint8(0x0F);
1573   emitUint8(0xC6);
1574   emitXmmRegisterOperand(dst, src);
1575   assert(imm.is_uint8());
1576   emitUint8(imm.value());
1577 }
1578 
shufps(Type,XmmRegister dst,const AsmAddress & src,const Immediate & imm)1579 void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst,
1580                             const AsmAddress &src, const Immediate &imm) {
1581   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1582   emitUint8(0x0F);
1583   emitUint8(0xC6);
1584   static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
1585   emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction);
1586   assert(imm.is_uint8());
1587   emitUint8(imm.value());
1588 }
1589 
sqrtpd(XmmRegister dst)1590 void AssemblerX8632::sqrtpd(XmmRegister dst) {
1591   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1592   emitUint8(0x66);
1593   emitUint8(0x0F);
1594   emitUint8(0x51);
1595   emitXmmRegisterOperand(dst, dst);
1596 }
1597 
cvtdq2ps(Type,XmmRegister dst,XmmRegister src)1598 void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1599                               XmmRegister src) {
1600   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1601   emitUint8(0x0F);
1602   emitUint8(0x5B);
1603   emitXmmRegisterOperand(dst, src);
1604 }
1605 
cvtdq2ps(Type,XmmRegister dst,const AsmAddress & src)1606 void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1607                               const AsmAddress &src) {
1608   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1609   emitUint8(0x0F);
1610   emitUint8(0x5B);
1611   emitOperand(gprEncoding(dst), src);
1612 }
1613 
cvttps2dq(Type,XmmRegister dst,XmmRegister src)1614 void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1615                                XmmRegister src) {
1616   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1617   emitUint8(0xF3);
1618   emitUint8(0x0F);
1619   emitUint8(0x5B);
1620   emitXmmRegisterOperand(dst, src);
1621 }
1622 
cvttps2dq(Type,XmmRegister dst,const AsmAddress & src)1623 void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1624                                const AsmAddress &src) {
1625   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1626   emitUint8(0xF3);
1627   emitUint8(0x0F);
1628   emitUint8(0x5B);
1629   emitOperand(gprEncoding(dst), src);
1630 }
1631 
cvtps2dq(Type,XmmRegister dst,XmmRegister src)1632 void AssemblerX8632::cvtps2dq(Type /* Ignore */, XmmRegister dst,
1633                               XmmRegister src) {
1634   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1635   emitUint8(0x66);
1636   emitUint8(0x0F);
1637   emitUint8(0x5B);
1638   emitXmmRegisterOperand(dst, src);
1639 }
1640 
cvtps2dq(Type,XmmRegister dst,const AsmAddress & src)1641 void AssemblerX8632::cvtps2dq(Type /* Ignore */, XmmRegister dst,
1642                               const AsmAddress &src) {
1643   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1644   emitUint8(0x66);
1645   emitUint8(0x0F);
1646   emitUint8(0x5B);
1647   emitOperand(gprEncoding(dst), src);
1648 }
1649 
cvtsi2ss(Type DestTy,XmmRegister dst,Type SrcTy,GPRRegister src)1650 void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy,
1651                               GPRRegister src) {
1652   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1653   emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1654   emitUint8(0x0F);
1655   emitUint8(0x2A);
1656   emitXmmRegisterOperand(dst, src);
1657 }
1658 
cvtsi2ss(Type DestTy,XmmRegister dst,Type SrcTy,const AsmAddress & src)1659 void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy,
1660                               const AsmAddress &src) {
1661   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1662   emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1663   emitUint8(0x0F);
1664   emitUint8(0x2A);
1665   emitOperand(gprEncoding(dst), src);
1666 }
1667 
cvtfloat2float(Type SrcTy,XmmRegister dst,XmmRegister src)1668 void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
1669                                     XmmRegister src) {
1670   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1671   // ss2sd or sd2ss
1672   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1673   emitUint8(0x0F);
1674   emitUint8(0x5A);
1675   emitXmmRegisterOperand(dst, src);
1676 }
1677 
cvtfloat2float(Type SrcTy,XmmRegister dst,const AsmAddress & src)1678 void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
1679                                     const AsmAddress &src) {
1680   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1681   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1682   emitUint8(0x0F);
1683   emitUint8(0x5A);
1684   emitOperand(gprEncoding(dst), src);
1685 }
1686 
cvttss2si(Type DestTy,GPRRegister dst,Type SrcTy,XmmRegister src)1687 void AssemblerX8632::cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy,
1688                                XmmRegister src) {
1689   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1690   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1691   emitUint8(0x0F);
1692   emitUint8(0x2C);
1693   emitXmmRegisterOperand(dst, src);
1694 }
1695 
cvttss2si(Type DestTy,GPRRegister dst,Type SrcTy,const AsmAddress & src)1696 void AssemblerX8632::cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy,
1697                                const AsmAddress &src) {
1698   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1699   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1700   emitUint8(0x0F);
1701   emitUint8(0x2C);
1702   emitOperand(gprEncoding(dst), src);
1703 }
1704 
cvtss2si(Type DestTy,GPRRegister dst,Type SrcTy,XmmRegister src)1705 void AssemblerX8632::cvtss2si(Type DestTy, GPRRegister dst, Type SrcTy,
1706                               XmmRegister src) {
1707   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1708   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1709   emitUint8(0x0F);
1710   emitUint8(0x2D);
1711   emitXmmRegisterOperand(dst, src);
1712 }
1713 
cvtss2si(Type DestTy,GPRRegister dst,Type SrcTy,const AsmAddress & src)1714 void AssemblerX8632::cvtss2si(Type DestTy, GPRRegister dst, Type SrcTy,
1715                               const AsmAddress &src) {
1716   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1717   emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1718   emitUint8(0x0F);
1719   emitUint8(0x2D);
1720   emitOperand(gprEncoding(dst), src);
1721 }
1722 
ucomiss(Type Ty,XmmRegister a,XmmRegister b)1723 void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, XmmRegister b) {
1724   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1725   if (Ty == IceType_f64)
1726     emitUint8(0x66);
1727   emitUint8(0x0F);
1728   emitUint8(0x2E);
1729   emitXmmRegisterOperand(a, b);
1730 }
1731 
ucomiss(Type Ty,XmmRegister a,const AsmAddress & b)1732 void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, const AsmAddress &b) {
1733   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1734   if (Ty == IceType_f64)
1735     emitUint8(0x66);
1736   emitUint8(0x0F);
1737   emitUint8(0x2E);
1738   emitOperand(gprEncoding(a), b);
1739 }
1740 
movmsk(Type Ty,GPRRegister dst,XmmRegister src)1741 void AssemblerX8632::movmsk(Type Ty, GPRRegister dst, XmmRegister src) {
1742   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1743   if (Ty == IceType_v16i8) {
1744     emitUint8(0x66);
1745   } else if (Ty == IceType_v4f32 || Ty == IceType_v4i32) {
1746     // No operand size prefix
1747   } else {
1748     assert(false && "Unexpected movmsk operand type");
1749   }
1750   emitUint8(0x0F);
1751   if (Ty == IceType_v16i8) {
1752     emitUint8(0xD7);
1753   } else if (Ty == IceType_v4f32 || Ty == IceType_v4i32) {
1754     emitUint8(0x50);
1755   } else {
1756     assert(false && "Unexpected movmsk operand type");
1757   }
1758   emitXmmRegisterOperand(dst, src);
1759 }
1760 
sqrt(Type Ty,XmmRegister dst,const AsmAddress & src)1761 void AssemblerX8632::sqrt(Type Ty, XmmRegister dst, const AsmAddress &src) {
1762   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1763   if (isScalarFloatingType(Ty))
1764     emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1765   emitUint8(0x0F);
1766   emitUint8(0x51);
1767   emitOperand(gprEncoding(dst), src);
1768 }
1769 
sqrt(Type Ty,XmmRegister dst,XmmRegister src)1770 void AssemblerX8632::sqrt(Type Ty, XmmRegister dst, XmmRegister src) {
1771   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1772   if (isScalarFloatingType(Ty))
1773     emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1774   emitUint8(0x0F);
1775   emitUint8(0x51);
1776   emitXmmRegisterOperand(dst, src);
1777 }
1778 
xorps(Type Ty,XmmRegister dst,const AsmAddress & src)1779 void AssemblerX8632::xorps(Type Ty, XmmRegister dst, const AsmAddress &src) {
1780   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1781   if (!isFloat32Asserting32Or64(Ty))
1782     emitUint8(0x66);
1783   emitUint8(0x0F);
1784   emitUint8(0x57);
1785   emitOperand(gprEncoding(dst), src);
1786 }
1787 
xorps(Type Ty,XmmRegister dst,XmmRegister src)1788 void AssemblerX8632::xorps(Type Ty, XmmRegister dst, XmmRegister src) {
1789   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1790   if (!isFloat32Asserting32Or64(Ty))
1791     emitUint8(0x66);
1792   emitUint8(0x0F);
1793   emitUint8(0x57);
1794   emitXmmRegisterOperand(dst, src);
1795 }
1796 
insertps(Type Ty,XmmRegister dst,XmmRegister src,const Immediate & imm)1797 void AssemblerX8632::insertps(Type Ty, XmmRegister dst, XmmRegister src,
1798                               const Immediate &imm) {
1799   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1800   assert(imm.is_uint8());
1801   assert(isVectorFloatingType(Ty));
1802   (void)Ty;
1803   emitUint8(0x66);
1804   emitUint8(0x0F);
1805   emitUint8(0x3A);
1806   emitUint8(0x21);
1807   emitXmmRegisterOperand(dst, src);
1808   emitUint8(imm.value());
1809 }
1810 
insertps(Type Ty,XmmRegister dst,const AsmAddress & src,const Immediate & imm)1811 void AssemblerX8632::insertps(Type Ty, XmmRegister dst, const AsmAddress &src,
1812                               const Immediate &imm) {
1813   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1814   assert(imm.is_uint8());
1815   assert(isVectorFloatingType(Ty));
1816   (void)Ty;
1817   emitUint8(0x66);
1818   emitUint8(0x0F);
1819   emitUint8(0x3A);
1820   emitUint8(0x21);
1821   static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
1822   emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction);
1823   emitUint8(imm.value());
1824 }
1825 
pinsr(Type Ty,XmmRegister dst,GPRRegister src,const Immediate & imm)1826 void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, GPRRegister src,
1827                            const Immediate &imm) {
1828   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1829   assert(imm.is_uint8());
1830   emitUint8(0x66);
1831   emitUint8(0x0F);
1832   if (Ty == IceType_i16) {
1833     emitUint8(0xC4);
1834   } else {
1835     emitUint8(0x3A);
1836     emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1837   }
1838   emitXmmRegisterOperand(dst, src);
1839   emitUint8(imm.value());
1840 }
1841 
pinsr(Type Ty,XmmRegister dst,const AsmAddress & src,const Immediate & imm)1842 void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, const AsmAddress &src,
1843                            const Immediate &imm) {
1844   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1845   assert(imm.is_uint8());
1846   emitUint8(0x66);
1847   emitUint8(0x0F);
1848   if (Ty == IceType_i16) {
1849     emitUint8(0xC4);
1850   } else {
1851     emitUint8(0x3A);
1852     emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1853   }
1854   static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
1855   emitOperand(gprEncoding(dst), src, OffsetFromNextInstruction);
1856   emitUint8(imm.value());
1857 }
1858 
pextr(Type Ty,GPRRegister dst,XmmRegister src,const Immediate & imm)1859 void AssemblerX8632::pextr(Type Ty, GPRRegister dst, XmmRegister src,
1860                            const Immediate &imm) {
1861   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1862   assert(imm.is_uint8());
1863   if (Ty == IceType_i16) {
1864     emitUint8(0x66);
1865     emitUint8(0x0F);
1866     emitUint8(0xC5);
1867     emitXmmRegisterOperand(dst, src);
1868     emitUint8(imm.value());
1869   } else {
1870     emitUint8(0x66);
1871     emitUint8(0x0F);
1872     emitUint8(0x3A);
1873     emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16);
1874     // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2)
1875     // is RMI because dst must be reg.
1876     emitXmmRegisterOperand(src, dst);
1877     emitUint8(imm.value());
1878   }
1879 }
1880 
pmovsxdq(XmmRegister dst,XmmRegister src)1881 void AssemblerX8632::pmovsxdq(XmmRegister dst, XmmRegister src) {
1882   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1883   emitUint8(0x66);
1884   emitUint8(0x0F);
1885   emitUint8(0x38);
1886   emitUint8(0x25);
1887   emitXmmRegisterOperand(dst, src);
1888 }
1889 
pcmpeq(Type Ty,XmmRegister dst,XmmRegister src)1890 void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, XmmRegister src) {
1891   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1892   emitUint8(0x66);
1893   emitUint8(0x0F);
1894   if (isByteSizedArithType(Ty)) {
1895     emitUint8(0x74);
1896   } else if (Ty == IceType_i16) {
1897     emitUint8(0x75);
1898   } else {
1899     emitUint8(0x76);
1900   }
1901   emitXmmRegisterOperand(dst, src);
1902 }
1903 
pcmpeq(Type Ty,XmmRegister dst,const AsmAddress & src)1904 void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, const AsmAddress &src) {
1905   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1906   emitUint8(0x66);
1907   emitUint8(0x0F);
1908   if (isByteSizedArithType(Ty)) {
1909     emitUint8(0x74);
1910   } else if (Ty == IceType_i16) {
1911     emitUint8(0x75);
1912   } else {
1913     emitUint8(0x76);
1914   }
1915   emitOperand(gprEncoding(dst), src);
1916 }
1917 
pcmpgt(Type Ty,XmmRegister dst,XmmRegister src)1918 void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, XmmRegister src) {
1919   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1920   emitUint8(0x66);
1921   emitUint8(0x0F);
1922   if (isByteSizedArithType(Ty)) {
1923     emitUint8(0x64);
1924   } else if (Ty == IceType_i16) {
1925     emitUint8(0x65);
1926   } else {
1927     emitUint8(0x66);
1928   }
1929   emitXmmRegisterOperand(dst, src);
1930 }
1931 
pcmpgt(Type Ty,XmmRegister dst,const AsmAddress & src)1932 void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, const AsmAddress &src) {
1933   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1934   emitUint8(0x66);
1935   emitUint8(0x0F);
1936   if (isByteSizedArithType(Ty)) {
1937     emitUint8(0x64);
1938   } else if (Ty == IceType_i16) {
1939     emitUint8(0x65);
1940   } else {
1941     emitUint8(0x66);
1942   }
1943   emitOperand(gprEncoding(dst), src);
1944 }
1945 
round(Type Ty,XmmRegister dst,XmmRegister src,const Immediate & mode)1946 void AssemblerX8632::round(Type Ty, XmmRegister dst, XmmRegister src,
1947                            const Immediate &mode) {
1948   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1949   emitUint8(0x66);
1950   emitUint8(0x0F);
1951   emitUint8(0x3A);
1952   switch (Ty) {
1953   case IceType_v4f32:
1954     emitUint8(0x08);
1955     break;
1956   case IceType_f32:
1957     emitUint8(0x0A);
1958     break;
1959   case IceType_f64:
1960     emitUint8(0x0B);
1961     break;
1962   default:
1963     assert(false && "Unsupported round operand type");
1964   }
1965   emitXmmRegisterOperand(dst, src);
1966   // Mask precision exeption.
1967   emitUint8(static_cast<uint8_t>(mode.value()) | 0x8);
1968 }
1969 
round(Type Ty,XmmRegister dst,const AsmAddress & src,const Immediate & mode)1970 void AssemblerX8632::round(Type Ty, XmmRegister dst, const AsmAddress &src,
1971                            const Immediate &mode) {
1972   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1973   emitUint8(0x66);
1974   emitUint8(0x0F);
1975   emitUint8(0x3A);
1976   switch (Ty) {
1977   case IceType_v4f32:
1978     emitUint8(0x08);
1979     break;
1980   case IceType_f32:
1981     emitUint8(0x0A);
1982     break;
1983   case IceType_f64:
1984     emitUint8(0x0B);
1985     break;
1986   default:
1987     assert(false && "Unsupported round operand type");
1988   }
1989   emitOperand(gprEncoding(dst), src);
1990   // Mask precision exeption.
1991   emitUint8(static_cast<uint8_t>(mode.value()) | 0x8);
1992 }
1993 
fnstcw(const AsmAddress & dst)1994 void AssemblerX8632::fnstcw(const AsmAddress &dst) {
1995   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1996   emitUint8(0xD9);
1997   emitOperand(7, dst);
1998 }
1999 
fldcw(const AsmAddress & src)2000 void AssemblerX8632::fldcw(const AsmAddress &src) {
2001   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2002   emitUint8(0xD9);
2003   emitOperand(5, src);
2004 }
2005 
fistpl(const AsmAddress & dst)2006 void AssemblerX8632::fistpl(const AsmAddress &dst) {
2007   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2008   emitUint8(0xDF);
2009   emitOperand(7, dst);
2010 }
2011 
fistps(const AsmAddress & dst)2012 void AssemblerX8632::fistps(const AsmAddress &dst) {
2013   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2014   emitUint8(0xDB);
2015   emitOperand(3, dst);
2016 }
2017 
fildl(const AsmAddress & src)2018 void AssemblerX8632::fildl(const AsmAddress &src) {
2019   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2020   emitUint8(0xDF);
2021   emitOperand(5, src);
2022 }
2023 
filds(const AsmAddress & src)2024 void AssemblerX8632::filds(const AsmAddress &src) {
2025   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2026   emitUint8(0xDB);
2027   emitOperand(0, src);
2028 }
2029 
fincstp()2030 void AssemblerX8632::fincstp() {
2031   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2032   emitUint8(0xD9);
2033   emitUint8(0xF7);
2034 }
2035 
2036 template <uint32_t Tag>
arith_int(Type Ty,GPRRegister reg,const Immediate & imm)2037 void AssemblerX8632::arith_int(Type Ty, GPRRegister reg, const Immediate &imm) {
2038   static_assert(Tag < 8, "Tag must be between 0..7");
2039   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2040   if (Ty == IceType_i16)
2041     emitOperandSizeOverride();
2042   if (isByteSizedType(Ty)) {
2043     emitComplexI8(Tag, AsmOperand(reg), imm);
2044   } else {
2045     emitComplex(Ty, Tag, AsmOperand(reg), imm);
2046   }
2047 }
2048 
2049 template <uint32_t Tag>
arith_int(Type Ty,GPRRegister reg0,GPRRegister reg1)2050 void AssemblerX8632::arith_int(Type Ty, GPRRegister reg0, GPRRegister reg1) {
2051   static_assert(Tag < 8, "Tag must be between 0..7");
2052   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2053   if (Ty == IceType_i16)
2054     emitOperandSizeOverride();
2055   if (isByteSizedType(Ty))
2056     emitUint8(Tag * 8 + 2);
2057   else
2058     emitUint8(Tag * 8 + 3);
2059   emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1));
2060 }
2061 
2062 template <uint32_t Tag>
arith_int(Type Ty,GPRRegister reg,const AsmAddress & address)2063 void AssemblerX8632::arith_int(Type Ty, GPRRegister reg,
2064                                const AsmAddress &address) {
2065   static_assert(Tag < 8, "Tag must be between 0..7");
2066   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2067   if (Ty == IceType_i16)
2068     emitOperandSizeOverride();
2069   if (isByteSizedType(Ty))
2070     emitUint8(Tag * 8 + 2);
2071   else
2072     emitUint8(Tag * 8 + 3);
2073   emitOperand(gprEncoding(reg), address);
2074 }
2075 
2076 template <uint32_t Tag>
arith_int(Type Ty,const AsmAddress & address,GPRRegister reg)2077 void AssemblerX8632::arith_int(Type Ty, const AsmAddress &address,
2078                                GPRRegister reg) {
2079   static_assert(Tag < 8, "Tag must be between 0..7");
2080   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2081   if (Ty == IceType_i16)
2082     emitOperandSizeOverride();
2083   if (isByteSizedType(Ty))
2084     emitUint8(Tag * 8 + 0);
2085   else
2086     emitUint8(Tag * 8 + 1);
2087   emitOperand(gprEncoding(reg), address);
2088 }
2089 
2090 template <uint32_t Tag>
arith_int(Type Ty,const AsmAddress & address,const Immediate & imm)2091 void AssemblerX8632::arith_int(Type Ty, const AsmAddress &address,
2092                                const Immediate &imm) {
2093   static_assert(Tag < 8, "Tag must be between 0..7");
2094   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2095   if (Ty == IceType_i16)
2096     emitOperandSizeOverride();
2097   if (isByteSizedType(Ty)) {
2098     emitComplexI8(Tag, address, imm);
2099   } else {
2100     emitComplex(Ty, Tag, address, imm);
2101   }
2102 }
2103 
cmp(Type Ty,GPRRegister reg,const Immediate & imm)2104 void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const Immediate &imm) {
2105   arith_int<7>(Ty, reg, imm);
2106 }
2107 
cmp(Type Ty,GPRRegister reg0,GPRRegister reg1)2108 void AssemblerX8632::cmp(Type Ty, GPRRegister reg0, GPRRegister reg1) {
2109   arith_int<7>(Ty, reg0, reg1);
2110 }
2111 
cmp(Type Ty,GPRRegister reg,const AsmAddress & address)2112 void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const AsmAddress &address) {
2113   arith_int<7>(Ty, reg, address);
2114 }
2115 
cmp(Type Ty,const AsmAddress & address,GPRRegister reg)2116 void AssemblerX8632::cmp(Type Ty, const AsmAddress &address, GPRRegister reg) {
2117   arith_int<7>(Ty, address, reg);
2118 }
2119 
cmp(Type Ty,const AsmAddress & address,const Immediate & imm)2120 void AssemblerX8632::cmp(Type Ty, const AsmAddress &address,
2121                          const Immediate &imm) {
2122   arith_int<7>(Ty, address, imm);
2123 }
2124 
test(Type Ty,GPRRegister reg1,GPRRegister reg2)2125 void AssemblerX8632::test(Type Ty, GPRRegister reg1, GPRRegister reg2) {
2126   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2127   if (Ty == IceType_i16)
2128     emitOperandSizeOverride();
2129   if (isByteSizedType(Ty))
2130     emitUint8(0x84);
2131   else
2132     emitUint8(0x85);
2133   emitRegisterOperand(gprEncoding(reg1), gprEncoding(reg2));
2134 }
2135 
test(Type Ty,const AsmAddress & addr,GPRRegister reg)2136 void AssemblerX8632::test(Type Ty, const AsmAddress &addr, GPRRegister reg) {
2137   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2138   if (Ty == IceType_i16)
2139     emitOperandSizeOverride();
2140   if (isByteSizedType(Ty))
2141     emitUint8(0x84);
2142   else
2143     emitUint8(0x85);
2144   emitOperand(gprEncoding(reg), addr);
2145 }
2146 
test(Type Ty,GPRRegister reg,const Immediate & immediate)2147 void AssemblerX8632::test(Type Ty, GPRRegister reg,
2148                           const Immediate &immediate) {
2149   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2150   // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only
2151   // test the byte register to keep the encoding short. This is legal even if
2152   // the register had high bits set since this only sets flags registers based
2153   // on the "AND" of the two operands, and the immediate had zeros at those
2154   // high bits.
2155   constexpr GPRRegister Last8BitGPR = GPRRegister::Encoded_Reg_ebx;
2156   if (immediate.is_uint8() && reg <= Last8BitGPR) {
2157     // Use zero-extended 8-bit immediate.
2158     if (reg == RegX8632::Encoded_Reg_eax) {
2159       emitUint8(0xA8);
2160     } else {
2161       emitUint8(0xF6);
2162       emitUint8(0xC0 + gprEncoding(reg));
2163     }
2164     emitUint8(immediate.value() & 0xFF);
2165   } else if (reg == RegX8632::Encoded_Reg_eax) {
2166     // Use short form if the destination is EAX.
2167     if (Ty == IceType_i16)
2168       emitOperandSizeOverride();
2169     emitUint8(0xA9);
2170     emitImmediate(Ty, immediate);
2171   } else {
2172     if (Ty == IceType_i16)
2173       emitOperandSizeOverride();
2174     emitUint8(0xF7);
2175     emitRegisterOperand(0, gprEncoding(reg));
2176     emitImmediate(Ty, immediate);
2177   }
2178 }
2179 
test(Type Ty,const AsmAddress & addr,const Immediate & immediate)2180 void AssemblerX8632::test(Type Ty, const AsmAddress &addr,
2181                           const Immediate &immediate) {
2182   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2183   // If the immediate is short, we only test the byte addr to keep the encoding
2184   // short.
2185   if (immediate.is_uint8()) {
2186     // Use zero-extended 8-bit immediate.
2187     emitUint8(0xF6);
2188     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
2189     emitOperand(0, addr, OffsetFromNextInstruction);
2190     emitUint8(immediate.value() & 0xFF);
2191   } else {
2192     if (Ty == IceType_i16)
2193       emitOperandSizeOverride();
2194     emitUint8(0xF7);
2195     const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4;
2196     emitOperand(0, addr, OffsetFromNextInstruction);
2197     emitImmediate(Ty, immediate);
2198   }
2199 }
2200 
And(Type Ty,GPRRegister dst,GPRRegister src)2201 void AssemblerX8632::And(Type Ty, GPRRegister dst, GPRRegister src) {
2202   arith_int<4>(Ty, dst, src);
2203 }
2204 
And(Type Ty,GPRRegister dst,const AsmAddress & address)2205 void AssemblerX8632::And(Type Ty, GPRRegister dst, const AsmAddress &address) {
2206   arith_int<4>(Ty, dst, address);
2207 }
2208 
And(Type Ty,GPRRegister dst,const Immediate & imm)2209 void AssemblerX8632::And(Type Ty, GPRRegister dst, const Immediate &imm) {
2210   arith_int<4>(Ty, dst, imm);
2211 }
2212 
And(Type Ty,const AsmAddress & address,GPRRegister reg)2213 void AssemblerX8632::And(Type Ty, const AsmAddress &address, GPRRegister reg) {
2214   arith_int<4>(Ty, address, reg);
2215 }
2216 
And(Type Ty,const AsmAddress & address,const Immediate & imm)2217 void AssemblerX8632::And(Type Ty, const AsmAddress &address,
2218                          const Immediate &imm) {
2219   arith_int<4>(Ty, address, imm);
2220 }
2221 
Or(Type Ty,GPRRegister dst,GPRRegister src)2222 void AssemblerX8632::Or(Type Ty, GPRRegister dst, GPRRegister src) {
2223   arith_int<1>(Ty, dst, src);
2224 }
2225 
Or(Type Ty,GPRRegister dst,const AsmAddress & address)2226 void AssemblerX8632::Or(Type Ty, GPRRegister dst, const AsmAddress &address) {
2227   arith_int<1>(Ty, dst, address);
2228 }
2229 
Or(Type Ty,GPRRegister dst,const Immediate & imm)2230 void AssemblerX8632::Or(Type Ty, GPRRegister dst, const Immediate &imm) {
2231   arith_int<1>(Ty, dst, imm);
2232 }
2233 
Or(Type Ty,const AsmAddress & address,GPRRegister reg)2234 void AssemblerX8632::Or(Type Ty, const AsmAddress &address, GPRRegister reg) {
2235   arith_int<1>(Ty, address, reg);
2236 }
2237 
Or(Type Ty,const AsmAddress & address,const Immediate & imm)2238 void AssemblerX8632::Or(Type Ty, const AsmAddress &address,
2239                         const Immediate &imm) {
2240   arith_int<1>(Ty, address, imm);
2241 }
2242 
Xor(Type Ty,GPRRegister dst,GPRRegister src)2243 void AssemblerX8632::Xor(Type Ty, GPRRegister dst, GPRRegister src) {
2244   arith_int<6>(Ty, dst, src);
2245 }
2246 
Xor(Type Ty,GPRRegister dst,const AsmAddress & address)2247 void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const AsmAddress &address) {
2248   arith_int<6>(Ty, dst, address);
2249 }
2250 
Xor(Type Ty,GPRRegister dst,const Immediate & imm)2251 void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const Immediate &imm) {
2252   arith_int<6>(Ty, dst, imm);
2253 }
2254 
Xor(Type Ty,const AsmAddress & address,GPRRegister reg)2255 void AssemblerX8632::Xor(Type Ty, const AsmAddress &address, GPRRegister reg) {
2256   arith_int<6>(Ty, address, reg);
2257 }
2258 
Xor(Type Ty,const AsmAddress & address,const Immediate & imm)2259 void AssemblerX8632::Xor(Type Ty, const AsmAddress &address,
2260                          const Immediate &imm) {
2261   arith_int<6>(Ty, address, imm);
2262 }
2263 
add(Type Ty,GPRRegister dst,GPRRegister src)2264 void AssemblerX8632::add(Type Ty, GPRRegister dst, GPRRegister src) {
2265   arith_int<0>(Ty, dst, src);
2266 }
2267 
add(Type Ty,GPRRegister reg,const AsmAddress & address)2268 void AssemblerX8632::add(Type Ty, GPRRegister reg, const AsmAddress &address) {
2269   arith_int<0>(Ty, reg, address);
2270 }
2271 
add(Type Ty,GPRRegister reg,const Immediate & imm)2272 void AssemblerX8632::add(Type Ty, GPRRegister reg, const Immediate &imm) {
2273   arith_int<0>(Ty, reg, imm);
2274 }
2275 
add(Type Ty,const AsmAddress & address,GPRRegister reg)2276 void AssemblerX8632::add(Type Ty, const AsmAddress &address, GPRRegister reg) {
2277   arith_int<0>(Ty, address, reg);
2278 }
2279 
add(Type Ty,const AsmAddress & address,const Immediate & imm)2280 void AssemblerX8632::add(Type Ty, const AsmAddress &address,
2281                          const Immediate &imm) {
2282   arith_int<0>(Ty, address, imm);
2283 }
2284 
adc(Type Ty,GPRRegister dst,GPRRegister src)2285 void AssemblerX8632::adc(Type Ty, GPRRegister dst, GPRRegister src) {
2286   arith_int<2>(Ty, dst, src);
2287 }
2288 
adc(Type Ty,GPRRegister dst,const AsmAddress & address)2289 void AssemblerX8632::adc(Type Ty, GPRRegister dst, const AsmAddress &address) {
2290   arith_int<2>(Ty, dst, address);
2291 }
2292 
adc(Type Ty,GPRRegister reg,const Immediate & imm)2293 void AssemblerX8632::adc(Type Ty, GPRRegister reg, const Immediate &imm) {
2294   arith_int<2>(Ty, reg, imm);
2295 }
2296 
adc(Type Ty,const AsmAddress & address,GPRRegister reg)2297 void AssemblerX8632::adc(Type Ty, const AsmAddress &address, GPRRegister reg) {
2298   arith_int<2>(Ty, address, reg);
2299 }
2300 
adc(Type Ty,const AsmAddress & address,const Immediate & imm)2301 void AssemblerX8632::adc(Type Ty, const AsmAddress &address,
2302                          const Immediate &imm) {
2303   arith_int<2>(Ty, address, imm);
2304 }
2305 
sub(Type Ty,GPRRegister dst,GPRRegister src)2306 void AssemblerX8632::sub(Type Ty, GPRRegister dst, GPRRegister src) {
2307   arith_int<5>(Ty, dst, src);
2308 }
2309 
sub(Type Ty,GPRRegister reg,const AsmAddress & address)2310 void AssemblerX8632::sub(Type Ty, GPRRegister reg, const AsmAddress &address) {
2311   arith_int<5>(Ty, reg, address);
2312 }
2313 
sub(Type Ty,GPRRegister reg,const Immediate & imm)2314 void AssemblerX8632::sub(Type Ty, GPRRegister reg, const Immediate &imm) {
2315   arith_int<5>(Ty, reg, imm);
2316 }
2317 
sub(Type Ty,const AsmAddress & address,GPRRegister reg)2318 void AssemblerX8632::sub(Type Ty, const AsmAddress &address, GPRRegister reg) {
2319   arith_int<5>(Ty, address, reg);
2320 }
2321 
sub(Type Ty,const AsmAddress & address,const Immediate & imm)2322 void AssemblerX8632::sub(Type Ty, const AsmAddress &address,
2323                          const Immediate &imm) {
2324   arith_int<5>(Ty, address, imm);
2325 }
2326 
sbb(Type Ty,GPRRegister dst,GPRRegister src)2327 void AssemblerX8632::sbb(Type Ty, GPRRegister dst, GPRRegister src) {
2328   arith_int<3>(Ty, dst, src);
2329 }
2330 
sbb(Type Ty,GPRRegister dst,const AsmAddress & address)2331 void AssemblerX8632::sbb(Type Ty, GPRRegister dst, const AsmAddress &address) {
2332   arith_int<3>(Ty, dst, address);
2333 }
2334 
sbb(Type Ty,GPRRegister reg,const Immediate & imm)2335 void AssemblerX8632::sbb(Type Ty, GPRRegister reg, const Immediate &imm) {
2336   arith_int<3>(Ty, reg, imm);
2337 }
2338 
sbb(Type Ty,const AsmAddress & address,GPRRegister reg)2339 void AssemblerX8632::sbb(Type Ty, const AsmAddress &address, GPRRegister reg) {
2340   arith_int<3>(Ty, address, reg);
2341 }
2342 
sbb(Type Ty,const AsmAddress & address,const Immediate & imm)2343 void AssemblerX8632::sbb(Type Ty, const AsmAddress &address,
2344                          const Immediate &imm) {
2345   arith_int<3>(Ty, address, imm);
2346 }
2347 
cbw()2348 void AssemblerX8632::cbw() {
2349   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2350   emitOperandSizeOverride();
2351   emitUint8(0x98);
2352 }
2353 
cwd()2354 void AssemblerX8632::cwd() {
2355   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2356   emitOperandSizeOverride();
2357   emitUint8(0x99);
2358 }
2359 
cdq()2360 void AssemblerX8632::cdq() {
2361   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2362   emitUint8(0x99);
2363 }
2364 
div(Type Ty,GPRRegister reg)2365 void AssemblerX8632::div(Type Ty, GPRRegister reg) {
2366   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2367   if (Ty == IceType_i16)
2368     emitOperandSizeOverride();
2369   if (isByteSizedArithType(Ty))
2370     emitUint8(0xF6);
2371   else
2372     emitUint8(0xF7);
2373   emitRegisterOperand(6, gprEncoding(reg));
2374 }
2375 
div(Type Ty,const AsmAddress & addr)2376 void AssemblerX8632::div(Type Ty, const AsmAddress &addr) {
2377   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2378   if (Ty == IceType_i16)
2379     emitOperandSizeOverride();
2380   if (isByteSizedArithType(Ty))
2381     emitUint8(0xF6);
2382   else
2383     emitUint8(0xF7);
2384   emitOperand(6, addr);
2385 }
2386 
idiv(Type Ty,GPRRegister reg)2387 void AssemblerX8632::idiv(Type Ty, GPRRegister reg) {
2388   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2389   if (Ty == IceType_i16)
2390     emitOperandSizeOverride();
2391   if (isByteSizedArithType(Ty))
2392     emitUint8(0xF6);
2393   else
2394     emitUint8(0xF7);
2395   emitRegisterOperand(7, gprEncoding(reg));
2396 }
2397 
idiv(Type Ty,const AsmAddress & addr)2398 void AssemblerX8632::idiv(Type Ty, const AsmAddress &addr) {
2399   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2400   if (Ty == IceType_i16)
2401     emitOperandSizeOverride();
2402   if (isByteSizedArithType(Ty))
2403     emitUint8(0xF6);
2404   else
2405     emitUint8(0xF7);
2406   emitOperand(7, addr);
2407 }
2408 
imul(Type Ty,GPRRegister dst,GPRRegister src)2409 void AssemblerX8632::imul(Type Ty, GPRRegister dst, GPRRegister src) {
2410   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2411   assert(Ty == IceType_i16 || Ty == IceType_i32);
2412   if (Ty == IceType_i16)
2413     emitOperandSizeOverride();
2414   emitUint8(0x0F);
2415   emitUint8(0xAF);
2416   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2417 }
2418 
imul(Type Ty,GPRRegister reg,const AsmAddress & address)2419 void AssemblerX8632::imul(Type Ty, GPRRegister reg, const AsmAddress &address) {
2420   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2421   assert(Ty == IceType_i16 || Ty == IceType_i32);
2422   if (Ty == IceType_i16)
2423     emitOperandSizeOverride();
2424   emitUint8(0x0F);
2425   emitUint8(0xAF);
2426   emitOperand(gprEncoding(reg), address);
2427 }
2428 
imul(Type Ty,GPRRegister reg,const Immediate & imm)2429 void AssemblerX8632::imul(Type Ty, GPRRegister reg, const Immediate &imm) {
2430   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2431   assert(Ty == IceType_i16 || Ty == IceType_i32 || Ty == IceType_i64);
2432   if (Ty == IceType_i16)
2433     emitOperandSizeOverride();
2434   if (imm.is_int8()) {
2435     emitUint8(0x6B);
2436     emitRegisterOperand(gprEncoding(reg), gprEncoding(reg));
2437     emitUint8(imm.value() & 0xFF);
2438   } else {
2439     emitUint8(0x69);
2440     emitRegisterOperand(gprEncoding(reg), gprEncoding(reg));
2441     emitImmediate(Ty, imm);
2442   }
2443 }
2444 
imul(Type Ty,GPRRegister reg)2445 void AssemblerX8632::imul(Type Ty, GPRRegister reg) {
2446   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2447   if (Ty == IceType_i16)
2448     emitOperandSizeOverride();
2449   if (isByteSizedArithType(Ty))
2450     emitUint8(0xF6);
2451   else
2452     emitUint8(0xF7);
2453   emitRegisterOperand(5, gprEncoding(reg));
2454 }
2455 
imul(Type Ty,const AsmAddress & address)2456 void AssemblerX8632::imul(Type Ty, const AsmAddress &address) {
2457   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2458   if (Ty == IceType_i16)
2459     emitOperandSizeOverride();
2460   if (isByteSizedArithType(Ty))
2461     emitUint8(0xF6);
2462   else
2463     emitUint8(0xF7);
2464   emitOperand(5, address);
2465 }
2466 
imul(Type Ty,GPRRegister dst,GPRRegister src,const Immediate & imm)2467 void AssemblerX8632::imul(Type Ty, GPRRegister dst, GPRRegister src,
2468                           const Immediate &imm) {
2469   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2470   assert(Ty == IceType_i16 || Ty == IceType_i32);
2471   if (Ty == IceType_i16)
2472     emitOperandSizeOverride();
2473   if (imm.is_int8()) {
2474     emitUint8(0x6B);
2475     emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2476     emitUint8(imm.value() & 0xFF);
2477   } else {
2478     emitUint8(0x69);
2479     emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2480     emitImmediate(Ty, imm);
2481   }
2482 }
2483 
imul(Type Ty,GPRRegister dst,const AsmAddress & address,const Immediate & imm)2484 void AssemblerX8632::imul(Type Ty, GPRRegister dst, const AsmAddress &address,
2485                           const Immediate &imm) {
2486   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2487   assert(Ty == IceType_i16 || Ty == IceType_i32);
2488   if (Ty == IceType_i16)
2489     emitOperandSizeOverride();
2490   if (imm.is_int8()) {
2491     emitUint8(0x6B);
2492     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
2493     emitOperand(gprEncoding(dst), address, OffsetFromNextInstruction);
2494     emitUint8(imm.value() & 0xFF);
2495   } else {
2496     emitUint8(0x69);
2497     const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4;
2498     emitOperand(gprEncoding(dst), address, OffsetFromNextInstruction);
2499     emitImmediate(Ty, imm);
2500   }
2501 }
2502 
mul(Type Ty,GPRRegister reg)2503 void AssemblerX8632::mul(Type Ty, GPRRegister reg) {
2504   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2505   if (Ty == IceType_i16)
2506     emitOperandSizeOverride();
2507   if (isByteSizedArithType(Ty))
2508     emitUint8(0xF6);
2509   else
2510     emitUint8(0xF7);
2511   emitRegisterOperand(4, gprEncoding(reg));
2512 }
2513 
mul(Type Ty,const AsmAddress & address)2514 void AssemblerX8632::mul(Type Ty, const AsmAddress &address) {
2515   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2516   if (Ty == IceType_i16)
2517     emitOperandSizeOverride();
2518   if (isByteSizedArithType(Ty))
2519     emitUint8(0xF6);
2520   else
2521     emitUint8(0xF7);
2522   emitOperand(4, address);
2523 }
2524 
incl(GPRRegister reg)2525 void AssemblerX8632::incl(GPRRegister reg) {
2526   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2527   emitUint8(0x40 + reg);
2528 }
2529 
incl(const AsmAddress & address)2530 void AssemblerX8632::incl(const AsmAddress &address) {
2531   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2532   emitUint8(0xFF);
2533   emitOperand(0, address);
2534 }
2535 
decl(GPRRegister reg)2536 void AssemblerX8632::decl(GPRRegister reg) {
2537   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2538   emitUint8(0x48 + reg);
2539 }
2540 
decl(const AsmAddress & address)2541 void AssemblerX8632::decl(const AsmAddress &address) {
2542   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2543   emitUint8(0xFF);
2544   emitOperand(1, address);
2545 }
2546 
rol(Type Ty,GPRRegister reg,const Immediate & imm)2547 void AssemblerX8632::rol(Type Ty, GPRRegister reg, const Immediate &imm) {
2548   emitGenericShift(0, Ty, reg, imm);
2549 }
2550 
rol(Type Ty,GPRRegister operand,GPRRegister shifter)2551 void AssemblerX8632::rol(Type Ty, GPRRegister operand, GPRRegister shifter) {
2552   emitGenericShift(0, Ty, AsmOperand(operand), shifter);
2553 }
2554 
rol(Type Ty,const AsmAddress & operand,GPRRegister shifter)2555 void AssemblerX8632::rol(Type Ty, const AsmAddress &operand,
2556                          GPRRegister shifter) {
2557   emitGenericShift(0, Ty, operand, shifter);
2558 }
2559 
shl(Type Ty,GPRRegister reg,const Immediate & imm)2560 void AssemblerX8632::shl(Type Ty, GPRRegister reg, const Immediate &imm) {
2561   emitGenericShift(4, Ty, reg, imm);
2562 }
2563 
shl(Type Ty,GPRRegister operand,GPRRegister shifter)2564 void AssemblerX8632::shl(Type Ty, GPRRegister operand, GPRRegister shifter) {
2565   emitGenericShift(4, Ty, AsmOperand(operand), shifter);
2566 }
2567 
shl(Type Ty,const AsmAddress & operand,GPRRegister shifter)2568 void AssemblerX8632::shl(Type Ty, const AsmAddress &operand,
2569                          GPRRegister shifter) {
2570   emitGenericShift(4, Ty, operand, shifter);
2571 }
2572 
shr(Type Ty,GPRRegister reg,const Immediate & imm)2573 void AssemblerX8632::shr(Type Ty, GPRRegister reg, const Immediate &imm) {
2574   emitGenericShift(5, Ty, reg, imm);
2575 }
2576 
shr(Type Ty,GPRRegister operand,GPRRegister shifter)2577 void AssemblerX8632::shr(Type Ty, GPRRegister operand, GPRRegister shifter) {
2578   emitGenericShift(5, Ty, AsmOperand(operand), shifter);
2579 }
2580 
shr(Type Ty,const AsmAddress & operand,GPRRegister shifter)2581 void AssemblerX8632::shr(Type Ty, const AsmAddress &operand,
2582                          GPRRegister shifter) {
2583   emitGenericShift(5, Ty, operand, shifter);
2584 }
2585 
sar(Type Ty,GPRRegister reg,const Immediate & imm)2586 void AssemblerX8632::sar(Type Ty, GPRRegister reg, const Immediate &imm) {
2587   emitGenericShift(7, Ty, reg, imm);
2588 }
2589 
sar(Type Ty,GPRRegister operand,GPRRegister shifter)2590 void AssemblerX8632::sar(Type Ty, GPRRegister operand, GPRRegister shifter) {
2591   emitGenericShift(7, Ty, AsmOperand(operand), shifter);
2592 }
2593 
sar(Type Ty,const AsmAddress & address,GPRRegister shifter)2594 void AssemblerX8632::sar(Type Ty, const AsmAddress &address,
2595                          GPRRegister shifter) {
2596   emitGenericShift(7, Ty, address, shifter);
2597 }
2598 
shld(Type Ty,GPRRegister dst,GPRRegister src)2599 void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src) {
2600   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2601   assert(Ty == IceType_i16 || Ty == IceType_i32);
2602   if (Ty == IceType_i16)
2603     emitOperandSizeOverride();
2604   emitUint8(0x0F);
2605   emitUint8(0xA5);
2606   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2607 }
2608 
shld(Type Ty,GPRRegister dst,GPRRegister src,const Immediate & imm)2609 void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src,
2610                           const Immediate &imm) {
2611   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2612   assert(Ty == IceType_i16 || Ty == IceType_i32);
2613   assert(imm.is_int8());
2614   if (Ty == IceType_i16)
2615     emitOperandSizeOverride();
2616   emitUint8(0x0F);
2617   emitUint8(0xA4);
2618   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2619   emitUint8(imm.value() & 0xFF);
2620 }
2621 
shld(Type Ty,const AsmAddress & operand,GPRRegister src)2622 void AssemblerX8632::shld(Type Ty, const AsmAddress &operand, GPRRegister src) {
2623   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2624   assert(Ty == IceType_i16 || Ty == IceType_i32);
2625   if (Ty == IceType_i16)
2626     emitOperandSizeOverride();
2627   emitUint8(0x0F);
2628   emitUint8(0xA5);
2629   emitOperand(gprEncoding(src), operand);
2630 }
2631 
shrd(Type Ty,GPRRegister dst,GPRRegister src)2632 void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src) {
2633   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2634   assert(Ty == IceType_i16 || Ty == IceType_i32);
2635   if (Ty == IceType_i16)
2636     emitOperandSizeOverride();
2637   emitUint8(0x0F);
2638   emitUint8(0xAD);
2639   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2640 }
2641 
shrd(Type Ty,GPRRegister dst,GPRRegister src,const Immediate & imm)2642 void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src,
2643                           const Immediate &imm) {
2644   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2645   assert(Ty == IceType_i16 || Ty == IceType_i32);
2646   assert(imm.is_int8());
2647   if (Ty == IceType_i16)
2648     emitOperandSizeOverride();
2649   emitUint8(0x0F);
2650   emitUint8(0xAC);
2651   emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2652   emitUint8(imm.value() & 0xFF);
2653 }
2654 
shrd(Type Ty,const AsmAddress & dst,GPRRegister src)2655 void AssemblerX8632::shrd(Type Ty, const AsmAddress &dst, GPRRegister src) {
2656   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2657   assert(Ty == IceType_i16 || Ty == IceType_i32);
2658   if (Ty == IceType_i16)
2659     emitOperandSizeOverride();
2660   emitUint8(0x0F);
2661   emitUint8(0xAD);
2662   emitOperand(gprEncoding(src), dst);
2663 }
2664 
neg(Type Ty,GPRRegister reg)2665 void AssemblerX8632::neg(Type Ty, GPRRegister reg) {
2666   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2667   if (Ty == IceType_i16)
2668     emitOperandSizeOverride();
2669   if (isByteSizedArithType(Ty))
2670     emitUint8(0xF6);
2671   else
2672     emitUint8(0xF7);
2673   emitRegisterOperand(3, gprEncoding(reg));
2674 }
2675 
neg(Type Ty,const AsmAddress & addr)2676 void AssemblerX8632::neg(Type Ty, const AsmAddress &addr) {
2677   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2678   if (Ty == IceType_i16)
2679     emitOperandSizeOverride();
2680   if (isByteSizedArithType(Ty))
2681     emitUint8(0xF6);
2682   else
2683     emitUint8(0xF7);
2684   emitOperand(3, addr);
2685 }
2686 
notl(GPRRegister reg)2687 void AssemblerX8632::notl(GPRRegister reg) {
2688   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2689   emitUint8(0xF7);
2690   emitUint8(0xD0 | gprEncoding(reg));
2691 }
2692 
bswap(Type Ty,GPRRegister reg)2693 void AssemblerX8632::bswap(Type Ty, GPRRegister reg) {
2694   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2695   assert(Ty == IceType_i32);
2696   emitUint8(0x0F);
2697   emitUint8(0xC8 | gprEncoding(reg));
2698 }
2699 
bsf(Type Ty,GPRRegister dst,GPRRegister src)2700 void AssemblerX8632::bsf(Type Ty, GPRRegister dst, GPRRegister src) {
2701   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2702   assert(Ty == IceType_i16 || Ty == IceType_i32);
2703   if (Ty == IceType_i16)
2704     emitOperandSizeOverride();
2705   emitUint8(0x0F);
2706   emitUint8(0xBC);
2707   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2708 }
2709 
bsf(Type Ty,GPRRegister dst,const AsmAddress & src)2710 void AssemblerX8632::bsf(Type Ty, GPRRegister dst, const AsmAddress &src) {
2711   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2712   assert(Ty == IceType_i16 || Ty == IceType_i32);
2713   if (Ty == IceType_i16)
2714     emitOperandSizeOverride();
2715   emitUint8(0x0F);
2716   emitUint8(0xBC);
2717   emitOperand(gprEncoding(dst), src);
2718 }
2719 
bsr(Type Ty,GPRRegister dst,GPRRegister src)2720 void AssemblerX8632::bsr(Type Ty, GPRRegister dst, GPRRegister src) {
2721   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2722   assert(Ty == IceType_i16 || Ty == IceType_i32);
2723   if (Ty == IceType_i16)
2724     emitOperandSizeOverride();
2725   emitUint8(0x0F);
2726   emitUint8(0xBD);
2727   emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2728 }
2729 
bsr(Type Ty,GPRRegister dst,const AsmAddress & src)2730 void AssemblerX8632::bsr(Type Ty, GPRRegister dst, const AsmAddress &src) {
2731   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2732   assert(Ty == IceType_i16 || Ty == IceType_i32);
2733   if (Ty == IceType_i16)
2734     emitOperandSizeOverride();
2735   emitUint8(0x0F);
2736   emitUint8(0xBD);
2737   emitOperand(gprEncoding(dst), src);
2738 }
2739 
bt(GPRRegister base,GPRRegister offset)2740 void AssemblerX8632::bt(GPRRegister base, GPRRegister offset) {
2741   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2742   emitUint8(0x0F);
2743   emitUint8(0xA3);
2744   emitRegisterOperand(gprEncoding(offset), gprEncoding(base));
2745 }
2746 
ret()2747 void AssemblerX8632::ret() {
2748   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2749   emitUint8(0xC3);
2750 }
2751 
ret(const Immediate & imm)2752 void AssemblerX8632::ret(const Immediate &imm) {
2753   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2754   emitUint8(0xC2);
2755   assert(imm.is_uint16());
2756   emitUint8(imm.value() & 0xFF);
2757   emitUint8((imm.value() >> 8) & 0xFF);
2758 }
2759 
nop(int size)2760 void AssemblerX8632::nop(int size) {
2761   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2762   // There are nops up to size 15, but for now just provide up to size 8.
2763   assert(0 < size && size <= MAX_NOP_SIZE);
2764   switch (size) {
2765   case 1:
2766     emitUint8(0x90);
2767     break;
2768   case 2:
2769     emitUint8(0x66);
2770     emitUint8(0x90);
2771     break;
2772   case 3:
2773     emitUint8(0x0F);
2774     emitUint8(0x1F);
2775     emitUint8(0x00);
2776     break;
2777   case 4:
2778     emitUint8(0x0F);
2779     emitUint8(0x1F);
2780     emitUint8(0x40);
2781     emitUint8(0x00);
2782     break;
2783   case 5:
2784     emitUint8(0x0F);
2785     emitUint8(0x1F);
2786     emitUint8(0x44);
2787     emitUint8(0x00);
2788     emitUint8(0x00);
2789     break;
2790   case 6:
2791     emitUint8(0x66);
2792     emitUint8(0x0F);
2793     emitUint8(0x1F);
2794     emitUint8(0x44);
2795     emitUint8(0x00);
2796     emitUint8(0x00);
2797     break;
2798   case 7:
2799     emitUint8(0x0F);
2800     emitUint8(0x1F);
2801     emitUint8(0x80);
2802     emitUint8(0x00);
2803     emitUint8(0x00);
2804     emitUint8(0x00);
2805     emitUint8(0x00);
2806     break;
2807   case 8:
2808     emitUint8(0x0F);
2809     emitUint8(0x1F);
2810     emitUint8(0x84);
2811     emitUint8(0x00);
2812     emitUint8(0x00);
2813     emitUint8(0x00);
2814     emitUint8(0x00);
2815     emitUint8(0x00);
2816     break;
2817   default:
2818     llvm_unreachable("Unimplemented");
2819   }
2820 }
2821 
int3()2822 void AssemblerX8632::int3() {
2823   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2824   emitUint8(0xCC);
2825 }
2826 
hlt()2827 void AssemblerX8632::hlt() {
2828   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2829   emitUint8(0xF4);
2830 }
2831 
ud2()2832 void AssemblerX8632::ud2() {
2833   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2834   emitUint8(0x0F);
2835   emitUint8(0x0B);
2836 }
2837 
j(BrCond condition,Label * label,bool near)2838 void AssemblerX8632::j(BrCond condition, Label *label, bool near) {
2839   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2840   if (label->isBound()) {
2841     static const int kShortSize = 2;
2842     static const int kLongSize = 6;
2843     intptr_t offset = label->getPosition() - Buffer.size();
2844     assert(offset <= 0);
2845     if (Utils::IsInt(8, offset - kShortSize)) {
2846       emitUint8(0x70 + condition);
2847       emitUint8((offset - kShortSize) & 0xFF);
2848     } else {
2849       emitUint8(0x0F);
2850       emitUint8(0x80 + condition);
2851       emitInt32(offset - kLongSize);
2852     }
2853   } else if (near) {
2854     emitUint8(0x70 + condition);
2855     emitNearLabelLink(label);
2856   } else {
2857     emitUint8(0x0F);
2858     emitUint8(0x80 + condition);
2859     emitLabelLink(label);
2860   }
2861 }
2862 
j(BrCond condition,const ConstantRelocatable * label)2863 void AssemblerX8632::j(BrCond condition, const ConstantRelocatable *label) {
2864   llvm::report_fatal_error("Untested - please verify and then reenable.");
2865   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2866   emitUint8(0x0F);
2867   emitUint8(0x80 + condition);
2868   auto *Fixup = this->createFixup(FK_PcRel, label);
2869   Fixup->set_addend(-4);
2870   emitFixup(Fixup);
2871   emitInt32(0);
2872 }
2873 
jmp(GPRRegister reg)2874 void AssemblerX8632::jmp(GPRRegister reg) {
2875   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2876   emitUint8(0xFF);
2877   emitRegisterOperand(4, gprEncoding(reg));
2878 }
2879 
jmp(Label * label,bool near)2880 void AssemblerX8632::jmp(Label *label, bool near) {
2881   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2882   if (label->isBound()) {
2883     static const int kShortSize = 2;
2884     static const int kLongSize = 5;
2885     intptr_t offset = label->getPosition() - Buffer.size();
2886     assert(offset <= 0);
2887     if (Utils::IsInt(8, offset - kShortSize)) {
2888       emitUint8(0xEB);
2889       emitUint8((offset - kShortSize) & 0xFF);
2890     } else {
2891       emitUint8(0xE9);
2892       emitInt32(offset - kLongSize);
2893     }
2894   } else if (near) {
2895     emitUint8(0xEB);
2896     emitNearLabelLink(label);
2897   } else {
2898     emitUint8(0xE9);
2899     emitLabelLink(label);
2900   }
2901 }
2902 
jmp(const ConstantRelocatable * label)2903 void AssemblerX8632::jmp(const ConstantRelocatable *label) {
2904   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2905   emitUint8(0xE9);
2906   auto *Fixup = this->createFixup(FK_PcRel, label);
2907   Fixup->set_addend(-4);
2908   emitFixup(Fixup);
2909   emitInt32(0);
2910 }
2911 
jmp(const Immediate & abs_address)2912 void AssemblerX8632::jmp(const Immediate &abs_address) {
2913   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2914   emitUint8(0xE9);
2915   AssemblerFixup *Fixup = createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
2916   Fixup->set_addend(abs_address.value() - 4);
2917   emitFixup(Fixup);
2918   emitInt32(0);
2919 }
2920 
mfence()2921 void AssemblerX8632::mfence() {
2922   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2923   emitUint8(0x0F);
2924   emitUint8(0xAE);
2925   emitUint8(0xF0);
2926 }
2927 
lock()2928 void AssemblerX8632::lock() {
2929   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2930   emitUint8(0xF0);
2931 }
2932 
cmpxchg(Type Ty,const AsmAddress & address,GPRRegister reg,bool Locked)2933 void AssemblerX8632::cmpxchg(Type Ty, const AsmAddress &address,
2934                              GPRRegister reg, bool Locked) {
2935   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2936   if (Ty == IceType_i16)
2937     emitOperandSizeOverride();
2938   if (Locked)
2939     emitUint8(0xF0);
2940   emitUint8(0x0F);
2941   if (isByteSizedArithType(Ty))
2942     emitUint8(0xB0);
2943   else
2944     emitUint8(0xB1);
2945   emitOperand(gprEncoding(reg), address);
2946 }
2947 
cmpxchg8b(const AsmAddress & address,bool Locked)2948 void AssemblerX8632::cmpxchg8b(const AsmAddress &address, bool Locked) {
2949   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2950   if (Locked)
2951     emitUint8(0xF0);
2952   emitUint8(0x0F);
2953   emitUint8(0xC7);
2954   emitOperand(1, address);
2955 }
2956 
xadd(Type Ty,const AsmAddress & addr,GPRRegister reg,bool Locked)2957 void AssemblerX8632::xadd(Type Ty, const AsmAddress &addr, GPRRegister reg,
2958                           bool Locked) {
2959   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2960   if (Ty == IceType_i16)
2961     emitOperandSizeOverride();
2962   if (Locked)
2963     emitUint8(0xF0);
2964   emitUint8(0x0F);
2965   if (isByteSizedArithType(Ty))
2966     emitUint8(0xC0);
2967   else
2968     emitUint8(0xC1);
2969   emitOperand(gprEncoding(reg), addr);
2970 }
2971 
xchg(Type Ty,GPRRegister reg0,GPRRegister reg1)2972 void AssemblerX8632::xchg(Type Ty, GPRRegister reg0, GPRRegister reg1) {
2973   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2974   if (Ty == IceType_i16)
2975     emitOperandSizeOverride();
2976   // Use short form if either register is EAX.
2977   if (reg0 == RegX8632::Encoded_Reg_eax) {
2978     emitUint8(0x90 + gprEncoding(reg1));
2979   } else if (reg1 == RegX8632::Encoded_Reg_eax) {
2980     emitUint8(0x90 + gprEncoding(reg0));
2981   } else {
2982     if (isByteSizedArithType(Ty))
2983       emitUint8(0x86);
2984     else
2985       emitUint8(0x87);
2986     emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1));
2987   }
2988 }
2989 
xchg(Type Ty,const AsmAddress & addr,GPRRegister reg)2990 void AssemblerX8632::xchg(Type Ty, const AsmAddress &addr, GPRRegister reg) {
2991   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2992   if (Ty == IceType_i16)
2993     emitOperandSizeOverride();
2994   if (isByteSizedArithType(Ty))
2995     emitUint8(0x86);
2996   else
2997     emitUint8(0x87);
2998   emitOperand(gprEncoding(reg), addr);
2999 }
3000 
iaca_start()3001 void AssemblerX8632::iaca_start() {
3002   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3003   emitUint8(0x0F);
3004   emitUint8(0x0B);
3005 
3006   // mov $111, ebx
3007   constexpr GPRRegister dst = GPRRegister::Encoded_Reg_ebx;
3008   constexpr Type Ty = IceType_i32;
3009   emitUint8(0xB8 + gprEncoding(dst));
3010   emitImmediate(Ty, Immediate(111));
3011 
3012   emitUint8(0x64);
3013   emitUint8(0x67);
3014   emitUint8(0x90);
3015 }
3016 
iaca_end()3017 void AssemblerX8632::iaca_end() {
3018   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3019 
3020   // mov $222, ebx
3021   constexpr GPRRegister dst = GPRRegister::Encoded_Reg_ebx;
3022   constexpr Type Ty = IceType_i32;
3023   emitUint8(0xB8 + gprEncoding(dst));
3024   emitImmediate(Ty, Immediate(222));
3025 
3026   emitUint8(0x64);
3027   emitUint8(0x67);
3028   emitUint8(0x90);
3029 
3030   emitUint8(0x0F);
3031   emitUint8(0x0B);
3032 }
3033 
emitSegmentOverride(uint8_t prefix)3034 void AssemblerX8632::emitSegmentOverride(uint8_t prefix) {
3035   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3036   emitUint8(prefix);
3037 }
3038 
align(intptr_t alignment,intptr_t offset)3039 void AssemblerX8632::align(intptr_t alignment, intptr_t offset) {
3040   assert(llvm::isPowerOf2_32(alignment));
3041   intptr_t pos = offset + Buffer.getPosition();
3042   intptr_t mod = pos & (alignment - 1);
3043   if (mod == 0) {
3044     return;
3045   }
3046   intptr_t bytes_needed = alignment - mod;
3047   while (bytes_needed > MAX_NOP_SIZE) {
3048     nop(MAX_NOP_SIZE);
3049     bytes_needed -= MAX_NOP_SIZE;
3050   }
3051   if (bytes_needed) {
3052     nop(bytes_needed);
3053   }
3054   assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
3055 }
3056 
bind(Label * L)3057 void AssemblerX8632::bind(Label *L) {
3058   const intptr_t Bound = Buffer.size();
3059   assert(!L->isBound()); // Labels can only be bound once.
3060   while (L->isLinked()) {
3061     const intptr_t Position = L->getLinkPosition();
3062     const intptr_t Next = Buffer.load<int32_t>(Position);
3063     const intptr_t Offset = Bound - (Position + 4);
3064     Buffer.store<int32_t>(Position, Offset);
3065     L->Position = Next;
3066   }
3067   while (L->hasNear()) {
3068     intptr_t Position = L->getNearPosition();
3069     const intptr_t Offset = Bound - (Position + 1);
3070     assert(Utils::IsInt(8, Offset));
3071     Buffer.store<int8_t>(Position, Offset);
3072   }
3073   L->bindTo(Bound);
3074 }
3075 
emitOperand(int rm,const AsmOperand & operand,RelocOffsetT Addend)3076 void AssemblerX8632::emitOperand(int rm, const AsmOperand &operand,
3077                                  RelocOffsetT Addend) {
3078   assert(rm >= 0 && rm < 8);
3079   const intptr_t length = operand.length_;
3080   assert(length > 0);
3081   intptr_t displacement_start = 1;
3082   // Emit the ModRM byte updated with the given RM value.
3083   assert((operand.encoding_[0] & 0x38) == 0);
3084   emitUint8(operand.encoding_[0] + (rm << 3));
3085   // Whenever the addressing mode is not register indirect, using esp == 0x4
3086   // as the register operation indicates an SIB byte follows.
3087   if (((operand.encoding_[0] & 0xc0) != 0xc0) &&
3088       ((operand.encoding_[0] & 0x07) == 0x04)) {
3089     emitUint8(operand.encoding_[1]);
3090     displacement_start = 2;
3091   }
3092 
3093   AssemblerFixup *Fixup = operand.fixup();
3094   if (Fixup == nullptr) {
3095     for (intptr_t i = displacement_start; i < length; i++) {
3096       emitUint8(operand.encoding_[i]);
3097     }
3098     return;
3099   }
3100 
3101   // Emit the fixup, and a dummy 4-byte immediate. Note that the Disp32 in
3102   // operand.encoding_[i, i+1, i+2, i+3] is part of the constant relocatable
3103   // used to create the fixup, so there's no need to add it to the addend.
3104   assert(length - displacement_start == 4);
3105   if (fixupIsPCRel(Fixup->kind())) {
3106     Fixup->set_addend(Fixup->get_addend() - Addend);
3107   } else {
3108     Fixup->set_addend(Fixup->get_addend());
3109   }
3110   emitFixup(Fixup);
3111   emitInt32(0);
3112 }
3113 
emitImmediate(Type Ty,const Immediate & imm)3114 void AssemblerX8632::emitImmediate(Type Ty, const Immediate &imm) {
3115   auto *const Fixup = imm.fixup();
3116   if (Ty == IceType_i16) {
3117     assert(Fixup == nullptr);
3118     emitInt16(imm.value());
3119     return;
3120   }
3121 
3122   if (Fixup == nullptr) {
3123     emitInt32(imm.value());
3124     return;
3125   }
3126 
3127   Fixup->set_addend(Fixup->get_addend() + imm.value());
3128   emitFixup(Fixup);
3129   emitInt32(0);
3130 }
3131 
emitComplexI8(int rm,const AsmOperand & operand,const Immediate & immediate)3132 void AssemblerX8632::emitComplexI8(int rm, const AsmOperand &operand,
3133                                    const Immediate &immediate) {
3134   assert(rm >= 0 && rm < 8);
3135   assert(immediate.is_int8());
3136   if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
3137     // Use short form if the destination is al.
3138     emitUint8(0x04 + (rm << 3));
3139     emitUint8(immediate.value() & 0xFF);
3140   } else {
3141     // Use sign-extended 8-bit immediate.
3142     emitUint8(0x80);
3143     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
3144     emitOperand(rm, operand, OffsetFromNextInstruction);
3145     emitUint8(immediate.value() & 0xFF);
3146   }
3147 }
3148 
emitComplex(Type Ty,int rm,const AsmOperand & operand,const Immediate & immediate)3149 void AssemblerX8632::emitComplex(Type Ty, int rm, const AsmOperand &operand,
3150                                  const Immediate &immediate) {
3151   assert(rm >= 0 && rm < 8);
3152   if (immediate.is_int8()) {
3153     // Use sign-extended 8-bit immediate.
3154     emitUint8(0x83);
3155     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
3156     emitOperand(rm, operand, OffsetFromNextInstruction);
3157     emitUint8(immediate.value() & 0xFF);
3158   } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
3159     // Use short form if the destination is eax.
3160     emitUint8(0x05 + (rm << 3));
3161     emitImmediate(Ty, immediate);
3162   } else {
3163     emitUint8(0x81);
3164     const uint8_t OffsetFromNextInstruction = Ty == IceType_i16 ? 2 : 4;
3165     emitOperand(rm, operand, OffsetFromNextInstruction);
3166     emitImmediate(Ty, immediate);
3167   }
3168 }
3169 
emitLabel(Label * label,intptr_t instruction_size)3170 void AssemblerX8632::emitLabel(Label *label, intptr_t instruction_size) {
3171   if (label->isBound()) {
3172     intptr_t offset = label->getPosition() - Buffer.size();
3173     assert(offset <= 0);
3174     emitInt32(offset - instruction_size);
3175   } else {
3176     emitLabelLink(label);
3177   }
3178 }
3179 
emitLabelLink(Label * Label)3180 void AssemblerX8632::emitLabelLink(Label *Label) {
3181   assert(!Label->isBound());
3182   intptr_t Position = Buffer.size();
3183   emitInt32(Label->Position);
3184   Label->linkTo(*this, Position);
3185 }
3186 
emitNearLabelLink(Label * Label)3187 void AssemblerX8632::emitNearLabelLink(Label *Label) {
3188   assert(!Label->isBound());
3189   intptr_t Position = Buffer.size();
3190   emitUint8(0);
3191   Label->nearLinkTo(*this, Position);
3192 }
3193 
emitGenericShift(int rm,Type Ty,GPRRegister reg,const Immediate & imm)3194 void AssemblerX8632::emitGenericShift(int rm, Type Ty, GPRRegister reg,
3195                                       const Immediate &imm) {
3196   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3197   // We don't assert that imm fits into 8 bits; instead, it gets masked below.
3198   // Note that we don't mask it further (e.g. to 5 bits) because we want the
3199   // same processor behavior regardless of whether it's an immediate (masked to
3200   // 8 bits) or in register cl (essentially ecx masked to 8 bits).
3201   if (Ty == IceType_i16)
3202     emitOperandSizeOverride();
3203   if (imm.value() == 1) {
3204     emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1);
3205     emitOperand(rm, AsmOperand(reg));
3206   } else {
3207     emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1);
3208     static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
3209     emitOperand(rm, AsmOperand(reg), OffsetFromNextInstruction);
3210     emitUint8(imm.value() & 0xFF);
3211   }
3212 }
3213 
emitGenericShift(int rm,Type Ty,const AsmOperand & operand,GPRRegister shifter)3214 void AssemblerX8632::emitGenericShift(int rm, Type Ty,
3215                                       const AsmOperand &operand,
3216                                       GPRRegister shifter) {
3217   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3218   assert(shifter == RegX8632::Encoded_Reg_ecx);
3219   (void)shifter;
3220   if (Ty == IceType_i16)
3221     emitOperandSizeOverride();
3222   emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
3223   emitOperand(rm, operand);
3224 }
3225 
3226 } // namespace X8632
3227 } // end of namespace Ice
3228