| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 const Smi& smi_const = Smi::Cast(constant); | 1082 const Smi& smi_const = Smi::Cast(constant); |
| 1083 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 1083 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| 1084 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); | 1084 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| 1085 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; | 1085 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
| 1086 return Utils::IsInt(32, disp); | 1086 return Utils::IsInt(32, disp); |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 | 1089 |
| 1090 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 1090 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
| 1091 const intptr_t kNumInputs = 1; | 1091 const intptr_t kNumInputs = 1; |
| 1092 const intptr_t kNumTemps = 0; | |
| 1093 LocationSummary* locs = | |
| 1094 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 1095 // TODO(fschneider): Allow immediate operands for the char code. | 1092 // TODO(fschneider): Allow immediate operands for the char code. |
| 1096 locs->set_in(0, Location::RequiresRegister()); | 1093 return LocationSummary::Make(kNumInputs, |
| 1097 locs->set_out(Location::RequiresRegister()); | 1094 Location::RequiresRegister(), |
| 1098 return locs; | 1095 LocationSummary::kNoCall); |
| 1099 } | 1096 } |
| 1100 | 1097 |
| 1101 | 1098 |
| 1102 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1099 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1103 Register char_code = locs()->in(0).reg(); | 1100 Register char_code = locs()->in(0).reg(); |
| 1104 Register result = locs()->out().reg(); | 1101 Register result = locs()->out().reg(); |
| 1105 __ movq(result, | 1102 __ movq(result, |
| 1106 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); | 1103 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); |
| 1107 __ movq(result, Address(result, | 1104 __ movq(result, Address(result, |
| 1108 char_code, | 1105 char_code, |
| 1109 TIMES_HALF_WORD_SIZE, // Char code is a smi. | 1106 TIMES_HALF_WORD_SIZE, // Char code is a smi. |
| 1110 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 1107 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
| 1111 } | 1108 } |
| 1112 | 1109 |
| 1113 | 1110 |
| 1114 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 1111 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { |
| 1115 const intptr_t kNumInputs = 1; | 1112 const intptr_t kNumInputs = 1; |
| 1116 const intptr_t kNumTemps = 0; | 1113 return LocationSummary::Make(kNumInputs, |
| 1117 LocationSummary* locs = | 1114 Location::RequiresRegister(), |
| 1118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1115 LocationSummary::kNoCall); |
| 1119 locs->set_in(0, Location::RequiresRegister()); | |
| 1120 locs->set_out(Location::RequiresRegister()); | |
| 1121 return locs; | |
| 1122 } | 1116 } |
| 1123 | 1117 |
| 1124 | 1118 |
| 1125 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1119 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1126 Register object = locs()->in(0).reg(); | 1120 Register object = locs()->in(0).reg(); |
| 1127 Register result = locs()->out().reg(); | 1121 Register result = locs()->out().reg(); |
| 1128 __ movq(result, FieldAddress(object, offset())); | 1122 __ movq(result, FieldAddress(object, offset())); |
| 1129 } | 1123 } |
| 1130 | 1124 |
| 1131 | 1125 |
| 1126 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { |
| 1127 const intptr_t kNumInputs = 1; |
| 1128 return LocationSummary::Make(kNumInputs, |
| 1129 Location::RequiresRegister(), |
| 1130 LocationSummary::kNoCall); |
| 1131 } |
| 1132 |
| 1133 |
| 1134 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1135 Register object = locs()->in(0).reg(); |
| 1136 Register result = locs()->out().reg(); |
| 1137 Label load, done; |
| 1138 __ testq(object, Immediate(kSmiTagMask)); |
| 1139 __ j(NOT_ZERO, &load, Assembler::kNearJump); |
| 1140 __ movq(result, Immediate(Smi::RawValue(kSmiCid))); |
| 1141 __ jmp(&done); |
| 1142 __ Bind(&load); |
| 1143 __ LoadClassId(result, object); |
| 1144 __ SmiTag(result); |
| 1145 __ Bind(&done); |
| 1146 } |
| 1147 |
| 1148 |
| 1132 CompileType LoadIndexedInstr::ComputeType() const { | 1149 CompileType LoadIndexedInstr::ComputeType() const { |
| 1133 switch (class_id_) { | 1150 switch (class_id_) { |
| 1134 case kArrayCid: | 1151 case kArrayCid: |
| 1135 case kImmutableArrayCid: | 1152 case kImmutableArrayCid: |
| 1136 return CompileType::Dynamic(); | 1153 return CompileType::Dynamic(); |
| 1137 | 1154 |
| 1138 case kTypedDataFloat32ArrayCid: | 1155 case kTypedDataFloat32ArrayCid: |
| 1139 case kTypedDataFloat64ArrayCid: | 1156 case kTypedDataFloat64ArrayCid: |
| 1140 return CompileType::FromCid(kDoubleCid); | 1157 return CompileType::FromCid(kDoubleCid); |
| 1141 case kTypedDataFloat32x4ArrayCid: | 1158 case kTypedDataFloat32x4ArrayCid: |
| (...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2740 slow_path->entry_label(), | 2757 slow_path->entry_label(), |
| 2741 Assembler::kFarJump, | 2758 Assembler::kFarJump, |
| 2742 out_reg); | 2759 out_reg); |
| 2743 __ Bind(slow_path->exit_label()); | 2760 __ Bind(slow_path->exit_label()); |
| 2744 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | 2761 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); |
| 2745 } | 2762 } |
| 2746 | 2763 |
| 2747 | 2764 |
| 2748 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2765 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { |
| 2749 const intptr_t kNumInputs = 1; | 2766 const intptr_t kNumInputs = 1; |
| 2750 const intptr_t kNumTemps = 0; | 2767 return LocationSummary::Make(kNumInputs, |
| 2751 LocationSummary* summary = | 2768 Location::RequiresFpuRegister(), |
| 2752 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2769 LocationSummary::kNoCall); |
| 2753 summary->set_in(0, Location::RequiresRegister()); | |
| 2754 summary->set_out(Location::RequiresFpuRegister()); | |
| 2755 return summary; | |
| 2756 } | 2770 } |
| 2757 | 2771 |
| 2758 | 2772 |
| 2759 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2773 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2760 const intptr_t value_cid = value()->Type()->ToCid(); | 2774 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2761 const Register value = locs()->in(0).reg(); | 2775 const Register value = locs()->in(0).reg(); |
| 2762 const XmmRegister result = locs()->out().fpu_reg(); | 2776 const XmmRegister result = locs()->out().fpu_reg(); |
| 2763 | 2777 |
| 2764 if (value_cid != kFloat32x4Cid) { | 2778 if (value_cid != kFloat32x4Cid) { |
| 2765 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2779 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3184 } | 3198 } |
| 3185 | 3199 |
| 3186 | 3200 |
| 3187 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3201 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3188 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3202 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
| 3189 } | 3203 } |
| 3190 | 3204 |
| 3191 | 3205 |
| 3192 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3206 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3193 const intptr_t kNumInputs = 1; | 3207 const intptr_t kNumInputs = 1; |
| 3194 const intptr_t kNumTemps = 0; | 3208 return LocationSummary::Make(kNumInputs, |
| 3195 LocationSummary* summary = | 3209 Location::SameAsFirstInput(), |
| 3196 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3210 LocationSummary::kNoCall); |
| 3197 summary->set_in(0, Location::RequiresRegister()); | |
| 3198 summary->set_out(Location::SameAsFirstInput()); | |
| 3199 return summary; | |
| 3200 } | 3211 } |
| 3201 | 3212 |
| 3202 | 3213 |
| 3203 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3214 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3204 Register value = locs()->in(0).reg(); | 3215 Register value = locs()->in(0).reg(); |
| 3205 ASSERT(value == locs()->out().reg()); | 3216 ASSERT(value == locs()->out().reg()); |
| 3206 switch (op_kind()) { | 3217 switch (op_kind()) { |
| 3207 case Token::kNEGATE: { | 3218 case Token::kNEGATE: { |
| 3208 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3219 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3209 kDeoptUnaryOp); | 3220 kDeoptUnaryOp); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3271 __ SmiTag(result); | 3282 __ SmiTag(result); |
| 3272 __ jmp(&done); | 3283 __ jmp(&done); |
| 3273 __ Bind(&do_call); | 3284 __ Bind(&do_call); |
| 3274 ASSERT(instance_call()->HasICData()); | 3285 ASSERT(instance_call()->HasICData()); |
| 3275 const ICData& ic_data = *instance_call()->ic_data(); | 3286 const ICData& ic_data = *instance_call()->ic_data(); |
| 3276 ASSERT((ic_data.NumberOfChecks() == 1)); | 3287 ASSERT((ic_data.NumberOfChecks() == 1)); |
| 3277 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); | 3288 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); |
| 3278 | 3289 |
| 3279 const intptr_t kNumberOfArguments = 1; | 3290 const intptr_t kNumberOfArguments = 1; |
| 3280 __ pushq(value_obj); | 3291 __ pushq(value_obj); |
| 3281 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3292 compiler->GenerateStaticCall(deopt_id(), |
| 3282 instance_call()->token_pos(), | 3293 instance_call()->token_pos(), |
| 3283 target, | 3294 target, |
| 3284 kNumberOfArguments, | 3295 kNumberOfArguments, |
| 3285 Array::Handle(), // No argument names. | 3296 Array::Handle(), // No argument names. |
| 3286 locs()); | 3297 locs()); |
| 3287 __ Bind(&done); | 3298 __ Bind(&done); |
| 3288 } | 3299 } |
| 3289 | 3300 |
| 3290 | 3301 |
| 3291 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3302 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3380 __ leave(); | 3391 __ leave(); |
| 3381 } | 3392 } |
| 3382 | 3393 |
| 3383 | 3394 |
| 3384 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3395 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 3385 return MakeCallSummary(); | 3396 return MakeCallSummary(); |
| 3386 } | 3397 } |
| 3387 | 3398 |
| 3388 | 3399 |
| 3389 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3400 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3390 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 3401 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3391 kDeoptPolymorphicInstanceCallTestFail); | 3402 kDeoptPolymorphicInstanceCallTestFail); |
| 3392 if (ic_data().NumberOfChecks() == 0) { | 3403 if (ic_data().NumberOfChecks() == 0) { |
| 3393 __ jmp(deopt); | 3404 __ jmp(deopt); |
| 3394 return; | 3405 return; |
| 3395 } | 3406 } |
| 3396 ASSERT(ic_data().num_args_tested() == 1); | 3407 ASSERT(ic_data().num_args_tested() == 1); |
| 3397 if (!with_checks()) { | 3408 if (!with_checks()) { |
| 3398 ASSERT(ic_data().HasOneTarget()); | 3409 ASSERT(ic_data().HasOneTarget()); |
| 3399 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 3410 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 3400 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3411 compiler->GenerateStaticCall(deopt_id(), |
| 3401 instance_call()->token_pos(), | 3412 instance_call()->token_pos(), |
| 3402 target, | 3413 target, |
| 3403 instance_call()->ArgumentCount(), | 3414 instance_call()->ArgumentCount(), |
| 3404 instance_call()->argument_names(), | 3415 instance_call()->argument_names(), |
| 3405 locs()); | 3416 locs()); |
| 3406 return; | 3417 return; |
| 3407 } | 3418 } |
| 3408 | 3419 |
| 3409 // Load receiver into RAX. | 3420 // Load receiver into RAX. |
| 3410 __ movq(RAX, | 3421 __ movq(RAX, |
| 3411 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); | 3422 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); |
| 3412 LoadValueCid(compiler, RDI, RAX, | 3423 LoadValueCid(compiler, RDI, RAX, |
| 3413 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); | 3424 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); |
| 3414 compiler->EmitTestAndCall(ic_data(), | 3425 compiler->EmitTestAndCall(ic_data(), |
| 3415 RDI, // Class id register. | 3426 RDI, // Class id register. |
| 3416 instance_call()->ArgumentCount(), | 3427 instance_call()->ArgumentCount(), |
| 3417 instance_call()->argument_names(), | 3428 instance_call()->argument_names(), |
| 3418 deopt, | 3429 deopt, |
| 3419 instance_call()->deopt_id(), | 3430 deopt_id(), |
| 3420 instance_call()->token_pos(), | 3431 instance_call()->token_pos(), |
| 3421 locs()); | 3432 locs()); |
| 3422 } | 3433 } |
| 3423 | 3434 |
| 3424 | 3435 |
| 3425 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3436 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 3426 UNREACHABLE(); | 3437 UNREACHABLE(); |
| 3427 return NULL; | 3438 return NULL; |
| 3428 } | 3439 } |
| 3429 | 3440 |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3905 PcDescriptors::kOther, | 3916 PcDescriptors::kOther, |
| 3906 locs()); | 3917 locs()); |
| 3907 __ Drop(2); // Discard type arguments and receiver. | 3918 __ Drop(2); // Discard type arguments and receiver. |
| 3908 } | 3919 } |
| 3909 | 3920 |
| 3910 } // namespace dart | 3921 } // namespace dart |
| 3911 | 3922 |
| 3912 #undef __ | 3923 #undef __ |
| 3913 | 3924 |
| 3914 #endif // defined TARGET_ARCH_X64 | 3925 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |