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

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

Issue 7112010: Plumbing changes to merge various element kind implementaions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 6 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/x64/lithium-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2512 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 __ bind(&miss); 2523 __ bind(&miss);
2524 __ DecrementCounter(counters->keyed_store_field(), 1); 2524 __ DecrementCounter(counters->keyed_store_field(), 1);
2525 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2525 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2526 __ Jump(ic, RelocInfo::CODE_TARGET); 2526 __ Jump(ic, RelocInfo::CODE_TARGET);
2527 2527
2528 // Return the generated code. 2528 // Return the generated code.
2529 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2529 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2530 } 2530 }
2531 2531
2532 2532
2533 MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( 2533 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(
2534 Map* receiver_map) { 2534 Map* receiver_map) {
2535 // ----------- S t a t e ------------- 2535 // ----------- S t a t e -------------
2536 // -- rax : value 2536 // -- rax : value
2537 // -- rcx : key 2537 // -- rcx : key
2538 // -- rdx : receiver 2538 // -- rdx : receiver
2539 // -- rsp[0] : return address 2539 // -- rsp[0] : return address
2540 // ----------------------------------- 2540 // -----------------------------------
2541 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2541 MaybeObject* maybe_stub;
2542 MaybeObject* maybe_stub = 2542 if (receiver_map->has_fast_elements()) {
2543 KeyedStoreFastElementStub(is_js_array).TryGetCode(); 2543 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2544 maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode();
2545 } else {
2546 ASSERT(receiver_map->has_external_array_elements());
2547 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
2548 maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode();
2549 }
2544 Code* stub; 2550 Code* stub;
2545 if (!maybe_stub->To(&stub)) return maybe_stub; 2551 if (!maybe_stub->To(&stub)) return maybe_stub;
2546 __ DispatchMap(rdx, 2552 __ DispatchMap(rdx,
2547 Handle<Map>(receiver_map), 2553 Handle<Map>(receiver_map),
2548 Handle<Code>(stub), 2554 Handle<Code>(stub),
2549 DO_SMI_CHECK); 2555 DO_SMI_CHECK);
2550 2556
2551 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2557 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2552 __ jmp(ic, RelocInfo::CODE_TARGET); 2558 __ jmp(ic, RelocInfo::CODE_TARGET);
2553 2559
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
2983 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); 2989 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
2984 __ bind(&miss); 2990 __ bind(&miss);
2985 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 2991 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
2986 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2992 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2987 2993
2988 // Return the generated code. 2994 // Return the generated code.
2989 return GetCode(CALLBACKS, name); 2995 return GetCode(CALLBACKS, name);
2990 } 2996 }
2991 2997
2992 2998
2993 MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { 2999 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
2994 // ----------- S t a t e ------------- 3000 // ----------- S t a t e -------------
2995 // -- rax : key 3001 // -- rax : key
2996 // -- rdx : receiver 3002 // -- rdx : receiver
2997 // -- rsp[0] : return address 3003 // -- rsp[0] : return address
2998 // ----------------------------------- 3004 // -----------------------------------
2999 MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); 3005 MaybeObject* maybe_stub;
3006 if (receiver_map->has_fast_elements()) {
3007 maybe_stub = KeyedLoadFastElementStub().TryGetCode();
3008 } else {
3009 ASSERT(receiver_map->has_external_array_elements());
3010 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
3011 maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode();
3012 }
3000 Code* stub; 3013 Code* stub;
3001 if (!maybe_stub->To(&stub)) return maybe_stub; 3014 if (!maybe_stub->To(&stub)) return maybe_stub;
3002 __ DispatchMap(rdx, 3015 __ DispatchMap(rdx,
3003 Handle<Map>(receiver_map), 3016 Handle<Map>(receiver_map),
3004 Handle<Code>(stub), 3017 Handle<Code>(stub),
3005 DO_SMI_CHECK); 3018 DO_SMI_CHECK);
3006 3019
3007 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3020 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3008 __ jmp(ic, RelocInfo::CODE_TARGET); 3021 __ jmp(ic, RelocInfo::CODE_TARGET);
3009 3022
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3169 Code* code = 3182 Code* code =
3170 isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric); 3183 isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
3171 Handle<Code> generic_construct_stub(code); 3184 Handle<Code> generic_construct_stub(code);
3172 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 3185 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
3173 3186
3174 // Return the generated code. 3187 // Return the generated code.
3175 return GetCode(); 3188 return GetCode();
3176 } 3189 }
3177 3190
3178 3191
3179 MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
3180 JSObject*receiver, ExternalArrayType array_type) {
3181 // ----------- S t a t e -------------
3182 // -- rax : key
3183 // -- rdx : receiver
3184 // -- rsp[0] : return address
3185 // -----------------------------------
3186 MaybeObject* maybe_stub =
3187 KeyedLoadExternalArrayStub(array_type).TryGetCode();
3188 Code* stub;
3189 if (!maybe_stub->To(&stub)) return maybe_stub;
3190 __ DispatchMap(rdx,
3191 Handle<Map>(receiver->map()),
3192 Handle<Code>(stub),
3193 DO_SMI_CHECK);
3194
3195 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3196 __ jmp(ic, RelocInfo::CODE_TARGET);
3197
3198 // Return the generated code.
3199 return GetCode();
3200 }
3201
3202 MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
3203 JSObject* receiver, ExternalArrayType array_type) {
3204 // ----------- S t a t e -------------
3205 // -- rax : value
3206 // -- rcx : key
3207 // -- rdx : receiver
3208 // -- rsp[0] : return address
3209 // -----------------------------------
3210 MaybeObject* maybe_stub =
3211 KeyedStoreExternalArrayStub(array_type).TryGetCode();
3212 Code* stub;
3213 if (!maybe_stub->To(&stub)) return maybe_stub;
3214 __ DispatchMap(rdx,
3215 Handle<Map>(receiver->map()),
3216 Handle<Code>(stub),
3217 DO_SMI_CHECK);
3218
3219 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3220 __ jmp(ic, RelocInfo::CODE_TARGET);
3221
3222 return GetCode();
3223 }
3224
3225
3226 #undef __ 3192 #undef __
3227 #define __ ACCESS_MASM(masm) 3193 #define __ ACCESS_MASM(masm)
3228 3194
3229 3195
3230 void KeyedLoadStubCompiler::GenerateLoadExternalArray( 3196 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
3231 MacroAssembler* masm, 3197 MacroAssembler* masm,
3232 ExternalArrayType array_type) { 3198 JSObject::ElementsKind elements_kind) {
3233 // ----------- S t a t e ------------- 3199 // ----------- S t a t e -------------
3234 // -- rax : key 3200 // -- rax : key
3235 // -- rdx : receiver 3201 // -- rdx : receiver
3236 // -- rsp[0] : return address 3202 // -- rsp[0] : return address
3237 // ----------------------------------- 3203 // -----------------------------------
3238 Label slow, miss_force_generic; 3204 Label slow, miss_force_generic;
3239 3205
3240 // This stub is meant to be tail-jumped to, the receiver must already 3206 // This stub is meant to be tail-jumped to, the receiver must already
3241 // have been verified by the caller to not be a smi. 3207 // have been verified by the caller to not be a smi.
3242 3208
3243 // Check that the key is a smi. 3209 // Check that the key is a smi.
3244 __ JumpIfNotSmi(rax, &miss_force_generic); 3210 __ JumpIfNotSmi(rax, &miss_force_generic);
3245 3211
3246 // Check that the index is in range. 3212 // Check that the index is in range.
3247 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 3213 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3248 __ SmiToInteger32(rcx, rax); 3214 __ SmiToInteger32(rcx, rax);
3249 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); 3215 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset));
3250 // Unsigned comparison catches both negative and too-large values. 3216 // Unsigned comparison catches both negative and too-large values.
3251 __ j(above_equal, &miss_force_generic); 3217 __ j(above_equal, &miss_force_generic);
3252 3218
3253 // rax: index (as a smi) 3219 // rax: index (as a smi)
3254 // rdx: receiver (JSObject) 3220 // rdx: receiver (JSObject)
3255 // rcx: untagged index 3221 // rcx: untagged index
3256 // rbx: elements array 3222 // rbx: elements array
3257 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3223 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3258 // rbx: base pointer of external storage 3224 // rbx: base pointer of external storage
3259 switch (array_type) { 3225 switch (elements_kind) {
3260 case kExternalByteArray: 3226 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3261 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); 3227 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0));
3262 break; 3228 break;
3263 case kExternalPixelArray: 3229 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3264 case kExternalUnsignedByteArray: 3230 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3265 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); 3231 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0));
3266 break; 3232 break;
3267 case kExternalShortArray: 3233 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3268 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); 3234 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0));
3269 break; 3235 break;
3270 case kExternalUnsignedShortArray: 3236 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3271 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); 3237 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0));
3272 break; 3238 break;
3273 case kExternalIntArray: 3239 case JSObject::EXTERNAL_INT_ELEMENTS:
3274 __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0)); 3240 __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0));
3275 break; 3241 break;
3276 case kExternalUnsignedIntArray: 3242 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3277 __ movl(rcx, Operand(rbx, rcx, times_4, 0)); 3243 __ movl(rcx, Operand(rbx, rcx, times_4, 0));
3278 break; 3244 break;
3279 case kExternalFloatArray: 3245 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3280 __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0)); 3246 __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0));
3281 break; 3247 break;
3282 case kExternalDoubleArray: 3248 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3283 __ movsd(xmm0, Operand(rbx, rcx, times_8, 0)); 3249 __ movsd(xmm0, Operand(rbx, rcx, times_8, 0));
3284 break; 3250 break;
3285 default: 3251 default:
3286 UNREACHABLE(); 3252 UNREACHABLE();
3287 break; 3253 break;
3288 } 3254 }
3289 3255
3290 // rax: index 3256 // rax: index
3291 // rdx: receiver 3257 // rdx: receiver
3292 // For integer array types: 3258 // For integer array types:
3293 // rcx: value 3259 // rcx: value
3294 // For floating-point array type: 3260 // For floating-point array type:
3295 // xmm0: value as double. 3261 // xmm0: value as double.
3296 3262
3297 ASSERT(kSmiValueSize == 32); 3263 ASSERT(kSmiValueSize == 32);
3298 if (array_type == kExternalUnsignedIntArray) { 3264 if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
3299 // For the UnsignedInt array type, we need to see whether 3265 // For the UnsignedInt array type, we need to see whether
3300 // the value can be represented in a Smi. If not, we need to convert 3266 // the value can be represented in a Smi. If not, we need to convert
3301 // it to a HeapNumber. 3267 // it to a HeapNumber.
3302 Label box_int; 3268 Label box_int;
3303 3269
3304 __ JumpIfUIntNotValidSmiValue(rcx, &box_int, Label::kNear); 3270 __ JumpIfUIntNotValidSmiValue(rcx, &box_int, Label::kNear);
3305 3271
3306 __ Integer32ToSmi(rax, rcx); 3272 __ Integer32ToSmi(rax, rcx);
3307 __ ret(0); 3273 __ ret(0);
3308 3274
3309 __ bind(&box_int); 3275 __ bind(&box_int);
3310 3276
3311 // Allocate a HeapNumber for the int and perform int-to-double 3277 // Allocate a HeapNumber for the int and perform int-to-double
3312 // conversion. 3278 // conversion.
3313 // The value is zero-extended since we loaded the value from memory 3279 // The value is zero-extended since we loaded the value from memory
3314 // with movl. 3280 // with movl.
3315 __ cvtqsi2sd(xmm0, rcx); 3281 __ cvtqsi2sd(xmm0, rcx);
3316 3282
3317 __ AllocateHeapNumber(rcx, rbx, &slow); 3283 __ AllocateHeapNumber(rcx, rbx, &slow);
3318 // Set the value. 3284 // Set the value.
3319 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); 3285 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
3320 __ movq(rax, rcx); 3286 __ movq(rax, rcx);
3321 __ ret(0); 3287 __ ret(0);
3322 } else if (array_type == kExternalFloatArray || 3288 } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3323 array_type == kExternalDoubleArray) { 3289 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3324 // For the floating-point array type, we need to always allocate a 3290 // For the floating-point array type, we need to always allocate a
3325 // HeapNumber. 3291 // HeapNumber.
3326 __ AllocateHeapNumber(rcx, rbx, &slow); 3292 __ AllocateHeapNumber(rcx, rbx, &slow);
3327 // Set the value. 3293 // Set the value.
3328 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); 3294 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
3329 __ movq(rax, rcx); 3295 __ movq(rax, rcx);
3330 __ ret(0); 3296 __ ret(0);
3331 } else { 3297 } else {
3332 __ Integer32ToSmi(rax, rcx); 3298 __ Integer32ToSmi(rax, rcx);
3333 __ ret(0); 3299 __ ret(0);
(...skipping 22 matching lines...) Expand all
3356 // -- rsp[0] : return address 3322 // -- rsp[0] : return address
3357 // ----------------------------------- 3323 // -----------------------------------
3358 Handle<Code> miss_ic = 3324 Handle<Code> miss_ic =
3359 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); 3325 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3360 __ jmp(miss_ic, RelocInfo::CODE_TARGET); 3326 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3361 } 3327 }
3362 3328
3363 3329
3364 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3330 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3365 MacroAssembler* masm, 3331 MacroAssembler* masm,
3366 ExternalArrayType array_type) { 3332 JSObject::ElementsKind elements_kind) {
3367 // ----------- S t a t e ------------- 3333 // ----------- S t a t e -------------
3368 // -- rax : value 3334 // -- rax : value
3369 // -- rcx : key 3335 // -- rcx : key
3370 // -- rdx : receiver 3336 // -- rdx : receiver
3371 // -- rsp[0] : return address 3337 // -- rsp[0] : return address
3372 // ----------------------------------- 3338 // -----------------------------------
3373 Label slow, miss_force_generic; 3339 Label slow, miss_force_generic;
3374 3340
3375 // This stub is meant to be tail-jumped to, the receiver must already 3341 // This stub is meant to be tail-jumped to, the receiver must already
3376 // have been verified by the caller to not be a smi. 3342 // have been verified by the caller to not be a smi.
3377 3343
3378 // Check that the key is a smi. 3344 // Check that the key is a smi.
3379 __ JumpIfNotSmi(rcx, &miss_force_generic); 3345 __ JumpIfNotSmi(rcx, &miss_force_generic);
3380 3346
3381 // Check that the index is in range. 3347 // Check that the index is in range.
3382 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 3348 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3383 __ SmiToInteger32(rdi, rcx); // Untag the index. 3349 __ SmiToInteger32(rdi, rcx); // Untag the index.
3384 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); 3350 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset));
3385 // Unsigned comparison catches both negative and too-large values. 3351 // Unsigned comparison catches both negative and too-large values.
3386 __ j(above_equal, &miss_force_generic); 3352 __ j(above_equal, &miss_force_generic);
3387 3353
3388 // Handle both smis and HeapNumbers in the fast path. Go to the 3354 // Handle both smis and HeapNumbers in the fast path. Go to the
3389 // runtime for all other kinds of values. 3355 // runtime for all other kinds of values.
3390 // rax: value 3356 // rax: value
3391 // rcx: key (a smi) 3357 // rcx: key (a smi)
3392 // rdx: receiver (a JSObject) 3358 // rdx: receiver (a JSObject)
3393 // rbx: elements array 3359 // rbx: elements array
3394 // rdi: untagged key 3360 // rdi: untagged key
3395 Label check_heap_number; 3361 Label check_heap_number;
3396 if (array_type == kExternalPixelArray) { 3362 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3397 // Float to pixel conversion is only implemented in the runtime for now. 3363 // Float to pixel conversion is only implemented in the runtime for now.
3398 __ JumpIfNotSmi(rax, &slow); 3364 __ JumpIfNotSmi(rax, &slow);
3399 } else { 3365 } else {
3400 __ JumpIfNotSmi(rax, &check_heap_number, Label::kNear); 3366 __ JumpIfNotSmi(rax, &check_heap_number, Label::kNear);
3401 } 3367 }
3402 // No more branches to slow case on this path. Key and receiver not needed. 3368 // No more branches to slow case on this path. Key and receiver not needed.
3403 __ SmiToInteger32(rdx, rax); 3369 __ SmiToInteger32(rdx, rax);
3404 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3370 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3405 // rbx: base pointer of external storage 3371 // rbx: base pointer of external storage
3406 switch (array_type) { 3372 switch (elements_kind) {
3407 case kExternalPixelArray: 3373 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3408 { // Clamp the value to [0..255]. 3374 { // Clamp the value to [0..255].
3409 Label done; 3375 Label done;
3410 __ testl(rdx, Immediate(0xFFFFFF00)); 3376 __ testl(rdx, Immediate(0xFFFFFF00));
3411 __ j(zero, &done, Label::kNear); 3377 __ j(zero, &done, Label::kNear);
3412 __ setcc(negative, rdx); // 1 if negative, 0 if positive. 3378 __ setcc(negative, rdx); // 1 if negative, 0 if positive.
3413 __ decb(rdx); // 0 if negative, 255 if positive. 3379 __ decb(rdx); // 0 if negative, 255 if positive.
3414 __ bind(&done); 3380 __ bind(&done);
3415 } 3381 }
3416 __ movb(Operand(rbx, rdi, times_1, 0), rdx); 3382 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3417 break; 3383 break;
3418 case kExternalByteArray: 3384 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3419 case kExternalUnsignedByteArray: 3385 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3420 __ movb(Operand(rbx, rdi, times_1, 0), rdx); 3386 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3421 break; 3387 break;
3422 case kExternalShortArray: 3388 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3423 case kExternalUnsignedShortArray: 3389 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3424 __ movw(Operand(rbx, rdi, times_2, 0), rdx); 3390 __ movw(Operand(rbx, rdi, times_2, 0), rdx);
3425 break; 3391 break;
3426 case kExternalIntArray: 3392 case JSObject::EXTERNAL_INT_ELEMENTS:
3427 case kExternalUnsignedIntArray: 3393 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3428 __ movl(Operand(rbx, rdi, times_4, 0), rdx); 3394 __ movl(Operand(rbx, rdi, times_4, 0), rdx);
3429 break; 3395 break;
3430 case kExternalFloatArray: 3396 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3431 // Need to perform int-to-float conversion. 3397 // Need to perform int-to-float conversion.
3432 __ cvtlsi2ss(xmm0, rdx); 3398 __ cvtlsi2ss(xmm0, rdx);
3433 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); 3399 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3434 break; 3400 break;
3435 case kExternalDoubleArray: 3401 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3436 // Need to perform int-to-float conversion. 3402 // Need to perform int-to-float conversion.
3437 __ cvtlsi2sd(xmm0, rdx); 3403 __ cvtlsi2sd(xmm0, rdx);
3438 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); 3404 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
3439 break; 3405 break;
3440 default: 3406 case JSObject::FAST_ELEMENTS:
3407 case JSObject::FAST_DOUBLE_ELEMENTS:
3408 case JSObject::DICTIONARY_ELEMENTS:
3441 UNREACHABLE(); 3409 UNREACHABLE();
3442 break; 3410 break;
3443 } 3411 }
3444 __ ret(0); 3412 __ ret(0);
3445 3413
3446 // TODO(danno): handle heap number -> pixel array conversion 3414 // TODO(danno): handle heap number -> pixel array conversion
3447 if (array_type != kExternalPixelArray) { 3415 if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3448 __ bind(&check_heap_number); 3416 __ bind(&check_heap_number);
3449 // rax: value 3417 // rax: value
3450 // rcx: key (a smi) 3418 // rcx: key (a smi)
3451 // rdx: receiver (a JSObject) 3419 // rdx: receiver (a JSObject)
3452 // rbx: elements array 3420 // rbx: elements array
3453 // rdi: untagged key 3421 // rdi: untagged key
3454 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister); 3422 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister);
3455 __ j(not_equal, &slow); 3423 __ j(not_equal, &slow);
3456 // No more branches to slow case on this path. 3424 // No more branches to slow case on this path.
3457 3425
3458 // The WebGL specification leaves the behavior of storing NaN and 3426 // The WebGL specification leaves the behavior of storing NaN and
3459 // +/-Infinity into integer arrays basically undefined. For more 3427 // +/-Infinity into integer arrays basically undefined. For more
3460 // reproducible behavior, convert these to zero. 3428 // reproducible behavior, convert these to zero.
3461 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); 3429 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
3462 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3430 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3463 // rdi: untagged index 3431 // rdi: untagged index
3464 // rbx: base pointer of external storage 3432 // rbx: base pointer of external storage
3465 // top of FPU stack: value 3433 // top of FPU stack: value
3466 if (array_type == kExternalFloatArray) { 3434 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3467 __ cvtsd2ss(xmm0, xmm0); 3435 __ cvtsd2ss(xmm0, xmm0);
3468 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); 3436 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3469 __ ret(0); 3437 __ ret(0);
3470 } else if (array_type == kExternalDoubleArray) { 3438 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3471 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); 3439 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
3472 __ ret(0); 3440 __ ret(0);
3473 } else { 3441 } else {
3474 // Perform float-to-int conversion with truncation (round-to-zero) 3442 // Perform float-to-int conversion with truncation (round-to-zero)
3475 // behavior. 3443 // behavior.
3476 3444
3477 // Convert to int32 and store the low byte/word. 3445 // Convert to int32 and store the low byte/word.
3478 // If the value is NaN or +/-infinity, the result is 0x80000000, 3446 // If the value is NaN or +/-infinity, the result is 0x80000000,
3479 // which is automatically zero when taken mod 2^n, n < 32. 3447 // which is automatically zero when taken mod 2^n, n < 32.
3480 // rdx: value (converted to an untagged integer) 3448 // rdx: value (converted to an untagged integer)
3481 // rdi: untagged index 3449 // rdi: untagged index
3482 // rbx: base pointer of external storage 3450 // rbx: base pointer of external storage
3483 switch (array_type) { 3451 switch (elements_kind) {
3484 case kExternalByteArray: 3452 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3485 case kExternalUnsignedByteArray: 3453 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3486 __ cvttsd2si(rdx, xmm0); 3454 __ cvttsd2si(rdx, xmm0);
3487 __ movb(Operand(rbx, rdi, times_1, 0), rdx); 3455 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3488 break; 3456 break;
3489 case kExternalShortArray: 3457 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3490 case kExternalUnsignedShortArray: 3458 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3491 __ cvttsd2si(rdx, xmm0); 3459 __ cvttsd2si(rdx, xmm0);
3492 __ movw(Operand(rbx, rdi, times_2, 0), rdx); 3460 __ movw(Operand(rbx, rdi, times_2, 0), rdx);
3493 break; 3461 break;
3494 case kExternalIntArray: 3462 case JSObject::EXTERNAL_INT_ELEMENTS:
3495 case kExternalUnsignedIntArray: { 3463 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3496 // Convert to int64, so that NaN and infinities become 3464 // Convert to int64, so that NaN and infinities become
3497 // 0x8000000000000000, which is zero mod 2^32. 3465 // 0x8000000000000000, which is zero mod 2^32.
3498 __ cvttsd2siq(rdx, xmm0); 3466 __ cvttsd2siq(rdx, xmm0);
3499 __ movl(Operand(rbx, rdi, times_4, 0), rdx); 3467 __ movl(Operand(rbx, rdi, times_4, 0), rdx);
3500 break; 3468 break;
3501 } 3469 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3502 default: 3470 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3471 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3472 case JSObject::FAST_ELEMENTS:
3473 case JSObject::FAST_DOUBLE_ELEMENTS:
3474 case JSObject::DICTIONARY_ELEMENTS:
3503 UNREACHABLE(); 3475 UNREACHABLE();
3504 break; 3476 break;
3505 } 3477 }
3506 __ ret(0); 3478 __ ret(0);
3507 } 3479 }
3508 } 3480 }
3509 3481
3510 // Slow case: call runtime. 3482 // Slow case: call runtime.
3511 __ bind(&slow); 3483 __ bind(&slow);
3512 3484
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3625 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3597 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3626 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3598 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3627 } 3599 }
3628 3600
3629 3601
3630 #undef __ 3602 #undef __
3631 3603
3632 } } // namespace v8::internal 3604 } } // namespace v8::internal
3633 3605
3634 #endif // V8_TARGET_ARCH_X64 3606 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698