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

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

Issue 155346: X64: Fixed test .status format, and made test.py forward arch to scons. (Closed)
Patch Set: Created 11 years, 5 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/x64/assembler-x64.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/disasm-x64.cc
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index f962c0193f37c16f659bc6986b499565b20c1f83..f350360939acbb8c0939dbed131a27e4549c4fca 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -34,8 +34,15 @@
namespace disasm {
-enum OperandOrder {
- UNSET_OP_ORDER = 0, REG_OPER_OP_ORDER, OPER_REG_OP_ORDER
+enum OperandType {
+ UNSET_OP_ORDER = 0,
+ // Operand size decides between 16, 32 and 64 bit operands.
+ REG_OPER_OP_ORDER = 1, // Register destination, operand source.
+ OPER_REG_OP_ORDER = 2, // Operand destination, register source.
+ // Fixed 8-bit operands.
+ BYTE_SIZE_OPERAND_FLAG = 4,
+ BYTE_REG_OPER_OP_ORDER = REG_OPER_OP_ORDER | BYTE_SIZE_OPERAND_FLAG,
+ BYTE_OPER_REG_OP_ORDER = OPER_REG_OP_ORDER | BYTE_SIZE_OPERAND_FLAG
};
//------------------------------------------------------------------
@@ -43,28 +50,53 @@ enum OperandOrder {
//------------------------------------------------------------------
struct ByteMnemonic {
int b; // -1 terminates, otherwise must be in range (0..255)
- OperandOrder op_order_;
+ OperandType op_order_;
const char* mnem;
};
static ByteMnemonic two_operands_instr[] = {
- { 0x03, REG_OPER_OP_ORDER, "add" },
- { 0x21, OPER_REG_OP_ORDER, "and" },
- { 0x23, REG_OPER_OP_ORDER, "and" },
- { 0x3B, REG_OPER_OP_ORDER, "cmp" },
- { 0x8D, REG_OPER_OP_ORDER, "lea" },
- { 0x09, OPER_REG_OP_ORDER, "or" },
- { 0x0B, REG_OPER_OP_ORDER, "or" },
- { 0x1B, REG_OPER_OP_ORDER, "sbb" },
- { 0x29, OPER_REG_OP_ORDER, "sub" },
- { 0x2B, REG_OPER_OP_ORDER, "sub" },
- { 0x85, REG_OPER_OP_ORDER, "test" },
- { 0x31, OPER_REG_OP_ORDER, "xor" },
- { 0x33, REG_OPER_OP_ORDER, "xor" },
- { 0x87, REG_OPER_OP_ORDER, "xchg" },
- { 0x8A, REG_OPER_OP_ORDER, "movb" },
- { 0x8B, REG_OPER_OP_ORDER, "mov" },
+ { 0x00, BYTE_OPER_REG_OP_ORDER, "add" },
+ { 0x01, OPER_REG_OP_ORDER, "add" },
+ { 0x02, BYTE_REG_OPER_OP_ORDER, "add" },
+ { 0x03, REG_OPER_OP_ORDER, "add" },
+ { 0x08, BYTE_OPER_REG_OP_ORDER, "or" },
+ { 0x09, OPER_REG_OP_ORDER, "or" },
+ { 0x0A, BYTE_REG_OPER_OP_ORDER, "or" },
+ { 0x0B, REG_OPER_OP_ORDER, "or" },
+ { 0x10, BYTE_OPER_REG_OP_ORDER, "adc" },
+ { 0x11, OPER_REG_OP_ORDER, "adc" },
+ { 0x12, BYTE_REG_OPER_OP_ORDER, "adc" },
+ { 0x13, REG_OPER_OP_ORDER, "adc" },
+ { 0x18, BYTE_OPER_REG_OP_ORDER, "sbb" },
+ { 0x19, OPER_REG_OP_ORDER, "sbb" },
+ { 0x1A, BYTE_REG_OPER_OP_ORDER, "sbb" },
+ { 0x1B, REG_OPER_OP_ORDER, "sbb" },
+ { 0x20, BYTE_OPER_REG_OP_ORDER, "and" },
+ { 0x21, OPER_REG_OP_ORDER, "and" },
+ { 0x22, BYTE_REG_OPER_OP_ORDER, "and" },
+ { 0x23, REG_OPER_OP_ORDER, "and" },
+ { 0x28, BYTE_OPER_REG_OP_ORDER, "sub" },
+ { 0x29, OPER_REG_OP_ORDER, "sub" },
+ { 0x2A, BYTE_REG_OPER_OP_ORDER, "sub" },
+ { 0x2B, REG_OPER_OP_ORDER, "sub" },
+ { 0x30, BYTE_OPER_REG_OP_ORDER, "xor" },
+ { 0x31, OPER_REG_OP_ORDER, "xor" },
+ { 0x32, BYTE_REG_OPER_OP_ORDER, "xor" },
+ { 0x33, REG_OPER_OP_ORDER, "xor" },
+ { 0x38, BYTE_OPER_REG_OP_ORDER, "cmp" },
+ { 0x39, OPER_REG_OP_ORDER, "cmp" },
+ { 0x3A, BYTE_REG_OPER_OP_ORDER, "cmp" },
+ { 0x3B, REG_OPER_OP_ORDER, "cmp" },
+ { 0x8D, REG_OPER_OP_ORDER, "lea" },
+ { 0x84, BYTE_REG_OPER_OP_ORDER, "test" },
+ { 0x85, REG_OPER_OP_ORDER, "test" },
+ { 0x86, BYTE_REG_OPER_OP_ORDER, "xchg" },
+ { 0x87, REG_OPER_OP_ORDER, "xchg" },
+ { 0x88, BYTE_OPER_REG_OP_ORDER, "mov" },
+ { 0x89, OPER_REG_OP_ORDER, "mov" },
+ { 0x8A, BYTE_REG_OPER_OP_ORDER, "mov" },
+ { 0x8B, REG_OPER_OP_ORDER, "mov" },
{ -1, UNSET_OP_ORDER, "" }
};
@@ -97,6 +129,7 @@ static ByteMnemonic short_immediate_instr[] = {
{ 0x05, UNSET_OP_ORDER, "add" },
{ 0x0D, UNSET_OP_ORDER, "or" },
{ 0x15, UNSET_OP_ORDER, "adc" },
+ { 0x1D, UNSET_OP_ORDER, "sbb" },
{ 0x25, UNSET_OP_ORDER, "and" },
{ 0x2D, UNSET_OP_ORDER, "sub" },
{ 0x35, UNSET_OP_ORDER, "xor" },
@@ -127,7 +160,8 @@ enum InstructionType {
struct InstructionDesc {
const char* mnem;
InstructionType type;
- OperandOrder op_order_;
+ OperandType op_order_;
+ bool byte_size_operation; // Fixed 8-bit operation.
};
@@ -143,7 +177,7 @@ class InstructionTable {
void Clear();
void Init();
void CopyTable(ByteMnemonic bm[], InstructionType type);
- void SetTableRange(InstructionType type, byte start, byte end,
+ void SetTableRange(InstructionType type, byte start, byte end, bool byte_size,
const char* mnem);
void AddJumpConditionalShort();
};
@@ -157,9 +191,10 @@ InstructionTable::InstructionTable() {
void InstructionTable::Clear() {
for (int i = 0; i < 256; i++) {
- instructions_[i].mnem = "";
+ instructions_[i].mnem = "(bad)";
instructions_[i].type = NO_INSTR;
instructions_[i].op_order_ = UNSET_OP_ORDER;
+ instructions_[i].byte_size_operation = false;
}
}
@@ -170,9 +205,9 @@ void InstructionTable::Init() {
CopyTable(call_jump_instr, CALL_JUMP_INSTR);
CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
AddJumpConditionalShort();
- SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, "push");
- SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, "pop");
- SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
+ SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, false, "push");
+ SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, false, "pop");
+ SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, false, "mov");
}
@@ -180,20 +215,27 @@ void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {
for (int i = 0; bm[i].b >= 0; i++) {
InstructionDesc* id = &instructions_[bm[i].b];
id->mnem = bm[i].mnem;
- id->op_order_ = bm[i].op_order_;
- assert(id->type == NO_INSTR); // Information already entered
+ OperandType op_order = bm[i].op_order_;
+ id->op_order_ =
+ static_cast<OperandType>(op_order & ~BYTE_SIZE_OPERAND_FLAG);
+ assert(id->type == NO_INSTR); // Information not already entered
id->type = type;
+ id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0);
}
}
-void InstructionTable::SetTableRange(InstructionType type, byte start,
- byte end, const char* mnem) {
+void InstructionTable::SetTableRange(InstructionType type,
+ byte start,
+ byte end,
+ bool byte_size,
+ const char* mnem) {
for (byte b = start; b <= end; b++) {
InstructionDesc* id = &instructions_[b];
assert(id->type == NO_INSTR); // Information already entered
id->mnem = mnem;
id->type = type;
+ id->byte_size_operation = byte_size;
}
}
@@ -228,7 +270,8 @@ class DisassemblerX64 {
abort_on_unimplemented_(
unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE),
rex_(0),
- operand_size_(0) {
+ operand_size_(0),
+ byte_size_operand_(false) {
tmp_buffer_[0] = '\0';
}
@@ -240,6 +283,12 @@ class DisassemblerX64 {
int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
private:
+ enum OperandSize {
+ BYTE_SIZE = 0,
+ WORD_SIZE = 1,
+ DOUBLEWORD_SIZE = 2,
+ QUADWORD_SIZE = 3
+ };
const NameConverter& converter_;
v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
@@ -248,6 +297,8 @@ class DisassemblerX64 {
// Prefixes parsed
byte rex_;
byte operand_size_;
+ // Byte size operand override.
+ bool byte_size_operand_;
void setOperandSizePrefix(byte prefix) {
ASSERT_EQ(0x66, prefix);
@@ -272,12 +323,15 @@ class DisassemblerX64 {
bool rex_w() { return (rex_ & 0x08) != 0; }
- int operand_size() {
- return rex_w() ? 64 : (operand_size_ != 0) ? 16 : 32;
+ OperandSize operand_size() {
+ if (byte_size_operand_) return BYTE_SIZE;
+ if (rex_w()) return QUADWORD_SIZE;
+ if (operand_size_ != 0) return WORD_SIZE;
+ return DOUBLEWORD_SIZE;
}
char operand_size_code() {
- return rex_w() ? 'q' : (operand_size_ != 0) ? 'w' : 'l';
+ return "bwlq"[operand_size()];
}
const char* NameOfCPURegister(int reg) const {
@@ -312,7 +366,7 @@ class DisassemblerX64 {
int* base) {
*scale = (data >> 6) & 3;
*index = ((data >> 3) & 7) | (rex_x() ? 8 : 0);
- *base = data & 7 | (rex_b() ? 8 : 0);
+ *base = (data & 7) | (rex_b() ? 8 : 0);
}
typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const;
@@ -322,11 +376,12 @@ class DisassemblerX64 {
int PrintRightOperand(byte* modrmp);
int PrintRightByteOperand(byte* modrmp);
int PrintOperands(const char* mnem,
- OperandOrder op_order,
+ OperandType op_order,
byte* data);
+ int PrintImmediate(byte* data, OperandSize size);
int PrintImmediateOp(byte* data);
int F7Instruction(byte* data);
- int D1D3C1Instruction(byte* data);
+ int ShiftInstruction(byte* data);
int JumpShort(byte* data);
int JumpConditional(byte* data);
int JumpConditionalShort(byte* data);
@@ -451,6 +506,34 @@ int DisassemblerX64::PrintRightOperandHelper(
}
+int DisassemblerX64::PrintImmediate(byte* data, OperandSize size) {
William Hesse 2009/07/14 09:09:22 I would call the argument immediate_size, since th
+ int64_t value;
+ int count;
+ switch (size) {
+ case BYTE_SIZE:
+ value = *data;
+ count = 1;
+ break;
+ case WORD_SIZE:
+ value = *reinterpret_cast<int16_t*>(data);
+ count = 2;
+ break;
+ case DOUBLEWORD_SIZE:
+ value = *reinterpret_cast<uint32_t*>(data);
+ count = 4;
+ break;
+ case QUADWORD_SIZE:
+ value = *reinterpret_cast<int32_t*>(data);
+ count = 4;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ AppendToBuffer(V8_PTR_PREFIX"x", value);
+ return count;
+}
+
+
int DisassemblerX64::PrintRightOperand(byte* modrmp) {
return PrintRightOperandHelper(modrmp,
&DisassemblerX64::NameOfCPURegister);
@@ -466,25 +549,30 @@ int DisassemblerX64::PrintRightByteOperand(byte* modrmp) {
// Returns number of bytes used including the current *data.
// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
int DisassemblerX64::PrintOperands(const char* mnem,
- OperandOrder op_order,
+ OperandType op_order,
byte* data) {
byte modrm = *data;
int mod, regop, rm;
get_modrm(modrm, &mod, &regop, &rm);
int advance = 0;
+ const char* register_name =
+ byte_size_operand_ ? NameOfByteCPURegister(regop)
+ : NameOfCPURegister(regop);
switch (op_order) {
case REG_OPER_OP_ORDER: {
AppendToBuffer("%s%c %s,",
mnem,
operand_size_code(),
- NameOfCPURegister(regop));
- advance = PrintRightOperand(data);
+ register_name);
+ advance = byte_size_operand_ ? PrintRightByteOperand(data)
+ : PrintRightOperand(data);
break;
}
case OPER_REG_OP_ORDER: {
AppendToBuffer("%s%c ", mnem, operand_size_code());
- advance = PrintRightOperand(data);
- AppendToBuffer(",%s", NameOfCPURegister(regop));
+ advance = byte_size_operand_ ? PrintRightByteOperand(data)
+ : PrintRightOperand(data);
+ AppendToBuffer(",%s", register_name);
break;
}
default:
@@ -498,7 +586,7 @@ int DisassemblerX64::PrintOperands(const char* mnem,
// Returns number of bytes used by machine instruction, including *data byte.
// Writes immediate instructions to 'tmp_buffer_'.
int DisassemblerX64::PrintImmediateOp(byte* data) {
- bool sign_extension_bit = (*data & 0x02) != 0;
+ bool byte_size_immediate = (*data & 0x02) != 0;
byte modrm = *(data + 1);
int mod, regop, rm;
get_modrm(modrm, &mod, &regop, &rm);
@@ -528,15 +616,12 @@ int DisassemblerX64::PrintImmediateOp(byte* data) {
default:
UnimplementedInstruction();
}
- AppendToBuffer("%s ", mnem);
+ AppendToBuffer("%s%c ", mnem, operand_size_code());
int count = PrintRightOperand(data + 1);
- if (sign_extension_bit) {
- AppendToBuffer(",0x%x", *(data + 1 + count));
- return 1 + count + 1 /*int8*/;
- } else {
- AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));
- return 1 + count + 4 /*int32_t*/;
- }
+ AppendToBuffer(",0x");
+ OperandSize op_size = byte_size_immediate ? BYTE_SIZE : operand_size();
William Hesse 2009/07/14 09:09:22 immediate_size, not op_size.
+ count += PrintImmediate(data + 1 + count, op_size);
+ return 1 + count;
}
@@ -589,78 +674,65 @@ int DisassemblerX64::F7Instruction(byte* data) {
}
-int DisassemblerX64::D1D3C1Instruction(byte* data) {
- byte op = *data;
- assert(op == 0xD1 || op == 0xD3 || op == 0xC1);
+int DisassemblerX64::ShiftInstruction(byte* data) {
+ byte op = *data & (~1);
+ if (op != 0xD0 && op == 0xD0 && op == 0xC0) {
+ UnimplementedInstruction();
+ return 1;
+ }
byte modrm = *(data + 1);
int mod, regop, rm;
get_modrm(modrm, &mod, &regop, &rm);
ASSERT(regop < 8);
int imm8 = -1;
int num_bytes = 2;
- if (mod == 3) {
- const char* mnem = NULL;
- if (op == 0xD1) {
- imm8 = 1;
- switch (regop) {
- case 2:
- mnem = "rcl";
- break;
- case 7:
- mnem = "sar";
- break;
- case 4:
- mnem = "shl";
- break;
- default:
- UnimplementedInstruction();
- }
- } else if (op == 0xC1) {
- imm8 = *(data + 2);
- num_bytes = 3;
- switch (regop) {
- case 2:
- mnem = "rcl";
- break;
- case 4:
- mnem = "shl";
- break;
- case 5:
- mnem = "shr";
- break;
- case 7:
- mnem = "sar";
- break;
- default:
- UnimplementedInstruction();
- }
- } else if (op == 0xD3) {
- switch (regop) {
- case 4:
- mnem = "shl";
- break;
- case 5:
- mnem = "shr";
- break;
- case 7:
- mnem = "sar";
- break;
- default:
- UnimplementedInstruction();
- }
- }
- assert(mnem != NULL);
- AppendToBuffer("%s%c %s,",
- mnem,
- operand_size_code(),
- NameOfCPURegister(rm));
- if (imm8 > 0) {
- AppendToBuffer("%d", imm8);
- } else {
- AppendToBuffer("cl");
- }
- } else {
+ if (mod != 3) {
UnimplementedInstruction();
+ return num_bytes;
+ }
+ const char* mnem = NULL;
+ switch (regop) {
+ case 0:
+ mnem = "rol";
+ break;
+ case 1:
+ mnem = "ror";
+ break;
+ case 2:
+ mnem = "rcl";
+ break;
+ case 3:
+ mnem = "rcr";
+ break;
+ case 4:
+ mnem = "shl";
+ break;
+ case 5:
+ mnem = "shr";
+ break;
+ case 7:
+ mnem = "sar";
+ break;
+ default:
+ UnimplementedInstruction();
+ return num_bytes;
+ }
+ assert(mnem != NULL);
+ if (op == 0xD0) {
+ imm8 = 1;
+ } else if (op == 0xC0) {
+ imm8 = *(data + 2);
+ num_bytes = 3;
+ }
+ AppendToBuffer("%s%c %s,",
+ mnem,
+ operand_size_code(),
+ byte_size_operand_ ? NameOfByteCPURegister(rm)
+ : NameOfCPURegister(rm));
+ if (imm8 > 0) {
William Hesse 2009/07/14 09:09:22 This seems wrong. Why aren't we testing the opcod
+ AppendToBuffer("%d", imm8);
+ } else {
+ AppendToBuffer("cl");
}
return num_bytes;
}
@@ -716,20 +788,14 @@ int DisassemblerX64::FPUInstruction(byte* data) {
if (b1 == 0xD9) {
const char* mnem = NULL;
switch (b2) {
- case 0xE8:
- mnem = "fld1";
- break;
- case 0xEE:
- mnem = "fldz";
+ case 0xE0:
+ mnem = "fchs";
break;
case 0xE1:
mnem = "fabs";
break;
- case 0xE0:
- mnem = "fchs";
- break;
- case 0xF8:
- mnem = "fprem";
+ case 0xE4:
+ mnem = "ftst";
break;
case 0xF5:
mnem = "fprem1";
@@ -737,8 +803,14 @@ int DisassemblerX64::FPUInstruction(byte* data) {
case 0xF7:
mnem = "fincstp";
break;
- case 0xE4:
- mnem = "ftst";
+ case 0xE8:
+ mnem = "fld1";
+ break;
+ case 0xEE:
+ mnem = "fldz";
+ break;
+ case 0xF8:
+ mnem = "fprem";
break;
}
if (mnem != NULL) {
@@ -906,7 +978,8 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
while (true) {
current = *data;
if (current == 0x66) {
- setOperandSizePrefix(current);
+ // If the sequence is 66 0f, it's not a prefix, but a SSE escape.
+ if (*(data + 1) == 0x0F) break;
data++;
} else if ((current & 0xF0) == 0x40) {
setRex(current);
@@ -918,6 +991,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
}
const InstructionDesc& idesc = instruction_table.Get(current);
+ byte_size_operand_ = idesc.byte_size_operation;
switch (idesc.type) {
case ZERO_OPERANDS_INSTR:
AppendToBuffer(idesc.mnem);
@@ -949,15 +1023,15 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
case MOVE_REG_INSTR: {
byte* addr = NULL;
switch (operand_size()) {
- case 16:
+ case WORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
data += 3;
break;
- case 32:
+ case DOUBLEWORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
data += 5;
break;
- case 64:
+ case QUADWORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
data += 9;
break;
@@ -1012,8 +1086,8 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
AppendToBuffer("imul %s,%s,0x%x", NameOfCPURegister(regop),
NameOfCPURegister(rm), imm);
data += 2 + (*data == 0x6B ? 1 : 4);
- }
break;
+ }
case 0xF6: {
int mod, regop, rm;
@@ -1024,8 +1098,8 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
UnimplementedInstruction();
}
data += 3;
- }
break;
+ }
case 0x81: // fall through
case 0x83: // 0x81 with sign extension bit set
@@ -1170,13 +1244,13 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
case 0x95:
case 0x96:
case 0x97: {
- int reg = current & 0x7 | (rex_b() ? 8 : 0);
+ int reg = (current & 0x7) | (rex_b() ? 8 : 0);
if (reg == 0) {
AppendToBuffer("nop"); // Common name for xchg rax,rax.
} else {
AppendToBuffer("xchg%c rax, %s",
operand_size_code(),
- NameOfByteCPURegister(reg));
+ NameOfCPURegister(reg));
}
}
@@ -1209,17 +1283,39 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
data += 2;
break;
- case 0xA9:
- AppendToBuffer("test%c rax,0x%x", // CHECKME!
- operand_size_code(),
- *reinterpret_cast<int32_t*>(data + 1));
- data += 5;
+ case 0xA9: {
+ int64_t value;
+ switch (operand_size()) {
+ case WORD_SIZE:
+ value = *reinterpret_cast<uint16_t*>(data + 1);
+ data += 3;
+ break;
+ case DOUBLEWORD_SIZE:
+ value = *reinterpret_cast<uint32_t*>(data + 1);
+ data += 5;
+ break;
+ case QUADWORD_SIZE:
+ value = *reinterpret_cast<int32_t*>(data + 1);
+ data += 5;
+ break;
+ default:
+ UNREACHABLE();
+ }
break;
-
+ AppendToBuffer("test%c rax,0x%"V8_PTR_PREFIX"ux",
+ operand_size_code(),
+ value);
+ }
case 0xD1: // fall through
case 0xD3: // fall through
case 0xC1:
- data += D1D3C1Instruction(data);
+ data += ShiftInstruction(data);
+ break;
+ case 0xD0: // fall through
+ case 0xD2: // fall through
+ case 0xC0:
+ byte_size_operand_ = true;
+ data += ShiftInstruction(data);
break;
case 0xD9: // fall through
@@ -1289,11 +1385,17 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
break;
case 0xF3:
- if (*(data + 1) == 0x0F && *(data + 2) == 0x2C) {
- data += 3;
- data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
+ if (*(data + 1) == 0x0F) {
+ if (*(data + 2) == 0x2C) {
+ data += 3;
+ data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
+ } else {
+ UnimplementedInstruction();
+ data += 1;
+ }
} else {
UnimplementedInstruction();
+ data += 1;
}
break;
@@ -1303,6 +1405,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
default:
UnimplementedInstruction();
+ data += 1;
}
} // !processed
« no previous file with comments | « src/x64/assembler-x64.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698