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 |