| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index 49743fd5218bf86c78e825d67c2ccf1bf9064c38..f7cb241211d32c3bc673ab54c3b7b1ed9133fbb7 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -500,7 +500,7 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
|
|
|
| Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
|
| HConstant* constant = chunk_->LookupConstant(op);
|
| - ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
|
| + ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
|
| return constant->handle();
|
| }
|
|
|
| @@ -510,6 +510,11 @@ bool LCodeGen::IsInteger32(LConstantOperand* op) const {
|
| }
|
|
|
|
|
| +bool LCodeGen::IsSmi(LConstantOperand* op) const {
|
| + return chunk_->LookupLiteralRepresentation(op).IsSmi();
|
| +}
|
| +
|
| +
|
| int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| HConstant* constant = chunk_->LookupConstant(op);
|
| return constant->Integer32Value();
|
| @@ -1837,7 +1842,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
|
| Representation r = instr->hydrogen()->value()->representation();
|
| - if (r.IsInteger32()) {
|
| + if (r.IsInteger32() || r.IsSmi()) {
|
| Register reg = ToRegister(instr->value());
|
| EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
|
| } else if (r.IsDouble()) {
|
| @@ -3898,13 +3903,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
|
|
| Handle<Map> transition = instr->transition();
|
|
|
| - if (FLAG_track_fields && representation.IsSmi()) {
|
| - Register value = ToRegister(instr->value());
|
| - __ SmiTagCheckOverflow(value, value, scratch);
|
| - if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
| - DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
|
| - }
|
| - } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
|
| + if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
|
| Register value = ToRegister(instr->value());
|
| if (!instr->hydrogen()->value()->type().IsHeapObject()) {
|
| __ And(scratch, value, Operand(kSmiTagMask));
|
| @@ -4407,6 +4406,21 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
| + LOperand* input = instr->value();
|
| + ASSERT(input->IsRegister());
|
| + LOperand* output = instr->result();
|
| + ASSERT(output->IsRegister());
|
| + Register scratch = scratch0();
|
| +
|
| + __ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch);
|
| + if (!instr->hydrogen()->value()->HasRange() ||
|
| + !instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
| + DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
| LOperand* input = instr->value();
|
| LOperand* output = instr->result();
|
| @@ -4866,7 +4880,59 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
|
|
| // Deopt if the operation did not succeed (except_flag != 0).
|
| DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
| +
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + Label done;
|
| + __ Branch(&done, ne, result_reg, Operand(zero_reg));
|
| + __ mfc1(scratch1, double_input.high());
|
| + __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
| + DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
| + __ bind(&done);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
|
| + Register result_reg = ToRegister(instr->result());
|
| + Register scratch1 = scratch0();
|
| + Register scratch2 = ToRegister(instr->temp());
|
| + DoubleRegister double_input = ToDoubleRegister(instr->value());
|
| +
|
| + if (instr->truncating()) {
|
| + Register scratch3 = ToRegister(instr->temp2());
|
| + FPURegister single_scratch = double_scratch0().low();
|
| + __ EmitECMATruncate(result_reg,
|
| + double_input,
|
| + single_scratch,
|
| + scratch1,
|
| + scratch2,
|
| + scratch3);
|
| + } else {
|
| + Register except_flag = scratch2;
|
| +
|
| + __ EmitFPUTruncate(kRoundToMinusInf,
|
| + result_reg,
|
| + double_input,
|
| + scratch1,
|
| + double_scratch0(),
|
| + except_flag,
|
| + kCheckForInexactConversion);
|
| +
|
| + // Deopt if the operation did not succeed (except_flag != 0).
|
| + DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
| +
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + Label done;
|
| + __ Branch(&done, ne, result_reg, Operand(zero_reg));
|
| + __ mfc1(scratch1, double_input.high());
|
| + __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
| + DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
| + __ bind(&done);
|
| + }
|
| }
|
| + __ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
|
| + DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg));
|
| }
|
|
|
|
|
|
|