Index: src/x64/assembler-x64.cc |
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc |
index 7a7fc6c87bcae85226d288b86a25060ab907ac49..aeb4ddfc6bd350630b136cafa9042ee3e906eb6e 100644 |
--- a/src/x64/assembler-x64.cc |
+++ b/src/x64/assembler-x64.cc |
@@ -2045,159 +2045,137 @@ void Assembler::store_rax(ExternalReference ref) { |
void Assembler::testb(Register dst, Register src) { |
EnsureSpace ensure_space(this); |
- if (src.low_bits() == 4) { |
- emit_rex_32(src, dst); |
- emit(0x84); |
- emit_modrm(src, dst); |
- } else { |
- if (!dst.is_byte_register() || !src.is_byte_register()) { |
- // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
- emit_rex_32(dst, src); |
- } |
- emit(0x84); |
- emit_modrm(dst, src); |
- } |
+ emit_test(dst, src, sizeof(int8_t)); |
} |
- |
void Assembler::testb(Register reg, Immediate mask) { |
DCHECK(is_int8(mask.value_) || is_uint8(mask.value_)); |
- EnsureSpace ensure_space(this); |
- if (reg.is(rax)) { |
- emit(0xA8); |
- emit(mask.value_); // Low byte emitted. |
- } else { |
- if (!reg.is_byte_register()) { |
- // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
- emit_rex_32(reg); |
- } |
- emit(0xF6); |
- emit_modrm(0x0, reg); |
- emit(mask.value_); // Low byte emitted. |
- } |
+ emit_test(reg, mask, sizeof(int8_t)); |
} |
- |
void Assembler::testb(const Operand& op, Immediate mask) { |
DCHECK(is_int8(mask.value_) || is_uint8(mask.value_)); |
- EnsureSpace ensure_space(this); |
- emit_optional_rex_32(rax, op); |
- emit(0xF6); |
- emit_operand(rax, op); // Operation code 0 |
- emit(mask.value_); // Low byte emitted. |
+ emit_test(op, mask, sizeof(int8_t)); |
} |
void Assembler::testb(const Operand& op, Register reg) { |
- EnsureSpace ensure_space(this); |
- if (!reg.is_byte_register()) { |
- // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
- emit_rex_32(reg, op); |
- } else { |
- emit_optional_rex_32(reg, op); |
- } |
- emit(0x84); |
- emit_operand(reg, op); |
+ emit_test(op, reg, sizeof(int8_t)); |
} |
void Assembler::testw(Register dst, Register src) { |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- if (!dst.is_byte_register() || !src.is_byte_register()) { |
- // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
- emit_rex_32(dst, src); |
- } |
- emit(0x85); |
- emit_modrm(dst, src); |
+ emit_test(dst, src, sizeof(uint16_t)); |
} |
void Assembler::testw(Register reg, Immediate mask) { |
- DCHECK(is_int16(mask.value_) || is_uint16(mask.value_)); |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- if (reg.is(rax)) { |
- emit(0xA9); |
- emitw(mask.value_); |
- } else { |
- if (!reg.is_byte_register()) { |
- emit_rex_32(reg); |
- } |
- emit(0xF7); |
- emit_modrm(0x0, reg); |
- emitw(mask.value_); |
- } |
+ emit_test(reg, mask, sizeof(int16_t)); |
} |
void Assembler::testw(const Operand& op, Immediate mask) { |
- DCHECK(is_int16(mask.value_) || is_uint16(mask.value_)); |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- emit_optional_rex_32(rax, op); |
- emit(0xF7); |
- emit_operand(rax, op); |
- emitw(mask.value_); |
+ emit_test(op, mask, sizeof(int16_t)); |
} |
void Assembler::testw(const Operand& op, Register reg) { |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- emit_optional_rex_32(reg, op); |
- emit(0x85); |
- emit_operand(rax, op); |
+ emit_test(op, reg, sizeof(int16_t)); |
} |
void Assembler::emit_test(Register dst, Register src, int size) { |
EnsureSpace ensure_space(this); |
- if (src.low_bits() == 4) { |
- emit_rex(src, dst, size); |
- emit(0x85); |
- emit_modrm(src, dst); |
+ if (src.low_bits() == 4) std::swap(dst, src); |
+ if (size == sizeof(int16_t)) { |
+ emit(0x66); |
+ size = sizeof(int32_t); |
+ } |
+ bool byte_operand = size == sizeof(int8_t); |
+ if (byte_operand) { |
+ size = sizeof(int32_t); |
+ if (!src.is_byte_register() || !dst.is_byte_register()) { |
+ emit_rex_32(dst, src); |
+ } |
} else { |
emit_rex(dst, src, size); |
- emit(0x85); |
- emit_modrm(dst, src); |
} |
+ emit(byte_operand ? 0x84 : 0x85); |
+ emit_modrm(dst, src); |
} |
void Assembler::emit_test(Register reg, Immediate mask, int size) { |
- // testl with a mask that fits in the low byte is exactly testb. |
if (is_uint8(mask.value_)) { |
- testb(reg, mask); |
- return; |
+ size = sizeof(int8_t); |
+ } else if (is_uint16(mask.value_)) { |
+ size = sizeof(int16_t); |
} |
EnsureSpace ensure_space(this); |
- if (reg.is(rax)) { |
- emit_rex(rax, size); |
- emit(0xA9); |
- emit(mask); |
+ bool half_word = size == sizeof(int16_t); |
+ if (half_word) { |
+ emit(0x66); |
+ size = sizeof(int32_t); |
+ } |
+ bool byte_operand = size == sizeof(int8_t); |
+ if (byte_operand) { |
+ size = sizeof(int32_t); |
+ if (!reg.is_byte_register()) emit_rex_32(reg); |
} else { |
emit_rex(reg, size); |
- emit(0xF7); |
+ } |
+ if (reg.is(rax)) { |
+ emit(byte_operand ? 0xA8 : 0xA9); |
+ } else { |
+ emit(byte_operand ? 0xF6 : 0xF7); |
emit_modrm(0x0, reg); |
+ } |
+ if (byte_operand) { |
+ emit(mask.value_); |
+ } else if (half_word) { |
+ emitw(mask.value_); |
+ } else { |
emit(mask); |
} |
} |
- |
void Assembler::emit_test(const Operand& op, Immediate mask, int size) { |
- // testl with a mask that fits in the low byte is exactly testb. |
if (is_uint8(mask.value_)) { |
- testb(op, mask); |
- return; |
+ size = sizeof(int8_t); |
+ } else if (is_uint16(mask.value_)) { |
+ size = sizeof(int16_t); |
} |
EnsureSpace ensure_space(this); |
+ bool half_word = size == sizeof(int16_t); |
+ if (half_word) { |
+ emit(0x66); |
+ size = sizeof(int32_t); |
+ } |
+ bool byte_operand = size == sizeof(int8_t); |
+ if (byte_operand) { |
+ size = sizeof(int32_t); |
+ } |
emit_rex(rax, op, size); |
- emit(0xF7); |
+ emit(byte_operand ? 0xF6 : 0xF7); |
emit_operand(rax, op); // Operation code 0 |
- emit(mask); |
+ if (byte_operand) { |
+ emit(mask.value_); |
+ } else if (half_word) { |
+ emitw(mask.value_); |
+ } else { |
+ emit(mask); |
+ } |
} |
- |
void Assembler::emit_test(const Operand& op, Register reg, int size) { |
EnsureSpace ensure_space(this); |
- emit_rex(reg, op, size); |
- emit(0x85); |
+ if (size == sizeof(int16_t)) { |
+ emit(0x66); |
+ size = sizeof(int32_t); |
+ } |
+ bool byte_operand = size == sizeof(int8_t); |
+ if (byte_operand) { |
+ size = sizeof(int32_t); |
+ if (!reg.is_byte_register()) emit_rex_32(reg, op); |
+ } else { |
+ emit_rex(reg, op, size); |
+ } |
+ emit(byte_operand ? 0x84 : 0x85); |
emit_operand(reg, op); |
} |