| Index: src/ia32/disasm-ia32.cc
|
| ===================================================================
|
| --- src/ia32/disasm-ia32.cc (revision 3574)
|
| +++ src/ia32/disasm-ia32.cc (working copy)
|
| @@ -61,6 +61,7 @@
|
| {0x0B, "or", REG_OPER_OP_ORDER},
|
| {0x1B, "sbb", REG_OPER_OP_ORDER},
|
| {0x29, "sub", OPER_REG_OP_ORDER},
|
| + {0x2A, "subb", REG_OPER_OP_ORDER},
|
| {0x2B, "sub", REG_OPER_OP_ORDER},
|
| {0x85, "test", REG_OPER_OP_ORDER},
|
| {0x31, "xor", OPER_REG_OP_ORDER},
|
| @@ -116,6 +117,11 @@
|
| };
|
|
|
|
|
| +static const char* loop_mnem[] = {
|
| + "loopne", "loope", "loop"
|
| +};
|
| +
|
| +
|
| static const char* set_conditional_mnem[] = {
|
| /*0*/ "seto", "setno", "setc", "setnc",
|
| /*4*/ "setz", "setnz", "setna", "seta",
|
| @@ -137,6 +143,7 @@
|
| ZERO_OPERANDS_INSTR,
|
| TWO_OPERANDS_INSTR,
|
| JUMP_CONDITIONAL_SHORT_INSTR,
|
| + LOOP_INSTR,
|
| REGISTER_INSTR,
|
| MOVE_REG_INSTR,
|
| CALL_JUMP_INSTR,
|
| @@ -166,6 +173,7 @@
|
| byte end,
|
| const char* mnem);
|
| void AddJumpConditionalShort();
|
| + void AddLoop();
|
| };
|
|
|
|
|
| @@ -190,6 +198,7 @@
|
| CopyTable(call_jump_instr, CALL_JUMP_INSTR);
|
| CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
|
| AddJumpConditionalShort();
|
| + AddLoop();
|
| SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
|
| SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
|
| SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
|
| @@ -233,6 +242,16 @@
|
| }
|
|
|
|
|
| +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;
|
|
|
|
|
| @@ -329,6 +348,7 @@
|
| int JumpShort(byte* data);
|
| int JumpConditional(byte* data, const char* comment);
|
| int JumpConditionalShort(byte* data, const char* comment);
|
| + int Loop(byte* data);
|
| int SetCC(byte* data);
|
| int CMov(byte* data);
|
| int FPUInstruction(byte* data);
|
| @@ -617,6 +637,17 @@
|
|
|
|
|
| // 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.
|
| int DisassemblerIA32::SetCC(byte* data) {
|
| ASSERT_EQ(0x0F, *data);
|
| byte cond = *(data+1) & 0x0F;
|
| @@ -854,6 +885,10 @@
|
| data += JumpConditionalShort(data, branch_hint);
|
| break;
|
|
|
| + case LOOP_INSTR:
|
| + data += Loop(data);
|
| + break;
|
| +
|
| case REGISTER_INSTR:
|
| AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
|
| data++;
|
|
|