OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 __ test(scratch, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); | 1240 __ test(scratch, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); |
1241 __ j(not_zero, label); | 1241 __ j(not_zero, label); |
1242 } | 1242 } |
1243 | 1243 |
1244 | 1244 |
1245 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 1245 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { |
1246 Label check_unequal_objects; | 1246 Label check_unequal_objects; |
1247 Condition cc = GetCondition(); | 1247 Condition cc = GetCondition(); |
1248 | 1248 |
1249 Label miss; | 1249 Label miss; |
1250 CheckInputType(masm, edx, left_, &miss); | 1250 CheckInputType(masm, edx, left(), &miss); |
1251 CheckInputType(masm, eax, right_, &miss); | 1251 CheckInputType(masm, eax, right(), &miss); |
1252 | 1252 |
1253 // Compare two smis. | 1253 // Compare two smis. |
1254 Label non_smi, smi_done; | 1254 Label non_smi, smi_done; |
1255 __ mov(ecx, edx); | 1255 __ mov(ecx, edx); |
1256 __ or_(ecx, eax); | 1256 __ or_(ecx, eax); |
1257 __ JumpIfNotSmi(ecx, &non_smi, Label::kNear); | 1257 __ JumpIfNotSmi(ecx, &non_smi, Label::kNear); |
1258 __ sub(edx, eax); // Return on the result of the subtraction. | 1258 __ sub(edx, eax); // Return on the result of the subtraction. |
1259 __ j(no_overflow, &smi_done, Label::kNear); | 1259 __ j(no_overflow, &smi_done, Label::kNear); |
1260 __ not_(edx); // Correct sign in case of overflow. edx is never 0 here. | 1260 __ not_(edx); // Correct sign in case of overflow. edx is never 0 here. |
1261 __ bind(&smi_done); | 1261 __ bind(&smi_done); |
(...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3063 } | 3063 } |
3064 | 3064 |
3065 // Tail call into the stub that handles binary operations with allocation | 3065 // Tail call into the stub that handles binary operations with allocation |
3066 // sites. | 3066 // sites. |
3067 BinaryOpWithAllocationSiteStub stub(isolate(), state()); | 3067 BinaryOpWithAllocationSiteStub stub(isolate(), state()); |
3068 __ TailCallStub(&stub); | 3068 __ TailCallStub(&stub); |
3069 } | 3069 } |
3070 | 3070 |
3071 | 3071 |
3072 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 3072 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
3073 DCHECK(state_ == CompareIC::SMI); | 3073 DCHECK(state() == CompareIC::SMI); |
3074 Label miss; | 3074 Label miss; |
3075 __ mov(ecx, edx); | 3075 __ mov(ecx, edx); |
3076 __ or_(ecx, eax); | 3076 __ or_(ecx, eax); |
3077 __ JumpIfNotSmi(ecx, &miss, Label::kNear); | 3077 __ JumpIfNotSmi(ecx, &miss, Label::kNear); |
3078 | 3078 |
3079 if (GetCondition() == equal) { | 3079 if (GetCondition() == equal) { |
3080 // For equality we do not care about the sign of the result. | 3080 // For equality we do not care about the sign of the result. |
3081 __ sub(eax, edx); | 3081 __ sub(eax, edx); |
3082 } else { | 3082 } else { |
3083 Label done; | 3083 Label done; |
3084 __ sub(edx, eax); | 3084 __ sub(edx, eax); |
3085 __ j(no_overflow, &done, Label::kNear); | 3085 __ j(no_overflow, &done, Label::kNear); |
3086 // Correct sign of result in case of overflow. | 3086 // Correct sign of result in case of overflow. |
3087 __ not_(edx); | 3087 __ not_(edx); |
3088 __ bind(&done); | 3088 __ bind(&done); |
3089 __ mov(eax, edx); | 3089 __ mov(eax, edx); |
3090 } | 3090 } |
3091 __ ret(0); | 3091 __ ret(0); |
3092 | 3092 |
3093 __ bind(&miss); | 3093 __ bind(&miss); |
3094 GenerateMiss(masm); | 3094 GenerateMiss(masm); |
3095 } | 3095 } |
3096 | 3096 |
3097 | 3097 |
3098 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { | 3098 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { |
3099 DCHECK(state_ == CompareIC::NUMBER); | 3099 DCHECK(state() == CompareIC::NUMBER); |
3100 | 3100 |
3101 Label generic_stub; | 3101 Label generic_stub; |
3102 Label unordered, maybe_undefined1, maybe_undefined2; | 3102 Label unordered, maybe_undefined1, maybe_undefined2; |
3103 Label miss; | 3103 Label miss; |
3104 | 3104 |
3105 if (left_ == CompareIC::SMI) { | 3105 if (left() == CompareIC::SMI) { |
3106 __ JumpIfNotSmi(edx, &miss); | 3106 __ JumpIfNotSmi(edx, &miss); |
3107 } | 3107 } |
3108 if (right_ == CompareIC::SMI) { | 3108 if (right() == CompareIC::SMI) { |
3109 __ JumpIfNotSmi(eax, &miss); | 3109 __ JumpIfNotSmi(eax, &miss); |
3110 } | 3110 } |
3111 | 3111 |
3112 // Inlining the double comparison and falling back to the general compare | 3112 // Inlining the double comparison and falling back to the general compare |
3113 // stub if NaN is involved or SSE2 or CMOV is unsupported. | 3113 // stub if NaN is involved or SSE2 or CMOV is unsupported. |
3114 __ mov(ecx, edx); | 3114 __ mov(ecx, edx); |
3115 __ and_(ecx, eax); | 3115 __ and_(ecx, eax); |
3116 __ JumpIfSmi(ecx, &generic_stub, Label::kNear); | 3116 __ JumpIfSmi(ecx, &generic_stub, Label::kNear); |
3117 | 3117 |
3118 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 3118 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
3119 isolate()->factory()->heap_number_map()); | 3119 isolate()->factory()->heap_number_map()); |
3120 __ j(not_equal, &maybe_undefined1, Label::kNear); | 3120 __ j(not_equal, &maybe_undefined1, Label::kNear); |
3121 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 3121 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
3122 isolate()->factory()->heap_number_map()); | 3122 isolate()->factory()->heap_number_map()); |
3123 __ j(not_equal, &maybe_undefined2, Label::kNear); | 3123 __ j(not_equal, &maybe_undefined2, Label::kNear); |
3124 | 3124 |
3125 __ bind(&unordered); | 3125 __ bind(&unordered); |
3126 __ bind(&generic_stub); | 3126 __ bind(&generic_stub); |
3127 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC, | 3127 ICCompareStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, |
3128 CompareIC::GENERIC); | 3128 CompareIC::GENERIC); |
3129 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 3129 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
3130 | 3130 |
3131 __ bind(&maybe_undefined1); | 3131 __ bind(&maybe_undefined1); |
3132 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3132 if (Token::IsOrderedRelationalCompareOp(op())) { |
3133 __ cmp(eax, Immediate(isolate()->factory()->undefined_value())); | 3133 __ cmp(eax, Immediate(isolate()->factory()->undefined_value())); |
3134 __ j(not_equal, &miss); | 3134 __ j(not_equal, &miss); |
3135 __ JumpIfSmi(edx, &unordered); | 3135 __ JumpIfSmi(edx, &unordered); |
3136 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); | 3136 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); |
3137 __ j(not_equal, &maybe_undefined2, Label::kNear); | 3137 __ j(not_equal, &maybe_undefined2, Label::kNear); |
3138 __ jmp(&unordered); | 3138 __ jmp(&unordered); |
3139 } | 3139 } |
3140 | 3140 |
3141 __ bind(&maybe_undefined2); | 3141 __ bind(&maybe_undefined2); |
3142 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3142 if (Token::IsOrderedRelationalCompareOp(op())) { |
3143 __ cmp(edx, Immediate(isolate()->factory()->undefined_value())); | 3143 __ cmp(edx, Immediate(isolate()->factory()->undefined_value())); |
3144 __ j(equal, &unordered); | 3144 __ j(equal, &unordered); |
3145 } | 3145 } |
3146 | 3146 |
3147 __ bind(&miss); | 3147 __ bind(&miss); |
3148 GenerateMiss(masm); | 3148 GenerateMiss(masm); |
3149 } | 3149 } |
3150 | 3150 |
3151 | 3151 |
3152 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { | 3152 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { |
3153 DCHECK(state_ == CompareIC::INTERNALIZED_STRING); | 3153 DCHECK(state() == CompareIC::INTERNALIZED_STRING); |
3154 DCHECK(GetCondition() == equal); | 3154 DCHECK(GetCondition() == equal); |
3155 | 3155 |
3156 // Registers containing left and right operands respectively. | 3156 // Registers containing left and right operands respectively. |
3157 Register left = edx; | 3157 Register left = edx; |
3158 Register right = eax; | 3158 Register right = eax; |
3159 Register tmp1 = ecx; | 3159 Register tmp1 = ecx; |
3160 Register tmp2 = ebx; | 3160 Register tmp2 = ebx; |
3161 | 3161 |
3162 // Check that both operands are heap objects. | 3162 // Check that both operands are heap objects. |
3163 Label miss; | 3163 Label miss; |
(...skipping 24 matching lines...) Expand all Loading... |
3188 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); | 3188 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); |
3189 __ bind(&done); | 3189 __ bind(&done); |
3190 __ ret(0); | 3190 __ ret(0); |
3191 | 3191 |
3192 __ bind(&miss); | 3192 __ bind(&miss); |
3193 GenerateMiss(masm); | 3193 GenerateMiss(masm); |
3194 } | 3194 } |
3195 | 3195 |
3196 | 3196 |
3197 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { | 3197 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { |
3198 DCHECK(state_ == CompareIC::UNIQUE_NAME); | 3198 DCHECK(state() == CompareIC::UNIQUE_NAME); |
3199 DCHECK(GetCondition() == equal); | 3199 DCHECK(GetCondition() == equal); |
3200 | 3200 |
3201 // Registers containing left and right operands respectively. | 3201 // Registers containing left and right operands respectively. |
3202 Register left = edx; | 3202 Register left = edx; |
3203 Register right = eax; | 3203 Register right = eax; |
3204 Register tmp1 = ecx; | 3204 Register tmp1 = ecx; |
3205 Register tmp2 = ebx; | 3205 Register tmp2 = ebx; |
3206 | 3206 |
3207 // Check that both operands are heap objects. | 3207 // Check that both operands are heap objects. |
3208 Label miss; | 3208 Label miss; |
(...skipping 24 matching lines...) Expand all Loading... |
3233 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); | 3233 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); |
3234 __ bind(&done); | 3234 __ bind(&done); |
3235 __ ret(0); | 3235 __ ret(0); |
3236 | 3236 |
3237 __ bind(&miss); | 3237 __ bind(&miss); |
3238 GenerateMiss(masm); | 3238 GenerateMiss(masm); |
3239 } | 3239 } |
3240 | 3240 |
3241 | 3241 |
3242 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 3242 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
3243 DCHECK(state_ == CompareIC::STRING); | 3243 DCHECK(state() == CompareIC::STRING); |
3244 Label miss; | 3244 Label miss; |
3245 | 3245 |
3246 bool equality = Token::IsEqualityOp(op_); | 3246 bool equality = Token::IsEqualityOp(op()); |
3247 | 3247 |
3248 // Registers containing left and right operands respectively. | 3248 // Registers containing left and right operands respectively. |
3249 Register left = edx; | 3249 Register left = edx; |
3250 Register right = eax; | 3250 Register right = eax; |
3251 Register tmp1 = ecx; | 3251 Register tmp1 = ecx; |
3252 Register tmp2 = ebx; | 3252 Register tmp2 = ebx; |
3253 Register tmp3 = edi; | 3253 Register tmp3 = edi; |
3254 | 3254 |
3255 // Check that both operands are heap objects. | 3255 // Check that both operands are heap objects. |
3256 __ mov(tmp1, left); | 3256 __ mov(tmp1, left); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3323 } else { | 3323 } else { |
3324 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3324 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3325 } | 3325 } |
3326 | 3326 |
3327 __ bind(&miss); | 3327 __ bind(&miss); |
3328 GenerateMiss(masm); | 3328 GenerateMiss(masm); |
3329 } | 3329 } |
3330 | 3330 |
3331 | 3331 |
3332 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3332 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
3333 DCHECK(state_ == CompareIC::OBJECT); | 3333 DCHECK(state() == CompareIC::OBJECT); |
3334 Label miss; | 3334 Label miss; |
3335 __ mov(ecx, edx); | 3335 __ mov(ecx, edx); |
3336 __ and_(ecx, eax); | 3336 __ and_(ecx, eax); |
3337 __ JumpIfSmi(ecx, &miss, Label::kNear); | 3337 __ JumpIfSmi(ecx, &miss, Label::kNear); |
3338 | 3338 |
3339 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); | 3339 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); |
3340 __ j(not_equal, &miss, Label::kNear); | 3340 __ j(not_equal, &miss, Label::kNear); |
3341 __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); | 3341 __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); |
3342 __ j(not_equal, &miss, Label::kNear); | 3342 __ j(not_equal, &miss, Label::kNear); |
3343 | 3343 |
(...skipping 30 matching lines...) Expand all Loading... |
3374 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 3374 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
3375 { | 3375 { |
3376 // Call the runtime system in a fresh internal frame. | 3376 // Call the runtime system in a fresh internal frame. |
3377 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss), | 3377 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss), |
3378 isolate()); | 3378 isolate()); |
3379 FrameScope scope(masm, StackFrame::INTERNAL); | 3379 FrameScope scope(masm, StackFrame::INTERNAL); |
3380 __ push(edx); // Preserve edx and eax. | 3380 __ push(edx); // Preserve edx and eax. |
3381 __ push(eax); | 3381 __ push(eax); |
3382 __ push(edx); // And also use them as the arguments. | 3382 __ push(edx); // And also use them as the arguments. |
3383 __ push(eax); | 3383 __ push(eax); |
3384 __ push(Immediate(Smi::FromInt(op_))); | 3384 __ push(Immediate(Smi::FromInt(op()))); |
3385 __ CallExternalReference(miss, 3); | 3385 __ CallExternalReference(miss, 3); |
3386 // Compute the entry point of the rewritten stub. | 3386 // Compute the entry point of the rewritten stub. |
3387 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); | 3387 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); |
3388 __ pop(eax); | 3388 __ pop(eax); |
3389 __ pop(edx); | 3389 __ pop(edx); |
3390 } | 3390 } |
3391 | 3391 |
3392 // Do a tail call to the rewritten stub. | 3392 // Do a tail call to the rewritten stub. |
3393 __ jmp(edi); | 3393 __ jmp(edi); |
3394 } | 3394 } |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4421 Operand(ebp, 7 * kPointerSize), | 4421 Operand(ebp, 7 * kPointerSize), |
4422 NULL); | 4422 NULL); |
4423 } | 4423 } |
4424 | 4424 |
4425 | 4425 |
4426 #undef __ | 4426 #undef __ |
4427 | 4427 |
4428 } } // namespace v8::internal | 4428 } } // namespace v8::internal |
4429 | 4429 |
4430 #endif // V8_TARGET_ARCH_X87 | 4430 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |