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

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

Issue 13560007: Remove ARM support for soft float (pre-VFP2) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 8 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/macro-assembler-arm.cc ('k') | src/assembler.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 } 968 }
969 969
970 970
971 // Convert and store int passed in register ival to IEEE 754 single precision 971 // Convert and store int passed in register ival to IEEE 754 single precision
972 // floating point value at memory location (dst + 4 * wordoffset) 972 // floating point value at memory location (dst + 4 * wordoffset)
973 // If VFP3 is available use it for conversion. 973 // If VFP3 is available use it for conversion.
974 static void StoreIntAsFloat(MacroAssembler* masm, 974 static void StoreIntAsFloat(MacroAssembler* masm,
975 Register dst, 975 Register dst,
976 Register wordoffset, 976 Register wordoffset,
977 Register ival, 977 Register ival,
978 Register fval, 978 Register scratch1) {
979 Register scratch1, 979 __ vmov(s0, ival);
980 Register scratch2) { 980 __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
981 if (CpuFeatures::IsSupported(VFP2)) { 981 __ vcvt_f32_s32(s0, s0);
982 CpuFeatureScope scope(masm, VFP2); 982 __ vstr(s0, scratch1, 0);
983 __ vmov(s0, ival);
984 __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
985 __ vcvt_f32_s32(s0, s0);
986 __ vstr(s0, scratch1, 0);
987 } else {
988 Label not_special, done;
989 // Move sign bit from source to destination. This works because the sign
990 // bit in the exponent word of the double has the same position and polarity
991 // as the 2's complement sign bit in a Smi.
992 ASSERT(kBinary32SignMask == 0x80000000u);
993
994 __ and_(fval, ival, Operand(kBinary32SignMask), SetCC);
995 // Negate value if it is negative.
996 __ rsb(ival, ival, Operand::Zero(), LeaveCC, ne);
997
998 // We have -1, 0 or 1, which we treat specially. Register ival contains
999 // absolute value: it is either equal to 1 (special case of -1 and 1),
1000 // greater than 1 (not a special case) or less than 1 (special case of 0).
1001 __ cmp(ival, Operand(1));
1002 __ b(gt, &not_special);
1003
1004 // For 1 or -1 we need to or in the 0 exponent (biased).
1005 static const uint32_t exponent_word_for_1 =
1006 kBinary32ExponentBias << kBinary32ExponentShift;
1007
1008 __ orr(fval, fval, Operand(exponent_word_for_1), LeaveCC, eq);
1009 __ b(&done);
1010
1011 __ bind(&not_special);
1012 // Count leading zeros.
1013 // Gets the wrong answer for 0, but we already checked for that case above.
1014 Register zeros = scratch2;
1015 __ CountLeadingZeros(zeros, ival, scratch1);
1016
1017 // Compute exponent and or it into the exponent register.
1018 __ rsb(scratch1,
1019 zeros,
1020 Operand((kBitsPerInt - 1) + kBinary32ExponentBias));
1021
1022 __ orr(fval,
1023 fval,
1024 Operand(scratch1, LSL, kBinary32ExponentShift));
1025
1026 // Shift up the source chopping the top bit off.
1027 __ add(zeros, zeros, Operand(1));
1028 // This wouldn't work for 1 and -1 as the shift would be 32 which means 0.
1029 __ mov(ival, Operand(ival, LSL, zeros));
1030 // And the top (top 20 bits).
1031 __ orr(fval,
1032 fval,
1033 Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits));
1034
1035 __ bind(&done);
1036 __ str(fval, MemOperand(dst, wordoffset, LSL, 2));
1037 }
1038 } 983 }
1039 984
1040 985
1041 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 986 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1042 __ Jump(code, RelocInfo::CODE_TARGET); 987 __ Jump(code, RelocInfo::CODE_TARGET);
1043 } 988 }
1044 989
1045 990
1046 #undef __ 991 #undef __
1047 #define __ ACCESS_MASM(masm()) 992 #define __ ACCESS_MASM(masm())
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 Handle<JSFunction> function, 2020 Handle<JSFunction> function,
2076 Handle<String> name) { 2021 Handle<String> name) {
2077 // ----------- S t a t e ------------- 2022 // ----------- S t a t e -------------
2078 // -- r2 : function name 2023 // -- r2 : function name
2079 // -- lr : return address 2024 // -- lr : return address
2080 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2025 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2081 // -- ... 2026 // -- ...
2082 // -- sp[argc * 4] : receiver 2027 // -- sp[argc * 4] : receiver
2083 // ----------------------------------- 2028 // -----------------------------------
2084 2029
2085 if (!CpuFeatures::IsSupported(VFP2)) {
2086 return Handle<Code>::null();
2087 }
2088
2089 CpuFeatureScope scope_vfp2(masm(), VFP2);
2090 const int argc = arguments().immediate(); 2030 const int argc = arguments().immediate();
2091 // If the object is not a JSObject or we got an unexpected number of 2031 // If the object is not a JSObject or we got an unexpected number of
2092 // arguments, bail out to the regular call. 2032 // arguments, bail out to the regular call.
2093 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2033 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2094 2034
2095 Label miss, slow; 2035 Label miss, slow;
2096 GenerateNameCheck(name, &miss); 2036 GenerateNameCheck(name, &miss);
2097 2037
2098 if (cell.is_null()) { 2038 if (cell.is_null()) {
2099 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2039 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 3059
3120 // ---------- S t a t e -------------- 3060 // ---------- S t a t e --------------
3121 // -- lr : return address 3061 // -- lr : return address
3122 // -- r0 : key 3062 // -- r0 : key
3123 // -- r1 : receiver 3063 // -- r1 : receiver
3124 // ----------------------------------- 3064 // -----------------------------------
3125 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3065 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3126 } 3066 }
3127 3067
3128 3068
3129 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3130 switch (elements_kind) {
3131 case EXTERNAL_BYTE_ELEMENTS:
3132 case EXTERNAL_SHORT_ELEMENTS:
3133 case EXTERNAL_INT_ELEMENTS:
3134 return true;
3135
3136 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3137 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3138 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3139 case EXTERNAL_PIXEL_ELEMENTS:
3140 return false;
3141
3142 case EXTERNAL_FLOAT_ELEMENTS:
3143 case EXTERNAL_DOUBLE_ELEMENTS:
3144 case FAST_ELEMENTS:
3145 case FAST_SMI_ELEMENTS:
3146 case FAST_DOUBLE_ELEMENTS:
3147 case FAST_HOLEY_ELEMENTS:
3148 case FAST_HOLEY_SMI_ELEMENTS:
3149 case FAST_HOLEY_DOUBLE_ELEMENTS:
3150 case DICTIONARY_ELEMENTS:
3151 case NON_STRICT_ARGUMENTS_ELEMENTS:
3152 UNREACHABLE();
3153 return false;
3154 }
3155 return false;
3156 }
3157
3158
3159 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3069 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3160 Register key, 3070 Register key,
3161 Register scratch0, 3071 Register scratch0,
3162 Register scratch1, 3072 Register scratch1,
3163 DwVfpRegister double_scratch0, 3073 DwVfpRegister double_scratch0,
3164 DwVfpRegister double_scratch1, 3074 DwVfpRegister double_scratch1,
3165 Label* fail) { 3075 Label* fail) {
3166 if (CpuFeatures::IsSupported(VFP2)) { 3076 Label key_ok;
3167 CpuFeatureScope scope(masm, VFP2); 3077 // Check for smi or a smi inside a heap number. We convert the heap
3168 Label key_ok; 3078 // number and check if the conversion is exact and fits into the smi
3169 // Check for smi or a smi inside a heap number. We convert the heap 3079 // range.
3170 // number and check if the conversion is exact and fits into the smi 3080 __ JumpIfSmi(key, &key_ok);
3171 // range. 3081 __ CheckMap(key,
3172 __ JumpIfSmi(key, &key_ok); 3082 scratch0,
3173 __ CheckMap(key, 3083 Heap::kHeapNumberMapRootIndex,
3174 scratch0, 3084 fail,
3175 Heap::kHeapNumberMapRootIndex, 3085 DONT_DO_SMI_CHECK);
3176 fail, 3086 __ sub(ip, key, Operand(kHeapObjectTag));
3177 DONT_DO_SMI_CHECK); 3087 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
3178 __ sub(ip, key, Operand(kHeapObjectTag)); 3088 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1);
3179 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); 3089 __ b(ne, fail);
3180 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1); 3090 __ TrySmiTag(scratch0, fail, scratch1);
3181 __ b(ne, fail); 3091 __ mov(key, scratch0);
3182 __ TrySmiTag(scratch0, fail, scratch1); 3092 __ bind(&key_ok);
3183 __ mov(key, scratch0);
3184 __ bind(&key_ok);
3185 } else {
3186 // Check that the key is a smi.
3187 __ JumpIfNotSmi(key, fail);
3188 }
3189 } 3093 }
3190 3094
3191 3095
3192 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3096 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3193 MacroAssembler* masm, 3097 MacroAssembler* masm,
3194 ElementsKind elements_kind) { 3098 ElementsKind elements_kind) {
3195 // ---------- S t a t e -------------- 3099 // ---------- S t a t e --------------
3196 // -- r0 : value 3100 // -- r0 : value
3197 // -- r1 : key 3101 // -- r1 : key
3198 // -- r2 : receiver 3102 // -- r2 : receiver
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3152 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3249 __ strh(r5, MemOperand(r3, key, LSL, 0)); 3153 __ strh(r5, MemOperand(r3, key, LSL, 0));
3250 break; 3154 break;
3251 case EXTERNAL_INT_ELEMENTS: 3155 case EXTERNAL_INT_ELEMENTS:
3252 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3156 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3253 __ str(r5, MemOperand(r3, key, LSL, 1)); 3157 __ str(r5, MemOperand(r3, key, LSL, 1));
3254 break; 3158 break;
3255 case EXTERNAL_FLOAT_ELEMENTS: 3159 case EXTERNAL_FLOAT_ELEMENTS:
3256 // Perform int-to-float conversion and store to memory. 3160 // Perform int-to-float conversion and store to memory.
3257 __ SmiUntag(r4, key); 3161 __ SmiUntag(r4, key);
3258 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); 3162 StoreIntAsFloat(masm, r3, r4, r5, r7);
3259 break; 3163 break;
3260 case EXTERNAL_DOUBLE_ELEMENTS: 3164 case EXTERNAL_DOUBLE_ELEMENTS:
3261 __ add(r3, r3, Operand(key, LSL, 2)); 3165 __ add(r3, r3, Operand(key, LSL, 2));
3262 // r3: effective address of the double element 3166 // r3: effective address of the double element
3263 FloatingPointHelper::Destination destination; 3167 FloatingPointHelper::Destination destination;
3264 if (CpuFeatures::IsSupported(VFP2)) { 3168 destination = FloatingPointHelper::kVFPRegisters;
3265 destination = FloatingPointHelper::kVFPRegisters;
3266 } else {
3267 destination = FloatingPointHelper::kCoreRegisters;
3268 }
3269 FloatingPointHelper::ConvertIntToDouble( 3169 FloatingPointHelper::ConvertIntToDouble(
3270 masm, r5, destination, 3170 masm, r5, destination,
3271 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent. 3171 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent.
3272 r4, s2); // These are: scratch2, single_scratch. 3172 r4, s2); // These are: scratch2, single_scratch.
3273 if (destination == FloatingPointHelper::kVFPRegisters) { 3173 __ vstr(d0, r3, 0);
3274 CpuFeatureScope scope(masm, VFP2);
3275 __ vstr(d0, r3, 0);
3276 } else {
3277 __ str(r6, MemOperand(r3, 0));
3278 __ str(r7, MemOperand(r3, Register::kSizeInBytes));
3279 }
3280 break; 3174 break;
3281 case FAST_ELEMENTS: 3175 case FAST_ELEMENTS:
3282 case FAST_SMI_ELEMENTS: 3176 case FAST_SMI_ELEMENTS:
3283 case FAST_DOUBLE_ELEMENTS: 3177 case FAST_DOUBLE_ELEMENTS:
3284 case FAST_HOLEY_ELEMENTS: 3178 case FAST_HOLEY_ELEMENTS:
3285 case FAST_HOLEY_SMI_ELEMENTS: 3179 case FAST_HOLEY_SMI_ELEMENTS:
3286 case FAST_HOLEY_DOUBLE_ELEMENTS: 3180 case FAST_HOLEY_DOUBLE_ELEMENTS:
3287 case DICTIONARY_ELEMENTS: 3181 case DICTIONARY_ELEMENTS:
3288 case NON_STRICT_ARGUMENTS_ELEMENTS: 3182 case NON_STRICT_ARGUMENTS_ELEMENTS:
3289 UNREACHABLE(); 3183 UNREACHABLE();
3290 break; 3184 break;
3291 } 3185 }
3292 3186
3293 // Entry registers are intact, r0 holds the value which is the return value. 3187 // Entry registers are intact, r0 holds the value which is the return value.
3294 __ Ret(); 3188 __ Ret();
3295 3189
3296 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { 3190 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3297 // r3: external array. 3191 // r3: external array.
3298 __ bind(&check_heap_number); 3192 __ bind(&check_heap_number);
3299 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); 3193 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
3300 __ b(ne, &slow); 3194 __ b(ne, &slow);
3301 3195
3302 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3196 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3303 3197
3304 // r3: base pointer of external storage. 3198 // r3: base pointer of external storage.
3305 3199
3306 // The WebGL specification leaves the behavior of storing NaN and 3200 // The WebGL specification leaves the behavior of storing NaN and
3307 // +/-Infinity into integer arrays basically undefined. For more 3201 // +/-Infinity into integer arrays basically undefined. For more
3308 // reproducible behavior, convert these to zero. 3202 // reproducible behavior, convert these to zero.
3309 if (CpuFeatures::IsSupported(VFP2)) {
3310 CpuFeatureScope scope(masm, VFP2);
3311 3203
3312 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3204 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3313 // vldr requires offset to be a multiple of 4 so we can not 3205 // vldr requires offset to be a multiple of 4 so we can not
3314 // include -kHeapObjectTag into it. 3206 // include -kHeapObjectTag into it.
3315 __ sub(r5, r0, Operand(kHeapObjectTag)); 3207 __ sub(r5, r0, Operand(kHeapObjectTag));
3316 __ vldr(d0, r5, HeapNumber::kValueOffset); 3208 __ vldr(d0, r5, HeapNumber::kValueOffset);
3317 __ add(r5, r3, Operand(key, LSL, 1)); 3209 __ add(r5, r3, Operand(key, LSL, 1));
3318 __ vcvt_f32_f64(s0, d0); 3210 __ vcvt_f32_f64(s0, d0);
3319 __ vstr(s0, r5, 0); 3211 __ vstr(s0, r5, 0);
3320 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3212 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3321 __ sub(r5, r0, Operand(kHeapObjectTag)); 3213 __ sub(r5, r0, Operand(kHeapObjectTag));
3322 __ vldr(d0, r5, HeapNumber::kValueOffset); 3214 __ vldr(d0, r5, HeapNumber::kValueOffset);
3323 __ add(r5, r3, Operand(key, LSL, 2)); 3215 __ add(r5, r3, Operand(key, LSL, 2));
3324 __ vstr(d0, r5, 0); 3216 __ vstr(d0, r5, 0);
3325 } else { 3217 } else {
3326 // Hoisted load. vldr requires offset to be a multiple of 4 so we can 3218 // Hoisted load. vldr requires offset to be a multiple of 4 so we can
3327 // not include -kHeapObjectTag into it. 3219 // not include -kHeapObjectTag into it.
3328 __ sub(r5, value, Operand(kHeapObjectTag)); 3220 __ sub(r5, value, Operand(kHeapObjectTag));
3329 __ vldr(d0, r5, HeapNumber::kValueOffset); 3221 __ vldr(d0, r5, HeapNumber::kValueOffset);
3330 __ ECMAToInt32VFP(r5, d0, d1, r6, r7, r9); 3222 __ ECMAToInt32(r5, d0, d1, r6, r7, r9);
3331 3223
3332 switch (elements_kind) { 3224 switch (elements_kind) {
3333 case EXTERNAL_BYTE_ELEMENTS: 3225 case EXTERNAL_BYTE_ELEMENTS:
3334 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3226 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3335 __ strb(r5, MemOperand(r3, key, LSR, 1)); 3227 __ strb(r5, MemOperand(r3, key, LSR, 1));
3336 break; 3228 break;
3337 case EXTERNAL_SHORT_ELEMENTS: 3229 case EXTERNAL_SHORT_ELEMENTS:
3338 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3230 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3339 __ strh(r5, MemOperand(r3, key, LSL, 0)); 3231 __ strh(r5, MemOperand(r3, key, LSL, 0));
3340 break; 3232 break;
3341 case EXTERNAL_INT_ELEMENTS: 3233 case EXTERNAL_INT_ELEMENTS:
3342 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3234 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3343 __ str(r5, MemOperand(r3, key, LSL, 1)); 3235 __ str(r5, MemOperand(r3, key, LSL, 1));
3344 break; 3236 break;
3345 case EXTERNAL_PIXEL_ELEMENTS: 3237 case EXTERNAL_PIXEL_ELEMENTS:
3346 case EXTERNAL_FLOAT_ELEMENTS: 3238 case EXTERNAL_FLOAT_ELEMENTS:
3347 case EXTERNAL_DOUBLE_ELEMENTS: 3239 case EXTERNAL_DOUBLE_ELEMENTS:
3348 case FAST_ELEMENTS: 3240 case FAST_ELEMENTS:
3349 case FAST_SMI_ELEMENTS: 3241 case FAST_SMI_ELEMENTS:
3350 case FAST_DOUBLE_ELEMENTS: 3242 case FAST_DOUBLE_ELEMENTS:
3351 case FAST_HOLEY_ELEMENTS: 3243 case FAST_HOLEY_ELEMENTS:
3352 case FAST_HOLEY_SMI_ELEMENTS: 3244 case FAST_HOLEY_SMI_ELEMENTS:
3353 case FAST_HOLEY_DOUBLE_ELEMENTS: 3245 case FAST_HOLEY_DOUBLE_ELEMENTS:
3354 case DICTIONARY_ELEMENTS: 3246 case DICTIONARY_ELEMENTS:
3355 case NON_STRICT_ARGUMENTS_ELEMENTS: 3247 case NON_STRICT_ARGUMENTS_ELEMENTS:
3356 UNREACHABLE(); 3248 UNREACHABLE();
3357 break; 3249 break;
3358 }
3359 }
3360
3361 // Entry registers are intact, r0 holds the value which is the return
3362 // value.
3363 __ Ret();
3364 } else {
3365 // VFP3 is not available do manual conversions.
3366 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3367 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3368
3369 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3370 Label done, nan_or_infinity_or_zero;
3371 static const int kMantissaInHiWordShift =
3372 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3373
3374 static const int kMantissaInLoWordShift =
3375 kBitsPerInt - kMantissaInHiWordShift;
3376
3377 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3378 // and infinities. All these should be converted to 0.
3379 __ mov(r7, Operand(HeapNumber::kExponentMask));
3380 __ and_(r9, r5, Operand(r7), SetCC);
3381 __ b(eq, &nan_or_infinity_or_zero);
3382
3383 __ teq(r9, Operand(r7));
3384 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3385 __ b(eq, &nan_or_infinity_or_zero);
3386
3387 // Rebias exponent.
3388 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3389 __ add(r9,
3390 r9,
3391 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3392
3393 __ cmp(r9, Operand(kBinary32MaxExponent));
3394 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3395 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3396 __ b(gt, &done);
3397
3398 __ cmp(r9, Operand(kBinary32MinExponent));
3399 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3400 __ b(lt, &done);
3401
3402 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3403 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3404 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3405 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3406 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3407
3408 __ bind(&done);
3409 __ str(r5, MemOperand(r3, key, LSL, 1));
3410 // Entry registers are intact, r0 holds the value which is the return
3411 // value.
3412 __ Ret();
3413
3414 __ bind(&nan_or_infinity_or_zero);
3415 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3416 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3417 __ orr(r9, r9, r7);
3418 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
3419 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
3420 __ b(&done);
3421 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3422 __ add(r7, r3, Operand(key, LSL, 2));
3423 // r7: effective address of destination element.
3424 __ str(r6, MemOperand(r7, 0));
3425 __ str(r5, MemOperand(r7, Register::kSizeInBytes));
3426 __ Ret();
3427 } else {
3428 bool is_signed_type = IsElementTypeSigned(elements_kind);
3429 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
3430 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
3431
3432 Label done, sign;
3433
3434 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3435 // and infinities. All these should be converted to 0.
3436 __ mov(r7, Operand(HeapNumber::kExponentMask));
3437 __ and_(r9, r5, Operand(r7), SetCC);
3438 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3439 __ b(eq, &done);
3440
3441 __ teq(r9, Operand(r7));
3442 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3443 __ b(eq, &done);
3444
3445 // Unbias exponent.
3446 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3447 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
3448 // If exponent is negative then result is 0.
3449 __ mov(r5, Operand::Zero(), LeaveCC, mi);
3450 __ b(mi, &done);
3451
3452 // If exponent is too big then result is minimal value.
3453 __ cmp(r9, Operand(meaningfull_bits - 1));
3454 __ mov(r5, Operand(min_value), LeaveCC, ge);
3455 __ b(ge, &done);
3456
3457 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC);
3458 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3459 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3460
3461 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
3462 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
3463 __ b(pl, &sign);
3464
3465 __ rsb(r9, r9, Operand::Zero());
3466 __ mov(r5, Operand(r5, LSL, r9));
3467 __ rsb(r9, r9, Operand(meaningfull_bits));
3468 __ orr(r5, r5, Operand(r6, LSR, r9));
3469
3470 __ bind(&sign);
3471 __ teq(r7, Operand::Zero());
3472 __ rsb(r5, r5, Operand::Zero(), LeaveCC, ne);
3473
3474 __ bind(&done);
3475 switch (elements_kind) {
3476 case EXTERNAL_BYTE_ELEMENTS:
3477 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3478 __ strb(r5, MemOperand(r3, key, LSR, 1));
3479 break;
3480 case EXTERNAL_SHORT_ELEMENTS:
3481 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3482 __ strh(r5, MemOperand(r3, key, LSL, 0));
3483 break;
3484 case EXTERNAL_INT_ELEMENTS:
3485 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3486 __ str(r5, MemOperand(r3, key, LSL, 1));
3487 break;
3488 case EXTERNAL_PIXEL_ELEMENTS:
3489 case EXTERNAL_FLOAT_ELEMENTS:
3490 case EXTERNAL_DOUBLE_ELEMENTS:
3491 case FAST_ELEMENTS:
3492 case FAST_SMI_ELEMENTS:
3493 case FAST_DOUBLE_ELEMENTS:
3494 case FAST_HOLEY_ELEMENTS:
3495 case FAST_HOLEY_SMI_ELEMENTS:
3496 case FAST_HOLEY_DOUBLE_ELEMENTS:
3497 case DICTIONARY_ELEMENTS:
3498 case NON_STRICT_ARGUMENTS_ELEMENTS:
3499 UNREACHABLE();
3500 break;
3501 }
3502 } 3250 }
3503 } 3251 }
3252
3253 // Entry registers are intact, r0 holds the value which is the return
3254 // value.
3255 __ Ret();
3504 } 3256 }
3505 3257
3506 // Slow case, key and receiver still in r0 and r1. 3258 // Slow case, key and receiver still in r0 and r1.
3507 __ bind(&slow); 3259 __ bind(&slow);
3508 __ IncrementCounter( 3260 __ IncrementCounter(
3509 masm->isolate()->counters()->keyed_load_external_array_slow(), 3261 masm->isolate()->counters()->keyed_load_external_array_slow(),
3510 1, r2, r3); 3262 1, r2, r3);
3511 3263
3512 // ---------- S t a t e -------------- 3264 // ---------- S t a t e --------------
3513 // -- lr : return address 3265 // -- lr : return address
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3600 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3849 } 3601 }
3850 } 3602 }
3851 3603
3852 3604
3853 #undef __ 3605 #undef __
3854 3606
3855 } } // namespace v8::internal 3607 } } // namespace v8::internal
3856 3608
3857 #endif // V8_TARGET_ARCH_ARM 3609 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698