Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: src/IceAssemblerX86BaseImpl.h

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

Powered by Google App Engine
This is Rietveld 408576698