Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Unified Diff: src/x64/assembler-x64.cc

Issue 2605863002: [turbofan] Improve codegen for 8- and 16-bit memory comparisons on Intel platforms (Closed)
Patch Set: Fix assert Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | test/cctest/test-assembler-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | test/cctest/test-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698