Index: runtime/vm/disassembler_x64.cc |
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc |
index 37d818454ca75b619ccfce1063dc150359fc5806..6b76e52c9b4d15023da08b326ee078c8e65d2dbe 100644 |
--- a/runtime/vm/disassembler_x64.cc |
+++ b/runtime/vm/disassembler_x64.cc |
@@ -388,7 +388,9 @@ class DisassemblerX64 : public ValueObject { |
int PrintRightOperand(uint8_t* modrmp); |
int PrintRightByteOperand(uint8_t* modrmp); |
int PrintRightXMMOperand(uint8_t* modrmp); |
+ void PrintDisp(int disp, const char* after); |
int PrintImmediate(uint8_t* data, OperandSize size); |
+ void PrintImmediateValue(int64_t value); |
int PrintImmediateOp(uint8_t* data); |
const char* TwoByteMnemonic(uint8_t opcode); |
int TwoByteOpcodeInstruction(uint8_t* data); |
@@ -454,7 +456,8 @@ int DisassemblerX64::PrintRightOperandHelper( |
case 0: |
if ((rm & 7) == 5) { |
int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); |
- AppendToBuffer("[rip%s%#x]", disp < 0 ? "-" : "+", Utils::Abs(disp)); |
+ AppendToBuffer("[rip"); |
+ PrintDisp(disp, "]"); |
return 5; |
} else if ((rm & 7) == 4) { |
// Codes for SIB byte. |
@@ -469,9 +472,8 @@ int DisassemblerX64::PrintRightOperandHelper( |
} else if (base == 5) { |
// base == rbp means no base register (when mod == 0). |
int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); |
- AppendToBuffer("[%s*%d+%#x]", |
- NameOfCPURegister(index), |
- 1 << scale, disp); |
+ AppendToBuffer("[%s*%d", NameOfCPURegister(index), 1 << scale); |
+ PrintDisp(disp, "]"); |
return 6; |
} else if (index != 4 && base != 5) { |
// [base+index*scale] |
@@ -498,36 +500,22 @@ int DisassemblerX64::PrintRightOperandHelper( |
int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) |
: *reinterpret_cast<char*>(modrmp + 2); |
if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
- if (-disp > 0) { |
- AppendToBuffer("[%s-%#x]", NameOfCPURegister(base), -disp); |
- } else { |
- AppendToBuffer("[%s+%#x]", NameOfCPURegister(base), disp); |
- } |
+ AppendToBuffer("[%s", NameOfCPURegister(base)); |
+ PrintDisp(disp, "]"); |
} else { |
- if (-disp > 0) { |
- AppendToBuffer("[%s+%s*%d-%#x]", |
- NameOfCPURegister(base), |
- NameOfCPURegister(index), |
- 1 << scale, |
- -disp); |
- } else { |
- AppendToBuffer("[%s+%s*%d+%#x]", |
- NameOfCPURegister(base), |
- NameOfCPURegister(index), |
- 1 << scale, |
- disp); |
- } |
+ AppendToBuffer("[%s+%s*%d", |
+ NameOfCPURegister(base), |
+ NameOfCPURegister(index), |
+ 1 << scale); |
+ PrintDisp(disp, "]"); |
} |
return mod == 2 ? 6 : 3; |
} else { |
// No sib. |
int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) |
: *reinterpret_cast<char*>(modrmp + 1); |
- if (-disp > 0) { |
- AppendToBuffer("[%s-%#x]", NameOfCPURegister(rm), -disp); |
- } else { |
- AppendToBuffer("[%s+%#x]", NameOfCPURegister(rm), disp); |
- } |
+ AppendToBuffer("[%s", NameOfCPURegister(rm)); |
+ PrintDisp(disp, "]"); |
return (mod == 2) ? 5 : 2; |
} |
break; |
@@ -567,10 +555,29 @@ int DisassemblerX64::PrintImmediate(uint8_t* data, OperandSize size) { |
value = 0; // Initialize variables on all paths to satisfy the compiler. |
count = 0; |
} |
- AppendToBuffer("%#" Px64 "", value); |
+ PrintImmediateValue(value); |
return count; |
} |
+void DisassemblerX64::PrintImmediateValue(int64_t value) { |
+ if (value >= 0 && value <= 9) { |
regis
2016/04/19 20:59:22
((value >= 0) && (value <= 9))
sra1
2016/04/19 23:32:39
Done.
|
+ AppendToBuffer("%" Pd64 "", value); |
+ } else { |
+ AppendToBuffer("%#" Px64 "", value); |
+ } |
+} |
+ |
+void DisassemblerX64::PrintDisp(int disp, const char* after) { |
+ if (-disp > 0) { |
+ AppendToBuffer("-%#x", -disp); |
+ } else { |
+ AppendToBuffer("+%#x", disp); |
+ } |
+ if (after != NULL) AppendToBuffer("%s", after); |
+} |
+ |
+ |
+ |
// Returns number of bytes used by machine instruction, including *data byte. |
// Writes immediate instructions to 'tmp_buffer_'. |
@@ -652,7 +659,7 @@ int DisassemblerX64::F6F7Instruction(uint8_t* data) { |
} else if (regop == 0) { |
AppendToBuffer("test%c ", operand_size_code()); |
int count = PrintRightOperand(data + 1); // Use name of 64-bit register. |
- AppendToBuffer(",0x"); |
+ AppendToBuffer(","); |
count += PrintImmediate(data + 1 + count, operand_size()); |
return 1 + count; |
} else { |
@@ -1607,7 +1614,8 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
if (!processed) { |
switch (*data) { |
case 0xC2: |
- AppendToBuffer("ret %#x", *reinterpret_cast<uint16_t*>(data + 1)); |
+ AppendToBuffer("ret "); |
+ PrintImmediateValue(*reinterpret_cast<uint16_t*>(data + 1)); |
data += 3; |
break; |
@@ -1624,10 +1632,11 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
get_modrm(*(data + 1), &mod, ®op, &rm); |
int32_t imm = *data == 0x6B ? *(data + 2) |
: *reinterpret_cast<int32_t*>(data + 2); |
- AppendToBuffer("imul%c %s,%s,%#x", |
+ AppendToBuffer("imul%c %s,%s,", |
operand_size_code(), |
NameOfCPURegister(regop), |
- NameOfCPURegister(rm), imm); |
+ NameOfCPURegister(rm)); |
+ PrintImmediateValue(imm); |
data += 2 + (*data == 0x6B ? 1 : 4); |
break; |
} |
@@ -1694,13 +1703,15 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
AppendToBuffer("movb "); |
data += PrintRightByteOperand(data); |
int32_t imm = *data; |
- AppendToBuffer(",%#x", imm); |
+ AppendToBuffer(","); |
+ PrintImmediateValue(imm); |
data++; |
} else { |
AppendToBuffer("mov%c ", operand_size_code()); |
data += PrintRightOperand(data); |
int32_t imm = *reinterpret_cast<int32_t*>(data); |
- AppendToBuffer(",%#x", imm); |
+ AppendToBuffer(","); |
+ PrintImmediateValue(imm); |
data += 4; |
} |
} |
@@ -1711,7 +1722,8 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
AppendToBuffer("cmpb "); |
data += PrintRightByteOperand(data); |
int32_t imm = *data; |
- AppendToBuffer(",%#x", imm); |
+ AppendToBuffer(","); |
+ PrintImmediateValue(imm); |
data++; |
} |
break; |
@@ -1776,12 +1788,12 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
uint8_t is_32bit = (opcode >= 0xB8); |
int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); |
if (is_32bit) { |
- AppendToBuffer("mov%c %s, ", |
+ AppendToBuffer("mov%c %s,", |
operand_size_code(), |
NameOfCPURegister(reg)); |
data += PrintImmediate(data, DOUBLEWORD_SIZE); |
} else { |
- AppendToBuffer("movb %s, ", |
+ AppendToBuffer("movb %s,", |
NameOfByteCPURegister(reg)); |
data += PrintImmediate(data, BYTE_SIZE); |
} |
@@ -1800,12 +1812,14 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
break; |
} |
case 0x68: |
- AppendToBuffer("push %#x", *reinterpret_cast<int32_t*>(data + 1)); |
+ AppendToBuffer("push "); |
+ PrintImmediateValue(*reinterpret_cast<int32_t*>(data + 1)); |
data += 5; |
break; |
case 0x6A: |
- AppendToBuffer("push %#x", *reinterpret_cast<int8_t*>(data + 1)); |
+ AppendToBuffer("push "); |
+ PrintImmediateValue(*reinterpret_cast<int8_t*>(data + 1)); |
data += 2; |
break; |
@@ -1853,7 +1867,8 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
break; |
case 0xA8: |
- AppendToBuffer("test al,%#x", *reinterpret_cast<uint8_t*>(data + 1)); |
+ AppendToBuffer("test al,"); |
+ PrintImmediateValue(*reinterpret_cast<uint8_t*>(data + 1)); |
data += 2; |
break; |
@@ -1875,9 +1890,8 @@ int DisassemblerX64::InstructionDecode(uword pc) { |
default: |
UNREACHABLE(); |
} |
- AppendToBuffer("test%c rax,%#" Px64 "", |
- operand_size_code(), |
- value); |
+ AppendToBuffer("test%c rax,", operand_size_code()); |
+ PrintImmediateValue(value); |
break; |
} |
case 0xD1: // fall through |