| Index: src/x64/assembler-x64.h
|
| diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
|
| index d47ca32e0dd7f457d027438a4ff8db4b3a3ee100..6a75485d995d879414c6f7ea3d2f1d8f88158d36 100644
|
| --- a/src/x64/assembler-x64.h
|
| +++ b/src/x64/assembler-x64.h
|
| @@ -680,6 +680,8 @@ class Assembler : public AssemblerBase {
|
| // - Instructions on 64-bit (quadword) operands/registers use 'q'.
|
| // - Instructions on operands/registers with pointer size use 'p'.
|
|
|
| + STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
|
| +
|
| #define DECLARE_INSTRUCTION(instruction) \
|
| template<class P1> \
|
| void instruction##p(P1 p1) { \
|
| @@ -806,15 +808,15 @@ class Assembler : public AssemblerBase {
|
| void cmpb_al(Immediate src);
|
|
|
| void cmpb(Register dst, Register src) {
|
| - arithmetic_op(0x3A, dst, src);
|
| + arithmetic_op_8(0x3A, dst, src);
|
| }
|
|
|
| void cmpb(Register dst, const Operand& src) {
|
| - arithmetic_op(0x3A, dst, src);
|
| + arithmetic_op_8(0x3A, dst, src);
|
| }
|
|
|
| void cmpb(const Operand& dst, Register src) {
|
| - arithmetic_op(0x38, src, dst);
|
| + arithmetic_op_8(0x38, src, dst);
|
| }
|
|
|
| void cmpb(const Operand& dst, Immediate src) {
|
| @@ -1425,14 +1427,16 @@ class Assembler : public AssemblerBase {
|
| // AND, OR, XOR, or CMP. The encodings of these operations are all
|
| // similar, differing just in the opcode or in the reg field of the
|
| // ModR/M byte.
|
| + void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
|
| + void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
|
| void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
|
| void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
|
| - void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
|
| - void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
|
| - void arithmetic_op(byte opcode, Register reg, Register rm_reg);
|
| - void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
|
| - void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
|
| - void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
|
| + // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
|
| + void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
|
| + void arithmetic_op(byte opcode,
|
| + Register reg,
|
| + const Operand& rm_reg,
|
| + int size);
|
| // Operate on a byte in memory or register.
|
| void immediate_arithmetic_op_8(byte subcode,
|
| Register dst,
|
| @@ -1447,13 +1451,15 @@ class Assembler : public AssemblerBase {
|
| void immediate_arithmetic_op_16(byte subcode,
|
| const Operand& dst,
|
| Immediate src);
|
| - // Operate on a 32-bit word in memory or register.
|
| - void immediate_arithmetic_op_32(byte subcode,
|
| - Register dst,
|
| - Immediate src);
|
| - void immediate_arithmetic_op_32(byte subcode,
|
| - const Operand& dst,
|
| - Immediate src);
|
| + // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
|
| + void immediate_arithmetic_op(byte subcode,
|
| + Register dst,
|
| + Immediate src,
|
| + int size);
|
| + void immediate_arithmetic_op(byte subcode,
|
| + const Operand& dst,
|
| + Immediate src,
|
| + int size);
|
|
|
| // Emit machine code for a shift operation.
|
| void shift(Register dst, Immediate shift_amount, int subcode);
|
| @@ -1473,138 +1479,63 @@ class Assembler : public AssemblerBase {
|
|
|
| // Arithmetics
|
| void emit_add(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x03, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x03, dst, src);
|
| - }
|
| + arithmetic_op(0x03, dst, src, size);
|
| }
|
|
|
| void emit_add(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x0, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x0, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x0, dst, src, size);
|
| }
|
|
|
| void emit_add(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x03, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x03, dst, src);
|
| - }
|
| + arithmetic_op(0x03, dst, src, size);
|
| }
|
|
|
| void emit_add(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x1, src, dst);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x1, src, dst);
|
| - }
|
| + arithmetic_op(0x1, src, dst, size);
|
| }
|
|
|
| void emit_add(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x0, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x0, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x0, dst, src, size);
|
| }
|
|
|
| void emit_and(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x23, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x23, dst, src);
|
| - }
|
| + arithmetic_op(0x23, dst, src, size);
|
| }
|
|
|
| void emit_and(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x23, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x23, dst, src);
|
| - }
|
| + arithmetic_op(0x23, dst, src, size);
|
| }
|
|
|
| void emit_and(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x21, src, dst);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x21, src, dst);
|
| - }
|
| + arithmetic_op(0x21, src, dst, size);
|
| }
|
|
|
| void emit_and(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x4, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x4, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x4, dst, src, size);
|
| }
|
|
|
| void emit_and(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x4, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x4, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x4, dst, src, size);
|
| }
|
|
|
| void emit_cmp(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x3B, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x3B, dst, src);
|
| - }
|
| + arithmetic_op(0x3B, dst, src, size);
|
| }
|
|
|
| void emit_cmp(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x3B, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x3B, dst, src);
|
| - }
|
| + arithmetic_op(0x3B, dst, src, size);
|
| }
|
|
|
| void emit_cmp(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x39, src, dst);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x39, src, dst);
|
| - }
|
| + arithmetic_op(0x39, src, dst, size);
|
| }
|
|
|
| void emit_cmp(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x7, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x7, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x7, dst, src, size);
|
| }
|
|
|
| void emit_cmp(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x7, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x7, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x7, dst, src, size);
|
| }
|
|
|
| void emit_dec(Register dst, int size);
|
| @@ -1644,99 +1575,49 @@ class Assembler : public AssemblerBase {
|
| void emit_not(const Operand& dst, int size);
|
|
|
| void emit_or(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x0B, dst, src);
|
| - } else {
|
| - arithmetic_op_32(0x0B, dst, src);
|
| - }
|
| + arithmetic_op(0x0B, dst, src, size);
|
| }
|
|
|
| void emit_or(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x0B, dst, src);
|
| - } else {
|
| - arithmetic_op_32(0x0B, dst, src);
|
| - }
|
| + arithmetic_op(0x0B, dst, src, size);
|
| }
|
|
|
| void emit_or(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x9, src, dst);
|
| - } else {
|
| - arithmetic_op_32(0x9, src, dst);
|
| - }
|
| + arithmetic_op(0x9, src, dst, size);
|
| }
|
|
|
| void emit_or(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x1, dst, src);
|
| - } else {
|
| - immediate_arithmetic_op_32(0x1, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x1, dst, src, size);
|
| }
|
|
|
| void emit_or(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x1, dst, src);
|
| - } else {
|
| - immediate_arithmetic_op_32(0x1, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x1, dst, src, size);
|
| }
|
|
|
| void emit_repmovs(int size);
|
|
|
| void emit_sbb(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x1b, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x1b, dst, src);
|
| - }
|
| + arithmetic_op(0x1b, dst, src, size);
|
| }
|
|
|
| void emit_sub(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x2B, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x2B, dst, src);
|
| - }
|
| + arithmetic_op(0x2B, dst, src, size);
|
| }
|
|
|
| void emit_sub(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x5, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x5, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x5, dst, src, size);
|
| }
|
|
|
| void emit_sub(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x2B, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x2B, dst, src);
|
| - }
|
| + arithmetic_op(0x2B, dst, src, size);
|
| }
|
|
|
| void emit_sub(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x29, src, dst);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x29, src, dst);
|
| - }
|
| + arithmetic_op(0x29, src, dst, size);
|
| }
|
|
|
| void emit_sub(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x5, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x5, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x5, dst, src, size);
|
| }
|
|
|
| void emit_test(Register dst, Register src, int size);
|
| @@ -1748,52 +1629,29 @@ class Assembler : public AssemblerBase {
|
| void emit_xchg(Register dst, Register src, int size);
|
|
|
| void emit_xor(Register dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - if (dst.code() == src.code()) {
|
| - arithmetic_op_32(0x33, dst, src);
|
| - } else {
|
| - arithmetic_op(0x33, dst, src);
|
| - }
|
| + if (size == kInt64Size && dst.code() == src.code()) {
|
| + // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
|
| + // there is no need to make this a 64 bit operation.
|
| + arithmetic_op(0x33, dst, src, kInt32Size);
|
| } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x33, dst, src);
|
| + arithmetic_op(0x33, dst, src, size);
|
| }
|
| }
|
|
|
| void emit_xor(Register dst, const Operand& src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x33, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x33, dst, src);
|
| - }
|
| + arithmetic_op(0x33, dst, src, size);
|
| }
|
|
|
| void emit_xor(Register dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x6, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x6, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x6, dst, src, size);
|
| }
|
|
|
| void emit_xor(const Operand& dst, Immediate src, int size) {
|
| - if (size == kInt64Size) {
|
| - immediate_arithmetic_op(0x6, dst, src);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - immediate_arithmetic_op_32(0x6, dst, src);
|
| - }
|
| + immediate_arithmetic_op(0x6, dst, src, size);
|
| }
|
|
|
| void emit_xor(const Operand& dst, Register src, int size) {
|
| - if (size == kInt64Size) {
|
| - arithmetic_op(0x31, src, dst);
|
| - } else {
|
| - ASSERT(size == kInt32Size);
|
| - arithmetic_op_32(0x31, src, dst);
|
| - }
|
| + arithmetic_op(0x31, src, dst, size);
|
| }
|
|
|
| friend class CodePatcher;
|
|
|