| 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 |