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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { | 276 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { |
277 if (instr->IsCall()) { | 277 if (instr->IsCall()) { |
278 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 278 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
279 } | 279 } |
280 if (!instr->IsLazyBailout() && !instr->IsGap()) { | 280 if (!instr->IsLazyBailout() && !instr->IsGap()) { |
281 safepoints_.BumpLastLazySafepointIndex(); | 281 safepoints_.BumpLastLazySafepointIndex(); |
282 } | 282 } |
283 } | 283 } |
284 | 284 |
285 | 285 |
| 286 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { |
| 287 if (instr->HasResult() && instr->MustSignExtendResult(chunk())) { |
| 288 if (instr->result()->IsRegister()) { |
| 289 Register result_reg = ToRegister(instr->result()); |
| 290 __ movsxlq(result_reg, result_reg); |
| 291 } else { |
| 292 // Sign extend the 32bit result in the stack slots. |
| 293 ASSERT(instr->result()->IsStackSlot()); |
| 294 Operand src = ToOperand(instr->result()); |
| 295 __ movsxlq(kScratchRegister, src); |
| 296 __ movq(src, kScratchRegister); |
| 297 } |
| 298 } |
| 299 } |
| 300 |
| 301 |
286 bool LCodeGen::GenerateJumpTable() { | 302 bool LCodeGen::GenerateJumpTable() { |
287 Label needs_frame; | 303 Label needs_frame; |
288 if (jump_table_.length() > 0) { | 304 if (jump_table_.length() > 0) { |
289 Comment(";;; -------------------- Jump table --------------------"); | 305 Comment(";;; -------------------- Jump table --------------------"); |
290 } | 306 } |
291 for (int i = 0; i < jump_table_.length(); i++) { | 307 for (int i = 0; i < jump_table_.length(); i++) { |
292 __ bind(&jump_table_[i].label); | 308 __ bind(&jump_table_[i].label); |
293 Address entry = jump_table_[i].address; | 309 Address entry = jump_table_[i].address; |
294 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; | 310 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; |
295 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | 311 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 return ToDoubleRegister(op->index()); | 423 return ToDoubleRegister(op->index()); |
408 } | 424 } |
409 | 425 |
410 | 426 |
411 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { | 427 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { |
412 return op->IsConstantOperand() && | 428 return op->IsConstantOperand() && |
413 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 429 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
414 } | 430 } |
415 | 431 |
416 | 432 |
| 433 bool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const { |
| 434 return op->IsConstantOperand() && |
| 435 chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); |
| 436 } |
| 437 |
| 438 |
417 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { | 439 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { |
418 return op->IsConstantOperand() && | 440 return op->IsConstantOperand() && |
419 chunk_->LookupLiteralRepresentation(op).IsSmi(); | 441 chunk_->LookupLiteralRepresentation(op).IsSmi(); |
420 } | 442 } |
421 | 443 |
422 | 444 |
423 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { | 445 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { |
424 return op->IsConstantOperand() && | 446 return op->IsConstantOperand() && |
425 chunk_->LookupLiteralRepresentation(op).IsTagged(); | 447 chunk_->LookupLiteralRepresentation(op).IsTagged(); |
426 } | 448 } |
(...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2933 StackArgumentsAccessor args(arguments, length, | 2955 StackArgumentsAccessor args(arguments, length, |
2934 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 2956 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
2935 __ movp(result, args.GetArgumentOperand(0)); | 2957 __ movp(result, args.GetArgumentOperand(0)); |
2936 } | 2958 } |
2937 } | 2959 } |
2938 | 2960 |
2939 | 2961 |
2940 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2962 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
2941 ElementsKind elements_kind = instr->elements_kind(); | 2963 ElementsKind elements_kind = instr->elements_kind(); |
2942 LOperand* key = instr->key(); | 2964 LOperand* key = instr->key(); |
2943 if (!key->IsConstantOperand()) { | |
2944 Register key_reg = ToRegister(key); | |
2945 // Even though the HLoad/StoreKeyed (in this case) instructions force | |
2946 // the input representation for the key to be an integer, the input | |
2947 // gets replaced during bound check elimination with the index argument | |
2948 // to the bounds check, which can be tagged, so that case must be | |
2949 // handled here, too. | |
2950 if (instr->hydrogen()->IsDehoisted()) { | |
2951 // Sign extend key because it could be a 32 bit negative value | |
2952 // and the dehoisted address computation happens in 64 bits | |
2953 __ movsxlq(key_reg, key_reg); | |
2954 } | |
2955 } | |
2956 int base_offset = instr->is_fixed_typed_array() | 2965 int base_offset = instr->is_fixed_typed_array() |
2957 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | 2966 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
2958 : 0; | 2967 : 0; |
2959 Operand operand(BuildFastArrayOperand( | 2968 Operand operand(BuildFastArrayOperand( |
2960 instr->elements(), | 2969 instr->elements(), |
2961 key, | 2970 key, |
2962 elements_kind, | 2971 elements_kind, |
2963 base_offset, | 2972 base_offset, |
2964 instr->additional_index())); | 2973 instr->additional_index())); |
2965 | 2974 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3019 UNREACHABLE(); | 3028 UNREACHABLE(); |
3020 break; | 3029 break; |
3021 } | 3030 } |
3022 } | 3031 } |
3023 } | 3032 } |
3024 | 3033 |
3025 | 3034 |
3026 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3035 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
3027 XMMRegister result(ToDoubleRegister(instr->result())); | 3036 XMMRegister result(ToDoubleRegister(instr->result())); |
3028 LOperand* key = instr->key(); | 3037 LOperand* key = instr->key(); |
3029 if (!key->IsConstantOperand()) { | |
3030 Register key_reg = ToRegister(key); | |
3031 // Even though the HLoad/StoreKeyed instructions force the input | |
3032 // representation for the key to be an integer, the input gets replaced | |
3033 // during bound check elimination with the index argument to the bounds | |
3034 // check, which can be tagged, so that case must be handled here, too. | |
3035 if (instr->hydrogen()->IsDehoisted()) { | |
3036 // Sign extend key because it could be a 32 bit negative value | |
3037 // and the dehoisted address computation happens in 64 bits | |
3038 __ movsxlq(key_reg, key_reg); | |
3039 } | |
3040 } | |
3041 | |
3042 if (instr->hydrogen()->RequiresHoleCheck()) { | 3038 if (instr->hydrogen()->RequiresHoleCheck()) { |
3043 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3039 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
3044 sizeof(kHoleNanLower32); | 3040 sizeof(kHoleNanLower32); |
3045 Operand hole_check_operand = BuildFastArrayOperand( | 3041 Operand hole_check_operand = BuildFastArrayOperand( |
3046 instr->elements(), | 3042 instr->elements(), |
3047 key, | 3043 key, |
3048 FAST_DOUBLE_ELEMENTS, | 3044 FAST_DOUBLE_ELEMENTS, |
3049 offset, | 3045 offset, |
3050 instr->additional_index()); | 3046 instr->additional_index()); |
3051 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 3047 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
3052 DeoptimizeIf(equal, instr->environment()); | 3048 DeoptimizeIf(equal, instr->environment()); |
3053 } | 3049 } |
3054 | 3050 |
3055 Operand double_load_operand = BuildFastArrayOperand( | 3051 Operand double_load_operand = BuildFastArrayOperand( |
3056 instr->elements(), | 3052 instr->elements(), |
3057 key, | 3053 key, |
3058 FAST_DOUBLE_ELEMENTS, | 3054 FAST_DOUBLE_ELEMENTS, |
3059 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3055 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
3060 instr->additional_index()); | 3056 instr->additional_index()); |
3061 __ movsd(result, double_load_operand); | 3057 __ movsd(result, double_load_operand); |
3062 } | 3058 } |
3063 | 3059 |
3064 | 3060 |
3065 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3061 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3066 HLoadKeyed* hinstr = instr->hydrogen(); | 3062 HLoadKeyed* hinstr = instr->hydrogen(); |
3067 Register result = ToRegister(instr->result()); | 3063 Register result = ToRegister(instr->result()); |
3068 LOperand* key = instr->key(); | 3064 LOperand* key = instr->key(); |
3069 if (!key->IsConstantOperand()) { | |
3070 Register key_reg = ToRegister(key); | |
3071 // Even though the HLoad/StoreKeyedFastElement instructions force | |
3072 // the input representation for the key to be an integer, the input | |
3073 // gets replaced during bound check elimination with the index | |
3074 // argument to the bounds check, which can be tagged, so that | |
3075 // case must be handled here, too. | |
3076 if (hinstr->IsDehoisted()) { | |
3077 // Sign extend key because it could be a 32 bit negative value | |
3078 // and the dehoisted address computation happens in 64 bits | |
3079 __ movsxlq(key_reg, key_reg); | |
3080 } | |
3081 } | |
3082 | |
3083 bool requires_hole_check = hinstr->RequiresHoleCheck(); | 3065 bool requires_hole_check = hinstr->RequiresHoleCheck(); |
3084 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | 3066 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
3085 Representation representation = hinstr->representation(); | 3067 Representation representation = hinstr->representation(); |
3086 | 3068 |
3087 if (representation.IsInteger32() && | 3069 if (representation.IsInteger32() && |
3088 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { | 3070 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
3089 ASSERT(!requires_hole_check); | 3071 ASSERT(!requires_hole_check); |
3090 #ifdef DEBUG | 3072 #ifdef DEBUG |
3091 Register scratch = kScratchRegister; | 3073 Register scratch = kScratchRegister; |
3092 __ Load(scratch, | 3074 __ Load(scratch, |
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4136 } | 4118 } |
4137 } | 4119 } |
4138 Condition condition = hinstr->allow_equality() ? below : below_equal; | 4120 Condition condition = hinstr->allow_equality() ? below : below_equal; |
4139 ApplyCheckIf(condition, instr); | 4121 ApplyCheckIf(condition, instr); |
4140 } | 4122 } |
4141 | 4123 |
4142 | 4124 |
4143 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4125 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4144 ElementsKind elements_kind = instr->elements_kind(); | 4126 ElementsKind elements_kind = instr->elements_kind(); |
4145 LOperand* key = instr->key(); | 4127 LOperand* key = instr->key(); |
4146 if (!key->IsConstantOperand()) { | |
4147 Register key_reg = ToRegister(key); | |
4148 // Even though the HLoad/StoreKeyedFastElement instructions force | |
4149 // the input representation for the key to be an integer, the input | |
4150 // gets replaced during bound check elimination with the index | |
4151 // argument to the bounds check, which can be tagged, so that case | |
4152 // must be handled here, too. | |
4153 if (instr->hydrogen()->IsDehoisted()) { | |
4154 // Sign extend key because it could be a 32 bit negative value | |
4155 // and the dehoisted address computation happens in 64 bits | |
4156 __ movsxlq(key_reg, key_reg); | |
4157 } | |
4158 } | |
4159 int base_offset = instr->is_fixed_typed_array() | 4128 int base_offset = instr->is_fixed_typed_array() |
4160 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | 4129 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
4161 : 0; | 4130 : 0; |
4162 Operand operand(BuildFastArrayOperand( | 4131 Operand operand(BuildFastArrayOperand( |
4163 instr->elements(), | 4132 instr->elements(), |
4164 key, | 4133 key, |
4165 elements_kind, | 4134 elements_kind, |
4166 base_offset, | 4135 base_offset, |
4167 instr->additional_index())); | 4136 instr->additional_index())); |
4168 | 4137 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4212 UNREACHABLE(); | 4181 UNREACHABLE(); |
4213 break; | 4182 break; |
4214 } | 4183 } |
4215 } | 4184 } |
4216 } | 4185 } |
4217 | 4186 |
4218 | 4187 |
4219 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4188 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4220 XMMRegister value = ToDoubleRegister(instr->value()); | 4189 XMMRegister value = ToDoubleRegister(instr->value()); |
4221 LOperand* key = instr->key(); | 4190 LOperand* key = instr->key(); |
4222 if (!key->IsConstantOperand()) { | |
4223 Register key_reg = ToRegister(key); | |
4224 // Even though the HLoad/StoreKeyedFastElement instructions force | |
4225 // the input representation for the key to be an integer, the | |
4226 // input gets replaced during bound check elimination with the index | |
4227 // argument to the bounds check, which can be tagged, so that case | |
4228 // must be handled here, too. | |
4229 if (instr->hydrogen()->IsDehoisted()) { | |
4230 // Sign extend key because it could be a 32 bit negative value | |
4231 // and the dehoisted address computation happens in 64 bits | |
4232 __ movsxlq(key_reg, key_reg); | |
4233 } | |
4234 } | |
4235 | |
4236 if (instr->NeedsCanonicalization()) { | 4191 if (instr->NeedsCanonicalization()) { |
4237 Label have_value; | 4192 Label have_value; |
4238 | 4193 |
4239 __ ucomisd(value, value); | 4194 __ ucomisd(value, value); |
4240 __ j(parity_odd, &have_value, Label::kNear); // NaN. | 4195 __ j(parity_odd, &have_value, Label::kNear); // NaN. |
4241 | 4196 |
4242 __ Set(kScratchRegister, BitCast<uint64_t>( | 4197 __ Set(kScratchRegister, BitCast<uint64_t>( |
4243 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 4198 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
4244 __ movq(value, kScratchRegister); | 4199 __ movq(value, kScratchRegister); |
4245 | 4200 |
4246 __ bind(&have_value); | 4201 __ bind(&have_value); |
4247 } | 4202 } |
4248 | 4203 |
4249 Operand double_store_operand = BuildFastArrayOperand( | 4204 Operand double_store_operand = BuildFastArrayOperand( |
4250 instr->elements(), | 4205 instr->elements(), |
4251 key, | 4206 key, |
4252 FAST_DOUBLE_ELEMENTS, | 4207 FAST_DOUBLE_ELEMENTS, |
4253 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4208 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
4254 instr->additional_index()); | 4209 instr->additional_index()); |
4255 | 4210 |
4256 __ movsd(double_store_operand, value); | 4211 __ movsd(double_store_operand, value); |
4257 } | 4212 } |
4258 | 4213 |
4259 | 4214 |
4260 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4215 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4261 HStoreKeyed* hinstr = instr->hydrogen(); | 4216 HStoreKeyed* hinstr = instr->hydrogen(); |
4262 LOperand* key = instr->key(); | 4217 LOperand* key = instr->key(); |
4263 if (!key->IsConstantOperand()) { | |
4264 Register key_reg = ToRegister(key); | |
4265 // Even though the HLoad/StoreKeyedFastElement instructions force | |
4266 // the input representation for the key to be an integer, the | |
4267 // input gets replaced during bound check elimination with the index | |
4268 // argument to the bounds check, which can be tagged, so that case | |
4269 // must be handled here, too. | |
4270 if (hinstr->IsDehoisted()) { | |
4271 // Sign extend key because it could be a 32 bit negative value | |
4272 // and the dehoisted address computation happens in 64 bits | |
4273 __ movsxlq(key_reg, key_reg); | |
4274 } | |
4275 } | |
4276 | |
4277 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | 4218 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
4278 Representation representation = hinstr->value()->representation(); | 4219 Representation representation = hinstr->value()->representation(); |
4279 | 4220 |
4280 if (representation.IsInteger32()) { | 4221 if (representation.IsInteger32()) { |
4281 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 4222 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
4282 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); | 4223 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); |
4283 #ifdef DEBUG | 4224 #ifdef DEBUG |
4284 Register scratch = kScratchRegister; | 4225 Register scratch = kScratchRegister; |
4285 __ Load(scratch, | 4226 __ Load(scratch, |
4286 BuildFastArrayOperand(instr->elements(), | 4227 BuildFastArrayOperand(instr->elements(), |
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5659 FixedArray::kHeaderSize - kPointerSize)); | 5600 FixedArray::kHeaderSize - kPointerSize)); |
5660 __ bind(&done); | 5601 __ bind(&done); |
5661 } | 5602 } |
5662 | 5603 |
5663 | 5604 |
5664 #undef __ | 5605 #undef __ |
5665 | 5606 |
5666 } } // namespace v8::internal | 5607 } } // namespace v8::internal |
5667 | 5608 |
5668 #endif // V8_TARGET_ARCH_X64 | 5609 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |