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

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

Issue 293743005: Introduce x87 port (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: rebase Created 6 years, 7 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
« no previous file with comments | « src/x87/deoptimizer-x87.cc ('k') | src/x87/frames-x87.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <assert.h> 5 #include <assert.h>
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <stdarg.h> 7 #include <stdarg.h>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 10
11 #if V8_TARGET_ARCH_IA32 11 #if V8_TARGET_ARCH_X87
12 12
13 #include "disasm.h" 13 #include "disasm.h"
14 14
15 namespace disasm { 15 namespace disasm {
16 16
17 enum OperandOrder { 17 enum OperandOrder {
18 UNSET_OP_ORDER = 0, 18 UNSET_OP_ORDER = 0,
19 REG_OPER_OP_ORDER, 19 REG_OPER_OP_ORDER,
20 OPER_REG_OP_ORDER 20 OPER_REG_OP_ORDER
21 }; 21 };
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 void InstructionTable::AddJumpConditionalShort() { 233 void InstructionTable::AddJumpConditionalShort() {
234 for (byte b = 0x70; b <= 0x7F; b++) { 234 for (byte b = 0x70; b <= 0x7F; b++) {
235 InstructionDesc* id = &instructions_[b]; 235 InstructionDesc* id = &instructions_[b];
236 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. 236 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
237 id->mnem = jump_conditional_mnem[b & 0x0F]; 237 id->mnem = jump_conditional_mnem[b & 0x0F];
238 id->type = JUMP_CONDITIONAL_SHORT_INSTR; 238 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
239 } 239 }
240 } 240 }
241 241
242 242
243 // The IA32 disassembler implementation. 243 // The X87 disassembler implementation.
244 class DisassemblerIA32 { 244 class DisassemblerX87 {
245 public: 245 public:
246 DisassemblerIA32(const NameConverter& converter, 246 DisassemblerX87(const NameConverter& converter,
247 bool abort_on_unimplemented = true) 247 bool abort_on_unimplemented = true)
248 : converter_(converter), 248 : converter_(converter),
249 instruction_table_(InstructionTable::get_instance()), 249 instruction_table_(InstructionTable::get_instance()),
250 tmp_buffer_pos_(0), 250 tmp_buffer_pos_(0),
251 abort_on_unimplemented_(abort_on_unimplemented) { 251 abort_on_unimplemented_(abort_on_unimplemented) {
252 tmp_buffer_[0] = '\0'; 252 tmp_buffer_[0] = '\0';
253 } 253 }
254 254
255 virtual ~DisassemblerIA32() {} 255 virtual ~DisassemblerX87() {}
256 256
257 // Writes one disassembled instruction into 'buffer' (0-terminated). 257 // Writes one disassembled instruction into 'buffer' (0-terminated).
258 // Returns the length of the disassembled machine instruction in bytes. 258 // Returns the length of the disassembled machine instruction in bytes.
259 int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); 259 int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
260 260
261 private: 261 private:
262 const NameConverter& converter_; 262 const NameConverter& converter_;
263 InstructionTable* instruction_table_; 263 InstructionTable* instruction_table_;
264 v8::internal::EmbeddedVector<char, 128> tmp_buffer_; 264 v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
265 unsigned int tmp_buffer_pos_; 265 unsigned int tmp_buffer_pos_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 *rm = data & 7; 315 *rm = data & 7;
316 } 316 }
317 317
318 318
319 static void get_sib(byte data, int* scale, int* index, int* base) { 319 static void get_sib(byte data, int* scale, int* index, int* base) {
320 *scale = (data >> 6) & 3; 320 *scale = (data >> 6) & 3;
321 *index = (data >> 3) & 7; 321 *index = (data >> 3) & 7;
322 *base = data & 7; 322 *base = data & 7;
323 } 323 }
324 324
325 typedef const char* (DisassemblerIA32::*RegisterNameMapping)(int reg) const; 325 typedef const char* (DisassemblerX87::*RegisterNameMapping)(int reg) const;
326 326
327 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); 327 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
328 int PrintRightOperand(byte* modrmp); 328 int PrintRightOperand(byte* modrmp);
329 int PrintRightByteOperand(byte* modrmp); 329 int PrintRightByteOperand(byte* modrmp);
330 int PrintRightXMMOperand(byte* modrmp); 330 int PrintRightXMMOperand(byte* modrmp);
331 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 331 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
332 int PrintImmediateOp(byte* data); 332 int PrintImmediateOp(byte* data);
333 int F7Instruction(byte* data); 333 int F7Instruction(byte* data);
334 int D1D3C1Instruction(byte* data); 334 int D1D3C1Instruction(byte* data);
335 int JumpShort(byte* data); 335 int JumpShort(byte* data);
(...skipping 10 matching lines...) Expand all
346 void UnimplementedInstruction() { 346 void UnimplementedInstruction() {
347 if (abort_on_unimplemented_) { 347 if (abort_on_unimplemented_) {
348 UNIMPLEMENTED(); 348 UNIMPLEMENTED();
349 } else { 349 } else {
350 AppendToBuffer("'Unimplemented Instruction'"); 350 AppendToBuffer("'Unimplemented Instruction'");
351 } 351 }
352 } 352 }
353 }; 353 };
354 354
355 355
356 void DisassemblerIA32::AppendToBuffer(const char* format, ...) { 356 void DisassemblerX87::AppendToBuffer(const char* format, ...) {
357 v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_; 357 v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
358 va_list args; 358 va_list args;
359 va_start(args, format); 359 va_start(args, format);
360 int result = v8::internal::OS::VSNPrintF(buf, format, args); 360 int result = v8::internal::OS::VSNPrintF(buf, format, args);
361 va_end(args); 361 va_end(args);
362 tmp_buffer_pos_ += result; 362 tmp_buffer_pos_ += result;
363 } 363 }
364 364
365 int DisassemblerIA32::PrintRightOperandHelper( 365 int DisassemblerX87::PrintRightOperandHelper(
366 byte* modrmp, 366 byte* modrmp,
367 RegisterNameMapping direct_register_name) { 367 RegisterNameMapping direct_register_name) {
368 int mod, regop, rm; 368 int mod, regop, rm;
369 get_modrm(*modrmp, &mod, &regop, &rm); 369 get_modrm(*modrmp, &mod, &regop, &rm);
370 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : 370 RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
371 &DisassemblerIA32::NameOfCPURegister; 371 &DisassemblerX87::NameOfCPURegister;
372 switch (mod) { 372 switch (mod) {
373 case 0: 373 case 0:
374 if (rm == ebp) { 374 if (rm == ebp) {
375 int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1); 375 int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1);
376 AppendToBuffer("[0x%x]", disp); 376 AppendToBuffer("[0x%x]", disp);
377 return 5; 377 return 5;
378 } else if (rm == esp) { 378 } else if (rm == esp) {
379 byte sib = *(modrmp + 1); 379 byte sib = *(modrmp + 1);
380 int scale, index, base; 380 int scale, index, base;
381 get_sib(sib, &scale, &index, &base); 381 get_sib(sib, &scale, &index, &base);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 AppendToBuffer("%s", (this->*register_name)(rm)); 443 AppendToBuffer("%s", (this->*register_name)(rm));
444 return 1; 444 return 1;
445 default: 445 default:
446 UnimplementedInstruction(); 446 UnimplementedInstruction();
447 return 1; 447 return 1;
448 } 448 }
449 UNREACHABLE(); 449 UNREACHABLE();
450 } 450 }
451 451
452 452
453 int DisassemblerIA32::PrintRightOperand(byte* modrmp) { 453 int DisassemblerX87::PrintRightOperand(byte* modrmp) {
454 return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister); 454 return PrintRightOperandHelper(modrmp, &DisassemblerX87::NameOfCPURegister);
455 } 455 }
456 456
457 457
458 int DisassemblerIA32::PrintRightByteOperand(byte* modrmp) { 458 int DisassemblerX87::PrintRightByteOperand(byte* modrmp) {
459 return PrintRightOperandHelper(modrmp, 459 return PrintRightOperandHelper(modrmp,
460 &DisassemblerIA32::NameOfByteCPURegister); 460 &DisassemblerX87::NameOfByteCPURegister);
461 } 461 }
462 462
463 463
464 int DisassemblerIA32::PrintRightXMMOperand(byte* modrmp) { 464 int DisassemblerX87::PrintRightXMMOperand(byte* modrmp) {
465 return PrintRightOperandHelper(modrmp, 465 return PrintRightOperandHelper(modrmp,
466 &DisassemblerIA32::NameOfXMMRegister); 466 &DisassemblerX87::NameOfXMMRegister);
467 } 467 }
468 468
469 469
470 // Returns number of bytes used including the current *data. 470 // Returns number of bytes used including the current *data.
471 // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'. 471 // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
472 int DisassemblerIA32::PrintOperands(const char* mnem, 472 int DisassemblerX87::PrintOperands(const char* mnem,
473 OperandOrder op_order, 473 OperandOrder op_order,
474 byte* data) { 474 byte* data) {
475 byte modrm = *data; 475 byte modrm = *data;
476 int mod, regop, rm; 476 int mod, regop, rm;
477 get_modrm(modrm, &mod, &regop, &rm); 477 get_modrm(modrm, &mod, &regop, &rm);
478 int advance = 0; 478 int advance = 0;
479 switch (op_order) { 479 switch (op_order) {
480 case REG_OPER_OP_ORDER: { 480 case REG_OPER_OP_ORDER: {
481 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop)); 481 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));
482 advance = PrintRightOperand(data); 482 advance = PrintRightOperand(data);
483 break; 483 break;
484 } 484 }
485 case OPER_REG_OP_ORDER: { 485 case OPER_REG_OP_ORDER: {
486 AppendToBuffer("%s ", mnem); 486 AppendToBuffer("%s ", mnem);
487 advance = PrintRightOperand(data); 487 advance = PrintRightOperand(data);
488 AppendToBuffer(",%s", NameOfCPURegister(regop)); 488 AppendToBuffer(",%s", NameOfCPURegister(regop));
489 break; 489 break;
490 } 490 }
491 default: 491 default:
492 UNREACHABLE(); 492 UNREACHABLE();
493 break; 493 break;
494 } 494 }
495 return advance; 495 return advance;
496 } 496 }
497 497
498 498
499 // Returns number of bytes used by machine instruction, including *data byte. 499 // Returns number of bytes used by machine instruction, including *data byte.
500 // Writes immediate instructions to 'tmp_buffer_'. 500 // Writes immediate instructions to 'tmp_buffer_'.
501 int DisassemblerIA32::PrintImmediateOp(byte* data) { 501 int DisassemblerX87::PrintImmediateOp(byte* data) {
502 bool sign_extension_bit = (*data & 0x02) != 0; 502 bool sign_extension_bit = (*data & 0x02) != 0;
503 byte modrm = *(data+1); 503 byte modrm = *(data+1);
504 int mod, regop, rm; 504 int mod, regop, rm;
505 get_modrm(modrm, &mod, &regop, &rm); 505 get_modrm(modrm, &mod, &regop, &rm);
506 const char* mnem = "Imm???"; 506 const char* mnem = "Imm???";
507 switch (regop) { 507 switch (regop) {
508 case 0: mnem = "add"; break; 508 case 0: mnem = "add"; break;
509 case 1: mnem = "or"; break; 509 case 1: mnem = "or"; break;
510 case 2: mnem = "adc"; break; 510 case 2: mnem = "adc"; break;
511 case 4: mnem = "and"; break; 511 case 4: mnem = "and"; break;
512 case 5: mnem = "sub"; break; 512 case 5: mnem = "sub"; break;
513 case 6: mnem = "xor"; break; 513 case 6: mnem = "xor"; break;
514 case 7: mnem = "cmp"; break; 514 case 7: mnem = "cmp"; break;
515 default: UnimplementedInstruction(); 515 default: UnimplementedInstruction();
516 } 516 }
517 AppendToBuffer("%s ", mnem); 517 AppendToBuffer("%s ", mnem);
518 int count = PrintRightOperand(data+1); 518 int count = PrintRightOperand(data+1);
519 if (sign_extension_bit) { 519 if (sign_extension_bit) {
520 AppendToBuffer(",0x%x", *(data + 1 + count)); 520 AppendToBuffer(",0x%x", *(data + 1 + count));
521 return 1 + count + 1 /*int8*/; 521 return 1 + count + 1 /*int8*/;
522 } else { 522 } else {
523 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); 523 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));
524 return 1 + count + 4 /*int32_t*/; 524 return 1 + count + 4 /*int32_t*/;
525 } 525 }
526 } 526 }
527 527
528 528
529 // Returns number of bytes used, including *data. 529 // Returns number of bytes used, including *data.
530 int DisassemblerIA32::F7Instruction(byte* data) { 530 int DisassemblerX87::F7Instruction(byte* data) {
531 ASSERT_EQ(0xF7, *data); 531 ASSERT_EQ(0xF7, *data);
532 byte modrm = *(data+1); 532 byte modrm = *(data+1);
533 int mod, regop, rm; 533 int mod, regop, rm;
534 get_modrm(modrm, &mod, &regop, &rm); 534 get_modrm(modrm, &mod, &regop, &rm);
535 if (mod == 3 && regop != 0) { 535 if (mod == 3 && regop != 0) {
536 const char* mnem = NULL; 536 const char* mnem = NULL;
537 switch (regop) { 537 switch (regop) {
538 case 2: mnem = "not"; break; 538 case 2: mnem = "not"; break;
539 case 3: mnem = "neg"; break; 539 case 3: mnem = "neg"; break;
540 case 4: mnem = "mul"; break; 540 case 4: mnem = "mul"; break;
(...skipping 13 matching lines...) Expand all
554 int32_t imm = *reinterpret_cast<int32_t*>(data+1+count); 554 int32_t imm = *reinterpret_cast<int32_t*>(data+1+count);
555 AppendToBuffer(",0x%x", imm); 555 AppendToBuffer(",0x%x", imm);
556 return 1+count+4 /*int32_t*/; 556 return 1+count+4 /*int32_t*/;
557 } else { 557 } else {
558 UnimplementedInstruction(); 558 UnimplementedInstruction();
559 return 2; 559 return 2;
560 } 560 }
561 } 561 }
562 562
563 563
564 int DisassemblerIA32::D1D3C1Instruction(byte* data) { 564 int DisassemblerX87::D1D3C1Instruction(byte* data) {
565 byte op = *data; 565 byte op = *data;
566 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); 566 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1);
567 byte modrm = *(data+1); 567 byte modrm = *(data+1);
568 int mod, regop, rm; 568 int mod, regop, rm;
569 get_modrm(modrm, &mod, &regop, &rm); 569 get_modrm(modrm, &mod, &regop, &rm);
570 int imm8 = -1; 570 int imm8 = -1;
571 int num_bytes = 2; 571 int num_bytes = 2;
572 if (mod == 3) { 572 if (mod == 3) {
573 const char* mnem = NULL; 573 const char* mnem = NULL;
574 switch (regop) { 574 switch (regop) {
(...skipping 22 matching lines...) Expand all
597 AppendToBuffer("cl"); 597 AppendToBuffer("cl");
598 } 598 }
599 } else { 599 } else {
600 UnimplementedInstruction(); 600 UnimplementedInstruction();
601 } 601 }
602 return num_bytes; 602 return num_bytes;
603 } 603 }
604 604
605 605
606 // Returns number of bytes used, including *data. 606 // Returns number of bytes used, including *data.
607 int DisassemblerIA32::JumpShort(byte* data) { 607 int DisassemblerX87::JumpShort(byte* data) {
608 ASSERT_EQ(0xEB, *data); 608 ASSERT_EQ(0xEB, *data);
609 byte b = *(data+1); 609 byte b = *(data+1);
610 byte* dest = data + static_cast<int8_t>(b) + 2; 610 byte* dest = data + static_cast<int8_t>(b) + 2;
611 AppendToBuffer("jmp %s", NameOfAddress(dest)); 611 AppendToBuffer("jmp %s", NameOfAddress(dest));
612 return 2; 612 return 2;
613 } 613 }
614 614
615 615
616 // Returns number of bytes used, including *data. 616 // Returns number of bytes used, including *data.
617 int DisassemblerIA32::JumpConditional(byte* data, const char* comment) { 617 int DisassemblerX87::JumpConditional(byte* data, const char* comment) {
618 ASSERT_EQ(0x0F, *data); 618 ASSERT_EQ(0x0F, *data);
619 byte cond = *(data+1) & 0x0F; 619 byte cond = *(data+1) & 0x0F;
620 byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; 620 byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6;
621 const char* mnem = jump_conditional_mnem[cond]; 621 const char* mnem = jump_conditional_mnem[cond];
622 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 622 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
623 if (comment != NULL) { 623 if (comment != NULL) {
624 AppendToBuffer(", %s", comment); 624 AppendToBuffer(", %s", comment);
625 } 625 }
626 return 6; // includes 0x0F 626 return 6; // includes 0x0F
627 } 627 }
628 628
629 629
630 // Returns number of bytes used, including *data. 630 // Returns number of bytes used, including *data.
631 int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { 631 int DisassemblerX87::JumpConditionalShort(byte* data, const char* comment) {
632 byte cond = *data & 0x0F; 632 byte cond = *data & 0x0F;
633 byte b = *(data+1); 633 byte b = *(data+1);
634 byte* dest = data + static_cast<int8_t>(b) + 2; 634 byte* dest = data + static_cast<int8_t>(b) + 2;
635 const char* mnem = jump_conditional_mnem[cond]; 635 const char* mnem = jump_conditional_mnem[cond];
636 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 636 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
637 if (comment != NULL) { 637 if (comment != NULL) {
638 AppendToBuffer(", %s", comment); 638 AppendToBuffer(", %s", comment);
639 } 639 }
640 return 2; 640 return 2;
641 } 641 }
642 642
643 643
644 // Returns number of bytes used, including *data. 644 // Returns number of bytes used, including *data.
645 int DisassemblerIA32::SetCC(byte* data) { 645 int DisassemblerX87::SetCC(byte* data) {
646 ASSERT_EQ(0x0F, *data); 646 ASSERT_EQ(0x0F, *data);
647 byte cond = *(data+1) & 0x0F; 647 byte cond = *(data+1) & 0x0F;
648 const char* mnem = set_conditional_mnem[cond]; 648 const char* mnem = set_conditional_mnem[cond];
649 AppendToBuffer("%s ", mnem); 649 AppendToBuffer("%s ", mnem);
650 PrintRightByteOperand(data+2); 650 PrintRightByteOperand(data+2);
651 return 3; // Includes 0x0F. 651 return 3; // Includes 0x0F.
652 } 652 }
653 653
654 654
655 // Returns number of bytes used, including *data. 655 // Returns number of bytes used, including *data.
656 int DisassemblerIA32::CMov(byte* data) { 656 int DisassemblerX87::CMov(byte* data) {
657 ASSERT_EQ(0x0F, *data); 657 ASSERT_EQ(0x0F, *data);
658 byte cond = *(data + 1) & 0x0F; 658 byte cond = *(data + 1) & 0x0F;
659 const char* mnem = conditional_move_mnem[cond]; 659 const char* mnem = conditional_move_mnem[cond];
660 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 660 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
661 return 2 + op_size; // includes 0x0F 661 return 2 + op_size; // includes 0x0F
662 } 662 }
663 663
664 664
665 // Returns number of bytes used, including *data. 665 // Returns number of bytes used, including *data.
666 int DisassemblerIA32::FPUInstruction(byte* data) { 666 int DisassemblerX87::FPUInstruction(byte* data) {
667 byte escape_opcode = *data; 667 byte escape_opcode = *data;
668 ASSERT_EQ(0xD8, escape_opcode & 0xF8); 668 ASSERT_EQ(0xD8, escape_opcode & 0xF8);
669 byte modrm_byte = *(data+1); 669 byte modrm_byte = *(data+1);
670 670
671 if (modrm_byte >= 0xC0) { 671 if (modrm_byte >= 0xC0) {
672 return RegisterFPUInstruction(escape_opcode, modrm_byte); 672 return RegisterFPUInstruction(escape_opcode, modrm_byte);
673 } else { 673 } else {
674 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); 674 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
675 } 675 }
676 } 676 }
677 677
678 int DisassemblerIA32::MemoryFPUInstruction(int escape_opcode, 678 int DisassemblerX87::MemoryFPUInstruction(int escape_opcode,
679 int modrm_byte, 679 int modrm_byte,
680 byte* modrm_start) { 680 byte* modrm_start) {
681 const char* mnem = "?"; 681 const char* mnem = "?";
682 int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte. 682 int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte.
683 switch (escape_opcode) { 683 switch (escape_opcode) {
684 case 0xD9: switch (regop) { 684 case 0xD9: switch (regop) {
685 case 0: mnem = "fld_s"; break; 685 case 0: mnem = "fld_s"; break;
686 case 2: mnem = "fst_s"; break; 686 case 2: mnem = "fst_s"; break;
687 case 3: mnem = "fstp_s"; break; 687 case 3: mnem = "fstp_s"; break;
688 case 7: mnem = "fstcw"; break; 688 case 7: mnem = "fstcw"; break;
(...skipping 26 matching lines...) Expand all
715 } 715 }
716 break; 716 break;
717 717
718 default: UnimplementedInstruction(); 718 default: UnimplementedInstruction();
719 } 719 }
720 AppendToBuffer("%s ", mnem); 720 AppendToBuffer("%s ", mnem);
721 int count = PrintRightOperand(modrm_start); 721 int count = PrintRightOperand(modrm_start);
722 return count + 1; 722 return count + 1;
723 } 723 }
724 724
725 int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, 725 int DisassemblerX87::RegisterFPUInstruction(int escape_opcode,
726 byte modrm_byte) { 726 byte modrm_byte) {
727 bool has_register = false; // Is the FPU register encoded in modrm_byte? 727 bool has_register = false; // Is the FPU register encoded in modrm_byte?
728 const char* mnem = "?"; 728 const char* mnem = "?";
729 729
730 switch (escape_opcode) { 730 switch (escape_opcode) {
731 case 0xD8: 731 case 0xD8:
732 has_register = true; 732 has_register = true;
733 switch (modrm_byte & 0xF8) { 733 switch (modrm_byte & 0xF8) {
734 case 0xC0: mnem = "fadd_i"; break; 734 case 0xC0: mnem = "fadd_i"; break;
735 case 0xE0: mnem = "fsub_i"; break; 735 case 0xE0: mnem = "fsub_i"; break;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 case 0xAD: return "shrd"; 866 case 0xAD: return "shrd";
867 case 0xAC: return "shrd"; // 3-operand version. 867 case 0xAC: return "shrd"; // 3-operand version.
868 case 0xAB: return "bts"; 868 case 0xAB: return "bts";
869 case 0xBD: return "bsr"; 869 case 0xBD: return "bsr";
870 default: return NULL; 870 default: return NULL;
871 } 871 }
872 } 872 }
873 873
874 874
875 // Disassembled instruction '*instr' and writes it into 'out_buffer'. 875 // Disassembled instruction '*instr' and writes it into 'out_buffer'.
876 int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, 876 int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
877 byte* instr) { 877 byte* instr) {
878 tmp_buffer_pos_ = 0; // starting to write as position 0 878 tmp_buffer_pos_ = 0; // starting to write as position 0
879 byte* data = instr; 879 byte* data = instr;
880 // Check for hints. 880 // Check for hints.
881 const char* branch_hint = NULL; 881 const char* branch_hint = NULL;
882 // We use these two prefixes only with branch prediction 882 // We use these two prefixes only with branch prediction
883 if (*data == 0x3E /*ds*/) { 883 if (*data == 0x3E /*ds*/) {
884 branch_hint = "predicted taken"; 884 branch_hint = "predicted taken";
885 data++; 885 data++;
886 } else if (*data == 0x2E /*cs*/) { 886 } else if (*data == 0x2E /*cs*/) {
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 } 1702 }
1703 1703
1704 1704
1705 const char* NameConverter::NameOfXMMRegister(int reg) const { 1705 const char* NameConverter::NameOfXMMRegister(int reg) const {
1706 if (0 <= reg && reg < 8) return xmm_regs[reg]; 1706 if (0 <= reg && reg < 8) return xmm_regs[reg];
1707 return "noxmmreg"; 1707 return "noxmmreg";
1708 } 1708 }
1709 1709
1710 1710
1711 const char* NameConverter::NameInCode(byte* addr) const { 1711 const char* NameConverter::NameInCode(byte* addr) const {
1712 // IA32 does not embed debug strings at the moment. 1712 // X87 does not embed debug strings at the moment.
1713 UNREACHABLE(); 1713 UNREACHABLE();
1714 return ""; 1714 return "";
1715 } 1715 }
1716 1716
1717 1717
1718 //------------------------------------------------------------------------------ 1718 //------------------------------------------------------------------------------
1719 1719
1720 Disassembler::Disassembler(const NameConverter& converter) 1720 Disassembler::Disassembler(const NameConverter& converter)
1721 : converter_(converter) {} 1721 : converter_(converter) {}
1722 1722
1723 1723
1724 Disassembler::~Disassembler() {} 1724 Disassembler::~Disassembler() {}
1725 1725
1726 1726
1727 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1727 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1728 byte* instruction) { 1728 byte* instruction) {
1729 DisassemblerIA32 d(converter_, false /*do not crash if unimplemented*/); 1729 DisassemblerX87 d(converter_, false /*do not crash if unimplemented*/);
1730 return d.InstructionDecode(buffer, instruction); 1730 return d.InstructionDecode(buffer, instruction);
1731 } 1731 }
1732 1732
1733 1733
1734 // The IA-32 assembler does not currently use constant pools. 1734 // The IA-32 assembler does not currently use constant pools.
1735 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 1735 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1736 1736
1737 1737
1738 /*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1738 /*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1739 NameConverter converter; 1739 NameConverter converter;
(...skipping 12 matching lines...) Expand all
1752 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 1752 for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
1753 fprintf(f, " "); 1753 fprintf(f, " ");
1754 } 1754 }
1755 fprintf(f, " %s\n", buffer.start()); 1755 fprintf(f, " %s\n", buffer.start());
1756 } 1756 }
1757 } 1757 }
1758 1758
1759 1759
1760 } // namespace disasm 1760 } // namespace disasm
1761 1761
1762 #endif // V8_TARGET_ARCH_IA32 1762 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/deoptimizer-x87.cc ('k') | src/x87/frames-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698