Added two missing instructions to disassembler.

The subb and the loop instructions are also added to the IA-32 disassembler.

Review URL: http://codereview.chromium.org/541008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3576 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 41e1d6a6
...@@ -61,6 +61,7 @@ static ByteMnemonic two_operands_instr[] = { ...@@ -61,6 +61,7 @@ static ByteMnemonic two_operands_instr[] = {
{0x0B, "or", REG_OPER_OP_ORDER}, {0x0B, "or", REG_OPER_OP_ORDER},
{0x1B, "sbb", REG_OPER_OP_ORDER}, {0x1B, "sbb", REG_OPER_OP_ORDER},
{0x29, "sub", OPER_REG_OP_ORDER}, {0x29, "sub", OPER_REG_OP_ORDER},
{0x2A, "subb", REG_OPER_OP_ORDER},
{0x2B, "sub", REG_OPER_OP_ORDER}, {0x2B, "sub", REG_OPER_OP_ORDER},
{0x85, "test", REG_OPER_OP_ORDER}, {0x85, "test", REG_OPER_OP_ORDER},
{0x31, "xor", OPER_REG_OP_ORDER}, {0x31, "xor", OPER_REG_OP_ORDER},
...@@ -116,6 +117,11 @@ static const char* jump_conditional_mnem[] = { ...@@ -116,6 +117,11 @@ static const char* jump_conditional_mnem[] = {
}; };
static const char* loop_mnem[] = {
"loopne", "loope", "loop"
};
static const char* set_conditional_mnem[] = { static const char* set_conditional_mnem[] = {
/*0*/ "seto", "setno", "setc", "setnc", /*0*/ "seto", "setno", "setc", "setnc",
/*4*/ "setz", "setnz", "setna", "seta", /*4*/ "setz", "setnz", "setna", "seta",
...@@ -137,6 +143,7 @@ enum InstructionType { ...@@ -137,6 +143,7 @@ enum InstructionType {
ZERO_OPERANDS_INSTR, ZERO_OPERANDS_INSTR,
TWO_OPERANDS_INSTR, TWO_OPERANDS_INSTR,
JUMP_CONDITIONAL_SHORT_INSTR, JUMP_CONDITIONAL_SHORT_INSTR,
LOOP_INSTR,
REGISTER_INSTR, REGISTER_INSTR,
MOVE_REG_INSTR, MOVE_REG_INSTR,
CALL_JUMP_INSTR, CALL_JUMP_INSTR,
...@@ -166,6 +173,7 @@ class InstructionTable { ...@@ -166,6 +173,7 @@ class InstructionTable {
byte end, byte end,
const char* mnem); const char* mnem);
void AddJumpConditionalShort(); void AddJumpConditionalShort();
void AddLoop();
}; };
...@@ -190,6 +198,7 @@ void InstructionTable::Init() { ...@@ -190,6 +198,7 @@ void InstructionTable::Init() {
CopyTable(call_jump_instr, CALL_JUMP_INSTR); CopyTable(call_jump_instr, CALL_JUMP_INSTR);
CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
AddJumpConditionalShort(); AddJumpConditionalShort();
AddLoop();
SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
...@@ -233,6 +242,16 @@ void InstructionTable::AddJumpConditionalShort() { ...@@ -233,6 +242,16 @@ void InstructionTable::AddJumpConditionalShort() {
} }
void InstructionTable::AddLoop() {
for (byte b = 0xE0; b <= 0xE2; b++) {
InstructionDesc* id = &instructions_[b];
ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
id->mnem = loop_mnem[b & 0x03];
id->type = LOOP_INSTR;
}
}
static InstructionTable instruction_table; static InstructionTable instruction_table;
...@@ -329,6 +348,7 @@ class DisassemblerIA32 { ...@@ -329,6 +348,7 @@ class DisassemblerIA32 {
int JumpShort(byte* data); int JumpShort(byte* data);
int JumpConditional(byte* data, const char* comment); int JumpConditional(byte* data, const char* comment);
int JumpConditionalShort(byte* data, const char* comment); int JumpConditionalShort(byte* data, const char* comment);
int Loop(byte* data);
int SetCC(byte* data); int SetCC(byte* data);
int CMov(byte* data); int CMov(byte* data);
int FPUInstruction(byte* data); int FPUInstruction(byte* data);
...@@ -616,6 +636,17 @@ int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { ...@@ -616,6 +636,17 @@ int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) {
} }
// Returns number of bytes used, including *data.
int DisassemblerIA32::Loop(byte* data) {
byte cond = *data & 0x03;
byte b = *(data+1);
byte* dest = data + static_cast<int8_t>(b) + 2;
const char* mnem = loop_mnem[cond];
AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
return 2;
}
// Returns number of bytes used, including *data. // Returns number of bytes used, including *data.
int DisassemblerIA32::SetCC(byte* data) { int DisassemblerIA32::SetCC(byte* data) {
ASSERT_EQ(0x0F, *data); ASSERT_EQ(0x0F, *data);
...@@ -854,6 +885,10 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -854,6 +885,10 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
data += JumpConditionalShort(data, branch_hint); data += JumpConditionalShort(data, branch_hint);
break; break;
case LOOP_INSTR:
data += Loop(data);
break;
case REGISTER_INSTR: case REGISTER_INSTR:
AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
data++; data++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment