| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2984 if (instr->hydrogen()->IsDehoisted()) { | 2984 if (instr->hydrogen()->IsDehoisted()) { |
| 2985 // Sign extend key because it could be a 32 bit negative value | 2985 // Sign extend key because it could be a 32 bit negative value |
| 2986 // and the dehoisted address computation happens in 64 bits | 2986 // and the dehoisted address computation happens in 64 bits |
| 2987 __ movsxlq(key_reg, key_reg); | 2987 __ movsxlq(key_reg, key_reg); |
| 2988 } | 2988 } |
| 2989 } | 2989 } |
| 2990 Operand operand(BuildFastArrayOperand( | 2990 Operand operand(BuildFastArrayOperand( |
| 2991 instr->elements(), | 2991 instr->elements(), |
| 2992 key, | 2992 key, |
| 2993 elements_kind, | 2993 elements_kind, |
| 2994 0, | 2994 instr->base_offset())); |
| 2995 instr->additional_index())); | |
| 2996 | 2995 |
| 2997 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2996 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 2998 XMMRegister result(ToDoubleRegister(instr->result())); | 2997 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2999 __ movss(result, operand); | 2998 __ movss(result, operand); |
| 3000 __ cvtss2sd(result, result); | 2999 __ cvtss2sd(result, result); |
| 3001 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3000 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3002 __ movsd(ToDoubleRegister(instr->result()), operand); | 3001 __ movsd(ToDoubleRegister(instr->result()), operand); |
| 3003 } else { | 3002 } else { |
| 3004 Register result(ToRegister(instr->result())); | 3003 Register result(ToRegister(instr->result())); |
| 3005 switch (elements_kind) { | 3004 switch (elements_kind) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 // during bound check elimination with the index argument to the bounds | 3052 // during bound check elimination with the index argument to the bounds |
| 3054 // check, which can be tagged, so that case must be handled here, too. | 3053 // check, which can be tagged, so that case must be handled here, too. |
| 3055 if (instr->hydrogen()->IsDehoisted()) { | 3054 if (instr->hydrogen()->IsDehoisted()) { |
| 3056 // Sign extend key because it could be a 32 bit negative value | 3055 // Sign extend key because it could be a 32 bit negative value |
| 3057 // and the dehoisted address computation happens in 64 bits | 3056 // and the dehoisted address computation happens in 64 bits |
| 3058 __ movsxlq(key_reg, key_reg); | 3057 __ movsxlq(key_reg, key_reg); |
| 3059 } | 3058 } |
| 3060 } | 3059 } |
| 3061 | 3060 |
| 3062 if (instr->hydrogen()->RequiresHoleCheck()) { | 3061 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3063 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
| 3064 sizeof(kHoleNanLower32); | |
| 3065 Operand hole_check_operand = BuildFastArrayOperand( | 3062 Operand hole_check_operand = BuildFastArrayOperand( |
| 3066 instr->elements(), | 3063 instr->elements(), |
| 3067 key, | 3064 key, |
| 3068 FAST_DOUBLE_ELEMENTS, | 3065 FAST_DOUBLE_ELEMENTS, |
| 3069 offset, | 3066 instr->base_offset() + sizeof(kHoleNanLower32)); |
| 3070 instr->additional_index()); | |
| 3071 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 3067 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| 3072 DeoptimizeIf(equal, instr->environment()); | 3068 DeoptimizeIf(equal, instr->environment()); |
| 3073 } | 3069 } |
| 3074 | 3070 |
| 3075 Operand double_load_operand = BuildFastArrayOperand( | 3071 Operand double_load_operand = BuildFastArrayOperand( |
| 3076 instr->elements(), | 3072 instr->elements(), |
| 3077 key, | 3073 key, |
| 3078 FAST_DOUBLE_ELEMENTS, | 3074 FAST_DOUBLE_ELEMENTS, |
| 3079 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3075 instr->base_offset()); |
| 3080 instr->additional_index()); | |
| 3081 __ movsd(result, double_load_operand); | 3076 __ movsd(result, double_load_operand); |
| 3082 } | 3077 } |
| 3083 | 3078 |
| 3084 | 3079 |
| 3085 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3080 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3086 Register result = ToRegister(instr->result()); | 3081 Register result = ToRegister(instr->result()); |
| 3087 LOperand* key = instr->key(); | 3082 LOperand* key = instr->key(); |
| 3088 if (!key->IsConstantOperand()) { | 3083 if (!key->IsConstantOperand()) { |
| 3089 Register key_reg = ToRegister(key); | 3084 Register key_reg = ToRegister(key); |
| 3090 // Even though the HLoad/StoreKeyedFastElement instructions force | 3085 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3091 // the input representation for the key to be an integer, the input | 3086 // the input representation for the key to be an integer, the input |
| 3092 // gets replaced during bound check elimination with the index | 3087 // gets replaced during bound check elimination with the index |
| 3093 // argument to the bounds check, which can be tagged, so that | 3088 // argument to the bounds check, which can be tagged, so that |
| 3094 // case must be handled here, too. | 3089 // case must be handled here, too. |
| 3095 if (instr->hydrogen()->IsDehoisted()) { | 3090 if (instr->hydrogen()->IsDehoisted()) { |
| 3096 // Sign extend key because it could be a 32 bit negative value | 3091 // Sign extend key because it could be a 32 bit negative value |
| 3097 // and the dehoisted address computation happens in 64 bits | 3092 // and the dehoisted address computation happens in 64 bits |
| 3098 __ movsxlq(key_reg, key_reg); | 3093 __ movsxlq(key_reg, key_reg); |
| 3099 } | 3094 } |
| 3100 } | 3095 } |
| 3101 | 3096 |
| 3102 // Load the result. | 3097 // Load the result. |
| 3103 __ movq(result, | 3098 __ movq(result, |
| 3104 BuildFastArrayOperand(instr->elements(), | 3099 BuildFastArrayOperand(instr->elements(), |
| 3105 key, | 3100 key, |
| 3106 FAST_ELEMENTS, | 3101 FAST_ELEMENTS, |
| 3107 FixedArray::kHeaderSize - kHeapObjectTag, | 3102 instr->base_offset())); |
| 3108 instr->additional_index())); | |
| 3109 | 3103 |
| 3110 // Check for the hole value. | 3104 // Check for the hole value. |
| 3111 if (instr->hydrogen()->RequiresHoleCheck()) { | 3105 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3112 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3106 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 3113 Condition smi = __ CheckSmi(result); | 3107 Condition smi = __ CheckSmi(result); |
| 3114 DeoptimizeIf(NegateCondition(smi), instr->environment()); | 3108 DeoptimizeIf(NegateCondition(smi), instr->environment()); |
| 3115 } else { | 3109 } else { |
| 3116 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 3110 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 3117 DeoptimizeIf(equal, instr->environment()); | 3111 DeoptimizeIf(equal, instr->environment()); |
| 3118 } | 3112 } |
| 3119 } | 3113 } |
| 3120 } | 3114 } |
| 3121 | 3115 |
| 3122 | 3116 |
| 3123 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3117 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
| 3124 if (instr->is_external()) { | 3118 if (instr->is_external()) { |
| 3125 DoLoadKeyedExternalArray(instr); | 3119 DoLoadKeyedExternalArray(instr); |
| 3126 } else if (instr->hydrogen()->representation().IsDouble()) { | 3120 } else if (instr->hydrogen()->representation().IsDouble()) { |
| 3127 DoLoadKeyedFixedDoubleArray(instr); | 3121 DoLoadKeyedFixedDoubleArray(instr); |
| 3128 } else { | 3122 } else { |
| 3129 DoLoadKeyedFixedArray(instr); | 3123 DoLoadKeyedFixedArray(instr); |
| 3130 } | 3124 } |
| 3131 } | 3125 } |
| 3132 | 3126 |
| 3133 | 3127 |
| 3134 Operand LCodeGen::BuildFastArrayOperand( | 3128 Operand LCodeGen::BuildFastArrayOperand( |
| 3135 LOperand* elements_pointer, | 3129 LOperand* elements_pointer, |
| 3136 LOperand* key, | 3130 LOperand* key, |
| 3137 ElementsKind elements_kind, | 3131 ElementsKind elements_kind, |
| 3138 uint32_t offset, | 3132 uint32_t offset) { |
| 3139 uint32_t additional_index) { | |
| 3140 Register elements_pointer_reg = ToRegister(elements_pointer); | 3133 Register elements_pointer_reg = ToRegister(elements_pointer); |
| 3141 int shift_size = ElementsKindToShiftSize(elements_kind); | 3134 int shift_size = ElementsKindToShiftSize(elements_kind); |
| 3142 if (key->IsConstantOperand()) { | 3135 if (key->IsConstantOperand()) { |
| 3143 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); | 3136 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); |
| 3144 if (constant_value & 0xF0000000) { | 3137 if (constant_value & 0xF0000000) { |
| 3145 Abort(kArrayIndexConstantValueTooBig); | 3138 Abort(kArrayIndexConstantValueTooBig); |
| 3146 } | 3139 } |
| 3147 return Operand(elements_pointer_reg, | 3140 return Operand(elements_pointer_reg, |
| 3148 ((constant_value + additional_index) << shift_size) | 3141 (constant_value << shift_size) + offset); |
| 3149 + offset); | |
| 3150 } else { | 3142 } else { |
| 3151 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 3143 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
| 3152 return Operand(elements_pointer_reg, | 3144 return Operand(elements_pointer_reg, |
| 3153 ToRegister(key), | 3145 ToRegister(key), |
| 3154 scale_factor, | 3146 scale_factor, |
| 3155 offset + (additional_index << shift_size)); | 3147 offset); |
| 3156 } | 3148 } |
| 3157 } | 3149 } |
| 3158 | 3150 |
| 3159 | 3151 |
| 3160 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3152 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3161 ASSERT(ToRegister(instr->context()).is(rsi)); | 3153 ASSERT(ToRegister(instr->context()).is(rsi)); |
| 3162 ASSERT(ToRegister(instr->object()).is(rdx)); | 3154 ASSERT(ToRegister(instr->object()).is(rdx)); |
| 3163 ASSERT(ToRegister(instr->key()).is(rax)); | 3155 ASSERT(ToRegister(instr->key()).is(rax)); |
| 3164 | 3156 |
| 3165 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3157 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| (...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4173 if (instr->hydrogen()->IsDehoisted()) { | 4165 if (instr->hydrogen()->IsDehoisted()) { |
| 4174 // Sign extend key because it could be a 32 bit negative value | 4166 // Sign extend key because it could be a 32 bit negative value |
| 4175 // and the dehoisted address computation happens in 64 bits | 4167 // and the dehoisted address computation happens in 64 bits |
| 4176 __ movsxlq(key_reg, key_reg); | 4168 __ movsxlq(key_reg, key_reg); |
| 4177 } | 4169 } |
| 4178 } | 4170 } |
| 4179 Operand operand(BuildFastArrayOperand( | 4171 Operand operand(BuildFastArrayOperand( |
| 4180 instr->elements(), | 4172 instr->elements(), |
| 4181 key, | 4173 key, |
| 4182 elements_kind, | 4174 elements_kind, |
| 4183 0, | 4175 instr->base_offset())); |
| 4184 instr->additional_index())); | |
| 4185 | 4176 |
| 4186 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4177 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4187 XMMRegister value(ToDoubleRegister(instr->value())); | 4178 XMMRegister value(ToDoubleRegister(instr->value())); |
| 4188 __ cvtsd2ss(value, value); | 4179 __ cvtsd2ss(value, value); |
| 4189 __ movss(operand, value); | 4180 __ movss(operand, value); |
| 4190 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4181 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4191 __ movsd(operand, ToDoubleRegister(instr->value())); | 4182 __ movsd(operand, ToDoubleRegister(instr->value())); |
| 4192 } else { | 4183 } else { |
| 4193 Register value(ToRegister(instr->value())); | 4184 Register value(ToRegister(instr->value())); |
| 4194 switch (elements_kind) { | 4185 switch (elements_kind) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4249 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 4240 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
| 4250 __ movq(value, kScratchRegister); | 4241 __ movq(value, kScratchRegister); |
| 4251 | 4242 |
| 4252 __ bind(&have_value); | 4243 __ bind(&have_value); |
| 4253 } | 4244 } |
| 4254 | 4245 |
| 4255 Operand double_store_operand = BuildFastArrayOperand( | 4246 Operand double_store_operand = BuildFastArrayOperand( |
| 4256 instr->elements(), | 4247 instr->elements(), |
| 4257 key, | 4248 key, |
| 4258 FAST_DOUBLE_ELEMENTS, | 4249 FAST_DOUBLE_ELEMENTS, |
| 4259 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4250 instr->base_offset()); |
| 4260 instr->additional_index()); | |
| 4261 | 4251 |
| 4262 __ movsd(double_store_operand, value); | 4252 __ movsd(double_store_operand, value); |
| 4263 } | 4253 } |
| 4264 | 4254 |
| 4265 | 4255 |
| 4266 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4256 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4267 Register elements = ToRegister(instr->elements()); | 4257 Register elements = ToRegister(instr->elements()); |
| 4268 LOperand* key = instr->key(); | 4258 LOperand* key = instr->key(); |
| 4269 if (!key->IsConstantOperand()) { | 4259 if (!key->IsConstantOperand()) { |
| 4270 Register key_reg = ToRegister(key); | 4260 Register key_reg = ToRegister(key); |
| 4271 // Even though the HLoad/StoreKeyedFastElement instructions force | 4261 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4272 // the input representation for the key to be an integer, the | 4262 // the input representation for the key to be an integer, the |
| 4273 // input gets replaced during bound check elimination with the index | 4263 // input gets replaced during bound check elimination with the index |
| 4274 // argument to the bounds check, which can be tagged, so that case | 4264 // argument to the bounds check, which can be tagged, so that case |
| 4275 // must be handled here, too. | 4265 // must be handled here, too. |
| 4276 if (instr->hydrogen()->IsDehoisted()) { | 4266 if (instr->hydrogen()->IsDehoisted()) { |
| 4277 // Sign extend key because it could be a 32 bit negative value | 4267 // Sign extend key because it could be a 32 bit negative value |
| 4278 // and the dehoisted address computation happens in 64 bits | 4268 // and the dehoisted address computation happens in 64 bits |
| 4279 __ movsxlq(key_reg, key_reg); | 4269 __ movsxlq(key_reg, key_reg); |
| 4280 } | 4270 } |
| 4281 } | 4271 } |
| 4282 | 4272 |
| 4283 Operand operand = | 4273 Operand operand = |
| 4284 BuildFastArrayOperand(instr->elements(), | 4274 BuildFastArrayOperand(instr->elements(), |
| 4285 key, | 4275 key, |
| 4286 FAST_ELEMENTS, | 4276 FAST_ELEMENTS, |
| 4287 FixedArray::kHeaderSize - kHeapObjectTag, | 4277 instr->base_offset()); |
| 4288 instr->additional_index()); | |
| 4289 if (instr->value()->IsRegister()) { | 4278 if (instr->value()->IsRegister()) { |
| 4290 __ movq(operand, ToRegister(instr->value())); | 4279 __ movq(operand, ToRegister(instr->value())); |
| 4291 } else { | 4280 } else { |
| 4292 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4281 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4293 if (IsInteger32Constant(operand_value)) { | 4282 if (IsInteger32Constant(operand_value)) { |
| 4294 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); | 4283 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); |
| 4295 __ Move(operand, smi_value); | 4284 __ Move(operand, smi_value); |
| 4296 } else { | 4285 } else { |
| 4297 Handle<Object> handle_value = ToHandle(operand_value); | 4286 Handle<Object> handle_value = ToHandle(operand_value); |
| 4298 __ Move(operand, handle_value); | 4287 __ Move(operand, handle_value); |
| (...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5613 FieldOperand(object, HeapObject::kMapOffset)); | 5602 FieldOperand(object, HeapObject::kMapOffset)); |
| 5614 DeoptimizeIf(not_equal, instr->environment()); | 5603 DeoptimizeIf(not_equal, instr->environment()); |
| 5615 } | 5604 } |
| 5616 | 5605 |
| 5617 | 5606 |
| 5618 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { | 5607 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { |
| 5619 Register object = ToRegister(instr->object()); | 5608 Register object = ToRegister(instr->object()); |
| 5620 Register index = ToRegister(instr->index()); | 5609 Register index = ToRegister(instr->index()); |
| 5621 | 5610 |
| 5622 Label out_of_object, done; | 5611 Label out_of_object, done; |
| 5623 __ SmiToInteger32(index, index); | |
| 5624 __ cmpl(index, Immediate(0)); | 5612 __ cmpl(index, Immediate(0)); |
| 5625 __ j(less, &out_of_object, Label::kNear); | 5613 __ j(less, &out_of_object, Label::kNear); |
| 5626 __ movq(object, FieldOperand(object, | 5614 __ movq(object, FieldOperand(object, |
| 5627 index, | 5615 index, |
| 5628 times_pointer_size, | 5616 times_pointer_size, |
| 5629 JSObject::kHeaderSize)); | 5617 JSObject::kHeaderSize)); |
| 5630 __ jmp(&done, Label::kNear); | 5618 __ jmp(&done, Label::kNear); |
| 5631 | 5619 |
| 5632 __ bind(&out_of_object); | 5620 __ bind(&out_of_object); |
| 5633 __ movq(object, FieldOperand(object, JSObject::kPropertiesOffset)); | 5621 __ movq(object, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 5634 __ negl(index); | 5622 __ negl(index); |
| 5635 // Index is now equal to out of object property index plus 1. | 5623 // Index is now equal to out of object property index plus 1. |
| 5636 __ movq(object, FieldOperand(object, | 5624 __ movq(object, FieldOperand(object, |
| 5637 index, | 5625 index, |
| 5638 times_pointer_size, | 5626 times_pointer_size, |
| 5639 FixedArray::kHeaderSize - kPointerSize)); | 5627 FixedArray::kHeaderSize - kPointerSize)); |
| 5640 __ bind(&done); | 5628 __ bind(&done); |
| 5641 } | 5629 } |
| 5642 | 5630 |
| 5643 | 5631 |
| 5644 #undef __ | 5632 #undef __ |
| 5645 | 5633 |
| 5646 } } // namespace v8::internal | 5634 } } // namespace v8::internal |
| 5647 | 5635 |
| 5648 #endif // V8_TARGET_ARCH_X64 | 5636 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |