Index: runtime/vm/disassembler_x64.cc |
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc |
index 26735dfd65e3897257a5f64ce2428bafed45bc05..657fbc07fb07fbac75a73265d40c780b59aa97ee 100644 |
--- a/runtime/vm/disassembler_x64.cc |
+++ b/runtime/vm/disassembler_x64.cc |
@@ -38,7 +38,6 @@ struct ByteMnemonic { |
const char* mnem; |
}; |
- |
static const ByteMnemonic two_operands_instr[] = { |
{0x00, BYTE_OPER_REG_OP_ORDER, "add"}, |
{0x01, OPER_REG_OP_ORDER, "add"}, |
@@ -84,7 +83,6 @@ static const ByteMnemonic two_operands_instr[] = { |
{0x8D, REG_OPER_OP_ORDER, "lea"}, |
{-1, UNSET_OP_ORDER, ""}}; |
- |
static const ByteMnemonic zero_operands_instr[] = { |
{0xC3, UNSET_OP_ORDER, "ret"}, {0xC9, UNSET_OP_ORDER, "leave"}, |
{0xF4, UNSET_OP_ORDER, "hlt"}, {0xFC, UNSET_OP_ORDER, "cld"}, |
@@ -96,12 +94,10 @@ static const ByteMnemonic zero_operands_instr[] = { |
{0xA6, UNSET_OP_ORDER, "cmps"}, {0xA7, UNSET_OP_ORDER, "cmps"}, |
{-1, UNSET_OP_ORDER, ""}}; |
- |
static const ByteMnemonic call_jump_instr[] = {{0xE8, UNSET_OP_ORDER, "call"}, |
{0xE9, UNSET_OP_ORDER, "jmp"}, |
{-1, UNSET_OP_ORDER, ""}}; |
- |
static const ByteMnemonic short_immediate_instr[] = { |
{0x05, UNSET_OP_ORDER, "add"}, {0x0D, UNSET_OP_ORDER, "or"}, |
{0x15, UNSET_OP_ORDER, "adc"}, {0x1D, UNSET_OP_ORDER, "sbb"}, |
@@ -109,12 +105,10 @@ static const ByteMnemonic short_immediate_instr[] = { |
{0x35, UNSET_OP_ORDER, "xor"}, {0x3D, UNSET_OP_ORDER, "cmp"}, |
{-1, UNSET_OP_ORDER, ""}}; |
- |
static const char* const conditional_code_suffix[] = { |
"o", "no", "c", "nc", "z", "nz", "na", "a", |
"s", "ns", "pe", "po", "l", "ge", "le", "g"}; |
- |
enum InstructionType { |
NO_INSTR, |
ZERO_OPERANDS_INSTR, |
@@ -127,7 +121,6 @@ enum InstructionType { |
SHORT_IMMEDIATE_INSTR |
}; |
- |
enum Prefixes { |
ESCAPE_PREFIX = 0x0F, |
OPERAND_SIZE_OVERRIDE_PREFIX = 0x66, |
@@ -137,7 +130,6 @@ enum Prefixes { |
REPEQ_PREFIX = REP_PREFIX |
}; |
- |
struct InstructionDesc { |
const char* mnem; |
InstructionType type; |
@@ -145,7 +137,6 @@ struct InstructionDesc { |
bool byte_size_operation; // Fixed 8-bit operation. |
}; |
- |
class InstructionTable : public ValueObject { |
public: |
InstructionTable(); |
@@ -166,13 +157,11 @@ class InstructionTable : public ValueObject { |
DISALLOW_COPY_AND_ASSIGN(InstructionTable); |
}; |
- |
InstructionTable::InstructionTable() { |
Clear(); |
Init(); |
} |
- |
void InstructionTable::Clear() { |
for (int i = 0; i < 256; i++) { |
instructions_[i].mnem = "(bad)"; |
@@ -182,7 +171,6 @@ void InstructionTable::Clear() { |
} |
} |
- |
void InstructionTable::Init() { |
CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); |
CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); |
@@ -194,7 +182,6 @@ void InstructionTable::Init() { |
SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, false, "mov"); |
} |
- |
void InstructionTable::CopyTable(const ByteMnemonic bm[], |
InstructionType type) { |
for (int i = 0; bm[i].b >= 0; i++) { |
@@ -209,7 +196,6 @@ void InstructionTable::CopyTable(const ByteMnemonic bm[], |
} |
} |
- |
void InstructionTable::SetTableRange(InstructionType type, |
uint8_t start, |
uint8_t end, |
@@ -224,7 +210,6 @@ void InstructionTable::SetTableRange(InstructionType type, |
} |
} |
- |
void InstructionTable::AddJumpConditionalShort() { |
for (uint8_t b = 0x70; b <= 0x7F; b++) { |
InstructionDesc* id = &instructions_[b]; |
@@ -234,10 +219,8 @@ void InstructionTable::AddJumpConditionalShort() { |
} |
} |
- |
static InstructionTable instruction_table; |
- |
static InstructionDesc cmov_instructions[16] = { |
{"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, |
{"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, |
@@ -256,11 +239,9 @@ static InstructionDesc cmov_instructions[16] = { |
{"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, |
{"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}}; |
- |
//------------------------------------------------- |
// DisassemblerX64 implementation. |
- |
static const int kMaxXmmRegisters = 16; |
static const char* xmm_regs[kMaxXmmRegisters] = { |
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", |
@@ -392,7 +373,6 @@ class DisassemblerX64 : public ValueObject { |
DISALLOW_COPY_AND_ASSIGN(DisassemblerX64); |
}; |
- |
// Append the str to the output buffer. |
void DisassemblerX64::Print(const char* format, ...) { |
intptr_t available = buffer_size_ - buffer_pos_; |
@@ -410,7 +390,6 @@ void DisassemblerX64::Print(const char* format, ...) { |
ASSERT(buffer_pos_ < buffer_size_); |
} |
- |
int DisassemblerX64::PrintRightOperandHelper( |
uint8_t* modrmp, |
RegisterNameMapping direct_register_name) { |
@@ -491,7 +470,6 @@ int DisassemblerX64::PrintRightOperandHelper( |
UNREACHABLE(); |
} |
- |
int DisassemblerX64::PrintImmediate(uint8_t* data, |
OperandSize size, |
bool sign_extend) { |
@@ -553,7 +531,6 @@ void DisassemblerX64::PrintDisp(int disp, const char* after) { |
if (after != NULL) Print("%s", after); |
} |
- |
// Returns number of bytes used by machine instruction, including *data byte. |
// Writes immediate instructions to 'tmp_buffer_'. |
int DisassemblerX64::PrintImmediateOp(uint8_t* data) { |
@@ -599,7 +576,6 @@ int DisassemblerX64::PrintImmediateOp(uint8_t* data) { |
return 1 + count; |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::F6F7Instruction(uint8_t* data) { |
ASSERT(*data == 0xF7 || *data == 0xF6); |
@@ -641,7 +617,6 @@ int DisassemblerX64::F6F7Instruction(uint8_t* data) { |
} |
} |
- |
int DisassemblerX64::ShiftInstruction(uint8_t* data) { |
uint8_t op = *data & (~1); |
if (op != 0xD0 && op != 0xD2 && op != 0xC0) { |
@@ -702,23 +677,19 @@ int DisassemblerX64::ShiftInstruction(uint8_t* data) { |
return num_bytes; |
} |
- |
int DisassemblerX64::PrintRightOperand(uint8_t* modrmp) { |
return PrintRightOperandHelper(modrmp, &DisassemblerX64::NameOfCPURegister); |
} |
- |
int DisassemblerX64::PrintRightByteOperand(uint8_t* modrmp) { |
return PrintRightOperandHelper(modrmp, |
&DisassemblerX64::NameOfByteCPURegister); |
} |
- |
int DisassemblerX64::PrintRightXMMOperand(uint8_t* modrmp) { |
return PrintRightOperandHelper(modrmp, &DisassemblerX64::NameOfXMMRegister); |
} |
- |
// 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, |
@@ -751,13 +722,11 @@ int DisassemblerX64::PrintOperands(const char* mnem, |
return advance; |
} |
- |
void DisassemblerX64::PrintAddress(uint8_t* addr_byte_ptr) { |
uword addr = reinterpret_cast<uword>(addr_byte_ptr); |
Print("%#" Px "", addr); |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::JumpShort(uint8_t* data) { |
ASSERT(0xEB == *data); |
@@ -768,7 +737,6 @@ int DisassemblerX64::JumpShort(uint8_t* data) { |
return 2; |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::JumpConditional(uint8_t* data) { |
ASSERT(0x0F == *data); |
@@ -780,7 +748,6 @@ int DisassemblerX64::JumpConditional(uint8_t* data) { |
return 6; // includes 0x0F |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::JumpConditionalShort(uint8_t* data) { |
uint8_t cond = *data & 0x0F; |
@@ -792,7 +759,6 @@ int DisassemblerX64::JumpConditionalShort(uint8_t* data) { |
return 2; |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::SetCC(uint8_t* data) { |
ASSERT(0x0F == *data); |
@@ -803,7 +769,6 @@ int DisassemblerX64::SetCC(uint8_t* data) { |
return 3; // includes 0x0F |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::FPUInstruction(uint8_t* data) { |
uint8_t escape_opcode = *data; |
@@ -817,7 +782,6 @@ int DisassemblerX64::FPUInstruction(uint8_t* data) { |
} |
} |
- |
int DisassemblerX64::MemoryFPUInstruction(int escape_opcode, |
int modrm_byte, |
uint8_t* modrm_start) { |
@@ -1070,7 +1034,6 @@ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode, |
return 2; |
} |
- |
// TODO(srdjan): Should we add a branch hint argument? |
bool DisassemblerX64::DecodeInstructionType(uint8_t** data) { |
uint8_t current; |
@@ -1185,7 +1148,6 @@ bool DisassemblerX64::DecodeInstructionType(uint8_t** data) { |
return true; |
} |
- |
// Handle all two-byte opcodes, which start with 0x0F. |
// These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix. |
// We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A. |
@@ -1568,7 +1530,6 @@ int DisassemblerX64::TwoByteOpcodeInstruction(uint8_t* data) { |
return static_cast<int>(current - data); |
} |
- |
// Mnemonics for two-byte opcode instructions starting with 0x0F. |
// The argument is the second byte of the two-byte opcode. |
// Returns NULL if the instruction is not handled here. |
@@ -1626,7 +1587,6 @@ const char* DisassemblerX64::TwoByteMnemonic(uint8_t opcode) { |
} |
} |
- |
int DisassemblerX64::InstructionDecode(uword pc) { |
uint8_t* data = reinterpret_cast<uint8_t*>(pc); |
@@ -1943,7 +1903,6 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
return instr_len; |
} |
- |
void Disassembler::DecodeInstruction(char* hex_buffer, |
intptr_t hex_size, |
char* human_buffer, |