Chromium Code Reviews| Index: src/arm64/lithium-arm64.h |
| diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h |
| index b036446746ce391c460b3ca08a081422e44492b7..f41a29a2bed048976dc707355be53bd953095d40 100644 |
| --- a/src/arm64/lithium-arm64.h |
| +++ b/src/arm64/lithium-arm64.h |
| @@ -559,12 +559,36 @@ class LAddE V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| }; |
| -class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| +class LShiftedRightOpInterface { |
| + public: |
|
ulan
2014/05/02 10:01:18
Google style guide doesn't allow non-pure multiple
Alexandre Rames
2014/05/02 13:51:44
Done.
|
| + LShiftedRightOpInterface() |
| + : shift_(NO_SHIFT), shift_amount_(0) {} |
| + LShiftedRightOpInterface(Shift shift, LOperand* shift_amount) |
| + : shift_(shift), shift_amount_(shift_amount) {} |
| + |
| + virtual ~LShiftedRightOpInterface() {} |
| + |
| + Shift shift() const { return shift_; } |
| + LOperand* shift_amount() const { return shift_amount_; } |
| + |
| + protected: |
| + Shift shift_; |
| + LOperand* shift_amount_; |
| +}; |
| + |
| + |
| +class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0>, |
| + public LShiftedRightOpInterface { |
| public: |
| LAddI(LOperand* left, LOperand* right) { |
| inputs_[0] = left; |
| inputs_[1] = right; |
| } |
| + LAddI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount) |
| + : LShiftedRightOpInterface(shift, shift_amount) { |
| + inputs_[0] = left; |
| + inputs_[1] = right; |
| + } |
| LOperand* left() { return inputs_[0]; } |
| LOperand* right() { return inputs_[1]; } |
| @@ -728,13 +752,20 @@ class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> { |
| }; |
| -class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| +class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0>, |
| + public LShiftedRightOpInterface { |
| public: |
| LBitI(LOperand* left, LOperand* right) { |
| inputs_[0] = left; |
| inputs_[1] = right; |
| } |
| + LBitI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount) |
| + : LShiftedRightOpInterface(shift, shift_amount) { |
| + inputs_[0] = left; |
| + inputs_[1] = right; |
| + } |
| + |
| LOperand* left() { return inputs_[0]; } |
| LOperand* right() { return inputs_[1]; } |
| @@ -2700,13 +2731,20 @@ class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 2> { |
| }; |
| -class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> { |
| +class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0>, |
| + public LShiftedRightOpInterface { |
| public: |
| LSubI(LOperand* left, LOperand* right) { |
| inputs_[0] = left; |
| inputs_[1] = right; |
| } |
| + LSubI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount) |
| + : LShiftedRightOpInterface(shift, shift_amount) { |
| + inputs_[0] = left; |
| + inputs_[1] = right; |
| + } |
| + |
| LOperand* left() { return inputs_[0]; } |
| LOperand* right() { return inputs_[1]; } |
| @@ -3052,6 +3090,41 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase { |
| void VisitInstruction(HInstruction* current); |
| void DoBasicBlock(HBasicBlock* block); |
| + int ShiftAmountFromHConstant(HValue* constant) { |
| + return HConstant::cast(constant)->Integer32Value() & 0x1f; |
| + } |
| + bool LikelyFitsImmField(HInstruction* instr, int imm) { |
| + if (instr->IsAdd() || instr->IsSub()) { |
| + return Assembler::IsImmAddSub(imm) || Assembler::IsImmAddSub(-imm); |
|
ulan
2014/05/02 10:01:18
Did you mean && instead of ||?
Alexandre Rames
2014/05/02 13:51:44
'||' was intended. IsImmAddSub() works with unsign
|
| + } else if (instr->IsBitwise()) { |
| + unsigned unused_n, unused_imm_s, unused_imm_r; |
| + return Assembler::IsImmLogical(imm, kWRegSizeInBits, |
| + &unused_n, &unused_imm_s, &unused_imm_r); |
| + } else { |
| + UNREACHABLE(); |
|
ulan
2014/05/02 10:01:18
nit: I'd slightly prefer a more compact ASSERT(ins
Alexandre Rames
2014/05/02 13:51:44
Done.
|
| + return false; |
| + } |
| + } |
| + |
| + // Indicates if a sequence of the form |
| + // lsl x8, x9, #imm |
| + // add x0, x1, x8 |
| + // can be replaced with: |
| + // add x0, x1, x9 LSL #imm |
| + // If this is not possible, the function returns NULL. Otherwise it returns a |
| + // pointer to the shift instruction that would be optimized away. |
| + HBitwiseBinaryOperation* CanTransformToShiftedOp(HValue* val, |
| + HValue** left = NULL); |
| + // Checks if all uses of the shift operation can optimize it away. |
| + bool ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift); |
| + // Attempts to merge the binary operation and an eventual previous shift |
| + // operation into a single operation. Returns the merged instruction on |
| + // success, and NULL otherwise. |
| + LInstruction* TryDoOpWithShiftedRightOperand(HBinaryOperation* op); |
| + LInstruction* DoShiftedBinaryOp(HBinaryOperation* instr, |
| + HValue* left, |
| + HBitwiseBinaryOperation* shift); |
| + |
| LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); |
| LInstruction* DoArithmeticD(Token::Value op, |
| HArithmeticBinaryOperation* instr); |