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:
parent
c12a0774ea
commit
61a78e2a11
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user