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

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

Powered by Google App Engine
This is Rietveld 408576698