| OLD | NEW |
| 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 117 |
| 118 | 118 |
| 119 static const char* set_conditional_mnem[] = { | 119 static const char* set_conditional_mnem[] = { |
| 120 /*0*/ "seto", "setno", "setc", "setnc", | 120 /*0*/ "seto", "setno", "setc", "setnc", |
| 121 /*4*/ "setz", "setnz", "setna", "seta", | 121 /*4*/ "setz", "setnz", "setna", "seta", |
| 122 /*8*/ "sets", "setns", "setpe", "setpo", | 122 /*8*/ "sets", "setns", "setpe", "setpo", |
| 123 /*12*/ "setl", "setnl", "setng", "setg" | 123 /*12*/ "setl", "setnl", "setng", "setg" |
| 124 }; | 124 }; |
| 125 | 125 |
| 126 | 126 |
| 127 static const char* conditional_move_mnem[] = { |
| 128 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", |
| 129 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", |
| 130 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", |
| 131 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" |
| 132 }; |
| 133 |
| 134 |
| 127 enum InstructionType { | 135 enum InstructionType { |
| 128 NO_INSTR, | 136 NO_INSTR, |
| 129 ZERO_OPERANDS_INSTR, | 137 ZERO_OPERANDS_INSTR, |
| 130 TWO_OPERANDS_INSTR, | 138 TWO_OPERANDS_INSTR, |
| 131 JUMP_CONDITIONAL_SHORT_INSTR, | 139 JUMP_CONDITIONAL_SHORT_INSTR, |
| 132 REGISTER_INSTR, | 140 REGISTER_INSTR, |
| 133 MOVE_REG_INSTR, | 141 MOVE_REG_INSTR, |
| 134 CALL_JUMP_INSTR, | 142 CALL_JUMP_INSTR, |
| 135 SHORT_IMMEDIATE_INSTR | 143 SHORT_IMMEDIATE_INSTR |
| 136 }; | 144 }; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 int PrintRightOperand(byte* modrmp); | 312 int PrintRightOperand(byte* modrmp); |
| 305 int PrintRightByteOperand(byte* modrmp); | 313 int PrintRightByteOperand(byte* modrmp); |
| 306 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); | 314 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); |
| 307 int PrintImmediateOp(byte* data); | 315 int PrintImmediateOp(byte* data); |
| 308 int F7Instruction(byte* data); | 316 int F7Instruction(byte* data); |
| 309 int D1D3C1Instruction(byte* data); | 317 int D1D3C1Instruction(byte* data); |
| 310 int JumpShort(byte* data); | 318 int JumpShort(byte* data); |
| 311 int JumpConditional(byte* data, const char* comment); | 319 int JumpConditional(byte* data, const char* comment); |
| 312 int JumpConditionalShort(byte* data, const char* comment); | 320 int JumpConditionalShort(byte* data, const char* comment); |
| 313 int SetCC(byte* data); | 321 int SetCC(byte* data); |
| 322 int CMov(byte* data); |
| 314 int FPUInstruction(byte* data); | 323 int FPUInstruction(byte* data); |
| 315 void AppendToBuffer(const char* format, ...); | 324 void AppendToBuffer(const char* format, ...); |
| 316 | 325 |
| 317 | 326 |
| 318 void UnimplementedInstruction() { | 327 void UnimplementedInstruction() { |
| 319 if (abort_on_unimplemented_) { | 328 if (abort_on_unimplemented_) { |
| 320 UNIMPLEMENTED(); | 329 UNIMPLEMENTED(); |
| 321 } else { | 330 } else { |
| 322 AppendToBuffer("'Unimplemented Instruction'"); | 331 AppendToBuffer("'Unimplemented Instruction'"); |
| 323 } | 332 } |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 assert(*data == 0x0F); | 617 assert(*data == 0x0F); |
| 609 byte cond = *(data+1) & 0x0F; | 618 byte cond = *(data+1) & 0x0F; |
| 610 const char* mnem = set_conditional_mnem[cond]; | 619 const char* mnem = set_conditional_mnem[cond]; |
| 611 AppendToBuffer("%s ", mnem); | 620 AppendToBuffer("%s ", mnem); |
| 612 PrintRightByteOperand(data+2); | 621 PrintRightByteOperand(data+2); |
| 613 return 3; // includes 0x0F | 622 return 3; // includes 0x0F |
| 614 } | 623 } |
| 615 | 624 |
| 616 | 625 |
| 617 // Returns number of bytes used, including *data. | 626 // Returns number of bytes used, including *data. |
| 627 int DisassemblerIA32::CMov(byte* data) { |
| 628 assert(*data == 0x0F); |
| 629 byte cond = *(data + 1) & 0x0F; |
| 630 const char* mnem = conditional_move_mnem[cond]; |
| 631 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); |
| 632 return 2 + op_size; // includes 0x0F |
| 633 } |
| 634 |
| 635 |
| 636 // Returns number of bytes used, including *data. |
| 618 int DisassemblerIA32::FPUInstruction(byte* data) { | 637 int DisassemblerIA32::FPUInstruction(byte* data) { |
| 619 byte b1 = *data; | 638 byte b1 = *data; |
| 620 byte b2 = *(data + 1); | 639 byte b2 = *(data + 1); |
| 621 if (b1 == 0xD9) { | 640 if (b1 == 0xD9) { |
| 622 const char* mnem = NULL; | 641 const char* mnem = NULL; |
| 623 switch (b2) { | 642 switch (b2) { |
| 624 case 0xE8: mnem = "fld1"; break; | 643 case 0xE8: mnem = "fld1"; break; |
| 625 case 0xEE: mnem = "fldz"; break; | 644 case 0xEE: mnem = "fldz"; break; |
| 626 case 0xE1: mnem = "fabs"; break; | 645 case 0xE1: mnem = "fabs"; break; |
| 627 case 0xE0: mnem = "fchs"; break; | 646 case 0xE0: mnem = "fchs"; break; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 AppendToBuffer("%s", f0mnem); | 873 AppendToBuffer("%s", f0mnem); |
| 855 data += 2; | 874 data += 2; |
| 856 } else if ((f0byte & 0xF0) == 0x80) { | 875 } else if ((f0byte & 0xF0) == 0x80) { |
| 857 data += JumpConditional(data, branch_hint); | 876 data += JumpConditional(data, branch_hint); |
| 858 } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || | 877 } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || |
| 859 f0byte == 0xB7 || f0byte == 0xAF) { | 878 f0byte == 0xB7 || f0byte == 0xAF) { |
| 860 data += 2; | 879 data += 2; |
| 861 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); | 880 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); |
| 862 } else if ((f0byte & 0xF0) == 0x90) { | 881 } else if ((f0byte & 0xF0) == 0x90) { |
| 863 data += SetCC(data); | 882 data += SetCC(data); |
| 883 } else if ((f0byte & 0xF0) == 0x40) { |
| 884 data += CMov(data); |
| 864 } else { | 885 } else { |
| 865 data += 2; | 886 data += 2; |
| 866 if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) { | 887 if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) { |
| 867 // shrd, shld, bts | 888 // shrd, shld, bts |
| 868 AppendToBuffer("%s ", f0mnem); | 889 AppendToBuffer("%s ", f0mnem); |
| 869 int mod, regop, rm; | 890 int mod, regop, rm; |
| 870 get_modrm(*data, &mod, ®op, &rm); | 891 get_modrm(*data, &mod, ®op, &rm); |
| 871 data += PrintRightOperand(data); | 892 data += PrintRightOperand(data); |
| 872 if (f0byte == 0xAB) { | 893 if (f0byte == 0xAB) { |
| 873 AppendToBuffer(",%s", NameOfCPURegister(regop)); | 894 AppendToBuffer(",%s", NameOfCPURegister(regop)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 if (*data == 0x8B) { | 970 if (*data == 0x8B) { |
| 950 data++; | 971 data++; |
| 951 data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); | 972 data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); |
| 952 } else if (*data == 0x89) { | 973 } else if (*data == 0x89) { |
| 953 data++; | 974 data++; |
| 954 int mod, regop, rm; | 975 int mod, regop, rm; |
| 955 get_modrm(*data, &mod, ®op, &rm); | 976 get_modrm(*data, &mod, ®op, &rm); |
| 956 AppendToBuffer("mov_w "); | 977 AppendToBuffer("mov_w "); |
| 957 data += PrintRightOperand(data); | 978 data += PrintRightOperand(data); |
| 958 AppendToBuffer(",%s", NameOfCPURegister(regop)); | 979 AppendToBuffer(",%s", NameOfCPURegister(regop)); |
| 980 } else if (*data == 0x0F) { |
| 981 data++; |
| 982 if ( *data == 0x2F) { |
| 983 data++; |
| 984 int mod, regop, rm; |
| 985 get_modrm(*data, &mod, ®op, &rm); |
| 986 AppendToBuffer("comisd %s,%s", |
| 987 NameOfXMMRegister(regop), |
| 988 NameOfXMMRegister(rm)); |
| 989 data++; |
| 990 } else { |
| 991 UnimplementedInstruction(); |
| 992 } |
| 959 } else { | 993 } else { |
| 960 UnimplementedInstruction(); | 994 UnimplementedInstruction(); |
| 961 } | 995 } |
| 962 break; | 996 break; |
| 963 | 997 |
| 964 case 0xFE: | 998 case 0xFE: |
| 965 { data++; | 999 { data++; |
| 966 int mod, regop, rm; | 1000 int mod, regop, rm; |
| 967 get_modrm(*data, &mod, ®op, &rm); | 1001 get_modrm(*data, &mod, ®op, &rm); |
| 968 if (mod == 3 && regop == ecx) { | 1002 if (mod == 3 && regop == ecx) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 } | 1227 } |
| 1194 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { | 1228 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { |
| 1195 fprintf(f, " "); | 1229 fprintf(f, " "); |
| 1196 } | 1230 } |
| 1197 fprintf(f, " %s\n", buffer.start()); | 1231 fprintf(f, " %s\n", buffer.start()); |
| 1198 } | 1232 } |
| 1199 } | 1233 } |
| 1200 | 1234 |
| 1201 | 1235 |
| 1202 } // namespace disasm | 1236 } // namespace disasm |
| OLD | NEW |