OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_ARM_LITHIUM_ARM_H_ | 5 #ifndef V8_ARM_LITHIUM_ARM_H_ |
6 #define V8_ARM_LITHIUM_ARM_H_ | 6 #define V8_ARM_LITHIUM_ARM_H_ |
7 | 7 |
8 #include "src/hydrogen.h" | 8 #include "src/hydrogen.h" |
9 #include "src/lithium-allocator.h" | 9 #include "src/lithium-allocator.h" |
10 #include "src/lithium.h" | 10 #include "src/lithium.h" |
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 LOperand* index() { return inputs_[0]; } | 1230 LOperand* index() { return inputs_[0]; } |
1231 LOperand* length() { return inputs_[1]; } | 1231 LOperand* length() { return inputs_[1]; } |
1232 | 1232 |
1233 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") | 1233 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") |
1234 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) | 1234 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) |
1235 }; | 1235 }; |
1236 | 1236 |
1237 | 1237 |
1238 class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1238 class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1239 public: | 1239 public: |
1240 LBitI(LOperand* left, LOperand* right) { | 1240 LBitI(LOperand* left, LOperand* right) |
| 1241 : shift_(NO_SHIFT), shift_amount_(0) { |
1241 inputs_[0] = left; | 1242 inputs_[0] = left; |
1242 inputs_[1] = right; | 1243 inputs_[1] = right; |
1243 } | 1244 } |
| 1245 |
| 1246 LBitI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1247 : shift_(shift), shift_amount_(shift_amount) { |
| 1248 inputs_[0] = left; |
| 1249 inputs_[1] = right; |
| 1250 } |
1244 | 1251 |
1245 LOperand* left() { return inputs_[0]; } | 1252 LOperand* left() { return inputs_[0]; } |
1246 LOperand* right() { return inputs_[1]; } | 1253 LOperand* right() { return inputs_[1]; } |
1247 | 1254 |
| 1255 ShiftOp shift() const { return shift_; } |
| 1256 LOperand* shift_amount() const { return shift_amount_; } |
| 1257 |
1248 Token::Value op() const { return hydrogen()->op(); } | 1258 Token::Value op() const { return hydrogen()->op(); } |
1249 | 1259 |
1250 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") | 1260 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") |
1251 DECLARE_HYDROGEN_ACCESSOR(Bitwise) | 1261 DECLARE_HYDROGEN_ACCESSOR(Bitwise) |
| 1262 |
| 1263 protected: |
| 1264 ShiftOp shift_; |
| 1265 LOperand* shift_amount_; |
1252 }; | 1266 }; |
1253 | 1267 |
1254 | 1268 |
1255 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1269 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1256 public: | 1270 public: |
1257 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) | 1271 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) |
1258 : op_(op), can_deopt_(can_deopt) { | 1272 : op_(op), can_deopt_(can_deopt) { |
1259 inputs_[0] = left; | 1273 inputs_[0] = left; |
1260 inputs_[1] = right; | 1274 inputs_[1] = right; |
1261 } | 1275 } |
1262 | 1276 |
1263 Token::Value op() const { return op_; } | 1277 Token::Value op() const { return op_; } |
1264 LOperand* left() { return inputs_[0]; } | 1278 LOperand* left() { return inputs_[0]; } |
1265 LOperand* right() { return inputs_[1]; } | 1279 LOperand* right() { return inputs_[1]; } |
1266 bool can_deopt() const { return can_deopt_; } | 1280 bool can_deopt() const { return can_deopt_; } |
1267 | 1281 |
1268 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") | 1282 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") |
1269 | 1283 |
1270 private: | 1284 private: |
1271 Token::Value op_; | 1285 Token::Value op_; |
1272 bool can_deopt_; | 1286 bool can_deopt_; |
1273 }; | 1287 }; |
1274 | 1288 |
1275 | 1289 |
1276 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1290 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1277 public: | 1291 public: |
1278 LSubI(LOperand* left, LOperand* right) { | 1292 LSubI(LOperand* left, LOperand* right) |
| 1293 : shift_(NO_SHIFT), shift_amount_(0) { |
1279 inputs_[0] = left; | 1294 inputs_[0] = left; |
1280 inputs_[1] = right; | 1295 inputs_[1] = right; |
1281 } | 1296 } |
1282 | 1297 |
| 1298 LSubI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1299 : shift_(shift), shift_amount_(shift_amount) { |
| 1300 inputs_[0] = left; |
| 1301 inputs_[1] = right; |
| 1302 } |
| 1303 |
| 1304 ShiftOp shift() const { return shift_; } |
| 1305 LOperand* shift_amount() const { return shift_amount_; } |
| 1306 |
1283 LOperand* left() { return inputs_[0]; } | 1307 LOperand* left() { return inputs_[0]; } |
1284 LOperand* right() { return inputs_[1]; } | 1308 LOperand* right() { return inputs_[1]; } |
1285 | 1309 |
1286 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") | 1310 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") |
1287 DECLARE_HYDROGEN_ACCESSOR(Sub) | 1311 DECLARE_HYDROGEN_ACCESSOR(Sub) |
| 1312 |
| 1313 protected: |
| 1314 ShiftOp shift_; |
| 1315 LOperand* shift_amount_; |
1288 }; | 1316 }; |
1289 | 1317 |
1290 | 1318 |
1291 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1319 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1292 public: | 1320 public: |
1293 LRSubI(LOperand* left, LOperand* right) { | 1321 LRSubI(LOperand* left, LOperand* right) { |
1294 inputs_[0] = left; | 1322 inputs_[0] = left; |
1295 inputs_[1] = right; | 1323 inputs_[1] = right; |
1296 } | 1324 } |
1297 | 1325 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 LOperand* index() { return inputs_[2]; } | 1474 LOperand* index() { return inputs_[2]; } |
1447 LOperand* value() { return inputs_[3]; } | 1475 LOperand* value() { return inputs_[3]; } |
1448 | 1476 |
1449 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") | 1477 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") |
1450 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) | 1478 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) |
1451 }; | 1479 }; |
1452 | 1480 |
1453 | 1481 |
1454 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1482 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1455 public: | 1483 public: |
1456 LAddI(LOperand* left, LOperand* right) { | 1484 LAddI(LOperand* left, LOperand* right) |
| 1485 : shift_(NO_SHIFT), shift_amount_(0) { |
1457 inputs_[0] = left; | 1486 inputs_[0] = left; |
1458 inputs_[1] = right; | 1487 inputs_[1] = right; |
1459 } | 1488 } |
| 1489 |
| 1490 LAddI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1491 : shift_(shift), shift_amount_(shift_amount) { |
| 1492 inputs_[0] = left; |
| 1493 inputs_[1] = right; |
| 1494 } |
1460 | 1495 |
1461 LOperand* left() { return inputs_[0]; } | 1496 LOperand* left() { return inputs_[0]; } |
1462 LOperand* right() { return inputs_[1]; } | 1497 LOperand* right() { return inputs_[1]; } |
1463 | 1498 |
| 1499 ShiftOp shift() const { return shift_; } |
| 1500 LOperand* shift_amount() const { return shift_amount_; } |
| 1501 |
1464 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") | 1502 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") |
1465 DECLARE_HYDROGEN_ACCESSOR(Add) | 1503 DECLARE_HYDROGEN_ACCESSOR(Add) |
| 1504 |
| 1505 protected: |
| 1506 ShiftOp shift_; |
| 1507 LOperand* shift_amount_; |
1466 }; | 1508 }; |
1467 | 1509 |
1468 | 1510 |
1469 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1511 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1470 public: | 1512 public: |
1471 LMathMinMax(LOperand* left, LOperand* right) { | 1513 LMathMinMax(LOperand* left, LOperand* right) { |
1472 inputs_[0] = left; | 1514 inputs_[0] = left; |
1473 inputs_[1] = right; | 1515 inputs_[1] = right; |
1474 } | 1516 } |
1475 | 1517 |
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2817 // instruction. | 2859 // instruction. |
2818 LInstruction* MarkAsCall( | 2860 LInstruction* MarkAsCall( |
2819 LInstruction* instr, | 2861 LInstruction* instr, |
2820 HInstruction* hinstr, | 2862 HInstruction* hinstr, |
2821 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); | 2863 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); |
2822 | 2864 |
2823 void VisitInstruction(HInstruction* current); | 2865 void VisitInstruction(HInstruction* current); |
2824 void AddInstruction(LInstruction* instr, HInstruction* current); | 2866 void AddInstruction(LInstruction* instr, HInstruction* current); |
2825 | 2867 |
2826 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); | 2868 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); |
| 2869 |
| 2870 int JSShiftAmountFromHConstant(HValue* constant) { |
| 2871 return HConstant::cast(constant)->Integer32Value() & 0x1f; |
| 2872 } |
| 2873 bool LikelyFitsImmField(HInstruction* instr, int imm) { |
| 2874 Instr instr_bits; |
| 2875 // All arithmetic and logical operations accept the same range of |
| 2876 // immediates. In some cases though, the operation itself can be changed to |
| 2877 // get a wider effective range of immediates. |
| 2878 if (instr->IsAdd() || instr->IsSub()) { |
| 2879 // ADD and SUB can be exchanged with a negate immediate. |
| 2880 instr_bits = ADD; |
| 2881 } else if (HBitwise::cast(instr)->op() == Token::BIT_AND) { |
| 2882 ASSERT(instr->IsBitwise()); |
| 2883 // AND and BIC can be exchanged with an inverted immediate. |
| 2884 instr_bits = AND; |
| 2885 } else { |
| 2886 ASSERT(instr->IsBitwise()); |
| 2887 // Use ORR for all other operations, since fits_shifter() can't adapt ORR. |
| 2888 instr_bits = ORR; |
| 2889 } |
| 2890 return fits_shifter(imm, NULL, NULL, &instr_bits); |
| 2891 } |
| 2892 |
| 2893 // Indicates if a sequence of the form |
| 2894 // mov r1, r2 LSL #imm |
| 2895 // add r0, r5, r1 |
| 2896 // can be replaced with: |
| 2897 // add r0, r5, r2 LSL #imm |
| 2898 // If this is not possible, the function returns NULL. Otherwise it returns a |
| 2899 // pointer to the shift instruction that would be optimized away. |
| 2900 HBitwiseBinaryOperation* CanTransformToShiftedOp(HValue* val, |
| 2901 HValue** left = NULL); |
| 2902 // Checks if all uses of the shift operation can optimize it away. |
| 2903 bool ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift); |
| 2904 // Attempts to merge the binary operation and a previous shift operation into |
| 2905 // a single operation. Returns the merged instruction on success, and NULL |
| 2906 // otherwise. |
| 2907 LInstruction* TryDoOpWithShiftedRightOperand(HBinaryOperation* op); |
| 2908 LInstruction* DoShiftedBinaryOp(HBinaryOperation* instr, |
| 2909 HValue* left, |
| 2910 HBitwiseBinaryOperation* shift); |
| 2911 |
2827 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); | 2912 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); |
2828 LInstruction* DoArithmeticD(Token::Value op, | 2913 LInstruction* DoArithmeticD(Token::Value op, |
2829 HArithmeticBinaryOperation* instr); | 2914 HArithmeticBinaryOperation* instr); |
2830 LInstruction* DoArithmeticT(Token::Value op, | 2915 LInstruction* DoArithmeticT(Token::Value op, |
2831 HBinaryOperation* instr); | 2916 HBinaryOperation* instr); |
2832 | 2917 |
2833 LPlatformChunk* chunk_; | 2918 LPlatformChunk* chunk_; |
2834 CompilationInfo* info_; | 2919 CompilationInfo* info_; |
2835 HGraph* const graph_; | 2920 HGraph* const graph_; |
2836 Status status_; | 2921 Status status_; |
2837 HInstruction* current_instruction_; | 2922 HInstruction* current_instruction_; |
2838 HBasicBlock* current_block_; | 2923 HBasicBlock* current_block_; |
2839 HBasicBlock* next_block_; | 2924 HBasicBlock* next_block_; |
2840 LAllocator* allocator_; | 2925 LAllocator* allocator_; |
2841 | 2926 |
2842 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 2927 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
2843 }; | 2928 }; |
2844 | 2929 |
2845 #undef DECLARE_HYDROGEN_ACCESSOR | 2930 #undef DECLARE_HYDROGEN_ACCESSOR |
2846 #undef DECLARE_CONCRETE_INSTRUCTION | 2931 #undef DECLARE_CONCRETE_INSTRUCTION |
2847 | 2932 |
2848 } } // namespace v8::internal | 2933 } } // namespace v8::internal |
2849 | 2934 |
2850 #endif // V8_ARM_LITHIUM_ARM_H_ | 2935 #endif // V8_ARM_LITHIUM_ARM_H_ |
OLD | NEW |