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
This commit is contained in:
palfia@homejinni.com 2013-07-25 19:57:10 +00:00
parent c12a0774ea
commit 61a78e2a11
4 changed files with 74 additions and 46 deletions

View File

@ -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<int32_t>(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)

View File

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

View File

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

View File

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