| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3245 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3245 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3246 if (constant_key & 0xF0000000) { | 3246 if (constant_key & 0xF0000000) { |
| 3247 Abort(kArrayIndexConstantValueTooBig); | 3247 Abort(kArrayIndexConstantValueTooBig); |
| 3248 } | 3248 } |
| 3249 } else { | 3249 } else { |
| 3250 key = ToRegister(instr->key()); | 3250 key = ToRegister(instr->key()); |
| 3251 } | 3251 } |
| 3252 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3252 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3253 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3253 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3254 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3254 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3255 int additional_offset = instr->additional_index() << element_size_shift; | 3255 int base_offset = instr->base_offset(); |
| 3256 | 3256 |
| 3257 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3257 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3258 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3258 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3259 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3259 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3260 Operand operand = key_is_constant | 3260 Operand operand = key_is_constant |
| 3261 ? Operand(constant_key << element_size_shift) | 3261 ? Operand(constant_key << element_size_shift) |
| 3262 : Operand(key, LSL, shift_size); | 3262 : Operand(key, LSL, shift_size); |
| 3263 __ add(scratch0(), external_pointer, operand); | 3263 __ add(scratch0(), external_pointer, operand); |
| 3264 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3264 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3265 __ vldr(double_scratch0().low(), scratch0(), additional_offset); | 3265 __ vldr(double_scratch0().low(), scratch0(), base_offset); |
| 3266 __ vcvt_f64_f32(result, double_scratch0().low()); | 3266 __ vcvt_f64_f32(result, double_scratch0().low()); |
| 3267 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3267 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 3268 __ vldr(result, scratch0(), additional_offset); | 3268 __ vldr(result, scratch0(), base_offset); |
| 3269 } | 3269 } |
| 3270 } else { | 3270 } else { |
| 3271 Register result = ToRegister(instr->result()); | 3271 Register result = ToRegister(instr->result()); |
| 3272 MemOperand mem_operand = PrepareKeyedOperand( | 3272 MemOperand mem_operand = PrepareKeyedOperand( |
| 3273 key, external_pointer, key_is_constant, constant_key, | 3273 key, external_pointer, key_is_constant, constant_key, |
| 3274 element_size_shift, shift_size, | 3274 element_size_shift, shift_size, base_offset); |
| 3275 instr->additional_index(), additional_offset); | |
| 3276 switch (elements_kind) { | 3275 switch (elements_kind) { |
| 3277 case EXTERNAL_BYTE_ELEMENTS: | 3276 case EXTERNAL_BYTE_ELEMENTS: |
| 3278 __ ldrsb(result, mem_operand); | 3277 __ ldrsb(result, mem_operand); |
| 3279 break; | 3278 break; |
| 3280 case EXTERNAL_PIXEL_ELEMENTS: | 3279 case EXTERNAL_PIXEL_ELEMENTS: |
| 3281 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3280 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3282 __ ldrb(result, mem_operand); | 3281 __ ldrb(result, mem_operand); |
| 3283 break; | 3282 break; |
| 3284 case EXTERNAL_SHORT_ELEMENTS: | 3283 case EXTERNAL_SHORT_ELEMENTS: |
| 3285 __ ldrsh(result, mem_operand); | 3284 __ ldrsh(result, mem_operand); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3316 | 3315 |
| 3317 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3316 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 3318 Register elements = ToRegister(instr->elements()); | 3317 Register elements = ToRegister(instr->elements()); |
| 3319 bool key_is_constant = instr->key()->IsConstantOperand(); | 3318 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3320 Register key = no_reg; | 3319 Register key = no_reg; |
| 3321 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3320 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3322 Register scratch = scratch0(); | 3321 Register scratch = scratch0(); |
| 3323 | 3322 |
| 3324 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3323 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 3325 | 3324 |
| 3326 int base_offset = | 3325 int base_offset = instr->base_offset(); |
| 3327 FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
| 3328 (instr->additional_index() << element_size_shift); | |
| 3329 if (key_is_constant) { | 3326 if (key_is_constant) { |
| 3330 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3327 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3331 if (constant_key & 0xF0000000) { | 3328 if (constant_key & 0xF0000000) { |
| 3332 Abort(kArrayIndexConstantValueTooBig); | 3329 Abort(kArrayIndexConstantValueTooBig); |
| 3333 } | 3330 } |
| 3334 base_offset += constant_key << element_size_shift; | 3331 base_offset += constant_key * kDoubleSize; |
| 3335 } | 3332 } |
| 3336 __ add(scratch, elements, Operand(base_offset)); | 3333 __ add(scratch, elements, Operand(base_offset)); |
| 3337 | 3334 |
| 3338 if (!key_is_constant) { | 3335 if (!key_is_constant) { |
| 3339 key = ToRegister(instr->key()); | 3336 key = ToRegister(instr->key()); |
| 3340 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3337 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3341 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3338 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3342 __ add(scratch, scratch, Operand(key, LSL, shift_size)); | 3339 __ add(scratch, scratch, Operand(key, LSL, shift_size)); |
| 3343 } | 3340 } |
| 3344 | 3341 |
| 3345 __ vldr(result, scratch, 0); | 3342 __ vldr(result, scratch, 0); |
| 3346 | 3343 |
| 3347 if (instr->hydrogen()->RequiresHoleCheck()) { | 3344 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3348 __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); | 3345 __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); |
| 3349 __ cmp(scratch, Operand(kHoleNanUpper32)); | 3346 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 3350 DeoptimizeIf(eq, instr->environment()); | 3347 DeoptimizeIf(eq, instr->environment()); |
| 3351 } | 3348 } |
| 3352 } | 3349 } |
| 3353 | 3350 |
| 3354 | 3351 |
| 3355 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3352 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3356 Register elements = ToRegister(instr->elements()); | 3353 Register elements = ToRegister(instr->elements()); |
| 3357 Register result = ToRegister(instr->result()); | 3354 Register result = ToRegister(instr->result()); |
| 3358 Register scratch = scratch0(); | 3355 Register scratch = scratch0(); |
| 3359 Register store_base = scratch; | 3356 Register store_base = scratch; |
| 3360 int offset = 0; | 3357 int offset = instr->base_offset(); |
| 3361 | 3358 |
| 3362 if (instr->key()->IsConstantOperand()) { | 3359 if (instr->key()->IsConstantOperand()) { |
| 3363 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3360 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 3364 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 3361 offset += ToInteger32(const_operand) * kPointerSize; |
| 3365 instr->additional_index()); | |
| 3366 store_base = elements; | 3362 store_base = elements; |
| 3367 } else { | 3363 } else { |
| 3368 Register key = ToRegister(instr->key()); | 3364 Register key = ToRegister(instr->key()); |
| 3369 // Even though the HLoadKeyed instruction forces the input | 3365 // Even though the HLoadKeyed instruction forces the input |
| 3370 // representation for the key to be an integer, the input gets replaced | 3366 // representation for the key to be an integer, the input gets replaced |
| 3371 // during bound check elimination with the index argument to the bounds | 3367 // during bound check elimination with the index argument to the bounds |
| 3372 // check, which can be tagged, so that case must be handled here, too. | 3368 // check, which can be tagged, so that case must be handled here, too. |
| 3373 if (instr->hydrogen()->key()->representation().IsSmi()) { | 3369 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3374 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 3370 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
| 3375 } else { | 3371 } else { |
| 3376 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 3372 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 3377 } | 3373 } |
| 3378 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 3379 } | 3374 } |
| 3380 __ ldr(result, FieldMemOperand(store_base, offset)); | 3375 __ ldr(result, MemOperand(store_base, offset)); |
| 3381 | 3376 |
| 3382 // Check for the hole value. | 3377 // Check for the hole value. |
| 3383 if (instr->hydrogen()->RequiresHoleCheck()) { | 3378 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3384 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3379 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 3385 __ SmiTst(result); | 3380 __ SmiTst(result); |
| 3386 DeoptimizeIf(ne, instr->environment()); | 3381 DeoptimizeIf(ne, instr->environment()); |
| 3387 } else { | 3382 } else { |
| 3388 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3383 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 3389 __ cmp(result, scratch); | 3384 __ cmp(result, scratch); |
| 3390 DeoptimizeIf(eq, instr->environment()); | 3385 DeoptimizeIf(eq, instr->environment()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3403 } | 3398 } |
| 3404 } | 3399 } |
| 3405 | 3400 |
| 3406 | 3401 |
| 3407 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3402 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
| 3408 Register base, | 3403 Register base, |
| 3409 bool key_is_constant, | 3404 bool key_is_constant, |
| 3410 int constant_key, | 3405 int constant_key, |
| 3411 int element_size, | 3406 int element_size, |
| 3412 int shift_size, | 3407 int shift_size, |
| 3413 int additional_index, | 3408 int base_offset) { |
| 3414 int additional_offset) { | 3409 if (key_is_constant) { |
| 3415 if (additional_index != 0 && !key_is_constant) { | 3410 return MemOperand(base, (constant_key << element_size) + base_offset); |
| 3416 additional_index *= 1 << (element_size - shift_size); | |
| 3417 __ add(scratch0(), key, Operand(additional_index)); | |
| 3418 } | 3411 } |
| 3419 | 3412 |
| 3420 if (key_is_constant) { | 3413 if (base_offset == 0) { |
| 3421 return MemOperand(base, | |
| 3422 (constant_key << element_size) + additional_offset); | |
| 3423 } | |
| 3424 | |
| 3425 if (additional_index == 0) { | |
| 3426 if (shift_size >= 0) { | 3414 if (shift_size >= 0) { |
| 3427 return MemOperand(base, key, LSL, shift_size); | 3415 return MemOperand(base, key, LSL, shift_size); |
| 3428 } else { | 3416 } else { |
| 3429 ASSERT_EQ(-1, shift_size); | 3417 ASSERT_EQ(-1, shift_size); |
| 3430 return MemOperand(base, key, LSR, 1); | 3418 return MemOperand(base, key, LSR, 1); |
| 3431 } | 3419 } |
| 3432 } | 3420 } |
| 3433 | 3421 |
| 3434 if (shift_size >= 0) { | 3422 if (shift_size >= 0) { |
| 3423 ASSERT((base_offset & ((1 << shift_size) - 1)) == 0); |
| 3424 __ add(scratch0(), key, Operand(base_offset >> shift_size)); |
| 3435 return MemOperand(base, scratch0(), LSL, shift_size); | 3425 return MemOperand(base, scratch0(), LSL, shift_size); |
| 3436 } else { | 3426 } else { |
| 3437 ASSERT_EQ(-1, shift_size); | 3427 ASSERT_EQ(-1, shift_size); |
| 3428 __ add(scratch0(), key, Operand(base_offset << 1)); |
| 3438 return MemOperand(base, scratch0(), LSR, 1); | 3429 return MemOperand(base, scratch0(), LSR, 1); |
| 3439 } | 3430 } |
| 3440 } | 3431 } |
| 3441 | 3432 |
| 3442 | 3433 |
| 3443 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3434 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3444 ASSERT(ToRegister(instr->context()).is(cp)); | 3435 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3445 ASSERT(ToRegister(instr->object()).is(r1)); | 3436 ASSERT(ToRegister(instr->object()).is(r1)); |
| 3446 ASSERT(ToRegister(instr->key()).is(r0)); | 3437 ASSERT(ToRegister(instr->key()).is(r0)); |
| 3447 | 3438 |
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4319 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4310 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4320 if (constant_key & 0xF0000000) { | 4311 if (constant_key & 0xF0000000) { |
| 4321 Abort(kArrayIndexConstantValueTooBig); | 4312 Abort(kArrayIndexConstantValueTooBig); |
| 4322 } | 4313 } |
| 4323 } else { | 4314 } else { |
| 4324 key = ToRegister(instr->key()); | 4315 key = ToRegister(instr->key()); |
| 4325 } | 4316 } |
| 4326 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4317 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4327 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4318 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4328 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4319 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4329 int additional_offset = instr->additional_index() << element_size_shift; | 4320 int base_offset = instr->base_offset(); |
| 4330 | 4321 |
| 4331 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4322 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4332 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4323 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4333 Register address = scratch0(); | 4324 Register address = scratch0(); |
| 4334 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4325 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4335 if (key_is_constant) { | 4326 if (key_is_constant) { |
| 4336 if (constant_key != 0) { | 4327 if (constant_key != 0) { |
| 4337 __ add(address, external_pointer, | 4328 __ add(address, external_pointer, |
| 4338 Operand(constant_key << element_size_shift)); | 4329 Operand(constant_key << element_size_shift)); |
| 4339 } else { | 4330 } else { |
| 4340 address = external_pointer; | 4331 address = external_pointer; |
| 4341 } | 4332 } |
| 4342 } else { | 4333 } else { |
| 4343 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4334 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
| 4344 } | 4335 } |
| 4345 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4336 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4346 __ vcvt_f32_f64(double_scratch0().low(), value); | 4337 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4347 __ vstr(double_scratch0().low(), address, additional_offset); | 4338 __ vstr(double_scratch0().low(), address, base_offset); |
| 4348 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4339 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 4349 __ vstr(value, address, additional_offset); | 4340 __ vstr(value, address, base_offset); |
| 4350 } | 4341 } |
| 4351 } else { | 4342 } else { |
| 4352 Register value(ToRegister(instr->value())); | 4343 Register value(ToRegister(instr->value())); |
| 4353 MemOperand mem_operand = PrepareKeyedOperand( | 4344 MemOperand mem_operand = PrepareKeyedOperand( |
| 4354 key, external_pointer, key_is_constant, constant_key, | 4345 key, external_pointer, key_is_constant, constant_key, |
| 4355 element_size_shift, shift_size, | 4346 element_size_shift, shift_size, |
| 4356 instr->additional_index(), additional_offset); | 4347 base_offset); |
| 4357 switch (elements_kind) { | 4348 switch (elements_kind) { |
| 4358 case EXTERNAL_PIXEL_ELEMENTS: | 4349 case EXTERNAL_PIXEL_ELEMENTS: |
| 4359 case EXTERNAL_BYTE_ELEMENTS: | 4350 case EXTERNAL_BYTE_ELEMENTS: |
| 4360 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4351 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4361 __ strb(value, mem_operand); | 4352 __ strb(value, mem_operand); |
| 4362 break; | 4353 break; |
| 4363 case EXTERNAL_SHORT_ELEMENTS: | 4354 case EXTERNAL_SHORT_ELEMENTS: |
| 4364 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4355 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4365 __ strh(value, mem_operand); | 4356 __ strh(value, mem_operand); |
| 4366 break; | 4357 break; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4384 } | 4375 } |
| 4385 } | 4376 } |
| 4386 | 4377 |
| 4387 | 4378 |
| 4388 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4379 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4389 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4380 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 4390 Register elements = ToRegister(instr->elements()); | 4381 Register elements = ToRegister(instr->elements()); |
| 4391 Register scratch = scratch0(); | 4382 Register scratch = scratch0(); |
| 4392 DwVfpRegister double_scratch = double_scratch0(); | 4383 DwVfpRegister double_scratch = double_scratch0(); |
| 4393 bool key_is_constant = instr->key()->IsConstantOperand(); | 4384 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4385 int base_offset = instr->base_offset(); |
| 4394 | 4386 |
| 4395 // Calculate the effective address of the slot in the array to store the | 4387 // Calculate the effective address of the slot in the array to store the |
| 4396 // double value. | 4388 // double value. |
| 4397 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4389 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4398 if (key_is_constant) { | 4390 if (key_is_constant) { |
| 4399 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4391 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4400 if (constant_key & 0xF0000000) { | 4392 if (constant_key & 0xF0000000) { |
| 4401 Abort(kArrayIndexConstantValueTooBig); | 4393 Abort(kArrayIndexConstantValueTooBig); |
| 4402 } | 4394 } |
| 4403 __ add(scratch, elements, | 4395 __ add(scratch, elements, |
| 4404 Operand((constant_key << element_size_shift) + | 4396 Operand((constant_key << element_size_shift) + base_offset)); |
| 4405 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4406 } else { | 4397 } else { |
| 4407 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4398 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4408 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4399 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4409 __ add(scratch, elements, | 4400 __ add(scratch, elements, Operand(base_offset)); |
| 4410 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4411 __ add(scratch, scratch, | 4401 __ add(scratch, scratch, |
| 4412 Operand(ToRegister(instr->key()), LSL, shift_size)); | 4402 Operand(ToRegister(instr->key()), LSL, shift_size)); |
| 4413 } | 4403 } |
| 4414 | 4404 |
| 4415 if (instr->NeedsCanonicalization()) { | 4405 if (instr->NeedsCanonicalization()) { |
| 4416 // Force a canonical NaN. | 4406 // Force a canonical NaN. |
| 4417 if (masm()->emit_debug_code()) { | 4407 if (masm()->emit_debug_code()) { |
| 4418 __ vmrs(ip); | 4408 __ vmrs(ip); |
| 4419 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); | 4409 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); |
| 4420 __ Assert(ne, kDefaultNaNModeNotSet); | 4410 __ Assert(ne, kDefaultNaNModeNotSet); |
| 4421 } | 4411 } |
| 4422 __ VFPCanonicalizeNaN(double_scratch, value); | 4412 __ VFPCanonicalizeNaN(double_scratch, value); |
| 4423 __ vstr(double_scratch, scratch, | 4413 __ vstr(double_scratch, scratch, 0); |
| 4424 instr->additional_index() << element_size_shift); | |
| 4425 } else { | 4414 } else { |
| 4426 __ vstr(value, scratch, instr->additional_index() << element_size_shift); | 4415 __ vstr(value, scratch, 0); |
| 4427 } | 4416 } |
| 4428 } | 4417 } |
| 4429 | 4418 |
| 4430 | 4419 |
| 4431 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4420 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4432 Register value = ToRegister(instr->value()); | 4421 Register value = ToRegister(instr->value()); |
| 4433 Register elements = ToRegister(instr->elements()); | 4422 Register elements = ToRegister(instr->elements()); |
| 4434 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4423 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
| 4435 : no_reg; | 4424 : no_reg; |
| 4436 Register scratch = scratch0(); | 4425 Register scratch = scratch0(); |
| 4437 Register store_base = scratch; | 4426 Register store_base = scratch; |
| 4438 int offset = 0; | 4427 int offset = instr->base_offset(); |
| 4439 | 4428 |
| 4440 // Do the store. | 4429 // Do the store. |
| 4441 if (instr->key()->IsConstantOperand()) { | 4430 if (instr->key()->IsConstantOperand()) { |
| 4442 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4431 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 4443 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 4432 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 4444 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 4433 offset += ToInteger32(const_operand) * kPointerSize; |
| 4445 instr->additional_index()); | |
| 4446 store_base = elements; | 4434 store_base = elements; |
| 4447 } else { | 4435 } else { |
| 4448 // Even though the HLoadKeyed instruction forces the input | 4436 // Even though the HLoadKeyed instruction forces the input |
| 4449 // representation for the key to be an integer, the input gets replaced | 4437 // representation for the key to be an integer, the input gets replaced |
| 4450 // during bound check elimination with the index argument to the bounds | 4438 // during bound check elimination with the index argument to the bounds |
| 4451 // check, which can be tagged, so that case must be handled here, too. | 4439 // check, which can be tagged, so that case must be handled here, too. |
| 4452 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4440 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4453 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 4441 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
| 4454 } else { | 4442 } else { |
| 4455 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 4443 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 4456 } | 4444 } |
| 4457 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 4458 } | 4445 } |
| 4459 __ str(value, FieldMemOperand(store_base, offset)); | 4446 __ str(value, MemOperand(store_base, offset)); |
| 4460 | 4447 |
| 4461 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4448 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4462 SmiCheck check_needed = | 4449 SmiCheck check_needed = |
| 4463 instr->hydrogen()->value()->IsHeapObject() | 4450 instr->hydrogen()->value()->IsHeapObject() |
| 4464 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4451 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4465 // Compute address of modified element and store it into key register. | 4452 // Compute address of modified element and store it into key register. |
| 4466 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | 4453 __ add(key, store_base, Operand(offset)); |
| 4467 __ RecordWrite(elements, | 4454 __ RecordWrite(elements, |
| 4468 key, | 4455 key, |
| 4469 value, | 4456 value, |
| 4470 GetLinkRegisterState(), | 4457 GetLinkRegisterState(), |
| 4471 kSaveFPRegs, | 4458 kSaveFPRegs, |
| 4472 EMIT_REMEMBERED_SET, | 4459 EMIT_REMEMBERED_SET, |
| 4473 check_needed); | 4460 check_needed); |
| 4474 } | 4461 } |
| 4475 } | 4462 } |
| 4476 | 4463 |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5857 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { | 5844 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { |
| 5858 Register object = ToRegister(instr->object()); | 5845 Register object = ToRegister(instr->object()); |
| 5859 Register index = ToRegister(instr->index()); | 5846 Register index = ToRegister(instr->index()); |
| 5860 Register result = ToRegister(instr->result()); | 5847 Register result = ToRegister(instr->result()); |
| 5861 Register scratch = scratch0(); | 5848 Register scratch = scratch0(); |
| 5862 | 5849 |
| 5863 Label out_of_object, done; | 5850 Label out_of_object, done; |
| 5864 __ cmp(index, Operand::Zero()); | 5851 __ cmp(index, Operand::Zero()); |
| 5865 __ b(lt, &out_of_object); | 5852 __ b(lt, &out_of_object); |
| 5866 | 5853 |
| 5867 __ add(scratch, object, Operand::PointerOffsetFromSmiKey(index)); | 5854 __ add(scratch, object, Operand(index, LSL, kPointerSizeLog2)); |
| 5868 __ ldr(result, FieldMemOperand(scratch, JSObject::kHeaderSize)); | 5855 __ ldr(result, FieldMemOperand(scratch, JSObject::kHeaderSize)); |
| 5869 | 5856 |
| 5870 __ b(&done); | 5857 __ b(&done); |
| 5871 | 5858 |
| 5872 __ bind(&out_of_object); | 5859 __ bind(&out_of_object); |
| 5873 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5860 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5874 // Index is equal to negated out of object property index plus 1. | 5861 // Index is equal to negated out of object property index plus 1. |
| 5875 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); | 5862 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2)); |
| 5876 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | |
| 5877 __ ldr(result, FieldMemOperand(scratch, | 5863 __ ldr(result, FieldMemOperand(scratch, |
| 5878 FixedArray::kHeaderSize - kPointerSize)); | 5864 FixedArray::kHeaderSize - kPointerSize)); |
| 5879 __ bind(&done); | 5865 __ bind(&done); |
| 5880 } | 5866 } |
| 5881 | 5867 |
| 5882 | 5868 |
| 5883 #undef __ | 5869 #undef __ |
| 5884 | 5870 |
| 5885 } } // namespace v8::internal | 5871 } } // namespace v8::internal |
| OLD | NEW |