| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index b6244af4129a3349a7df107922128d18706631c9..9b2f7e6c2320b010cf30259b3fd6b038ba4cce0d 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -590,7 +590,7 @@ int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
|
|
| 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();
|
| }
|
|
|
| @@ -607,6 +607,11 @@ bool LCodeGen::IsInteger32(LConstantOperand* op) const {
|
| }
|
|
|
|
|
| +bool LCodeGen::IsSmi(LConstantOperand* op) const {
|
| + return chunk_->LookupLiteralRepresentation(op).IsSmi();
|
| +}
|
| +
|
| +
|
| Operand LCodeGen::ToOperand(LOperand* op) const {
|
| if (op->IsRegister()) return Operand(ToRegister(op));
|
| if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op));
|
| @@ -2101,7 +2106,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| CpuFeatureScope scope(masm(), SSE2);
|
|
|
| Representation r = instr->hydrogen()->value()->representation();
|
| - if (r.IsInteger32()) {
|
| + if (r.IsInteger32() || r.IsSmi()) {
|
| Register reg = ToRegister(instr->value());
|
| __ test(reg, Operand(reg));
|
| EmitBranch(true_block, false_block, not_zero);
|
| @@ -4220,15 +4225,9 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| if (FLAG_track_fields && representation.IsSmi()) {
|
| if (instr->value()->IsConstantOperand()) {
|
| LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| - if (!IsInteger32(operand_value)) {
|
| + if (!IsSmi(operand_value)) {
|
| DeoptimizeIf(no_condition, instr->environment());
|
| }
|
| - } else {
|
| - Register value = ToRegister(instr->value());
|
| - __ SmiTag(value);
|
| - if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
| - DeoptimizeIf(overflow, instr->environment());
|
| - }
|
| }
|
| } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
|
| if (instr->value()->IsConstantOperand()) {
|
| @@ -4293,12 +4292,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
|
|
| if (instr->value()->IsConstantOperand()) {
|
| LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| - if (IsInteger32(operand_value)) {
|
| - // In lithium register preparation, we made sure that the constant integer
|
| - // operand fits into smi range.
|
| - Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
|
| - __ mov(FieldOperand(write_register, offset), Immediate(smi_value));
|
| - } else if (operand_value->IsRegister()) {
|
| + if (operand_value->IsRegister()) {
|
| __ mov(FieldOperand(write_register, offset), ToRegister(operand_value));
|
| } else {
|
| Handle<Object> handle_value = ToHandle(operand_value);
|
| @@ -4769,6 +4763,16 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
| + Register input = ToRegister(instr->value());
|
| + __ SmiTag(input);
|
| + if (!instr->hydrogen()->value()->HasRange() ||
|
| + !instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
| + DeoptimizeIf(overflow, instr->environment());
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
| CpuFeatureScope scope(masm(), SSE2);
|
| LOperand* input = instr->value();
|
| @@ -5621,6 +5625,41 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
|
| + LOperand* input = instr->value();
|
| + ASSERT(input->IsDoubleRegister());
|
| + LOperand* result = instr->result();
|
| + ASSERT(result->IsRegister());
|
| + CpuFeatureScope scope(masm(), SSE2);
|
| +
|
| + XMMRegister input_reg = ToDoubleRegister(input);
|
| + Register result_reg = ToRegister(result);
|
| +
|
| + Label done;
|
| + __ cvttsd2si(result_reg, Operand(input_reg));
|
| + __ cvtsi2sd(xmm0, Operand(result_reg));
|
| + __ ucomisd(xmm0, input_reg);
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + DeoptimizeIf(parity_even, instr->environment()); // NaN.
|
| +
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + // The integer converted back is equal to the original. We
|
| + // only have to test if we got -0 as an input.
|
| + __ test(result_reg, Operand(result_reg));
|
| + __ j(not_zero, &done, Label::kNear);
|
| + __ movmskpd(result_reg, input_reg);
|
| + // Bit 0 contains the sign of the double in input_reg.
|
| + // If input was positive, we are ok and return 0, otherwise
|
| + // deoptimize.
|
| + __ and_(result_reg, 1);
|
| + DeoptimizeIf(not_zero, instr->environment());
|
| + __ bind(&done);
|
| + }
|
| + __ SmiTag(result_reg);
|
| + DeoptimizeIf(overflow, instr->environment());
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
|
| LOperand* input = instr->value();
|
| __ test(ToOperand(input), Immediate(kSmiTagMask));
|
|
|