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; |