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 |