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