| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2938 XMMRegister xmm_scratch = xmm0; | 2938 XMMRegister xmm_scratch = xmm0; |
| 2939 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 2939 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 2940 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); | 2940 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| 2941 __ xorps(xmm_scratch, xmm_scratch); | 2941 __ xorps(xmm_scratch, xmm_scratch); |
| 2942 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. | 2942 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. |
| 2943 __ sqrtsd(input_reg, input_reg); | 2943 __ sqrtsd(input_reg, input_reg); |
| 2944 } | 2944 } |
| 2945 | 2945 |
| 2946 | 2946 |
| 2947 void LCodeGen::DoPower(LPower* instr) { | 2947 void LCodeGen::DoPower(LPower* instr) { |
| 2948 LOperand* left = instr->InputAt(0); | |
| 2949 LOperand* right = instr->InputAt(1); | |
| 2950 DoubleRegister result_reg = ToDoubleRegister(instr->result()); | |
| 2951 Representation exponent_type = instr->hydrogen()->right()->representation(); | 2948 Representation exponent_type = instr->hydrogen()->right()->representation(); |
| 2949 // Having marked this as a call, we can use any registers. |
| 2950 // Just make sure that the input registers are the expected ones. |
| 2951 ASSERT(!instr->InputAt(1)->IsDoubleRegister() || |
| 2952 ToDoubleRegister(instr->InputAt(1)).is(xmm2)); |
| 2953 ASSERT(!instr->InputAt(1)->IsRegister() || |
| 2954 ToRegister(instr->InputAt(1)).is(eax)); |
| 2955 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm1)); |
| 2956 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); |
| 2952 | 2957 |
| 2953 if (exponent_type.IsDouble()) { | 2958 if (exponent_type.IsTagged()) { |
| 2954 // It is safe to use ebx directly since the instruction is marked | 2959 Label no_deopt; |
| 2955 // as a call. | 2960 __ JumpIfSmi(eax, &no_deopt); |
| 2956 __ PrepareCallCFunction(4, ebx); | 2961 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); |
| 2957 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | 2962 DeoptimizeIf(not_equal, instr->environment()); |
| 2958 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); | 2963 __ bind(&no_deopt); |
| 2959 __ CallCFunction(ExternalReference::power_double_double_function(isolate()), | 2964 MathPowStub stub(MathPowStub::TAGGED); |
| 2960 4); | 2965 __ CallStub(&stub); |
| 2961 } else if (exponent_type.IsInteger32()) { | 2966 } else if (exponent_type.IsInteger32()) { |
| 2962 // It is safe to use ebx directly since the instruction is marked | 2967 MathPowStub stub(MathPowStub::INTEGER); |
| 2963 // as a call. | 2968 __ CallStub(&stub); |
| 2964 ASSERT(!ToRegister(right).is(ebx)); | |
| 2965 __ PrepareCallCFunction(4, ebx); | |
| 2966 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | |
| 2967 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); | |
| 2968 __ CallCFunction(ExternalReference::power_double_int_function(isolate()), | |
| 2969 4); | |
| 2970 } else { | 2969 } else { |
| 2971 ASSERT(exponent_type.IsTagged()); | 2970 ASSERT(exponent_type.IsDouble()); |
| 2972 CpuFeatures::Scope scope(SSE2); | 2971 MathPowStub stub(MathPowStub::DOUBLE); |
| 2973 Register right_reg = ToRegister(right); | 2972 __ CallStub(&stub); |
| 2974 | |
| 2975 Label non_smi, call; | |
| 2976 __ JumpIfNotSmi(right_reg, &non_smi); | |
| 2977 __ SmiUntag(right_reg); | |
| 2978 __ cvtsi2sd(result_reg, Operand(right_reg)); | |
| 2979 __ jmp(&call); | |
| 2980 | |
| 2981 __ bind(&non_smi); | |
| 2982 // It is safe to use ebx directly since the instruction is marked | |
| 2983 // as a call. | |
| 2984 ASSERT(!right_reg.is(ebx)); | |
| 2985 __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx); | |
| 2986 DeoptimizeIf(not_equal, instr->environment()); | |
| 2987 __ movdbl(result_reg, FieldOperand(right_reg, HeapNumber::kValueOffset)); | |
| 2988 | |
| 2989 __ bind(&call); | |
| 2990 __ PrepareCallCFunction(4, ebx); | |
| 2991 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | |
| 2992 __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg); | |
| 2993 __ CallCFunction(ExternalReference::power_double_double_function(isolate()), | |
| 2994 4); | |
| 2995 } | 2973 } |
| 2996 | |
| 2997 // Return value is in st(0) on ia32. | |
| 2998 // Store it into the (fixed) result register. | |
| 2999 __ sub(Operand(esp), Immediate(kDoubleSize)); | |
| 3000 __ fstp_d(Operand(esp, 0)); | |
| 3001 __ movdbl(result_reg, Operand(esp, 0)); | |
| 3002 __ add(Operand(esp), Immediate(kDoubleSize)); | |
| 3003 } | 2974 } |
| 3004 | 2975 |
| 3005 | 2976 |
| 3006 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 2977 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { |
| 3007 ASSERT(instr->value()->Equals(instr->result())); | 2978 ASSERT(instr->value()->Equals(instr->result())); |
| 3008 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 2979 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3009 Label positive, done, zero; | 2980 Label positive, done, zero; |
| 3010 __ xorps(xmm0, xmm0); | 2981 __ xorps(xmm0, xmm0); |
| 3011 __ ucomisd(input_reg, xmm0); | 2982 __ ucomisd(input_reg, xmm0); |
| 3012 __ j(above, &positive, Label::kNear); | 2983 __ j(above, &positive, Label::kNear); |
| (...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4631 this, pointers, Safepoint::kLazyDeopt); | 4602 this, pointers, Safepoint::kLazyDeopt); |
| 4632 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4603 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
| 4633 } | 4604 } |
| 4634 | 4605 |
| 4635 | 4606 |
| 4636 #undef __ | 4607 #undef __ |
| 4637 | 4608 |
| 4638 } } // namespace v8::internal | 4609 } } // namespace v8::internal |
| 4639 | 4610 |
| 4640 #endif // V8_TARGET_ARCH_IA32 | 4611 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |