Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: src/ia32/disasm-ia32.cc

Issue 541008: Added two missing instructions to disassembler.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. 1 // Copyright 2007-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 static ByteMnemonic two_operands_instr[] = { 54 static ByteMnemonic two_operands_instr[] = {
55 {0x03, "add", REG_OPER_OP_ORDER}, 55 {0x03, "add", REG_OPER_OP_ORDER},
56 {0x21, "and", OPER_REG_OP_ORDER}, 56 {0x21, "and", OPER_REG_OP_ORDER},
57 {0x23, "and", REG_OPER_OP_ORDER}, 57 {0x23, "and", REG_OPER_OP_ORDER},
58 {0x3B, "cmp", REG_OPER_OP_ORDER}, 58 {0x3B, "cmp", REG_OPER_OP_ORDER},
59 {0x8D, "lea", REG_OPER_OP_ORDER}, 59 {0x8D, "lea", REG_OPER_OP_ORDER},
60 {0x09, "or", OPER_REG_OP_ORDER}, 60 {0x09, "or", OPER_REG_OP_ORDER},
61 {0x0B, "or", REG_OPER_OP_ORDER}, 61 {0x0B, "or", REG_OPER_OP_ORDER},
62 {0x1B, "sbb", REG_OPER_OP_ORDER}, 62 {0x1B, "sbb", REG_OPER_OP_ORDER},
63 {0x29, "sub", OPER_REG_OP_ORDER}, 63 {0x29, "sub", OPER_REG_OP_ORDER},
64 {0x2A, "subb", REG_OPER_OP_ORDER},
64 {0x2B, "sub", REG_OPER_OP_ORDER}, 65 {0x2B, "sub", REG_OPER_OP_ORDER},
65 {0x85, "test", REG_OPER_OP_ORDER}, 66 {0x85, "test", REG_OPER_OP_ORDER},
66 {0x31, "xor", OPER_REG_OP_ORDER}, 67 {0x31, "xor", OPER_REG_OP_ORDER},
67 {0x33, "xor", REG_OPER_OP_ORDER}, 68 {0x33, "xor", REG_OPER_OP_ORDER},
68 {0x87, "xchg", REG_OPER_OP_ORDER}, 69 {0x87, "xchg", REG_OPER_OP_ORDER},
69 {0x8A, "mov_b", REG_OPER_OP_ORDER}, 70 {0x8A, "mov_b", REG_OPER_OP_ORDER},
70 {0x8B, "mov", REG_OPER_OP_ORDER}, 71 {0x8B, "mov", REG_OPER_OP_ORDER},
71 {-1, "", UNSET_OP_ORDER} 72 {-1, "", UNSET_OP_ORDER}
72 }; 73 };
73 74
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 110
110 111
111 static const char* jump_conditional_mnem[] = { 112 static const char* jump_conditional_mnem[] = {
112 /*0*/ "jo", "jno", "jc", "jnc", 113 /*0*/ "jo", "jno", "jc", "jnc",
113 /*4*/ "jz", "jnz", "jna", "ja", 114 /*4*/ "jz", "jnz", "jna", "ja",
114 /*8*/ "js", "jns", "jpe", "jpo", 115 /*8*/ "js", "jns", "jpe", "jpo",
115 /*12*/ "jl", "jnl", "jng", "jg" 116 /*12*/ "jl", "jnl", "jng", "jg"
116 }; 117 };
117 118
118 119
120 static const char* loop_mnem[] = {
121 "loopne", "loope", "loop"
122 };
123
124
119 static const char* set_conditional_mnem[] = { 125 static const char* set_conditional_mnem[] = {
120 /*0*/ "seto", "setno", "setc", "setnc", 126 /*0*/ "seto", "setno", "setc", "setnc",
121 /*4*/ "setz", "setnz", "setna", "seta", 127 /*4*/ "setz", "setnz", "setna", "seta",
122 /*8*/ "sets", "setns", "setpe", "setpo", 128 /*8*/ "sets", "setns", "setpe", "setpo",
123 /*12*/ "setl", "setnl", "setng", "setg" 129 /*12*/ "setl", "setnl", "setng", "setg"
124 }; 130 };
125 131
126 132
127 static const char* conditional_move_mnem[] = { 133 static const char* conditional_move_mnem[] = {
128 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", 134 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc",
129 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", 135 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova",
130 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", 136 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
131 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" 137 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"
132 }; 138 };
133 139
134 140
135 enum InstructionType { 141 enum InstructionType {
136 NO_INSTR, 142 NO_INSTR,
137 ZERO_OPERANDS_INSTR, 143 ZERO_OPERANDS_INSTR,
138 TWO_OPERANDS_INSTR, 144 TWO_OPERANDS_INSTR,
139 JUMP_CONDITIONAL_SHORT_INSTR, 145 JUMP_CONDITIONAL_SHORT_INSTR,
146 LOOP_INSTR,
140 REGISTER_INSTR, 147 REGISTER_INSTR,
141 MOVE_REG_INSTR, 148 MOVE_REG_INSTR,
142 CALL_JUMP_INSTR, 149 CALL_JUMP_INSTR,
143 SHORT_IMMEDIATE_INSTR 150 SHORT_IMMEDIATE_INSTR
144 }; 151 };
145 152
146 153
147 struct InstructionDesc { 154 struct InstructionDesc {
148 const char* mnem; 155 const char* mnem;
149 InstructionType type; 156 InstructionType type;
150 OperandOrder op_order_; 157 OperandOrder op_order_;
151 }; 158 };
152 159
153 160
154 class InstructionTable { 161 class InstructionTable {
155 public: 162 public:
156 InstructionTable(); 163 InstructionTable();
157 const InstructionDesc& Get(byte x) const { return instructions_[x]; } 164 const InstructionDesc& Get(byte x) const { return instructions_[x]; }
158 165
159 private: 166 private:
160 InstructionDesc instructions_[256]; 167 InstructionDesc instructions_[256];
161 void Clear(); 168 void Clear();
162 void Init(); 169 void Init();
163 void CopyTable(ByteMnemonic bm[], InstructionType type); 170 void CopyTable(ByteMnemonic bm[], InstructionType type);
164 void SetTableRange(InstructionType type, 171 void SetTableRange(InstructionType type,
165 byte start, 172 byte start,
166 byte end, 173 byte end,
167 const char* mnem); 174 const char* mnem);
168 void AddJumpConditionalShort(); 175 void AddJumpConditionalShort();
176 void AddLoop();
169 }; 177 };
170 178
171 179
172 InstructionTable::InstructionTable() { 180 InstructionTable::InstructionTable() {
173 Clear(); 181 Clear();
174 Init(); 182 Init();
175 } 183 }
176 184
177 185
178 void InstructionTable::Clear() { 186 void InstructionTable::Clear() {
179 for (int i = 0; i < 256; i++) { 187 for (int i = 0; i < 256; i++) {
180 instructions_[i].mnem = ""; 188 instructions_[i].mnem = "";
181 instructions_[i].type = NO_INSTR; 189 instructions_[i].type = NO_INSTR;
182 instructions_[i].op_order_ = UNSET_OP_ORDER; 190 instructions_[i].op_order_ = UNSET_OP_ORDER;
183 } 191 }
184 } 192 }
185 193
186 194
187 void InstructionTable::Init() { 195 void InstructionTable::Init() {
188 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); 196 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
189 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); 197 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
190 CopyTable(call_jump_instr, CALL_JUMP_INSTR); 198 CopyTable(call_jump_instr, CALL_JUMP_INSTR);
191 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); 199 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
192 AddJumpConditionalShort(); 200 AddJumpConditionalShort();
201 AddLoop();
193 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); 202 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
194 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); 203 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
195 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); 204 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
196 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); 205 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop");
197 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. 206 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop.
198 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); 207 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
199 } 208 }
200 209
201 210
202 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) { 211 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {
(...skipping 23 matching lines...) Expand all
226 void InstructionTable::AddJumpConditionalShort() { 235 void InstructionTable::AddJumpConditionalShort() {
227 for (byte b = 0x70; b <= 0x7F; b++) { 236 for (byte b = 0x70; b <= 0x7F; b++) {
228 InstructionDesc* id = &instructions_[b]; 237 InstructionDesc* id = &instructions_[b];
229 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. 238 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
230 id->mnem = jump_conditional_mnem[b & 0x0F]; 239 id->mnem = jump_conditional_mnem[b & 0x0F];
231 id->type = JUMP_CONDITIONAL_SHORT_INSTR; 240 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
232 } 241 }
233 } 242 }
234 243
235 244
245 void InstructionTable::AddLoop() {
246 for (byte b = 0xE0; b <= 0xE2; b++) {
247 InstructionDesc* id = &instructions_[b];
248 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
249 id->mnem = loop_mnem[b & 0x03];
250 id->type = LOOP_INSTR;
251 }
252 }
253
254
236 static InstructionTable instruction_table; 255 static InstructionTable instruction_table;
237 256
238 257
239 // The IA32 disassembler implementation. 258 // The IA32 disassembler implementation.
240 class DisassemblerIA32 { 259 class DisassemblerIA32 {
241 public: 260 public:
242 DisassemblerIA32(const NameConverter& converter, 261 DisassemblerIA32(const NameConverter& converter,
243 bool abort_on_unimplemented = true) 262 bool abort_on_unimplemented = true)
244 : converter_(converter), 263 : converter_(converter),
245 tmp_buffer_pos_(0), 264 tmp_buffer_pos_(0),
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); 341 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
323 int PrintRightOperand(byte* modrmp); 342 int PrintRightOperand(byte* modrmp);
324 int PrintRightByteOperand(byte* modrmp); 343 int PrintRightByteOperand(byte* modrmp);
325 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 344 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
326 int PrintImmediateOp(byte* data); 345 int PrintImmediateOp(byte* data);
327 int F7Instruction(byte* data); 346 int F7Instruction(byte* data);
328 int D1D3C1Instruction(byte* data); 347 int D1D3C1Instruction(byte* data);
329 int JumpShort(byte* data); 348 int JumpShort(byte* data);
330 int JumpConditional(byte* data, const char* comment); 349 int JumpConditional(byte* data, const char* comment);
331 int JumpConditionalShort(byte* data, const char* comment); 350 int JumpConditionalShort(byte* data, const char* comment);
351 int Loop(byte* data);
332 int SetCC(byte* data); 352 int SetCC(byte* data);
333 int CMov(byte* data); 353 int CMov(byte* data);
334 int FPUInstruction(byte* data); 354 int FPUInstruction(byte* data);
335 int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); 355 int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
336 int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); 356 int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
337 void AppendToBuffer(const char* format, ...); 357 void AppendToBuffer(const char* format, ...);
338 358
339 359
340 void UnimplementedInstruction() { 360 void UnimplementedInstruction() {
341 if (abort_on_unimplemented_) { 361 if (abort_on_unimplemented_) {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 const char* mnem = jump_conditional_mnem[cond]; 630 const char* mnem = jump_conditional_mnem[cond];
611 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 631 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
612 if (comment != NULL) { 632 if (comment != NULL) {
613 AppendToBuffer(", %s", comment); 633 AppendToBuffer(", %s", comment);
614 } 634 }
615 return 2; 635 return 2;
616 } 636 }
617 637
618 638
619 // Returns number of bytes used, including *data. 639 // Returns number of bytes used, including *data.
640 int DisassemblerIA32::Loop(byte* data) {
641 byte cond = *data & 0x03;
642 byte b = *(data+1);
643 byte* dest = data + static_cast<int8_t>(b) + 2;
644 const char* mnem = loop_mnem[cond];
645 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
646 return 2;
647 }
648
649
650 // Returns number of bytes used, including *data.
620 int DisassemblerIA32::SetCC(byte* data) { 651 int DisassemblerIA32::SetCC(byte* data) {
621 ASSERT_EQ(0x0F, *data); 652 ASSERT_EQ(0x0F, *data);
622 byte cond = *(data+1) & 0x0F; 653 byte cond = *(data+1) & 0x0F;
623 const char* mnem = set_conditional_mnem[cond]; 654 const char* mnem = set_conditional_mnem[cond];
624 AppendToBuffer("%s ", mnem); 655 AppendToBuffer("%s ", mnem);
625 PrintRightByteOperand(data+2); 656 PrintRightByteOperand(data+2);
626 return 3; // Includes 0x0F. 657 return 3; // Includes 0x0F.
627 } 658 }
628 659
629 660
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 878
848 case TWO_OPERANDS_INSTR: 879 case TWO_OPERANDS_INSTR:
849 data++; 880 data++;
850 data += PrintOperands(idesc.mnem, idesc.op_order_, data); 881 data += PrintOperands(idesc.mnem, idesc.op_order_, data);
851 break; 882 break;
852 883
853 case JUMP_CONDITIONAL_SHORT_INSTR: 884 case JUMP_CONDITIONAL_SHORT_INSTR:
854 data += JumpConditionalShort(data, branch_hint); 885 data += JumpConditionalShort(data, branch_hint);
855 break; 886 break;
856 887
888 case LOOP_INSTR:
889 data += Loop(data);
890 break;
891
857 case REGISTER_INSTR: 892 case REGISTER_INSTR:
858 AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); 893 AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
859 data++; 894 data++;
860 break; 895 break;
861 896
862 case MOVE_REG_INSTR: { 897 case MOVE_REG_INSTR: {
863 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); 898 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
864 AppendToBuffer("mov %s,%s", 899 AppendToBuffer("mov %s,%s",
865 NameOfCPURegister(*data & 0x07), 900 NameOfCPURegister(*data & 0x07),
866 NameOfAddress(addr)); 901 NameOfAddress(addr));
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 } 1332 }
1298 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 1333 for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
1299 fprintf(f, " "); 1334 fprintf(f, " ");
1300 } 1335 }
1301 fprintf(f, " %s\n", buffer.start()); 1336 fprintf(f, " %s\n", buffer.start());
1302 } 1337 }
1303 } 1338 }
1304 1339
1305 1340
1306 } // namespace disasm 1341 } // namespace disasm
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698