OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
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 3092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3103 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3103 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3104 if (constant_key & 0xF0000000) { | 3104 if (constant_key & 0xF0000000) { |
3105 Abort(kArrayIndexConstantValueTooBig); | 3105 Abort(kArrayIndexConstantValueTooBig); |
3106 } | 3106 } |
3107 } else { | 3107 } else { |
3108 key = ToRegister(instr->key()); | 3108 key = ToRegister(instr->key()); |
3109 } | 3109 } |
3110 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3110 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3111 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3111 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
3112 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3112 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
3113 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) | 3113 int base_offset = instr->base_offset(); |
3114 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
3115 : 0; | |
3116 | 3114 |
3117 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3115 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
3118 elements_kind == FLOAT32_ELEMENTS || | 3116 elements_kind == FLOAT32_ELEMENTS || |
3119 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 3117 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
3120 elements_kind == FLOAT64_ELEMENTS) { | 3118 elements_kind == FLOAT64_ELEMENTS) { |
3121 int base_offset = | 3119 int base_offset = instr->base_offset(); |
3122 (instr->additional_index() << element_size_shift) + additional_offset; | |
3123 FPURegister result = ToDoubleRegister(instr->result()); | 3120 FPURegister result = ToDoubleRegister(instr->result()); |
3124 if (key_is_constant) { | 3121 if (key_is_constant) { |
3125 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); | 3122 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); |
3126 } else { | 3123 } else { |
3127 __ sll(scratch0(), key, shift_size); | 3124 __ sll(scratch0(), key, shift_size); |
3128 __ Addu(scratch0(), scratch0(), external_pointer); | 3125 __ Addu(scratch0(), scratch0(), external_pointer); |
3129 } | 3126 } |
3130 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3127 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
3131 elements_kind == FLOAT32_ELEMENTS) { | 3128 elements_kind == FLOAT32_ELEMENTS) { |
3132 __ lwc1(result, MemOperand(scratch0(), base_offset)); | 3129 __ lwc1(result, MemOperand(scratch0(), base_offset)); |
3133 __ cvt_d_s(result, result); | 3130 __ cvt_d_s(result, result); |
3134 } else { // loading doubles, not floats. | 3131 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3135 __ ldc1(result, MemOperand(scratch0(), base_offset)); | 3132 __ ldc1(result, MemOperand(scratch0(), base_offset)); |
3136 } | 3133 } |
3137 } else { | 3134 } else { |
3138 Register result = ToRegister(instr->result()); | 3135 Register result = ToRegister(instr->result()); |
3139 MemOperand mem_operand = PrepareKeyedOperand( | 3136 MemOperand mem_operand = PrepareKeyedOperand( |
3140 key, external_pointer, key_is_constant, constant_key, | 3137 key, external_pointer, key_is_constant, constant_key, |
3141 element_size_shift, shift_size, | 3138 element_size_shift, shift_size, base_offset); |
3142 instr->additional_index(), additional_offset); | |
3143 switch (elements_kind) { | 3139 switch (elements_kind) { |
3144 case EXTERNAL_INT8_ELEMENTS: | 3140 case EXTERNAL_INT8_ELEMENTS: |
3145 case INT8_ELEMENTS: | 3141 case INT8_ELEMENTS: |
3146 __ lb(result, mem_operand); | 3142 __ lb(result, mem_operand); |
3147 break; | 3143 break; |
3148 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: | 3144 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
3149 case EXTERNAL_UINT8_ELEMENTS: | 3145 case EXTERNAL_UINT8_ELEMENTS: |
3150 case UINT8_ELEMENTS: | 3146 case UINT8_ELEMENTS: |
3151 case UINT8_CLAMPED_ELEMENTS: | 3147 case UINT8_CLAMPED_ELEMENTS: |
3152 __ lbu(result, mem_operand); | 3148 __ lbu(result, mem_operand); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3192 | 3188 |
3193 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3189 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
3194 Register elements = ToRegister(instr->elements()); | 3190 Register elements = ToRegister(instr->elements()); |
3195 bool key_is_constant = instr->key()->IsConstantOperand(); | 3191 bool key_is_constant = instr->key()->IsConstantOperand(); |
3196 Register key = no_reg; | 3192 Register key = no_reg; |
3197 DoubleRegister result = ToDoubleRegister(instr->result()); | 3193 DoubleRegister result = ToDoubleRegister(instr->result()); |
3198 Register scratch = scratch0(); | 3194 Register scratch = scratch0(); |
3199 | 3195 |
3200 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3196 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
3201 | 3197 |
3202 int base_offset = | 3198 int base_offset = instr->base_offset(); |
3203 FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
3204 (instr->additional_index() << element_size_shift); | |
3205 if (key_is_constant) { | 3199 if (key_is_constant) { |
3206 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3200 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3207 if (constant_key & 0xF0000000) { | 3201 if (constant_key & 0xF0000000) { |
3208 Abort(kArrayIndexConstantValueTooBig); | 3202 Abort(kArrayIndexConstantValueTooBig); |
3209 } | 3203 } |
3210 base_offset += constant_key << element_size_shift; | 3204 base_offset += constant_key * kDoubleSize; |
3211 } | 3205 } |
3212 __ Addu(scratch, elements, Operand(base_offset)); | 3206 __ Addu(scratch, elements, Operand(base_offset)); |
3213 | 3207 |
3214 if (!key_is_constant) { | 3208 if (!key_is_constant) { |
3215 key = ToRegister(instr->key()); | 3209 key = ToRegister(instr->key()); |
3216 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3210 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
3217 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3211 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
3218 __ sll(at, key, shift_size); | 3212 __ sll(at, key, shift_size); |
3219 __ Addu(scratch, scratch, at); | 3213 __ Addu(scratch, scratch, at); |
3220 } | 3214 } |
3221 | 3215 |
3222 __ ldc1(result, MemOperand(scratch)); | 3216 __ ldc1(result, MemOperand(scratch)); |
3223 | 3217 |
3224 if (instr->hydrogen()->RequiresHoleCheck()) { | 3218 if (instr->hydrogen()->RequiresHoleCheck()) { |
3225 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); | 3219 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); |
3226 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | 3220 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
3227 } | 3221 } |
3228 } | 3222 } |
3229 | 3223 |
3230 | 3224 |
3231 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3225 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3232 Register elements = ToRegister(instr->elements()); | 3226 Register elements = ToRegister(instr->elements()); |
3233 Register result = ToRegister(instr->result()); | 3227 Register result = ToRegister(instr->result()); |
3234 Register scratch = scratch0(); | 3228 Register scratch = scratch0(); |
3235 Register store_base = scratch; | 3229 Register store_base = scratch; |
3236 int offset = 0; | 3230 int offset = instr->base_offset(); |
3237 | 3231 |
3238 if (instr->key()->IsConstantOperand()) { | 3232 if (instr->key()->IsConstantOperand()) { |
3239 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3233 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
3240 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 3234 offset += ToInteger32(const_operand) * kPointerSize; |
3241 instr->additional_index()); | |
3242 store_base = elements; | 3235 store_base = elements; |
3243 } else { | 3236 } else { |
3244 Register key = ToRegister(instr->key()); | 3237 Register key = ToRegister(instr->key()); |
3245 // Even though the HLoadKeyed instruction forces the input | 3238 // Even though the HLoadKeyed instruction forces the input |
3246 // representation for the key to be an integer, the input gets replaced | 3239 // representation for the key to be an integer, the input gets replaced |
3247 // during bound check elimination with the index argument to the bounds | 3240 // during bound check elimination with the index argument to the bounds |
3248 // check, which can be tagged, so that case must be handled here, too. | 3241 // check, which can be tagged, so that case must be handled here, too. |
3249 if (instr->hydrogen()->key()->representation().IsSmi()) { | 3242 if (instr->hydrogen()->key()->representation().IsSmi()) { |
3250 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); | 3243 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); |
3251 __ addu(scratch, elements, scratch); | 3244 __ addu(scratch, elements, scratch); |
3252 } else { | 3245 } else { |
3253 __ sll(scratch, key, kPointerSizeLog2); | 3246 __ sll(scratch, key, kPointerSizeLog2); |
3254 __ addu(scratch, elements, scratch); | 3247 __ addu(scratch, elements, scratch); |
3255 } | 3248 } |
3256 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
3257 } | 3249 } |
3258 __ lw(result, FieldMemOperand(store_base, offset)); | 3250 __ lw(result, MemOperand(store_base, offset)); |
3259 | 3251 |
3260 // Check for the hole value. | 3252 // Check for the hole value. |
3261 if (instr->hydrogen()->RequiresHoleCheck()) { | 3253 if (instr->hydrogen()->RequiresHoleCheck()) { |
3262 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3254 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
3263 __ SmiTst(result, scratch); | 3255 __ SmiTst(result, scratch); |
3264 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3256 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
3265 } else { | 3257 } else { |
3266 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3258 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
3267 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); | 3259 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); |
3268 } | 3260 } |
(...skipping 11 matching lines...) Expand all Loading... |
3280 } | 3272 } |
3281 } | 3273 } |
3282 | 3274 |
3283 | 3275 |
3284 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3276 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
3285 Register base, | 3277 Register base, |
3286 bool key_is_constant, | 3278 bool key_is_constant, |
3287 int constant_key, | 3279 int constant_key, |
3288 int element_size, | 3280 int element_size, |
3289 int shift_size, | 3281 int shift_size, |
3290 int additional_index, | 3282 int base_offset) { |
3291 int additional_offset) { | |
3292 int base_offset = (additional_index << element_size) + additional_offset; | |
3293 if (key_is_constant) { | 3283 if (key_is_constant) { |
3294 return MemOperand(base, | 3284 return MemOperand(base, (constant_key << element_size) + base_offset); |
3295 base_offset + (constant_key << element_size)); | |
3296 } | 3285 } |
3297 | 3286 |
3298 if (additional_offset != 0) { | 3287 if (base_offset == 0) { |
3299 if (shift_size >= 0) { | |
3300 __ sll(scratch0(), key, shift_size); | |
3301 __ Addu(scratch0(), scratch0(), Operand(base_offset)); | |
3302 } else { | |
3303 ASSERT_EQ(-1, shift_size); | |
3304 // Key can be negative, so using sra here. | |
3305 __ sra(scratch0(), key, 1); | |
3306 __ Addu(scratch0(), scratch0(), Operand(base_offset)); | |
3307 } | |
3308 __ Addu(scratch0(), base, scratch0()); | |
3309 return MemOperand(scratch0()); | |
3310 } | |
3311 | |
3312 if (additional_index != 0) { | |
3313 additional_index *= 1 << (element_size - shift_size); | |
3314 __ Addu(scratch0(), key, Operand(additional_index)); | |
3315 } | |
3316 | |
3317 if (additional_index == 0) { | |
3318 if (shift_size >= 0) { | 3288 if (shift_size >= 0) { |
3319 __ sll(scratch0(), key, shift_size); | 3289 __ sll(scratch0(), key, shift_size); |
3320 __ Addu(scratch0(), base, scratch0()); | 3290 __ Addu(scratch0(), base, scratch0()); |
3321 return MemOperand(scratch0()); | 3291 return MemOperand(scratch0()); |
3322 } else { | 3292 } else { |
3323 ASSERT_EQ(-1, shift_size); | 3293 ASSERT_EQ(-1, shift_size); |
3324 __ srl(scratch0(), key, 1); | 3294 __ srl(scratch0(), key, 1); |
3325 __ Addu(scratch0(), base, scratch0()); | 3295 __ Addu(scratch0(), base, scratch0()); |
3326 return MemOperand(scratch0()); | 3296 return MemOperand(scratch0()); |
3327 } | 3297 } |
3328 } | 3298 } |
3329 | 3299 |
3330 if (shift_size >= 0) { | 3300 if (shift_size >= 0) { |
3331 __ sll(scratch0(), scratch0(), shift_size); | 3301 __ sll(scratch0(), key, shift_size); |
3332 __ Addu(scratch0(), base, scratch0()); | 3302 __ Addu(scratch0(), base, scratch0()); |
3333 return MemOperand(scratch0()); | 3303 return MemOperand(scratch0(), base_offset); |
3334 } else { | 3304 } else { |
3335 ASSERT_EQ(-1, shift_size); | 3305 ASSERT_EQ(-1, shift_size); |
3336 __ srl(scratch0(), scratch0(), 1); | 3306 __ sra(scratch0(), key, 1); |
3337 __ Addu(scratch0(), base, scratch0()); | 3307 __ Addu(scratch0(), base, scratch0()); |
3338 return MemOperand(scratch0()); | 3308 return MemOperand(scratch0(), base_offset); |
3339 } | 3309 } |
3340 } | 3310 } |
3341 | 3311 |
3342 | 3312 |
3343 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3313 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
3344 ASSERT(ToRegister(instr->context()).is(cp)); | 3314 ASSERT(ToRegister(instr->context()).is(cp)); |
3345 ASSERT(ToRegister(instr->object()).is(a1)); | 3315 ASSERT(ToRegister(instr->object()).is(a1)); |
3346 ASSERT(ToRegister(instr->key()).is(a0)); | 3316 ASSERT(ToRegister(instr->key()).is(a0)); |
3347 | 3317 |
3348 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3318 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4201 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4171 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4202 if (constant_key & 0xF0000000) { | 4172 if (constant_key & 0xF0000000) { |
4203 Abort(kArrayIndexConstantValueTooBig); | 4173 Abort(kArrayIndexConstantValueTooBig); |
4204 } | 4174 } |
4205 } else { | 4175 } else { |
4206 key = ToRegister(instr->key()); | 4176 key = ToRegister(instr->key()); |
4207 } | 4177 } |
4208 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4178 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4209 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4179 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4210 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4180 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
4211 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) | 4181 int base_offset = instr->base_offset(); |
4212 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
4213 : 0; | |
4214 | 4182 |
4215 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4183 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
4216 elements_kind == FLOAT32_ELEMENTS || | 4184 elements_kind == FLOAT32_ELEMENTS || |
4217 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4185 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
4218 elements_kind == FLOAT64_ELEMENTS) { | 4186 elements_kind == FLOAT64_ELEMENTS) { |
4219 int base_offset = | |
4220 (instr->additional_index() << element_size_shift) + additional_offset; | |
4221 Register address = scratch0(); | 4187 Register address = scratch0(); |
4222 FPURegister value(ToDoubleRegister(instr->value())); | 4188 FPURegister value(ToDoubleRegister(instr->value())); |
4223 if (key_is_constant) { | 4189 if (key_is_constant) { |
4224 if (constant_key != 0) { | 4190 if (constant_key != 0) { |
4225 __ Addu(address, external_pointer, | 4191 __ Addu(address, external_pointer, |
4226 Operand(constant_key << element_size_shift)); | 4192 Operand(constant_key << element_size_shift)); |
4227 } else { | 4193 } else { |
4228 address = external_pointer; | 4194 address = external_pointer; |
4229 } | 4195 } |
4230 } else { | 4196 } else { |
4231 __ sll(address, key, shift_size); | 4197 __ sll(address, key, shift_size); |
4232 __ Addu(address, external_pointer, address); | 4198 __ Addu(address, external_pointer, address); |
4233 } | 4199 } |
4234 | 4200 |
4235 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4201 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
4236 elements_kind == FLOAT32_ELEMENTS) { | 4202 elements_kind == FLOAT32_ELEMENTS) { |
4237 __ cvt_s_d(double_scratch0(), value); | 4203 __ cvt_s_d(double_scratch0(), value); |
4238 __ swc1(double_scratch0(), MemOperand(address, base_offset)); | 4204 __ swc1(double_scratch0(), MemOperand(address, base_offset)); |
4239 } else { // Storing doubles, not floats. | 4205 } else { // Storing doubles, not floats. |
4240 __ sdc1(value, MemOperand(address, base_offset)); | 4206 __ sdc1(value, MemOperand(address, base_offset)); |
4241 } | 4207 } |
4242 } else { | 4208 } else { |
4243 Register value(ToRegister(instr->value())); | 4209 Register value(ToRegister(instr->value())); |
4244 MemOperand mem_operand = PrepareKeyedOperand( | 4210 MemOperand mem_operand = PrepareKeyedOperand( |
4245 key, external_pointer, key_is_constant, constant_key, | 4211 key, external_pointer, key_is_constant, constant_key, |
4246 element_size_shift, shift_size, | 4212 element_size_shift, shift_size, |
4247 instr->additional_index(), additional_offset); | 4213 base_offset); |
4248 switch (elements_kind) { | 4214 switch (elements_kind) { |
4249 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: | 4215 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
4250 case EXTERNAL_INT8_ELEMENTS: | 4216 case EXTERNAL_INT8_ELEMENTS: |
4251 case EXTERNAL_UINT8_ELEMENTS: | 4217 case EXTERNAL_UINT8_ELEMENTS: |
4252 case UINT8_ELEMENTS: | 4218 case UINT8_ELEMENTS: |
4253 case UINT8_CLAMPED_ELEMENTS: | 4219 case UINT8_CLAMPED_ELEMENTS: |
4254 case INT8_ELEMENTS: | 4220 case INT8_ELEMENTS: |
4255 __ sb(value, mem_operand); | 4221 __ sb(value, mem_operand); |
4256 break; | 4222 break; |
4257 case EXTERNAL_INT16_ELEMENTS: | 4223 case EXTERNAL_INT16_ELEMENTS: |
(...skipping 26 matching lines...) Expand all Loading... |
4284 } | 4250 } |
4285 } | 4251 } |
4286 | 4252 |
4287 | 4253 |
4288 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4254 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4289 DoubleRegister value = ToDoubleRegister(instr->value()); | 4255 DoubleRegister value = ToDoubleRegister(instr->value()); |
4290 Register elements = ToRegister(instr->elements()); | 4256 Register elements = ToRegister(instr->elements()); |
4291 Register scratch = scratch0(); | 4257 Register scratch = scratch0(); |
4292 DoubleRegister double_scratch = double_scratch0(); | 4258 DoubleRegister double_scratch = double_scratch0(); |
4293 bool key_is_constant = instr->key()->IsConstantOperand(); | 4259 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4260 int base_offset = instr->base_offset(); |
4294 Label not_nan, done; | 4261 Label not_nan, done; |
4295 | 4262 |
4296 // Calculate the effective address of the slot in the array to store the | 4263 // Calculate the effective address of the slot in the array to store the |
4297 // double value. | 4264 // double value. |
4298 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4265 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
4299 if (key_is_constant) { | 4266 if (key_is_constant) { |
4300 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4267 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4301 if (constant_key & 0xF0000000) { | 4268 if (constant_key & 0xF0000000) { |
4302 Abort(kArrayIndexConstantValueTooBig); | 4269 Abort(kArrayIndexConstantValueTooBig); |
4303 } | 4270 } |
4304 __ Addu(scratch, elements, | 4271 __ Addu(scratch, elements, |
4305 Operand((constant_key << element_size_shift) + | 4272 Operand((constant_key << element_size_shift) + base_offset)); |
4306 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4307 } else { | 4273 } else { |
4308 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4274 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4309 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4275 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
4310 __ Addu(scratch, elements, | 4276 __ Addu(scratch, elements, Operand(base_offset)); |
4311 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4312 __ sll(at, ToRegister(instr->key()), shift_size); | 4277 __ sll(at, ToRegister(instr->key()), shift_size); |
4313 __ Addu(scratch, scratch, at); | 4278 __ Addu(scratch, scratch, at); |
4314 } | 4279 } |
4315 | 4280 |
4316 if (instr->NeedsCanonicalization()) { | 4281 if (instr->NeedsCanonicalization()) { |
4317 Label is_nan; | 4282 Label is_nan; |
4318 // Check for NaN. All NaNs must be canonicalized. | 4283 // Check for NaN. All NaNs must be canonicalized. |
4319 __ BranchF(NULL, &is_nan, eq, value, value); | 4284 __ BranchF(NULL, &is_nan, eq, value, value); |
4320 __ Branch(¬_nan); | 4285 __ Branch(¬_nan); |
4321 | 4286 |
4322 // Only load canonical NaN if the comparison above set the overflow. | 4287 // Only load canonical NaN if the comparison above set the overflow. |
4323 __ bind(&is_nan); | 4288 __ bind(&is_nan); |
4324 __ LoadRoot(at, Heap::kNanValueRootIndex); | 4289 __ LoadRoot(at, Heap::kNanValueRootIndex); |
4325 __ ldc1(double_scratch, FieldMemOperand(at, HeapNumber::kValueOffset)); | 4290 __ ldc1(double_scratch, FieldMemOperand(at, HeapNumber::kValueOffset)); |
4326 __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() << | 4291 __ sdc1(double_scratch, MemOperand(scratch, 0)); |
4327 element_size_shift)); | |
4328 __ Branch(&done); | 4292 __ Branch(&done); |
4329 } | 4293 } |
4330 | 4294 |
4331 __ bind(¬_nan); | 4295 __ bind(¬_nan); |
4332 __ sdc1(value, MemOperand(scratch, instr->additional_index() << | 4296 __ sdc1(value, MemOperand(scratch, 0)); |
4333 element_size_shift)); | |
4334 __ bind(&done); | 4297 __ bind(&done); |
4335 } | 4298 } |
4336 | 4299 |
4337 | 4300 |
4338 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4301 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4339 Register value = ToRegister(instr->value()); | 4302 Register value = ToRegister(instr->value()); |
4340 Register elements = ToRegister(instr->elements()); | 4303 Register elements = ToRegister(instr->elements()); |
4341 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4304 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
4342 : no_reg; | 4305 : no_reg; |
4343 Register scratch = scratch0(); | 4306 Register scratch = scratch0(); |
4344 Register store_base = scratch; | 4307 Register store_base = scratch; |
4345 int offset = 0; | 4308 int offset = instr->base_offset(); |
4346 | 4309 |
4347 // Do the store. | 4310 // Do the store. |
4348 if (instr->key()->IsConstantOperand()) { | 4311 if (instr->key()->IsConstantOperand()) { |
4349 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4312 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
4350 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 4313 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
4351 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 4314 offset += ToInteger32(const_operand) * kPointerSize; |
4352 instr->additional_index()); | |
4353 store_base = elements; | 4315 store_base = elements; |
4354 } else { | 4316 } else { |
4355 // Even though the HLoadKeyed instruction forces the input | 4317 // Even though the HLoadKeyed instruction forces the input |
4356 // representation for the key to be an integer, the input gets replaced | 4318 // representation for the key to be an integer, the input gets replaced |
4357 // during bound check elimination with the index argument to the bounds | 4319 // during bound check elimination with the index argument to the bounds |
4358 // check, which can be tagged, so that case must be handled here, too. | 4320 // check, which can be tagged, so that case must be handled here, too. |
4359 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4321 if (instr->hydrogen()->key()->representation().IsSmi()) { |
4360 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); | 4322 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); |
4361 __ addu(scratch, elements, scratch); | 4323 __ addu(scratch, elements, scratch); |
4362 } else { | 4324 } else { |
4363 __ sll(scratch, key, kPointerSizeLog2); | 4325 __ sll(scratch, key, kPointerSizeLog2); |
4364 __ addu(scratch, elements, scratch); | 4326 __ addu(scratch, elements, scratch); |
4365 } | 4327 } |
4366 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
4367 } | 4328 } |
4368 __ sw(value, FieldMemOperand(store_base, offset)); | 4329 __ sw(value, MemOperand(store_base, offset)); |
4369 | 4330 |
4370 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4331 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4371 SmiCheck check_needed = | 4332 SmiCheck check_needed = |
4372 instr->hydrogen()->value()->IsHeapObject() | 4333 instr->hydrogen()->value()->IsHeapObject() |
4373 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4334 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4374 // Compute address of modified element and store it into key register. | 4335 // Compute address of modified element and store it into key register. |
4375 __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); | 4336 __ Addu(key, store_base, Operand(offset)); |
4376 __ RecordWrite(elements, | 4337 __ RecordWrite(elements, |
4377 key, | 4338 key, |
4378 value, | 4339 value, |
4379 GetRAState(), | 4340 GetRAState(), |
4380 kSaveFPRegs, | 4341 kSaveFPRegs, |
4381 EMIT_REMEMBERED_SET, | 4342 EMIT_REMEMBERED_SET, |
4382 check_needed); | 4343 check_needed); |
4383 } | 4344 } |
4384 } | 4345 } |
4385 | 4346 |
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5917 __ lw(result, FieldMemOperand(scratch, | 5878 __ lw(result, FieldMemOperand(scratch, |
5918 FixedArray::kHeaderSize - kPointerSize)); | 5879 FixedArray::kHeaderSize - kPointerSize)); |
5919 __ bind(deferred->exit()); | 5880 __ bind(deferred->exit()); |
5920 __ bind(&done); | 5881 __ bind(&done); |
5921 } | 5882 } |
5922 | 5883 |
5923 | 5884 |
5924 #undef __ | 5885 #undef __ |
5925 | 5886 |
5926 } } // namespace v8::internal | 5887 } } // namespace v8::internal |
OLD | NEW |