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

Unified Diff: src/ia32/disasm-ia32.cc

Issue 770183002: [ia32] Introduce vex prefix version of float64 arithmetic binop (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years 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/ia32/assembler-ia32.cc ('k') | test/cctest/test-disasm-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/disasm-ia32.cc
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index 252376162f65c27389af66e57b1dc7d573b5a113..57d1cc929c9b778728a2dbdee77e2507007a3cf4 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -246,6 +246,9 @@ class DisassemblerIA32 {
DisassemblerIA32(const NameConverter& converter,
bool abort_on_unimplemented = true)
: converter_(converter),
+ vex_byte0_(0),
+ vex_byte1_(0),
+ vex_byte2_(0),
instruction_table_(InstructionTable::get_instance()),
tmp_buffer_pos_(0),
abort_on_unimplemented_(abort_on_unimplemented) {
@@ -260,6 +263,9 @@ class DisassemblerIA32 {
private:
const NameConverter& converter_;
+ byte vex_byte0_; // 0xc4 or 0xc5
+ byte vex_byte1_;
+ byte vex_byte2_; // only for 3 bytes vex prefix
InstructionTable* instruction_table_;
v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
unsigned int tmp_buffer_pos_;
@@ -287,6 +293,57 @@ class DisassemblerIA32 {
kSAR = 7
};
+ bool vex_128() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 4) != 1;
+ }
+
+ bool vex_66() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 1;
+ }
+
+ bool vex_f3() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 2;
+ }
+
+ bool vex_f2() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 3;
+ }
+
+ bool vex_w() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte2_ & 0x80) == 1;
+ }
+
+ bool vex_0f() {
+ if (vex_byte0_ == 0xc5) return true;
+ return (vex_byte1_ & 3) == 1;
+ }
+
+ bool vex_0f38() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte1_ & 3) == 2;
+ }
+
+ bool vex_0f3a() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte1_ & 3) == 3;
+ }
+
+ int vex_vreg() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return ~(checked >> 3) & 0xf;
+ }
+
+ char float_size_code() { return "sd"[vex_w()]; }
const char* NameOfCPURegister(int reg) const {
return converter_.NameOfCPURegister(reg);
@@ -340,6 +397,7 @@ class DisassemblerIA32 {
int FPUInstruction(byte* data);
int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
+ int AVXInstruction(byte* data);
void AppendToBuffer(const char* format, ...);
@@ -679,6 +737,44 @@ int DisassemblerIA32::CMov(byte* data) {
}
+int DisassemblerIA32::AVXInstruction(byte* data) {
+ byte opcode = *data;
+ byte* current = data + 1;
+ if (vex_f2() && vex_0f()) {
+ int mod, regop, rm, vvvv = vex_vreg();
+ get_modrm(*current, &mod, &regop, &rm);
+ switch (opcode) {
+ case 0x58:
+ AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x59:
+ AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x5c:
+ AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x5e:
+ AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ default:
+ UnimplementedInstruction();
+ }
+ } else {
+ UnimplementedInstruction();
+ }
+
+ return static_cast<int>(current - data);
+}
+
+
// Returns number of bytes used, including *data.
int DisassemblerIA32::FPUInstruction(byte* data) {
byte escape_opcode = *data;
@@ -903,65 +999,81 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
} else if (*data == 0x2E /*cs*/) {
branch_hint = "predicted not taken";
data++;
+ } else if (*data == 0xC4 && *(data + 1) >= 0xc0) {
+ vex_byte0_ = *data;
+ vex_byte1_ = *(data + 1);
+ vex_byte2_ = *(data + 2);
+ data += 3;
+ } else if (*data == 0xC5 && *(data + 1) >= 0xc0) {
+ vex_byte0_ = *data;
+ vex_byte1_ = *(data + 1);
+ data += 2;
}
+
bool processed = true; // Will be set to false if the current instruction
// is not in 'instructions' table.
- const InstructionDesc& idesc = instruction_table_->Get(*data);
- switch (idesc.type) {
- case ZERO_OPERANDS_INSTR:
- AppendToBuffer(idesc.mnem);
- data++;
- break;
+ // Decode AVX instructions.
+ if (vex_byte0_ != 0) {
+ data += AVXInstruction(data);
+ } else {
+ const InstructionDesc& idesc = instruction_table_->Get(*data);
+ switch (idesc.type) {
+ case ZERO_OPERANDS_INSTR:
+ AppendToBuffer(idesc.mnem);
+ data++;
+ break;
- case TWO_OPERANDS_INSTR:
- data++;
- data += PrintOperands(idesc.mnem, idesc.op_order_, data);
- break;
+ case TWO_OPERANDS_INSTR:
+ data++;
+ data += PrintOperands(idesc.mnem, idesc.op_order_, data);
+ break;
- case JUMP_CONDITIONAL_SHORT_INSTR:
- data += JumpConditionalShort(data, branch_hint);
- break;
+ case JUMP_CONDITIONAL_SHORT_INSTR:
+ data += JumpConditionalShort(data, branch_hint);
+ break;
- case REGISTER_INSTR:
- AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
- data++;
- break;
+ case REGISTER_INSTR:
+ AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
+ data++;
+ break;
- case MOVE_REG_INSTR: {
- byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
- AppendToBuffer("mov %s,%s",
- NameOfCPURegister(*data & 0x07),
- NameOfAddress(addr));
- data += 5;
- break;
- }
+ case MOVE_REG_INSTR: {
+ byte* addr =
+ reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+ AppendToBuffer("mov %s,%s", NameOfCPURegister(*data & 0x07),
+ NameOfAddress(addr));
+ data += 5;
+ break;
+ }
- case CALL_JUMP_INSTR: {
- byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5;
- AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
- data += 5;
- break;
- }
+ case CALL_JUMP_INSTR: {
+ byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
+ AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
+ data += 5;
+ break;
+ }
- case SHORT_IMMEDIATE_INSTR: {
- byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
- AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
- data += 5;
- break;
- }
+ case SHORT_IMMEDIATE_INSTR: {
+ byte* addr =
+ reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+ AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
+ data += 5;
+ break;
+ }
- case BYTE_IMMEDIATE_INSTR: {
- AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
- data += 2;
- break;
- }
+ case BYTE_IMMEDIATE_INSTR: {
+ AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
+ data += 2;
+ break;
+ }
- case NO_INSTR:
- processed = false;
- break;
+ case NO_INSTR:
+ processed = false;
+ break;
- default:
- UNIMPLEMENTED(); // This type is not implemented.
+ default:
+ UNIMPLEMENTED(); // This type is not implemented.
+ }
}
//----------------------------
if (!processed) {
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | test/cctest/test-disasm-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698