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