OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 if (*p != 0) { // 0 means uninitialized. | 264 if (*p != 0) { // 0 means uninitialized. |
265 *p += pc_delta; | 265 *p += pc_delta; |
266 } | 266 } |
267 } | 267 } |
268 } | 268 } |
269 | 269 |
270 ASSERT(!overflow()); | 270 ASSERT(!overflow()); |
271 } | 271 } |
272 | 272 |
273 | 273 |
274 void Assembler::emit_operand(Register reg, const Operand& adr) { | 274 void Assembler::emit_operand(int rm, const Operand& adr) { |
275 ASSERT_EQ(rm & 0x07, rm); | |
William Hesse
2009/05/29 13:08:00
I think that rm should be anded with 0x7 always, s
Lasse Reichstein
2009/05/29 13:13:29
I'd rather fail than silently correct errors. The
| |
275 const unsigned length = adr.len_; | 276 const unsigned length = adr.len_; |
276 ASSERT(length > 0); | 277 ASSERT(length > 0); |
277 | 278 |
278 // Emit updated ModRM byte containing the given register. | 279 // Emit updated ModRM byte containing the given register. |
279 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); | 280 pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3); |
280 | 281 |
281 // Emit the rest of the encoded operand. | 282 // Emit the rest of the encoded operand. |
282 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 283 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
283 pc_ += length; | 284 pc_ += length; |
284 } | 285 } |
285 | 286 |
286 | 287 |
287 // Assembler Instruction implementations | 288 // Assembler Instruction implementations |
288 | 289 |
289 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { | 290 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 L->link_to(pc_offset() - sizeof(int32_t)); | 356 L->link_to(pc_offset() - sizeof(int32_t)); |
356 } else { | 357 } else { |
357 ASSERT(L->is_unused()); | 358 ASSERT(L->is_unused()); |
358 int32_t current = pc_offset(); | 359 int32_t current = pc_offset(); |
359 emitl(current); | 360 emitl(current); |
360 L->link_to(current); | 361 L->link_to(current); |
361 } | 362 } |
362 } | 363 } |
363 | 364 |
364 | 365 |
366 void Assembler::call(Register adr) { | |
367 EnsureSpace ensure_space(this); | |
368 last_pc_ = pc_; | |
369 // Opcode: FF /2 r64 | |
370 if (!is_uint3(adr.code())) { | |
371 emit_rex_64(adr); | |
372 } | |
373 emit(0xFF); | |
374 emit(0xD0 | (adr.code() & 0x07)); | |
375 } | |
376 | |
377 | |
365 void Assembler::dec(Register dst) { | 378 void Assembler::dec(Register dst) { |
366 EnsureSpace ensure_space(this); | 379 EnsureSpace ensure_space(this); |
367 last_pc_ = pc_; | 380 last_pc_ = pc_; |
368 emit_rex_64(dst); | 381 emit_rex_64(dst); |
369 emit(0xFF); | 382 emit(0xFF); |
370 emit(0xC8 | (dst.code() & 0x7)); | 383 emit(0xC8 | (dst.code() & 0x7)); |
371 } | 384 } |
372 | 385 |
373 | 386 |
374 void Assembler::dec(const Operand& dst) { | 387 void Assembler::dec(const Operand& dst) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 // 1110 1001 #32-bit disp | 485 // 1110 1001 #32-bit disp |
473 ASSERT(L->is_unused()); | 486 ASSERT(L->is_unused()); |
474 emit(0xE9); | 487 emit(0xE9); |
475 int32_t current = pc_offset(); | 488 int32_t current = pc_offset(); |
476 emitl(current); | 489 emitl(current); |
477 L->link_to(current); | 490 L->link_to(current); |
478 } | 491 } |
479 } | 492 } |
480 | 493 |
481 | 494 |
495 void Assembler::jmp(Register target) { | |
496 EnsureSpace ensure_space(this); | |
497 last_pc_ = pc_; | |
498 // Opcode FF/4 r64 | |
499 if (!is_uint3(target.code())) { | |
500 emit_rex_64(target); | |
501 } | |
502 emit(0xFF); | |
503 emit(0xE0 | target.code() & 0x07); | |
504 } | |
505 | |
506 | |
482 void Assembler::movq(Register dst, const Operand& src) { | 507 void Assembler::movq(Register dst, const Operand& src) { |
483 EnsureSpace ensure_space(this); | 508 EnsureSpace ensure_space(this); |
484 last_pc_ = pc_; | 509 last_pc_ = pc_; |
485 emit_rex_64(dst, src); | 510 emit_rex_64(dst, src); |
486 emit(0x8B); | 511 emit(0x8B); |
487 emit_operand(dst, src); | 512 emit_operand(dst, src); |
488 } | 513 } |
489 | 514 |
490 | 515 |
491 void Assembler::movq(Register dst, Register src) { | 516 void Assembler::movq(Register dst, Register src) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 | 577 |
553 void Assembler::not_(const Operand& dst) { | 578 void Assembler::not_(const Operand& dst) { |
554 EnsureSpace ensure_space(this); | 579 EnsureSpace ensure_space(this); |
555 last_pc_ = pc_; | 580 last_pc_ = pc_; |
556 emit_rex_64(dst); | 581 emit_rex_64(dst); |
557 emit(0xF7); | 582 emit(0xF7); |
558 emit_operand(2, dst); | 583 emit_operand(2, dst); |
559 } | 584 } |
560 | 585 |
561 | 586 |
587 void Assembler::nop(int n) { | |
588 // The recommended muti-byte sequences of NOP instructions from the Intel 64 | |
589 // and IA-32 Architectures Software Developer's Manual. | |
590 // | |
591 // Length Assembly Byte Sequence | |
592 // 2 bytes 66 NOP 66 90H | |
593 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H | |
594 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H | |
595 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H | |
596 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H | |
597 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H | |
598 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H | |
599 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 | |
600 // 00000000H] 00H | |
601 | |
602 ASSERT(1 <= n); | |
603 ASSERT(n <= 9); | |
604 EnsureSpace ensure_space(this); | |
605 last_pc_ = pc_; | |
606 switch (n) { | |
607 case 1: | |
608 emit(0x90); | |
609 return; | |
610 case 2: | |
611 emit(0x66); | |
612 emit(0x90); | |
613 return; | |
614 case 3: | |
615 emit(0x0f); | |
616 emit(0x1f); | |
617 emit(0x00); | |
618 return; | |
619 case 4: | |
620 emit(0x0f); | |
621 emit(0x1f); | |
622 emit(0x40); | |
623 emit(0x00); | |
624 return; | |
625 case 5: | |
626 emit(0x0f); | |
627 emit(0x1f); | |
628 emit(0x44); | |
629 emit(0x00); | |
630 emit(0x00); | |
631 return; | |
632 case 6: | |
633 emit(0x66); | |
634 emit(0x0f); | |
635 emit(0x1f); | |
636 emit(0x44); | |
637 emit(0x00); | |
638 emit(0x00); | |
639 return; | |
640 case 7: | |
641 emit(0x0f); | |
642 emit(0x1f); | |
643 emit(0x80); | |
644 emit(0x00); | |
645 emit(0x00); | |
646 emit(0x00); | |
647 emit(0x00); | |
648 return; | |
649 case 8: | |
650 emit(0x0f); | |
651 emit(0x1f); | |
652 emit(0x84); | |
653 emit(0x00); | |
654 emit(0x00); | |
655 emit(0x00); | |
656 emit(0x00); | |
657 emit(0x00); | |
658 return; | |
659 case 9: | |
660 emit(0x66); | |
661 emit(0x0f); | |
662 emit(0x1f); | |
663 emit(0x84); | |
664 emit(0x00); | |
665 emit(0x00); | |
666 emit(0x00); | |
667 emit(0x00); | |
668 emit(0x00); | |
669 return; | |
670 } | |
671 } | |
672 | |
673 | |
562 void Assembler::pop(Register dst) { | 674 void Assembler::pop(Register dst) { |
563 EnsureSpace ensure_space(this); | 675 EnsureSpace ensure_space(this); |
564 last_pc_ = pc_; | 676 last_pc_ = pc_; |
565 if (dst.code() & 0x8) { | 677 if (dst.code() & 0x8) { |
566 emit_rex_64(dst); | 678 emit_rex_64(dst); |
567 } | 679 } |
568 emit(0x58 | (dst.code() & 0x7)); | 680 emit(0x58 | (dst.code() & 0x7)); |
569 } | 681 } |
570 | 682 |
571 | 683 |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1003 UNIMPLEMENTED(); | 1115 UNIMPLEMENTED(); |
1004 return NULL; | 1116 return NULL; |
1005 } | 1117 } |
1006 | 1118 |
1007 byte* JavaScriptFrame::GetCallerStackPointer() const { | 1119 byte* JavaScriptFrame::GetCallerStackPointer() const { |
1008 UNIMPLEMENTED(); | 1120 UNIMPLEMENTED(); |
1009 return NULL; | 1121 return NULL; |
1010 } | 1122 } |
1011 | 1123 |
1012 } } // namespace v8::internal | 1124 } } // namespace v8::internal |
OLD | NEW |