Chromium Code Reviews| 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 |