| 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 |