Chromium Code Reviews| 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 |