| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "arm/lithium-codegen-arm.h" | 7 #include "arm/lithium-codegen-arm.h" |
| 8 #include "arm/lithium-gap-resolver-arm.h" | 8 #include "arm/lithium-gap-resolver-arm.h" |
| 9 #include "code-stubs.h" | 9 #include "code-stubs.h" |
| 10 #include "stub-cache.h" | 10 #include "stub-cache.h" |
| (...skipping 3150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3161 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3161 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3162 if (constant_key & 0xF0000000) { | 3162 if (constant_key & 0xF0000000) { |
| 3163 Abort(kArrayIndexConstantValueTooBig); | 3163 Abort(kArrayIndexConstantValueTooBig); |
| 3164 } | 3164 } |
| 3165 } else { | 3165 } else { |
| 3166 key = ToRegister(instr->key()); | 3166 key = ToRegister(instr->key()); |
| 3167 } | 3167 } |
| 3168 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3168 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3169 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3169 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3170 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3170 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3171 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) | 3171 int base_offset = instr->base_offset(); |
| 3172 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
| 3173 : 0; | |
| 3174 | |
| 3175 | 3172 |
| 3176 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3173 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3177 elements_kind == FLOAT32_ELEMENTS || | 3174 elements_kind == FLOAT32_ELEMENTS || |
| 3178 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 3175 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3179 elements_kind == FLOAT64_ELEMENTS) { | 3176 elements_kind == FLOAT64_ELEMENTS) { |
| 3180 int base_offset = | 3177 int base_offset = instr->base_offset(); |
| 3181 (instr->additional_index() << element_size_shift) + additional_offset; | |
| 3182 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3178 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3183 Operand operand = key_is_constant | 3179 Operand operand = key_is_constant |
| 3184 ? Operand(constant_key << element_size_shift) | 3180 ? Operand(constant_key << element_size_shift) |
| 3185 : Operand(key, LSL, shift_size); | 3181 : Operand(key, LSL, shift_size); |
| 3186 __ add(scratch0(), external_pointer, operand); | 3182 __ add(scratch0(), external_pointer, operand); |
| 3187 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3183 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3188 elements_kind == FLOAT32_ELEMENTS) { | 3184 elements_kind == FLOAT32_ELEMENTS) { |
| 3189 __ vldr(double_scratch0().low(), scratch0(), base_offset); | 3185 __ vldr(double_scratch0().low(), scratch0(), base_offset); |
| 3190 __ vcvt_f64_f32(result, double_scratch0().low()); | 3186 __ vcvt_f64_f32(result, double_scratch0().low()); |
| 3191 } else { // loading doubles, not floats. | 3187 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 3192 __ vldr(result, scratch0(), base_offset); | 3188 __ vldr(result, scratch0(), base_offset); |
| 3193 } | 3189 } |
| 3194 } else { | 3190 } else { |
| 3195 Register result = ToRegister(instr->result()); | 3191 Register result = ToRegister(instr->result()); |
| 3196 MemOperand mem_operand = PrepareKeyedOperand( | 3192 MemOperand mem_operand = PrepareKeyedOperand( |
| 3197 key, external_pointer, key_is_constant, constant_key, | 3193 key, external_pointer, key_is_constant, constant_key, |
| 3198 element_size_shift, shift_size, | 3194 element_size_shift, shift_size, base_offset); |
| 3199 instr->additional_index(), additional_offset); | |
| 3200 switch (elements_kind) { | 3195 switch (elements_kind) { |
| 3201 case EXTERNAL_INT8_ELEMENTS: | 3196 case EXTERNAL_INT8_ELEMENTS: |
| 3202 case INT8_ELEMENTS: | 3197 case INT8_ELEMENTS: |
| 3203 __ ldrsb(result, mem_operand); | 3198 __ ldrsb(result, mem_operand); |
| 3204 break; | 3199 break; |
| 3205 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: | 3200 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 3206 case EXTERNAL_UINT8_ELEMENTS: | 3201 case EXTERNAL_UINT8_ELEMENTS: |
| 3207 case UINT8_ELEMENTS: | 3202 case UINT8_ELEMENTS: |
| 3208 case UINT8_CLAMPED_ELEMENTS: | 3203 case UINT8_CLAMPED_ELEMENTS: |
| 3209 __ ldrb(result, mem_operand); | 3204 __ ldrb(result, mem_operand); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3249 | 3244 |
| 3250 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3245 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 3251 Register elements = ToRegister(instr->elements()); | 3246 Register elements = ToRegister(instr->elements()); |
| 3252 bool key_is_constant = instr->key()->IsConstantOperand(); | 3247 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3253 Register key = no_reg; | 3248 Register key = no_reg; |
| 3254 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3249 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3255 Register scratch = scratch0(); | 3250 Register scratch = scratch0(); |
| 3256 | 3251 |
| 3257 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3252 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 3258 | 3253 |
| 3259 int base_offset = | 3254 int base_offset = instr->base_offset(); |
| 3260 FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
| 3261 (instr->additional_index() << element_size_shift); | |
| 3262 if (key_is_constant) { | 3255 if (key_is_constant) { |
| 3263 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3256 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3264 if (constant_key & 0xF0000000) { | 3257 if (constant_key & 0xF0000000) { |
| 3265 Abort(kArrayIndexConstantValueTooBig); | 3258 Abort(kArrayIndexConstantValueTooBig); |
| 3266 } | 3259 } |
| 3267 base_offset += constant_key << element_size_shift; | 3260 base_offset += constant_key * kDoubleSize; |
| 3268 } | 3261 } |
| 3269 __ add(scratch, elements, Operand(base_offset)); | 3262 __ add(scratch, elements, Operand(base_offset)); |
| 3270 | 3263 |
| 3271 if (!key_is_constant) { | 3264 if (!key_is_constant) { |
| 3272 key = ToRegister(instr->key()); | 3265 key = ToRegister(instr->key()); |
| 3273 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3266 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3274 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3267 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3275 __ add(scratch, scratch, Operand(key, LSL, shift_size)); | 3268 __ add(scratch, scratch, Operand(key, LSL, shift_size)); |
| 3276 } | 3269 } |
| 3277 | 3270 |
| 3278 __ vldr(result, scratch, 0); | 3271 __ vldr(result, scratch, 0); |
| 3279 | 3272 |
| 3280 if (instr->hydrogen()->RequiresHoleCheck()) { | 3273 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3281 __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); | 3274 __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); |
| 3282 __ cmp(scratch, Operand(kHoleNanUpper32)); | 3275 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 3283 DeoptimizeIf(eq, instr->environment()); | 3276 DeoptimizeIf(eq, instr->environment()); |
| 3284 } | 3277 } |
| 3285 } | 3278 } |
| 3286 | 3279 |
| 3287 | 3280 |
| 3288 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3281 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3289 Register elements = ToRegister(instr->elements()); | 3282 Register elements = ToRegister(instr->elements()); |
| 3290 Register result = ToRegister(instr->result()); | 3283 Register result = ToRegister(instr->result()); |
| 3291 Register scratch = scratch0(); | 3284 Register scratch = scratch0(); |
| 3292 Register store_base = scratch; | 3285 Register store_base = scratch; |
| 3293 int offset = 0; | 3286 int offset = instr->base_offset(); |
| 3294 | 3287 |
| 3295 if (instr->key()->IsConstantOperand()) { | 3288 if (instr->key()->IsConstantOperand()) { |
| 3296 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3289 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 3297 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 3290 offset += ToInteger32(const_operand) * kPointerSize; |
| 3298 instr->additional_index()); | |
| 3299 store_base = elements; | 3291 store_base = elements; |
| 3300 } else { | 3292 } else { |
| 3301 Register key = ToRegister(instr->key()); | 3293 Register key = ToRegister(instr->key()); |
| 3302 // Even though the HLoadKeyed instruction forces the input | 3294 // Even though the HLoadKeyed instruction forces the input |
| 3303 // representation for the key to be an integer, the input gets replaced | 3295 // representation for the key to be an integer, the input gets replaced |
| 3304 // during bound check elimination with the index argument to the bounds | 3296 // during bound check elimination with the index argument to the bounds |
| 3305 // check, which can be tagged, so that case must be handled here, too. | 3297 // check, which can be tagged, so that case must be handled here, too. |
| 3306 if (instr->hydrogen()->key()->representation().IsSmi()) { | 3298 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3307 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 3299 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
| 3308 } else { | 3300 } else { |
| 3309 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 3301 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 3310 } | 3302 } |
| 3311 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 3312 } | 3303 } |
| 3313 __ ldr(result, FieldMemOperand(store_base, offset)); | 3304 __ ldr(result, MemOperand(store_base, offset)); |
| 3314 | 3305 |
| 3315 // Check for the hole value. | 3306 // Check for the hole value. |
| 3316 if (instr->hydrogen()->RequiresHoleCheck()) { | 3307 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3317 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3308 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 3318 __ SmiTst(result); | 3309 __ SmiTst(result); |
| 3319 DeoptimizeIf(ne, instr->environment()); | 3310 DeoptimizeIf(ne, instr->environment()); |
| 3320 } else { | 3311 } else { |
| 3321 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3312 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 3322 __ cmp(result, scratch); | 3313 __ cmp(result, scratch); |
| 3323 DeoptimizeIf(eq, instr->environment()); | 3314 DeoptimizeIf(eq, instr->environment()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3336 } | 3327 } |
| 3337 } | 3328 } |
| 3338 | 3329 |
| 3339 | 3330 |
| 3340 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3331 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
| 3341 Register base, | 3332 Register base, |
| 3342 bool key_is_constant, | 3333 bool key_is_constant, |
| 3343 int constant_key, | 3334 int constant_key, |
| 3344 int element_size, | 3335 int element_size, |
| 3345 int shift_size, | 3336 int shift_size, |
| 3346 int additional_index, | 3337 int base_offset) { |
| 3347 int additional_offset) { | |
| 3348 int base_offset = (additional_index << element_size) + additional_offset; | |
| 3349 if (key_is_constant) { | 3338 if (key_is_constant) { |
| 3350 return MemOperand(base, | 3339 return MemOperand(base, (constant_key << element_size) + base_offset); |
| 3351 base_offset + (constant_key << element_size)); | |
| 3352 } | 3340 } |
| 3353 | 3341 |
| 3354 if (additional_offset != 0) { | 3342 if (base_offset == 0) { |
| 3355 __ mov(scratch0(), Operand(base_offset)); | |
| 3356 if (shift_size >= 0) { | |
| 3357 __ add(scratch0(), scratch0(), Operand(key, LSL, shift_size)); | |
| 3358 } else { | |
| 3359 ASSERT_EQ(-1, shift_size); | |
| 3360 // key can be negative, so using ASR here. | |
| 3361 __ add(scratch0(), scratch0(), Operand(key, ASR, 1)); | |
| 3362 } | |
| 3363 return MemOperand(base, scratch0()); | |
| 3364 } | |
| 3365 | |
| 3366 if (additional_index != 0) { | |
| 3367 additional_index *= 1 << (element_size - shift_size); | |
| 3368 __ add(scratch0(), key, Operand(additional_index)); | |
| 3369 } | |
| 3370 | |
| 3371 if (additional_index == 0) { | |
| 3372 if (shift_size >= 0) { | 3343 if (shift_size >= 0) { |
| 3373 return MemOperand(base, key, LSL, shift_size); | 3344 return MemOperand(base, key, LSL, shift_size); |
| 3374 } else { | 3345 } else { |
| 3375 ASSERT_EQ(-1, shift_size); | 3346 ASSERT_EQ(-1, shift_size); |
| 3376 return MemOperand(base, key, LSR, 1); | 3347 return MemOperand(base, key, LSR, 1); |
| 3377 } | 3348 } |
| 3378 } | 3349 } |
| 3379 | 3350 |
| 3380 if (shift_size >= 0) { | 3351 if (shift_size >= 0) { |
| 3381 return MemOperand(base, scratch0(), LSL, shift_size); | 3352 __ add(scratch0(), base, Operand(key, LSL, shift_size)); |
| 3353 return MemOperand(scratch0(), base_offset); |
| 3382 } else { | 3354 } else { |
| 3383 ASSERT_EQ(-1, shift_size); | 3355 ASSERT_EQ(-1, shift_size); |
| 3384 return MemOperand(base, scratch0(), LSR, 1); | 3356 __ add(scratch0(), base, Operand(key, ASR, 1)); |
| 3357 return MemOperand(scratch0(), base_offset); |
| 3385 } | 3358 } |
| 3386 } | 3359 } |
| 3387 | 3360 |
| 3388 | 3361 |
| 3389 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3362 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3390 ASSERT(ToRegister(instr->context()).is(cp)); | 3363 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3391 ASSERT(ToRegister(instr->object()).is(r1)); | 3364 ASSERT(ToRegister(instr->object()).is(r1)); |
| 3392 ASSERT(ToRegister(instr->key()).is(r0)); | 3365 ASSERT(ToRegister(instr->key()).is(r0)); |
| 3393 | 3366 |
| 3394 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3367 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4204 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4177 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4205 if (constant_key & 0xF0000000) { | 4178 if (constant_key & 0xF0000000) { |
| 4206 Abort(kArrayIndexConstantValueTooBig); | 4179 Abort(kArrayIndexConstantValueTooBig); |
| 4207 } | 4180 } |
| 4208 } else { | 4181 } else { |
| 4209 key = ToRegister(instr->key()); | 4182 key = ToRegister(instr->key()); |
| 4210 } | 4183 } |
| 4211 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4184 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4212 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4185 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4213 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4186 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4214 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) | 4187 int base_offset = instr->base_offset(); |
| 4215 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
| 4216 : 0; | |
| 4217 | 4188 |
| 4218 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4189 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4219 elements_kind == FLOAT32_ELEMENTS || | 4190 elements_kind == FLOAT32_ELEMENTS || |
| 4220 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4191 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4221 elements_kind == FLOAT64_ELEMENTS) { | 4192 elements_kind == FLOAT64_ELEMENTS) { |
| 4222 int base_offset = | |
| 4223 (instr->additional_index() << element_size_shift) + additional_offset; | |
| 4224 Register address = scratch0(); | 4193 Register address = scratch0(); |
| 4225 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4194 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4226 if (key_is_constant) { | 4195 if (key_is_constant) { |
| 4227 if (constant_key != 0) { | 4196 if (constant_key != 0) { |
| 4228 __ add(address, external_pointer, | 4197 __ add(address, external_pointer, |
| 4229 Operand(constant_key << element_size_shift)); | 4198 Operand(constant_key << element_size_shift)); |
| 4230 } else { | 4199 } else { |
| 4231 address = external_pointer; | 4200 address = external_pointer; |
| 4232 } | 4201 } |
| 4233 } else { | 4202 } else { |
| 4234 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4203 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
| 4235 } | 4204 } |
| 4236 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4205 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4237 elements_kind == FLOAT32_ELEMENTS) { | 4206 elements_kind == FLOAT32_ELEMENTS) { |
| 4238 __ vcvt_f32_f64(double_scratch0().low(), value); | 4207 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4239 __ vstr(double_scratch0().low(), address, base_offset); | 4208 __ vstr(double_scratch0().low(), address, base_offset); |
| 4240 } else { // Storing doubles, not floats. | 4209 } else { // Storing doubles, not floats. |
| 4241 __ vstr(value, address, base_offset); | 4210 __ vstr(value, address, base_offset); |
| 4242 } | 4211 } |
| 4243 } else { | 4212 } else { |
| 4244 Register value(ToRegister(instr->value())); | 4213 Register value(ToRegister(instr->value())); |
| 4245 MemOperand mem_operand = PrepareKeyedOperand( | 4214 MemOperand mem_operand = PrepareKeyedOperand( |
| 4246 key, external_pointer, key_is_constant, constant_key, | 4215 key, external_pointer, key_is_constant, constant_key, |
| 4247 element_size_shift, shift_size, | 4216 element_size_shift, shift_size, |
| 4248 instr->additional_index(), additional_offset); | 4217 base_offset); |
| 4249 switch (elements_kind) { | 4218 switch (elements_kind) { |
| 4250 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: | 4219 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 4251 case EXTERNAL_INT8_ELEMENTS: | 4220 case EXTERNAL_INT8_ELEMENTS: |
| 4252 case EXTERNAL_UINT8_ELEMENTS: | 4221 case EXTERNAL_UINT8_ELEMENTS: |
| 4253 case UINT8_ELEMENTS: | 4222 case UINT8_ELEMENTS: |
| 4254 case UINT8_CLAMPED_ELEMENTS: | 4223 case UINT8_CLAMPED_ELEMENTS: |
| 4255 case INT8_ELEMENTS: | 4224 case INT8_ELEMENTS: |
| 4256 __ strb(value, mem_operand); | 4225 __ strb(value, mem_operand); |
| 4257 break; | 4226 break; |
| 4258 case EXTERNAL_INT16_ELEMENTS: | 4227 case EXTERNAL_INT16_ELEMENTS: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4285 } | 4254 } |
| 4286 } | 4255 } |
| 4287 | 4256 |
| 4288 | 4257 |
| 4289 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4258 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4290 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4259 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 4291 Register elements = ToRegister(instr->elements()); | 4260 Register elements = ToRegister(instr->elements()); |
| 4292 Register scratch = scratch0(); | 4261 Register scratch = scratch0(); |
| 4293 DwVfpRegister double_scratch = double_scratch0(); | 4262 DwVfpRegister double_scratch = double_scratch0(); |
| 4294 bool key_is_constant = instr->key()->IsConstantOperand(); | 4263 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4264 int base_offset = instr->base_offset(); |
| 4295 | 4265 |
| 4296 // Calculate the effective address of the slot in the array to store the | 4266 // Calculate the effective address of the slot in the array to store the |
| 4297 // double value. | 4267 // double value. |
| 4298 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4268 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4299 if (key_is_constant) { | 4269 if (key_is_constant) { |
| 4300 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4270 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4301 if (constant_key & 0xF0000000) { | 4271 if (constant_key & 0xF0000000) { |
| 4302 Abort(kArrayIndexConstantValueTooBig); | 4272 Abort(kArrayIndexConstantValueTooBig); |
| 4303 } | 4273 } |
| 4304 __ add(scratch, elements, | 4274 __ add(scratch, elements, |
| 4305 Operand((constant_key << element_size_shift) + | 4275 Operand((constant_key << element_size_shift) + base_offset)); |
| 4306 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4307 } else { | 4276 } else { |
| 4308 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4277 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4309 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4278 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4310 __ add(scratch, elements, | 4279 __ add(scratch, elements, Operand(base_offset)); |
| 4311 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4312 __ add(scratch, scratch, | 4280 __ add(scratch, scratch, |
| 4313 Operand(ToRegister(instr->key()), LSL, shift_size)); | 4281 Operand(ToRegister(instr->key()), LSL, shift_size)); |
| 4314 } | 4282 } |
| 4315 | 4283 |
| 4316 if (instr->NeedsCanonicalization()) { | 4284 if (instr->NeedsCanonicalization()) { |
| 4317 // Force a canonical NaN. | 4285 // Force a canonical NaN. |
| 4318 if (masm()->emit_debug_code()) { | 4286 if (masm()->emit_debug_code()) { |
| 4319 __ vmrs(ip); | 4287 __ vmrs(ip); |
| 4320 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); | 4288 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); |
| 4321 __ Assert(ne, kDefaultNaNModeNotSet); | 4289 __ Assert(ne, kDefaultNaNModeNotSet); |
| 4322 } | 4290 } |
| 4323 __ VFPCanonicalizeNaN(double_scratch, value); | 4291 __ VFPCanonicalizeNaN(double_scratch, value); |
| 4324 __ vstr(double_scratch, scratch, | 4292 __ vstr(double_scratch, scratch, 0); |
| 4325 instr->additional_index() << element_size_shift); | |
| 4326 } else { | 4293 } else { |
| 4327 __ vstr(value, scratch, instr->additional_index() << element_size_shift); | 4294 __ vstr(value, scratch, 0); |
| 4328 } | 4295 } |
| 4329 } | 4296 } |
| 4330 | 4297 |
| 4331 | 4298 |
| 4332 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4299 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4333 Register value = ToRegister(instr->value()); | 4300 Register value = ToRegister(instr->value()); |
| 4334 Register elements = ToRegister(instr->elements()); | 4301 Register elements = ToRegister(instr->elements()); |
| 4335 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4302 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
| 4336 : no_reg; | 4303 : no_reg; |
| 4337 Register scratch = scratch0(); | 4304 Register scratch = scratch0(); |
| 4338 Register store_base = scratch; | 4305 Register store_base = scratch; |
| 4339 int offset = 0; | 4306 int offset = instr->base_offset(); |
| 4340 | 4307 |
| 4341 // Do the store. | 4308 // Do the store. |
| 4342 if (instr->key()->IsConstantOperand()) { | 4309 if (instr->key()->IsConstantOperand()) { |
| 4343 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4310 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 4344 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 4311 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 4345 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 4312 offset += ToInteger32(const_operand) * kPointerSize; |
| 4346 instr->additional_index()); | |
| 4347 store_base = elements; | 4313 store_base = elements; |
| 4348 } else { | 4314 } else { |
| 4349 // Even though the HLoadKeyed instruction forces the input | 4315 // Even though the HLoadKeyed instruction forces the input |
| 4350 // representation for the key to be an integer, the input gets replaced | 4316 // representation for the key to be an integer, the input gets replaced |
| 4351 // during bound check elimination with the index argument to the bounds | 4317 // during bound check elimination with the index argument to the bounds |
| 4352 // check, which can be tagged, so that case must be handled here, too. | 4318 // check, which can be tagged, so that case must be handled here, too. |
| 4353 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4319 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4354 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 4320 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
| 4355 } else { | 4321 } else { |
| 4356 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 4322 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 4357 } | 4323 } |
| 4358 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 4359 } | 4324 } |
| 4360 __ str(value, FieldMemOperand(store_base, offset)); | 4325 __ str(value, MemOperand(store_base, offset)); |
| 4361 | 4326 |
| 4362 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4327 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4363 SmiCheck check_needed = | 4328 SmiCheck check_needed = |
| 4364 instr->hydrogen()->value()->IsHeapObject() | 4329 instr->hydrogen()->value()->IsHeapObject() |
| 4365 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4330 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4366 // Compute address of modified element and store it into key register. | 4331 // Compute address of modified element and store it into key register. |
| 4367 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | 4332 __ add(key, store_base, Operand(offset)); |
| 4368 __ RecordWrite(elements, | 4333 __ RecordWrite(elements, |
| 4369 key, | 4334 key, |
| 4370 value, | 4335 value, |
| 4371 GetLinkRegisterState(), | 4336 GetLinkRegisterState(), |
| 4372 kSaveFPRegs, | 4337 kSaveFPRegs, |
| 4373 EMIT_REMEMBERED_SET, | 4338 EMIT_REMEMBERED_SET, |
| 4374 check_needed); | 4339 check_needed); |
| 4375 } | 4340 } |
| 4376 } | 4341 } |
| 4377 | 4342 |
| (...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5856 __ ldr(result, FieldMemOperand(scratch, | 5821 __ ldr(result, FieldMemOperand(scratch, |
| 5857 FixedArray::kHeaderSize - kPointerSize)); | 5822 FixedArray::kHeaderSize - kPointerSize)); |
| 5858 __ bind(deferred->exit()); | 5823 __ bind(deferred->exit()); |
| 5859 __ bind(&done); | 5824 __ bind(&done); |
| 5860 } | 5825 } |
| 5861 | 5826 |
| 5862 | 5827 |
| 5863 #undef __ | 5828 #undef __ |
| 5864 | 5829 |
| 5865 } } // namespace v8::internal | 5830 } } // namespace v8::internal |
| OLD | NEW |