| 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.h" | 9 #include "src/lithium.h" |
| 10 #include "src/lithium-allocator.h" | 10 #include "src/lithium-allocator.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) { | |
| 1244 inputs_[0] = left; | 1243 inputs_[0] = left; |
| 1245 inputs_[1] = right; | 1244 inputs_[1] = right; |
| 1246 } | 1245 } |
| 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 } | |
| 1253 | 1246 |
| 1254 LOperand* left() { return inputs_[0]; } | 1247 LOperand* left() { return inputs_[0]; } |
| 1255 LOperand* right() { return inputs_[1]; } | 1248 LOperand* right() { return inputs_[1]; } |
| 1256 | 1249 |
| 1257 ShiftOp shift() const { return shift_; } | |
| 1258 LOperand* shift_amount() const { return shift_amount_; } | |
| 1259 | |
| 1260 Token::Value op() const { return hydrogen()->op(); } | 1250 Token::Value op() const { return hydrogen()->op(); } |
| 1261 | 1251 |
| 1262 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") | 1252 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") |
| 1263 DECLARE_HYDROGEN_ACCESSOR(Bitwise) | 1253 DECLARE_HYDROGEN_ACCESSOR(Bitwise) |
| 1264 | |
| 1265 protected: | |
| 1266 ShiftOp shift_; | |
| 1267 LOperand* shift_amount_; | |
| 1268 }; | 1254 }; |
| 1269 | 1255 |
| 1270 | 1256 |
| 1271 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1257 class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| 1272 public: | 1258 public: |
| 1273 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) | 1259 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) |
| 1274 : op_(op), can_deopt_(can_deopt) { | 1260 : op_(op), can_deopt_(can_deopt) { |
| 1275 inputs_[0] = left; | 1261 inputs_[0] = left; |
| 1276 inputs_[1] = right; | 1262 inputs_[1] = right; |
| 1277 } | 1263 } |
| 1278 | 1264 |
| 1279 Token::Value op() const { return op_; } | 1265 Token::Value op() const { return op_; } |
| 1280 LOperand* left() { return inputs_[0]; } | 1266 LOperand* left() { return inputs_[0]; } |
| 1281 LOperand* right() { return inputs_[1]; } | 1267 LOperand* right() { return inputs_[1]; } |
| 1282 bool can_deopt() const { return can_deopt_; } | 1268 bool can_deopt() const { return can_deopt_; } |
| 1283 | 1269 |
| 1284 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") | 1270 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") |
| 1285 | 1271 |
| 1286 private: | 1272 private: |
| 1287 Token::Value op_; | 1273 Token::Value op_; |
| 1288 bool can_deopt_; | 1274 bool can_deopt_; |
| 1289 }; | 1275 }; |
| 1290 | 1276 |
| 1291 | 1277 |
| 1292 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1278 class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| 1293 public: | 1279 public: |
| 1294 LSubI(LOperand* left, LOperand* right) | 1280 LSubI(LOperand* left, LOperand* right) { |
| 1295 : shift_(NO_SHIFT), shift_amount_(0) { | |
| 1296 inputs_[0] = left; | 1281 inputs_[0] = left; |
| 1297 inputs_[1] = right; | 1282 inputs_[1] = right; |
| 1298 } | 1283 } |
| 1299 | 1284 |
| 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 | |
| 1309 LOperand* left() { return inputs_[0]; } | 1285 LOperand* left() { return inputs_[0]; } |
| 1310 LOperand* right() { return inputs_[1]; } | 1286 LOperand* right() { return inputs_[1]; } |
| 1311 | 1287 |
| 1312 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") | 1288 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") |
| 1313 DECLARE_HYDROGEN_ACCESSOR(Sub) | 1289 DECLARE_HYDROGEN_ACCESSOR(Sub) |
| 1314 | |
| 1315 protected: | |
| 1316 ShiftOp shift_; | |
| 1317 LOperand* shift_amount_; | |
| 1318 }; | 1290 }; |
| 1319 | 1291 |
| 1320 | 1292 |
| 1321 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1293 class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| 1322 public: | 1294 public: |
| 1323 LRSubI(LOperand* left, LOperand* right) { | 1295 LRSubI(LOperand* left, LOperand* right) { |
| 1324 inputs_[0] = left; | 1296 inputs_[0] = left; |
| 1325 inputs_[1] = right; | 1297 inputs_[1] = right; |
| 1326 } | 1298 } |
| 1327 | 1299 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 LOperand* index() { return inputs_[2]; } | 1448 LOperand* index() { return inputs_[2]; } |
| 1477 LOperand* value() { return inputs_[3]; } | 1449 LOperand* value() { return inputs_[3]; } |
| 1478 | 1450 |
| 1479 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") | 1451 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") |
| 1480 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) | 1452 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) |
| 1481 }; | 1453 }; |
| 1482 | 1454 |
| 1483 | 1455 |
| 1484 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1456 class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| 1485 public: | 1457 public: |
| 1486 LAddI(LOperand* left, LOperand* right) | 1458 LAddI(LOperand* left, LOperand* right) { |
| 1487 : shift_(NO_SHIFT), shift_amount_(0) { | |
| 1488 inputs_[0] = left; | 1459 inputs_[0] = left; |
| 1489 inputs_[1] = right; | 1460 inputs_[1] = right; |
| 1490 } | 1461 } |
| 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 } | |
| 1497 | 1462 |
| 1498 LOperand* left() { return inputs_[0]; } | 1463 LOperand* left() { return inputs_[0]; } |
| 1499 LOperand* right() { return inputs_[1]; } | 1464 LOperand* right() { return inputs_[1]; } |
| 1500 | 1465 |
| 1501 ShiftOp shift() const { return shift_; } | |
| 1502 LOperand* shift_amount() const { return shift_amount_; } | |
| 1503 | |
| 1504 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") | 1466 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") |
| 1505 DECLARE_HYDROGEN_ACCESSOR(Add) | 1467 DECLARE_HYDROGEN_ACCESSOR(Add) |
| 1506 | |
| 1507 protected: | |
| 1508 ShiftOp shift_; | |
| 1509 LOperand* shift_amount_; | |
| 1510 }; | 1468 }; |
| 1511 | 1469 |
| 1512 | 1470 |
| 1513 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { | 1471 class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| 1514 public: | 1472 public: |
| 1515 LMathMinMax(LOperand* left, LOperand* right) { | 1473 LMathMinMax(LOperand* left, LOperand* right) { |
| 1516 inputs_[0] = left; | 1474 inputs_[0] = left; |
| 1517 inputs_[1] = right; | 1475 inputs_[1] = right; |
| 1518 } | 1476 } |
| 1519 | 1477 |
| (...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2890 // instruction. | 2848 // instruction. |
| 2891 LInstruction* MarkAsCall( | 2849 LInstruction* MarkAsCall( |
| 2892 LInstruction* instr, | 2850 LInstruction* instr, |
| 2893 HInstruction* hinstr, | 2851 HInstruction* hinstr, |
| 2894 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); | 2852 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); |
| 2895 | 2853 |
| 2896 void VisitInstruction(HInstruction* current); | 2854 void VisitInstruction(HInstruction* current); |
| 2897 void AddInstruction(LInstruction* instr, HInstruction* current); | 2855 void AddInstruction(LInstruction* instr, HInstruction* current); |
| 2898 | 2856 |
| 2899 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); | 2857 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 | |
| 2943 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); | 2858 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); |
| 2944 LInstruction* DoArithmeticD(Token::Value op, | 2859 LInstruction* DoArithmeticD(Token::Value op, |
| 2945 HArithmeticBinaryOperation* instr); | 2860 HArithmeticBinaryOperation* instr); |
| 2946 LInstruction* DoArithmeticT(Token::Value op, | 2861 LInstruction* DoArithmeticT(Token::Value op, |
| 2947 HBinaryOperation* instr); | 2862 HBinaryOperation* instr); |
| 2948 | 2863 |
| 2949 LPlatformChunk* chunk_; | 2864 LPlatformChunk* chunk_; |
| 2950 CompilationInfo* info_; | 2865 CompilationInfo* info_; |
| 2951 HGraph* const graph_; | 2866 HGraph* const graph_; |
| 2952 Status status_; | 2867 Status status_; |
| 2953 HInstruction* current_instruction_; | 2868 HInstruction* current_instruction_; |
| 2954 HBasicBlock* current_block_; | 2869 HBasicBlock* current_block_; |
| 2955 HBasicBlock* next_block_; | 2870 HBasicBlock* next_block_; |
| 2956 LAllocator* allocator_; | 2871 LAllocator* allocator_; |
| 2957 | 2872 |
| 2958 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 2873 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
| 2959 }; | 2874 }; |
| 2960 | 2875 |
| 2961 #undef DECLARE_HYDROGEN_ACCESSOR | 2876 #undef DECLARE_HYDROGEN_ACCESSOR |
| 2962 #undef DECLARE_CONCRETE_INSTRUCTION | 2877 #undef DECLARE_CONCRETE_INSTRUCTION |
| 2963 | 2878 |
| 2964 } } // namespace v8::internal | 2879 } } // namespace v8::internal |
| 2965 | 2880 |
| 2966 #endif // V8_ARM_LITHIUM_ARM_H_ | 2881 #endif // V8_ARM_LITHIUM_ARM_H_ |
| OLD | NEW |