Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6664001: [Isolates] Merge (7083,7111] from bleeding_edge. (Closed)
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 2706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 __ bind(&miss); 2717 __ bind(&miss);
2718 Handle<Code> ic( 2718 Handle<Code> ic(
2719 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); 2719 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
2720 __ jmp(ic, RelocInfo::CODE_TARGET); 2720 __ jmp(ic, RelocInfo::CODE_TARGET);
2721 2721
2722 // Return the generated code. 2722 // Return the generated code.
2723 return GetCode(NORMAL, NULL); 2723 return GetCode(NORMAL, NULL);
2724 } 2724 }
2725 2725
2726 2726
2727 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
2728 JSObject* receiver) {
2729 // ----------- S t a t e -------------
2730 // -- eax : value
2731 // -- ecx : key
2732 // -- edx : receiver
2733 // -- esp[0] : return address
2734 // -----------------------------------
2735 Label miss;
2736
2737 // Check that the map matches.
2738 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
2739
2740 // Do the load.
2741 GenerateFastPixelArrayStore(masm(),
2742 edx,
2743 ecx,
2744 eax,
2745 edi,
2746 ebx,
2747 true,
2748 &miss,
2749 &miss,
2750 NULL,
2751 &miss);
2752
2753 // Handle store cache miss.
2754 __ bind(&miss);
2755 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2756 Builtins::KeyedStoreIC_Miss));
2757 __ jmp(ic, RelocInfo::CODE_TARGET);
2758
2759 // Return the generated code.
2760 return GetCode(NORMAL, NULL);
2761 }
2762
2763
2764 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2727 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2765 JSObject* object, 2728 JSObject* object,
2766 JSObject* last) { 2729 JSObject* last) {
2767 // ----------- S t a t e ------------- 2730 // ----------- S t a t e -------------
2768 // -- eax : receiver 2731 // -- eax : receiver
2769 // -- ecx : name 2732 // -- ecx : name
2770 // -- esp[0] : return address 2733 // -- esp[0] : return address
2771 // ----------------------------------- 2734 // -----------------------------------
2772 Label miss; 2735 Label miss;
2773 2736
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 __ ret(0); 3163 __ ret(0);
3201 3164
3202 __ bind(&miss); 3165 __ bind(&miss);
3203 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3166 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3204 3167
3205 // Return the generated code. 3168 // Return the generated code.
3206 return GetCode(NORMAL, NULL); 3169 return GetCode(NORMAL, NULL);
3207 } 3170 }
3208 3171
3209 3172
3210 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
3211 // ----------- S t a t e -------------
3212 // -- eax : key
3213 // -- edx : receiver
3214 // -- esp[0] : return address
3215 // -----------------------------------
3216 Label miss;
3217
3218 // Check that the map matches.
3219 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
3220
3221 GenerateFastPixelArrayLoad(masm(),
3222 edx,
3223 eax,
3224 ecx,
3225 ebx,
3226 eax,
3227 &miss,
3228 &miss,
3229 &miss);
3230
3231 // Handle load cache miss.
3232 __ bind(&miss);
3233 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
3234 Builtins::KeyedLoadIC_Miss));
3235 __ jmp(ic, RelocInfo::CODE_TARGET);
3236
3237 // Return the generated code.
3238 return GetCode(NORMAL, NULL);
3239 }
3240
3241
3242 // Specialized stub for constructing objects from functions which only have only 3173 // Specialized stub for constructing objects from functions which only have only
3243 // simple assignments of the form this.x = ...; in their body. 3174 // simple assignments of the form this.x = ...; in their body.
3244 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3175 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3245 // ----------- S t a t e ------------- 3176 // ----------- S t a t e -------------
3246 // -- eax : argc 3177 // -- eax : argc
3247 // -- edi : constructor 3178 // -- edi : constructor
3248 // -- esp[0] : return address 3179 // -- esp[0] : return address
3249 // -- esp[4] : last argument 3180 // -- esp[4] : last argument
3250 // ----------------------------------- 3181 // -----------------------------------
3251 Label generic_stub_call; 3182 Label generic_stub_call;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 Builtins::JSConstructStubGeneric); 3303 Builtins::JSConstructStubGeneric);
3373 Handle<Code> generic_construct_stub(code); 3304 Handle<Code> generic_construct_stub(code);
3374 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3305 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3375 3306
3376 // Return the generated code. 3307 // Return the generated code.
3377 return GetCode(); 3308 return GetCode();
3378 } 3309 }
3379 3310
3380 3311
3381 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3312 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3382 ExternalArrayType array_type, Code::Flags flags) { 3313 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3383 // ----------- S t a t e ------------- 3314 // ----------- S t a t e -------------
3384 // -- eax : key 3315 // -- eax : key
3385 // -- edx : receiver 3316 // -- edx : receiver
3386 // -- esp[0] : return address 3317 // -- esp[0] : return address
3387 // ----------------------------------- 3318 // -----------------------------------
3388 Label slow, failed_allocation; 3319 Label slow, failed_allocation;
3389 3320
3390 // Check that the object isn't a smi. 3321 // Check that the object isn't a smi.
3391 __ test(edx, Immediate(kSmiTagMask)); 3322 __ test(edx, Immediate(kSmiTagMask));
3392 __ j(zero, &slow, not_taken); 3323 __ j(zero, &slow, not_taken);
3393 3324
3394 // Check that the key is a smi. 3325 // Check that the key is a smi.
3395 __ test(eax, Immediate(kSmiTagMask)); 3326 __ test(eax, Immediate(kSmiTagMask));
3396 __ j(not_zero, &slow, not_taken); 3327 __ j(not_zero, &slow, not_taken);
3397 3328
3398 // Get the map of the receiver. 3329 // Check that the map matches.
3399 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3330 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3400 // Check that the receiver does not require access checks. We need
3401 // to check this explicitly since this generic stub does not perform
3402 // map checks.
3403 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
3404 1 << Map::kIsAccessCheckNeeded);
3405 __ j(not_zero, &slow, not_taken);
3406
3407 __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
3408 __ j(not_equal, &slow, not_taken);
3409
3410 // Check that the elements array is the appropriate type of
3411 // ExternalArray.
3412 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3331 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3413 Handle<Map> map(HEAP->MapForExternalArrayType(array_type));
3414 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
3415 Immediate(map));
3416 __ j(not_equal, &slow, not_taken);
3417 3332
3418 // eax: key, known to be a smi. 3333 // eax: key, known to be a smi.
3419 // edx: receiver, known to be a JSObject. 3334 // edx: receiver, known to be a JSObject.
3420 // ebx: elements object, known to be an external array. 3335 // ebx: elements object, known to be an external array.
3421 // Check that the index is in range. 3336 // Check that the index is in range.
3422 __ mov(ecx, eax); 3337 __ mov(ecx, eax);
3423 __ SmiUntag(ecx); // Untag the index. 3338 __ SmiUntag(ecx); // Untag the index.
3424 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3339 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3425 // Unsigned comparison catches both negative and too-large values. 3340 // Unsigned comparison catches both negative and too-large values.
3426 __ j(above_equal, &slow); 3341 __ j(above_equal, &slow);
3427
3428 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3342 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3429 // ebx: base pointer of external storage 3343 // ebx: base pointer of external storage
3430 switch (array_type) { 3344 switch (array_type) {
3431 case kExternalByteArray: 3345 case kExternalByteArray:
3432 __ movsx_b(ecx, Operand(ebx, ecx, times_1, 0)); 3346 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
3433 break; 3347 break;
3434 case kExternalUnsignedByteArray: 3348 case kExternalUnsignedByteArray:
3435 __ movzx_b(ecx, Operand(ebx, ecx, times_1, 0)); 3349 case kExternalPixelArray:
3350 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
3436 break; 3351 break;
3437 case kExternalShortArray: 3352 case kExternalShortArray:
3438 __ movsx_w(ecx, Operand(ebx, ecx, times_2, 0)); 3353 __ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
3439 break; 3354 break;
3440 case kExternalUnsignedShortArray: 3355 case kExternalUnsignedShortArray:
3441 __ movzx_w(ecx, Operand(ebx, ecx, times_2, 0)); 3356 __ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
3442 break; 3357 break;
3443 case kExternalIntArray: 3358 case kExternalIntArray:
3444 case kExternalUnsignedIntArray: 3359 case kExternalUnsignedIntArray:
3445 __ mov(ecx, Operand(ebx, ecx, times_4, 0)); 3360 __ mov(ecx, Operand(ebx, ecx, times_4, 0));
3446 break; 3361 break;
3447 case kExternalFloatArray: 3362 case kExternalFloatArray:
3448 __ fld_s(Operand(ebx, ecx, times_4, 0)); 3363 __ fld_s(Operand(ebx, ecx, times_4, 0));
3449 break; 3364 break;
3450 default: 3365 default:
3451 UNREACHABLE(); 3366 UNREACHABLE();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3506 __ ret(0); 3421 __ ret(0);
3507 } else if (array_type == kExternalFloatArray) { 3422 } else if (array_type == kExternalFloatArray) {
3508 // For the floating-point array type, we need to always allocate a 3423 // For the floating-point array type, we need to always allocate a
3509 // HeapNumber. 3424 // HeapNumber.
3510 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); 3425 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
3511 // Set the value. 3426 // Set the value.
3512 __ mov(eax, ecx); 3427 __ mov(eax, ecx);
3513 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3428 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
3514 __ ret(0); 3429 __ ret(0);
3515 } else { 3430 } else {
3516 __ mov(eax, ecx);
3517 __ SmiTag(eax); 3431 __ SmiTag(eax);
3518 __ ret(0); 3432 __ ret(0);
3519 } 3433 }
3520 3434
3521 // If we fail allocation of the HeapNumber, we still have a value on 3435 // If we fail allocation of the HeapNumber, we still have a value on
3522 // top of the FPU stack. Remove it. 3436 // top of the FPU stack. Remove it.
3523 __ bind(&failed_allocation); 3437 __ bind(&failed_allocation);
3524 __ ffree(); 3438 __ ffree();
3525 __ fincstp(); 3439 __ fincstp();
3526 // Fall through to slow case. 3440 // Fall through to slow case.
(...skipping 14 matching lines...) Expand all
3541 3455
3542 // Perform tail call to the entry. 3456 // Perform tail call to the entry.
3543 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3457 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
3544 3458
3545 // Return the generated code. 3459 // Return the generated code.
3546 return GetCode(flags); 3460 return GetCode(flags);
3547 } 3461 }
3548 3462
3549 3463
3550 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3464 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3551 ExternalArrayType array_type, Code::Flags flags) { 3465 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
3552 // ----------- S t a t e ------------- 3466 // ----------- S t a t e -------------
3553 // -- eax : value 3467 // -- eax : value
3554 // -- ecx : key 3468 // -- ecx : key
3555 // -- edx : receiver 3469 // -- edx : receiver
3556 // -- esp[0] : return address 3470 // -- esp[0] : return address
3557 // ----------------------------------- 3471 // -----------------------------------
3558 Label slow, check_heap_number; 3472 Label slow, check_heap_number;
3559 3473
3560 // Check that the object isn't a smi. 3474 // Check that the object isn't a smi.
3561 __ test(edx, Immediate(kSmiTagMask)); 3475 __ test(edx, Immediate(kSmiTagMask));
3562 __ j(zero, &slow); 3476 __ j(zero, &slow);
3563 // Get the map from the receiver. 3477
3564 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 3478 // Check that the map matches.
3565 // Check that the receiver does not require access checks. We need 3479 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3566 // to do this because this generic stub does not perform map checks. 3480
3567 __ test_b(FieldOperand(edi, Map::kBitFieldOffset),
3568 1 << Map::kIsAccessCheckNeeded);
3569 __ j(not_zero, &slow);
3570 // Check that the key is a smi. 3481 // Check that the key is a smi.
3571 __ test(ecx, Immediate(kSmiTagMask)); 3482 __ test(ecx, Immediate(kSmiTagMask));
3572 __ j(not_zero, &slow); 3483 __ j(not_zero, &slow);
3573 // Get the instance type from the map of the receiver.
3574 __ CmpInstanceType(edi, JS_OBJECT_TYPE);
3575 __ j(not_equal, &slow);
3576
3577 // Check that the elements array is the appropriate type of
3578 // ExternalArray.
3579 // eax: value
3580 // edx: receiver, a JSObject
3581 // ecx: key, a smi
3582 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3583 __ CheckMap(edi, Handle<Map>(HEAP->MapForExternalArrayType(array_type)),
3584 &slow, true);
3585 3484
3586 // Check that the index is in range. 3485 // Check that the index is in range.
3486 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3587 __ mov(ebx, ecx); 3487 __ mov(ebx, ecx);
3588 __ SmiUntag(ebx); 3488 __ SmiUntag(ebx);
3589 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3489 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
3590 // Unsigned comparison catches both negative and too-large values. 3490 // Unsigned comparison catches both negative and too-large values.
3591 __ j(above_equal, &slow); 3491 __ j(above_equal, &slow);
3592 3492
3593 // Handle both smis and HeapNumbers in the fast path. Go to the 3493 // Handle both smis and HeapNumbers in the fast path. Go to the
3594 // runtime for all other kinds of values. 3494 // runtime for all other kinds of values.
3595 // eax: value 3495 // eax: value
3596 // edx: receiver 3496 // edx: receiver
3597 // ecx: key 3497 // ecx: key
3598 // edi: elements array 3498 // edi: elements array
3599 // ebx: untagged index 3499 // ebx: untagged index
3600 __ test(eax, Immediate(kSmiTagMask)); 3500 __ test(eax, Immediate(kSmiTagMask));
3601 __ j(not_equal, &check_heap_number); 3501 if (array_type == kExternalPixelArray)
3502 __ j(not_equal, &slow);
3503 else
3504 __ j(not_equal, &check_heap_number);
3505
3602 // smi case 3506 // smi case
3603 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed. 3507 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
3604 __ SmiUntag(ecx); 3508 __ SmiUntag(ecx);
3605 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3509 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3606 // ecx: base pointer of external storage 3510 // ecx: base pointer of external storage
3607 switch (array_type) { 3511 switch (array_type) {
3512 case kExternalPixelArray:
3513 { // Clamp the value to [0..255].
3514 NearLabel done;
3515 __ test(ecx, Immediate(0xFFFFFF00));
3516 __ j(zero, &done);
3517 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3518 __ dec_b(ecx); // 0 if negative, 255 if positive.
3519 __ bind(&done);
3520 }
3521 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3522 break;
3608 case kExternalByteArray: 3523 case kExternalByteArray:
3609 case kExternalUnsignedByteArray: 3524 case kExternalUnsignedByteArray:
3610 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3525 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3611 break; 3526 break;
3612 case kExternalShortArray: 3527 case kExternalShortArray:
3613 case kExternalUnsignedShortArray: 3528 case kExternalUnsignedShortArray:
3614 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3529 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3615 break; 3530 break;
3616 case kExternalIntArray: 3531 case kExternalIntArray:
3617 case kExternalUnsignedIntArray: 3532 case kExternalUnsignedIntArray:
3618 __ mov(Operand(edi, ebx, times_4, 0), ecx); 3533 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3619 break; 3534 break;
3620 case kExternalFloatArray: 3535 case kExternalFloatArray:
3621 // Need to perform int-to-float conversion. 3536 // Need to perform int-to-float conversion.
3622 __ push(ecx); 3537 __ push(ecx);
3623 __ fild_s(Operand(esp, 0)); 3538 __ fild_s(Operand(esp, 0));
3624 __ pop(ecx); 3539 __ pop(ecx);
3625 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3540 __ fstp_s(Operand(edi, ebx, times_4, 0));
3626 break; 3541 break;
3627 default: 3542 default:
3628 UNREACHABLE(); 3543 UNREACHABLE();
3629 break; 3544 break;
3630 } 3545 }
3631 __ ret(0); // Return the original value. 3546 __ ret(0); // Return the original value.
3632 3547
3633 __ bind(&check_heap_number); 3548 // TODO(danno): handle heap number -> pixel array conversion
3634 // eax: value 3549 if (array_type != kExternalPixelArray) {
3635 // edx: receiver 3550 __ bind(&check_heap_number);
3636 // ecx: key 3551 // eax: value
3637 // edi: elements array 3552 // edx: receiver
3638 // ebx: untagged index 3553 // ecx: key
3639 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3554 // edi: elements array
3640 Immediate(FACTORY->heap_number_map())); 3555 // ebx: untagged index
3641 __ j(not_equal, &slow); 3556 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3557 Immediate(FACTORY->heap_number_map()));
3558 __ j(not_equal, &slow);
3642 3559
3643 // The WebGL specification leaves the behavior of storing NaN and 3560 // The WebGL specification leaves the behavior of storing NaN and
3644 // +/-Infinity into integer arrays basically undefined. For more 3561 // +/-Infinity into integer arrays basically undefined. For more
3645 // reproducible behavior, convert these to zero. 3562 // reproducible behavior, convert these to zero.
3646 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3563 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3647 // ebx: untagged index 3564 // ebx: untagged index
3648 // edi: base pointer of external storage 3565 // edi: base pointer of external storage
3649 if (array_type == kExternalFloatArray) { 3566 if (array_type == kExternalFloatArray) {
3650 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3567 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3651 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3568 __ fstp_s(Operand(edi, ebx, times_4, 0));
3652 __ ret(0); 3569 __ ret(0);
3653 } else { 3570 } else {
3654 // Perform float-to-int conversion with truncation (round-to-zero) 3571 // Perform float-to-int conversion with truncation (round-to-zero)
3655 // behavior. 3572 // behavior.
3656 3573
3657 // For the moment we make the slow call to the runtime on 3574 // For the moment we make the slow call to the runtime on
3658 // processors that don't support SSE2. The code in IntegerConvert 3575 // processors that don't support SSE2. The code in IntegerConvert
3659 // (code-stubs-ia32.cc) is roughly what is needed here though the 3576 // (code-stubs-ia32.cc) is roughly what is needed here though the
3660 // conversion failure case does not need to be handled. 3577 // conversion failure case does not need to be handled.
3661 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 3578 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) {
3662 if (array_type != kExternalIntArray && 3579 if (array_type != kExternalIntArray &&
3663 array_type != kExternalUnsignedIntArray) { 3580 array_type != kExternalUnsignedIntArray) {
3664 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3665 CpuFeatures::Scope scope(SSE2);
3666 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3667 // ecx: untagged integer value
3668 switch (array_type) {
3669 case kExternalByteArray:
3670 case kExternalUnsignedByteArray:
3671 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3672 break;
3673 case kExternalShortArray:
3674 case kExternalUnsignedShortArray:
3675 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3676 break;
3677 default:
3678 UNREACHABLE();
3679 break;
3680 }
3681 } else {
3682 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
3683 CpuFeatures::Scope scope(SSE3);
3684 // fisttp stores values as signed integers. To represent the
3685 // entire range of int and unsigned int arrays, store as a
3686 // 64-bit int and discard the high 32 bits.
3687 // If the value is NaN or +/-infinity, the result is 0x80000000,
3688 // which is automatically zero when taken mod 2^n, n < 32.
3689 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3690 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3691 __ fisttp_d(Operand(esp, 0));
3692 __ pop(ecx);
3693 __ add(Operand(esp), Immediate(kPointerSize));
3694 } else {
3695 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2)); 3581 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3696 CpuFeatures::Scope scope(SSE2); 3582 CpuFeatures::Scope scope(SSE2);
3697 // We can easily implement the correct rounding behavior for the 3583 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3698 // range [0, 2^31-1]. For the time being, to keep this code simple, 3584 // ecx: untagged integer value
3699 // make the slow runtime call for values outside this range. 3585 switch (array_type) {
3700 // Note: we could do better for signed int arrays. 3586 case kExternalPixelArray:
3701 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3587 { // Clamp the value to [0..255].
3702 // We will need the key if we have to make the slow runtime call. 3588 NearLabel done;
3703 __ push(ecx); 3589 __ test(ecx, Immediate(0xFFFFFF00));
3704 __ LoadPowerOf2(xmm1, ecx, 31); 3590 __ j(zero, &done);
3705 __ pop(ecx); 3591 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3706 __ ucomisd(xmm1, xmm0); 3592 __ dec_b(ecx); // 0 if negative, 255 if positive.
3707 __ j(above_equal, &slow); 3593 __ bind(&done);
3708 __ cvttsd2si(ecx, Operand(xmm0)); 3594 }
3595 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3596 case kExternalByteArray:
3597 case kExternalUnsignedByteArray:
3598 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3599 break;
3600 case kExternalShortArray:
3601 case kExternalUnsignedShortArray:
3602 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3603 break;
3604 default:
3605 UNREACHABLE();
3606 break;
3607 }
3608 } else {
3609 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
3610 CpuFeatures::Scope scope(SSE3);
3611 // fisttp stores values as signed integers. To represent the
3612 // entire range of int and unsigned int arrays, store as a
3613 // 64-bit int and discard the high 32 bits.
3614 // If the value is NaN or +/-infinity, the result is 0x80000000,
3615 // which is automatically zero when taken mod 2^n, n < 32.
3616 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3617 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3618 __ fisttp_d(Operand(esp, 0));
3619 __ pop(ecx);
3620 __ add(Operand(esp), Immediate(kPointerSize));
3621 } else {
3622 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3623 CpuFeatures::Scope scope(SSE2);
3624 // We can easily implement the correct rounding behavior for the
3625 // range [0, 2^31-1]. For the time being, to keep this code simple,
3626 // make the slow runtime call for values outside this range.
3627 // Note: we could do better for signed int arrays.
3628 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3629 // We will need the key if we have to make the slow runtime call.
3630 __ push(ecx);
3631 __ LoadPowerOf2(xmm1, ecx, 31);
3632 __ pop(ecx);
3633 __ ucomisd(xmm1, xmm0);
3634 __ j(above_equal, &slow);
3635 __ cvttsd2si(ecx, Operand(xmm0));
3636 }
3637 // ecx: untagged integer value
3638 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3709 } 3639 }
3710 // ecx: untagged integer value 3640 __ ret(0); // Return original value.
3711 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3712 } 3641 }
3713 __ ret(0); // Return original value.
3714 } 3642 }
3715 } 3643 }
3716 3644
3717 // Slow case: call runtime. 3645 // Slow case: call runtime.
3718 __ bind(&slow); 3646 __ bind(&slow);
3719 // ----------- S t a t e ------------- 3647 // ----------- S t a t e -------------
3720 // -- eax : value 3648 // -- eax : value
3721 // -- ecx : key 3649 // -- ecx : key
3722 // -- edx : receiver 3650 // -- edx : receiver
3723 // -- esp[0] : return address 3651 // -- esp[0] : return address
(...skipping 13 matching lines...) Expand all
3737 3665
3738 return GetCode(flags); 3666 return GetCode(flags);
3739 } 3667 }
3740 3668
3741 3669
3742 #undef __ 3670 #undef __
3743 3671
3744 } } // namespace v8::internal 3672 } } // namespace v8::internal
3745 3673
3746 #endif // V8_TARGET_ARCH_IA32 3674 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698