Index: src/x64/assembler-x64.cc |
=================================================================== |
--- src/x64/assembler-x64.cc (revision 2419) |
+++ src/x64/assembler-x64.cc (working copy) |
@@ -73,46 +73,9 @@ |
XMMRegister xmm15 = { 15 }; |
-Operand::Operand(Register base, int32_t disp): rex_(0) { |
- len_ = 1; |
- if (base.is(rsp) || base.is(r12)) { |
- // SIB byte is needed to encode (rsp + offset) or (r12 + offset). |
- set_sib(times_1, rsp, base); |
- } |
+// ----------------------------------------------------------------------------- |
+// Implementation of CpuFeatures |
- if (disp == 0 && !base.is(rbp) && !base.is(r13)) { |
- set_modrm(0, base); |
- } else if (is_int8(disp)) { |
- set_modrm(1, base); |
- set_disp8(disp); |
- } else { |
- set_modrm(2, base); |
- set_disp32(disp); |
- } |
-} |
- |
- |
-Operand::Operand(Register base, |
- Register index, |
- ScaleFactor scale, |
- int32_t disp): rex_(0) { |
- ASSERT(!index.is(rsp)); |
- len_ = 1; |
- set_sib(scale, index, base); |
- if (disp == 0 && !base.is(rbp) && !base.is(r13)) { |
- // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits |
- // possibly set by set_sib. |
- set_modrm(0, rsp); |
- } else if (is_int8(disp)) { |
- set_modrm(1, rsp); |
- set_disp8(disp); |
- } else { |
- set_modrm(2, rsp); |
- set_disp32(disp); |
- } |
-} |
- |
- |
// The required user mode extensions in X64 are (from AMD64 ABI Table A.1): |
// fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall |
uint64_t CpuFeatures::supported_ = kDefaultCpuFeatures; |
@@ -193,7 +156,72 @@ |
ASSERT(IsSupported(CMOV)); |
} |
+ |
// ----------------------------------------------------------------------------- |
+// Implementation of RelocInfo |
+ |
+// Patch the code at the current PC with a call to the target address. |
+// Additional guard int3 instructions can be added if required. |
+void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
+ // Call instruction takes up 13 bytes and int3 takes up one byte. |
+ Address patch_site = pc_; |
+ Memory::uint16_at(patch_site) = 0xBA49u; // movq r10, imm64 |
+ // Write "0x00, call r10" starting at last byte of address. We overwrite |
+ // the 0x00 later, and this lets us write a uint32. |
+ Memory::uint32_at(patch_site + 9) = 0xD2FF4900u; // 0x00, call r10 |
+ Memory::Address_at(patch_site + 2) = target; |
+ |
+ // Add the requested number of int3 instructions after the call. |
+ for (int i = 0; i < guard_bytes; i++) { |
+ *(patch_site + 13 + i) = 0xCC; // int3 |
+ } |
+} |
+ |
+ |
+// ----------------------------------------------------------------------------- |
+// Implementation of Operand |
+ |
+Operand::Operand(Register base, int32_t disp): rex_(0) { |
+ len_ = 1; |
+ if (base.is(rsp) || base.is(r12)) { |
+ // SIB byte is needed to encode (rsp + offset) or (r12 + offset). |
+ set_sib(times_1, rsp, base); |
+ } |
+ |
+ if (disp == 0 && !base.is(rbp) && !base.is(r13)) { |
+ set_modrm(0, base); |
+ } else if (is_int8(disp)) { |
+ set_modrm(1, base); |
+ set_disp8(disp); |
+ } else { |
+ set_modrm(2, base); |
+ set_disp32(disp); |
+ } |
+} |
+ |
+ |
+Operand::Operand(Register base, |
+ Register index, |
+ ScaleFactor scale, |
+ int32_t disp): rex_(0) { |
+ ASSERT(!index.is(rsp)); |
+ len_ = 1; |
+ set_sib(scale, index, base); |
+ if (disp == 0 && !base.is(rbp) && !base.is(r13)) { |
+ // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits |
+ // possibly set by set_sib. |
+ set_modrm(0, rsp); |
+ } else if (is_int8(disp)) { |
+ set_modrm(1, rsp); |
+ set_disp8(disp); |
+ } else { |
+ set_modrm(2, rsp); |
+ set_disp32(disp); |
+ } |
+} |
+ |
+ |
+// ----------------------------------------------------------------------------- |
// Implementation of Assembler |
#ifdef GENERATED_CODE_COVERAGE |