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); |