Commit 61a78e2a authored by palfia@homejinni.com's avatar palfia@homejinni.com

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
parent c12a0774
...@@ -477,9 +477,18 @@ bool LCodeGen::IsSmi(LConstantOperand* op) const { ...@@ -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); HConstant* constant = chunk_->LookupConstant(op);
return constant->Integer32Value(); int32_t value = constant->Integer32Value();
if (r.IsInteger32()) return value;
ASSERT(r.IsSmiOrTagged());
return reinterpret_cast<int32_t>(Smi::FromInt(value));
} }
...@@ -501,7 +510,10 @@ Operand LCodeGen::ToOperand(LOperand* op) { ...@@ -501,7 +510,10 @@ Operand LCodeGen::ToOperand(LOperand* op) {
LConstantOperand* const_op = LConstantOperand::cast(op); LConstantOperand* const_op = LConstantOperand::cast(op);
HConstant* constant = chunk()->LookupConstant(const_op); HConstant* constant = chunk()->LookupConstant(const_op);
Representation r = chunk_->LookupLiteralRepresentation(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()); ASSERT(constant->HasInteger32Value());
return Operand(constant->Integer32Value()); return Operand(constant->Integer32Value());
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
...@@ -1367,7 +1379,9 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1367,7 +1379,9 @@ void LCodeGen::DoMulI(LMulI* instr) {
if (right_op->IsConstantOperand() && !can_overflow) { if (right_op->IsConstantOperand() && !can_overflow) {
// Use optimized code for specific constants. // 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)) { if (bailout_on_minus_zero && (constant < 0)) {
// The case of a null constant will be handled separately. // The case of a null constant will be handled separately.
...@@ -1434,13 +1448,25 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1434,13 +1448,25 @@ void LCodeGen::DoMulI(LMulI* instr) {
if (can_overflow) { if (can_overflow) {
// hi:lo = left * right. // hi:lo = left * right.
__ mult(left, right); if (instr->hydrogen()->representation().IsSmi()) {
__ mfhi(scratch); __ SmiUntag(result, left);
__ mflo(result); __ mult(result, right);
__ mfhi(scratch);
__ mflo(result);
} else {
__ mult(left, right);
__ mfhi(scratch);
__ mflo(result);
}
__ sra(at, result, 31); __ sra(at, result, 31);
DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
} else { } 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) { if (bailout_on_minus_zero) {
...@@ -1803,7 +1829,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { ...@@ -1803,7 +1829,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
LOperand* right = instr->right(); LOperand* right = instr->right();
HMathMinMax::Operation operation = instr->hydrogen()->operation(); HMathMinMax::Operation operation = instr->hydrogen()->operation();
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
if (instr->hydrogen()->representation().IsInteger32()) { if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
Register left_reg = ToRegister(left); Register left_reg = ToRegister(left);
Operand right_op = (right->IsRegister() || right->IsConstantOperand()) Operand right_op = (right->IsRegister() || right->IsConstantOperand())
? ToOperand(right) ? ToOperand(right)
......
...@@ -114,7 +114,8 @@ class LCodeGen BASE_EMBEDDED { ...@@ -114,7 +114,8 @@ class LCodeGen BASE_EMBEDDED {
DoubleRegister EmitLoadDoubleRegister(LOperand* op, DoubleRegister EmitLoadDoubleRegister(LOperand* op,
FloatRegister flt_scratch, FloatRegister flt_scratch,
DoubleRegister dbl_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; Smi* ToSmi(LConstantOperand* op) const;
double ToDouble(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const;
Operand ToOperand(LOperand* op); Operand ToOperand(LOperand* op);
......
...@@ -251,10 +251,10 @@ void LGapResolver::EmitMove(int index) { ...@@ -251,10 +251,10 @@ void LGapResolver::EmitMove(int index) {
LConstantOperand* constant_source = LConstantOperand::cast(source); LConstantOperand* constant_source = LConstantOperand::cast(source);
if (destination->IsRegister()) { if (destination->IsRegister()) {
Register dst = cgen_->ToRegister(destination); Register dst = cgen_->ToRegister(destination);
if (cgen_->IsSmi(constant_source)) { Representation r = cgen_->IsSmi(constant_source)
__ li(dst, Operand(cgen_->ToSmi(constant_source))); ? Representation::Smi() : Representation::Integer32();
} else if (cgen_->IsInteger32(constant_source)) { if (cgen_->IsInteger32(constant_source)) {
__ li(dst, Operand(cgen_->ToInteger32(constant_source))); __ li(dst, Operand(cgen_->ToRepresentation(constant_source, r)));
} else { } else {
__ LoadObject(dst, cgen_->ToHandle(constant_source)); __ LoadObject(dst, cgen_->ToHandle(constant_source));
} }
...@@ -265,11 +265,11 @@ void LGapResolver::EmitMove(int index) { ...@@ -265,11 +265,11 @@ void LGapResolver::EmitMove(int index) {
} else { } else {
ASSERT(destination->IsStackSlot()); ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
if (cgen_->IsSmi(constant_source)) { Representation r = cgen_->IsSmi(constant_source)
__ li(kLithiumScratchReg, Operand(cgen_->ToSmi(constant_source))); ? Representation::Smi() : Representation::Integer32();
} else if (cgen_->IsInteger32(constant_source)) { if (cgen_->IsInteger32(constant_source)) {
__ li(kLithiumScratchReg, __ li(kLithiumScratchReg,
Operand(cgen_->ToInteger32(constant_source))); Operand(cgen_->ToRepresentation(constant_source, r)));
} else { } else {
__ LoadObject(kLithiumScratchReg, __ LoadObject(kLithiumScratchReg,
cgen_->ToHandle(constant_source)); cgen_->ToHandle(constant_source));
......
...@@ -783,8 +783,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, ...@@ -783,8 +783,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
op == Token::SUB); op == Token::SUB);
HValue* left = instr->left(); HValue* left = instr->left();
HValue* right = instr->right(); HValue* right = instr->right();
ASSERT(left->representation().IsSmiOrTagged()); ASSERT(left->representation().IsTagged());
ASSERT(right->representation().IsSmiOrTagged()); ASSERT(right->representation().IsTagged());
LOperand* left_operand = UseFixed(left, a1); LOperand* left_operand = UseFixed(left, a1);
LOperand* right_operand = UseFixed(right, a0); LOperand* right_operand = UseFixed(right, a0);
LArithmeticT* result = LArithmeticT* result =
...@@ -1315,17 +1315,17 @@ LInstruction* LChunkBuilder::DoShl(HShl* instr) { ...@@ -1315,17 +1315,17 @@ LInstruction* LChunkBuilder::DoShl(HShl* instr) {
LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
return DefineAsRegister(new(zone()) LBitI(left, right)); return DefineAsRegister(new(zone()) LBitI(left, right));
} else { } else {
ASSERT(instr->representation().IsSmiOrTagged()); ASSERT(instr->representation().IsTagged());
ASSERT(instr->left()->representation().IsSmiOrTagged()); ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsSmiOrTagged()); ASSERT(instr->right()->representation().IsTagged());
LOperand* left = UseFixed(instr->left(), a1); LOperand* left = UseFixed(instr->left(), a1);
LOperand* right = UseFixed(instr->right(), a0); LOperand* right = UseFixed(instr->right(), a0);
...@@ -1347,7 +1347,9 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ...@@ -1347,7 +1347,9 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
if (instr->representation().IsDouble()) { if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::DIV, instr); 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* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right()); LOperand* divisor = UseRegister(instr->right());
LDivI* div = new(zone()) LDivI(dividend, divisor); LDivI* div = new(zone()) LDivI(dividend, divisor);
...@@ -1414,9 +1416,9 @@ LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { ...@@ -1414,9 +1416,9 @@ LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
LInstruction* LChunkBuilder::DoMod(HMod* instr) { LInstruction* LChunkBuilder::DoMod(HMod* instr) {
HValue* left = instr->left(); HValue* left = instr->left();
HValue* right = instr->right(); HValue* right = instr->right();
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(left->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(right->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) { if (instr->HasPowerOf2Divisor()) {
ASSERT(!right->CanBeZero()); ASSERT(!right->CanBeZero());
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
...@@ -1444,7 +1446,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ...@@ -1444,7 +1446,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
? AssignEnvironment(result) ? AssignEnvironment(result)
: result; : result;
} }
} else if (instr->representation().IsSmiOrTagged()) { } else if (instr->representation().IsTagged()) {
return DoArithmeticT(Token::MOD, instr); return DoArithmeticT(Token::MOD, instr);
} else { } else {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
...@@ -1460,9 +1462,9 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ...@@ -1460,9 +1462,9 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
LInstruction* LChunkBuilder::DoMul(HMul* instr) { LInstruction* LChunkBuilder::DoMul(HMul* instr) {
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left; LOperand* left;
LOperand* right = UseOrConstant(instr->BetterRightOperand()); LOperand* right = UseOrConstant(instr->BetterRightOperand());
LOperand* temp = NULL; LOperand* temp = NULL;
...@@ -1505,9 +1507,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { ...@@ -1505,9 +1507,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
LInstruction* LChunkBuilder::DoSub(HSub* instr) { LInstruction* LChunkBuilder::DoSub(HSub* instr) {
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->left()); LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right()); LOperand* right = UseOrConstantAtStart(instr->right());
LSubI* sub = new(zone()) LSubI(left, right); LSubI* sub = new(zone()) LSubI(left, right);
...@@ -1534,9 +1536,9 @@ LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { ...@@ -1534,9 +1536,9 @@ LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
LAddI* add = new(zone()) LAddI(left, right); LAddI* add = new(zone()) LAddI(left, right);
...@@ -1557,7 +1559,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1557,7 +1559,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} }
return DoArithmeticD(Token::ADD, instr); return DoArithmeticD(Token::ADD, instr);
} else { } else {
ASSERT(instr->representation().IsSmiOrTagged()); ASSERT(instr->representation().IsTagged());
return DoArithmeticT(Token::ADD, instr); return DoArithmeticT(Token::ADD, instr);
} }
} }
...@@ -1566,9 +1568,9 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1566,9 +1568,9 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
LOperand* left = NULL; LOperand* left = NULL;
LOperand* right = NULL; LOperand* right = NULL;
if (instr->representation().IsInteger32()) { if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
left = UseRegisterAtStart(instr->BetterLeftOperand()); left = UseRegisterAtStart(instr->BetterLeftOperand());
right = UseOrConstantAtStart(instr->BetterRightOperand()); right = UseOrConstantAtStart(instr->BetterRightOperand());
} else { } else {
...@@ -2123,8 +2125,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( ...@@ -2123,8 +2125,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsInteger32() || ASSERT(instr->key()->representation().IsSmiOrInteger32());
instr->key()->representation().IsSmi());
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyed* result = NULL; LLoadKeyed* result = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment