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 |