OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/x64/lithium-codegen-x64.h" | 9 #include "src/x64/lithium-codegen-x64.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 } | 257 } |
258 | 258 |
259 | 259 |
260 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { | 260 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { |
261 if (instr->IsCall()) { | 261 if (instr->IsCall()) { |
262 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 262 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
263 } | 263 } |
264 if (!instr->IsLazyBailout() && !instr->IsGap()) { | 264 if (!instr->IsLazyBailout() && !instr->IsGap()) { |
265 safepoints_.BumpLastLazySafepointIndex(); | 265 safepoints_.BumpLastLazySafepointIndex(); |
266 } | 266 } |
267 if (kPointerSize == kInt32Size) { | |
268 if (instr->IsLoadKeyed() || instr->IsStoreKeyed()) { | |
Toon Verwaest
2014/06/12 08:54:25
Given that this code is only relevant for Load/Sto
haitao.feng
2014/06/12 09:34:56
Done.
| |
269 ElementsKind elements_kind = INT8_ELEMENTS; // Bogus initialization. | |
270 LOperand* key = NULL; | |
271 Representation key_representation = Representation::None(); | |
272 bool is_dehoisted = false; | |
273 if (instr->IsLoadKeyed()) { | |
274 LLoadKeyed* load = LLoadKeyed::cast(instr); | |
275 elements_kind = load->elements_kind(); | |
276 key = load->key(); | |
277 key_representation = load->hydrogen()->key()->representation(); | |
278 is_dehoisted = load->hydrogen()->IsDehoisted(); | |
279 } else { | |
280 LStoreKeyed* store = LStoreKeyed::cast(instr); | |
281 elements_kind = store->elements_kind(); | |
282 key = store->key(); | |
283 key_representation = store->hydrogen()->key()->representation(); | |
284 is_dehoisted = store->hydrogen()->IsDehoisted(); | |
285 } | |
286 if (!key->IsConstantOperand()) { | |
287 Register key_reg = ToRegister(key); | |
288 if (KeyedLoadOrStoreRequiresTemp(key_representation, elements_kind)) { | |
289 __ SmiToInteger64(key_reg, key_reg); | |
290 } else if (is_dehoisted) { | |
291 // Sign extend key because it could be a 32 bit negative value | |
292 // and the dehoisted address computation happens in 64 bits | |
293 __ movsxlq(key_reg, key_reg); | |
294 } | |
295 } | |
296 } | |
297 } | |
267 } | 298 } |
268 | 299 |
269 | 300 |
270 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { | 301 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { |
271 if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() && | 302 if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() && |
272 instr->hydrogen_value()->representation().IsInteger32() && | 303 instr->hydrogen_value()->representation().IsInteger32() && |
273 instr->result()->IsRegister()) { | 304 instr->result()->IsRegister()) { |
274 __ AssertZeroExtended(ToRegister(instr->result())); | 305 __ AssertZeroExtended(ToRegister(instr->result())); |
275 } | 306 } |
276 | 307 |
(...skipping 2753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3030 } | 3061 } |
3031 } | 3062 } |
3032 | 3063 |
3033 | 3064 |
3034 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3065 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
3035 ElementsKind elements_kind = instr->elements_kind(); | 3066 ElementsKind elements_kind = instr->elements_kind(); |
3036 LOperand* key = instr->key(); | 3067 LOperand* key = instr->key(); |
3037 Operand operand(BuildFastArrayOperand( | 3068 Operand operand(BuildFastArrayOperand( |
3038 instr->elements(), | 3069 instr->elements(), |
3039 key, | 3070 key, |
3071 instr->hydrogen()->key()->representation(), | |
3040 elements_kind, | 3072 elements_kind, |
3041 instr->base_offset())); | 3073 instr->base_offset())); |
3042 | 3074 |
3043 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3075 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
3044 elements_kind == FLOAT32_ELEMENTS) { | 3076 elements_kind == FLOAT32_ELEMENTS) { |
3045 XMMRegister result(ToDoubleRegister(instr->result())); | 3077 XMMRegister result(ToDoubleRegister(instr->result())); |
3046 __ movss(result, operand); | 3078 __ movss(result, operand); |
3047 __ cvtss2sd(result, result); | 3079 __ cvtss2sd(result, result); |
3048 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 3080 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
3049 elements_kind == FLOAT64_ELEMENTS) { | 3081 elements_kind == FLOAT64_ELEMENTS) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3100 } | 3132 } |
3101 | 3133 |
3102 | 3134 |
3103 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3135 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
3104 XMMRegister result(ToDoubleRegister(instr->result())); | 3136 XMMRegister result(ToDoubleRegister(instr->result())); |
3105 LOperand* key = instr->key(); | 3137 LOperand* key = instr->key(); |
3106 if (instr->hydrogen()->RequiresHoleCheck()) { | 3138 if (instr->hydrogen()->RequiresHoleCheck()) { |
3107 Operand hole_check_operand = BuildFastArrayOperand( | 3139 Operand hole_check_operand = BuildFastArrayOperand( |
3108 instr->elements(), | 3140 instr->elements(), |
3109 key, | 3141 key, |
3142 instr->hydrogen()->key()->representation(), | |
3110 FAST_DOUBLE_ELEMENTS, | 3143 FAST_DOUBLE_ELEMENTS, |
3111 instr->base_offset() + sizeof(kHoleNanLower32)); | 3144 instr->base_offset() + sizeof(kHoleNanLower32)); |
3112 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 3145 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
3113 DeoptimizeIf(equal, instr->environment()); | 3146 DeoptimizeIf(equal, instr->environment()); |
3114 } | 3147 } |
3115 | 3148 |
3116 Operand double_load_operand = BuildFastArrayOperand( | 3149 Operand double_load_operand = BuildFastArrayOperand( |
3117 instr->elements(), | 3150 instr->elements(), |
3118 key, | 3151 key, |
3152 instr->hydrogen()->key()->representation(), | |
3119 FAST_DOUBLE_ELEMENTS, | 3153 FAST_DOUBLE_ELEMENTS, |
3120 instr->base_offset()); | 3154 instr->base_offset()); |
3121 __ movsd(result, double_load_operand); | 3155 __ movsd(result, double_load_operand); |
3122 } | 3156 } |
3123 | 3157 |
3124 | 3158 |
3125 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3159 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3126 HLoadKeyed* hinstr = instr->hydrogen(); | 3160 HLoadKeyed* hinstr = instr->hydrogen(); |
3127 Register result = ToRegister(instr->result()); | 3161 Register result = ToRegister(instr->result()); |
3128 LOperand* key = instr->key(); | 3162 LOperand* key = instr->key(); |
3129 bool requires_hole_check = hinstr->RequiresHoleCheck(); | 3163 bool requires_hole_check = hinstr->RequiresHoleCheck(); |
3130 Representation representation = hinstr->representation(); | 3164 Representation representation = hinstr->representation(); |
3131 int offset = instr->base_offset(); | 3165 int offset = instr->base_offset(); |
3132 | 3166 |
3133 if (representation.IsInteger32() && SmiValuesAre32Bits() && | 3167 if (representation.IsInteger32() && SmiValuesAre32Bits() && |
3134 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { | 3168 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
3135 ASSERT(!requires_hole_check); | 3169 ASSERT(!requires_hole_check); |
3136 if (FLAG_debug_code) { | 3170 if (FLAG_debug_code) { |
3137 Register scratch = kScratchRegister; | 3171 Register scratch = kScratchRegister; |
3138 __ Load(scratch, | 3172 __ Load(scratch, |
3139 BuildFastArrayOperand(instr->elements(), | 3173 BuildFastArrayOperand(instr->elements(), |
3140 key, | 3174 key, |
3175 instr->hydrogen()->key()->representation(), | |
3141 FAST_ELEMENTS, | 3176 FAST_ELEMENTS, |
3142 offset), | 3177 offset), |
3143 Representation::Smi()); | 3178 Representation::Smi()); |
3144 __ AssertSmi(scratch); | 3179 __ AssertSmi(scratch); |
3145 } | 3180 } |
3146 // Read int value directly from upper half of the smi. | 3181 // Read int value directly from upper half of the smi. |
3147 STATIC_ASSERT(kSmiTag == 0); | 3182 STATIC_ASSERT(kSmiTag == 0); |
3148 ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 3183 ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
3149 offset += kPointerSize / 2; | 3184 offset += kPointerSize / 2; |
3150 } | 3185 } |
3151 | 3186 |
3152 __ Load(result, | 3187 __ Load(result, |
3153 BuildFastArrayOperand(instr->elements(), | 3188 BuildFastArrayOperand(instr->elements(), |
3154 key, | 3189 key, |
3190 instr->hydrogen()->key()->representation(), | |
3155 FAST_ELEMENTS, | 3191 FAST_ELEMENTS, |
3156 offset), | 3192 offset), |
3157 representation); | 3193 representation); |
3158 | 3194 |
3159 // Check for the hole value. | 3195 // Check for the hole value. |
3160 if (requires_hole_check) { | 3196 if (requires_hole_check) { |
3161 if (IsFastSmiElementsKind(hinstr->elements_kind())) { | 3197 if (IsFastSmiElementsKind(hinstr->elements_kind())) { |
3162 Condition smi = __ CheckSmi(result); | 3198 Condition smi = __ CheckSmi(result); |
3163 DeoptimizeIf(NegateCondition(smi), instr->environment()); | 3199 DeoptimizeIf(NegateCondition(smi), instr->environment()); |
3164 } else { | 3200 } else { |
(...skipping 11 matching lines...) Expand all Loading... | |
3176 DoLoadKeyedFixedDoubleArray(instr); | 3212 DoLoadKeyedFixedDoubleArray(instr); |
3177 } else { | 3213 } else { |
3178 DoLoadKeyedFixedArray(instr); | 3214 DoLoadKeyedFixedArray(instr); |
3179 } | 3215 } |
3180 } | 3216 } |
3181 | 3217 |
3182 | 3218 |
3183 Operand LCodeGen::BuildFastArrayOperand( | 3219 Operand LCodeGen::BuildFastArrayOperand( |
3184 LOperand* elements_pointer, | 3220 LOperand* elements_pointer, |
3185 LOperand* key, | 3221 LOperand* key, |
3222 Representation key_representation, | |
3186 ElementsKind elements_kind, | 3223 ElementsKind elements_kind, |
3187 uint32_t offset) { | 3224 uint32_t offset) { |
3188 Register elements_pointer_reg = ToRegister(elements_pointer); | 3225 Register elements_pointer_reg = ToRegister(elements_pointer); |
3189 int shift_size = ElementsKindToShiftSize(elements_kind); | 3226 int shift_size = ElementsKindToShiftSize(elements_kind); |
3190 if (key->IsConstantOperand()) { | 3227 if (key->IsConstantOperand()) { |
3191 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); | 3228 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); |
3192 if (constant_value & 0xF0000000) { | 3229 if (constant_value & 0xF0000000) { |
3193 Abort(kArrayIndexConstantValueTooBig); | 3230 Abort(kArrayIndexConstantValueTooBig); |
3194 } | 3231 } |
3195 return Operand(elements_pointer_reg, | 3232 return Operand(elements_pointer_reg, |
3196 (constant_value << shift_size) + offset); | 3233 (constant_value << shift_size) + offset); |
3197 } else { | 3234 } else { |
3235 // Take the tag bit into account while computing the shift size. | |
3236 if (key_representation.IsSmi() && (shift_size >= 1)) { | |
3237 ASSERT(SmiValuesAre31Bits()); | |
3238 shift_size -= kSmiTagSize; | |
3239 } | |
3198 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 3240 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
3199 return Operand(elements_pointer_reg, | 3241 return Operand(elements_pointer_reg, |
3200 ToRegister(key), | 3242 ToRegister(key), |
3201 scale_factor, | 3243 scale_factor, |
3202 offset); | 3244 offset); |
3203 } | 3245 } |
3204 } | 3246 } |
3205 | 3247 |
3206 | 3248 |
3207 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3249 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4164 } | 4206 } |
4165 } | 4207 } |
4166 | 4208 |
4167 | 4209 |
4168 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4210 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4169 ElementsKind elements_kind = instr->elements_kind(); | 4211 ElementsKind elements_kind = instr->elements_kind(); |
4170 LOperand* key = instr->key(); | 4212 LOperand* key = instr->key(); |
4171 Operand operand(BuildFastArrayOperand( | 4213 Operand operand(BuildFastArrayOperand( |
4172 instr->elements(), | 4214 instr->elements(), |
4173 key, | 4215 key, |
4216 instr->hydrogen()->key()->representation(), | |
4174 elements_kind, | 4217 elements_kind, |
4175 instr->base_offset())); | 4218 instr->base_offset())); |
4176 | 4219 |
4177 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4220 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
4178 elements_kind == FLOAT32_ELEMENTS) { | 4221 elements_kind == FLOAT32_ELEMENTS) { |
4179 XMMRegister value(ToDoubleRegister(instr->value())); | 4222 XMMRegister value(ToDoubleRegister(instr->value())); |
4180 __ cvtsd2ss(value, value); | 4223 __ cvtsd2ss(value, value); |
4181 __ movss(operand, value); | 4224 __ movss(operand, value); |
4182 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4225 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
4183 elements_kind == FLOAT64_ELEMENTS) { | 4226 elements_kind == FLOAT64_ELEMENTS) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4236 __ Set(kScratchRegister, BitCast<uint64_t>( | 4279 __ Set(kScratchRegister, BitCast<uint64_t>( |
4237 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 4280 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
4238 __ movq(value, kScratchRegister); | 4281 __ movq(value, kScratchRegister); |
4239 | 4282 |
4240 __ bind(&have_value); | 4283 __ bind(&have_value); |
4241 } | 4284 } |
4242 | 4285 |
4243 Operand double_store_operand = BuildFastArrayOperand( | 4286 Operand double_store_operand = BuildFastArrayOperand( |
4244 instr->elements(), | 4287 instr->elements(), |
4245 key, | 4288 key, |
4289 instr->hydrogen()->key()->representation(), | |
4246 FAST_DOUBLE_ELEMENTS, | 4290 FAST_DOUBLE_ELEMENTS, |
4247 instr->base_offset()); | 4291 instr->base_offset()); |
4248 | 4292 |
4249 __ movsd(double_store_operand, value); | 4293 __ movsd(double_store_operand, value); |
4250 } | 4294 } |
4251 | 4295 |
4252 | 4296 |
4253 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4297 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4254 HStoreKeyed* hinstr = instr->hydrogen(); | 4298 HStoreKeyed* hinstr = instr->hydrogen(); |
4255 LOperand* key = instr->key(); | 4299 LOperand* key = instr->key(); |
4256 int offset = instr->base_offset(); | 4300 int offset = instr->base_offset(); |
4257 Representation representation = hinstr->value()->representation(); | 4301 Representation representation = hinstr->value()->representation(); |
4258 | 4302 |
4259 if (representation.IsInteger32() && SmiValuesAre32Bits()) { | 4303 if (representation.IsInteger32() && SmiValuesAre32Bits()) { |
4260 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 4304 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
4261 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); | 4305 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); |
4262 if (FLAG_debug_code) { | 4306 if (FLAG_debug_code) { |
4263 Register scratch = kScratchRegister; | 4307 Register scratch = kScratchRegister; |
4264 __ Load(scratch, | 4308 __ Load(scratch, |
4265 BuildFastArrayOperand(instr->elements(), | 4309 BuildFastArrayOperand(instr->elements(), |
4266 key, | 4310 key, |
4311 instr->hydrogen()->key()->representation(), | |
4267 FAST_ELEMENTS, | 4312 FAST_ELEMENTS, |
4268 offset), | 4313 offset), |
4269 Representation::Smi()); | 4314 Representation::Smi()); |
4270 __ AssertSmi(scratch); | 4315 __ AssertSmi(scratch); |
4271 } | 4316 } |
4272 // Store int value directly to upper half of the smi. | 4317 // Store int value directly to upper half of the smi. |
4273 STATIC_ASSERT(kSmiTag == 0); | 4318 STATIC_ASSERT(kSmiTag == 0); |
4274 ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 4319 ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
4275 offset += kPointerSize / 2; | 4320 offset += kPointerSize / 2; |
4276 } | 4321 } |
4277 | 4322 |
4278 Operand operand = | 4323 Operand operand = |
4279 BuildFastArrayOperand(instr->elements(), | 4324 BuildFastArrayOperand(instr->elements(), |
4280 key, | 4325 key, |
4326 instr->hydrogen()->key()->representation(), | |
4281 FAST_ELEMENTS, | 4327 FAST_ELEMENTS, |
4282 offset); | 4328 offset); |
4283 if (instr->value()->IsRegister()) { | 4329 if (instr->value()->IsRegister()) { |
4284 __ Store(operand, ToRegister(instr->value()), representation); | 4330 __ Store(operand, ToRegister(instr->value()), representation); |
4285 } else { | 4331 } else { |
4286 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4332 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
4287 if (IsInteger32Constant(operand_value)) { | 4333 if (IsInteger32Constant(operand_value)) { |
4288 int32_t value = ToInteger32(operand_value); | 4334 int32_t value = ToInteger32(operand_value); |
4289 if (representation.IsSmi()) { | 4335 if (representation.IsSmi()) { |
4290 __ Move(operand, Smi::FromInt(value)); | 4336 __ Move(operand, Smi::FromInt(value)); |
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5735 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); | 5781 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); |
5736 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5782 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5737 } | 5783 } |
5738 | 5784 |
5739 | 5785 |
5740 #undef __ | 5786 #undef __ |
5741 | 5787 |
5742 } } // namespace v8::internal | 5788 } } // namespace v8::internal |
5743 | 5789 |
5744 #endif // V8_TARGET_ARCH_X64 | 5790 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |