OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 { 0xC9, UNSET_OP_ORDER, "leave" }, | 107 { 0xC9, UNSET_OP_ORDER, "leave" }, |
108 { 0xF4, UNSET_OP_ORDER, "hlt" }, | 108 { 0xF4, UNSET_OP_ORDER, "hlt" }, |
109 { 0xCC, UNSET_OP_ORDER, "int3" }, | 109 { 0xCC, UNSET_OP_ORDER, "int3" }, |
110 { 0x60, UNSET_OP_ORDER, "pushad" }, | 110 { 0x60, UNSET_OP_ORDER, "pushad" }, |
111 { 0x61, UNSET_OP_ORDER, "popad" }, | 111 { 0x61, UNSET_OP_ORDER, "popad" }, |
112 { 0x9C, UNSET_OP_ORDER, "pushfd" }, | 112 { 0x9C, UNSET_OP_ORDER, "pushfd" }, |
113 { 0x9D, UNSET_OP_ORDER, "popfd" }, | 113 { 0x9D, UNSET_OP_ORDER, "popfd" }, |
114 { 0x9E, UNSET_OP_ORDER, "sahf" }, | 114 { 0x9E, UNSET_OP_ORDER, "sahf" }, |
115 { 0x99, UNSET_OP_ORDER, "cdq" }, | 115 { 0x99, UNSET_OP_ORDER, "cdq" }, |
116 { 0x9B, UNSET_OP_ORDER, "fwait" }, | 116 { 0x9B, UNSET_OP_ORDER, "fwait" }, |
| 117 { 0xA4, UNSET_OP_ORDER, "movs" }, |
| 118 { 0xA5, UNSET_OP_ORDER, "movs" }, |
| 119 { 0xA6, UNSET_OP_ORDER, "cmps" }, |
| 120 { 0xA7, UNSET_OP_ORDER, "cmps" }, |
117 { -1, UNSET_OP_ORDER, "" } | 121 { -1, UNSET_OP_ORDER, "" } |
118 }; | 122 }; |
119 | 123 |
120 | 124 |
121 static ByteMnemonic call_jump_instr[] = { | 125 static ByteMnemonic call_jump_instr[] = { |
122 { 0xE8, UNSET_OP_ORDER, "call" }, | 126 { 0xE8, UNSET_OP_ORDER, "call" }, |
123 { 0xE9, UNSET_OP_ORDER, "jmp" }, | 127 { 0xE9, UNSET_OP_ORDER, "jmp" }, |
124 { -1, UNSET_OP_ORDER, "" } | 128 { -1, UNSET_OP_ORDER, "" } |
125 }; | 129 }; |
126 | 130 |
(...skipping 23 matching lines...) Expand all Loading... |
150 TWO_OPERANDS_INSTR, | 154 TWO_OPERANDS_INSTR, |
151 JUMP_CONDITIONAL_SHORT_INSTR, | 155 JUMP_CONDITIONAL_SHORT_INSTR, |
152 REGISTER_INSTR, | 156 REGISTER_INSTR, |
153 PUSHPOP_INSTR, // Has implicit 64-bit operand size. | 157 PUSHPOP_INSTR, // Has implicit 64-bit operand size. |
154 MOVE_REG_INSTR, | 158 MOVE_REG_INSTR, |
155 CALL_JUMP_INSTR, | 159 CALL_JUMP_INSTR, |
156 SHORT_IMMEDIATE_INSTR | 160 SHORT_IMMEDIATE_INSTR |
157 }; | 161 }; |
158 | 162 |
159 | 163 |
| 164 enum Prefixes { |
| 165 ESCAPE_PREFIX = 0x0F, |
| 166 OPERAND_SIZE_OVERRIDE_PREFIX = 0x66, |
| 167 ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67, |
| 168 REPNE_PREFIX = 0xF2, |
| 169 REP_PREFIX = 0xF3, |
| 170 REPEQ_PREFIX = REP_PREFIX |
| 171 }; |
| 172 |
| 173 |
160 struct InstructionDesc { | 174 struct InstructionDesc { |
161 const char* mnem; | 175 const char* mnem; |
162 InstructionType type; | 176 InstructionType type; |
163 OperandType op_order_; | 177 OperandType op_order_; |
164 bool byte_size_operation; // Fixed 8-bit operation. | 178 bool byte_size_operation; // Fixed 8-bit operation. |
165 }; | 179 }; |
166 | 180 |
167 | 181 |
168 class InstructionTable { | 182 class InstructionTable { |
169 public: | 183 public: |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 byte* instr) { | 1135 byte* instr) { |
1122 tmp_buffer_pos_ = 0; // starting to write as position 0 | 1136 tmp_buffer_pos_ = 0; // starting to write as position 0 |
1123 byte* data = instr; | 1137 byte* data = instr; |
1124 bool processed = true; // Will be set to false if the current instruction | 1138 bool processed = true; // Will be set to false if the current instruction |
1125 // is not in 'instructions' table. | 1139 // is not in 'instructions' table. |
1126 byte current; | 1140 byte current; |
1127 | 1141 |
1128 // Scan for prefixes. | 1142 // Scan for prefixes. |
1129 while (true) { | 1143 while (true) { |
1130 current = *data; | 1144 current = *data; |
1131 if (current == 0x66) { // Group 3 prefix. | 1145 if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix. |
1132 operand_size_ = current; | 1146 operand_size_ = current; |
1133 } else if ((current & 0xF0) == 0x40) { // REX prefix. | 1147 } else if ((current & 0xF0) == 0x40) { // REX prefix. |
1134 setRex(current); | 1148 setRex(current); |
1135 if (rex_w()) AppendToBuffer("REX.W "); | 1149 if (rex_w()) AppendToBuffer("REX.W "); |
1136 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix. | 1150 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3). |
1137 group_1_prefix_ = current; | 1151 group_1_prefix_ = current; |
1138 } else { // Not a prefix - an opcode. | 1152 } else { // Not a prefix - an opcode. |
1139 break; | 1153 break; |
1140 } | 1154 } |
1141 data++; | 1155 data++; |
1142 } | 1156 } |
1143 | 1157 |
1144 const InstructionDesc& idesc = instruction_table.Get(current); | 1158 const InstructionDesc& idesc = instruction_table.Get(current); |
1145 byte_size_operand_ = idesc.byte_size_operation; | 1159 byte_size_operand_ = idesc.byte_size_operation; |
1146 switch (idesc.type) { | 1160 switch (idesc.type) { |
1147 case ZERO_OPERANDS_INSTR: | 1161 case ZERO_OPERANDS_INSTR: |
1148 AppendToBuffer(idesc.mnem); | 1162 if (current >= 0xA4 && current <= 0xA7) { |
| 1163 // String move or compare operations. |
| 1164 if (group_1_prefix_ == REP_PREFIX) { |
| 1165 // REP. |
| 1166 AppendToBuffer("rep "); |
| 1167 } |
| 1168 if (rex_w()) AppendToBuffer("REX.W "); |
| 1169 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); |
| 1170 } else { |
| 1171 AppendToBuffer("%s", idesc.mnem, operand_size_code()); |
| 1172 } |
1149 data++; | 1173 data++; |
1150 break; | 1174 break; |
1151 | 1175 |
1152 case TWO_OPERANDS_INSTR: | 1176 case TWO_OPERANDS_INSTR: |
1153 data++; | 1177 data++; |
1154 data += PrintOperands(idesc.mnem, idesc.op_order_, data); | 1178 data += PrintOperands(idesc.mnem, idesc.op_order_, data); |
1155 break; | 1179 break; |
1156 | 1180 |
1157 case JUMP_CONDITIONAL_SHORT_INSTR: | 1181 case JUMP_CONDITIONAL_SHORT_INSTR: |
1158 data += JumpConditionalShort(data); | 1182 data += JumpConditionalShort(data); |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1587 fprintf(f, "%02x", *bp); | 1611 fprintf(f, "%02x", *bp); |
1588 } | 1612 } |
1589 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 1613 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
1590 fprintf(f, " "); | 1614 fprintf(f, " "); |
1591 } | 1615 } |
1592 fprintf(f, " %s\n", buffer.start()); | 1616 fprintf(f, " %s\n", buffer.start()); |
1593 } | 1617 } |
1594 } | 1618 } |
1595 | 1619 |
1596 } // namespace disasm | 1620 } // namespace disasm |
OLD | NEW |