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

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

Issue 18313: Fix disassembling of set instructions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 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 | « src/disasm-arm.cc ('k') | 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 109
110 110
111 static const char* jump_conditional_mnem[] = { 111 static const char* jump_conditional_mnem[] = {
112 /*0*/ "jo", "jno", "jc", "jnc", 112 /*0*/ "jo", "jno", "jc", "jnc",
113 /*4*/ "jz", "jnz", "jna", "ja", 113 /*4*/ "jz", "jnz", "jna", "ja",
114 /*8*/ "js", "jns", "jpe", "jpo", 114 /*8*/ "js", "jns", "jpe", "jpo",
115 /*12*/ "jl", "jnl", "jng", "jg" 115 /*12*/ "jl", "jnl", "jng", "jg"
116 }; 116 };
117 117
118 118
119 static const char* set_conditional_mnem[] = {
120 /*0*/ "seto", "setno", "setc", "setnc",
121 /*4*/ "setz", "setnz", "setna", "seta",
122 /*8*/ "sets", "setns", "setpe", "setpo",
123 /*12*/ "setl", "setnl", "setng", "setg"
124 };
125
126
119 enum InstructionType { 127 enum InstructionType {
120 NO_INSTR, 128 NO_INSTR,
121 ZERO_OPERANDS_INSTR, 129 ZERO_OPERANDS_INSTR,
122 TWO_OPERANDS_INSTR, 130 TWO_OPERANDS_INSTR,
123 JUMP_CONDITIONAL_SHORT_INSTR, 131 JUMP_CONDITIONAL_SHORT_INSTR,
124 REGISTER_INSTR, 132 REGISTER_INSTR,
125 MOVE_REG_INSTR, 133 MOVE_REG_INSTR,
126 CALL_JUMP_INSTR, 134 CALL_JUMP_INSTR,
127 SHORT_IMMEDIATE_INSTR 135 SHORT_IMMEDIATE_INSTR
128 }; 136 };
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 esi = 6, 262 esi = 6,
255 edi = 7 263 edi = 7
256 }; 264 };
257 265
258 266
259 const char* NameOfCPURegister(int reg) const { 267 const char* NameOfCPURegister(int reg) const {
260 return converter_.NameOfCPURegister(reg); 268 return converter_.NameOfCPURegister(reg);
261 } 269 }
262 270
263 271
272 const char* NameOfByteCPURegister(int reg) const {
273 return converter_.NameOfByteCPURegister(reg);
274 }
275
276
264 const char* NameOfXMMRegister(int reg) const { 277 const char* NameOfXMMRegister(int reg) const {
265 return converter_.NameOfXMMRegister(reg); 278 return converter_.NameOfXMMRegister(reg);
266 } 279 }
267 280
268 281
269 const char* NameOfAddress(byte* addr) const { 282 const char* NameOfAddress(byte* addr) const {
270 return converter_.NameOfAddress(addr); 283 return converter_.NameOfAddress(addr);
271 } 284 }
272 285
273 286
274 // Disassembler helper functions. 287 // Disassembler helper functions.
275 static void get_modrm(byte data, int* mod, int* regop, int* rm) { 288 static void get_modrm(byte data, int* mod, int* regop, int* rm) {
276 *mod = (data >> 6) & 3; 289 *mod = (data >> 6) & 3;
277 *regop = (data & 0x38) >> 3; 290 *regop = (data & 0x38) >> 3;
278 *rm = data & 7; 291 *rm = data & 7;
279 } 292 }
280 293
281 294
282 static void get_sib(byte data, int* scale, int* index, int* base) { 295 static void get_sib(byte data, int* scale, int* index, int* base) {
283 *scale = (data >> 6) & 3; 296 *scale = (data >> 6) & 3;
284 *index = (data >> 3) & 7; 297 *index = (data >> 3) & 7;
285 *base = data & 7; 298 *base = data & 7;
286 } 299 }
287 300
301 typedef const char* (DisassemblerIA32::*RegisterNameMapping)(int reg) const;
288 302
303 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
289 int PrintRightOperand(byte* modrmp); 304 int PrintRightOperand(byte* modrmp);
305 int PrintRightByteOperand(byte* modrmp);
290 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 306 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
291 int PrintImmediateOp(byte* data); 307 int PrintImmediateOp(byte* data);
292 int F7Instruction(byte* data); 308 int F7Instruction(byte* data);
293 int D1D3C1Instruction(byte* data); 309 int D1D3C1Instruction(byte* data);
294 int JumpShort(byte* data); 310 int JumpShort(byte* data);
295 int JumpConditional(byte* data, const char* comment); 311 int JumpConditional(byte* data, const char* comment);
296 int JumpConditionalShort(byte* data, const char* comment); 312 int JumpConditionalShort(byte* data, const char* comment);
297 int SetCC(byte* data); 313 int SetCC(byte* data);
298 int FPUInstruction(byte* data); 314 int FPUInstruction(byte* data);
299 void AppendToBuffer(const char* format, ...); 315 void AppendToBuffer(const char* format, ...);
(...skipping 11 matching lines...) Expand all
311 327
312 void DisassemblerIA32::AppendToBuffer(const char* format, ...) { 328 void DisassemblerIA32::AppendToBuffer(const char* format, ...) {
313 v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_; 329 v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
314 va_list args; 330 va_list args;
315 va_start(args, format); 331 va_start(args, format);
316 int result = v8::internal::OS::VSNPrintF(buf, format, args); 332 int result = v8::internal::OS::VSNPrintF(buf, format, args);
317 va_end(args); 333 va_end(args);
318 tmp_buffer_pos_ += result; 334 tmp_buffer_pos_ += result;
319 } 335 }
320 336
321 337 int DisassemblerIA32::PrintRightOperandHelper(
322 // Returns number of bytes used including the current *modrmp. 338 byte* modrmp,
323 // Writes instruction's right operand to 'tmp_buffer_'. 339 RegisterNameMapping register_name) {
324 int DisassemblerIA32::PrintRightOperand(byte* modrmp) {
325 int mod, regop, rm; 340 int mod, regop, rm;
326 get_modrm(*modrmp, &mod, &regop, &rm); 341 get_modrm(*modrmp, &mod, &regop, &rm);
327 switch (mod) { 342 switch (mod) {
328 case 0: 343 case 0:
329 if (rm == ebp) { 344 if (rm == ebp) {
330 int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1); 345 int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1);
331 AppendToBuffer("[0x%x]", disp); 346 AppendToBuffer("[0x%x]", disp);
332 return 5; 347 return 5;
333 } else if (rm == esp) { 348 } else if (rm == esp) {
334 byte sib = *(modrmp + 1); 349 byte sib = *(modrmp + 1);
335 int scale, index, base; 350 int scale, index, base;
336 get_sib(sib, &scale, &index, &base); 351 get_sib(sib, &scale, &index, &base);
337 if (index == esp && base == esp && scale == 0 /*times_1*/) { 352 if (index == esp && base == esp && scale == 0 /*times_1*/) {
338 AppendToBuffer("[%s]", NameOfCPURegister(rm)); 353 AppendToBuffer("[%s]", (this->*register_name)(rm));
339 return 2; 354 return 2;
340 } else if (base == ebp) { 355 } else if (base == ebp) {
341 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); 356 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
342 AppendToBuffer("[%s*%d+0x%x]", 357 AppendToBuffer("[%s*%d+0x%x]",
343 NameOfCPURegister(index), 358 (this->*register_name)(index),
344 1 << scale, 359 1 << scale,
345 disp); 360 disp);
346 return 6; 361 return 6;
347 } else if (index != esp && base != ebp) { 362 } else if (index != esp && base != ebp) {
348 // [base+index*scale] 363 // [base+index*scale]
349 AppendToBuffer("[%s+%s*%d]", 364 AppendToBuffer("[%s+%s*%d]",
350 NameOfCPURegister(base), 365 (this->*register_name)(base),
351 NameOfCPURegister(index), 366 (this->*register_name)(index),
352 1 << scale); 367 1 << scale);
353 return 2; 368 return 2;
354 } else { 369 } else {
355 UnimplementedInstruction(); 370 UnimplementedInstruction();
356 return 1; 371 return 1;
357 } 372 }
358 } else { 373 } else {
359 AppendToBuffer("[%s]", NameOfCPURegister(rm)); 374 AppendToBuffer("[%s]", (this->*register_name)(rm));
360 return 1; 375 return 1;
361 } 376 }
362 break; 377 break;
363 case 1: // fall through 378 case 1: // fall through
364 case 2: 379 case 2:
365 if (rm == esp) { 380 if (rm == esp) {
366 byte sib = *(modrmp + 1); 381 byte sib = *(modrmp + 1);
367 int scale, index, base; 382 int scale, index, base;
368 get_sib(sib, &scale, &index, &base); 383 get_sib(sib, &scale, &index, &base);
369 int disp = 384 int disp =
370 mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) : *(modrmp + 2); 385 mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) : *(modrmp + 2);
371 if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) { 386 if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) {
372 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp); 387 AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp);
373 } else { 388 } else {
374 AppendToBuffer("[%s+%s*%d+0x%x]", 389 AppendToBuffer("[%s+%s*%d+0x%x]",
375 NameOfCPURegister(base), 390 (this->*register_name)(base),
376 NameOfCPURegister(index), 391 (this->*register_name)(index),
377 1 << scale, 392 1 << scale,
378 disp); 393 disp);
379 } 394 }
380 return mod == 2 ? 6 : 3; 395 return mod == 2 ? 6 : 3;
381 } else { 396 } else {
382 // No sib. 397 // No sib.
383 int disp = 398 int disp =
384 mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) : *(modrmp + 1); 399 mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) : *(modrmp + 1);
385 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp); 400 AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp);
386 return mod == 2 ? 5 : 2; 401 return mod == 2 ? 5 : 2;
387 } 402 }
388 break; 403 break;
389 case 3: 404 case 3:
390 AppendToBuffer("%s", NameOfCPURegister(rm)); 405 AppendToBuffer("%s", (this->*register_name)(rm));
391 return 1; 406 return 1;
392 default: 407 default:
393 UnimplementedInstruction(); 408 UnimplementedInstruction();
394 return 1; 409 return 1;
395 } 410 }
396 UNREACHABLE(); 411 UNREACHABLE();
397 } 412 }
398 413
399 414
415 int DisassemblerIA32::PrintRightOperand(byte* modrmp) {
416 return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister);
417 }
418
419
420 int DisassemblerIA32::PrintRightByteOperand(byte* modrmp) {
421 return PrintRightOperandHelper(modrmp,
422 &DisassemblerIA32::NameOfByteCPURegister);
423 }
424
425
400 // Returns number of bytes used including the current *data. 426 // Returns number of bytes used including the current *data.
401 // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'. 427 // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
402 int DisassemblerIA32::PrintOperands(const char* mnem, 428 int DisassemblerIA32::PrintOperands(const char* mnem,
403 OperandOrder op_order, 429 OperandOrder op_order,
404 byte* data) { 430 byte* data) {
405 byte modrm = *data; 431 byte modrm = *data;
406 int mod, regop, rm; 432 int mod, regop, rm;
407 get_modrm(modrm, &mod, &regop, &rm); 433 get_modrm(modrm, &mod, &regop, &rm);
408 int advance = 0; 434 int advance = 0;
409 switch (op_order) { 435 switch (op_order) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 AppendToBuffer(", %s", comment); 600 AppendToBuffer(", %s", comment);
575 } 601 }
576 return 2; 602 return 2;
577 } 603 }
578 604
579 605
580 // Returns number of bytes used, including *data. 606 // Returns number of bytes used, including *data.
581 int DisassemblerIA32::SetCC(byte* data) { 607 int DisassemblerIA32::SetCC(byte* data) {
582 assert(*data == 0x0F); 608 assert(*data == 0x0F);
583 byte cond = *(data+1) & 0x0F; 609 byte cond = *(data+1) & 0x0F;
584 const char* mnem = jump_conditional_mnem[cond]; 610 const char* mnem = set_conditional_mnem[cond];
585 AppendToBuffer("set%s ", mnem); 611 AppendToBuffer("%s ", mnem);
586 PrintRightOperand(data+2); 612 PrintRightByteOperand(data+2);
587 return 3; // includes 0x0F 613 return 3; // includes 0x0F
588 } 614 }
589 615
590 616
591 // Returns number of bytes used, including *data. 617 // Returns number of bytes used, including *data.
592 int DisassemblerIA32::FPUInstruction(byte* data) { 618 int DisassemblerIA32::FPUInstruction(byte* data) {
593 byte b1 = *data; 619 byte b1 = *data;
594 byte b2 = *(data + 1); 620 byte b2 = *(data + 1);
595 if (b1 == 0xD9) { 621 if (b1 == 0xD9) {
596 const char* mnem = NULL; 622 const char* mnem = NULL;
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 " %s", 1088 " %s",
1063 tmp_buffer_.start()); 1089 tmp_buffer_.start());
1064 return instr_len; 1090 return instr_len;
1065 } 1091 }
1066 1092
1067 1093
1068 //------------------------------------------------------------------------------ 1094 //------------------------------------------------------------------------------
1069 1095
1070 1096
1071 static const char* cpu_regs[8] = { 1097 static const char* cpu_regs[8] = {
1072 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", 1098 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
1099 };
1100
1101
1102 static const char* byte_cpu_regs[8] = {
1103 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
1073 }; 1104 };
1074 1105
1075 1106
1076 static const char* xmm_regs[8] = { 1107 static const char* xmm_regs[8] = {
1077 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 1108 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
1078 }; 1109 };
1079 1110
1080 1111
1081 const char* NameConverter::NameOfAddress(byte* addr) const { 1112 const char* NameConverter::NameOfAddress(byte* addr) const {
1082 static v8::internal::EmbeddedVector<char, 32> tmp_buffer; 1113 static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
1083 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr); 1114 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
1084 return tmp_buffer.start(); 1115 return tmp_buffer.start();
1085 } 1116 }
1086 1117
1087 1118
1088 const char* NameConverter::NameOfConstant(byte* addr) const { 1119 const char* NameConverter::NameOfConstant(byte* addr) const {
1089 return NameOfAddress(addr); 1120 return NameOfAddress(addr);
1090 } 1121 }
1091 1122
1092 1123
1093 const char* NameConverter::NameOfCPURegister(int reg) const { 1124 const char* NameConverter::NameOfCPURegister(int reg) const {
1094 if (0 <= reg && reg < 8) return cpu_regs[reg]; 1125 if (0 <= reg && reg < 8) return cpu_regs[reg];
1095 return "noreg"; 1126 return "noreg";
1096 } 1127 }
1097 1128
1098 1129
1130 const char* NameConverter::NameOfByteCPURegister(int reg) const {
1131 if (0 <= reg && reg < 8) return byte_cpu_regs[reg];
1132 return "noreg";
1133 }
1134
1135
1099 const char* NameConverter::NameOfXMMRegister(int reg) const { 1136 const char* NameConverter::NameOfXMMRegister(int reg) const {
1100 if (0 <= reg && reg < 8) return xmm_regs[reg]; 1137 if (0 <= reg && reg < 8) return xmm_regs[reg];
1101 return "noxmmreg"; 1138 return "noxmmreg";
1102 } 1139 }
1103 1140
1104 1141
1105 const char* NameConverter::NameInCode(byte* addr) const { 1142 const char* NameConverter::NameInCode(byte* addr) const {
1106 // IA32 does not embed debug strings at the moment. 1143 // IA32 does not embed debug strings at the moment.
1107 UNREACHABLE(); 1144 UNREACHABLE();
1108 return ""; 1145 return "";
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 } 1182 }
1146 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 1183 for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
1147 fprintf(f, " "); 1184 fprintf(f, " ");
1148 } 1185 }
1149 fprintf(f, " %s\n", buffer.start()); 1186 fprintf(f, " %s\n", buffer.start());
1150 } 1187 }
1151 } 1188 }
1152 1189
1153 1190
1154 } // namespace disasm 1191 } // namespace disasm
OLDNEW
« no previous file with comments | « src/disasm-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698