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

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 8747023: Initial revision of assembler for x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, 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 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64)
7
8 #include "vm/assembler.h"
9 #include "vm/heap.h"
10 #include "vm/memory_region.h"
11 #include "vm/runtime_entry.h"
12
13 namespace dart {
14
15 void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) {
16 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length);
17 }
18
19
20 void Assembler::call(Register reg) {
21 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22 Operand operand(reg);
23 EmitOperandREX(2, operand, REX_NONE);
24 EmitUint8(0xFF);
25 EmitOperand(2, operand);
26 }
27
28
29 void Assembler::call(const Address& address) {
30 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
31 EmitOperandREX(2, address, REX_NONE);
32 EmitUint8(0xFF);
33 EmitOperand(2, address);
34 }
35
36
37 void Assembler::call(Label* label) {
38 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
39 static const int kSize = 5;
40 EmitUint8(0xE8);
41 EmitLabel(label, kSize);
42 }
43
44
45 void Assembler::call(const ExternalLabel* label) {
46 movq(R11, Immediate(label->address()));
47 call(R11);
48 }
49
50
51 void Assembler::pushq(Register reg) {
52 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
53 EmitRegisterREX(reg, REX_NONE);
54 EmitUint8(0x50 | (reg & 7));
55 }
56
57
58 void Assembler::pushq(const Address& address) {
59 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
60 EmitOperandREX(6, address, REX_NONE);
61 EmitUint8(0xFF);
62 EmitOperand(6, address);
63 }
64
65
66 void Assembler::popq(Register reg) {
67 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
68 EmitRegisterREX(reg, REX_NONE);
69 EmitUint8(0x58 | (reg & 7));
70 }
71
72
73 void Assembler::popq(const Address& address) {
74 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
75 EmitOperandREX(0, address, REX_NONE);
76 EmitUint8(0x8F);
77 EmitOperand(0, address);
78 }
79
80
81 void Assembler::movl(Register dst, Register src) {
82 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
83 Operand operand(src);
84 EmitOperandREX(dst, operand, REX_NONE);
85 EmitUint8(0x8B);
86 EmitOperand(dst & 7, operand);
87 }
88
89
90 void Assembler::movl(Register dst, const Immediate& imm) {
91 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
92 Operand operand(dst);
93 EmitOperandREX(0, operand, REX_NONE);
94 EmitUint8(0xC7);
95 EmitOperand(0, operand);
96 ASSERT(imm.is_int32());
97 EmitImmediate(imm);
98 }
99
100
101 void Assembler::movl(Register dst, const Address& src) {
102 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103 EmitOperandREX(dst, src, REX_NONE);
104 EmitUint8(0x8B);
105 EmitOperand(dst & 7, src);
106 }
107
108
109 void Assembler::movl(const Address& dst, Register src) {
110 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
111 EmitOperandREX(src, dst, REX_NONE);
112 EmitUint8(0x89);
113 EmitOperand(src & 7, dst);
114 }
115
116
117 void Assembler::movzxb(Register dst, Register src) {
118 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
119 Operand operand(src);
120 EmitOperandREX(dst, operand, REX_W);
121 EmitUint8(0x0F);
122 EmitUint8(0xB6);
123 EmitOperand(dst & 7, operand);
124 }
125
126
127 void Assembler::movzxb(Register dst, const Address& src) {
128 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
129 EmitOperandREX(dst, src, REX_W);
130 EmitUint8(0x0F);
131 EmitUint8(0xB6);
132 EmitOperand(dst & 7, src);
133 }
134
135
136 void Assembler::movsxb(Register dst, Register src) {
137 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
138 Operand operand(src);
139 EmitOperandREX(dst, operand, REX_W);
140 EmitUint8(0x0F);
141 EmitUint8(0xBE);
142 EmitOperand(dst & 7, operand);
143 }
144
145
146 void Assembler::movsxb(Register dst, const Address& src) {
147 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
148 EmitOperandREX(dst, src, REX_W);
149 EmitUint8(0x0F);
150 EmitUint8(0xBE);
151 EmitOperand(dst & 7, src);
152 }
153
154
155 void Assembler::movb(Register dst, const Address& src) {
156 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
157 EmitOperandREX(dst, src, REX_NONE);
158 EmitUint8(0x8A);
159 EmitOperand(dst & 7, src);
160 }
161
162
163 void Assembler::movb(const Address& dst, const Immediate& imm) {
164 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
165 EmitOperandREX(0, dst, REX_NONE);
166 EmitUint8(0xC6);
167 EmitOperand(0, dst);
168 ASSERT(imm.is_int8());
169 EmitUint8(imm.value() & 0xFF);
170 }
171
172
173 void Assembler::movb(const Address& dst, Register src) {
174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
175 EmitOperandREX(src, dst, REX_NONE);
176 EmitUint8(0x88);
177 EmitOperand(src & 7, dst);
178 }
179
180
181 void Assembler::movzxw(Register dst, Register src) {
182 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
183 Operand operand(src);
184 EmitOperandREX(dst, operand, REX_W);
185 EmitUint8(0x0F);
186 EmitUint8(0xB7);
187 EmitOperand(dst & 7, operand);
188 }
189
190
191 void Assembler::movzxw(Register dst, const Address& src) {
192 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
193 EmitOperandREX(dst, src, REX_W);
194 EmitUint8(0x0F);
195 EmitUint8(0xB7);
196 EmitOperand(dst & 7, src);
197 }
198
199
200 void Assembler::movsxw(Register dst, Register src) {
201 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
202 Operand operand(src);
203 EmitOperandREX(dst, operand, REX_W);
204 EmitUint8(0x0F);
205 EmitUint8(0xBF);
206 EmitOperand(dst & 7, operand);
207 }
208
209
210 void Assembler::movsxw(Register dst, const Address& src) {
211 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
212 EmitOperandREX(dst, src, REX_W);
213 EmitUint8(0x0F);
214 EmitUint8(0xBF);
215 EmitOperand(dst & 7, src);
216 }
217
218
219 void Assembler::movw(Register dst, const Address& src) {
220 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
221 EmitOperandREX(dst, src, REX_NONE);
222 EmitOperandSizeOverride();
223 EmitUint8(0x8B);
224 EmitOperand(dst & 7, src);
225 }
226
227
228 void Assembler::movw(const Address& dst, Register src) {
229 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
230 EmitOperandREX(src, dst, REX_NONE);
231 EmitOperandSizeOverride();
232 EmitUint8(0x89);
233 EmitOperand(src & 7, dst);
234 }
235
236
237 void Assembler::movq(Register dst, const Immediate& imm) {
238 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
239 if (imm.is_int32()) {
240 Operand operand(dst);
241 EmitOperandREX(0, operand, REX_W);
242 EmitUint8(0xC7);
243 EmitOperand(0, operand);
244 } else {
245 EmitRegisterREX(dst, REX_W);
246 EmitUint8(0xB8 | (dst & 7));
247 }
248 EmitImmediate(imm);
249 }
250
251
252 void Assembler::movq(Register dst, Register src) {
253 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
254 Operand operand(src);
255 EmitOperandREX(dst, operand, REX_W);
256 EmitUint8(0x8B);
257 EmitOperand(dst & 7, operand);
258 }
259
260
261 void Assembler::movq(Register dst, const Address& src) {
262 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
263 EmitOperandREX(dst, src, REX_W);
264 EmitUint8(0x8B);
265 EmitOperand(dst & 7, src);
266 }
267
268
269 void Assembler::movq(const Address& dst, Register src) {
270 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
271 EmitOperandREX(src, dst, REX_W);
272 EmitUint8(0x89);
273 EmitOperand(src & 7, dst);
274 }
275
276
277 void Assembler::movq(const Address& dst, const Immediate& imm) {
278 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
279 ASSERT(imm.is_int32());
280 Operand operand(dst);
281 EmitOperandREX(0, operand, REX_W);
282 EmitUint8(0xC7);
283 EmitOperand(0, operand);
284 EmitImmediate(imm);
285 }
286
287
288 void Assembler::movsxl(Register dst, const Address& src) {
289 UNIMPLEMENTED();
290 }
291
292
293 void Assembler::leaq(Register dst, const Address& src) {
294 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
295 EmitOperandREX(dst, src, REX_W);
296 EmitUint8(0x8D);
297 EmitOperand(dst & 7, src);
298 }
299
300
301 void Assembler::movss(XmmRegister dst, const Address& src) {
302 // TODO(srdjan): implement and test XMM8 - XMM15.
303 ASSERT(dst <= XMM7);
304 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
305 EmitUint8(0xF3);
306 EmitOperandREX(0, src, REX_NONE);
307 EmitUint8(0x0F);
308 EmitUint8(0x10);
309 EmitOperand(dst & 7, src);
310 }
311
312
313 void Assembler::movss(const Address& dst, XmmRegister src) {
314 // TODO(srdjan): implement and test XMM8 - XMM15.
315 ASSERT(src <= XMM7);
316 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
317 EmitUint8(0xF3);
318 EmitOperandREX(0, dst, REX_NONE);
319 EmitUint8(0x0F);
320 EmitUint8(0x11);
321 EmitOperand(src & 7, dst);
322 }
323
324
325 void Assembler::movss(XmmRegister dst, XmmRegister src) {
326 // TODO(srdjan): implement and test XMM8 - XMM15.
327 ASSERT(src <= XMM7);
328 ASSERT(dst <= XMM7);
329 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
330 EmitUint8(0xF3);
331 EmitUint8(0x0F);
332 EmitUint8(0x11);
333 EmitXmmRegisterOperand(src & 7, dst);
334 }
335
336
337 void Assembler::movd(XmmRegister dst, Register src) {
338 ASSERT(dst <= XMM7);
339 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
340 EmitUint8(0x66);
341 EmitUint8(0x0F);
342 EmitUint8(0x6E);
343 EmitOperand(dst, Operand(src));
344 }
345
346
347 void Assembler::movd(Register dst, XmmRegister src) {
348 ASSERT(src <= XMM7);
349 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
350 EmitUint8(0x66);
351 EmitUint8(0x0F);
352 EmitUint8(0x7E);
353 EmitOperand(src, Operand(dst));
354 }
355
356
357 void Assembler::addss(XmmRegister dst, XmmRegister src) {
358 // TODO(srdjan): implement and test XMM8 - XMM15.
359 ASSERT(src <= XMM7);
360 ASSERT(dst <= XMM7);
361 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
362 EmitUint8(0xF3);
363 EmitUint8(0x0F);
364 EmitUint8(0x58);
365 EmitXmmRegisterOperand(dst, src);
366 }
367
368
369 void Assembler::subss(XmmRegister dst, XmmRegister src) {
370 // TODO(srdjan): implement and test XMM8 - XMM15.
371 ASSERT(src <= XMM7);
372 ASSERT(dst <= XMM7);
373 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
374 EmitUint8(0xF3);
375 EmitUint8(0x0F);
376 EmitUint8(0x5C);
377 EmitXmmRegisterOperand(dst, src);
378 }
379
380
381 void Assembler::mulss(XmmRegister dst, XmmRegister src) {
382 // TODO(srdjan): implement and test XMM8 - XMM15.
383 ASSERT(src <= XMM7);
384 ASSERT(dst <= XMM7);
385 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
386 EmitUint8(0xF3);
387 EmitUint8(0x0F);
388 EmitUint8(0x59);
389 EmitXmmRegisterOperand(dst, src);
390 }
391
392
393 void Assembler::divss(XmmRegister dst, XmmRegister src) {
394 // TODO(srdjan): implement and test XMM8 - XMM15.
395 ASSERT(src <= XMM7);
396 ASSERT(dst <= XMM7);
397 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
398 EmitUint8(0xF3);
399 EmitUint8(0x0F);
400 EmitUint8(0x5E);
401 EmitXmmRegisterOperand(dst, src);
402 }
403
404
405 void Assembler::movsd(XmmRegister dst, const Address& src) {
406 // TODO(srdjan): implement and test XMM8 - XMM15.
407 ASSERT(dst <= XMM7);
408 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
409 EmitUint8(0xF2);
410 EmitOperandREX(0, src, REX_NONE);
411 EmitUint8(0x0F);
412 EmitUint8(0x10);
413 EmitOperand(dst & 7, src);
414 }
415
416
417 void Assembler::movsd(const Address& dst, XmmRegister src) {
418 // TODO(srdjan): implement and test XMM8 - XMM15.
419 ASSERT(src <= XMM7);
420 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
421 EmitUint8(0xF2);
422 EmitOperandREX(0, dst, REX_NONE);
423 EmitUint8(0x0F);
424 EmitUint8(0x11);
425 EmitOperand(src & 7, dst);
426 }
427
428
429 void Assembler::movsd(XmmRegister dst, XmmRegister src) {
430 // TODO(srdjan): implement and test XMM8 - XMM15.
431 ASSERT(src <= XMM7);
432 ASSERT(dst <= XMM7);
433 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
434 EmitUint8(0xF2);
435 EmitUint8(0x0F);
436 EmitUint8(0x11);
437 EmitXmmRegisterOperand(src & 7, dst);
438 }
439
440
441 void Assembler::addsd(XmmRegister dst, XmmRegister src) {
442 // TODO(srdjan): implement and test XMM8 - XMM15.
443 ASSERT(src <= XMM7);
444 ASSERT(dst <= XMM7);
445 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
446 EmitUint8(0xF2);
447 EmitUint8(0x0F);
448 EmitUint8(0x58);
449 EmitXmmRegisterOperand(dst, src);
450 }
451
452
453 void Assembler::subsd(XmmRegister dst, XmmRegister src) {
454 // TODO(srdjan): implement and test XMM8 - XMM15.
455 ASSERT(src <= XMM7);
456 ASSERT(dst <= XMM7);
457 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
458 EmitUint8(0xF2);
459 EmitUint8(0x0F);
460 EmitUint8(0x5C);
461 EmitXmmRegisterOperand(dst, src);
462 }
463
464
465 void Assembler::mulsd(XmmRegister dst, XmmRegister src) {
466 // TODO(srdjan): implement and test XMM8 - XMM15.
467 ASSERT(src <= XMM7);
468 ASSERT(dst <= XMM7);
469 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
470 EmitUint8(0xF2);
471 EmitUint8(0x0F);
472 EmitUint8(0x59);
473 EmitXmmRegisterOperand(dst, src);
474 }
475
476
477 void Assembler::divsd(XmmRegister dst, XmmRegister src) {
478 // TODO(srdjan): implement and test XMM8 - XMM15.
479 ASSERT(src <= XMM7);
480 ASSERT(dst <= XMM7);
481 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
482 EmitUint8(0xF2);
483 EmitUint8(0x0F);
484 EmitUint8(0x5E);
485 EmitXmmRegisterOperand(dst, src);
486 }
487
488
489 void Assembler::xchgl(Register dst, Register src) {
490 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
491 Operand operand(src);
492 EmitOperandREX(dst, operand, REX_NONE);
493 EmitUint8(0x87);
494 EmitOperand(dst & 7, operand);
495 }
496
497
498 void Assembler::xchgq(Register dst, Register src) {
499 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
500 Operand operand(src);
501 EmitOperandREX(dst, operand, REX_W);
502 EmitUint8(0x87);
503 EmitOperand(dst & 7, operand);
504 }
505
506
507 void Assembler::cmpl(Register reg, const Immediate& imm) {
508 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
509 EmitRegisterREX(reg, REX_NONE);
510 EmitComplex(7, Operand(reg), imm);
511 }
512
513
514 void Assembler::cmpl(Register reg0, Register reg1) {
515 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
516 Operand operand(reg1);
517 EmitOperandREX(reg0, operand, REX_NONE);
518 EmitUint8(0x3B);
519 EmitOperand(reg0 & 7, operand);
520 }
521
522
523 void Assembler::cmpl(Register reg, const Address& address) {
524 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
525 EmitOperandREX(reg, address, REX_NONE);
526 EmitUint8(0x3B);
527 EmitOperand(reg & 7, address);
528 }
529
530
531 void Assembler::cmpl(const Address& address, const Immediate& imm) {
532 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
533 Operand operand(address);
534 EmitOperandREX(7, operand, REX_NONE);
535 EmitComplex(7, operand, imm);
536 }
537
538
539 void Assembler::cmpq(const Address& address, const Immediate& imm) {
540 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
541 Operand operand(address);
542 EmitOperandREX(7, operand, REX_W);
543 EmitComplex(7, operand, imm);
544 }
545
546
547 void Assembler::cmpq(Register reg, const Immediate& imm) {
548 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
549 EmitRegisterREX(reg, REX_W);
550 EmitComplex(7, Operand(reg), imm);
551 }
552
553
554 void Assembler::cmpq(Register reg0, Register reg1) {
555 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
556 Operand operand(reg1);
557 EmitOperandREX(reg0, operand, REX_W);
558 EmitUint8(0x3B);
559 EmitOperand(reg0 & 7, operand);
560 }
561
562
563 void Assembler::cmpq(Register reg, const Address& address) {
564 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
565 EmitOperandREX(reg, address, REX_W);
566 EmitUint8(0x3B);
567 EmitOperand(reg & 7, address);
568 }
569
570
571 void Assembler::testl(Register reg1, Register reg2) {
572 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
573 Operand operand(reg2);
574 EmitOperandREX(reg1, operand, REX_NONE);
575 EmitUint8(0x85);
576 EmitOperand(reg1 & 7, operand);
577 }
578
579
580 void Assembler::testl(Register reg, const Immediate& imm) {
581 // TODO(kasperl): Deal with registers r8-r15 using the short
582 // encoding form of the immediate?
583
584 // We are using RBP for the exception marker. See testl(Label*).
585 ASSERT(reg != RBP);
586 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
587 // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
588 // we only test the byte register to keep the encoding short.
589 if (imm.is_uint8() && reg < 4) {
590 // Use zero-extended 8-bit immediate.
591 if (reg == RAX) {
592 EmitUint8(0xA8);
593 } else {
594 EmitUint8(0xF6);
595 EmitUint8(0xC0 + reg);
596 }
597 EmitUint8(imm.value() & 0xFF);
598 } else {
599 ASSERT(imm.is_int32());
600 if (reg == RAX) {
601 EmitUint8(0xA9);
602 } else {
603 EmitRegisterREX(reg, REX_NONE);
604 EmitUint8(0xF7);
605 EmitUint8(0xC0 | (reg & 7));
606 }
607 EmitImmediate(imm);
608 }
609 }
610
611
612 void Assembler::testq(Register reg1, Register reg2) {
613 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
614 Operand operand(reg2);
615 EmitOperandREX(reg1, operand, REX_W);
616 EmitUint8(0x85);
617 EmitOperand(reg1 & 7, operand);
618 }
619
620
621 void Assembler::testq(Register reg, const Immediate& imm) {
622 // TODO(kasperl): Deal with registers r8-r15 using the short
623 // encoding form of the immediate?
624
625 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
626 // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
627 // we only test the byte register to keep the encoding short.
628 if (imm.is_uint8() && reg < 4) {
629 // Use zero-extended 8-bit immediate.
630 if (reg == RAX) {
631 EmitUint8(0xA8);
632 } else {
633 EmitUint8(0xF6);
634 EmitUint8(0xC0 + reg);
635 }
636 EmitUint8(imm.value() & 0xFF);
637 } else {
638 ASSERT(imm.is_int32());
639 if (reg == RAX) {
640 EmitUint8(0xA9 | REX_W);
641 } else {
642 EmitRegisterREX(reg, REX_W);
643 EmitUint8(0xF7);
644 EmitUint8(0xC0 | (reg & 7));
645 }
646 EmitImmediate(imm);
647 }
648 }
649
650
651 void Assembler::andl(Register dst, Register src) {
652 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
653 Operand operand(src);
654 EmitOperandREX(dst, operand, REX_NONE);
655 EmitUint8(0x23);
656 EmitOperand(dst & 7, operand);
657 }
658
659
660 void Assembler::andl(Register dst, const Immediate& imm) {
661 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
662 EmitRegisterREX(dst, REX_NONE);
663 EmitComplex(4, Operand(dst), imm);
664 }
665
666
667 void Assembler::orl(Register dst, Register src) {
668 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
669 Operand operand(src);
670 EmitOperandREX(dst, operand, REX_NONE);
671 EmitUint8(0x0B);
672 EmitOperand(dst & 7, operand);
673 }
674
675
676 void Assembler::orl(Register dst, const Immediate& imm) {
677 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
678 EmitRegisterREX(dst, REX_NONE);
679 EmitComplex(1, Operand(dst), imm);
680 }
681
682
683 void Assembler::xorl(Register dst, Register src) {
684 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
685 Operand operand(src);
686 EmitOperandREX(dst, operand, REX_NONE);
687 EmitUint8(0x33);
688 EmitOperand(dst & 7, operand);
689 }
690
691
692 void Assembler::andq(Register dst, Register src) {
693 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
694 Operand operand(src);
695 EmitOperandREX(dst, operand, REX_W);
696 EmitUint8(0x23);
697 EmitOperand(dst & 7, operand);
698 }
699
700
701 void Assembler::andq(Register dst, const Immediate& imm) {
702 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
703 EmitRegisterREX(dst, REX_W);
704 EmitComplex(4, Operand(dst), imm);
705 }
706
707
708 void Assembler::orq(Register dst, Register src) {
709 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
710 Operand operand(src);
711 EmitOperandREX(dst, operand, REX_W);
712 EmitUint8(0x0B);
713 EmitOperand(dst & 7, operand);
714 }
715
716
717 void Assembler::orq(Register dst, const Immediate& imm) {
718 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
719 EmitRegisterREX(dst, REX_W);
720 EmitComplex(1, Operand(dst), imm);
721 }
722
723
724 void Assembler::xorq(Register dst, Register src) {
725 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
726 Operand operand(src);
727 EmitOperandREX(dst, operand, REX_W);
728 EmitUint8(0x33);
729 EmitOperand(dst & 7, operand);
730 }
731
732
733 void Assembler::addl(Register dst, Register src) {
734 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
735 Operand operand(src);
736 EmitOperandREX(dst, operand, REX_NONE);
737 EmitUint8(0x03);
738 EmitOperand(dst & 7, operand);
739 }
740
741
742 void Assembler::addq(Register dst, Register src) {
743 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
744 Operand operand(src);
745 EmitOperandREX(dst, operand, REX_W);
746 EmitUint8(0x03);
747 EmitOperand(dst & 7, operand);
748 }
749
750
751 void Assembler::addl(const Address& address, const Immediate& imm) {
752 UNIMPLEMENTED();
753 }
754
755
756 void Assembler::addq(Register reg, const Immediate& imm) {
757 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
758 EmitRegisterREX(reg, REX_W);
759 EmitComplex(0, Operand(reg), imm);
760 }
761
762
763 void Assembler::addq(const Address& address, const Immediate& imm) {
764 UNIMPLEMENTED();
765 }
766
767
768 void Assembler::subl(Register dst, Register src) {
769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
770 Operand operand(src);
771 EmitOperandREX(dst, operand, REX_NONE);
772 EmitUint8(0x2B);
773 EmitOperand(dst & 7, operand);
774 }
775
776
777 void Assembler::cdq() {
778 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
779 EmitUint8(0x99);
780 }
781
782
783 void Assembler::cqo() {
784 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
785 EmitRegisterREX(RAX, REX_W);
786 EmitUint8(0x99);
787 }
788
789
790 void Assembler::idivl(Register reg) {
791 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
792 EmitRegisterREX(reg, REX_NONE);
793 EmitUint8(0xF7);
794 EmitUint8(0xF8 | (reg & 7));
795 }
796
797
798 void Assembler::idivq(Register reg) {
799 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
800 EmitRegisterREX(reg, REX_W);
801 EmitUint8(0xF7);
802 EmitUint8(0xF8 | (reg & 7));
803 }
804
805
806 void Assembler::imull(Register dst, Register src) {
807 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
808 EmitUint8(0x0F);
809 EmitUint8(0xAF);
810 EmitOperand(dst, Operand(src));
811 }
812
813
814 void Assembler::imull(Register reg, const Immediate& imm) {
815 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
816 EmitUint8(0x69);
817 EmitOperand(reg, Operand(reg));
818 EmitImmediate(imm);
819 }
820
821
822 void Assembler::imulq(Register dst, Register src) {
823 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
824 Operand operand(src);
825 EmitOperandREX(dst, operand, REX_W);
826 EmitUint8(0x0F);
827 EmitUint8(0xAF);
828 EmitOperand(dst & 7, operand);
829 }
830
831
832 void Assembler::subq(Register dst, Register src) {
833 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
834 Operand operand(src);
835 EmitOperandREX(dst, operand, REX_W);
836 EmitUint8(0x2B);
837 EmitOperand(dst & 7, operand);
838 }
839
840
841 void Assembler::subq(Register reg, const Immediate& imm) {
842 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
843 EmitRegisterREX(reg, REX_W);
844 EmitComplex(5, Operand(reg), imm);
845 }
846
847
848 void Assembler::shll(Register reg, const Immediate& imm) {
849 EmitGenericShift(false, 4, reg, imm);
850 }
851
852
853 void Assembler::shll(Register operand, Register shifter) {
854 EmitGenericShift(false, 4, operand, shifter);
855 }
856
857
858 void Assembler::shrl(Register reg, const Immediate& imm) {
859 EmitGenericShift(false, 5, reg, imm);
860 }
861
862
863 void Assembler::shrl(Register operand, Register shifter) {
864 EmitGenericShift(false, 5, operand, shifter);
865 }
866
867
868 void Assembler::sarl(Register reg, const Immediate& imm) {
869 EmitGenericShift(false, 7, reg, imm);
870 }
871
872
873 void Assembler::sarl(Register operand, Register shifter) {
874 EmitGenericShift(false, 7, operand, shifter);
875 }
876
877
878 void Assembler::shlq(Register reg, const Immediate& imm) {
879 EmitGenericShift(true, 4, reg, imm);
880 }
881
882
883 void Assembler::shlq(Register operand, Register shifter) {
884 EmitGenericShift(true, 4, operand, shifter);
885 }
886
887
888 void Assembler::shrq(Register reg, const Immediate& imm) {
889 EmitGenericShift(true, 5, reg, imm);
890 }
891
892
893 void Assembler::shrq(Register operand, Register shifter) {
894 EmitGenericShift(true, 5, operand, shifter);
895 }
896
897
898 void Assembler::sarq(Register reg, const Immediate& imm) {
899 EmitGenericShift(true, 7, reg, imm);
900 }
901
902
903 void Assembler::sarq(Register operand, Register shifter) {
904 EmitGenericShift(true, 7, operand, shifter);
905 }
906
907
908 void Assembler::incl(const Address& address) {
909 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
910 Operand operand(address);
911 EmitOperandREX(0, operand, REX_NONE);
912 EmitUint8(0xFF);
913 EmitOperand(0, operand);
914 }
915
916
917 void Assembler::decl(const Address& address) {
918 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
919 Operand operand(address);
920 EmitOperandREX(1, operand, REX_NONE);
921 EmitUint8(0xFF);
922 EmitOperand(1, operand);
923 }
924
925
926 void Assembler::incq(Register reg) {
927 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
928 Operand operand(reg);
929 EmitOperandREX(0, operand, REX_W);
930 EmitUint8(0xFF);
931 EmitOperand(0, operand);
932 }
933
934
935 void Assembler::incq(const Address& address) {
936 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
937 Operand operand(address);
938 EmitOperandREX(0, operand, REX_W);
939 EmitUint8(0xFF);
940 EmitOperand(0, operand);
941 }
942
943
944 void Assembler::decq(Register reg) {
945 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
946 Operand operand(reg);
947 EmitOperandREX(1, operand, REX_W);
948 EmitUint8(0xFF);
949 EmitOperand(1, operand);
950 }
951
952
953 void Assembler::decq(const Address& address) {
954 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
955 Operand operand(address);
956 EmitOperandREX(1, operand, REX_W);
957 EmitUint8(0xFF);
958 EmitOperand(1, operand);
959 }
960
961
962 void Assembler::negl(Register reg) {
963 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
964 EmitRegisterREX(reg, REX_NONE);
965 EmitUint8(0xF7);
966 EmitOperand(3, Operand(reg));
967 }
968
969
970 void Assembler::negq(Register reg) {
971 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972 EmitRegisterREX(reg, REX_W);
973 EmitUint8(0xF7);
974 EmitOperand(3, Operand(reg));
975 }
976
977
978 void Assembler::enter(const Immediate& imm) {
979 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
980 EmitUint8(0xC8);
981 ASSERT(imm.is_uint16());
982 EmitUint8(imm.value() & 0xFF);
983 EmitUint8((imm.value() >> 8) & 0xFF);
984 EmitUint8(0x00);
985 }
986
987
988 void Assembler::leave() {
989 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
990 EmitUint8(0xC9);
991 }
992
993
994 void Assembler::ret() {
995 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
996 EmitUint8(0xC3);
997 }
998
999
1000 void Assembler::nop() {
1001 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1002 EmitUint8(0x90);
1003 }
1004
1005
1006 void Assembler::int3() {
1007 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1008 EmitUint8(0xCC);
1009 }
1010
1011
1012 void Assembler::hlt() {
1013 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1014 EmitUint8(0xF4);
1015 }
1016
1017
1018 void Assembler::j(Condition condition, Label* label, bool near) {
1019 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1020 if (label->IsBound()) {
1021 static const int kShortSize = 2;
1022 static const int kLongSize = 6;
1023 int offset = label->Position() - buffer_.Size();
1024 ASSERT(offset <= 0);
1025 if (Utils::IsInt(8, offset - kShortSize)) {
1026 EmitUint8(0x70 + condition);
1027 EmitUint8((offset - kShortSize) & 0xFF);
1028 } else {
1029 EmitUint8(0x0F);
1030 EmitUint8(0x80 + condition);
1031 EmitInt32(offset - kLongSize);
1032 }
1033 } else if (near) {
1034 EmitUint8(0x70 + condition);
1035 EmitNearLabelLink(label);
1036 } else {
1037 EmitUint8(0x0F);
1038 EmitUint8(0x80 + condition);
1039 EmitLabelLink(label);
1040 }
1041 }
1042
1043
1044 void Assembler::jmp(Register reg) {
1045 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1046 Operand operand(reg);
1047 EmitOperandREX(4, operand, REX_NONE);
1048 EmitUint8(0xFF);
1049 EmitOperand(4, operand);
1050 }
1051
1052
1053 void Assembler::jmp(Label* label, bool near) {
1054 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1055 if (label->IsBound()) {
1056 static const int kShortSize = 2;
1057 static const int kLongSize = 5;
1058 int offset = label->Position() - buffer_.Size();
1059 ASSERT(offset <= 0);
1060 if (Utils::IsInt(8, offset - kShortSize)) {
1061 EmitUint8(0xEB);
1062 EmitUint8((offset - kShortSize) & 0xFF);
1063 } else {
1064 EmitUint8(0xE9);
1065 EmitInt32(offset - kLongSize);
1066 }
1067 } else if (near) {
1068 EmitUint8(0xEB);
1069 EmitNearLabelLink(label);
1070 } else {
1071 EmitUint8(0xE9);
1072 EmitLabelLink(label);
1073 }
1074 }
1075
1076
1077 void Assembler::jmp(const ExternalLabel* label) {
1078 movq(R11, Immediate(label->address()));
1079 jmp(R11);
1080 }
1081
1082
1083 void Assembler::lock() {
1084 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1085 EmitUint8(0xF0);
1086 }
1087
1088
1089 void Assembler::cmpxchgl(const Address& address, Register reg) {
1090 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1091 EmitOperandREX(reg, address, REX_NONE);
1092 EmitUint8(0x0F);
1093 EmitUint8(0xB1);
1094 EmitOperand(reg & 7, address);
1095 }
1096
1097
1098 void Assembler::cmpxchgq(const Address& address, Register reg) {
1099 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1100 EmitOperandREX(reg, address, REX_W);
1101 EmitUint8(0x0F);
1102 EmitUint8(0xB1);
1103 EmitOperand(reg & 7, address);
1104 }
1105
1106
1107 void Assembler::AddImmediate(Register reg, const Immediate& imm) {
1108 int64_t value = imm.value();
1109 if (value > 0) {
1110 if (value == 1) {
1111 incq(reg);
1112 } else if (value != 0) {
1113 addq(reg, imm);
1114 }
1115 } else if (value < 0) {
1116 value = -value;
1117 if (value == 1) {
1118 decq(reg);
1119 } else if (value != 0) {
1120 subq(reg, Immediate(value));
1121 }
1122 }
1123 }
1124
1125
1126 void Assembler::LoadObject(Register dst, const Object& object) {
1127 UNIMPLEMENTED();
1128 ASSERT(object.IsZoneHandle());
1129 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1130 EmitUint8(0xB8 + dst);
1131 buffer_.EmitObject(object);
1132 }
1133
1134
1135 void Assembler::PushObject(const Object& object) {
1136 UNIMPLEMENTED();
1137 ASSERT(object.IsZoneHandle());
1138 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1139 EmitUint8(0x68);
1140 buffer_.EmitObject(object);
1141 }
1142
1143
1144 void Assembler::CompareObject(Register reg, const Object& object) {
1145 UNIMPLEMENTED();
1146 ASSERT(object.IsZoneHandle());
1147 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1148 if (reg == RAX) {
1149 EmitUint8(0x05 + (7 << 3));
1150 buffer_.EmitObject(object);
1151 } else {
1152 EmitUint8(0x81);
1153 EmitOperand(7, Operand(reg));
1154 buffer_.EmitObject(object);
1155 }
1156 }
1157
1158
1159 void Assembler::Stop(const char* message) {
1160 // Emit the lower half and the higher half of the message address as immediate
1161 // operands in the test rax instructions, followed by the int3 instruction.
1162 // Execution can be resumed with the 'cont' command in gdb.
1163 int64_t message_address = reinterpret_cast<int64_t>(message);
1164 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
1165 testl(RAX, Immediate(Utils::High32Bits(message_address)));
1166 int3();
1167 }
1168
1169
1170 void Assembler::Bind(Label* label) {
1171 int bound = buffer_.Size();
1172 ASSERT(!label->IsBound()); // Labels can only be bound once.
1173 while (label->IsLinked()) {
1174 int position = label->LinkPosition();
1175 int next = buffer_.Load<int32_t>(position);
1176 buffer_.Store<int32_t>(position, bound - (position + 4));
1177 label->position_ = next;
1178 }
1179 while (label->HasNear()) {
1180 int position = label->NearPosition();
1181 int offset = bound - (position + 1);
1182 ASSERT(Utils::IsInt(8, offset));
1183 buffer_.Store<int8_t>(position, offset);
1184 }
1185 label->BindTo(bound);
1186 }
1187
1188
1189 void Assembler::Align(int alignment, int offset) {
1190 UNIMPLEMENTED();
1191 }
1192
1193
1194 void Assembler::EmitOperand(int rm, const Operand& operand) {
1195 ASSERT(rm >= 0 && rm < 8);
1196 const int length = operand.length_;
1197 ASSERT(length > 0);
1198 // Emit the ModRM byte updated with the given RM value.
1199 ASSERT((operand.encoding_[0] & 0x38) == 0);
1200 EmitUint8(operand.encoding_[0] + (rm << 3));
1201 // Emit the rest of the encoded operand.
1202 for (int i = 1; i < length; i++) {
1203 EmitUint8(operand.encoding_[i]);
1204 }
1205 }
1206
1207
1208 void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister xmm_reg) {
1209 Operand operand;
1210 operand.SetModRM(3, static_cast<Register>(xmm_reg));
1211 EmitOperand(rm, operand);
1212 }
1213
1214
1215 void Assembler::EmitImmediate(const Immediate& imm) {
1216 if (imm.is_int32()) {
1217 EmitInt32(static_cast<int32_t>(imm.value()));
1218 } else {
1219 EmitInt64(imm.value());
1220 }
1221 }
1222
1223
1224 void Assembler::EmitComplex(int rm,
1225 const Operand& operand,
1226 const Immediate& immediate) {
1227 ASSERT(rm >= 0 && rm < 8);
1228 ASSERT(immediate.is_int32());
1229 if (immediate.is_int8()) {
1230 // Use sign-extended 8-bit immediate.
1231 EmitUint8(0x83);
1232 EmitOperand(rm, operand);
1233 EmitUint8(immediate.value() & 0xFF);
1234 } else if (operand.IsRegister(RAX)) {
1235 // Use short form if the destination is rax.
1236 EmitUint8(0x05 + (rm << 3));
1237 EmitImmediate(immediate);
1238 } else {
1239 EmitUint8(0x81);
1240 EmitOperand(rm, operand);
1241 EmitImmediate(immediate);
1242 }
1243 }
1244
1245
1246 void Assembler::EmitLabel(Label* label, int instruction_size) {
1247 if (label->IsBound()) {
1248 int offset = label->Position() - buffer_.Size();
1249 ASSERT(offset <= 0);
1250 EmitInt32(offset - instruction_size);
1251 } else {
1252 EmitLabelLink(label);
1253 }
1254 }
1255
1256
1257 void Assembler::EmitLabelLink(Label* label) {
1258 ASSERT(!label->IsBound());
1259 int position = buffer_.Size();
1260 EmitInt32(label->position_);
1261 label->LinkTo(position);
1262 }
1263
1264
1265 void Assembler::EmitNearLabelLink(Label* label) {
1266 ASSERT(!label->IsBound());
1267 int position = buffer_.Size();
1268 EmitUint8(0);
1269 label->NearLinkTo(position);
1270 }
1271
1272
1273 void Assembler::EmitGenericShift(bool wide,
1274 int rm,
1275 Register reg,
1276 const Immediate& imm) {
1277 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1278 ASSERT(imm.is_int8());
1279 if (wide) {
1280 EmitRegisterREX(reg, REX_W);
1281 } else {
1282 EmitRegisterREX(reg, REX_NONE);
1283 }
1284 if (imm.value() == 1) {
1285 EmitUint8(0xD1);
1286 EmitOperand(rm, Operand(reg));
1287 } else {
1288 EmitUint8(0xC1);
1289 EmitOperand(rm, Operand(reg));
1290 EmitUint8(imm.value() & 0xFF);
1291 }
1292 }
1293
1294
1295 void Assembler::EmitGenericShift(bool wide,
1296 int rm,
1297 Register operand,
1298 Register shifter) {
1299 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1300 ASSERT(shifter == RCX);
1301 if (wide) {
1302 EmitRegisterREX(operand, REX_W);
1303 } else {
1304 EmitRegisterREX(operand, REX_NONE);
1305 }
1306 EmitUint8(0xD3);
1307 EmitOperand(rm, Operand(operand));
1308 }
1309
1310 } // namespace dart
1311
1312 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698