OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 // Tables | 48 // Tables |
49 //------------------------------------------------------------------ | 49 //------------------------------------------------------------------ |
50 struct ByteMnemonic { | 50 struct ByteMnemonic { |
51 int b; // -1 terminates, otherwise must be in range (0..255) | 51 int b; // -1 terminates, otherwise must be in range (0..255) |
52 const char* mnem; | 52 const char* mnem; |
53 OperandOrder op_order_; | 53 OperandOrder op_order_; |
54 }; | 54 }; |
55 | 55 |
56 | 56 |
57 static const ByteMnemonic two_operands_instr[] = { | 57 static const ByteMnemonic two_operands_instr[] = { |
| 58 {0x01, "add", OPER_REG_OP_ORDER}, |
58 {0x03, "add", REG_OPER_OP_ORDER}, | 59 {0x03, "add", REG_OPER_OP_ORDER}, |
59 {0x09, "or", OPER_REG_OP_ORDER}, | 60 {0x09, "or", OPER_REG_OP_ORDER}, |
60 {0x0B, "or", REG_OPER_OP_ORDER}, | 61 {0x0B, "or", REG_OPER_OP_ORDER}, |
61 {0x1B, "sbb", REG_OPER_OP_ORDER}, | 62 {0x1B, "sbb", REG_OPER_OP_ORDER}, |
62 {0x21, "and", OPER_REG_OP_ORDER}, | 63 {0x21, "and", OPER_REG_OP_ORDER}, |
63 {0x23, "and", REG_OPER_OP_ORDER}, | 64 {0x23, "and", REG_OPER_OP_ORDER}, |
64 {0x29, "sub", OPER_REG_OP_ORDER}, | 65 {0x29, "sub", OPER_REG_OP_ORDER}, |
65 {0x2A, "subb", REG_OPER_OP_ORDER}, | 66 {0x2A, "subb", REG_OPER_OP_ORDER}, |
66 {0x2B, "sub", REG_OPER_OP_ORDER}, | 67 {0x2B, "sub", REG_OPER_OP_ORDER}, |
67 {0x31, "xor", OPER_REG_OP_ORDER}, | 68 {0x31, "xor", OPER_REG_OP_ORDER}, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 {0x0D, "or", UNSET_OP_ORDER}, | 111 {0x0D, "or", UNSET_OP_ORDER}, |
111 {0x15, "adc", UNSET_OP_ORDER}, | 112 {0x15, "adc", UNSET_OP_ORDER}, |
112 {0x25, "and", UNSET_OP_ORDER}, | 113 {0x25, "and", UNSET_OP_ORDER}, |
113 {0x2D, "sub", UNSET_OP_ORDER}, | 114 {0x2D, "sub", UNSET_OP_ORDER}, |
114 {0x35, "xor", UNSET_OP_ORDER}, | 115 {0x35, "xor", UNSET_OP_ORDER}, |
115 {0x3D, "cmp", UNSET_OP_ORDER}, | 116 {0x3D, "cmp", UNSET_OP_ORDER}, |
116 {-1, "", UNSET_OP_ORDER} | 117 {-1, "", UNSET_OP_ORDER} |
117 }; | 118 }; |
118 | 119 |
119 | 120 |
| 121 // Generally we don't want to generate these because they are subject to partial |
| 122 // register stalls. They are included for completeness and because the cmp |
| 123 // variant is used by the RecordWrite stub. Because it does not update the |
| 124 // register it is not subject to partial register stalls. |
| 125 static ByteMnemonic byte_immediate_instr[] = { |
| 126 {0x0c, "or", UNSET_OP_ORDER}, |
| 127 {0x24, "and", UNSET_OP_ORDER}, |
| 128 {0x34, "xor", UNSET_OP_ORDER}, |
| 129 {0x3c, "cmp", UNSET_OP_ORDER}, |
| 130 {-1, "", UNSET_OP_ORDER} |
| 131 }; |
| 132 |
| 133 |
120 static const char* const jump_conditional_mnem[] = { | 134 static const char* const jump_conditional_mnem[] = { |
121 /*0*/ "jo", "jno", "jc", "jnc", | 135 /*0*/ "jo", "jno", "jc", "jnc", |
122 /*4*/ "jz", "jnz", "jna", "ja", | 136 /*4*/ "jz", "jnz", "jna", "ja", |
123 /*8*/ "js", "jns", "jpe", "jpo", | 137 /*8*/ "js", "jns", "jpe", "jpo", |
124 /*12*/ "jl", "jnl", "jng", "jg" | 138 /*12*/ "jl", "jnl", "jng", "jg" |
125 }; | 139 }; |
126 | 140 |
127 | 141 |
128 static const char* const set_conditional_mnem[] = { | 142 static const char* const set_conditional_mnem[] = { |
129 /*0*/ "seto", "setno", "setc", "setnc", | 143 /*0*/ "seto", "setno", "setc", "setnc", |
(...skipping 12 matching lines...) Expand all Loading... |
142 | 156 |
143 | 157 |
144 enum InstructionType { | 158 enum InstructionType { |
145 NO_INSTR, | 159 NO_INSTR, |
146 ZERO_OPERANDS_INSTR, | 160 ZERO_OPERANDS_INSTR, |
147 TWO_OPERANDS_INSTR, | 161 TWO_OPERANDS_INSTR, |
148 JUMP_CONDITIONAL_SHORT_INSTR, | 162 JUMP_CONDITIONAL_SHORT_INSTR, |
149 REGISTER_INSTR, | 163 REGISTER_INSTR, |
150 MOVE_REG_INSTR, | 164 MOVE_REG_INSTR, |
151 CALL_JUMP_INSTR, | 165 CALL_JUMP_INSTR, |
152 SHORT_IMMEDIATE_INSTR | 166 SHORT_IMMEDIATE_INSTR, |
| 167 BYTE_IMMEDIATE_INSTR |
153 }; | 168 }; |
154 | 169 |
155 | 170 |
156 struct InstructionDesc { | 171 struct InstructionDesc { |
157 const char* mnem; | 172 const char* mnem; |
158 InstructionType type; | 173 InstructionType type; |
159 OperandOrder op_order_; | 174 OperandOrder op_order_; |
160 }; | 175 }; |
161 | 176 |
162 | 177 |
(...skipping 28 matching lines...) Expand all Loading... |
191 instructions_[i].op_order_ = UNSET_OP_ORDER; | 206 instructions_[i].op_order_ = UNSET_OP_ORDER; |
192 } | 207 } |
193 } | 208 } |
194 | 209 |
195 | 210 |
196 void InstructionTable::Init() { | 211 void InstructionTable::Init() { |
197 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); | 212 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); |
198 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); | 213 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); |
199 CopyTable(call_jump_instr, CALL_JUMP_INSTR); | 214 CopyTable(call_jump_instr, CALL_JUMP_INSTR); |
200 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); | 215 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); |
| 216 CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR); |
201 AddJumpConditionalShort(); | 217 AddJumpConditionalShort(); |
202 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); | 218 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); |
203 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); | 219 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); |
204 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); | 220 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); |
205 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); | 221 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); |
206 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. | 222 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. |
207 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); | 223 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); |
208 } | 224 } |
209 | 225 |
210 | 226 |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 break; | 921 break; |
906 } | 922 } |
907 | 923 |
908 case SHORT_IMMEDIATE_INSTR: { | 924 case SHORT_IMMEDIATE_INSTR: { |
909 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); | 925 byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); |
910 AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr)); | 926 AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr)); |
911 data += 5; | 927 data += 5; |
912 break; | 928 break; |
913 } | 929 } |
914 | 930 |
| 931 case BYTE_IMMEDIATE_INSTR: { |
| 932 AppendToBuffer("%s al, 0x%x", idesc.mnem, data[1]); |
| 933 data += 2; |
| 934 break; |
| 935 } |
| 936 |
915 case NO_INSTR: | 937 case NO_INSTR: |
916 processed = false; | 938 processed = false; |
917 break; | 939 break; |
918 | 940 |
919 default: | 941 default: |
920 UNIMPLEMENTED(); // This type is not implemented. | 942 UNIMPLEMENTED(); // This type is not implemented. |
921 } | 943 } |
922 //---------------------------- | 944 //---------------------------- |
923 if (!processed) { | 945 if (!processed) { |
924 switch (*data) { | 946 switch (*data) { |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 case 0x6A: | 1361 case 0x6A: |
1340 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); | 1362 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); |
1341 data += 2; | 1363 data += 2; |
1342 break; | 1364 break; |
1343 | 1365 |
1344 case 0xA8: | 1366 case 0xA8: |
1345 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); | 1367 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); |
1346 data += 2; | 1368 data += 2; |
1347 break; | 1369 break; |
1348 | 1370 |
1349 case 0x2C: | |
1350 AppendToBuffer("subb eax,0x%x", *reinterpret_cast<uint8_t*>(data+1)); | |
1351 data += 2; | |
1352 break; | |
1353 | |
1354 case 0xA9: | 1371 case 0xA9: |
1355 AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); | 1372 AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); |
1356 data += 5; | 1373 data += 5; |
1357 break; | 1374 break; |
1358 | 1375 |
1359 case 0xD1: // fall through | 1376 case 0xD1: // fall through |
1360 case 0xD3: // fall through | 1377 case 0xD3: // fall through |
1361 case 0xC1: | 1378 case 0xC1: |
1362 data += D1D3C1Instruction(data); | 1379 data += D1D3C1Instruction(data); |
1363 break; | 1380 break; |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 fprintf(f, " "); | 1647 fprintf(f, " "); |
1631 } | 1648 } |
1632 fprintf(f, " %s\n", buffer.start()); | 1649 fprintf(f, " %s\n", buffer.start()); |
1633 } | 1650 } |
1634 } | 1651 } |
1635 | 1652 |
1636 | 1653 |
1637 } // namespace disasm | 1654 } // namespace disasm |
1638 | 1655 |
1639 #endif // V8_TARGET_ARCH_IA32 | 1656 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |