| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2565 __ bind(&miss); | 2565 __ bind(&miss); |
| 2566 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2566 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2567 Builtins::KeyedStoreIC_Miss)); | 2567 Builtins::KeyedStoreIC_Miss)); |
| 2568 __ jmp(ic, RelocInfo::CODE_TARGET); | 2568 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2569 | 2569 |
| 2570 // Return the generated code. | 2570 // Return the generated code. |
| 2571 return GetCode(NORMAL, NULL); | 2571 return GetCode(NORMAL, NULL); |
| 2572 } | 2572 } |
| 2573 | 2573 |
| 2574 | 2574 |
| 2575 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray( | |
| 2576 JSObject* receiver) { | |
| 2577 // ----------- S t a t e ------------- | |
| 2578 // -- rax : value | |
| 2579 // -- rcx : key | |
| 2580 // -- rdx : receiver | |
| 2581 // -- rsp[0] : return address | |
| 2582 // ----------------------------------- | |
| 2583 Label miss; | |
| 2584 | |
| 2585 // Check that the map matches. | |
| 2586 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false); | |
| 2587 | |
| 2588 // Do the load. | |
| 2589 GenerateFastPixelArrayStore(masm(), | |
| 2590 rdx, | |
| 2591 rcx, | |
| 2592 rax, | |
| 2593 rdi, | |
| 2594 rbx, | |
| 2595 true, | |
| 2596 false, | |
| 2597 &miss, | |
| 2598 &miss, | |
| 2599 NULL, | |
| 2600 &miss); | |
| 2601 | |
| 2602 // Handle store cache miss. | |
| 2603 __ bind(&miss); | |
| 2604 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | |
| 2605 Builtins::KeyedStoreIC_Miss)); | |
| 2606 __ jmp(ic, RelocInfo::CODE_TARGET); | |
| 2607 | |
| 2608 // Return the generated code. | |
| 2609 return GetCode(NORMAL, NULL); | |
| 2610 } | |
| 2611 | |
| 2612 | |
| 2613 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2575 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
| 2614 JSObject* object, | 2576 JSObject* object, |
| 2615 JSObject* last) { | 2577 JSObject* last) { |
| 2616 // ----------- S t a t e ------------- | 2578 // ----------- S t a t e ------------- |
| 2617 // -- rax : receiver | 2579 // -- rax : receiver |
| 2618 // -- rcx : name | 2580 // -- rcx : name |
| 2619 // -- rsp[0] : return address | 2581 // -- rsp[0] : return address |
| 2620 // ----------------------------------- | 2582 // ----------------------------------- |
| 2621 Label miss; | 2583 Label miss; |
| 2622 | 2584 |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3042 __ ret(0); | 3004 __ ret(0); |
| 3043 | 3005 |
| 3044 __ bind(&miss); | 3006 __ bind(&miss); |
| 3045 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3007 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3046 | 3008 |
| 3047 // Return the generated code. | 3009 // Return the generated code. |
| 3048 return GetCode(NORMAL, NULL); | 3010 return GetCode(NORMAL, NULL); |
| 3049 } | 3011 } |
| 3050 | 3012 |
| 3051 | 3013 |
| 3052 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) { | |
| 3053 // ----------- S t a t e ------------- | |
| 3054 // -- rax : key | |
| 3055 // -- rdx : receiver | |
| 3056 // -- esp[0] : return address | |
| 3057 // ----------------------------------- | |
| 3058 Label miss; | |
| 3059 | |
| 3060 // Check that the map matches. | |
| 3061 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false); | |
| 3062 | |
| 3063 GenerateFastPixelArrayLoad(masm(), | |
| 3064 rdx, | |
| 3065 rax, | |
| 3066 rbx, | |
| 3067 rcx, | |
| 3068 rax, | |
| 3069 &miss, | |
| 3070 &miss, | |
| 3071 &miss); | |
| 3072 | |
| 3073 __ bind(&miss); | |
| 3074 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | |
| 3075 | |
| 3076 // Return the generated code. | |
| 3077 return GetCode(NORMAL, NULL); | |
| 3078 } | |
| 3079 | |
| 3080 | |
| 3081 // Specialized stub for constructing objects from functions which only have only | 3014 // Specialized stub for constructing objects from functions which only have only |
| 3082 // simple assignments of the form this.x = ...; in their body. | 3015 // simple assignments of the form this.x = ...; in their body. |
| 3083 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3016 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
| 3084 // ----------- S t a t e ------------- | 3017 // ----------- S t a t e ------------- |
| 3085 // -- rax : argc | 3018 // -- rax : argc |
| 3086 // -- rdi : constructor | 3019 // -- rdi : constructor |
| 3087 // -- rsp[0] : return address | 3020 // -- rsp[0] : return address |
| 3088 // -- rsp[4] : last argument | 3021 // -- rsp[4] : last argument |
| 3089 // ----------------------------------- | 3022 // ----------------------------------- |
| 3090 Label generic_stub_call; | 3023 Label generic_stub_call; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3204 Builtins::JSConstructStubGeneric); | 3137 Builtins::JSConstructStubGeneric); |
| 3205 Handle<Code> generic_construct_stub(code); | 3138 Handle<Code> generic_construct_stub(code); |
| 3206 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3139 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 3207 | 3140 |
| 3208 // Return the generated code. | 3141 // Return the generated code. |
| 3209 return GetCode(); | 3142 return GetCode(); |
| 3210 } | 3143 } |
| 3211 | 3144 |
| 3212 | 3145 |
| 3213 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( | 3146 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| 3214 ExternalArrayType array_type, Code::Flags flags) { | 3147 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { |
| 3215 // ----------- S t a t e ------------- | 3148 // ----------- S t a t e ------------- |
| 3216 // -- rax : key | 3149 // -- rax : key |
| 3217 // -- rdx : receiver | 3150 // -- rdx : receiver |
| 3218 // -- rsp[0] : return address | 3151 // -- rsp[0] : return address |
| 3219 // ----------------------------------- | 3152 // ----------------------------------- |
| 3220 Label slow; | 3153 Label slow; |
| 3221 | 3154 |
| 3222 // Check that the object isn't a smi. | 3155 // Check that the object isn't a smi. |
| 3223 __ JumpIfSmi(rdx, &slow); | 3156 __ JumpIfSmi(rdx, &slow); |
| 3224 | 3157 |
| 3225 // Check that the key is a smi. | 3158 // Check that the key is a smi. |
| 3226 __ JumpIfNotSmi(rax, &slow); | 3159 __ JumpIfNotSmi(rax, &slow); |
| 3227 | 3160 |
| 3228 // Check that the object is a JS object. | 3161 // Check that the map matches. |
| 3229 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); | 3162 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false); |
| 3230 __ j(not_equal, &slow); | |
| 3231 // Check that the receiver does not require access checks. We need | |
| 3232 // to check this explicitly since this generic stub does not perform | |
| 3233 // map checks. The map is already in rdx. | |
| 3234 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), | |
| 3235 Immediate(1 << Map::kIsAccessCheckNeeded)); | |
| 3236 __ j(not_zero, &slow); | |
| 3237 | |
| 3238 // Check that the elements array is the appropriate type of | |
| 3239 // ExternalArray. | |
| 3240 // rax: index (as a smi) | |
| 3241 // rdx: JSObject | |
| 3242 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3163 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 3243 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | |
| 3244 HEAP->RootIndexForExternalArrayType(array_type)); | |
| 3245 __ j(not_equal, &slow); | |
| 3246 | 3164 |
| 3247 // Check that the index is in range. | 3165 // Check that the index is in range. |
| 3248 __ SmiToInteger32(rcx, rax); | 3166 __ SmiToInteger32(rcx, rax); |
| 3249 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3167 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
| 3250 // Unsigned comparison catches both negative and too-large values. | 3168 // Unsigned comparison catches both negative and too-large values. |
| 3251 __ j(above_equal, &slow); | 3169 __ j(above_equal, &slow); |
| 3252 | 3170 |
| 3253 // rax: index (as a smi) | 3171 // rax: index (as a smi) |
| 3254 // rdx: receiver (JSObject) | 3172 // rdx: receiver (JSObject) |
| 3255 // rcx: untagged index | 3173 // rcx: untagged index |
| 3256 // rbx: elements array | 3174 // rbx: elements array |
| 3257 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); | 3175 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); |
| 3258 // rbx: base pointer of external storage | 3176 // rbx: base pointer of external storage |
| 3259 switch (array_type) { | 3177 switch (array_type) { |
| 3260 case kExternalByteArray: | 3178 case kExternalByteArray: |
| 3261 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); | 3179 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); |
| 3262 break; | 3180 break; |
| 3181 case kExternalPixelArray: |
| 3263 case kExternalUnsignedByteArray: | 3182 case kExternalUnsignedByteArray: |
| 3264 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); | 3183 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); |
| 3265 break; | 3184 break; |
| 3266 case kExternalShortArray: | 3185 case kExternalShortArray: |
| 3267 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); | 3186 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); |
| 3268 break; | 3187 break; |
| 3269 case kExternalUnsignedShortArray: | 3188 case kExternalUnsignedShortArray: |
| 3270 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); | 3189 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); |
| 3271 break; | 3190 break; |
| 3272 case kExternalIntArray: | 3191 case kExternalIntArray: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3345 | 3264 |
| 3346 // Perform tail call to the entry. | 3265 // Perform tail call to the entry. |
| 3347 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 3266 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| 3348 | 3267 |
| 3349 // Return the generated code. | 3268 // Return the generated code. |
| 3350 return GetCode(flags); | 3269 return GetCode(flags); |
| 3351 } | 3270 } |
| 3352 | 3271 |
| 3353 | 3272 |
| 3354 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( | 3273 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| 3355 ExternalArrayType array_type, Code::Flags flags) { | 3274 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { |
| 3356 // ----------- S t a t e ------------- | 3275 // ----------- S t a t e ------------- |
| 3357 // -- rax : value | 3276 // -- rax : value |
| 3358 // -- rcx : key | 3277 // -- rcx : key |
| 3359 // -- rdx : receiver | 3278 // -- rdx : receiver |
| 3360 // -- rsp[0] : return address | 3279 // -- rsp[0] : return address |
| 3361 // ----------------------------------- | 3280 // ----------------------------------- |
| 3362 Label slow; | 3281 Label slow; |
| 3363 | 3282 |
| 3364 // Check that the object isn't a smi. | 3283 // Check that the object isn't a smi. |
| 3365 __ JumpIfSmi(rdx, &slow); | 3284 __ JumpIfSmi(rdx, &slow); |
| 3366 // Get the map from the receiver. | 3285 |
| 3367 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); | 3286 // Check that the map matches. |
| 3368 // Check that the receiver does not require access checks. We need | 3287 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false); |
| 3369 // to do this because this generic stub does not perform map checks. | 3288 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 3370 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), | 3289 |
| 3371 Immediate(1 << Map::kIsAccessCheckNeeded)); | |
| 3372 __ j(not_zero, &slow); | |
| 3373 // Check that the key is a smi. | 3290 // Check that the key is a smi. |
| 3374 __ JumpIfNotSmi(rcx, &slow); | 3291 __ JumpIfNotSmi(rcx, &slow); |
| 3375 | 3292 |
| 3376 // Check that the object is a JS object. | |
| 3377 __ CmpInstanceType(rbx, JS_OBJECT_TYPE); | |
| 3378 __ j(not_equal, &slow); | |
| 3379 | |
| 3380 // Check that the elements array is the appropriate type of | |
| 3381 // ExternalArray. | |
| 3382 // rax: value | |
| 3383 // rcx: key (a smi) | |
| 3384 // rdx: receiver (a JSObject) | |
| 3385 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | |
| 3386 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | |
| 3387 HEAP->RootIndexForExternalArrayType(array_type)); | |
| 3388 __ j(not_equal, &slow); | |
| 3389 | |
| 3390 // Check that the index is in range. | 3293 // Check that the index is in range. |
| 3391 __ SmiToInteger32(rdi, rcx); // Untag the index. | 3294 __ SmiToInteger32(rdi, rcx); // Untag the index. |
| 3392 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3295 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
| 3393 // Unsigned comparison catches both negative and too-large values. | 3296 // Unsigned comparison catches both negative and too-large values. |
| 3394 __ j(above_equal, &slow); | 3297 __ j(above_equal, &slow); |
| 3395 | 3298 |
| 3396 // Handle both smis and HeapNumbers in the fast path. Go to the | 3299 // Handle both smis and HeapNumbers in the fast path. Go to the |
| 3397 // runtime for all other kinds of values. | 3300 // runtime for all other kinds of values. |
| 3398 // rax: value | 3301 // rax: value |
| 3399 // rcx: key (a smi) | 3302 // rcx: key (a smi) |
| 3400 // rdx: receiver (a JSObject) | 3303 // rdx: receiver (a JSObject) |
| 3401 // rbx: elements array | 3304 // rbx: elements array |
| 3402 // rdi: untagged key | 3305 // rdi: untagged key |
| 3403 NearLabel check_heap_number; | 3306 NearLabel check_heap_number; |
| 3404 __ JumpIfNotSmi(rax, &check_heap_number); | 3307 if (array_type == kExternalPixelArray) { |
| 3308 // Float to pixel conversion is only implemented in the runtime for now. |
| 3309 __ JumpIfNotSmi(rax, &slow); |
| 3310 } else { |
| 3311 __ JumpIfNotSmi(rax, &check_heap_number); |
| 3312 } |
| 3405 // No more branches to slow case on this path. Key and receiver not needed. | 3313 // No more branches to slow case on this path. Key and receiver not needed. |
| 3406 __ SmiToInteger32(rdx, rax); | 3314 __ SmiToInteger32(rdx, rax); |
| 3407 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); | 3315 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); |
| 3408 // rbx: base pointer of external storage | 3316 // rbx: base pointer of external storage |
| 3409 switch (array_type) { | 3317 switch (array_type) { |
| 3318 case kExternalPixelArray: |
| 3319 { // Clamp the value to [0..255]. |
| 3320 NearLabel done; |
| 3321 __ testl(rdx, Immediate(0xFFFFFF00)); |
| 3322 __ j(zero, &done); |
| 3323 __ setcc(negative, rdx); // 1 if negative, 0 if positive. |
| 3324 __ decb(rdx); // 0 if negative, 255 if positive. |
| 3325 __ bind(&done); |
| 3326 } |
| 3327 __ movb(Operand(rbx, rdi, times_1, 0), rdx); |
| 3328 break; |
| 3410 case kExternalByteArray: | 3329 case kExternalByteArray: |
| 3411 case kExternalUnsignedByteArray: | 3330 case kExternalUnsignedByteArray: |
| 3412 __ movb(Operand(rbx, rdi, times_1, 0), rdx); | 3331 __ movb(Operand(rbx, rdi, times_1, 0), rdx); |
| 3413 break; | 3332 break; |
| 3414 case kExternalShortArray: | 3333 case kExternalShortArray: |
| 3415 case kExternalUnsignedShortArray: | 3334 case kExternalUnsignedShortArray: |
| 3416 __ movw(Operand(rbx, rdi, times_2, 0), rdx); | 3335 __ movw(Operand(rbx, rdi, times_2, 0), rdx); |
| 3417 break; | 3336 break; |
| 3418 case kExternalIntArray: | 3337 case kExternalIntArray: |
| 3419 case kExternalUnsignedIntArray: | 3338 case kExternalUnsignedIntArray: |
| 3420 __ movl(Operand(rbx, rdi, times_4, 0), rdx); | 3339 __ movl(Operand(rbx, rdi, times_4, 0), rdx); |
| 3421 break; | 3340 break; |
| 3422 case kExternalFloatArray: | 3341 case kExternalFloatArray: |
| 3423 // Need to perform int-to-float conversion. | 3342 // Need to perform int-to-float conversion. |
| 3424 __ cvtlsi2ss(xmm0, rdx); | 3343 __ cvtlsi2ss(xmm0, rdx); |
| 3425 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); | 3344 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); |
| 3426 break; | 3345 break; |
| 3427 default: | 3346 default: |
| 3428 UNREACHABLE(); | 3347 UNREACHABLE(); |
| 3429 break; | 3348 break; |
| 3430 } | 3349 } |
| 3431 __ ret(0); | 3350 __ ret(0); |
| 3432 | 3351 |
| 3433 __ bind(&check_heap_number); | 3352 // TODO(danno): handle heap number -> pixel array conversion |
| 3434 // rax: value | 3353 if (array_type != kExternalPixelArray) { |
| 3435 // rcx: key (a smi) | 3354 __ bind(&check_heap_number); |
| 3436 // rdx: receiver (a JSObject) | 3355 // rax: value |
| 3437 // rbx: elements array | 3356 // rcx: key (a smi) |
| 3438 // rdi: untagged key | 3357 // rdx: receiver (a JSObject) |
| 3439 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister); | 3358 // rbx: elements array |
| 3440 __ j(not_equal, &slow); | 3359 // rdi: untagged key |
| 3441 // No more branches to slow case on this path. | 3360 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister); |
| 3361 __ j(not_equal, &slow); |
| 3362 // No more branches to slow case on this path. |
| 3442 | 3363 |
| 3443 // The WebGL specification leaves the behavior of storing NaN and | 3364 // The WebGL specification leaves the behavior of storing NaN and |
| 3444 // +/-Infinity into integer arrays basically undefined. For more | 3365 // +/-Infinity into integer arrays basically undefined. For more |
| 3445 // reproducible behavior, convert these to zero. | 3366 // reproducible behavior, convert these to zero. |
| 3446 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); | 3367 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 3447 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); | 3368 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); |
| 3448 // rdi: untagged index | |
| 3449 // rbx: base pointer of external storage | |
| 3450 // top of FPU stack: value | |
| 3451 if (array_type == kExternalFloatArray) { | |
| 3452 __ cvtsd2ss(xmm0, xmm0); | |
| 3453 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); | |
| 3454 __ ret(0); | |
| 3455 } else { | |
| 3456 // Perform float-to-int conversion with truncation (round-to-zero) | |
| 3457 // behavior. | |
| 3458 | |
| 3459 // Convert to int32 and store the low byte/word. | |
| 3460 // If the value is NaN or +/-infinity, the result is 0x80000000, | |
| 3461 // which is automatically zero when taken mod 2^n, n < 32. | |
| 3462 // rdx: value (converted to an untagged integer) | |
| 3463 // rdi: untagged index | 3369 // rdi: untagged index |
| 3464 // rbx: base pointer of external storage | 3370 // rbx: base pointer of external storage |
| 3465 switch (array_type) { | 3371 // top of FPU stack: value |
| 3466 case kExternalByteArray: | 3372 if (array_type == kExternalFloatArray) { |
| 3467 case kExternalUnsignedByteArray: | 3373 __ cvtsd2ss(xmm0, xmm0); |
| 3468 __ cvttsd2si(rdx, xmm0); | 3374 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); |
| 3469 __ movb(Operand(rbx, rdi, times_1, 0), rdx); | 3375 __ ret(0); |
| 3470 break; | 3376 } else { |
| 3471 case kExternalShortArray: | 3377 // Perform float-to-int conversion with truncation (round-to-zero) |
| 3472 case kExternalUnsignedShortArray: | 3378 // behavior. |
| 3473 __ cvttsd2si(rdx, xmm0); | 3379 |
| 3474 __ movw(Operand(rbx, rdi, times_2, 0), rdx); | 3380 // Convert to int32 and store the low byte/word. |
| 3475 break; | 3381 // If the value is NaN or +/-infinity, the result is 0x80000000, |
| 3476 case kExternalIntArray: | 3382 // which is automatically zero when taken mod 2^n, n < 32. |
| 3477 case kExternalUnsignedIntArray: { | 3383 // rdx: value (converted to an untagged integer) |
| 3478 // Convert to int64, so that NaN and infinities become | 3384 // rdi: untagged index |
| 3479 // 0x8000000000000000, which is zero mod 2^32. | 3385 // rbx: base pointer of external storage |
| 3480 __ cvttsd2siq(rdx, xmm0); | 3386 switch (array_type) { |
| 3481 __ movl(Operand(rbx, rdi, times_4, 0), rdx); | 3387 case kExternalByteArray: |
| 3482 break; | 3388 case kExternalUnsignedByteArray: |
| 3389 __ cvttsd2si(rdx, xmm0); |
| 3390 __ movb(Operand(rbx, rdi, times_1, 0), rdx); |
| 3391 break; |
| 3392 case kExternalShortArray: |
| 3393 case kExternalUnsignedShortArray: |
| 3394 __ cvttsd2si(rdx, xmm0); |
| 3395 __ movw(Operand(rbx, rdi, times_2, 0), rdx); |
| 3396 break; |
| 3397 case kExternalIntArray: |
| 3398 case kExternalUnsignedIntArray: { |
| 3399 // Convert to int64, so that NaN and infinities become |
| 3400 // 0x8000000000000000, which is zero mod 2^32. |
| 3401 __ cvttsd2siq(rdx, xmm0); |
| 3402 __ movl(Operand(rbx, rdi, times_4, 0), rdx); |
| 3403 break; |
| 3404 } |
| 3405 default: |
| 3406 UNREACHABLE(); |
| 3407 break; |
| 3483 } | 3408 } |
| 3484 default: | 3409 __ ret(0); |
| 3485 UNREACHABLE(); | |
| 3486 break; | |
| 3487 } | 3410 } |
| 3488 __ ret(0); | |
| 3489 } | 3411 } |
| 3490 | 3412 |
| 3491 // Slow case: call runtime. | 3413 // Slow case: call runtime. |
| 3492 __ bind(&slow); | 3414 __ bind(&slow); |
| 3493 | 3415 |
| 3494 // ----------- S t a t e ------------- | 3416 // ----------- S t a t e ------------- |
| 3495 // -- rax : value | 3417 // -- rax : value |
| 3496 // -- rcx : key | 3418 // -- rcx : key |
| 3497 // -- rdx : receiver | 3419 // -- rdx : receiver |
| 3498 // -- rsp[0] : return address | 3420 // -- rsp[0] : return address |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3511 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 3433 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
| 3512 | 3434 |
| 3513 return GetCode(flags); | 3435 return GetCode(flags); |
| 3514 } | 3436 } |
| 3515 | 3437 |
| 3516 #undef __ | 3438 #undef __ |
| 3517 | 3439 |
| 3518 } } // namespace v8::internal | 3440 } } // namespace v8::internal |
| 3519 | 3441 |
| 3520 #endif // V8_TARGET_ARCH_X64 | 3442 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |