From 817430f6cec5f5b386512b22a9df7efcc9d89fa3 Mon Sep 17 00:00:00 2001 From: "haitao.feng@intel.com" Date: Fri, 13 Jun 2014 02:38:46 +0000 Subject: [PATCH] Update Lithium AddI, SubI, MulI, BitI, ShiftI, MathMinMax to support x32 port. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/321373002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21827 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/lithium-codegen-x64.cc | 75 +++++++++++++++++++++++++++++++----------- src/x64/lithium-codegen-x64.h | 1 + src/x64/lithium-x64.cc | 10 ++++-- 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index edb5e6a..81e8e9b 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -436,8 +436,17 @@ bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { + return ToRepresentation(op, Representation::Integer32()); +} + + +int32_t LCodeGen::ToRepresentation(LConstantOperand* op, + const Representation& r) const { HConstant* constant = chunk_->LookupConstant(op); - return constant->Integer32Value(); + int32_t value = constant->Integer32Value(); + if (r.IsInteger32()) return value; + ASSERT(SmiValuesAre31Bits() && r.IsSmiOrTagged()); + return static_cast(reinterpret_cast(Smi::FromInt(value))); } @@ -1463,8 +1472,11 @@ void LCodeGen::DoMulI(LMulI* instr) { } __ j(not_zero, &done, Label::kNear); if (right->IsConstantOperand()) { - // Constant can't be represented as Smi due to immediate size limit. - ASSERT(!instr->hydrogen_value()->representation().IsSmi()); + // Constant can't be represented as 32-bit Smi due to immediate size + // limit. + ASSERT(SmiValuesAre32Bits() + ? !instr->hydrogen_value()->representation().IsSmi() + : SmiValuesAre31Bits()); if (ToInteger32(LConstantOperand::cast(right)) < 0) { DeoptimizeIf(no_condition, instr->environment()); } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { @@ -1499,7 +1511,9 @@ void LCodeGen::DoBitI(LBitI* instr) { ASSERT(left->IsRegister()); if (right->IsConstantOperand()) { - int32_t right_operand = ToInteger32(LConstantOperand::cast(right)); + int32_t right_operand = + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->right()->representation()); switch (instr->op()) { case Token::BIT_AND: __ andl(ToRegister(left), Immediate(right_operand)); @@ -1631,7 +1645,20 @@ void LCodeGen::DoShiftI(LShiftI* instr) { case Token::SHL: if (shift_count != 0) { if (instr->hydrogen_value()->representation().IsSmi()) { - __ shlp(ToRegister(left), Immediate(shift_count)); + if (SmiValuesAre32Bits()) { + __ shlp(ToRegister(left), Immediate(shift_count)); + } else { + ASSERT(SmiValuesAre31Bits()); + if (instr->can_deopt()) { + if (shift_count != 1) { + __ shll(ToRegister(left), Immediate(shift_count - 1)); + } + __ Integer32ToSmi(ToRegister(left), ToRegister(left)); + DeoptimizeIf(overflow, instr->environment()); + } else { + __ shll(ToRegister(left), Immediate(shift_count)); + } + } } else { __ shll(ToRegister(left), Immediate(shift_count)); } @@ -1651,8 +1678,10 @@ void LCodeGen::DoSubI(LSubI* instr) { ASSERT(left->Equals(instr->result())); if (right->IsConstantOperand()) { - __ subl(ToRegister(left), - Immediate(ToInteger32(LConstantOperand::cast(right)))); + int32_t right_operand = + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->right()->representation()); + __ subl(ToRegister(left), Immediate(right_operand)); } else if (right->IsRegister()) { if (instr->hydrogen_value()->representation().IsSmi()) { __ subp(ToRegister(left), ToRegister(right)); @@ -1853,8 +1882,11 @@ void LCodeGen::DoAddI(LAddI* instr) { if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { if (right->IsConstantOperand()) { - ASSERT(!target_rep.IsSmi()); // No support for smi-immediates. - int32_t offset = ToInteger32(LConstantOperand::cast(right)); + // No support for smi-immediates for 32-bit SMI. + ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); + int32_t offset = + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->right()->representation()); if (is_p) { __ leap(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); @@ -1872,13 +1904,15 @@ void LCodeGen::DoAddI(LAddI* instr) { } } else { if (right->IsConstantOperand()) { - ASSERT(!target_rep.IsSmi()); // No support for smi-immediates. + // No support for smi-immediates for 32-bit SMI. + ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); + int32_t right_operand = + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->right()->representation()); if (is_p) { - __ addp(ToRegister(left), - Immediate(ToInteger32(LConstantOperand::cast(right)))); + __ addp(ToRegister(left), Immediate(right_operand)); } else { - __ addl(ToRegister(left), - Immediate(ToInteger32(LConstantOperand::cast(right)))); + __ addl(ToRegister(left), Immediate(right_operand)); } } else if (right->IsRegister()) { if (is_p) { @@ -1912,9 +1946,12 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { : greater_equal; Register left_reg = ToRegister(left); if (right->IsConstantOperand()) { - Immediate right_imm = - Immediate(ToInteger32(LConstantOperand::cast(right))); - ASSERT(!instr->hydrogen_value()->representation().IsSmi()); + Immediate right_imm = Immediate( + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->right()->representation())); + ASSERT(SmiValuesAre32Bits() + ? !instr->hydrogen()->representation().IsSmi() + : SmiValuesAre31Bits()); __ cmpl(left_reg, right_imm); __ j(condition, &return_left, Label::kNear); __ movp(left_reg, right_imm); @@ -4769,8 +4806,8 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { Register output = ToRegister(instr->result()); if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { - __ testl(input, input); - DeoptimizeIf(sign, instr->environment()); + Condition is_smi = __ CheckUInteger32ValidSmiValue(input); + DeoptimizeIf(NegateCondition(is_smi), instr->environment()); } __ Integer32ToSmi(output, input); if (hchange->CheckFlag(HValue::kCanOverflow) && diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 51b7645..5621a3d 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -65,6 +65,7 @@ class LCodeGen: public LCodeGenBase { bool IsInteger32Constant(LConstantOperand* op) const; bool IsDehoistedKeyConstant(LConstantOperand* op) const; bool IsSmiConstant(LConstantOperand* op) const; + int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; int32_t ToInteger32(LConstantOperand* op) const; Smi* ToSmi(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const; diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index fd6f17d..325f2c0 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -699,17 +699,23 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, HValue* right_value = instr->right(); LOperand* right = NULL; int constant_value = 0; + bool does_deopt = false; if (right_value->IsConstant()) { HConstant* constant = HConstant::cast(right_value); right = chunk_->DefineConstantOperand(constant); constant_value = constant->Integer32Value() & 0x1f; + if (SmiValuesAre31Bits() && instr->representation().IsSmi() && + constant_value > 0) { + // Left shift can deoptimize if we shift by > 0 and the result + // cannot be truncated to smi. + does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); + } } else { right = UseFixed(right_value, rcx); } // Shift operations can only deoptimize if we do a logical shift by 0 and // the result cannot be truncated to int32. - bool does_deopt = false; if (op == Token::SHR && constant_value == 0) { if (FLAG_opt_safe_uint32_operations) { does_deopt = !instr->CheckFlag(HInstruction::kUint32); @@ -1521,7 +1527,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); HValue* right_candidate = instr->BetterRightOperand(); LOperand* right; - if (instr->representation().IsSmi()) { + if (SmiValuesAre32Bits() && instr->representation().IsSmi()) { // We cannot add a tagged immediate to a tagged value, // so we request it in a register. right = UseRegisterAtStart(right_candidate); -- 2.7.4