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

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

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