From 61a78e2a11013d33a21b5b9d67e17d0f4d7cdc46 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Thu, 25 Jul 2013 19:57:10 +0000 Subject: [PATCH] MIPS: Adding Smi support to Add, Sub, Mul, and Bitwise Port r15879 (ec1e278b) BUG= Review URL: https://codereview.chromium.org/20407002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15891 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 44 ++++++++++++++++----- src/mips/lithium-codegen-mips.h | 3 +- src/mips/lithium-gap-resolver-mips.cc | 16 ++++---- src/mips/lithium-mips.cc | 57 ++++++++++++++------------- 4 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 748e4385dd..5cf1d59e49 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -477,9 +477,18 @@ bool LCodeGen::IsSmi(LConstantOperand* op) const { } -int LCodeGen::ToInteger32(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(r.IsSmiOrTagged()); + return reinterpret_cast(Smi::FromInt(value)); } @@ -501,7 +510,10 @@ Operand LCodeGen::ToOperand(LOperand* op) { LConstantOperand* const_op = LConstantOperand::cast(op); HConstant* constant = chunk()->LookupConstant(const_op); Representation r = chunk_->LookupLiteralRepresentation(const_op); - if (r.IsInteger32()) { + if (r.IsSmi()) { + ASSERT(constant->HasSmiValue()); + return Operand(Smi::FromInt(constant->Integer32Value())); + } else if (r.IsInteger32()) { ASSERT(constant->HasInteger32Value()); return Operand(constant->Integer32Value()); } else if (r.IsDouble()) { @@ -1367,7 +1379,9 @@ void LCodeGen::DoMulI(LMulI* instr) { if (right_op->IsConstantOperand() && !can_overflow) { // Use optimized code for specific constants. - int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); + int32_t constant = ToRepresentation( + LConstantOperand::cast(right_op), + instr->hydrogen()->right()->representation()); if (bailout_on_minus_zero && (constant < 0)) { // The case of a null constant will be handled separately. @@ -1434,13 +1448,25 @@ void LCodeGen::DoMulI(LMulI* instr) { if (can_overflow) { // hi:lo = left * right. - __ mult(left, right); - __ mfhi(scratch); - __ mflo(result); + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiUntag(result, left); + __ mult(result, right); + __ mfhi(scratch); + __ mflo(result); + } else { + __ mult(left, right); + __ mfhi(scratch); + __ mflo(result); + } __ sra(at, result, 31); DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); } else { - __ Mul(result, left, right); + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiUntag(result, left); + __ Mul(result, result, right); + } else { + __ Mul(result, left, right); + } } if (bailout_on_minus_zero) { @@ -1803,7 +1829,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { LOperand* right = instr->right(); HMathMinMax::Operation operation = instr->hydrogen()->operation(); Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; - if (instr->hydrogen()->representation().IsInteger32()) { + if (instr->hydrogen()->representation().IsSmiOrInteger32()) { Register left_reg = ToRegister(left); Operand right_op = (right->IsRegister() || right->IsConstantOperand()) ? ToOperand(right) diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index d63ba6f359..a485b67db9 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -114,7 +114,8 @@ class LCodeGen BASE_EMBEDDED { DoubleRegister EmitLoadDoubleRegister(LOperand* op, FloatRegister flt_scratch, DoubleRegister dbl_scratch); - int ToInteger32(LConstantOperand* op) const; + int ToRepresentation(LConstantOperand* op, const Representation& r) const; + int32_t ToInteger32(LConstantOperand* op) const; Smi* ToSmi(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const; Operand ToOperand(LOperand* op); diff --git a/src/mips/lithium-gap-resolver-mips.cc b/src/mips/lithium-gap-resolver-mips.cc index 9705e1f41a..771b22862e 100644 --- a/src/mips/lithium-gap-resolver-mips.cc +++ b/src/mips/lithium-gap-resolver-mips.cc @@ -251,10 +251,10 @@ void LGapResolver::EmitMove(int index) { LConstantOperand* constant_source = LConstantOperand::cast(source); if (destination->IsRegister()) { Register dst = cgen_->ToRegister(destination); - if (cgen_->IsSmi(constant_source)) { - __ li(dst, Operand(cgen_->ToSmi(constant_source))); - } else if (cgen_->IsInteger32(constant_source)) { - __ li(dst, Operand(cgen_->ToInteger32(constant_source))); + Representation r = cgen_->IsSmi(constant_source) + ? Representation::Smi() : Representation::Integer32(); + if (cgen_->IsInteger32(constant_source)) { + __ li(dst, Operand(cgen_->ToRepresentation(constant_source, r))); } else { __ LoadObject(dst, cgen_->ToHandle(constant_source)); } @@ -265,11 +265,11 @@ void LGapResolver::EmitMove(int index) { } else { ASSERT(destination->IsStackSlot()); ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. - if (cgen_->IsSmi(constant_source)) { - __ li(kLithiumScratchReg, Operand(cgen_->ToSmi(constant_source))); - } else if (cgen_->IsInteger32(constant_source)) { + Representation r = cgen_->IsSmi(constant_source) + ? Representation::Smi() : Representation::Integer32(); + if (cgen_->IsInteger32(constant_source)) { __ li(kLithiumScratchReg, - Operand(cgen_->ToInteger32(constant_source))); + Operand(cgen_->ToRepresentation(constant_source, r))); } else { __ LoadObject(kLithiumScratchReg, cgen_->ToHandle(constant_source)); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 242e88f759..b03cea44cb 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -783,8 +783,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, op == Token::SUB); HValue* left = instr->left(); HValue* right = instr->right(); - ASSERT(left->representation().IsSmiOrTagged()); - ASSERT(right->representation().IsSmiOrTagged()); + ASSERT(left->representation().IsTagged()); + ASSERT(right->representation().IsTagged()); LOperand* left_operand = UseFixed(left, a1); LOperand* right_operand = UseFixed(right, a0); LArithmeticT* result = @@ -1315,17 +1315,17 @@ LInstruction* LChunkBuilder::DoShl(HShl* instr) { LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { - if (instr->representation().IsInteger32()) { - ASSERT(instr->left()->representation().IsInteger32()); - ASSERT(instr->right()->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); return DefineAsRegister(new(zone()) LBitI(left, right)); } else { - ASSERT(instr->representation().IsSmiOrTagged()); - ASSERT(instr->left()->representation().IsSmiOrTagged()); - ASSERT(instr->right()->representation().IsSmiOrTagged()); + ASSERT(instr->representation().IsTagged()); + ASSERT(instr->left()->representation().IsTagged()); + ASSERT(instr->right()->representation().IsTagged()); LOperand* left = UseFixed(instr->left(), a1); LOperand* right = UseFixed(instr->right(), a0); @@ -1347,7 +1347,9 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { if (instr->representation().IsDouble()) { return DoArithmeticD(Token::DIV, instr); - } else if (instr->representation().IsInteger32()) { + } else if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* dividend = UseRegister(instr->left()); LOperand* divisor = UseRegister(instr->right()); LDivI* div = new(zone()) LDivI(dividend, divisor); @@ -1414,9 +1416,9 @@ LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { LInstruction* LChunkBuilder::DoMod(HMod* instr) { HValue* left = instr->left(); HValue* right = instr->right(); - if (instr->representation().IsInteger32()) { - ASSERT(left->representation().IsInteger32()); - ASSERT(right->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); if (instr->HasPowerOf2Divisor()) { ASSERT(!right->CanBeZero()); LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), @@ -1444,7 +1446,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ? AssignEnvironment(result) : result; } - } else if (instr->representation().IsSmiOrTagged()) { + } else if (instr->representation().IsTagged()) { return DoArithmeticT(Token::MOD, instr); } else { ASSERT(instr->representation().IsDouble()); @@ -1460,9 +1462,9 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { LInstruction* LChunkBuilder::DoMul(HMul* instr) { - if (instr->representation().IsInteger32()) { - ASSERT(instr->left()->representation().IsInteger32()); - ASSERT(instr->right()->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* left; LOperand* right = UseOrConstant(instr->BetterRightOperand()); LOperand* temp = NULL; @@ -1505,9 +1507,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { LInstruction* LChunkBuilder::DoSub(HSub* instr) { - if (instr->representation().IsInteger32()) { - ASSERT(instr->left()->representation().IsInteger32()); - ASSERT(instr->right()->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* left = UseRegisterAtStart(instr->left()); LOperand* right = UseOrConstantAtStart(instr->right()); LSubI* sub = new(zone()) LSubI(left, right); @@ -1534,9 +1536,9 @@ LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { - if (instr->representation().IsInteger32()) { - ASSERT(instr->left()->representation().IsInteger32()); - ASSERT(instr->right()->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LAddI* add = new(zone()) LAddI(left, right); @@ -1557,7 +1559,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { } return DoArithmeticD(Token::ADD, instr); } else { - ASSERT(instr->representation().IsSmiOrTagged()); + ASSERT(instr->representation().IsTagged()); return DoArithmeticT(Token::ADD, instr); } } @@ -1566,9 +1568,9 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { LOperand* left = NULL; LOperand* right = NULL; - if (instr->representation().IsInteger32()) { - ASSERT(instr->left()->representation().IsInteger32()); - ASSERT(instr->right()->representation().IsInteger32()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); left = UseRegisterAtStart(instr->BetterLeftOperand()); right = UseOrConstantAtStart(instr->BetterRightOperand()); } else { @@ -2123,8 +2125,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { - ASSERT(instr->key()->representation().IsInteger32() || - instr->key()->representation().IsSmi()); + ASSERT(instr->key()->representation().IsSmiOrInteger32()); ElementsKind elements_kind = instr->elements_kind(); LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LLoadKeyed* result = NULL;