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

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

Issue 316010: Add fucomip instruction to disassembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 1 month 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 | src/x64/disasm-x64.cc » ('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 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. 197 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop.
198 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); 198 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
199 } 199 }
200 200
201 201
202 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) { 202 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {
203 for (int i = 0; bm[i].b >= 0; i++) { 203 for (int i = 0; bm[i].b >= 0; i++) {
204 InstructionDesc* id = &instructions_[bm[i].b]; 204 InstructionDesc* id = &instructions_[bm[i].b];
205 id->mnem = bm[i].mnem; 205 id->mnem = bm[i].mnem;
206 id->op_order_ = bm[i].op_order_; 206 id->op_order_ = bm[i].op_order_;
207 assert(id->type == NO_INSTR); // Information already entered 207 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
208 id->type = type; 208 id->type = type;
209 } 209 }
210 } 210 }
211 211
212 212
213 void InstructionTable::SetTableRange(InstructionType type, 213 void InstructionTable::SetTableRange(InstructionType type,
214 byte start, 214 byte start,
215 byte end, 215 byte end,
216 const char* mnem) { 216 const char* mnem) {
217 for (byte b = start; b <= end; b++) { 217 for (byte b = start; b <= end; b++) {
218 InstructionDesc* id = &instructions_[b]; 218 InstructionDesc* id = &instructions_[b];
219 assert(id->type == NO_INSTR); // Information already entered 219 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
220 id->mnem = mnem; 220 id->mnem = mnem;
221 id->type = type; 221 id->type = type;
222 } 222 }
223 } 223 }
224 224
225 225
226 void InstructionTable::AddJumpConditionalShort() { 226 void InstructionTable::AddJumpConditionalShort() {
227 for (byte b = 0x70; b <= 0x7F; b++) { 227 for (byte b = 0x70; b <= 0x7F; b++) {
228 InstructionDesc* id = &instructions_[b]; 228 InstructionDesc* id = &instructions_[b];
229 assert(id->type == NO_INSTR); // Information already entered 229 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
230 id->mnem = jump_conditional_mnem[b & 0x0F]; 230 id->mnem = jump_conditional_mnem[b & 0x0F];
231 id->type = JUMP_CONDITIONAL_SHORT_INSTR; 231 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
232 } 232 }
233 } 233 }
234 234
235 235
236 static InstructionTable instruction_table; 236 static InstructionTable instruction_table;
237 237
238 238
239 // The IA32 disassembler implementation. 239 // The IA32 disassembler implementation.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 314 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
315 int PrintImmediateOp(byte* data); 315 int PrintImmediateOp(byte* data);
316 int F7Instruction(byte* data); 316 int F7Instruction(byte* data);
317 int D1D3C1Instruction(byte* data); 317 int D1D3C1Instruction(byte* data);
318 int JumpShort(byte* data); 318 int JumpShort(byte* data);
319 int JumpConditional(byte* data, const char* comment); 319 int JumpConditional(byte* data, const char* comment);
320 int JumpConditionalShort(byte* data, const char* comment); 320 int JumpConditionalShort(byte* data, const char* comment);
321 int SetCC(byte* data); 321 int SetCC(byte* data);
322 int CMov(byte* data); 322 int CMov(byte* data);
323 int FPUInstruction(byte* data); 323 int FPUInstruction(byte* data);
324 int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
325 int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
324 void AppendToBuffer(const char* format, ...); 326 void AppendToBuffer(const char* format, ...);
325 327
326 328
327 void UnimplementedInstruction() { 329 void UnimplementedInstruction() {
328 if (abort_on_unimplemented_) { 330 if (abort_on_unimplemented_) {
329 UNIMPLEMENTED(); 331 UNIMPLEMENTED();
330 } else { 332 } else {
331 AppendToBuffer("'Unimplemented Instruction'"); 333 AppendToBuffer("'Unimplemented Instruction'");
332 } 334 }
333 } 335 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 return 1 + count + 1 /*int8*/; 488 return 1 + count + 1 /*int8*/;
487 } else { 489 } else {
488 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); 490 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));
489 return 1 + count + 4 /*int32_t*/; 491 return 1 + count + 4 /*int32_t*/;
490 } 492 }
491 } 493 }
492 494
493 495
494 // Returns number of bytes used, including *data. 496 // Returns number of bytes used, including *data.
495 int DisassemblerIA32::F7Instruction(byte* data) { 497 int DisassemblerIA32::F7Instruction(byte* data) {
496 assert(*data == 0xF7); 498 ASSERT_EQ(0xF7, *data);
497 byte modrm = *(data+1); 499 byte modrm = *(data+1);
498 int mod, regop, rm; 500 int mod, regop, rm;
499 get_modrm(modrm, &mod, &regop, &rm); 501 get_modrm(modrm, &mod, &regop, &rm);
500 if (mod == 3 && regop != 0) { 502 if (mod == 3 && regop != 0) {
501 const char* mnem = NULL; 503 const char* mnem = NULL;
502 switch (regop) { 504 switch (regop) {
503 case 2: mnem = "not"; break; 505 case 2: mnem = "not"; break;
504 case 3: mnem = "neg"; break; 506 case 3: mnem = "neg"; break;
505 case 4: mnem = "mul"; break; 507 case 4: mnem = "mul"; break;
506 case 7: mnem = "idiv"; break; 508 case 7: mnem = "idiv"; break;
(...skipping 12 matching lines...) Expand all
519 AppendToBuffer(",0x%x", imm); 521 AppendToBuffer(",0x%x", imm);
520 return 1+count+4 /*int32_t*/; 522 return 1+count+4 /*int32_t*/;
521 } else { 523 } else {
522 UnimplementedInstruction(); 524 UnimplementedInstruction();
523 return 2; 525 return 2;
524 } 526 }
525 } 527 }
526 528
527 int DisassemblerIA32::D1D3C1Instruction(byte* data) { 529 int DisassemblerIA32::D1D3C1Instruction(byte* data) {
528 byte op = *data; 530 byte op = *data;
529 assert(op == 0xD1 || op == 0xD3 || op == 0xC1); 531 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1);
530 byte modrm = *(data+1); 532 byte modrm = *(data+1);
531 int mod, regop, rm; 533 int mod, regop, rm;
532 get_modrm(modrm, &mod, &regop, &rm); 534 get_modrm(modrm, &mod, &regop, &rm);
533 int imm8 = -1; 535 int imm8 = -1;
534 int num_bytes = 2; 536 int num_bytes = 2;
535 if (mod == 3) { 537 if (mod == 3) {
536 const char* mnem = NULL; 538 const char* mnem = NULL;
537 if (op == 0xD1) { 539 if (op == 0xD1) {
538 imm8 = 1; 540 imm8 = 1;
539 switch (regop) { 541 switch (regop) {
(...skipping 13 matching lines...) Expand all
553 default: UnimplementedInstruction(); 555 default: UnimplementedInstruction();
554 } 556 }
555 } else if (op == 0xD3) { 557 } else if (op == 0xD3) {
556 switch (regop) { 558 switch (regop) {
557 case esp: mnem = "shl"; break; 559 case esp: mnem = "shl"; break;
558 case ebp: mnem = "shr"; break; 560 case ebp: mnem = "shr"; break;
559 case edi: mnem = "sar"; break; 561 case edi: mnem = "sar"; break;
560 default: UnimplementedInstruction(); 562 default: UnimplementedInstruction();
561 } 563 }
562 } 564 }
563 assert(mnem != NULL); 565 ASSERT_NE(NULL, mnem);
564 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm)); 566 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm));
565 if (imm8 > 0) { 567 if (imm8 > 0) {
566 AppendToBuffer("%d", imm8); 568 AppendToBuffer("%d", imm8);
567 } else { 569 } else {
568 AppendToBuffer("cl"); 570 AppendToBuffer("cl");
569 } 571 }
570 } else { 572 } else {
571 UnimplementedInstruction(); 573 UnimplementedInstruction();
572 } 574 }
573 return num_bytes; 575 return num_bytes;
574 } 576 }
575 577
576 578
577 // Returns number of bytes used, including *data. 579 // Returns number of bytes used, including *data.
578 int DisassemblerIA32::JumpShort(byte* data) { 580 int DisassemblerIA32::JumpShort(byte* data) {
579 assert(*data == 0xEB); 581 ASSERT_EQ(0xEB, *data);
580 byte b = *(data+1); 582 byte b = *(data+1);
581 byte* dest = data + static_cast<int8_t>(b) + 2; 583 byte* dest = data + static_cast<int8_t>(b) + 2;
582 AppendToBuffer("jmp %s", NameOfAddress(dest)); 584 AppendToBuffer("jmp %s", NameOfAddress(dest));
583 return 2; 585 return 2;
584 } 586 }
585 587
586 588
587 // Returns number of bytes used, including *data. 589 // Returns number of bytes used, including *data.
588 int DisassemblerIA32::JumpConditional(byte* data, const char* comment) { 590 int DisassemblerIA32::JumpConditional(byte* data, const char* comment) {
589 assert(*data == 0x0F); 591 ASSERT_EQ(0x0F, *data);
590 byte cond = *(data+1) & 0x0F; 592 byte cond = *(data+1) & 0x0F;
591 byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; 593 byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6;
592 const char* mnem = jump_conditional_mnem[cond]; 594 const char* mnem = jump_conditional_mnem[cond];
593 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 595 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
594 if (comment != NULL) { 596 if (comment != NULL) {
595 AppendToBuffer(", %s", comment); 597 AppendToBuffer(", %s", comment);
596 } 598 }
597 return 6; // includes 0x0F 599 return 6; // includes 0x0F
598 } 600 }
599 601
600 602
601 // Returns number of bytes used, including *data. 603 // Returns number of bytes used, including *data.
602 int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { 604 int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) {
603 byte cond = *data & 0x0F; 605 byte cond = *data & 0x0F;
604 byte b = *(data+1); 606 byte b = *(data+1);
605 byte* dest = data + static_cast<int8_t>(b) + 2; 607 byte* dest = data + static_cast<int8_t>(b) + 2;
606 const char* mnem = jump_conditional_mnem[cond]; 608 const char* mnem = jump_conditional_mnem[cond];
607 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 609 AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
608 if (comment != NULL) { 610 if (comment != NULL) {
609 AppendToBuffer(", %s", comment); 611 AppendToBuffer(", %s", comment);
610 } 612 }
611 return 2; 613 return 2;
612 } 614 }
613 615
614 616
615 // Returns number of bytes used, including *data. 617 // Returns number of bytes used, including *data.
616 int DisassemblerIA32::SetCC(byte* data) { 618 int DisassemblerIA32::SetCC(byte* data) {
617 assert(*data == 0x0F); 619 ASSERT_EQ(0x0F, *data);
618 byte cond = *(data+1) & 0x0F; 620 byte cond = *(data+1) & 0x0F;
619 const char* mnem = set_conditional_mnem[cond]; 621 const char* mnem = set_conditional_mnem[cond];
620 AppendToBuffer("%s ", mnem); 622 AppendToBuffer("%s ", mnem);
621 PrintRightByteOperand(data+2); 623 PrintRightByteOperand(data+2);
622 return 3; // includes 0x0F 624 return 3; // Includes 0x0F.
623 } 625 }
624 626
625 627
626 // Returns number of bytes used, including *data. 628 // Returns number of bytes used, including *data.
627 int DisassemblerIA32::CMov(byte* data) { 629 int DisassemblerIA32::CMov(byte* data) {
628 assert(*data == 0x0F); 630 ASSERT_EQ(0x0F, *data);
629 byte cond = *(data + 1) & 0x0F; 631 byte cond = *(data + 1) & 0x0F;
630 const char* mnem = conditional_move_mnem[cond]; 632 const char* mnem = conditional_move_mnem[cond];
631 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 633 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
632 return 2 + op_size; // includes 0x0F 634 return 2 + op_size; // includes 0x0F
633 } 635 }
634 636
635 637
636 // Returns number of bytes used, including *data. 638 // Returns number of bytes used, including *data.
637 int DisassemblerIA32::FPUInstruction(byte* data) { 639 int DisassemblerIA32::FPUInstruction(byte* data) {
638 byte b1 = *data; 640 byte escape_opcode = *data;
639 byte b2 = *(data + 1); 641 ASSERT_EQ(0xD8, escape_opcode & 0xF8);
640 if (b1 == 0xD9) { 642 byte modrm_byte = *(data+1);
641 const char* mnem = NULL; 643
642 switch (b2) { 644 if (modrm_byte >= 0xC0) {
643 case 0xE8: mnem = "fld1"; break; 645 return RegisterFPUInstruction(escape_opcode, modrm_byte);
644 case 0xEE: mnem = "fldz"; break; 646 } else {
645 case 0xE1: mnem = "fabs"; break; 647 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
646 case 0xE0: mnem = "fchs"; break; 648 }
647 case 0xF8: mnem = "fprem"; break; 649 }
648 case 0xF5: mnem = "fprem1"; break; 650
649 case 0xF7: mnem = "fincstp"; break; 651 int DisassemblerIA32::MemoryFPUInstruction(int escape_opcode,
650 case 0xE4: mnem = "ftst"; break; 652 int modrm_byte,
651 } 653 byte* modrm_start) {
652 if (mnem != NULL) { 654 const char* mnem = "?";
653 AppendToBuffer("%s", mnem); 655 int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte.
654 return 2; 656 switch (escape_opcode) {
655 } else if ((b2 & 0xF8) == 0xC8) { 657 case 0xD9: switch (regop) {
656 AppendToBuffer("fxch st%d", b2 & 0x7); 658 case 0: mnem = "fld_s"; break;
657 return 2; 659 case 3: mnem = "fstp_s"; break;
658 } else { 660 case 7: mnem = "fstcw"; break;
659 int mod, regop, rm;
660 get_modrm(*(data+1), &mod, &regop, &rm);
661 const char* mnem = "?";
662 switch (regop) {
663 case eax: mnem = "fld_s"; break;
664 case ebx: mnem = "fstp_s"; break;
665 default: UnimplementedInstruction(); 661 default: UnimplementedInstruction();
666 } 662 }
667 AppendToBuffer("%s ", mnem); 663 break;
668 int count = PrintRightOperand(data + 1); 664
669 return count + 1; 665 case 0xDB: switch (regop) {
670 } 666 case 0: mnem = "fild_s"; break;
671 } else if (b1 == 0xDD) { 667 case 1: mnem = "fisttp_s"; break;
672 if ((b2 & 0xF8) == 0xC0) { 668 case 2: mnem = "fist_s"; break;
673 AppendToBuffer("ffree st%d", b2 & 0x7); 669 case 3: mnem = "fistp_s"; break;
674 return 2;
675 } else {
676 int mod, regop, rm;
677 get_modrm(*(data+1), &mod, &regop, &rm);
678 const char* mnem = "?";
679 switch (regop) {
680 case eax: mnem = "fld_d"; break;
681 case ebx: mnem = "fstp_d"; break;
682 default: UnimplementedInstruction(); 670 default: UnimplementedInstruction();
683 } 671 }
684 AppendToBuffer("%s ", mnem); 672 break;
685 int count = PrintRightOperand(data + 1); 673
686 return count + 1; 674 case 0xDD: switch (regop) {
687 } 675 case 0: mnem = "fld_d"; break;
688 } else if (b1 == 0xDB) { 676 case 3: mnem = "fstp_d"; break;
689 int mod, regop, rm; 677 default: UnimplementedInstruction();
690 get_modrm(*(data+1), &mod, &regop, &rm); 678 }
691 const char* mnem = "?"; 679 break;
692 switch (regop) { 680
693 case eax: mnem = "fild_s"; break; 681 case 0xDF: switch (regop) {
694 case edx: mnem = "fist_s"; break; 682 case 5: mnem = "fild_d"; break;
695 case ebx: mnem = "fistp_s"; break; 683 case 7: mnem = "fistp_d"; break;
696 default: UnimplementedInstruction(); 684 default: UnimplementedInstruction();
697 } 685 }
698 AppendToBuffer("%s ", mnem); 686 break;
699 int count = PrintRightOperand(data + 1); 687
700 return count + 1; 688 default: UnimplementedInstruction();
701 } else if (b1 == 0xDF) { 689 }
702 if (b2 == 0xE0) { 690 AppendToBuffer("%s ", mnem);
703 AppendToBuffer("fnstsw_ax"); 691 int count = PrintRightOperand(modrm_start);
704 return 2; 692 return count + 1;
705 } 693 }
706 int mod, regop, rm; 694
707 get_modrm(*(data+1), &mod, &regop, &rm); 695 int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
708 const char* mnem = "?"; 696 byte modrm_byte) {
709 switch (regop) { 697 bool has_register = false; // Is the FPU register encoded in modrm_byte?
710 case ebp: mnem = "fild_d"; break; 698 const char* mnem = "?";
711 case edi: mnem = "fistp_d"; break; 699
712 default: UnimplementedInstruction(); 700 switch (escape_opcode) {
713 } 701 case 0xD8:
714 AppendToBuffer("%s ", mnem); 702 UnimplementedInstruction();
715 int count = PrintRightOperand(data + 1); 703 break;
716 return count + 1; 704
717 } else if (b1 == 0xDC || b1 == 0xDE) { 705 case 0xD9:
718 bool is_pop = (b1 == 0xDE); 706 switch (modrm_byte & 0xF8) {
719 if (is_pop && b2 == 0xD9) { 707 case 0xC8:
720 AppendToBuffer("fcompp"); 708 mnem = "fxch";
721 return 2; 709 has_register = true;
722 } 710 break;
723 const char* mnem = "FP0xDC"; 711 default:
724 switch (b2 & 0xF8) { 712 switch (modrm_byte) {
725 case 0xC0: mnem = "fadd"; break; 713 case 0xE0: mnem = "fchs"; break;
726 case 0xE8: mnem = "fsub"; break; 714 case 0xE1: mnem = "fabs"; break;
727 case 0xC8: mnem = "fmul"; break; 715 case 0xE4: mnem = "ftst"; break;
728 case 0xF8: mnem = "fdiv"; break; 716 case 0xE8: mnem = "fld1"; break;
729 default: UnimplementedInstruction(); 717 case 0xEE: mnem = "fldz"; break;
730 } 718 case 0xF5: mnem = "fprem1"; break;
731 AppendToBuffer("%s%s st%d", mnem, is_pop ? "p" : "", b2 & 0x7); 719 case 0xF7: mnem = "fincstp"; break;
732 return 2; 720 case 0xF8: mnem = "fprem"; break;
733 } else if (b1 == 0xDA && b2 == 0xE9) { 721 case 0xFE: mnem = "fsin"; break;
734 const char* mnem = "fucompp"; 722 case 0xFF: mnem = "fcos"; break;
723 default: UnimplementedInstruction();
724 }
725 }
726 break;
727
728 case 0xDA:
729 if (modrm_byte == 0xE9) {
730 mnem = "fucompp";
731 } else {
732 UnimplementedInstruction();
733 }
734 break;
735
736 case 0xDB:
737 if ((modrm_byte & 0xF8) == 0xE8) {
738 mnem = "fucomi";
739 has_register = true;
740 } else if (modrm_byte == 0xE2) {
741 mnem = "fclex";
742 } else {
743 UnimplementedInstruction();
744 }
745 break;
746
747 case 0xDC:
748 has_register = true;
749 switch (modrm_byte & 0xF8) {
750 case 0xC0: mnem = "fadd"; break;
751 case 0xE8: mnem = "fsub"; break;
752 case 0xC8: mnem = "fmul"; break;
753 case 0xF8: mnem = "fdiv"; break;
754 default: UnimplementedInstruction();
755 }
756 break;
757
758 case 0xDD:
759 has_register = true;
760 switch (modrm_byte & 0xF8) {
761 case 0xC0: mnem = "ffree"; break;
762 case 0xD8: mnem = "fstp"; break;
763 default: UnimplementedInstruction();
764 }
765 break;
766
767 case 0xDE:
768 if (modrm_byte == 0xD9) {
769 mnem = "fcompp";
770 } else {
771 has_register = true;
772 switch (modrm_byte & 0xF8) {
773 case 0xC0: mnem = "faddp"; break;
774 case 0xE8: mnem = "fsubp"; break;
775 case 0xC8: mnem = "fmulp"; break;
776 case 0xF8: mnem = "fdivp"; break;
777 default: UnimplementedInstruction();
778 }
779 }
780 break;
781
782 case 0xDF:
783 if (modrm_byte == 0xE0) {
784 mnem = "fnstsw_ax";
785 } else if ((modrm_byte & 0xF8) == 0xE8) {
786 mnem = "fucomip";
787 has_register = true;
788 }
789 break;
790
791 default: UnimplementedInstruction();
792 }
793
794 if (has_register) {
795 AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
796 } else {
735 AppendToBuffer("%s", mnem); 797 AppendToBuffer("%s", mnem);
736 return 2;
737 } 798 }
738 AppendToBuffer("Unknown FP instruction");
739 return 2; 799 return 2;
740 } 800 }
741 801
742 802
743 // Mnemonics for instructions 0xF0 byte. 803 // Mnemonics for instructions 0xF0 byte.
744 // Returns NULL if the instruction is not handled here. 804 // Returns NULL if the instruction is not handled here.
745 static const char* F0Mnem(byte f0byte) { 805 static const char* F0Mnem(byte f0byte) {
746 switch (f0byte) { 806 switch (f0byte) {
747 case 0xA2: return "cpuid"; 807 case 0xA2: return "cpuid";
748 case 0x31: return "rdtsc"; 808 case 0x31: return "rdtsc";
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1287 }
1228 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 1288 for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
1229 fprintf(f, " "); 1289 fprintf(f, " ");
1230 } 1290 }
1231 fprintf(f, " %s\n", buffer.start()); 1291 fprintf(f, " %s\n", buffer.start());
1232 } 1292 }
1233 } 1293 }
1234 1294
1235 1295
1236 } // namespace disasm 1296 } // namespace disasm
OLDNEW
« no previous file with comments | « no previous file | src/x64/disasm-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698