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 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 LOperand* index() { return inputs_[0]; } | 1232 LOperand* index() { return inputs_[0]; } |
1233 LOperand* length() { return inputs_[1]; } | 1233 LOperand* length() { return inputs_[1]; } |
1234 | 1234 |
1235 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") | 1235 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") |
1236 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) | 1236 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) |
1237 }; | 1237 }; |
1238 | 1238 |
1239 | 1239 |
1240 class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1240 class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1241 public: | 1241 public: |
1242 LBitI(LOperand* left, LOperand* right) { | 1242 LBitI(LOperand* left, LOperand* right) |
| 1243 : shift_(NO_SHIFT), shift_amount_(0) { |
1243 inputs_[0] = left; | 1244 inputs_[0] = left; |
1244 inputs_[1] = right; | 1245 inputs_[1] = right; |
1245 } | 1246 } |
| 1247 |
| 1248 LBitI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1249 : shift_(shift), shift_amount_(shift_amount) { |
| 1250 inputs_[0] = left; |
| 1251 inputs_[1] = right; |
| 1252 } |
1246 | 1253 |
1247 LOperand* left() { return inputs_[0]; } | 1254 LOperand* left() { return inputs_[0]; } |
1248 LOperand* right() { return inputs_[1]; } | 1255 LOperand* right() { return inputs_[1]; } |
1249 | 1256 |
| 1257 ShiftOp shift() const { return shift_; } |
| 1258 LOperand* shift_amount() const { return shift_amount_; } |
| 1259 |
1250 Token::Value op() const { return hydrogen()->op(); } | 1260 Token::Value op() const { return hydrogen()->op(); } |
1251 | 1261 |
1252 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") | 1262 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") |
1253 DECLARE_HYDROGEN_ACCESSOR(Bitwise) | 1263 DECLARE_HYDROGEN_ACCESSOR(Bitwise) |
| 1264 |
| 1265 protected: |
| 1266 ShiftOp shift_; |
| 1267 LOperand* shift_amount_; |
1254 }; | 1268 }; |
1255 | 1269 |
1256 | 1270 |
1257 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1271 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1258 public: | 1272 public: |
1259 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) | 1273 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) |
1260 : op_(op), can_deopt_(can_deopt) { | 1274 : op_(op), can_deopt_(can_deopt) { |
1261 inputs_[0] = left; | 1275 inputs_[0] = left; |
1262 inputs_[1] = right; | 1276 inputs_[1] = right; |
1263 } | 1277 } |
1264 | 1278 |
1265 Token::Value op() const { return op_; } | 1279 Token::Value op() const { return op_; } |
1266 LOperand* left() { return inputs_[0]; } | 1280 LOperand* left() { return inputs_[0]; } |
1267 LOperand* right() { return inputs_[1]; } | 1281 LOperand* right() { return inputs_[1]; } |
1268 bool can_deopt() const { return can_deopt_; } | 1282 bool can_deopt() const { return can_deopt_; } |
1269 | 1283 |
1270 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") | 1284 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") |
1271 | 1285 |
1272 private: | 1286 private: |
1273 Token::Value op_; | 1287 Token::Value op_; |
1274 bool can_deopt_; | 1288 bool can_deopt_; |
1275 }; | 1289 }; |
1276 | 1290 |
1277 | 1291 |
1278 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1292 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1279 public: | 1293 public: |
1280 LSubI(LOperand* left, LOperand* right) { | 1294 LSubI(LOperand* left, LOperand* right) |
| 1295 : shift_(NO_SHIFT), shift_amount_(0) { |
1281 inputs_[0] = left; | 1296 inputs_[0] = left; |
1282 inputs_[1] = right; | 1297 inputs_[1] = right; |
1283 } | 1298 } |
1284 | 1299 |
| 1300 LSubI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1301 : shift_(shift), shift_amount_(shift_amount) { |
| 1302 inputs_[0] = left; |
| 1303 inputs_[1] = right; |
| 1304 } |
| 1305 |
| 1306 ShiftOp shift() const { return shift_; } |
| 1307 LOperand* shift_amount() const { return shift_amount_; } |
| 1308 |
1285 LOperand* left() { return inputs_[0]; } | 1309 LOperand* left() { return inputs_[0]; } |
1286 LOperand* right() { return inputs_[1]; } | 1310 LOperand* right() { return inputs_[1]; } |
1287 | 1311 |
1288 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") | 1312 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") |
1289 DECLARE_HYDROGEN_ACCESSOR(Sub) | 1313 DECLARE_HYDROGEN_ACCESSOR(Sub) |
| 1314 |
| 1315 protected: |
| 1316 ShiftOp shift_; |
| 1317 LOperand* shift_amount_; |
1290 }; | 1318 }; |
1291 | 1319 |
1292 | 1320 |
1293 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1321 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1294 public: | 1322 public: |
1295 LRSubI(LOperand* left, LOperand* right) { | 1323 LRSubI(LOperand* left, LOperand* right) { |
1296 inputs_[0] = left; | 1324 inputs_[0] = left; |
1297 inputs_[1] = right; | 1325 inputs_[1] = right; |
1298 } | 1326 } |
1299 | 1327 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 LOperand* index() { return inputs_[2]; } | 1476 LOperand* index() { return inputs_[2]; } |
1449 LOperand* value() { return inputs_[3]; } | 1477 LOperand* value() { return inputs_[3]; } |
1450 | 1478 |
1451 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") | 1479 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") |
1452 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) | 1480 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) |
1453 }; | 1481 }; |
1454 | 1482 |
1455 | 1483 |
1456 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1484 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1457 public: | 1485 public: |
1458 LAddI(LOperand* left, LOperand* right) { | 1486 LAddI(LOperand* left, LOperand* right) |
| 1487 : shift_(NO_SHIFT), shift_amount_(0) { |
1459 inputs_[0] = left; | 1488 inputs_[0] = left; |
1460 inputs_[1] = right; | 1489 inputs_[1] = right; |
1461 } | 1490 } |
| 1491 |
| 1492 LAddI(LOperand* left, LOperand* right, ShiftOp shift, LOperand* shift_amount) |
| 1493 : shift_(shift), shift_amount_(shift_amount) { |
| 1494 inputs_[0] = left; |
| 1495 inputs_[1] = right; |
| 1496 } |
1462 | 1497 |
1463 LOperand* left() { return inputs_[0]; } | 1498 LOperand* left() { return inputs_[0]; } |
1464 LOperand* right() { return inputs_[1]; } | 1499 LOperand* right() { return inputs_[1]; } |
1465 | 1500 |
| 1501 ShiftOp shift() const { return shift_; } |
| 1502 LOperand* shift_amount() const { return shift_amount_; } |
| 1503 |
1466 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") | 1504 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") |
1467 DECLARE_HYDROGEN_ACCESSOR(Add) | 1505 DECLARE_HYDROGEN_ACCESSOR(Add) |
| 1506 |
| 1507 protected: |
| 1508 ShiftOp shift_; |
| 1509 LOperand* shift_amount_; |
1468 }; | 1510 }; |
1469 | 1511 |
1470 | 1512 |
1471 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1513 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
1472 public: | 1514 public: |
1473 LMathMinMax(LOperand* left, LOperand* right) { | 1515 LMathMinMax(LOperand* left, LOperand* right) { |
1474 inputs_[0] = left; | 1516 inputs_[0] = left; |
1475 inputs_[1] = right; | 1517 inputs_[1] = right; |
1476 } | 1518 } |
1477 | 1519 |
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2848 // instruction. | 2890 // instruction. |
2849 LInstruction* MarkAsCall( | 2891 LInstruction* MarkAsCall( |
2850 LInstruction* instr, | 2892 LInstruction* instr, |
2851 HInstruction* hinstr, | 2893 HInstruction* hinstr, |
2852 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); | 2894 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); |
2853 | 2895 |
2854 void VisitInstruction(HInstruction* current); | 2896 void VisitInstruction(HInstruction* current); |
2855 void AddInstruction(LInstruction* instr, HInstruction* current); | 2897 void AddInstruction(LInstruction* instr, HInstruction* current); |
2856 | 2898 |
2857 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); | 2899 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); |
| 2900 |
| 2901 int JSShiftAmountFromHConstant(HValue* constant) { |
| 2902 return HConstant::cast(constant)->Integer32Value() & 0x1f; |
| 2903 } |
| 2904 bool LikelyFitsImmField(HInstruction* instr, int imm) { |
| 2905 Instr instr_bits; |
| 2906 // All arithmetic and logical operations accept the same range of |
| 2907 // immediates. In some cases though, the operation itself can be changed to |
| 2908 // get a wider effective range of immediates. |
| 2909 if (instr->IsAdd() || instr->IsSub()) { |
| 2910 // ADD and SUB can be exchanged with a negate immediate. |
| 2911 instr_bits = ADD; |
| 2912 } else if (HBitwise::cast(instr)->op() == Token::BIT_AND) { |
| 2913 ASSERT(instr->IsBitwise()); |
| 2914 // AND and BIC can be exchanged with an inverted immediate. |
| 2915 instr_bits = AND; |
| 2916 } else { |
| 2917 ASSERT(instr->IsBitwise()); |
| 2918 // Use ORR for all other operations, since fits_shifter() can't adapt ORR. |
| 2919 instr_bits = ORR; |
| 2920 } |
| 2921 return fits_shifter(imm, NULL, NULL, &instr_bits); |
| 2922 } |
| 2923 |
| 2924 // Indicates if a sequence of the form |
| 2925 // mov r1, r2 LSL #imm |
| 2926 // add r0, r5, r1 |
| 2927 // can be replaced with: |
| 2928 // add r0, r5, r2 LSL #imm |
| 2929 // If this is not possible, the function returns NULL. Otherwise it returns a |
| 2930 // pointer to the shift instruction that would be optimized away. |
| 2931 HBitwiseBinaryOperation* CanTransformToShiftedOp(HValue* val, |
| 2932 HValue** left = NULL); |
| 2933 // Checks if all uses of the shift operation can optimize it away. |
| 2934 bool ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift); |
| 2935 // Attempts to merge the binary operation and a previous shift operation into |
| 2936 // a single operation. Returns the merged instruction on success, and NULL |
| 2937 // otherwise. |
| 2938 LInstruction* TryDoOpWithShiftedRightOperand(HBinaryOperation* op); |
| 2939 LInstruction* DoShiftedBinaryOp(HBinaryOperation* instr, |
| 2940 HValue* left, |
| 2941 HBitwiseBinaryOperation* shift); |
| 2942 |
2858 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); | 2943 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); |
2859 LInstruction* DoArithmeticD(Token::Value op, | 2944 LInstruction* DoArithmeticD(Token::Value op, |
2860 HArithmeticBinaryOperation* instr); | 2945 HArithmeticBinaryOperation* instr); |
2861 LInstruction* DoArithmeticT(Token::Value op, | 2946 LInstruction* DoArithmeticT(Token::Value op, |
2862 HBinaryOperation* instr); | 2947 HBinaryOperation* instr); |
2863 | 2948 |
2864 LPlatformChunk* chunk_; | 2949 LPlatformChunk* chunk_; |
2865 CompilationInfo* info_; | 2950 CompilationInfo* info_; |
2866 HGraph* const graph_; | 2951 HGraph* const graph_; |
2867 Status status_; | 2952 Status status_; |
2868 HInstruction* current_instruction_; | 2953 HInstruction* current_instruction_; |
2869 HBasicBlock* current_block_; | 2954 HBasicBlock* current_block_; |
2870 HBasicBlock* next_block_; | 2955 HBasicBlock* next_block_; |
2871 LAllocator* allocator_; | 2956 LAllocator* allocator_; |
2872 | 2957 |
2873 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 2958 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
2874 }; | 2959 }; |
2875 | 2960 |
2876 #undef DECLARE_HYDROGEN_ACCESSOR | 2961 #undef DECLARE_HYDROGEN_ACCESSOR |
2877 #undef DECLARE_CONCRETE_INSTRUCTION | 2962 #undef DECLARE_CONCRETE_INSTRUCTION |
2878 | 2963 |
2879 } } // namespace v8::internal | 2964 } } // namespace v8::internal |
2880 | 2965 |
2881 #endif // V8_ARM_LITHIUM_ARM_H_ | 2966 #endif // V8_ARM_LITHIUM_ARM_H_ |
OLD | NEW |