| 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 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3009 MathPowStub stub(MathPowStub::INTEGER); | 3009 MathPowStub stub(MathPowStub::INTEGER); |
| 3010 __ CallStub(&stub); | 3010 __ CallStub(&stub); |
| 3011 } else { | 3011 } else { |
| 3012 ASSERT(exponent_type.IsDouble()); | 3012 ASSERT(exponent_type.IsDouble()); |
| 3013 MathPowStub stub(MathPowStub::DOUBLE); | 3013 MathPowStub stub(MathPowStub::DOUBLE); |
| 3014 __ CallStub(&stub); | 3014 __ CallStub(&stub); |
| 3015 } | 3015 } |
| 3016 } | 3016 } |
| 3017 | 3017 |
| 3018 | 3018 |
| 3019 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 3020 Label return_left, return_right; |
| 3021 bool is_min = instr->IsMin(); |
| 3022 bool can_be_minus_zero = instr->hydrogen()->range()->CanBeMinusZero(); |
| 3023 if (instr->TempAt(0) == NULL) { |
| 3024 // Integer32 case |
| 3025 Register left = ToRegister(instr->InputAt(0)); |
| 3026 Register right = ToRegister(instr->InputAt(1)); |
| 3027 Register result = ToRegister(instr->result()); |
| 3028 ASSERT(left.is(result)); |
| 3029 __ cmp(left, right); |
| 3030 __ j(is_min ? less : greater, &return_left, Label::kNear); |
| 3031 __ j(is_min ? greater : less, &return_right, Label::kNear); |
| 3032 if (can_be_minus_zero) { |
| 3033 // Both are equal, check whether we are comparing zeros. |
| 3034 __ test(result, result); |
| 3035 __ j(not_zero, &return_left, Label::kNear); |
| 3036 // Deoptimize to check for minus zero. |
| 3037 DeoptimizeIf(no_condition, instr->environment()); |
| 3038 } |
| 3039 __ bind(&return_right); |
| 3040 __ mov(result, right); |
| 3041 __ bind(&return_left); |
| 3042 return; |
| 3043 } |
| 3044 |
| 3045 // Tagged or unpacked double. |
| 3046 bool tagged = !instr->result()->IsDoubleRegister(); |
| 3047 Label return_nan, bailout, both_smi; |
| 3048 DoubleRegister leftxmm, rightxmm, tempxmm ; |
| 3049 Register left, right; |
| 3050 Register temp = ToRegister(instr->TempAt(0)); |
| 3051 if (tagged) { |
| 3052 left = ToRegister(instr->InputAt(0)); |
| 3053 right = ToRegister(instr->InputAt(1)); |
| 3054 leftxmm = ToDoubleRegister(instr->TempAt(1)); |
| 3055 rightxmm = ToDoubleRegister(instr->TempAt(2)); |
| 3056 tempxmm = rightxmm; |
| 3057 Label left_smi, right_not_smi, left_prepared, right_prepared; |
| 3058 |
| 3059 __ JumpIfSmi(left, &left_smi, Label::kNear); |
| 3060 __ cmp(FieldOperand(left, HeapObject::kMapOffset), |
| 3061 masm()->isolate()->factory()->heap_number_map()); |
| 3062 __ j(not_equal, &bailout); |
| 3063 __ movdbl(leftxmm, FieldOperand(left, HeapNumber::kValueOffset)); |
| 3064 __ jmp(&left_prepared, Label::kNear); |
| 3065 |
| 3066 __ bind(&left_smi); |
| 3067 __ JumpIfSmi(right, &both_smi); |
| 3068 __ SmiUntag(left); |
| 3069 __ cvtsi2sd(leftxmm, left); |
| 3070 __ SmiTag(left); |
| 3071 __ jmp(&right_not_smi, Label::kNear); |
| 3072 __ bind(&left_prepared); |
| 3073 |
| 3074 __ JumpIfNotSmi(right, &right_not_smi, Label::kNear); |
| 3075 __ SmiUntag(right); |
| 3076 __ cvtsi2sd(rightxmm, right); |
| 3077 __ SmiTag(right); |
| 3078 __ jmp(&right_prepared, Label::kNear); |
| 3079 |
| 3080 __ bind(&right_not_smi); |
| 3081 __ cmp(FieldOperand(right, HeapObject::kMapOffset), |
| 3082 masm()->isolate()->factory()->heap_number_map()); |
| 3083 __ j(not_equal, &bailout); |
| 3084 __ movdbl(rightxmm, FieldOperand(right, HeapNumber::kValueOffset)); |
| 3085 __ bind(&right_prepared); |
| 3086 } else { |
| 3087 leftxmm = ToDoubleRegister(instr->InputAt(0)); |
| 3088 rightxmm = ToDoubleRegister(instr->InputAt(1)); |
| 3089 tempxmm = ToDoubleRegister(instr->TempAt(1)); |
| 3090 } |
| 3091 |
| 3092 // Compare doubles. |
| 3093 __ ucomisd(leftxmm, rightxmm); |
| 3094 __ j(is_min ? below : above, &return_left); |
| 3095 __ j(is_min ? above : below, &return_right); |
| 3096 if (can_be_minus_zero) { |
| 3097 __ j(carry, &return_nan); |
| 3098 __ xorpd(tempxmm, tempxmm); |
| 3099 __ ucomisd(leftxmm, tempxmm); |
| 3100 __ j(not_equal, &return_left); |
| 3101 __ movmskpd(temp, leftxmm); |
| 3102 __ test(temp, Immediate(1)); |
| 3103 __ j(is_min ? zero : not_zero, &return_right); |
| 3104 __ jmp(&return_left); |
| 3105 __ bind(&return_nan); |
| 3106 } else { |
| 3107 __ j(not_carry, &return_left); |
| 3108 } |
| 3109 |
| 3110 if (tagged) { |
| 3111 Register result = ToRegister(instr->result()); |
| 3112 ASSERT(left.is(result)); |
| 3113 // Return NaN. |
| 3114 __ mov(result, masm()->isolate()->factory()->nan_value()); |
| 3115 __ jmp(&return_left); |
| 3116 |
| 3117 __ bind(&bailout); |
| 3118 DeoptimizeIf(no_condition, instr->environment()); |
| 3119 |
| 3120 // Both smi. Neither can be minus zero. |
| 3121 __ bind(&both_smi); |
| 3122 __ cmp(left, right); |
| 3123 __ j(is_min ? less : greater, &return_left, Label::kNear); |
| 3124 __ bind(&return_right); |
| 3125 __ mov(result, right); |
| 3126 __ bind(&return_left); |
| 3127 } else { |
| 3128 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3129 ASSERT(leftxmm.is(result)); |
| 3130 // Return NaN. |
| 3131 __ xorps(result, result); |
| 3132 __ divsd(result, result); |
| 3133 __ jmp(&return_left, Label::kNear); |
| 3134 |
| 3135 __ bind(&return_right); |
| 3136 __ movsd(result, rightxmm); |
| 3137 __ bind(&return_left); |
| 3138 } |
| 3139 } |
| 3140 |
| 3141 |
| 3019 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 3142 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { |
| 3020 ASSERT(instr->value()->Equals(instr->result())); | 3143 ASSERT(instr->value()->Equals(instr->result())); |
| 3021 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3144 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3022 Label positive, done, zero; | 3145 Label positive, done, zero; |
| 3023 __ xorps(xmm0, xmm0); | 3146 __ xorps(xmm0, xmm0); |
| 3024 __ ucomisd(input_reg, xmm0); | 3147 __ ucomisd(input_reg, xmm0); |
| 3025 __ j(above, &positive, Label::kNear); | 3148 __ j(above, &positive, Label::kNear); |
| 3026 __ j(equal, &zero, Label::kNear); | 3149 __ j(equal, &zero, Label::kNear); |
| 3027 ExternalReference nan = | 3150 ExternalReference nan = |
| 3028 ExternalReference::address_of_canonical_non_hole_nan(); | 3151 ExternalReference::address_of_canonical_non_hole_nan(); |
| (...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4612 this, pointers, Safepoint::kLazyDeopt); | 4735 this, pointers, Safepoint::kLazyDeopt); |
| 4613 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4736 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
| 4614 } | 4737 } |
| 4615 | 4738 |
| 4616 | 4739 |
| 4617 #undef __ | 4740 #undef __ |
| 4618 | 4741 |
| 4619 } } // namespace v8::internal | 4742 } } // namespace v8::internal |
| 4620 | 4743 |
| 4621 #endif // V8_TARGET_ARCH_IA32 | 4744 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |