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

Side by Side Diff: src/arm/stub-cache-arm.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/arm/lithium-codegen-arm.cc ('k') | src/ast.h » ('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 3134 matching lines...) Expand 10 before | Expand all | Expand 10 after
3145 __ Ret(); 3145 __ Ret();
3146 3146
3147 __ bind(&miss); 3147 __ bind(&miss);
3148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3149 3149
3150 // Return the generated code. 3150 // Return the generated code.
3151 return GetCode(NORMAL, NULL); 3151 return GetCode(NORMAL, NULL);
3152 } 3152 }
3153 3153
3154 3154
3155 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
3156 // ----------- S t a t e -------------
3157 // -- lr : return address
3158 // -- r0 : key
3159 // -- r1 : receiver
3160 // -----------------------------------
3161 Label miss;
3162
3163 // Check that the map matches.
3164 __ CheckMap(r1, r2, Handle<Map>(receiver->map()), &miss, false);
3165
3166 GenerateFastPixelArrayLoad(masm(),
3167 r1,
3168 r0,
3169 r2,
3170 r3,
3171 r4,
3172 r5,
3173 r0,
3174 &miss,
3175 &miss,
3176 &miss);
3177
3178 __ bind(&miss);
3179 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
3180 Builtins::KeyedLoadIC_Miss));
3181 __ Jump(ic, RelocInfo::CODE_TARGET);
3182
3183 // Return the generated code.
3184 return GetCode(NORMAL, NULL);
3185 }
3186
3187
3188 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 3155 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
3189 int index, 3156 int index,
3190 Map* transition, 3157 Map* transition,
3191 String* name) { 3158 String* name) {
3192 // ----------- S t a t e ------------- 3159 // ----------- S t a t e -------------
3193 // -- r0 : value 3160 // -- r0 : value
3194 // -- r1 : name 3161 // -- r1 : name
3195 // -- r2 : receiver 3162 // -- r2 : receiver
3196 // -- lr : return address 3163 // -- lr : return address
3197 // ----------------------------------- 3164 // -----------------------------------
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3288 __ bind(&miss); 3255 __ bind(&miss);
3289 Handle<Code> ic( 3256 Handle<Code> ic(
3290 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); 3257 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
3291 __ Jump(ic, RelocInfo::CODE_TARGET); 3258 __ Jump(ic, RelocInfo::CODE_TARGET);
3292 3259
3293 // Return the generated code. 3260 // Return the generated code.
3294 return GetCode(NORMAL, NULL); 3261 return GetCode(NORMAL, NULL);
3295 } 3262 }
3296 3263
3297 3264
3298 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
3299 JSObject* receiver) {
3300 // ----------- S t a t e -------------
3301 // -- r0 : value
3302 // -- r1 : key
3303 // -- r2 : receiver
3304 // -- r3 : scratch
3305 // -- r4 : scratch
3306 // -- r5 : scratch
3307 // -- r6 : scratch
3308 // -- lr : return address
3309 // -----------------------------------
3310 Label miss;
3311
3312 // Check that the map matches.
3313 __ CheckMap(r2, r6, Handle<Map>(receiver->map()), &miss, false);
3314
3315 GenerateFastPixelArrayStore(masm(),
3316 r2,
3317 r1,
3318 r0,
3319 r3,
3320 r4,
3321 r5,
3322 r6,
3323 true,
3324 true,
3325 &miss,
3326 &miss,
3327 NULL,
3328 &miss);
3329
3330 __ bind(&miss);
3331 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
3332 Builtins::KeyedStoreIC_Miss));
3333 __ Jump(ic, RelocInfo::CODE_TARGET);
3334
3335 // Return the generated code.
3336 return GetCode(NORMAL, NULL);
3337 }
3338
3339
3340 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3265 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3341 // ----------- S t a t e ------------- 3266 // ----------- S t a t e -------------
3342 // -- r0 : argc 3267 // -- r0 : argc
3343 // -- r1 : constructor 3268 // -- r1 : constructor
3344 // -- lr : return address 3269 // -- lr : return address
3345 // -- [sp] : last argument 3270 // -- [sp] : last argument
3346 // ----------------------------------- 3271 // -----------------------------------
3347 Label generic_stub_call; 3272 Label generic_stub_call;
3348 3273
3349 // Use r7 for holding undefined which is used in several places below. 3274 // Use r7 for holding undefined which is used in several places below.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
3495 return false; 3420 return false;
3496 3421
3497 default: 3422 default:
3498 UNREACHABLE(); 3423 UNREACHABLE();
3499 return false; 3424 return false;
3500 } 3425 }
3501 } 3426 }
3502 3427
3503 3428
3504 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3429 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3505 ExternalArrayType array_type, Code::Flags flags) { 3430 JSObject* receiver_object,
3431 ExternalArrayType array_type,
3432 Code::Flags flags) {
3506 // ---------- S t a t e -------------- 3433 // ---------- S t a t e --------------
3507 // -- lr : return address 3434 // -- lr : return address
3508 // -- r0 : key 3435 // -- r0 : key
3509 // -- r1 : receiver 3436 // -- r1 : receiver
3510 // ----------------------------------- 3437 // -----------------------------------
3511 Label slow, failed_allocation; 3438 Label slow, failed_allocation;
3512 3439
3513 Register key = r0; 3440 Register key = r0;
3514 Register receiver = r1; 3441 Register receiver = r1;
3515 3442
3516 // Check that the object isn't a smi 3443 // Check that the object isn't a smi
3517 __ JumpIfSmi(receiver, &slow); 3444 __ JumpIfSmi(receiver, &slow);
3518 3445
3519 // Check that the key is a smi. 3446 // Check that the key is a smi.
3520 __ JumpIfNotSmi(key, &slow); 3447 __ JumpIfNotSmi(key, &slow);
3521 3448
3522 // Check that the object is a JS object. Load map into r2. 3449 // Make sure that we've got the right map.
3523 __ CompareObjectType(receiver, r2, r3, FIRST_JS_OBJECT_TYPE); 3450 __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset));
3524 __ b(lt, &slow); 3451 __ cmp(r2, Operand(Handle<Map>(receiver_object->map())));
3525
3526 // Check that the receiver does not require access checks. We need
3527 // to check this explicitly since this generic stub does not perform
3528 // map checks.
3529 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
3530 __ tst(r3, Operand(1 << Map::kIsAccessCheckNeeded));
3531 __ b(ne, &slow); 3452 __ b(ne, &slow);
3532 3453
3533 // Check that the elements array is the appropriate type of
3534 // ExternalArray.
3535 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3454 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3536 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); 3455 // r3: elements array
3537 __ LoadRoot(ip, HEAP->RootIndexForExternalArrayType(array_type));
3538 __ cmp(r2, ip);
3539 __ b(ne, &slow);
3540 3456
3541 // Check that the index is in range. 3457 // Check that the index is in range.
3542 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); 3458 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3543 __ cmp(ip, Operand(key, ASR, kSmiTagSize)); 3459 __ cmp(ip, Operand(key, ASR, kSmiTagSize));
3544 // Unsigned comparison catches both negative and too-large values. 3460 // Unsigned comparison catches both negative and too-large values.
3545 __ b(lo, &slow); 3461 __ b(lo, &slow);
3546 3462
3547 // r3: elements array
3548 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3463 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3549 // r3: base pointer of external storage 3464 // r3: base pointer of external storage
3550 3465
3551 // We are not untagging smi key and instead work with it 3466 // We are not untagging smi key and instead work with it
3552 // as if it was premultiplied by 2. 3467 // as if it was premultiplied by 2.
3553 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); 3468 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
3554 3469
3555 Register value = r2; 3470 Register value = r2;
3556 switch (array_type) { 3471 switch (array_type) {
3557 case kExternalByteArray: 3472 case kExternalByteArray:
3558 __ ldrsb(value, MemOperand(r3, key, LSR, 1)); 3473 __ ldrsb(value, MemOperand(r3, key, LSR, 1));
3559 break; 3474 break;
3475 case kExternalPixelArray:
3560 case kExternalUnsignedByteArray: 3476 case kExternalUnsignedByteArray:
3561 __ ldrb(value, MemOperand(r3, key, LSR, 1)); 3477 __ ldrb(value, MemOperand(r3, key, LSR, 1));
3562 break; 3478 break;
3563 case kExternalShortArray: 3479 case kExternalShortArray:
3564 __ ldrsh(value, MemOperand(r3, key, LSL, 0)); 3480 __ ldrsh(value, MemOperand(r3, key, LSL, 0));
3565 break; 3481 break;
3566 case kExternalUnsignedShortArray: 3482 case kExternalUnsignedShortArray:
3567 __ ldrh(value, MemOperand(r3, key, LSL, 0)); 3483 __ ldrh(value, MemOperand(r3, key, LSL, 0));
3568 break; 3484 break;
3569 case kExternalIntArray: 3485 case kExternalIntArray:
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
3775 3691
3776 __ Push(r1, r0); 3692 __ Push(r1, r0);
3777 3693
3778 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3694 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
3779 3695
3780 return GetCode(flags); 3696 return GetCode(flags);
3781 } 3697 }
3782 3698
3783 3699
3784 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3700 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3785 ExternalArrayType array_type, Code::Flags flags) { 3701 JSObject* receiver_object,
3702 ExternalArrayType array_type,
3703 Code::Flags flags) {
3786 // ---------- S t a t e -------------- 3704 // ---------- S t a t e --------------
3787 // -- r0 : value 3705 // -- r0 : value
3788 // -- r1 : key 3706 // -- r1 : key
3789 // -- r2 : receiver 3707 // -- r2 : receiver
3790 // -- lr : return address 3708 // -- lr : return address
3791 // ----------------------------------- 3709 // -----------------------------------
3792 Label slow, check_heap_number; 3710 Label slow, check_heap_number;
3793 3711
3794 // Register usage. 3712 // Register usage.
3795 Register value = r0; 3713 Register value = r0;
3796 Register key = r1; 3714 Register key = r1;
3797 Register receiver = r2; 3715 Register receiver = r2;
3798 // r3 mostly holds the elements array or the destination external array. 3716 // r3 mostly holds the elements array or the destination external array.
3799 3717
3800 // Check that the object isn't a smi. 3718 // Check that the object isn't a smi.
3801 __ JumpIfSmi(receiver, &slow); 3719 __ JumpIfSmi(receiver, &slow);
3802 3720
3803 // Check that the object is a JS object. Load map into r3. 3721 // Make sure that we've got the right map.
3804 __ CompareObjectType(receiver, r3, r4, FIRST_JS_OBJECT_TYPE); 3722 __ ldr(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
3805 __ b(le, &slow); 3723 __ cmp(r3, Operand(Handle<Map>(receiver_object->map())));
3724 __ b(ne, &slow);
3806 3725
3807 // Check that the receiver does not require access checks. We need 3726 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3808 // to do this because this generic stub does not perform map checks.
3809 __ ldrb(ip, FieldMemOperand(r3, Map::kBitFieldOffset));
3810 __ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded));
3811 __ b(ne, &slow);
3812 3727
3813 // Check that the key is a smi. 3728 // Check that the key is a smi.
3814 __ JumpIfNotSmi(key, &slow); 3729 __ JumpIfNotSmi(key, &slow);
3815 3730
3816 // Check that the elements array is the appropriate type of ExternalArray. 3731 // Check that the index is in range
3817 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3732 __ SmiUntag(r4, key);
3818 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
3819 __ LoadRoot(ip, HEAP->RootIndexForExternalArrayType(array_type));
3820 __ cmp(r4, ip);
3821 __ b(ne, &slow);
3822
3823 // Check that the index is in range.
3824 __ mov(r4, Operand(key, ASR, kSmiTagSize)); // Untag the index.
3825 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); 3733 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3826 __ cmp(r4, ip); 3734 __ cmp(r4, ip);
3827 // Unsigned comparison catches both negative and too-large values. 3735 // Unsigned comparison catches both negative and too-large values.
3828 __ b(hs, &slow); 3736 __ b(hs, &slow);
3829 3737
3830 // Handle both smis and HeapNumbers in the fast path. Go to the 3738 // Handle both smis and HeapNumbers in the fast path. Go to the
3831 // runtime for all other kinds of values. 3739 // runtime for all other kinds of values.
3832 // r3: external array. 3740 // r3: external array.
3833 // r4: key (integer). 3741 // r4: key (integer).
3834 __ JumpIfNotSmi(value, &check_heap_number); 3742 if (array_type == kExternalPixelArray) {
3835 __ mov(r5, Operand(value, ASR, kSmiTagSize)); // Untag the value. 3743 // Double to pixel conversion is only implemented in the runtime for now.
3744 __ JumpIfNotSmi(value, &slow);
3745 } else {
3746 __ JumpIfNotSmi(value, &check_heap_number);
3747 }
3748 __ SmiUntag(r5, value);
3836 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3749 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3837 3750
3838 // r3: base pointer of external storage. 3751 // r3: base pointer of external storage.
3839 // r4: key (integer). 3752 // r4: key (integer).
3840 // r5: value (integer). 3753 // r5: value (integer).
3841 switch (array_type) { 3754 switch (array_type) {
3755 case kExternalPixelArray:
3756 // Clamp the value to [0..255].
3757 __ Usat(r5, 8, Operand(r5));
3758 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3759 break;
3842 case kExternalByteArray: 3760 case kExternalByteArray:
3843 case kExternalUnsignedByteArray: 3761 case kExternalUnsignedByteArray:
3844 __ strb(r5, MemOperand(r3, r4, LSL, 0)); 3762 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3845 break; 3763 break;
3846 case kExternalShortArray: 3764 case kExternalShortArray:
3847 case kExternalUnsignedShortArray: 3765 case kExternalUnsignedShortArray:
3848 __ strh(r5, MemOperand(r3, r4, LSL, 1)); 3766 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3849 break; 3767 break;
3850 case kExternalIntArray: 3768 case kExternalIntArray:
3851 case kExternalUnsignedIntArray: 3769 case kExternalUnsignedIntArray:
3852 __ str(r5, MemOperand(r3, r4, LSL, 2)); 3770 __ str(r5, MemOperand(r3, r4, LSL, 2));
3853 break; 3771 break;
3854 case kExternalFloatArray: 3772 case kExternalFloatArray:
3855 // Perform int-to-float conversion and store to memory. 3773 // Perform int-to-float conversion and store to memory.
3856 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9); 3774 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9);
3857 break; 3775 break;
3858 default: 3776 default:
3859 UNREACHABLE(); 3777 UNREACHABLE();
3860 break; 3778 break;
3861 } 3779 }
3862 3780
3863 // Entry registers are intact, r0 holds the value which is the return value. 3781 // Entry registers are intact, r0 holds the value which is the return value.
3864 __ Ret(); 3782 __ Ret();
3865 3783
3866 3784 if (array_type != kExternalPixelArray) {
3867 // r3: external array. 3785 // r3: external array.
3868 // r4: index (integer). 3786 // r4: index (integer).
3869 __ bind(&check_heap_number); 3787 __ bind(&check_heap_number);
3870 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); 3788 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
3871 __ b(ne, &slow); 3789 __ b(ne, &slow);
3872 3790
3873 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3791 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3874 3792
3875 // r3: base pointer of external storage. 3793 // r3: base pointer of external storage.
3876 // r4: key (integer). 3794 // r4: key (integer).
3877 3795
3878 // The WebGL specification leaves the behavior of storing NaN and 3796 // The WebGL specification leaves the behavior of storing NaN and
3879 // +/-Infinity into integer arrays basically undefined. For more 3797 // +/-Infinity into integer arrays basically undefined. For more
3880 // reproducible behavior, convert these to zero. 3798 // reproducible behavior, convert these to zero.
3881 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 3799 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3882 CpuFeatures::Scope scope(VFP3); 3800 CpuFeatures::Scope scope(VFP3);
3883 3801
3884 3802
3885 if (array_type == kExternalFloatArray) { 3803 if (array_type == kExternalFloatArray) {
3886 // vldr requires offset to be a multiple of 4 so we can not 3804 // vldr requires offset to be a multiple of 4 so we can not
3887 // include -kHeapObjectTag into it. 3805 // include -kHeapObjectTag into it.
3888 __ sub(r5, r0, Operand(kHeapObjectTag)); 3806 __ sub(r5, r0, Operand(kHeapObjectTag));
3889 __ vldr(d0, r5, HeapNumber::kValueOffset); 3807 __ vldr(d0, r5, HeapNumber::kValueOffset);
3890 __ add(r5, r3, Operand(r4, LSL, 2)); 3808 __ add(r5, r3, Operand(r4, LSL, 2));
3891 __ vcvt_f32_f64(s0, d0); 3809 __ vcvt_f32_f64(s0, d0);
3892 __ vstr(s0, r5, 0); 3810 __ vstr(s0, r5, 0);
3893 } else {
3894 // Need to perform float-to-int conversion.
3895 // Test for NaN or infinity (both give zero).
3896 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
3897
3898 // Hoisted load. vldr requires offset to be a multiple of 4 so we can not
3899 // include -kHeapObjectTag into it.
3900 __ sub(r5, value, Operand(kHeapObjectTag));
3901 __ vldr(d0, r5, HeapNumber::kValueOffset);
3902
3903 __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
3904 // NaNs and Infinities have all-one exponents so they sign extend to -1.
3905 __ cmp(r6, Operand(-1));
3906 __ mov(r5, Operand(0), LeaveCC, eq);
3907
3908 // Not infinity or NaN simply convert to int.
3909 if (IsElementTypeSigned(array_type)) {
3910 __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
3911 } else { 3811 } else {
3912 __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne); 3812 // Need to perform float-to-int conversion.
3813 // Test for NaN or infinity (both give zero).
3814 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
3815
3816 // Hoisted load. vldr requires offset to be a multiple of 4 so we can
3817 // not include -kHeapObjectTag into it.
3818 __ sub(r5, value, Operand(kHeapObjectTag));
3819 __ vldr(d0, r5, HeapNumber::kValueOffset);
3820
3821 __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
3822 // NaNs and Infinities have all-one exponents so they sign extend to -1.
3823 __ cmp(r6, Operand(-1));
3824 __ mov(r5, Operand(0), LeaveCC, eq);
3825
3826 // Not infinity or NaN simply convert to int.
3827 if (IsElementTypeSigned(array_type)) {
3828 __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
3829 } else {
3830 __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne);
3831 }
3832 __ vmov(r5, s0, ne);
3833
3834 switch (array_type) {
3835 case kExternalByteArray:
3836 case kExternalUnsignedByteArray:
3837 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3838 break;
3839 case kExternalShortArray:
3840 case kExternalUnsignedShortArray:
3841 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3842 break;
3843 case kExternalIntArray:
3844 case kExternalUnsignedIntArray:
3845 __ str(r5, MemOperand(r3, r4, LSL, 2));
3846 break;
3847 default:
3848 UNREACHABLE();
3849 break;
3850 }
3913 } 3851 }
3914 __ vmov(r5, s0, ne); 3852
3915
3916 switch (array_type) {
3917 case kExternalByteArray:
3918 case kExternalUnsignedByteArray:
3919 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3920 break;
3921 case kExternalShortArray:
3922 case kExternalUnsignedShortArray:
3923 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3924 break;
3925 case kExternalIntArray:
3926 case kExternalUnsignedIntArray:
3927 __ str(r5, MemOperand(r3, r4, LSL, 2));
3928 break;
3929 default:
3930 UNREACHABLE();
3931 break;
3932 }
3933 }
3934
3935 // Entry registers are intact, r0 holds the value which is the return value.
3936 __ Ret();
3937 } else {
3938 // VFP3 is not available do manual conversions.
3939 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3940 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3941
3942 if (array_type == kExternalFloatArray) {
3943 Label done, nan_or_infinity_or_zero;
3944 static const int kMantissaInHiWordShift =
3945 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3946
3947 static const int kMantissaInLoWordShift =
3948 kBitsPerInt - kMantissaInHiWordShift;
3949
3950 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3951 // and infinities. All these should be converted to 0.
3952 __ mov(r7, Operand(HeapNumber::kExponentMask));
3953 __ and_(r9, r5, Operand(r7), SetCC);
3954 __ b(eq, &nan_or_infinity_or_zero);
3955
3956 __ teq(r9, Operand(r7));
3957 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3958 __ b(eq, &nan_or_infinity_or_zero);
3959
3960 // Rebias exponent.
3961 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3962 __ add(r9,
3963 r9,
3964 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3965
3966 __ cmp(r9, Operand(kBinary32MaxExponent));
3967 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3968 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3969 __ b(gt, &done);
3970
3971 __ cmp(r9, Operand(kBinary32MinExponent));
3972 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3973 __ b(lt, &done);
3974
3975 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3976 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3977 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3978 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3979 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3980
3981 __ bind(&done);
3982 __ str(r5, MemOperand(r3, r4, LSL, 2));
3983 // Entry registers are intact, r0 holds the value which is the return 3853 // Entry registers are intact, r0 holds the value which is the return
3984 // value. 3854 // value.
3985 __ Ret(); 3855 __ Ret();
3986
3987 __ bind(&nan_or_infinity_or_zero);
3988 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3989 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3990 __ orr(r9, r9, r7);
3991 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
3992 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
3993 __ b(&done);
3994 } else { 3856 } else {
3995 bool is_signed_type = IsElementTypeSigned(array_type); 3857 // VFP3 is not available do manual conversions.
3996 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; 3858 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3997 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; 3859 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3998 3860
3999 Label done, sign; 3861 if (array_type == kExternalFloatArray) {
4000 3862 Label done, nan_or_infinity_or_zero;
4001 // Test for all special exponent values: zeros, subnormal numbers, NaNs 3863 static const int kMantissaInHiWordShift =
4002 // and infinities. All these should be converted to 0. 3864 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
4003 __ mov(r7, Operand(HeapNumber::kExponentMask)); 3865
4004 __ and_(r9, r5, Operand(r7), SetCC); 3866 static const int kMantissaInLoWordShift =
4005 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq); 3867 kBitsPerInt - kMantissaInHiWordShift;
4006 __ b(eq, &done); 3868
4007 3869 // Test for all special exponent values: zeros, subnormal numbers, NaNs
4008 __ teq(r9, Operand(r7)); 3870 // and infinities. All these should be converted to 0.
4009 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq); 3871 __ mov(r7, Operand(HeapNumber::kExponentMask));
4010 __ b(eq, &done); 3872 __ and_(r9, r5, Operand(r7), SetCC);
4011 3873 __ b(eq, &nan_or_infinity_or_zero);
4012 // Unbias exponent. 3874
4013 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift)); 3875 __ teq(r9, Operand(r7));
4014 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC); 3876 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
4015 // If exponent is negative then result is 0. 3877 __ b(eq, &nan_or_infinity_or_zero);
4016 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, mi); 3878
4017 __ b(mi, &done); 3879 // Rebias exponent.
4018 3880 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
4019 // If exponent is too big then result is minimal value. 3881 __ add(r9,
4020 __ cmp(r9, Operand(meaningfull_bits - 1)); 3882 r9,
4021 __ mov(r5, Operand(min_value), LeaveCC, ge); 3883 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
4022 __ b(ge, &done); 3884
4023 3885 __ cmp(r9, Operand(kBinary32MaxExponent));
4024 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC); 3886 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
4025 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); 3887 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
4026 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord)); 3888 __ b(gt, &done);
4027 3889
4028 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); 3890 __ cmp(r9, Operand(kBinary32MinExponent));
4029 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl); 3891 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
4030 __ b(pl, &sign); 3892 __ b(lt, &done);
4031 3893
4032 __ rsb(r9, r9, Operand(0, RelocInfo::NONE)); 3894 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
4033 __ mov(r5, Operand(r5, LSL, r9)); 3895 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
4034 __ rsb(r9, r9, Operand(meaningfull_bits)); 3896 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
4035 __ orr(r5, r5, Operand(r6, LSR, r9)); 3897 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
4036 3898 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
4037 __ bind(&sign); 3899
4038 __ teq(r7, Operand(0, RelocInfo::NONE)); 3900 __ bind(&done);
4039 __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne); 3901 __ str(r5, MemOperand(r3, r4, LSL, 2));
4040 3902 // Entry registers are intact, r0 holds the value which is the return
4041 __ bind(&done); 3903 // value.
4042 switch (array_type) { 3904 __ Ret();
4043 case kExternalByteArray: 3905
4044 case kExternalUnsignedByteArray: 3906 __ bind(&nan_or_infinity_or_zero);
4045 __ strb(r5, MemOperand(r3, r4, LSL, 0)); 3907 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
4046 break; 3908 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
4047 case kExternalShortArray: 3909 __ orr(r9, r9, r7);
4048 case kExternalUnsignedShortArray: 3910 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
4049 __ strh(r5, MemOperand(r3, r4, LSL, 1)); 3911 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
4050 break; 3912 __ b(&done);
4051 case kExternalIntArray: 3913 } else {
4052 case kExternalUnsignedIntArray: 3914 bool is_signed_type = IsElementTypeSigned(array_type);
4053 __ str(r5, MemOperand(r3, r4, LSL, 2)); 3915 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
4054 break; 3916 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
4055 default: 3917
4056 UNREACHABLE(); 3918 Label done, sign;
4057 break; 3919
3920 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3921 // and infinities. All these should be converted to 0.
3922 __ mov(r7, Operand(HeapNumber::kExponentMask));
3923 __ and_(r9, r5, Operand(r7), SetCC);
3924 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3925 __ b(eq, &done);
3926
3927 __ teq(r9, Operand(r7));
3928 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3929 __ b(eq, &done);
3930
3931 // Unbias exponent.
3932 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3933 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
3934 // If exponent is negative then result is 0.
3935 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, mi);
3936 __ b(mi, &done);
3937
3938 // If exponent is too big then result is minimal value.
3939 __ cmp(r9, Operand(meaningfull_bits - 1));
3940 __ mov(r5, Operand(min_value), LeaveCC, ge);
3941 __ b(ge, &done);
3942
3943 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC);
3944 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3945 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3946
3947 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
3948 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
3949 __ b(pl, &sign);
3950
3951 __ rsb(r9, r9, Operand(0, RelocInfo::NONE));
3952 __ mov(r5, Operand(r5, LSL, r9));
3953 __ rsb(r9, r9, Operand(meaningfull_bits));
3954 __ orr(r5, r5, Operand(r6, LSR, r9));
3955
3956 __ bind(&sign);
3957 __ teq(r7, Operand(0, RelocInfo::NONE));
3958 __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne);
3959
3960 __ bind(&done);
3961 switch (array_type) {
3962 case kExternalByteArray:
3963 case kExternalUnsignedByteArray:
3964 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3965 break;
3966 case kExternalShortArray:
3967 case kExternalUnsignedShortArray:
3968 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3969 break;
3970 case kExternalIntArray:
3971 case kExternalUnsignedIntArray:
3972 __ str(r5, MemOperand(r3, r4, LSL, 2));
3973 break;
3974 default:
3975 UNREACHABLE();
3976 break;
3977 }
4058 } 3978 }
4059 } 3979 }
4060 } 3980 }
4061 3981
4062 // Slow case: call runtime. 3982 // Slow case: call runtime.
4063 __ bind(&slow); 3983 __ bind(&slow);
4064 3984
4065 // Entry registers are intact. 3985 // Entry registers are intact.
4066 // ---------- S t a t e -------------- 3986 // ---------- S t a t e --------------
4067 // -- r0 : value 3987 // -- r0 : value
(...skipping 14 matching lines...) Expand all
4082 4002
4083 return GetCode(flags); 4003 return GetCode(flags);
4084 } 4004 }
4085 4005
4086 4006
4087 #undef __ 4007 #undef __
4088 4008
4089 } } // namespace v8::internal 4009 } } // namespace v8::internal
4090 4010
4091 #endif // V8_TARGET_ARCH_ARM 4011 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698