| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index bcb90ca802677f0420aa5f0956f7292a5daa09fe..6f35ec18b1265c77478688d0c04a6614fbdf3d69 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -5317,6 +5317,87 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoDeferredTaggedToSmi(LTaggedToSmi* instr, Label* done) {
|
| + Register input_reg = ToRegister(instr->value());
|
| +
|
| + if (instr->truncating()) {
|
| + Label no_heap_number, check_bools, check_false;
|
| +
|
| + // Heap number map check.
|
| + __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| + factory()->heap_number_map());
|
| + __ j(not_equal, &no_heap_number, Label::kNear);
|
| + __ TruncateHeapNumberToI(input_reg, input_reg);
|
| + __ SmiTag(input_reg);
|
| + DeoptimizeIf(overflow, instr->environment());
|
| + __ jmp(done);
|
| +
|
| + __ bind(&no_heap_number);
|
| + // Check for Oddballs. Undefined/False is converted to zero and True to one
|
| + // for truncating conversions.
|
| + __ cmp(input_reg, factory()->undefined_value());
|
| + __ j(not_equal, &check_bools, Label::kNear);
|
| + __ Set(input_reg, Immediate(0));
|
| + __ jmp(done);
|
| +
|
| + __ bind(&check_bools);
|
| + __ cmp(input_reg, factory()->true_value());
|
| + __ j(not_equal, &check_false, Label::kNear);
|
| + __ Set(input_reg, Immediate(2));
|
| + __ jmp(done);
|
| +
|
| + __ bind(&check_false);
|
| + __ cmp(input_reg, factory()->false_value());
|
| + __ RecordComment("Deferred TaggedToI: cannot truncate");
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + __ Set(input_reg, Immediate(0));
|
| + __ jmp(done);
|
| + } else {
|
| + Label bailout;
|
| + XMMRegister scratch = (instr->temp() != NULL)
|
| + ? ToDoubleRegister(instr->temp())
|
| + : no_xmm_reg;
|
| + __ TaggedToI(input_reg, input_reg, scratch,
|
| + instr->hydrogen()->GetMinusZeroMode(), &bailout);
|
| + __ SmiTag(input_reg);
|
| + DeoptimizeIf(overflow, instr->environment());
|
| + __ jmp(done);
|
| + __ bind(&bailout);
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + }
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoTaggedToSmi(LTaggedToSmi* instr) {
|
| + class DeferredTaggedToSmi V8_FINAL : public LDeferredCode {
|
| + public:
|
| + DeferredTaggedToSmi(LCodeGen* codegen,
|
| + LTaggedToSmi* instr,
|
| + const X87Stack& x87_stack)
|
| + : LDeferredCode(codegen, x87_stack), instr_(instr) { }
|
| + virtual void Generate() V8_OVERRIDE {
|
| + codegen()->DoDeferredTaggedToSmi(instr_, done());
|
| + }
|
| + virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
|
| + private:
|
| + LTaggedToSmi* instr_;
|
| + };
|
| +
|
| + LOperand* input = instr->value();
|
| + ASSERT(input->IsRegister());
|
| + Register input_reg = ToRegister(input);
|
| + ASSERT(input_reg.is(ToRegister(instr->result())));
|
| +
|
| + if (!instr->hydrogen()->value()->representation().IsSmi()) {
|
| + DeferredTaggedToSmi* deferred =
|
| + new(zone()) DeferredTaggedToSmi(this, instr, x87_stack_);
|
| +
|
| + __ JumpIfNotSmi(input_reg, deferred->entry());
|
| + __ bind(deferred->exit());
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
|
| LOperand* input = instr->value();
|
| ASSERT(input->IsRegister());
|
| @@ -5402,23 +5483,35 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
|
| ASSERT(result->IsRegister());
|
| Register result_reg = ToRegister(result);
|
|
|
| - Label bailout, done;
|
| - if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
|
| - CpuFeatureScope scope(masm(), SSE2);
|
| - XMMRegister input_reg = ToDoubleRegister(input);
|
| - XMMRegister xmm_scratch = double_scratch0();
|
| - __ DoubleToI(result_reg, input_reg, xmm_scratch,
|
| - instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
|
| + if (instr->truncating()) {
|
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
|
| + CpuFeatureScope scope(masm(), SSE2);
|
| + XMMRegister input_reg = ToDoubleRegister(input);
|
| + __ TruncateDoubleToI(result_reg, input_reg);
|
| + } else {
|
| + X87Register input_reg = ToX87Register(input);
|
| + X87Fxch(input_reg);
|
| + __ TruncateX87TOSToI(result_reg);
|
| + }
|
| } else {
|
| - X87Register input_reg = ToX87Register(input);
|
| - X87Fxch(input_reg);
|
| - __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
|
| - &bailout, Label::kNear);
|
| + Label bailout, done;
|
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
|
| + CpuFeatureScope scope(masm(), SSE2);
|
| + XMMRegister input_reg = ToDoubleRegister(input);
|
| + XMMRegister xmm_scratch = double_scratch0();
|
| + __ DoubleToI(result_reg, input_reg, xmm_scratch,
|
| + instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
|
| + } else {
|
| + X87Register input_reg = ToX87Register(input);
|
| + X87Fxch(input_reg);
|
| + __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
|
| + &bailout, Label::kNear);
|
| + }
|
| + __ jmp(&done, Label::kNear);
|
| + __ bind(&bailout);
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + __ bind(&done);
|
| }
|
| - __ jmp(&done, Label::kNear);
|
| - __ bind(&bailout);
|
| - DeoptimizeIf(no_condition, instr->environment());
|
| - __ bind(&done);
|
|
|
| __ SmiTag(result_reg);
|
| DeoptimizeIf(overflow, instr->environment());
|
|
|