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 |