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

Side by Side Diff: src/assembler_ia32.cpp

Issue 476323004: Start adding an integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: lit test to check encodings, swap complexi8 Created 6 years, 3 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
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 //
5 // Modified by the Subzero authors.
6 //
7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===//
8 //
9 // The Subzero Code Generator
10 //
11 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details.
13 //
14 //===----------------------------------------------------------------------===//
15 //
16 // This file implements the Assembler class for x86-32.
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "assembler_ia32.h"
21 #include "IceMemoryRegion.h"
22
23 namespace Ice {
24 namespace x86 {
25
26 class DirectCallRelocation : public AssemblerFixup {
27 public:
28 void Process(const MemoryRegion &region, intptr_t position) {
29 // Direct calls are relative to the following instruction on x86.
30 int32_t pointer = region.Load<int32_t>(position);
31 int32_t delta = region.start() + position + sizeof(int32_t);
32 region.Store<int32_t>(position, pointer - delta);
33 }
34 };
35
36 void AssemblerX86::call(Register reg) {
37 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
38 EmitUint8(0xFF);
39 EmitRegisterOperand(2, reg);
40 }
41
42 void AssemblerX86::call(const Address &address) {
43 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
44 EmitUint8(0xFF);
45 EmitOperand(2, address);
46 }
47
48 void AssemblerX86::call(Label *label) {
49 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
50 EmitUint8(0xE8);
51 static const int kSize = 5;
52 EmitLabel(label, kSize);
53 }
54
55 void AssemblerX86::call(const ConstantRelocatable *label) {
56 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
57 intptr_t call_start = buffer_.GetPosition();
58 EmitUint8(0xE8);
59 // TODO(jvoung): Actually track the label of the relocation.
60 (void)label;
61 EmitFixup(new (this->Allocate<DirectCallRelocation>())
62 DirectCallRelocation());
63 EmitInt32(-4);
64 assert((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
65 }
66
67 void AssemblerX86::pushl(Register reg) {
68 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
69 EmitUint8(0x50 + reg);
70 }
71
72 void AssemblerX86::pushl(const Address &address) {
73 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
74 EmitUint8(0xFF);
75 EmitOperand(6, address);
76 }
77
78 void AssemblerX86::pushl(const Immediate &imm) {
79 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
80 EmitUint8(0x68);
81 EmitImmediate(imm);
82 }
83
84 void AssemblerX86::popl(Register reg) {
85 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
86 EmitUint8(0x58 + reg);
87 }
88
89 void AssemblerX86::popl(const Address &address) {
90 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
91 EmitUint8(0x8F);
92 EmitOperand(0, address);
93 }
94
95 void AssemblerX86::pushal() {
96 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
97 EmitUint8(0x60);
98 }
99
100 void AssemblerX86::popal() {
101 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
102 EmitUint8(0x61);
103 }
104
105 void AssemblerX86::setcc(Condition condition, ByteRegister dst) {
106 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
107 EmitUint8(0x0F);
108 EmitUint8(0x90 + condition);
109 EmitUint8(0xC0 + dst);
110 }
111
112 void AssemblerX86::movl(Register dst, const Immediate &imm) {
113 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
114 EmitUint8(0xB8 + dst);
115 EmitImmediate(imm);
116 }
117
118 void AssemblerX86::movl(Register dst, Register src) {
119 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
120 EmitUint8(0x89);
121 EmitRegisterOperand(src, dst);
122 }
123
124 void AssemblerX86::movl(Register dst, const Address &src) {
125 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
126 EmitUint8(0x8B);
127 EmitOperand(dst, src);
128 }
129
130 void AssemblerX86::movl(const Address &dst, Register src) {
131 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
132 EmitUint8(0x89);
133 EmitOperand(src, dst);
134 }
135
136 void AssemblerX86::movl(const Address &dst, const Immediate &imm) {
137 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
138 EmitUint8(0xC7);
139 EmitOperand(0, dst);
140 EmitImmediate(imm);
141 }
142
143 void AssemblerX86::movzxb(Register dst, ByteRegister src) {
144 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
145 EmitUint8(0x0F);
146 EmitUint8(0xB6);
147 EmitRegisterOperand(dst, src);
148 }
149
150 void AssemblerX86::movzxb(Register dst, const Address &src) {
151 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
152 EmitUint8(0x0F);
153 EmitUint8(0xB6);
154 EmitOperand(dst, src);
155 }
156
157 void AssemblerX86::movsxb(Register dst, ByteRegister src) {
158 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
159 EmitUint8(0x0F);
160 EmitUint8(0xBE);
161 EmitRegisterOperand(dst, src);
162 }
163
164 void AssemblerX86::movsxb(Register dst, const Address &src) {
165 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
166 EmitUint8(0x0F);
167 EmitUint8(0xBE);
168 EmitOperand(dst, src);
169 }
170
171 void AssemblerX86::movb(ByteRegister dst, const Address &src) {
172 (void)dst;
173 (void)src;
174 // FATAL
175 llvm_unreachable("Use movzxb or movsxb instead.");
176 }
177
178 void AssemblerX86::movb(const Address &dst, ByteRegister src) {
179 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
180 EmitUint8(0x88);
181 EmitOperand(src, dst);
182 }
183
184 void AssemblerX86::movb(const Address &dst, const Immediate &imm) {
185 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
186 EmitUint8(0xC6);
187 EmitOperand(EAX, dst);
188 assert(imm.is_int8());
189 EmitUint8(imm.value() & 0xFF);
190 }
191
192 void AssemblerX86::movzxw(Register dst, Register src) {
193 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
194 EmitUint8(0x0F);
195 EmitUint8(0xB7);
196 EmitRegisterOperand(dst, src);
197 }
198
199 void AssemblerX86::movzxw(Register dst, const Address &src) {
200 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
201 EmitUint8(0x0F);
202 EmitUint8(0xB7);
203 EmitOperand(dst, src);
204 }
205
206 void AssemblerX86::movsxw(Register dst, Register src) {
207 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
208 EmitUint8(0x0F);
209 EmitUint8(0xBF);
210 EmitRegisterOperand(dst, src);
211 }
212
213 void AssemblerX86::movsxw(Register dst, const Address &src) {
214 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
215 EmitUint8(0x0F);
216 EmitUint8(0xBF);
217 EmitOperand(dst, src);
218 }
219
220 void AssemblerX86::movw(Register dst, const Address &src) {
221 (void)dst;
222 (void)src;
223 // FATAL
224 llvm_unreachable("Use movzxw or movsxw instead.");
225 }
226
227 void AssemblerX86::movw(const Address &dst, Register src) {
228 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
229 EmitOperandSizeOverride();
230 EmitUint8(0x89);
231 EmitOperand(src, dst);
232 }
233
234 void AssemblerX86::leal(Register dst, const Address &src) {
235 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
236 EmitUint8(0x8D);
237 EmitOperand(dst, src);
238 }
239
240 void AssemblerX86::cmov(Condition cond, Register dst, Register src) {
241 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
242 EmitUint8(0x0F);
243 EmitUint8(0x40 + cond);
244 EmitRegisterOperand(dst, src);
245 }
246
247 void AssemblerX86::rep_movsb() {
248 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
249 EmitUint8(0xF3);
250 EmitUint8(0xA4);
251 }
252
253 void AssemblerX86::movss(XmmRegister dst, const Address &src) {
254 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
255 EmitUint8(0xF3);
256 EmitUint8(0x0F);
257 EmitUint8(0x10);
258 EmitOperand(dst, src);
259 }
260
261 void AssemblerX86::movss(const Address &dst, XmmRegister src) {
262 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
263 EmitUint8(0xF3);
264 EmitUint8(0x0F);
265 EmitUint8(0x11);
266 EmitOperand(src, dst);
267 }
268
269 void AssemblerX86::movss(XmmRegister dst, XmmRegister src) {
270 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
271 EmitUint8(0xF3);
272 EmitUint8(0x0F);
273 EmitUint8(0x11);
274 EmitXmmRegisterOperand(src, dst);
275 }
276
277 void AssemblerX86::movd(XmmRegister dst, Register src) {
278 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
279 EmitUint8(0x66);
280 EmitUint8(0x0F);
281 EmitUint8(0x6E);
282 EmitOperand(dst, Operand(src));
283 }
284
285 void AssemblerX86::movd(Register dst, XmmRegister src) {
286 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
287 EmitUint8(0x66);
288 EmitUint8(0x0F);
289 EmitUint8(0x7E);
290 EmitOperand(src, Operand(dst));
291 }
292
293 void AssemblerX86::movq(const Address &dst, XmmRegister src) {
294 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
295 EmitUint8(0x66);
296 EmitUint8(0x0F);
297 EmitUint8(0xD6);
298 EmitOperand(src, Operand(dst));
299 }
300
301 void AssemblerX86::movq(XmmRegister dst, const Address &src) {
302 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
303 EmitUint8(0xF3);
304 EmitUint8(0x0F);
305 EmitUint8(0x7E);
306 EmitOperand(dst, Operand(src));
307 }
308
309 // TODO(jvoung): In these xmm1, xmm2/mXX cases, the opcodes don't vary
310 // based on operand-type. Should we just have an "addss_start()" method,
311 // and then the caller can do EmitXmmRegisterOperand(dst, src)
312 // or EmitOperand(dst, src)? Then we don't have to fill in the missing
313 // variants which only handle Xmm, Xmm (but not Xmm, mXX).
314 // Only thing is we'll be diverging, and we'll end up making the
315 // EmitXmmRegisterOperand, etc. public instead of private.
316
317 void AssemblerX86::addss(XmmRegister dst, XmmRegister src) {
318 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
319 EmitUint8(0xF3);
320 EmitUint8(0x0F);
321 EmitUint8(0x58);
322 EmitXmmRegisterOperand(dst, src);
323 }
324
325 void AssemblerX86::addss(XmmRegister dst, const Address &src) {
326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
327 EmitUint8(0xF3);
328 EmitUint8(0x0F);
329 EmitUint8(0x58);
330 EmitOperand(dst, src);
331 }
332
333 void AssemblerX86::subss(XmmRegister dst, XmmRegister src) {
334 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
335 EmitUint8(0xF3);
336 EmitUint8(0x0F);
337 EmitUint8(0x5C);
338 EmitXmmRegisterOperand(dst, src);
339 }
340
341 void AssemblerX86::subss(XmmRegister dst, const Address &src) {
342 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
343 EmitUint8(0xF3);
344 EmitUint8(0x0F);
345 EmitUint8(0x5C);
346 EmitOperand(dst, src);
347 }
348
349 void AssemblerX86::mulss(XmmRegister dst, XmmRegister src) {
350 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
351 EmitUint8(0xF3);
352 EmitUint8(0x0F);
353 EmitUint8(0x59);
354 EmitXmmRegisterOperand(dst, src);
355 }
356
357 void AssemblerX86::mulss(XmmRegister dst, const Address &src) {
358 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
359 EmitUint8(0xF3);
360 EmitUint8(0x0F);
361 EmitUint8(0x59);
362 EmitOperand(dst, src);
363 }
364
365 void AssemblerX86::divss(XmmRegister dst, XmmRegister src) {
366 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
367 EmitUint8(0xF3);
368 EmitUint8(0x0F);
369 EmitUint8(0x5E);
370 EmitXmmRegisterOperand(dst, src);
371 }
372
373 void AssemblerX86::divss(XmmRegister dst, const Address &src) {
374 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
375 EmitUint8(0xF3);
376 EmitUint8(0x0F);
377 EmitUint8(0x5E);
378 EmitOperand(dst, src);
379 }
380
381 void AssemblerX86::flds(const Address &src) {
382 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
383 EmitUint8(0xD9);
384 EmitOperand(0, src);
385 }
386
387 void AssemblerX86::fstps(const Address &dst) {
388 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
389 EmitUint8(0xD9);
390 EmitOperand(3, dst);
391 }
392
393 void AssemblerX86::movsd(XmmRegister dst, const Address &src) {
394 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
395 EmitUint8(0xF2);
396 EmitUint8(0x0F);
397 EmitUint8(0x10);
398 EmitOperand(dst, src);
399 }
400
401 void AssemblerX86::movsd(const Address &dst, XmmRegister src) {
402 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
403 EmitUint8(0xF2);
404 EmitUint8(0x0F);
405 EmitUint8(0x11);
406 EmitOperand(src, dst);
407 }
408
409 void AssemblerX86::movsd(XmmRegister dst, XmmRegister src) {
410 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
411 EmitUint8(0xF2);
412 EmitUint8(0x0F);
413 EmitUint8(0x11);
414 EmitXmmRegisterOperand(src, dst);
415 }
416
417 void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) {
418 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
419 EmitUint8(0x0F);
420 EmitUint8(0x28);
421 EmitXmmRegisterOperand(dst, src);
422 }
423
424 void AssemblerX86::movups(XmmRegister dst, const Address &src) {
425 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
426 EmitUint8(0x0F);
427 EmitUint8(0x10);
428 EmitOperand(dst, src);
429 }
430
431 void AssemblerX86::movups(const Address &dst, XmmRegister src) {
432 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
433 EmitUint8(0x0F);
434 EmitUint8(0x11);
435 EmitOperand(src, dst);
436 }
437
438 void AssemblerX86::addsd(XmmRegister dst, XmmRegister src) {
439 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
440 EmitUint8(0xF2);
441 EmitUint8(0x0F);
442 EmitUint8(0x58);
443 EmitXmmRegisterOperand(dst, src);
444 }
445
446 void AssemblerX86::addsd(XmmRegister dst, const Address &src) {
447 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
448 EmitUint8(0xF2);
449 EmitUint8(0x0F);
450 EmitUint8(0x58);
451 EmitOperand(dst, src);
452 }
453
454 void AssemblerX86::addpl(XmmRegister dst, XmmRegister src) {
455 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
456 EmitUint8(0x66);
457 EmitUint8(0x0F);
458 EmitUint8(0xFE);
459 EmitXmmRegisterOperand(dst, src);
460 }
461
462 void AssemblerX86::subpl(XmmRegister dst, XmmRegister src) {
463 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
464 EmitUint8(0x66);
465 EmitUint8(0x0F);
466 EmitUint8(0xFA);
467 EmitXmmRegisterOperand(dst, src);
468 }
469
470 void AssemblerX86::addps(XmmRegister dst, XmmRegister src) {
471 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
472 EmitUint8(0x0F);
473 EmitUint8(0x58);
474 EmitXmmRegisterOperand(dst, src);
475 }
476
477 void AssemblerX86::addps(XmmRegister dst, const Address &src) {
478 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
479 EmitUint8(0x0F);
480 EmitUint8(0x58);
481 EmitOperand(dst, src);
482 }
483
484 void AssemblerX86::subps(XmmRegister dst, XmmRegister src) {
485 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
486 EmitUint8(0x0F);
487 EmitUint8(0x5C);
488 EmitXmmRegisterOperand(dst, src);
489 }
490
491 void AssemblerX86::subps(XmmRegister dst, const Address &src) {
492 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
493 EmitUint8(0x0F);
494 EmitUint8(0x5C);
495 EmitOperand(dst, src);
496 }
497
498 void AssemblerX86::divps(XmmRegister dst, XmmRegister src) {
499 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
500 EmitUint8(0x0F);
501 EmitUint8(0x5E);
502 EmitXmmRegisterOperand(dst, src);
503 }
504
505 void AssemblerX86::divps(XmmRegister dst, const Address &src) {
506 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
507 EmitUint8(0x0F);
508 EmitUint8(0x5E);
509 EmitOperand(dst, src);
510 }
511
512 void AssemblerX86::mulps(XmmRegister dst, XmmRegister src) {
513 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
514 EmitUint8(0x0F);
515 EmitUint8(0x59);
516 EmitXmmRegisterOperand(dst, src);
517 }
518
519 void AssemblerX86::mulps(XmmRegister dst, const Address &src) {
520 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
521 EmitUint8(0x0F);
522 EmitUint8(0x59);
523 EmitOperand(dst, src);
524 }
525
526 void AssemblerX86::minps(XmmRegister dst, XmmRegister src) {
527 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
528 EmitUint8(0x0F);
529 EmitUint8(0x5D);
530 EmitXmmRegisterOperand(dst, src);
531 }
532
533 void AssemblerX86::maxps(XmmRegister dst, XmmRegister src) {
534 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
535 EmitUint8(0x0F);
536 EmitUint8(0x5F);
537 EmitXmmRegisterOperand(dst, src);
538 }
539
540 void AssemblerX86::andps(XmmRegister dst, XmmRegister src) {
541 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
542 EmitUint8(0x0F);
543 EmitUint8(0x54);
544 EmitXmmRegisterOperand(dst, src);
545 }
546
547 void AssemblerX86::andps(XmmRegister dst, const Address &src) {
548 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
549 EmitUint8(0x0F);
550 EmitUint8(0x54);
551 EmitOperand(dst, src);
552 }
553
554 void AssemblerX86::orps(XmmRegister dst, XmmRegister src) {
555 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
556 EmitUint8(0x0F);
557 EmitUint8(0x56);
558 EmitXmmRegisterOperand(dst, src);
559 }
560
561 void AssemblerX86::notps(XmmRegister dst) {
562 static const struct ALIGN16 {
563 uint32_t a;
564 uint32_t b;
565 uint32_t c;
566 uint32_t d;
567 } float_not_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
568 xorps(dst,
569 Address::Absolute(reinterpret_cast<uintptr_t>(&float_not_constant)));
570 }
571
572 void AssemblerX86::negateps(XmmRegister dst) {
573 static const struct ALIGN16 {
574 uint32_t a;
575 uint32_t b;
576 uint32_t c;
577 uint32_t d;
578 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
579 xorps(dst,
580 Address::Absolute(reinterpret_cast<uintptr_t>(&float_negate_constant)));
581 }
582
583 void AssemblerX86::absps(XmmRegister dst) {
584 static const struct ALIGN16 {
585 uint32_t a;
586 uint32_t b;
587 uint32_t c;
588 uint32_t d;
589 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
590 andps(dst, Address::Absolute(
591 reinterpret_cast<uintptr_t>(&float_absolute_constant)));
592 }
593
594 void AssemblerX86::zerowps(XmmRegister dst) {
595 static const struct ALIGN16 {
596 uint32_t a;
597 uint32_t b;
598 uint32_t c;
599 uint32_t d;
600 } float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000};
601 andps(dst,
602 Address::Absolute(reinterpret_cast<uintptr_t>(&float_zerow_constant)));
603 }
604
605 void AssemblerX86::cmpps(XmmRegister dst, XmmRegister src,
606 uint8_t CmpCondition) {
607 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
608 EmitUint8(0x0F);
609 EmitUint8(0xC2);
610 EmitXmmRegisterOperand(dst, src);
611 EmitUint8(CmpCondition);
612 }
613
614 void AssemblerX86::cmpps(XmmRegister dst, const Address &src,
615 uint8_t CmpCondition) {
616 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
617 EmitUint8(0x0F);
618 EmitUint8(0xC2);
619 EmitOperand(dst, src);
620 EmitUint8(CmpCondition);
621 }
622
623 void AssemblerX86::sqrtps(XmmRegister dst) {
624 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
625 EmitUint8(0x0F);
626 EmitUint8(0x51);
627 EmitXmmRegisterOperand(dst, dst);
628 }
629
630 void AssemblerX86::rsqrtps(XmmRegister dst) {
631 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
632 EmitUint8(0x0F);
633 EmitUint8(0x52);
634 EmitXmmRegisterOperand(dst, dst);
635 }
636
637 void AssemblerX86::reciprocalps(XmmRegister dst) {
638 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
639 EmitUint8(0x0F);
640 EmitUint8(0x53);
641 EmitXmmRegisterOperand(dst, dst);
642 }
643
644 void AssemblerX86::movhlps(XmmRegister dst, XmmRegister src) {
645 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
646 EmitUint8(0x0F);
647 EmitUint8(0x12);
648 EmitXmmRegisterOperand(dst, src);
649 }
650
651 void AssemblerX86::movlhps(XmmRegister dst, XmmRegister src) {
652 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
653 EmitUint8(0x0F);
654 EmitUint8(0x16);
655 EmitXmmRegisterOperand(dst, src);
656 }
657
658 void AssemblerX86::unpcklps(XmmRegister dst, XmmRegister src) {
659 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
660 EmitUint8(0x0F);
661 EmitUint8(0x14);
662 EmitXmmRegisterOperand(dst, src);
663 }
664
665 void AssemblerX86::unpckhps(XmmRegister dst, XmmRegister src) {
666 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
667 EmitUint8(0x0F);
668 EmitUint8(0x15);
669 EmitXmmRegisterOperand(dst, src);
670 }
671
672 void AssemblerX86::unpcklpd(XmmRegister dst, XmmRegister src) {
673 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
674 EmitUint8(0x66);
675 EmitUint8(0x0F);
676 EmitUint8(0x14);
677 EmitXmmRegisterOperand(dst, src);
678 }
679
680 void AssemblerX86::unpckhpd(XmmRegister dst, XmmRegister src) {
681 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
682 EmitUint8(0x66);
683 EmitUint8(0x0F);
684 EmitUint8(0x15);
685 EmitXmmRegisterOperand(dst, src);
686 }
687
688 void AssemblerX86::set1ps(XmmRegister dst, Register tmp1,
689 const Immediate &imm) {
690 // Load 32-bit immediate value into tmp1.
691 movl(tmp1, imm);
692 // Move value from tmp1 into dst.
693 movd(dst, tmp1);
694 // Broadcast low lane into other three lanes.
695 shufps(dst, dst, Immediate(0x0));
696 }
697
698 void AssemblerX86::shufps(XmmRegister dst, XmmRegister src,
699 const Immediate &imm) {
700 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
701 EmitUint8(0x0F);
702 EmitUint8(0xC6);
703 EmitXmmRegisterOperand(dst, src);
704 assert(imm.is_uint8());
705 EmitUint8(imm.value());
706 }
707
708 void AssemblerX86::addpd(XmmRegister dst, XmmRegister src) {
709 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
710 EmitUint8(0x66);
711 EmitUint8(0x0F);
712 EmitUint8(0x58);
713 EmitXmmRegisterOperand(dst, src);
714 }
715
716 void AssemblerX86::negatepd(XmmRegister dst) {
717 static const struct ALIGN16 {
718 uint64_t a;
719 uint64_t b;
720 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL};
721 xorpd(dst, Address::Absolute(
722 reinterpret_cast<uintptr_t>(&double_negate_constant)));
723 }
724
725 void AssemblerX86::subpd(XmmRegister dst, XmmRegister src) {
726 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
727 EmitUint8(0x66);
728 EmitUint8(0x0F);
729 EmitUint8(0x5C);
730 EmitXmmRegisterOperand(dst, src);
731 }
732
733 void AssemblerX86::mulpd(XmmRegister dst, XmmRegister src) {
734 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
735 EmitUint8(0x66);
736 EmitUint8(0x0F);
737 EmitUint8(0x59);
738 EmitXmmRegisterOperand(dst, src);
739 }
740
741 void AssemblerX86::divpd(XmmRegister dst, XmmRegister src) {
742 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
743 EmitUint8(0x66);
744 EmitUint8(0x0F);
745 EmitUint8(0x5E);
746 EmitXmmRegisterOperand(dst, src);
747 }
748
749 void AssemblerX86::abspd(XmmRegister dst) {
750 static const struct ALIGN16 {
751 uint64_t a;
752 uint64_t b;
753 } double_absolute_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
754 andpd(dst, Address::Absolute(
755 reinterpret_cast<uintptr_t>(&double_absolute_constant)));
756 }
757
758 void AssemblerX86::minpd(XmmRegister dst, XmmRegister src) {
759 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
760 EmitUint8(0x66);
761 EmitUint8(0x0F);
762 EmitUint8(0x5D);
763 EmitXmmRegisterOperand(dst, src);
764 }
765
766 void AssemblerX86::maxpd(XmmRegister dst, XmmRegister src) {
767 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
768 EmitUint8(0x66);
769 EmitUint8(0x0F);
770 EmitUint8(0x5F);
771 EmitXmmRegisterOperand(dst, src);
772 }
773
774 void AssemblerX86::sqrtpd(XmmRegister dst) {
775 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
776 EmitUint8(0x66);
777 EmitUint8(0x0F);
778 EmitUint8(0x51);
779 EmitXmmRegisterOperand(dst, dst);
780 }
781
782 void AssemblerX86::cvtps2pd(XmmRegister dst, XmmRegister src) {
783 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
784 EmitUint8(0x0F);
785 EmitUint8(0x5A);
786 EmitXmmRegisterOperand(dst, src);
787 }
788
789 void AssemblerX86::cvtpd2ps(XmmRegister dst, XmmRegister src) {
790 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
791 EmitUint8(0x66);
792 EmitUint8(0x0F);
793 EmitUint8(0x5A);
794 EmitXmmRegisterOperand(dst, src);
795 }
796
797 void AssemblerX86::shufpd(XmmRegister dst, XmmRegister src,
798 const Immediate &imm) {
799 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
800 EmitUint8(0x66);
801 EmitUint8(0x0F);
802 EmitUint8(0xC6);
803 EmitXmmRegisterOperand(dst, src);
804 assert(imm.is_uint8());
805 EmitUint8(imm.value());
806 }
807
808 void AssemblerX86::subsd(XmmRegister dst, XmmRegister src) {
809 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
810 EmitUint8(0xF2);
811 EmitUint8(0x0F);
812 EmitUint8(0x5C);
813 EmitXmmRegisterOperand(dst, src);
814 }
815
816 void AssemblerX86::subsd(XmmRegister dst, const Address &src) {
817 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
818 EmitUint8(0xF2);
819 EmitUint8(0x0F);
820 EmitUint8(0x5C);
821 EmitOperand(dst, src);
822 }
823
824 void AssemblerX86::mulsd(XmmRegister dst, XmmRegister src) {
825 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
826 EmitUint8(0xF2);
827 EmitUint8(0x0F);
828 EmitUint8(0x59);
829 EmitXmmRegisterOperand(dst, src);
830 }
831
832 void AssemblerX86::mulsd(XmmRegister dst, const Address &src) {
833 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
834 EmitUint8(0xF2);
835 EmitUint8(0x0F);
836 EmitUint8(0x59);
837 EmitOperand(dst, src);
838 }
839
840 void AssemblerX86::divsd(XmmRegister dst, XmmRegister src) {
841 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
842 EmitUint8(0xF2);
843 EmitUint8(0x0F);
844 EmitUint8(0x5E);
845 EmitXmmRegisterOperand(dst, src);
846 }
847
848 void AssemblerX86::divsd(XmmRegister dst, const Address &src) {
849 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
850 EmitUint8(0xF2);
851 EmitUint8(0x0F);
852 EmitUint8(0x5E);
853 EmitOperand(dst, src);
854 }
855
856 void AssemblerX86::cvtsi2ss(XmmRegister dst, Register src) {
857 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
858 EmitUint8(0xF3);
859 EmitUint8(0x0F);
860 EmitUint8(0x2A);
861 EmitOperand(dst, Operand(src));
862 }
863
864 void AssemblerX86::cvtsi2sd(XmmRegister dst, Register src) {
865 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
866 EmitUint8(0xF2);
867 EmitUint8(0x0F);
868 EmitUint8(0x2A);
869 EmitOperand(dst, Operand(src));
870 }
871
872 void AssemblerX86::cvtss2si(Register dst, XmmRegister src) {
873 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
874 EmitUint8(0xF3);
875 EmitUint8(0x0F);
876 EmitUint8(0x2D);
877 EmitXmmRegisterOperand(dst, src);
878 }
879
880 void AssemblerX86::cvtss2sd(XmmRegister dst, XmmRegister src) {
881 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
882 EmitUint8(0xF3);
883 EmitUint8(0x0F);
884 EmitUint8(0x5A);
885 EmitXmmRegisterOperand(dst, src);
886 }
887
888 void AssemblerX86::cvtsd2si(Register dst, XmmRegister src) {
889 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
890 EmitUint8(0xF2);
891 EmitUint8(0x0F);
892 EmitUint8(0x2D);
893 EmitXmmRegisterOperand(dst, src);
894 }
895
896 void AssemblerX86::cvttss2si(Register dst, XmmRegister src) {
897 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
898 EmitUint8(0xF3);
899 EmitUint8(0x0F);
900 EmitUint8(0x2C);
901 EmitXmmRegisterOperand(dst, src);
902 }
903
904 void AssemblerX86::cvttsd2si(Register dst, XmmRegister src) {
905 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
906 EmitUint8(0xF2);
907 EmitUint8(0x0F);
908 EmitUint8(0x2C);
909 EmitXmmRegisterOperand(dst, src);
910 }
911
912 void AssemblerX86::cvtsd2ss(XmmRegister dst, XmmRegister src) {
913 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
914 EmitUint8(0xF2);
915 EmitUint8(0x0F);
916 EmitUint8(0x5A);
917 EmitXmmRegisterOperand(dst, src);
918 }
919
920 void AssemblerX86::cvtdq2pd(XmmRegister dst, XmmRegister src) {
921 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
922 EmitUint8(0xF3);
923 EmitUint8(0x0F);
924 EmitUint8(0xE6);
925 EmitXmmRegisterOperand(dst, src);
926 }
927
928 void AssemblerX86::ucomiss(XmmRegister a, XmmRegister b) {
929 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
930 EmitUint8(0x0F);
931 EmitUint8(0x2E);
932 EmitXmmRegisterOperand(a, b);
933 }
934
935 void AssemblerX86::ucomiss(XmmRegister a, const Address &b) {
936 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
937 EmitUint8(0x0F);
938 EmitUint8(0x2E);
939 EmitOperand(a, b);
940 }
941
942 void AssemblerX86::ucomisd(XmmRegister a, XmmRegister b) {
943 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
944 EmitUint8(0x66);
945 EmitUint8(0x0F);
946 EmitUint8(0x2E);
947 EmitXmmRegisterOperand(a, b);
948 }
949
950 void AssemblerX86::ucomisd(XmmRegister a, const Address &b) {
951 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
952 EmitUint8(0x66);
953 EmitUint8(0x0F);
954 EmitUint8(0x2E);
955 EmitOperand(a, b);
956 }
957
958 void AssemblerX86::movmskpd(Register dst, XmmRegister src) {
959 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
960 EmitUint8(0x66);
961 EmitUint8(0x0F);
962 EmitUint8(0x50);
963 EmitXmmRegisterOperand(dst, src);
964 }
965
966 void AssemblerX86::movmskps(Register dst, XmmRegister src) {
967 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
968 EmitUint8(0x0F);
969 EmitUint8(0x50);
970 EmitXmmRegisterOperand(dst, src);
971 }
972
973 void AssemblerX86::sqrtsd(XmmRegister dst, const Address &src) {
974 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
975 EmitUint8(0xF2);
976 EmitUint8(0x0F);
977 EmitUint8(0x51);
978 EmitOperand(dst, src);
979 }
980
981 void AssemblerX86::sqrtsd(XmmRegister dst, XmmRegister src) {
982 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
983 EmitUint8(0xF2);
984 EmitUint8(0x0F);
985 EmitUint8(0x51);
986 EmitXmmRegisterOperand(dst, src);
987 }
988
989 void AssemblerX86::sqrtss(XmmRegister dst, const Address &src) {
990 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
991 EmitUint8(0xF3);
992 EmitUint8(0x0F);
993 EmitUint8(0x51);
994 EmitOperand(dst, src);
995 }
996
997 void AssemblerX86::sqrtss(XmmRegister dst, XmmRegister src) {
998 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
999 EmitUint8(0xF3);
1000 EmitUint8(0x0F);
1001 EmitUint8(0x51);
1002 EmitXmmRegisterOperand(dst, src);
1003 }
1004
1005 void AssemblerX86::xorpd(XmmRegister dst, const Address &src) {
1006 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1007 EmitUint8(0x66);
1008 EmitUint8(0x0F);
1009 EmitUint8(0x57);
1010 EmitOperand(dst, src);
1011 }
1012
1013 void AssemblerX86::xorpd(XmmRegister dst, XmmRegister src) {
1014 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1015 EmitUint8(0x66);
1016 EmitUint8(0x0F);
1017 EmitUint8(0x57);
1018 EmitXmmRegisterOperand(dst, src);
1019 }
1020
1021 void AssemblerX86::orpd(XmmRegister dst, XmmRegister src) {
1022 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1023 EmitUint8(0x66);
1024 EmitUint8(0x0F);
1025 EmitUint8(0x56);
1026 EmitXmmRegisterOperand(dst, src);
1027 }
1028
1029 void AssemblerX86::xorps(XmmRegister dst, const Address &src) {
1030 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1031 EmitUint8(0x0F);
1032 EmitUint8(0x57);
1033 EmitOperand(dst, src);
1034 }
1035
1036 void AssemblerX86::xorps(XmmRegister dst, XmmRegister src) {
1037 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1038 EmitUint8(0x0F);
1039 EmitUint8(0x57);
1040 EmitXmmRegisterOperand(dst, src);
1041 }
1042
1043 void AssemblerX86::andpd(XmmRegister dst, const Address &src) {
1044 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1045 EmitUint8(0x66);
1046 EmitUint8(0x0F);
1047 EmitUint8(0x54);
1048 EmitOperand(dst, src);
1049 }
1050
1051 void AssemblerX86::andpd(XmmRegister dst, XmmRegister src) {
1052 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1053 EmitUint8(0x66);
1054 EmitUint8(0x0F);
1055 EmitUint8(0x54);
1056 EmitXmmRegisterOperand(dst, src);
1057 }
1058
1059 void AssemblerX86::pextrd(Register dst, XmmRegister src, const Immediate &imm) {
1060 // TODO(jvoung): Check Ice instead.
1061 // assert(TargetCPUFeatures::sse4_1_supported());
1062 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1063 EmitUint8(0x66);
1064 EmitUint8(0x0F);
1065 EmitUint8(0x3A);
1066 EmitUint8(0x16);
1067 EmitOperand(src, Operand(dst));
1068 assert(imm.is_uint8());
1069 EmitUint8(imm.value());
1070 }
1071
1072 void AssemblerX86::pmovsxdq(XmmRegister dst, XmmRegister src) {
1073 // assert(TargetCPUFeatures::sse4_1_supported());
1074 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1075 EmitUint8(0x66);
1076 EmitUint8(0x0F);
1077 EmitUint8(0x38);
1078 EmitUint8(0x25);
1079 EmitXmmRegisterOperand(dst, src);
1080 }
1081
1082 void AssemblerX86::pcmpeqq(XmmRegister dst, XmmRegister src) {
1083 // assert(TargetCPUFeatures::sse4_1_supported());
1084 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1085 EmitUint8(0x66);
1086 EmitUint8(0x0F);
1087 EmitUint8(0x38);
1088 EmitUint8(0x29);
1089 EmitXmmRegisterOperand(dst, src);
1090 }
1091
1092 void AssemblerX86::pxor(XmmRegister dst, XmmRegister src) {
1093 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1094 EmitUint8(0x66);
1095 EmitUint8(0x0F);
1096 EmitUint8(0xEF);
1097 EmitXmmRegisterOperand(dst, src);
1098 }
1099
1100 void AssemblerX86::roundsd(XmmRegister dst, XmmRegister src,
1101 RoundingMode mode) {
1102 // assert(TargetCPUFeatures::sse4_1_supported());
1103 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1104 EmitUint8(0x66);
1105 EmitUint8(0x0F);
1106 EmitUint8(0x3A);
1107 EmitUint8(0x0B);
1108 EmitXmmRegisterOperand(dst, src);
1109 // Mask precision exeption.
1110 EmitUint8(static_cast<uint8_t>(mode) | 0x8);
1111 }
1112
1113 void AssemblerX86::fldl(const Address &src) {
1114 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1115 EmitUint8(0xDD);
1116 EmitOperand(0, src);
1117 }
1118
1119 void AssemblerX86::fstpl(const Address &dst) {
1120 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1121 EmitUint8(0xDD);
1122 EmitOperand(3, dst);
1123 }
1124
1125 void AssemblerX86::fnstcw(const Address &dst) {
1126 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1127 EmitUint8(0xD9);
1128 EmitOperand(7, dst);
1129 }
1130
1131 void AssemblerX86::fldcw(const Address &src) {
1132 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1133 EmitUint8(0xD9);
1134 EmitOperand(5, src);
1135 }
1136
1137 void AssemblerX86::fistpl(const Address &dst) {
1138 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1139 EmitUint8(0xDF);
1140 EmitOperand(7, dst);
1141 }
1142
1143 void AssemblerX86::fistps(const Address &dst) {
1144 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1145 EmitUint8(0xDB);
1146 EmitOperand(3, dst);
1147 }
1148
1149 void AssemblerX86::fildl(const Address &src) {
1150 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1151 EmitUint8(0xDF);
1152 EmitOperand(5, src);
1153 }
1154
1155 void AssemblerX86::filds(const Address &src) {
1156 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1157 EmitUint8(0xDB);
1158 EmitOperand(0, src);
1159 }
1160
1161 void AssemblerX86::fincstp() {
1162 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1163 EmitUint8(0xD9);
1164 EmitUint8(0xF7);
1165 }
1166
1167 void AssemblerX86::xchgl(Register dst, Register src) {
1168 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1169 EmitUint8(0x87);
1170 EmitRegisterOperand(dst, src);
1171 }
1172
1173 void AssemblerX86::cmp(Type Ty, Register reg, const Immediate &imm) {
1174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1175 if (typeWidthInBytes(Ty) == 1) {
1176 EmitComplexI8(7, Operand(reg), imm);
1177 return;
1178 }
1179 if (Ty == IceType_i16)
1180 EmitOperandSizeOverride();
1181 EmitComplex(7, Operand(reg), imm);
1182 }
1183
1184 void AssemblerX86::cmp(Type Ty, Register reg0, Register reg1) {
1185 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1186 if (typeWidthInBytes(Ty) == 1) {
1187 EmitUint8(0x3A);
1188 } else if (Ty == IceType_i16) {
1189 EmitOperandSizeOverride();
1190 EmitUint8(0x3B);
1191 } else {
1192 EmitUint8(0x3B);
1193 }
1194 EmitRegisterOperand(reg0, reg1);
1195 }
1196
1197 void AssemblerX86::cmp(Type Ty, Register reg, const Address &address) {
1198 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1199 if (typeWidthInBytes(Ty) == 1) {
1200 EmitUint8(0x3A);
1201 } else if (Ty == IceType_i16) {
1202 EmitOperandSizeOverride();
1203 EmitUint8(0x3B);
1204 } else {
1205 EmitUint8(0x3B);
1206 }
1207 EmitOperand(reg, address);
1208 }
1209
1210 void AssemblerX86::cmp(Type Ty, const Address &address, Register reg) {
1211 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1212 if (typeWidthInBytes(Ty) == 1) {
1213 EmitUint8(0x38);
1214 } else if (Ty == IceType_i16) {
1215 EmitOperandSizeOverride();
1216 EmitUint8(0x39);
1217 } else {
1218 EmitUint8(0x39);
1219 }
1220 EmitOperand(reg, address);
1221 }
1222
1223 void AssemblerX86::cmp(Type Ty, const Address &address, const Immediate &imm) {
1224 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1225 if (typeWidthInBytes(Ty) == 1) {
1226 EmitComplexI8(7, address, imm);
1227 return;
1228 }
1229 if (Ty == IceType_i16)
1230 EmitOperandSizeOverride();
1231 EmitComplex(7, address, imm);
1232 }
1233
1234 void AssemblerX86::testl(Register reg1, Register reg2) {
1235 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1236 EmitUint8(0x85);
1237 EmitRegisterOperand(reg1, reg2);
1238 }
1239
1240 void AssemblerX86::testl(Register reg, const Immediate &immediate) {
1241 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1242 // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
1243 // we only test the byte register to keep the encoding short.
1244 if (immediate.is_uint8() && reg < 4) {
1245 // Use zero-extended 8-bit immediate.
1246 if (reg == EAX) {
1247 EmitUint8(0xA8);
1248 } else {
1249 EmitUint8(0xF6);
1250 EmitUint8(0xC0 + reg);
1251 }
1252 EmitUint8(immediate.value() & 0xFF);
1253 } else if (reg == EAX) {
1254 // Use short form if the destination is EAX.
1255 EmitUint8(0xA9);
1256 EmitImmediate(immediate);
1257 } else {
1258 EmitUint8(0xF7);
1259 EmitOperand(0, Operand(reg));
1260 EmitImmediate(immediate);
1261 }
1262 }
1263
1264 void AssemblerX86::_and(Type Ty, Register dst, Register src) {
1265 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1266 if (typeWidthInBytes(Ty) == 1) {
1267 EmitUint8(0x22);
1268 } else if (Ty == IceType_i16) {
1269 EmitOperandSizeOverride();
1270 EmitUint8(0x23);
1271 } else {
1272 EmitUint8(0x23);
1273 }
1274 EmitRegisterOperand(dst, src);
1275 }
1276
1277 void AssemblerX86::_and(Type Ty, Register reg, const Immediate &imm) {
1278 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1279 if (typeWidthInBytes(Ty) == 1) {
1280 EmitComplexI8(4, Operand(reg), imm);
1281 return;
1282 }
1283 if (Ty == IceType_i16)
1284 EmitOperandSizeOverride();
1285 EmitComplex(4, Operand(reg), imm);
1286 }
1287
1288 void AssemblerX86::_and(Type Ty, Register dst, const Address &address) {
1289 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1290 if (typeWidthInBytes(Ty) == 1) {
1291 EmitUint8(0x22);
1292 } else if (Ty == IceType_i16) {
1293 EmitOperandSizeOverride();
1294 EmitUint8(0x23);
1295 } else {
1296 EmitUint8(0x23);
1297 }
1298 EmitOperand(dst, address);
1299 }
1300
1301 void AssemblerX86::_or(Type Ty, Register dst, Register src) {
1302 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1303 if (typeWidthInBytes(Ty) == 1) {
1304 EmitUint8(0x0A);
1305 } else if (Ty == IceType_i16) {
1306 EmitOperandSizeOverride();
1307 EmitUint8(0x0B);
1308 } else {
1309 EmitUint8(0x0B);
1310 }
1311 EmitRegisterOperand(dst, src);
1312 }
1313
1314 void AssemblerX86::_or(Type Ty, Register reg, const Immediate &imm) {
1315 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1316 if (typeWidthInBytes(Ty) == 1) {
1317 EmitComplexI8(1, Operand(reg), imm);
1318 return;
1319 }
1320 if (Ty == IceType_i16)
1321 EmitOperandSizeOverride();
1322 EmitComplex(1, Operand(reg), imm);
1323 }
1324
1325 void AssemblerX86::_or(Type Ty, Register dst, const Address &address) {
1326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1327 if (typeWidthInBytes(Ty) == 1) {
1328 EmitUint8(0x0A);
1329 } else if (Ty == IceType_i16) {
1330 EmitOperandSizeOverride();
1331 EmitUint8(0x0B);
1332 } else {
1333 EmitUint8(0x0B);
1334 }
1335 EmitOperand(dst, address);
1336 }
1337
1338 void AssemblerX86::_xor(Type Ty, Register dst, Register src) {
1339 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1340 if (typeWidthInBytes(Ty) == 1) {
1341 EmitUint8(0x32);
1342 } else if (Ty == IceType_i16) {
1343 EmitOperandSizeOverride();
1344 EmitUint8(0x33);
1345 } else {
1346 EmitUint8(0x33);
1347 }
1348 EmitRegisterOperand(dst, src);
1349 }
1350
1351 void AssemblerX86::_xor(Type Ty, Register reg, const Immediate &imm) {
1352 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1353 if (typeWidthInBytes(Ty) == 1) {
1354 EmitComplexI8(6, Operand(reg), imm);
1355 return;
1356 }
1357 if (Ty == IceType_i16)
1358 EmitOperandSizeOverride();
1359 EmitComplex(6, Operand(reg), imm);
1360 }
1361
1362 void AssemblerX86::_xor(Type Ty, Register dst, const Address &address) {
1363 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1364 if (typeWidthInBytes(Ty) == 1) {
1365 EmitUint8(0x32);
1366 } else if (Ty == IceType_i16) {
1367 EmitOperandSizeOverride();
1368 EmitUint8(0x33);
1369 } else {
1370 EmitUint8(0x33);
1371 }
1372 EmitOperand(dst, address);
1373 }
1374
1375 void AssemblerX86::add(Type Ty, Register reg, const Immediate &imm) {
1376 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1377 if (typeWidthInBytes(Ty) == 1) {
1378 EmitComplexI8(0, Operand(reg), imm);
1379 return;
1380 }
1381 if (Ty == IceType_i16)
1382 EmitOperandSizeOverride();
1383 EmitComplex(0, Operand(reg), imm);
1384 }
1385
1386 void AssemblerX86::add(Type Ty, const Address &address, Register reg) {
1387 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1388 if (typeWidthInBytes(Ty) == 1) {
1389 EmitUint8(0x00);
1390 } else if (Ty == IceType_i16) {
1391 EmitOperandSizeOverride();
1392 EmitUint8(0x01);
1393 } else {
1394 EmitUint8(0x01);
1395 }
1396 EmitOperand(reg, address);
1397 }
1398
1399 void AssemblerX86::add(Type Ty, const Address &address, const Immediate &imm) {
1400 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1401 if (typeWidthInBytes(Ty) == 1) {
1402 EmitComplexI8(0, address, imm);
1403 return;
1404 }
1405 if (Ty == IceType_i16)
1406 EmitOperandSizeOverride();
1407 EmitComplex(0, address, imm);
1408 }
1409
1410 // TODO(jvoung): In these cases, Reg-Reg and Reg-Mem are very similar.
1411 // Instead of using EmitRegisterOperand() it is possible to use
1412 // EmitOperand(dst, Operand(src)), and then they would be identical.
1413 // Then the only outlier is Reg-Imm.
1414
1415 void AssemblerX86::add(Type Ty, Register dst, Register src) {
1416 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1417 if (typeWidthInBytes(Ty) == 1) {
1418 EmitUint8(0x02);
1419 } else if (Ty == IceType_i16) {
1420 EmitOperandSizeOverride();
1421 EmitUint8(0x03);
1422 } else {
1423 EmitUint8(0x03);
1424 }
1425 EmitRegisterOperand(dst, src);
1426 }
1427
1428 void AssemblerX86::add(Type Ty, Register reg, const Address &address) {
1429 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1430 if (typeWidthInBytes(Ty) == 1) {
1431 EmitUint8(0x02);
1432 } else if (Ty == IceType_i16) {
1433 EmitOperandSizeOverride();
1434 EmitUint8(0x03);
1435 } else {
1436 EmitUint8(0x03);
1437 }
1438 EmitOperand(reg, address);
1439 }
1440
1441 void AssemblerX86::adc(Type Ty, Register reg, const Immediate &imm) {
1442 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1443 if (typeWidthInBytes(Ty) == 1) {
1444 EmitComplexI8(2, Operand(reg), imm);
1445 return;
1446 }
1447 if (Ty == IceType_i16)
1448 EmitOperandSizeOverride();
1449 EmitComplex(2, Operand(reg), imm);
1450 }
1451
1452 void AssemblerX86::adc(Type Ty, Register dst, Register src) {
1453 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1454 if (typeWidthInBytes(Ty) == 1) {
1455 EmitUint8(0x12);
1456 } else if (Ty == IceType_i16) {
1457 EmitOperandSizeOverride();
1458 EmitUint8(0x13);
1459 } else {
1460 EmitUint8(0x13);
1461 }
1462 EmitRegisterOperand(dst, src);
1463 }
1464
1465 void AssemblerX86::adc(Type Ty, Register dst, const Address &address) {
1466 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1467 if (typeWidthInBytes(Ty) == 1) {
1468 EmitUint8(0x12);
1469 } else if (Ty == IceType_i16) {
1470 EmitOperandSizeOverride();
1471 EmitUint8(0x13);
1472 } else {
1473 EmitUint8(0x13);
1474 }
1475 EmitOperand(dst, address);
1476 }
1477
1478 void AssemblerX86::sub(Type Ty, Register dst, Register src) {
1479 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1480 if (typeWidthInBytes(Ty) == 1) {
1481 EmitUint8(0x2A);
1482 } else if (Ty == IceType_i16) {
1483 EmitOperandSizeOverride();
1484 EmitUint8(0x2B);
1485 } else {
1486 EmitUint8(0x2B);
1487 }
1488 EmitRegisterOperand(dst, src);
1489 }
1490
1491 void AssemblerX86::sub(Type Ty, Register reg, const Immediate &imm) {
1492 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1493 if (typeWidthInBytes(Ty) == 1) {
1494 EmitComplexI8(5, Operand(reg), imm);
1495 return;
1496 }
1497 if (Ty == IceType_i16)
1498 EmitOperandSizeOverride();
1499 EmitComplex(5, Operand(reg), imm);
1500 }
1501
1502 void AssemblerX86::sub(Type Ty, Register reg, const Address &address) {
1503 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1504 if (typeWidthInBytes(Ty) == 1) {
1505 EmitUint8(0x2A);
1506 } else if (Ty == IceType_i16) {
1507 EmitOperandSizeOverride();
1508 EmitUint8(0x2B);
1509 } else {
1510 EmitUint8(0x2B);
1511 }
1512 EmitOperand(reg, address);
1513 }
1514
1515 void AssemblerX86::cbw() {
1516 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1517 EmitOperandSizeOverride();
1518 EmitUint8(0x98);
1519 }
1520
1521 void AssemblerX86::cwd() {
1522 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1523 EmitOperandSizeOverride();
1524 EmitUint8(0x99);
1525 }
1526
1527 void AssemblerX86::cdq() {
1528 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1529 EmitUint8(0x99);
1530 }
1531
1532 void AssemblerX86::idivl(Register reg) {
1533 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1534 EmitUint8(0xF7);
1535 EmitUint8(0xF8 | reg);
1536 }
1537
1538 void AssemblerX86::imull(Register dst, Register src) {
1539 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1540 EmitUint8(0x0F);
1541 EmitUint8(0xAF);
1542 EmitOperand(dst, Operand(src));
1543 }
1544
1545 void AssemblerX86::imull(Register reg, const Immediate &imm) {
1546 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1547 EmitUint8(0x69);
1548 EmitOperand(reg, Operand(reg));
1549 EmitImmediate(imm);
1550 }
1551
1552 void AssemblerX86::imull(Register reg, const Address &address) {
1553 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1554 EmitUint8(0x0F);
1555 EmitUint8(0xAF);
1556 EmitOperand(reg, address);
1557 }
1558
1559 void AssemblerX86::imull(Register reg) {
1560 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1561 EmitUint8(0xF7);
1562 EmitOperand(5, Operand(reg));
1563 }
1564
1565 void AssemblerX86::imull(const Address &address) {
1566 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1567 EmitUint8(0xF7);
1568 EmitOperand(5, address);
1569 }
1570
1571 void AssemblerX86::mull(Register reg) {
1572 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1573 EmitUint8(0xF7);
1574 EmitOperand(4, Operand(reg));
1575 }
1576
1577 void AssemblerX86::mull(const Address &address) {
1578 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1579 EmitUint8(0xF7);
1580 EmitOperand(4, address);
1581 }
1582
1583 void AssemblerX86::sbb(Type Ty, Register dst, Register src) {
1584 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1585 if (typeWidthInBytes(Ty) == 1) {
1586 EmitUint8(0x1A);
1587 } else if (Ty == IceType_i16) {
1588 EmitOperandSizeOverride();
1589 EmitUint8(0x1B);
1590 } else {
1591 EmitUint8(0x1B);
1592 }
1593 EmitRegisterOperand(dst, src);
1594 }
1595
1596 void AssemblerX86::sbb(Type Ty, Register reg, const Immediate &imm) {
1597 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1598 if (typeWidthInBytes(Ty) == 1) {
1599 EmitComplexI8(3, Operand(reg), imm);
1600 return;
1601 }
1602 if (Ty == IceType_i16)
1603 EmitOperandSizeOverride();
1604 EmitComplex(3, Operand(reg), imm);
1605 }
1606
1607 void AssemblerX86::sbb(Type Ty, Register dst, const Address &address) {
1608 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1609 if (typeWidthInBytes(Ty) == 1) {
1610 EmitUint8(0x1A);
1611 } else if (Ty == IceType_i16) {
1612 EmitOperandSizeOverride();
1613 EmitUint8(0x1B);
1614 } else {
1615 EmitUint8(0x1B);
1616 }
1617 EmitOperand(dst, address);
1618 }
1619
1620 void AssemblerX86::incl(Register reg) {
1621 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1622 EmitUint8(0x40 + reg);
1623 }
1624
1625 void AssemblerX86::incl(const Address &address) {
1626 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1627 EmitUint8(0xFF);
1628 EmitOperand(0, address);
1629 }
1630
1631 void AssemblerX86::decl(Register reg) {
1632 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1633 EmitUint8(0x48 + reg);
1634 }
1635
1636 void AssemblerX86::decl(const Address &address) {
1637 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1638 EmitUint8(0xFF);
1639 EmitOperand(1, address);
1640 }
1641
1642 void AssemblerX86::shll(Register reg, const Immediate &imm) {
1643 EmitGenericShift(4, reg, imm);
1644 }
1645
1646 void AssemblerX86::shll(Register operand, Register shifter) {
1647 EmitGenericShift(4, Operand(operand), shifter);
1648 }
1649
1650 void AssemblerX86::shll(const Address &operand, Register shifter) {
1651 EmitGenericShift(4, Operand(operand), shifter);
1652 }
1653
1654 void AssemblerX86::shrl(Register reg, const Immediate &imm) {
1655 EmitGenericShift(5, reg, imm);
1656 }
1657
1658 void AssemblerX86::shrl(Register operand, Register shifter) {
1659 EmitGenericShift(5, Operand(operand), shifter);
1660 }
1661
1662 void AssemblerX86::sarl(Register reg, const Immediate &imm) {
1663 EmitGenericShift(7, reg, imm);
1664 }
1665
1666 void AssemblerX86::sarl(Register operand, Register shifter) {
1667 EmitGenericShift(7, Operand(operand), shifter);
1668 }
1669
1670 void AssemblerX86::sarl(const Address &address, Register shifter) {
1671 EmitGenericShift(7, Operand(address), shifter);
1672 }
1673
1674 void AssemblerX86::shld(Register dst, Register src) {
1675 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1676 EmitUint8(0x0F);
1677 EmitUint8(0xA5);
1678 EmitRegisterOperand(src, dst);
1679 }
1680
1681 void AssemblerX86::shld(Register dst, Register src, const Immediate &imm) {
1682 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1683 assert(imm.is_int8());
1684 EmitUint8(0x0F);
1685 EmitUint8(0xA4);
1686 EmitRegisterOperand(src, dst);
1687 EmitUint8(imm.value() & 0xFF);
1688 }
1689
1690 void AssemblerX86::shld(const Address &operand, Register src) {
1691 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1692 EmitUint8(0x0F);
1693 EmitUint8(0xA5);
1694 EmitOperand(src, Operand(operand));
1695 }
1696
1697 void AssemblerX86::shrd(Register dst, Register src) {
1698 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1699 EmitUint8(0x0F);
1700 EmitUint8(0xAD);
1701 EmitRegisterOperand(src, dst);
1702 }
1703
1704 void AssemblerX86::shrd(Register dst, Register src, const Immediate &imm) {
1705 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1706 assert(imm.is_int8());
1707 EmitUint8(0x0F);
1708 EmitUint8(0xAC);
1709 EmitRegisterOperand(src, dst);
1710 EmitUint8(imm.value() & 0xFF);
1711 }
1712
1713 void AssemblerX86::shrd(const Address &dst, Register src) {
1714 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1715 EmitUint8(0x0F);
1716 EmitUint8(0xAD);
1717 EmitOperand(src, Operand(dst));
1718 }
1719
1720 void AssemblerX86::negl(Register reg) {
1721 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1722 EmitUint8(0xF7);
1723 EmitOperand(3, Operand(reg));
1724 }
1725
1726 void AssemblerX86::notl(Register reg) {
1727 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1728 EmitUint8(0xF7);
1729 EmitUint8(0xD0 | reg);
1730 }
1731
1732 void AssemblerX86::bsrl(Register dst, Register src) {
1733 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1734 EmitUint8(0x0F);
1735 EmitUint8(0xBD);
1736 EmitRegisterOperand(dst, src);
1737 }
1738
1739 void AssemblerX86::bt(Register base, Register offset) {
1740 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1741 EmitUint8(0x0F);
1742 EmitUint8(0xA3);
1743 EmitRegisterOperand(offset, base);
1744 }
1745
1746 void AssemblerX86::enter(const Immediate &imm) {
1747 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1748 EmitUint8(0xC8);
1749 assert(imm.is_uint16());
1750 EmitUint8(imm.value() & 0xFF);
1751 EmitUint8((imm.value() >> 8) & 0xFF);
1752 EmitUint8(0x00);
1753 }
1754
1755 void AssemblerX86::leave() {
1756 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1757 EmitUint8(0xC9);
1758 }
1759
1760 void AssemblerX86::ret() {
1761 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1762 EmitUint8(0xC3);
1763 }
1764
1765 void AssemblerX86::ret(const Immediate &imm) {
1766 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1767 EmitUint8(0xC2);
1768 assert(imm.is_uint16());
1769 EmitUint8(imm.value() & 0xFF);
1770 EmitUint8((imm.value() >> 8) & 0xFF);
1771 }
1772
1773 void AssemblerX86::nop(int size) {
1774 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1775 // There are nops up to size 15, but for now just provide up to size 8.
1776 assert(0 < size && size <= MAX_NOP_SIZE);
1777 switch (size) {
1778 case 1:
1779 EmitUint8(0x90);
1780 break;
1781 case 2:
1782 EmitUint8(0x66);
1783 EmitUint8(0x90);
1784 break;
1785 case 3:
1786 EmitUint8(0x0F);
1787 EmitUint8(0x1F);
1788 EmitUint8(0x00);
1789 break;
1790 case 4:
1791 EmitUint8(0x0F);
1792 EmitUint8(0x1F);
1793 EmitUint8(0x40);
1794 EmitUint8(0x00);
1795 break;
1796 case 5:
1797 EmitUint8(0x0F);
1798 EmitUint8(0x1F);
1799 EmitUint8(0x44);
1800 EmitUint8(0x00);
1801 EmitUint8(0x00);
1802 break;
1803 case 6:
1804 EmitUint8(0x66);
1805 EmitUint8(0x0F);
1806 EmitUint8(0x1F);
1807 EmitUint8(0x44);
1808 EmitUint8(0x00);
1809 EmitUint8(0x00);
1810 break;
1811 case 7:
1812 EmitUint8(0x0F);
1813 EmitUint8(0x1F);
1814 EmitUint8(0x80);
1815 EmitUint8(0x00);
1816 EmitUint8(0x00);
1817 EmitUint8(0x00);
1818 EmitUint8(0x00);
1819 break;
1820 case 8:
1821 EmitUint8(0x0F);
1822 EmitUint8(0x1F);
1823 EmitUint8(0x84);
1824 EmitUint8(0x00);
1825 EmitUint8(0x00);
1826 EmitUint8(0x00);
1827 EmitUint8(0x00);
1828 EmitUint8(0x00);
1829 break;
1830 default:
1831 llvm_unreachable("UNIMPLEMENTED");
1832 }
1833 }
1834
1835 void AssemblerX86::int3() {
1836 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1837 EmitUint8(0xCC);
1838 }
1839
1840 void AssemblerX86::hlt() {
1841 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1842 EmitUint8(0xF4);
1843 }
1844
1845 void AssemblerX86::j(Condition condition, Label *label, bool near) {
1846 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1847 if (label->IsBound()) {
1848 static const int kShortSize = 2;
1849 static const int kLongSize = 6;
1850 intptr_t offset = label->Position() - buffer_.Size();
1851 assert(offset <= 0);
1852 if (Utils::IsInt(8, offset - kShortSize)) {
1853 EmitUint8(0x70 + condition);
1854 EmitUint8((offset - kShortSize) & 0xFF);
1855 } else {
1856 EmitUint8(0x0F);
1857 EmitUint8(0x80 + condition);
1858 EmitInt32(offset - kLongSize);
1859 }
1860 } else if (near) {
1861 EmitUint8(0x70 + condition);
1862 EmitNearLabelLink(label);
1863 } else {
1864 EmitUint8(0x0F);
1865 EmitUint8(0x80 + condition);
1866 EmitLabelLink(label);
1867 }
1868 }
1869
1870 void AssemblerX86::j(Condition condition, const ConstantRelocatable *label) {
1871 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1872 EmitUint8(0x0F);
1873 EmitUint8(0x80 + condition);
1874 // TODO(jvoung): actually track the target.
1875 (void)label;
1876 EmitFixup(new (this->Allocate<DirectCallRelocation>())
1877 DirectCallRelocation());
1878 EmitInt32(-4);
1879 }
1880
1881 void AssemblerX86::jmp(Register reg) {
1882 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1883 EmitUint8(0xFF);
1884 EmitRegisterOperand(4, reg);
1885 }
1886
1887 void AssemblerX86::jmp(Label *label, bool near) {
1888 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1889 if (label->IsBound()) {
1890 static const int kShortSize = 2;
1891 static const int kLongSize = 5;
1892 intptr_t offset = label->Position() - buffer_.Size();
1893 assert(offset <= 0);
1894 if (Utils::IsInt(8, offset - kShortSize)) {
1895 EmitUint8(0xEB);
1896 EmitUint8((offset - kShortSize) & 0xFF);
1897 } else {
1898 EmitUint8(0xE9);
1899 EmitInt32(offset - kLongSize);
1900 }
1901 } else if (near) {
1902 EmitUint8(0xEB);
1903 EmitNearLabelLink(label);
1904 } else {
1905 EmitUint8(0xE9);
1906 EmitLabelLink(label);
1907 }
1908 }
1909
1910 void AssemblerX86::jmp(const ConstantRelocatable *label) {
1911 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1912 EmitUint8(0xE9);
1913 // TODO(jvoung): Actually track the target.
1914 (void)label;
1915 EmitFixup(new (this->Allocate<DirectCallRelocation>())
1916 DirectCallRelocation());
1917 EmitInt32(-4);
1918 }
1919
1920 void AssemblerX86::lock() {
1921 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1922 EmitUint8(0xF0);
1923 }
1924
1925 void AssemblerX86::cmpxchgl(const Address &address, Register reg) {
1926 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1927 EmitUint8(0x0F);
1928 EmitUint8(0xB1);
1929 EmitOperand(reg, address);
1930 }
1931
1932 void AssemblerX86::cpuid() {
1933 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1934 EmitUint8(0x0F);
1935 EmitUint8(0xA2);
1936 }
1937
1938 void AssemblerX86::AddImmediate(Register reg, const Immediate &imm) {
1939 const intptr_t value = imm.value();
1940 if (value == 0) {
1941 return;
1942 }
1943 if ((value > 0) || (value == std::numeric_limits<int32_t>::min())) {
1944 if (value == 1) {
1945 incl(reg);
1946 } else {
1947 add(IceType_i32, reg, imm);
1948 }
1949 } else {
1950 SubImmediate(reg, Immediate(-value));
1951 }
1952 }
1953
1954 void AssemblerX86::SubImmediate(Register reg, const Immediate &imm) {
1955 const intptr_t value = imm.value();
1956 if (value == 0) {
1957 return;
1958 }
1959 if ((value > 0) || (value == std::numeric_limits<int32_t>::min())) {
1960 if (value == 1) {
1961 decl(reg);
1962 } else {
1963 sub(IceType_i32, reg, imm);
1964 }
1965 } else {
1966 AddImmediate(reg, Immediate(-value));
1967 }
1968 }
1969
1970 void AssemblerX86::FloatNegate(XmmRegister f) {
1971 static const struct ALIGN16 {
1972 uint32_t a;
1973 uint32_t b;
1974 uint32_t c;
1975 uint32_t d;
1976 } float_negate_constant = {0x80000000, 0x00000000, 0x80000000, 0x00000000};
1977 xorps(f,
1978 Address::Absolute(reinterpret_cast<uintptr_t>(&float_negate_constant)));
1979 }
1980
1981 void AssemblerX86::DoubleNegate(XmmRegister d) {
1982 static const struct ALIGN16 {
1983 uint64_t a;
1984 uint64_t b;
1985 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL};
1986 xorpd(d, Address::Absolute(
1987 reinterpret_cast<uintptr_t>(&double_negate_constant)));
1988 }
1989
1990 void AssemblerX86::DoubleAbs(XmmRegister reg) {
1991 static const struct ALIGN16 {
1992 uint64_t a;
1993 uint64_t b;
1994 } double_abs_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
1995 andpd(reg,
1996 Address::Absolute(reinterpret_cast<uintptr_t>(&double_abs_constant)));
1997 }
1998
1999 void AssemblerX86::Align(intptr_t alignment, intptr_t offset) {
2000 assert(llvm::isPowerOf2_32(alignment));
2001 intptr_t pos = offset + buffer_.GetPosition();
2002 intptr_t mod = pos & (alignment - 1);
2003 if (mod == 0) {
2004 return;
2005 }
2006 intptr_t bytes_needed = alignment - mod;
2007 while (bytes_needed > MAX_NOP_SIZE) {
2008 nop(MAX_NOP_SIZE);
2009 bytes_needed -= MAX_NOP_SIZE;
2010 }
2011 if (bytes_needed) {
2012 nop(bytes_needed);
2013 }
2014 assert(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0);
2015 }
2016
2017 void AssemblerX86::Bind(Label *label) {
2018 intptr_t bound = buffer_.Size();
2019 assert(!label->IsBound()); // Labels can only be bound once.
2020 while (label->IsLinked()) {
2021 intptr_t position = label->LinkPosition();
2022 intptr_t next = buffer_.Load<int32_t>(position);
2023 buffer_.Store<int32_t>(position, bound - (position + 4));
2024 label->position_ = next;
2025 }
2026 while (label->HasNear()) {
2027 intptr_t position = label->NearPosition();
2028 intptr_t offset = bound - (position + 1);
2029 assert(Utils::IsInt(8, offset));
2030 buffer_.Store<int8_t>(position, offset);
2031 }
2032 label->BindTo(bound);
2033 }
2034
2035 void AssemblerX86::EmitOperand(int rm, const Operand &operand) {
2036 assert(rm >= 0 && rm < 8);
2037 const intptr_t length = operand.length_;
2038 assert(length > 0);
2039 // Emit the ModRM byte updated with the given RM value.
2040 assert((operand.encoding_[0] & 0x38) == 0);
2041 EmitUint8(operand.encoding_[0] + (rm << 3));
2042 // Emit the rest of the encoded operand.
2043 for (intptr_t i = 1; i < length; i++) {
2044 EmitUint8(operand.encoding_[i]);
2045 }
2046 }
2047
2048 void AssemblerX86::EmitImmediate(const Immediate &imm) {
2049 EmitInt32(imm.value());
2050 }
2051
2052 void AssemblerX86::EmitComplexI8(int rm, const Operand &operand,
2053 const Immediate &immediate) {
2054 assert(rm >= 0 && rm < 8);
2055 assert(immediate.is_int8());
2056 if (operand.IsRegister(EAX)) {
2057 // Use short form if the destination is al.
2058 EmitUint8(0x04 + (rm << 3));
2059 EmitUint8(immediate.value() & 0xFF);
2060 } else {
2061 // Use sign-extended 8-bit immediate.
2062 EmitUint8(0x80);
2063 EmitOperand(rm, operand);
2064 EmitUint8(immediate.value() & 0xFF);
2065 }
2066 }
2067
2068 void AssemblerX86::EmitComplex(int rm, const Operand &operand,
2069 const Immediate &immediate) {
2070 assert(rm >= 0 && rm < 8);
2071 if (immediate.is_int8()) {
2072 // Use sign-extended 8-bit immediate.
2073 EmitUint8(0x83);
2074 EmitOperand(rm, operand);
2075 EmitUint8(immediate.value() & 0xFF);
2076 } else if (operand.IsRegister(EAX)) {
2077 // Use short form if the destination is eax.
2078 EmitUint8(0x05 + (rm << 3));
2079 EmitImmediate(immediate);
2080 } else {
2081 EmitUint8(0x81);
2082 EmitOperand(rm, operand);
2083 EmitImmediate(immediate);
2084 }
2085 }
2086
2087 void AssemblerX86::EmitLabel(Label *label, intptr_t instruction_size) {
2088 if (label->IsBound()) {
2089 intptr_t offset = label->Position() - buffer_.Size();
2090 assert(offset <= 0);
2091 EmitInt32(offset - instruction_size);
2092 } else {
2093 EmitLabelLink(label);
2094 }
2095 }
2096
2097 void AssemblerX86::EmitLabelLink(Label *label) {
2098 assert(!label->IsBound());
2099 intptr_t position = buffer_.Size();
2100 EmitInt32(label->position_);
2101 label->LinkTo(position);
2102 }
2103
2104 void AssemblerX86::EmitNearLabelLink(Label *label) {
2105 assert(!label->IsBound());
2106 intptr_t position = buffer_.Size();
2107 EmitUint8(0);
2108 label->NearLinkTo(position);
2109 }
2110
2111 void AssemblerX86::EmitGenericShift(int rm, Register reg,
2112 const Immediate &imm) {
2113 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2114 assert(imm.is_int8());
2115 if (imm.value() == 1) {
2116 EmitUint8(0xD1);
2117 EmitOperand(rm, Operand(reg));
2118 } else {
2119 EmitUint8(0xC1);
2120 EmitOperand(rm, Operand(reg));
2121 EmitUint8(imm.value() & 0xFF);
2122 }
2123 }
2124
2125 void AssemblerX86::EmitGenericShift(int rm, const Operand &operand,
2126 Register shifter) {
2127 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2128 assert(shifter == ECX);
2129 EmitUint8(0xD3);
2130 EmitOperand(rm, Operand(operand));
2131 }
2132
2133 } // end of namespace x86
2134 } // end of namespace Ice
OLDNEW
« src/IceUtils.h ('K') | « src/assembler_ia32.h ('k') | src/llvm2ice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698