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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 | 110 |
111 | 111 |
112 static const char* jump_conditional_mnem[] = { | 112 static const char* jump_conditional_mnem[] = { |
113 /*0*/ "jo", "jno", "jc", "jnc", | 113 /*0*/ "jo", "jno", "jc", "jnc", |
114 /*4*/ "jz", "jnz", "jna", "ja", | 114 /*4*/ "jz", "jnz", "jna", "ja", |
115 /*8*/ "js", "jns", "jpe", "jpo", | 115 /*8*/ "js", "jns", "jpe", "jpo", |
116 /*12*/ "jl", "jnl", "jng", "jg" | 116 /*12*/ "jl", "jnl", "jng", "jg" |
117 }; | 117 }; |
118 | 118 |
119 | 119 |
120 static const char* loop_mnem[] = { | |
121 "loopne", "loope", "loop" | |
122 }; | |
123 | |
124 | |
125 static const char* set_conditional_mnem[] = { | 120 static const char* set_conditional_mnem[] = { |
126 /*0*/ "seto", "setno", "setc", "setnc", | 121 /*0*/ "seto", "setno", "setc", "setnc", |
127 /*4*/ "setz", "setnz", "setna", "seta", | 122 /*4*/ "setz", "setnz", "setna", "seta", |
128 /*8*/ "sets", "setns", "setpe", "setpo", | 123 /*8*/ "sets", "setns", "setpe", "setpo", |
129 /*12*/ "setl", "setnl", "setng", "setg" | 124 /*12*/ "setl", "setnl", "setng", "setg" |
130 }; | 125 }; |
131 | 126 |
132 | 127 |
133 static const char* conditional_move_mnem[] = { | 128 static const char* conditional_move_mnem[] = { |
134 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", | 129 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", |
135 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", | 130 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", |
136 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", | 131 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", |
137 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" | 132 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" |
138 }; | 133 }; |
139 | 134 |
140 | 135 |
141 enum InstructionType { | 136 enum InstructionType { |
142 NO_INSTR, | 137 NO_INSTR, |
143 ZERO_OPERANDS_INSTR, | 138 ZERO_OPERANDS_INSTR, |
144 TWO_OPERANDS_INSTR, | 139 TWO_OPERANDS_INSTR, |
145 JUMP_CONDITIONAL_SHORT_INSTR, | 140 JUMP_CONDITIONAL_SHORT_INSTR, |
146 LOOP_INSTR, | |
147 REGISTER_INSTR, | 141 REGISTER_INSTR, |
148 MOVE_REG_INSTR, | 142 MOVE_REG_INSTR, |
149 CALL_JUMP_INSTR, | 143 CALL_JUMP_INSTR, |
150 SHORT_IMMEDIATE_INSTR | 144 SHORT_IMMEDIATE_INSTR |
151 }; | 145 }; |
152 | 146 |
153 | 147 |
154 struct InstructionDesc { | 148 struct InstructionDesc { |
155 const char* mnem; | 149 const char* mnem; |
156 InstructionType type; | 150 InstructionType type; |
157 OperandOrder op_order_; | 151 OperandOrder op_order_; |
158 }; | 152 }; |
159 | 153 |
160 | 154 |
161 class InstructionTable { | 155 class InstructionTable { |
162 public: | 156 public: |
163 InstructionTable(); | 157 InstructionTable(); |
164 const InstructionDesc& Get(byte x) const { return instructions_[x]; } | 158 const InstructionDesc& Get(byte x) const { return instructions_[x]; } |
165 | 159 |
166 private: | 160 private: |
167 InstructionDesc instructions_[256]; | 161 InstructionDesc instructions_[256]; |
168 void Clear(); | 162 void Clear(); |
169 void Init(); | 163 void Init(); |
170 void CopyTable(ByteMnemonic bm[], InstructionType type); | 164 void CopyTable(ByteMnemonic bm[], InstructionType type); |
171 void SetTableRange(InstructionType type, | 165 void SetTableRange(InstructionType type, |
172 byte start, | 166 byte start, |
173 byte end, | 167 byte end, |
174 const char* mnem); | 168 const char* mnem); |
175 void AddJumpConditionalShort(); | 169 void AddJumpConditionalShort(); |
176 void AddLoop(); | |
177 }; | 170 }; |
178 | 171 |
179 | 172 |
180 InstructionTable::InstructionTable() { | 173 InstructionTable::InstructionTable() { |
181 Clear(); | 174 Clear(); |
182 Init(); | 175 Init(); |
183 } | 176 } |
184 | 177 |
185 | 178 |
186 void InstructionTable::Clear() { | 179 void InstructionTable::Clear() { |
187 for (int i = 0; i < 256; i++) { | 180 for (int i = 0; i < 256; i++) { |
188 instructions_[i].mnem = ""; | 181 instructions_[i].mnem = ""; |
189 instructions_[i].type = NO_INSTR; | 182 instructions_[i].type = NO_INSTR; |
190 instructions_[i].op_order_ = UNSET_OP_ORDER; | 183 instructions_[i].op_order_ = UNSET_OP_ORDER; |
191 } | 184 } |
192 } | 185 } |
193 | 186 |
194 | 187 |
195 void InstructionTable::Init() { | 188 void InstructionTable::Init() { |
196 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); | 189 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); |
197 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); | 190 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); |
198 CopyTable(call_jump_instr, CALL_JUMP_INSTR); | 191 CopyTable(call_jump_instr, CALL_JUMP_INSTR); |
199 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); | 192 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); |
200 AddJumpConditionalShort(); | 193 AddJumpConditionalShort(); |
201 AddLoop(); | |
202 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); | 194 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); |
203 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); | 195 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); |
204 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); | 196 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); |
205 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); | 197 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); |
206 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. | 198 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. |
207 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); | 199 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); |
208 } | 200 } |
209 | 201 |
210 | 202 |
211 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) { | 203 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) { |
(...skipping 23 matching lines...) Expand all Loading... |
235 void InstructionTable::AddJumpConditionalShort() { | 227 void InstructionTable::AddJumpConditionalShort() { |
236 for (byte b = 0x70; b <= 0x7F; b++) { | 228 for (byte b = 0x70; b <= 0x7F; b++) { |
237 InstructionDesc* id = &instructions_[b]; | 229 InstructionDesc* id = &instructions_[b]; |
238 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. | 230 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. |
239 id->mnem = jump_conditional_mnem[b & 0x0F]; | 231 id->mnem = jump_conditional_mnem[b & 0x0F]; |
240 id->type = JUMP_CONDITIONAL_SHORT_INSTR; | 232 id->type = JUMP_CONDITIONAL_SHORT_INSTR; |
241 } | 233 } |
242 } | 234 } |
243 | 235 |
244 | 236 |
245 void InstructionTable::AddLoop() { | |
246 for (byte b = 0xE0; b <= 0xE2; b++) { | |
247 InstructionDesc* id = &instructions_[b]; | |
248 ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. | |
249 id->mnem = loop_mnem[b & 0x03]; | |
250 id->type = LOOP_INSTR; | |
251 } | |
252 } | |
253 | |
254 | |
255 static InstructionTable instruction_table; | 237 static InstructionTable instruction_table; |
256 | 238 |
257 | 239 |
258 // The IA32 disassembler implementation. | 240 // The IA32 disassembler implementation. |
259 class DisassemblerIA32 { | 241 class DisassemblerIA32 { |
260 public: | 242 public: |
261 DisassemblerIA32(const NameConverter& converter, | 243 DisassemblerIA32(const NameConverter& converter, |
262 bool abort_on_unimplemented = true) | 244 bool abort_on_unimplemented = true) |
263 : converter_(converter), | 245 : converter_(converter), |
264 tmp_buffer_pos_(0), | 246 tmp_buffer_pos_(0), |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); | 323 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); |
342 int PrintRightOperand(byte* modrmp); | 324 int PrintRightOperand(byte* modrmp); |
343 int PrintRightByteOperand(byte* modrmp); | 325 int PrintRightByteOperand(byte* modrmp); |
344 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); | 326 int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); |
345 int PrintImmediateOp(byte* data); | 327 int PrintImmediateOp(byte* data); |
346 int F7Instruction(byte* data); | 328 int F7Instruction(byte* data); |
347 int D1D3C1Instruction(byte* data); | 329 int D1D3C1Instruction(byte* data); |
348 int JumpShort(byte* data); | 330 int JumpShort(byte* data); |
349 int JumpConditional(byte* data, const char* comment); | 331 int JumpConditional(byte* data, const char* comment); |
350 int JumpConditionalShort(byte* data, const char* comment); | 332 int JumpConditionalShort(byte* data, const char* comment); |
351 int Loop(byte* data); | |
352 int SetCC(byte* data); | 333 int SetCC(byte* data); |
353 int CMov(byte* data); | 334 int CMov(byte* data); |
354 int FPUInstruction(byte* data); | 335 int FPUInstruction(byte* data); |
355 int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); | 336 int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); |
356 int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); | 337 int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); |
357 void AppendToBuffer(const char* format, ...); | 338 void AppendToBuffer(const char* format, ...); |
358 | 339 |
359 | 340 |
360 void UnimplementedInstruction() { | 341 void UnimplementedInstruction() { |
361 if (abort_on_unimplemented_) { | 342 if (abort_on_unimplemented_) { |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 const char* mnem = jump_conditional_mnem[cond]; | 611 const char* mnem = jump_conditional_mnem[cond]; |
631 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | 612 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); |
632 if (comment != NULL) { | 613 if (comment != NULL) { |
633 AppendToBuffer(", %s", comment); | 614 AppendToBuffer(", %s", comment); |
634 } | 615 } |
635 return 2; | 616 return 2; |
636 } | 617 } |
637 | 618 |
638 | 619 |
639 // Returns number of bytes used, including *data. | 620 // Returns number of bytes used, including *data. |
640 int DisassemblerIA32::Loop(byte* data) { | |
641 byte cond = *data & 0x03; | |
642 byte b = *(data+1); | |
643 byte* dest = data + static_cast<int8_t>(b) + 2; | |
644 const char* mnem = loop_mnem[cond]; | |
645 AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | |
646 return 2; | |
647 } | |
648 | |
649 | |
650 // Returns number of bytes used, including *data. | |
651 int DisassemblerIA32::SetCC(byte* data) { | 621 int DisassemblerIA32::SetCC(byte* data) { |
652 ASSERT_EQ(0x0F, *data); | 622 ASSERT_EQ(0x0F, *data); |
653 byte cond = *(data+1) & 0x0F; | 623 byte cond = *(data+1) & 0x0F; |
654 const char* mnem = set_conditional_mnem[cond]; | 624 const char* mnem = set_conditional_mnem[cond]; |
655 AppendToBuffer("%s ", mnem); | 625 AppendToBuffer("%s ", mnem); |
656 PrintRightByteOperand(data+2); | 626 PrintRightByteOperand(data+2); |
657 return 3; // Includes 0x0F. | 627 return 3; // Includes 0x0F. |
658 } | 628 } |
659 | 629 |
660 | 630 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 | 848 |
879 case TWO_OPERANDS_INSTR: | 849 case TWO_OPERANDS_INSTR: |
880 data++; | 850 data++; |
881 data += PrintOperands(idesc.mnem, idesc.op_order_, data); | 851 data += PrintOperands(idesc.mnem, idesc.op_order_, data); |
882 break; | 852 break; |
883 | 853 |
884 case JUMP_CONDITIONAL_SHORT_INSTR: | 854 case JUMP_CONDITIONAL_SHORT_INSTR: |
885 data += JumpConditionalShort(data, branch_hint); | 855 data += JumpConditionalShort(data, branch_hint); |
886 break; | 856 break; |
887 | 857 |
888 case LOOP_INSTR: | |
889 data += Loop(data); | |
890 break; | |
891 | |
892 case REGISTER_INSTR: | 858 case REGISTER_INSTR: |
893 AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); | 859 AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); |
894 data++; | 860 data++; |
895 break; | 861 break; |
896 | 862 |
897 case MOVE_REG_INSTR: { | 863 case MOVE_REG_INSTR: { |
898 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); | 864 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); |
899 AppendToBuffer("mov %s,%s", | 865 AppendToBuffer("mov %s,%s", |
900 NameOfCPURegister(*data & 0x07), | 866 NameOfCPURegister(*data & 0x07), |
901 NameOfAddress(addr)); | 867 NameOfAddress(addr)); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 AppendToBuffer("%s ", is_byte ? "mov_b" : "mov"); | 1001 AppendToBuffer("%s ", is_byte ? "mov_b" : "mov"); |
1036 data += PrintRightOperand(data); | 1002 data += PrintRightOperand(data); |
1037 int32_t imm = is_byte ? *data : *reinterpret_cast<int32_t*>(data); | 1003 int32_t imm = is_byte ? *data : *reinterpret_cast<int32_t*>(data); |
1038 AppendToBuffer(",0x%x", imm); | 1004 AppendToBuffer(",0x%x", imm); |
1039 data += is_byte ? 1 : 4; | 1005 data += is_byte ? 1 : 4; |
1040 } | 1006 } |
1041 break; | 1007 break; |
1042 | 1008 |
1043 case 0x80: | 1009 case 0x80: |
1044 { data++; | 1010 { data++; |
1045 AppendToBuffer("%s ", "cmpb"); | 1011 int mod, regop, rm; |
| 1012 get_modrm(*data, &mod, ®op, &rm); |
| 1013 const char* mnem = NULL; |
| 1014 printf("%d\n", regop); |
| 1015 switch (regop) { |
| 1016 case 5: mnem = "subb"; break; |
| 1017 case 7: mnem = "cmpb"; break; |
| 1018 default: UnimplementedInstruction(); |
| 1019 } |
| 1020 AppendToBuffer("%s ", mnem); |
1046 data += PrintRightOperand(data); | 1021 data += PrintRightOperand(data); |
1047 int32_t imm = *data; | 1022 int32_t imm = *data; |
1048 AppendToBuffer(",0x%x", imm); | 1023 AppendToBuffer(",0x%x", imm); |
1049 data++; | 1024 data++; |
1050 } | 1025 } |
1051 break; | 1026 break; |
1052 | 1027 |
1053 case 0x88: // 8bit, fall through | 1028 case 0x88: // 8bit, fall through |
1054 case 0x89: // 32bit | 1029 case 0x89: // 32bit |
1055 { bool is_byte = *data == 0x88; | 1030 { bool is_byte = *data == 0x88; |
(...skipping 29 matching lines...) Expand all Loading... |
1085 NameOfXMMRegister(rm)); | 1060 NameOfXMMRegister(rm)); |
1086 data++; | 1061 data++; |
1087 } else if (*data == 0x57) { | 1062 } else if (*data == 0x57) { |
1088 data++; | 1063 data++; |
1089 int mod, regop, rm; | 1064 int mod, regop, rm; |
1090 get_modrm(*data, &mod, ®op, &rm); | 1065 get_modrm(*data, &mod, ®op, &rm); |
1091 AppendToBuffer("xorpd %s,%s", | 1066 AppendToBuffer("xorpd %s,%s", |
1092 NameOfXMMRegister(regop), | 1067 NameOfXMMRegister(regop), |
1093 NameOfXMMRegister(rm)); | 1068 NameOfXMMRegister(rm)); |
1094 data++; | 1069 data++; |
| 1070 } else if (*data == 0x6F) { |
| 1071 data++; |
| 1072 int mod, regop, rm; |
| 1073 get_modrm(*data, &mod, ®op, &rm); |
| 1074 AppendToBuffer("movdqa %s,", NameOfXMMRegister(regop)); |
| 1075 data += PrintRightOperand(data); |
| 1076 } else if (*data == 0x7F) { |
| 1077 AppendToBuffer("movdqa "); |
| 1078 data++; |
| 1079 int mod, regop, rm; |
| 1080 get_modrm(*data, &mod, ®op, &rm); |
| 1081 data += PrintRightOperand(data); |
| 1082 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1095 } else { | 1083 } else { |
1096 UnimplementedInstruction(); | 1084 UnimplementedInstruction(); |
1097 } | 1085 } |
1098 } else { | 1086 } else { |
1099 UnimplementedInstruction(); | 1087 UnimplementedInstruction(); |
1100 } | 1088 } |
1101 break; | 1089 break; |
1102 | 1090 |
1103 case 0xFE: | 1091 case 0xFE: |
1104 { data++; | 1092 { data++; |
(...skipping 16 matching lines...) Expand all Loading... |
1121 case 0x6A: | 1109 case 0x6A: |
1122 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); | 1110 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); |
1123 data += 2; | 1111 data += 2; |
1124 break; | 1112 break; |
1125 | 1113 |
1126 case 0xA8: | 1114 case 0xA8: |
1127 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); | 1115 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); |
1128 data += 2; | 1116 data += 2; |
1129 break; | 1117 break; |
1130 | 1118 |
| 1119 case 0x2C: |
| 1120 AppendToBuffer("subb eax,0x%x", *reinterpret_cast<uint8_t*>(data+1)); |
| 1121 data += 2; |
| 1122 break; |
| 1123 |
1131 case 0xA9: | 1124 case 0xA9: |
1132 AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); | 1125 AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); |
1133 data += 5; | 1126 data += 5; |
1134 break; | 1127 break; |
1135 | 1128 |
1136 case 0xD1: // fall through | 1129 case 0xD1: // fall through |
1137 case 0xD3: // fall through | 1130 case 0xD3: // fall through |
1138 case 0xC1: | 1131 case 0xC1: |
1139 data += D1D3C1Instruction(data); | 1132 data += D1D3C1Instruction(data); |
1140 break; | 1133 break; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 NameOfXMMRegister(rm)); | 1184 NameOfXMMRegister(rm)); |
1192 data++; | 1185 data++; |
1193 } | 1186 } |
1194 } | 1187 } |
1195 } else { | 1188 } else { |
1196 UnimplementedInstruction(); | 1189 UnimplementedInstruction(); |
1197 } | 1190 } |
1198 break; | 1191 break; |
1199 | 1192 |
1200 case 0xF3: | 1193 case 0xF3: |
1201 if (*(data+1) == 0x0F && *(data+2) == 0x2C) { | 1194 if (*(data+1) == 0x0F) { |
1202 data += 3; | 1195 if (*(data+2) == 0x2C) { |
1203 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); | 1196 data += 3; |
| 1197 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); |
| 1198 } else if (*(data+2) == 0x6F) { |
| 1199 data += 3; |
| 1200 int mod, regop, rm; |
| 1201 get_modrm(*data, &mod, ®op, &rm); |
| 1202 AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop)); |
| 1203 data += PrintRightOperand(data); |
| 1204 } else if (*(data+2) == 0x7F) { |
| 1205 AppendToBuffer("movdqu "); |
| 1206 data += 3; |
| 1207 int mod, regop, rm; |
| 1208 get_modrm(*data, &mod, ®op, &rm); |
| 1209 data += PrintRightOperand(data); |
| 1210 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
| 1211 } else { |
| 1212 UnimplementedInstruction(); |
| 1213 } |
| 1214 } else if (*(data+1) == 0xA5) { |
| 1215 data += 2; |
| 1216 AppendToBuffer("rep_movs"); |
1204 } else { | 1217 } else { |
1205 UnimplementedInstruction(); | 1218 UnimplementedInstruction(); |
1206 } | 1219 } |
1207 break; | 1220 break; |
1208 | 1221 |
1209 case 0xF7: | 1222 case 0xF7: |
1210 data += F7Instruction(data); | 1223 data += F7Instruction(data); |
1211 break; | 1224 break; |
1212 | 1225 |
1213 default: | 1226 default: |
1214 UnimplementedInstruction(); | 1227 UnimplementedInstruction(); |
1215 } | 1228 } |
1216 } | 1229 } |
1217 | 1230 |
1218 if (tmp_buffer_pos_ < sizeof tmp_buffer_) { | 1231 if (tmp_buffer_pos_ < sizeof tmp_buffer_) { |
1219 tmp_buffer_[tmp_buffer_pos_] = '\0'; | 1232 tmp_buffer_[tmp_buffer_pos_] = '\0'; |
1220 } | 1233 } |
1221 | 1234 |
1222 int instr_len = data - instr; | 1235 int instr_len = data - instr; |
| 1236 if (instr_len == 0) { |
| 1237 printf("%02x", *data); |
| 1238 } |
1223 ASSERT(instr_len > 0); // Ensure progress. | 1239 ASSERT(instr_len > 0); // Ensure progress. |
1224 | 1240 |
1225 int outp = 0; | 1241 int outp = 0; |
1226 // Instruction bytes. | 1242 // Instruction bytes. |
1227 for (byte* bp = instr; bp < data; bp++) { | 1243 for (byte* bp = instr; bp < data; bp++) { |
1228 outp += v8::internal::OS::SNPrintF(out_buffer + outp, | 1244 outp += v8::internal::OS::SNPrintF(out_buffer + outp, |
1229 "%02x", | 1245 "%02x", |
1230 *bp); | 1246 *bp); |
1231 } | 1247 } |
1232 for (int i = 6 - instr_len; i >= 0; i--) { | 1248 for (int i = 6 - instr_len; i >= 0; i--) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1348 } |
1333 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { | 1349 for (int i = 6 - (pc - prev_pc); i >= 0; i--) { |
1334 fprintf(f, " "); | 1350 fprintf(f, " "); |
1335 } | 1351 } |
1336 fprintf(f, " %s\n", buffer.start()); | 1352 fprintf(f, " %s\n", buffer.start()); |
1337 } | 1353 } |
1338 } | 1354 } |
1339 | 1355 |
1340 | 1356 |
1341 } // namespace disasm | 1357 } // namespace disasm |
OLD | NEW |