| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 3736 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3747 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3747 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 
| 3748   ASSERT(ToRegister(instr->result()).is(r0)); | 3748   ASSERT(ToRegister(instr->result()).is(r0)); | 
| 3749   CallKnownFunction(instr->function(), | 3749   CallKnownFunction(instr->function(), | 
| 3750                     instr->arity(), | 3750                     instr->arity(), | 
| 3751                     instr, | 3751                     instr, | 
| 3752                     CALL_AS_METHOD, | 3752                     CALL_AS_METHOD, | 
| 3753                     R1_UNINITIALIZED); | 3753                     R1_UNINITIALIZED); | 
| 3754 } | 3754 } | 
| 3755 | 3755 | 
| 3756 | 3756 | 
| 3757 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 3757 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 
| 3758   Register input = ToRegister(instr->value()); | 3758   Register input = ToRegister(instr->value()); | 
| 3759   Register result = ToRegister(instr->result()); | 3759   Register result = ToRegister(instr->result()); | 
| 3760   Register scratch = scratch0(); | 3760   Register scratch = scratch0(); | 
| 3761 | 3761 | 
| 3762   // Deoptimize if not a heap number. | 3762   // Deoptimize if not a heap number. | 
| 3763   __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 3763   __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 
| 3764   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3764   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| 3765   __ cmp(scratch, Operand(ip)); | 3765   __ cmp(scratch, Operand(ip)); | 
| 3766   DeoptimizeIf(ne, instr->environment()); | 3766   DeoptimizeIf(ne, instr->environment()); | 
| 3767 | 3767 | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3813     __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 3813     __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 
| 3814     __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); | 3814     __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); | 
| 3815 | 3815 | 
| 3816     __ StoreToSafepointRegisterSlot(tmp1, result); | 3816     __ StoreToSafepointRegisterSlot(tmp1, result); | 
| 3817   } | 3817   } | 
| 3818 | 3818 | 
| 3819   __ bind(&done); | 3819   __ bind(&done); | 
| 3820 } | 3820 } | 
| 3821 | 3821 | 
| 3822 | 3822 | 
| 3823 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 3823 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { | 
| 3824   Register input = ToRegister(instr->value()); | 3824   Register input = ToRegister(instr->value()); | 
| 3825   Register result = ToRegister(instr->result()); | 3825   Register result = ToRegister(instr->result()); | 
| 3826   __ cmp(input, Operand::Zero()); | 3826   __ cmp(input, Operand::Zero()); | 
| 3827   __ Move(result, input, pl); | 3827   __ Move(result, input, pl); | 
| 3828   // We can make rsb conditional because the previous cmp instruction | 3828   // We can make rsb conditional because the previous cmp instruction | 
| 3829   // will clear the V (overflow) flag and rsb won't set this flag | 3829   // will clear the V (overflow) flag and rsb won't set this flag | 
| 3830   // if input is positive. | 3830   // if input is positive. | 
| 3831   __ rsb(result, input, Operand::Zero(), SetCC, mi); | 3831   __ rsb(result, input, Operand::Zero(), SetCC, mi); | 
| 3832   // Deoptimize on overflow. | 3832   // Deoptimize on overflow. | 
| 3833   DeoptimizeIf(vs, instr->environment()); | 3833   DeoptimizeIf(vs, instr->environment()); | 
| 3834 } | 3834 } | 
| 3835 | 3835 | 
| 3836 | 3836 | 
| 3837 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3837 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 
| 3838   // Class for deferred case. | 3838   // Class for deferred case. | 
| 3839   class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3839   class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 
| 3840    public: | 3840    public: | 
| 3841     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3841     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 
| 3842                                     LUnaryMathOperation* instr) |  | 
| 3843         : LDeferredCode(codegen), instr_(instr) { } | 3842         : LDeferredCode(codegen), instr_(instr) { } | 
| 3844     virtual void Generate() { | 3843     virtual void Generate() { | 
| 3845       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3844       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 
| 3846     } | 3845     } | 
| 3847     virtual LInstruction* instr() { return instr_; } | 3846     virtual LInstruction* instr() { return instr_; } | 
| 3848    private: | 3847    private: | 
| 3849     LUnaryMathOperation* instr_; | 3848     LMathAbs* instr_; | 
| 3850   }; | 3849   }; | 
| 3851 | 3850 | 
| 3852   Representation r = instr->hydrogen()->value()->representation(); | 3851   Representation r = instr->hydrogen()->value()->representation(); | 
| 3853   if (r.IsDouble()) { | 3852   if (r.IsDouble()) { | 
| 3854     DwVfpRegister input = ToDoubleRegister(instr->value()); | 3853     DwVfpRegister input = ToDoubleRegister(instr->value()); | 
| 3855     DwVfpRegister result = ToDoubleRegister(instr->result()); | 3854     DwVfpRegister result = ToDoubleRegister(instr->result()); | 
| 3856     __ vabs(result, input); | 3855     __ vabs(result, input); | 
| 3857   } else if (r.IsInteger32()) { | 3856   } else if (r.IsInteger32()) { | 
| 3858     EmitIntegerMathAbs(instr); | 3857     EmitIntegerMathAbs(instr); | 
| 3859   } else { | 3858   } else { | 
| 3860     // Representation is tagged. | 3859     // Representation is tagged. | 
| 3861     DeferredMathAbsTaggedHeapNumber* deferred = | 3860     DeferredMathAbsTaggedHeapNumber* deferred = | 
| 3862         new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3861         new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 
| 3863     Register input = ToRegister(instr->value()); | 3862     Register input = ToRegister(instr->value()); | 
| 3864     // Smi check. | 3863     // Smi check. | 
| 3865     __ JumpIfNotSmi(input, deferred->entry()); | 3864     __ JumpIfNotSmi(input, deferred->entry()); | 
| 3866     // If smi, handle it directly. | 3865     // If smi, handle it directly. | 
| 3867     EmitIntegerMathAbs(instr); | 3866     EmitIntegerMathAbs(instr); | 
| 3868     __ bind(deferred->exit()); | 3867     __ bind(deferred->exit()); | 
| 3869   } | 3868   } | 
| 3870 } | 3869 } | 
| 3871 | 3870 | 
| 3872 | 3871 | 
| 3873 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3872 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 
| 3874   DwVfpRegister input = ToDoubleRegister(instr->value()); | 3873   DwVfpRegister input = ToDoubleRegister(instr->value()); | 
| 3875   Register result = ToRegister(instr->result()); | 3874   Register result = ToRegister(instr->result()); | 
| 3876   Register input_high = scratch0(); | 3875   Register input_high = scratch0(); | 
| 3877   Label done, exact; | 3876   Label done, exact; | 
| 3878 | 3877 | 
| 3879   __ vmov(input_high, input.high()); | 3878   __ vmov(input_high, input.high()); | 
| 3880   __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); | 3879   __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); | 
| 3881   DeoptimizeIf(al, instr->environment()); | 3880   DeoptimizeIf(al, instr->environment()); | 
| 3882 | 3881 | 
| 3883   __ bind(&exact); | 3882   __ bind(&exact); | 
| 3884   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3883   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 3885     // Test for -0. | 3884     // Test for -0. | 
| 3886     __ cmp(result, Operand::Zero()); | 3885     __ cmp(result, Operand::Zero()); | 
| 3887     __ b(ne, &done); | 3886     __ b(ne, &done); | 
| 3888     __ cmp(input_high, Operand::Zero()); | 3887     __ cmp(input_high, Operand::Zero()); | 
| 3889     DeoptimizeIf(mi, instr->environment()); | 3888     DeoptimizeIf(mi, instr->environment()); | 
| 3890   } | 3889   } | 
| 3891   __ bind(&done); | 3890   __ bind(&done); | 
| 3892 } | 3891 } | 
| 3893 | 3892 | 
| 3894 | 3893 | 
| 3895 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3894 void LCodeGen::DoMathRound(LMathRound* instr) { | 
| 3896   DwVfpRegister input = ToDoubleRegister(instr->value()); | 3895   DwVfpRegister input = ToDoubleRegister(instr->value()); | 
| 3897   Register result = ToRegister(instr->result()); | 3896   Register result = ToRegister(instr->result()); | 
| 3898   DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3897   DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 
| 3899   DwVfpRegister input_plus_dot_five = double_scratch1; | 3898   DwVfpRegister input_plus_dot_five = double_scratch1; | 
| 3900   Register input_high = scratch0(); | 3899   Register input_high = scratch0(); | 
| 3901   DwVfpRegister dot_five = double_scratch0(); | 3900   DwVfpRegister dot_five = double_scratch0(); | 
| 3902   Label convert, done; | 3901   Label convert, done; | 
| 3903 | 3902 | 
| 3904   __ Vmov(dot_five, 0.5, scratch0()); | 3903   __ Vmov(dot_five, 0.5, scratch0()); | 
| 3905   __ vabs(double_scratch1, input); | 3904   __ vabs(double_scratch1, input); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 3924   __ vadd(input_plus_dot_five, input, dot_five); | 3923   __ vadd(input_plus_dot_five, input, dot_five); | 
| 3925   __ vmov(input_high, input_plus_dot_five.high()); | 3924   __ vmov(input_high, input_plus_dot_five.high()); | 
| 3926   // Reuse dot_five (double_scratch0) as we no longer need this value. | 3925   // Reuse dot_five (double_scratch0) as we no longer need this value. | 
| 3927   __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), | 3926   __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), | 
| 3928                    &done, &done); | 3927                    &done, &done); | 
| 3929   DeoptimizeIf(al, instr->environment()); | 3928   DeoptimizeIf(al, instr->environment()); | 
| 3930   __ bind(&done); | 3929   __ bind(&done); | 
| 3931 } | 3930 } | 
| 3932 | 3931 | 
| 3933 | 3932 | 
| 3934 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3933 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { | 
| 3935   DwVfpRegister input = ToDoubleRegister(instr->value()); | 3934   DwVfpRegister input = ToDoubleRegister(instr->value()); | 
| 3936   DwVfpRegister result = ToDoubleRegister(instr->result()); | 3935   DwVfpRegister result = ToDoubleRegister(instr->result()); | 
| 3937   __ vsqrt(result, input); | 3936   __ vsqrt(result, input); | 
| 3938 } | 3937 } | 
| 3939 | 3938 | 
| 3940 | 3939 | 
| 3941 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 3940 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { | 
| 3942   DwVfpRegister input = ToDoubleRegister(instr->value()); | 3941   DwVfpRegister input = ToDoubleRegister(instr->value()); | 
| 3943   DwVfpRegister result = ToDoubleRegister(instr->result()); | 3942   DwVfpRegister result = ToDoubleRegister(instr->result()); | 
| 3944   DwVfpRegister temp = ToDoubleRegister(instr->temp()); | 3943   DwVfpRegister temp = ToDoubleRegister(instr->temp()); | 
| 3945 | 3944 | 
| 3946   // Note that according to ECMA-262 15.8.2.13: | 3945   // Note that according to ECMA-262 15.8.2.13: | 
| 3947   // Math.pow(-Infinity, 0.5) == Infinity | 3946   // Math.pow(-Infinity, 0.5) == Infinity | 
| 3948   // Math.sqrt(-Infinity) == NaN | 3947   // Math.sqrt(-Infinity) == NaN | 
| 3949   Label done; | 3948   Label done; | 
| 3950   __ vmov(temp, -V8_INFINITY, scratch0()); | 3949   __ vmov(temp, -V8_INFINITY, scratch0()); | 
| 3951   __ VFPCompareAndSetFlags(input, temp); | 3950   __ VFPCompareAndSetFlags(input, temp); | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4076   DwVfpRegister double_scratch2 = double_scratch0(); | 4075   DwVfpRegister double_scratch2 = double_scratch0(); | 
| 4077   Register temp1 = ToRegister(instr->temp1()); | 4076   Register temp1 = ToRegister(instr->temp1()); | 
| 4078   Register temp2 = ToRegister(instr->temp2()); | 4077   Register temp2 = ToRegister(instr->temp2()); | 
| 4079 | 4078 | 
| 4080   MathExpGenerator::EmitMathExp( | 4079   MathExpGenerator::EmitMathExp( | 
| 4081       masm(), input, result, double_scratch1, double_scratch2, | 4080       masm(), input, result, double_scratch1, double_scratch2, | 
| 4082       temp1, temp2, scratch0()); | 4081       temp1, temp2, scratch0()); | 
| 4083 } | 4082 } | 
| 4084 | 4083 | 
| 4085 | 4084 | 
| 4086 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 4085 void LCodeGen::DoMathLog(LMathLog* instr) { | 
| 4087   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 4086   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 
| 4088   TranscendentalCacheStub stub(TranscendentalCache::LOG, | 4087   TranscendentalCacheStub stub(TranscendentalCache::LOG, | 
| 4089                                TranscendentalCacheStub::UNTAGGED); | 4088                                TranscendentalCacheStub::UNTAGGED); | 
| 4090   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4089   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 
| 4091 } | 4090 } | 
| 4092 | 4091 | 
| 4093 | 4092 | 
| 4094 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { | 4093 void LCodeGen::DoMathTan(LMathTan* instr) { | 
| 4095   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 4094   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 
| 4096   TranscendentalCacheStub stub(TranscendentalCache::TAN, | 4095   TranscendentalCacheStub stub(TranscendentalCache::TAN, | 
| 4097                                TranscendentalCacheStub::UNTAGGED); | 4096                                TranscendentalCacheStub::UNTAGGED); | 
| 4098   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4097   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 
| 4099 } | 4098 } | 
| 4100 | 4099 | 
| 4101 | 4100 | 
| 4102 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { | 4101 void LCodeGen::DoMathCos(LMathCos* instr) { | 
| 4103   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 4102   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 
| 4104   TranscendentalCacheStub stub(TranscendentalCache::COS, | 4103   TranscendentalCacheStub stub(TranscendentalCache::COS, | 
| 4105                                TranscendentalCacheStub::UNTAGGED); | 4104                                TranscendentalCacheStub::UNTAGGED); | 
| 4106   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4105   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 
| 4107 } | 4106 } | 
| 4108 | 4107 | 
| 4109 | 4108 | 
| 4110 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { | 4109 void LCodeGen::DoMathSin(LMathSin* instr) { | 
| 4111   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 4110   ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 
| 4112   TranscendentalCacheStub stub(TranscendentalCache::SIN, | 4111   TranscendentalCacheStub stub(TranscendentalCache::SIN, | 
| 4113                                TranscendentalCacheStub::UNTAGGED); | 4112                                TranscendentalCacheStub::UNTAGGED); | 
| 4114   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4113   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 
| 4115 } | 4114 } | 
| 4116 | 4115 | 
| 4117 | 4116 | 
| 4118 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { |  | 
| 4119   switch (instr->op()) { |  | 
| 4120     case kMathAbs: |  | 
| 4121       DoMathAbs(instr); |  | 
| 4122       break; |  | 
| 4123     case kMathFloor: |  | 
| 4124       DoMathFloor(instr); |  | 
| 4125       break; |  | 
| 4126     case kMathRound: |  | 
| 4127       DoMathRound(instr); |  | 
| 4128       break; |  | 
| 4129     case kMathSqrt: |  | 
| 4130       DoMathSqrt(instr); |  | 
| 4131       break; |  | 
| 4132     case kMathPowHalf: |  | 
| 4133       DoMathPowHalf(instr); |  | 
| 4134       break; |  | 
| 4135     case kMathCos: |  | 
| 4136       DoMathCos(instr); |  | 
| 4137       break; |  | 
| 4138     case kMathSin: |  | 
| 4139       DoMathSin(instr); |  | 
| 4140       break; |  | 
| 4141     case kMathTan: |  | 
| 4142       DoMathTan(instr); |  | 
| 4143       break; |  | 
| 4144     case kMathLog: |  | 
| 4145       DoMathLog(instr); |  | 
| 4146       break; |  | 
| 4147     default: |  | 
| 4148       Abort("Unimplemented type of LUnaryMathOperation."); |  | 
| 4149       UNREACHABLE(); |  | 
| 4150   } |  | 
| 4151 } |  | 
| 4152 |  | 
| 4153 |  | 
| 4154 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4117 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 
| 4155   ASSERT(ToRegister(instr->function()).is(r1)); | 4118   ASSERT(ToRegister(instr->function()).is(r1)); | 
| 4156   ASSERT(instr->HasPointerMap()); | 4119   ASSERT(instr->HasPointerMap()); | 
| 4157 | 4120 | 
| 4158   if (instr->known_function().is_null()) { | 4121   if (instr->known_function().is_null()) { | 
| 4159     LPointerMap* pointers = instr->pointer_map(); | 4122     LPointerMap* pointers = instr->pointer_map(); | 
| 4160     RecordPosition(pointers->position()); | 4123     RecordPosition(pointers->position()); | 
| 4161     SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 4124     SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 
| 4162     ParameterCount count(instr->arity()); | 4125     ParameterCount count(instr->arity()); | 
| 4163     __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 4126     __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 
| (...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6042   __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6005   __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 
| 6043   __ ldr(result, FieldMemOperand(scratch, | 6006   __ ldr(result, FieldMemOperand(scratch, | 
| 6044                                  FixedArray::kHeaderSize - kPointerSize)); | 6007                                  FixedArray::kHeaderSize - kPointerSize)); | 
| 6045   __ bind(&done); | 6008   __ bind(&done); | 
| 6046 } | 6009 } | 
| 6047 | 6010 | 
| 6048 | 6011 | 
| 6049 #undef __ | 6012 #undef __ | 
| 6050 | 6013 | 
| 6051 } }  // namespace v8::internal | 6014 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|