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 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3317 } | 3331 } |
3318 | 3332 |
3319 | 3333 |
3320 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3334 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3321 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3335 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
3322 } | 3336 } |
3323 | 3337 |
3324 | 3338 |
3325 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3339 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
3326 const intptr_t kNumInputs = 1; | 3340 const intptr_t kNumInputs = 1; |
3327 const intptr_t kNumTemps = 0; | 3341 return LocationSummary::Make(kNumInputs, |
3328 LocationSummary* summary = | 3342 Location::SameAsFirstInput(), |
3329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3343 LocationSummary::kNoCall); |
3330 summary->set_in(0, Location::RequiresRegister()); | |
3331 summary->set_out(Location::SameAsFirstInput()); | |
3332 return summary; | |
3333 } | 3344 } |
3334 | 3345 |
3335 | 3346 |
3336 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3347 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3337 Register value = locs()->in(0).reg(); | 3348 Register value = locs()->in(0).reg(); |
3338 ASSERT(value == locs()->out().reg()); | 3349 ASSERT(value == locs()->out().reg()); |
3339 switch (op_kind()) { | 3350 switch (op_kind()) { |
3340 case Token::kNEGATE: { | 3351 case Token::kNEGATE: { |
3341 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3352 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3342 kDeoptUnaryOp); | 3353 kDeoptUnaryOp); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3404 __ SmiTag(result); | 3415 __ SmiTag(result); |
3405 __ jmp(&done); | 3416 __ jmp(&done); |
3406 __ Bind(&do_call); | 3417 __ Bind(&do_call); |
3407 ASSERT(instance_call()->HasICData()); | 3418 ASSERT(instance_call()->HasICData()); |
3408 const ICData& ic_data = *instance_call()->ic_data(); | 3419 const ICData& ic_data = *instance_call()->ic_data(); |
3409 ASSERT((ic_data.NumberOfChecks() == 1)); | 3420 ASSERT((ic_data.NumberOfChecks() == 1)); |
3410 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); | 3421 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); |
3411 | 3422 |
3412 const intptr_t kNumberOfArguments = 1; | 3423 const intptr_t kNumberOfArguments = 1; |
3413 __ pushq(value_obj); | 3424 __ pushq(value_obj); |
3414 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3425 compiler->GenerateStaticCall(deopt_id(), |
3415 instance_call()->token_pos(), | 3426 instance_call()->token_pos(), |
3416 target, | 3427 target, |
3417 kNumberOfArguments, | 3428 kNumberOfArguments, |
3418 Array::Handle(), // No argument names. | 3429 Array::Handle(), // No argument names. |
3419 locs()); | 3430 locs()); |
3420 __ Bind(&done); | 3431 __ Bind(&done); |
3421 } | 3432 } |
3422 | 3433 |
3423 | 3434 |
3424 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3435 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3513 __ leave(); | 3524 __ leave(); |
3514 } | 3525 } |
3515 | 3526 |
3516 | 3527 |
3517 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3528 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
3518 return MakeCallSummary(); | 3529 return MakeCallSummary(); |
3519 } | 3530 } |
3520 | 3531 |
3521 | 3532 |
3522 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3533 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3523 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 3534 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3524 kDeoptPolymorphicInstanceCallTestFail); | 3535 kDeoptPolymorphicInstanceCallTestFail); |
3525 if (ic_data().NumberOfChecks() == 0) { | 3536 if (ic_data().NumberOfChecks() == 0) { |
3526 __ jmp(deopt); | 3537 __ jmp(deopt); |
3527 return; | 3538 return; |
3528 } | 3539 } |
3529 ASSERT(ic_data().num_args_tested() == 1); | 3540 ASSERT(ic_data().num_args_tested() == 1); |
3530 if (!with_checks()) { | 3541 if (!with_checks()) { |
3531 ASSERT(ic_data().HasOneTarget()); | 3542 ASSERT(ic_data().HasOneTarget()); |
3532 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 3543 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
3533 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3544 compiler->GenerateStaticCall(deopt_id(), |
3534 instance_call()->token_pos(), | 3545 instance_call()->token_pos(), |
3535 target, | 3546 target, |
3536 instance_call()->ArgumentCount(), | 3547 instance_call()->ArgumentCount(), |
3537 instance_call()->argument_names(), | 3548 instance_call()->argument_names(), |
3538 locs()); | 3549 locs()); |
3539 return; | 3550 return; |
3540 } | 3551 } |
3541 | 3552 |
3542 // Load receiver into RAX. | 3553 // Load receiver into RAX. |
3543 __ movq(RAX, | 3554 __ movq(RAX, |
3544 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); | 3555 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); |
3545 LoadValueCid(compiler, RDI, RAX, | 3556 LoadValueCid(compiler, RDI, RAX, |
3546 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); | 3557 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); |
3547 compiler->EmitTestAndCall(ic_data(), | 3558 compiler->EmitTestAndCall(ic_data(), |
3548 RDI, // Class id register. | 3559 RDI, // Class id register. |
3549 instance_call()->ArgumentCount(), | 3560 instance_call()->ArgumentCount(), |
3550 instance_call()->argument_names(), | 3561 instance_call()->argument_names(), |
3551 deopt, | 3562 deopt, |
3552 instance_call()->deopt_id(), | 3563 deopt_id(), |
3553 instance_call()->token_pos(), | 3564 instance_call()->token_pos(), |
3554 locs()); | 3565 locs()); |
3555 } | 3566 } |
3556 | 3567 |
3557 | 3568 |
3558 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3569 LocationSummary* BranchInstr::MakeLocationSummary() const { |
3559 UNREACHABLE(); | 3570 UNREACHABLE(); |
3560 return NULL; | 3571 return NULL; |
3561 } | 3572 } |
3562 | 3573 |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4038 PcDescriptors::kOther, | 4049 PcDescriptors::kOther, |
4039 locs()); | 4050 locs()); |
4040 __ Drop(2); // Discard type arguments and receiver. | 4051 __ Drop(2); // Discard type arguments and receiver. |
4041 } | 4052 } |
4042 | 4053 |
4043 } // namespace dart | 4054 } // namespace dart |
4044 | 4055 |
4045 #undef __ | 4056 #undef __ |
4046 | 4057 |
4047 #endif // defined TARGET_ARCH_X64 | 4058 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |