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