| Index: src/x64/assembler-x64.cc
|
| diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
|
| index 3f3d34e7729bd4305261ebafd2621fa315bbd64d..3fbd2ba43cb9efcd968763177fc5a7543bc7bbff 100644
|
| --- a/src/x64/assembler-x64.cc
|
| +++ b/src/x64/assembler-x64.cc
|
| @@ -255,6 +255,53 @@ Operand::Operand(Register base,
|
| }
|
|
|
|
|
| +Operand::Operand(const Operand& base, int32_t displacement_delta) {
|
| + rex_ = base.rex_;
|
| + len_ = 1;
|
| + byte modrm = base.buf_[0];
|
| + ASSERT_NE(0xC0, modrm & 0xC0); // Must be a memory operand.
|
| + if ((modrm & 7) == rsp.code()) {
|
| + // Has SIB byte
|
| + buf_[1] = base.buf_[1];
|
| + len_ = 2;
|
| + }
|
| + int old_displacement;
|
| + switch (modrm >> 6) {
|
| + case 0:
|
| + // No current displacement, unless base is rbp/r13.
|
| + if ((modrm & 7) != rbp.code()) {
|
| + old_displacement = 0;
|
| + break;
|
| + }
|
| + // Fallthrough to 32-bit displacement.
|
| + case 2:
|
| + // Current 32-bit displacement.
|
| + old_displacement =
|
| + Memory::int32_at(const_cast<Address>(base.buf_ + len_));
|
| + break;
|
| + case 1:
|
| + // Current 8-bit displacement.
|
| + old_displacement = static_cast<int8_t>(base.buf_[len_]);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + old_displacement = 0; // Seems to be used uninitialized otherwise.
|
| + }
|
| + int32_t displacement = old_displacement + displacement_delta;
|
| + modrm = modrm & 0x3f;
|
| + if (displacement == 0 && (modrm & 7) != rbp.code()) {
|
| + // Zero mod part of ModR/M and no displacement.
|
| + } else if (is_int8(displacement)) {
|
| + modrm = modrm | 0x40;
|
| + set_disp8(displacement);
|
| + } else {
|
| + modrm = modrm | 0x80u;
|
| + set_disp32(displacement);
|
| + }
|
| + buf_[0] = modrm;
|
| +}
|
| +
|
| +
|
| // -----------------------------------------------------------------------------
|
| // Implementation of Assembler
|
|
|
| @@ -1970,6 +2017,31 @@ void Assembler::fstp_d(const Operand& adr) {
|
| }
|
|
|
|
|
| +void Assembler::fst_d(const Operand& adr) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_optional_rex_32(adr);
|
| + emit(0xDD);
|
| + emit_operand(2, adr);
|
| +}
|
| +
|
| +
|
| +void Assembler::fstp(int stack_slot) {
|
| + ASSERT(is_uint3(stack_slot));
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit(0xDD);
|
| + emit(0xD8 + stack_slot);
|
| +}
|
| +
|
| +void Assembler::fst(int stack_slot) {
|
| + ASSERT(is_uint3(stack_slot));
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit(0xDD);
|
| + emit(0xD0 + stack_slot);
|
| +}
|
| +
|
| void Assembler::fild_s(const Operand& adr) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| @@ -2175,6 +2247,13 @@ void Assembler::ftst() {
|
| }
|
|
|
|
|
| +void Assembler::fucom(int i) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_farith(0xDD, 0xE0, i);
|
| +}
|
| +
|
| +
|
| void Assembler::fucomp(int i) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| @@ -2206,6 +2285,13 @@ void Assembler::fnstsw_ax() {
|
| }
|
|
|
|
|
| +void Assembler::fxam() {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit(0xD9);
|
| + emit(0xE5);
|
| +}
|
| +
|
| void Assembler::fwait() {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
|
|