Chromium Code Reviews| Index: src/x64/assembler-x64.cc |
| diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc |
| index acea713198a17f41d959484b2c992097b2dab05d..86e11653383ca2266c5a2dfaf3f95ea71ebed995 100644 |
| --- a/src/x64/assembler-x64.cc |
| +++ b/src/x64/assembler-x64.cc |
| @@ -271,12 +271,13 @@ void Assembler::GrowBuffer() { |
| } |
| -void Assembler::emit_operand(Register reg, const Operand& adr) { |
| +void Assembler::emit_operand(int rm, const Operand& adr) { |
| + 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
|
| const unsigned length = adr.len_; |
| ASSERT(length > 0); |
| // Emit updated ModRM byte containing the given register. |
| - pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); |
| + pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3); |
| // Emit the rest of the encoded operand. |
| for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
| @@ -362,6 +363,18 @@ void Assembler::call(Label* L) { |
| } |
| +void Assembler::call(Register adr) { |
| + EnsureSpace ensure_space(this); |
| + last_pc_ = pc_; |
| + // Opcode: FF /2 r64 |
| + if (!is_uint3(adr.code())) { |
| + emit_rex_64(adr); |
| + } |
| + emit(0xFF); |
| + emit(0xD0 | (adr.code() & 0x07)); |
| +} |
| + |
| + |
| void Assembler::dec(Register dst) { |
| EnsureSpace ensure_space(this); |
| last_pc_ = pc_; |
| @@ -479,6 +492,18 @@ void Assembler::jmp(Label* L) { |
| } |
| +void Assembler::jmp(Register target) { |
| + EnsureSpace ensure_space(this); |
| + last_pc_ = pc_; |
| + // Opcode FF/4 r64 |
| + if (!is_uint3(target.code())) { |
| + emit_rex_64(target); |
| + } |
| + emit(0xFF); |
| + emit(0xE0 | target.code() & 0x07); |
| +} |
| + |
| + |
| void Assembler::movq(Register dst, const Operand& src) { |
| EnsureSpace ensure_space(this); |
| last_pc_ = pc_; |
| @@ -559,6 +584,93 @@ void Assembler::not_(const Operand& dst) { |
| } |
| +void Assembler::nop(int n) { |
| + // The recommended muti-byte sequences of NOP instructions from the Intel 64 |
| + // and IA-32 Architectures Software Developer's Manual. |
| + // |
| + // Length Assembly Byte Sequence |
| + // 2 bytes 66 NOP 66 90H |
| + // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H |
| + // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H |
| + // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H |
| + // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H |
| + // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H |
| + // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H |
| + // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 |
| + // 00000000H] 00H |
| + |
| + ASSERT(1 <= n); |
| + ASSERT(n <= 9); |
| + EnsureSpace ensure_space(this); |
| + last_pc_ = pc_; |
| + switch (n) { |
| + case 1: |
| + emit(0x90); |
| + return; |
| + case 2: |
| + emit(0x66); |
| + emit(0x90); |
| + return; |
| + case 3: |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x00); |
| + return; |
| + case 4: |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x40); |
| + emit(0x00); |
| + return; |
| + case 5: |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x44); |
| + emit(0x00); |
| + emit(0x00); |
| + return; |
| + case 6: |
| + emit(0x66); |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x44); |
| + emit(0x00); |
| + emit(0x00); |
| + return; |
| + case 7: |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x80); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + return; |
| + case 8: |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x84); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + return; |
| + case 9: |
| + emit(0x66); |
| + emit(0x0f); |
| + emit(0x1f); |
| + emit(0x84); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + emit(0x00); |
| + return; |
| + } |
| +} |
| + |
| + |
| void Assembler::pop(Register dst) { |
| EnsureSpace ensure_space(this); |
| last_pc_ = pc_; |