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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 const Smi& smi_const = Smi::Cast(constant); | 1070 const Smi& smi_const = Smi::Cast(constant); |
1071 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 1071 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
1072 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); | 1072 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
1073 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; | 1073 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
1074 return Utils::IsInt(32, disp); | 1074 return Utils::IsInt(32, disp); |
1075 } | 1075 } |
1076 | 1076 |
1077 | 1077 |
1078 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 1078 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
1079 const intptr_t kNumInputs = 1; | 1079 const intptr_t kNumInputs = 1; |
1080 const intptr_t kNumTemps = 0; | |
1081 LocationSummary* locs = | |
1082 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1083 // TODO(fschneider): Allow immediate operands for the char code. | 1080 // TODO(fschneider): Allow immediate operands for the char code. |
1084 locs->set_in(0, Location::RequiresRegister()); | 1081 return LocationSummary::Make(kNumInputs, |
1085 locs->set_out(Location::RequiresRegister()); | 1082 Location::RequiresRegister(), |
1086 return locs; | 1083 LocationSummary::kNoCall); |
1087 } | 1084 } |
1088 | 1085 |
1089 | 1086 |
1090 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1087 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1091 Register char_code = locs()->in(0).reg(); | 1088 Register char_code = locs()->in(0).reg(); |
1092 Register result = locs()->out().reg(); | 1089 Register result = locs()->out().reg(); |
1093 __ movl(result, | 1090 __ movl(result, |
1094 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); | 1091 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); |
1095 __ movl(result, Address(result, | 1092 __ movl(result, Address(result, |
1096 char_code, | 1093 char_code, |
1097 TIMES_HALF_WORD_SIZE, // Char code is a smi. | 1094 TIMES_HALF_WORD_SIZE, // Char code is a smi. |
1098 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 1095 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
1099 } | 1096 } |
1100 | 1097 |
1101 | 1098 |
1102 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 1099 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { |
1103 const intptr_t kNumInputs = 1; | 1100 const intptr_t kNumInputs = 1; |
1104 const intptr_t kNumTemps = 0; | 1101 return LocationSummary::Make(kNumInputs, |
1105 LocationSummary* locs = | 1102 Location::RequiresRegister(), |
1106 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1103 LocationSummary::kNoCall); |
1107 locs->set_in(0, Location::RequiresRegister()); | |
1108 locs->set_out(Location::RequiresRegister()); | |
1109 return locs; | |
1110 } | 1104 } |
1111 | 1105 |
1112 | 1106 |
1113 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1107 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1114 Register object = locs()->in(0).reg(); | 1108 Register object = locs()->in(0).reg(); |
1115 Register result = locs()->out().reg(); | 1109 Register result = locs()->out().reg(); |
1116 __ movl(result, FieldAddress(object, offset())); | 1110 __ movl(result, FieldAddress(object, offset())); |
1117 } | 1111 } |
1118 | 1112 |
1119 | 1113 |
| 1114 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { |
| 1115 const intptr_t kNumInputs = 1; |
| 1116 return LocationSummary::Make(kNumInputs, |
| 1117 Location::RequiresRegister(), |
| 1118 LocationSummary::kNoCall); |
| 1119 } |
| 1120 |
| 1121 |
| 1122 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1123 Register object = locs()->in(0).reg(); |
| 1124 Register result = locs()->out().reg(); |
| 1125 Label load, done; |
| 1126 __ testl(object, Immediate(kSmiTagMask)); |
| 1127 __ j(NOT_ZERO, &load, Assembler::kNearJump); |
| 1128 __ movl(result, Immediate(Smi::RawValue(kSmiCid))); |
| 1129 __ jmp(&done); |
| 1130 __ Bind(&load); |
| 1131 __ LoadClassId(result, object); |
| 1132 __ SmiTag(result); |
| 1133 __ Bind(&done); |
| 1134 } |
| 1135 |
| 1136 |
1120 CompileType LoadIndexedInstr::ComputeType() const { | 1137 CompileType LoadIndexedInstr::ComputeType() const { |
1121 switch (class_id_) { | 1138 switch (class_id_) { |
1122 case kArrayCid: | 1139 case kArrayCid: |
1123 case kImmutableArrayCid: | 1140 case kImmutableArrayCid: |
1124 return CompileType::Dynamic(); | 1141 return CompileType::Dynamic(); |
1125 | 1142 |
1126 case kTypedDataFloat32ArrayCid: | 1143 case kTypedDataFloat32ArrayCid: |
1127 case kTypedDataFloat64ArrayCid: | 1144 case kTypedDataFloat64ArrayCid: |
1128 return CompileType::FromCid(kDoubleCid); | 1145 return CompileType::FromCid(kDoubleCid); |
1129 case kTypedDataFloat32x4ArrayCid: | 1146 case kTypedDataFloat32x4ArrayCid: |
(...skipping 2180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3310 } | 3327 } |
3311 | 3328 |
3312 | 3329 |
3313 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3330 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3314 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3331 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
3315 } | 3332 } |
3316 | 3333 |
3317 | 3334 |
3318 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3335 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
3319 const intptr_t kNumInputs = 1; | 3336 const intptr_t kNumInputs = 1; |
3320 const intptr_t kNumTemps = 0; | 3337 return LocationSummary::Make(kNumInputs, |
3321 LocationSummary* summary = | 3338 Location::SameAsFirstInput(), |
3322 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3339 LocationSummary::kNoCall); |
3323 summary->set_in(0, Location::RequiresRegister()); | |
3324 summary->set_out(Location::SameAsFirstInput()); | |
3325 return summary; | |
3326 } | 3340 } |
3327 | 3341 |
3328 | 3342 |
3329 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3343 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3330 Register value = locs()->in(0).reg(); | 3344 Register value = locs()->in(0).reg(); |
3331 ASSERT(value == locs()->out().reg()); | 3345 ASSERT(value == locs()->out().reg()); |
3332 switch (op_kind()) { | 3346 switch (op_kind()) { |
3333 case Token::kNEGATE: { | 3347 case Token::kNEGATE: { |
3334 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3348 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3335 kDeoptUnaryOp); | 3349 kDeoptUnaryOp); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3393 __ SmiTag(result); | 3407 __ SmiTag(result); |
3394 __ jmp(&done); | 3408 __ jmp(&done); |
3395 __ Bind(&do_call); | 3409 __ Bind(&do_call); |
3396 __ pushl(value_obj); | 3410 __ pushl(value_obj); |
3397 ASSERT(instance_call()->HasICData()); | 3411 ASSERT(instance_call()->HasICData()); |
3398 const ICData& ic_data = *instance_call()->ic_data(); | 3412 const ICData& ic_data = *instance_call()->ic_data(); |
3399 ASSERT((ic_data.NumberOfChecks() == 1)); | 3413 ASSERT((ic_data.NumberOfChecks() == 1)); |
3400 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); | 3414 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); |
3401 | 3415 |
3402 const intptr_t kNumberOfArguments = 1; | 3416 const intptr_t kNumberOfArguments = 1; |
3403 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3417 compiler->GenerateStaticCall(deopt_id(), |
3404 instance_call()->token_pos(), | 3418 instance_call()->token_pos(), |
3405 target, | 3419 target, |
3406 kNumberOfArguments, | 3420 kNumberOfArguments, |
3407 Array::Handle(), // No argument names., | 3421 Array::Handle(), // No argument names., |
3408 locs()); | 3422 locs()); |
3409 __ Bind(&done); | 3423 __ Bind(&done); |
3410 } | 3424 } |
3411 | 3425 |
3412 | 3426 |
3413 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3427 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 __ leave(); | 3503 __ leave(); |
3490 } | 3504 } |
3491 | 3505 |
3492 | 3506 |
3493 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3507 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
3494 return MakeCallSummary(); | 3508 return MakeCallSummary(); |
3495 } | 3509 } |
3496 | 3510 |
3497 | 3511 |
3498 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3512 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3499 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 3513 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3500 kDeoptPolymorphicInstanceCallTestFail); | 3514 kDeoptPolymorphicInstanceCallTestFail); |
3501 if (ic_data().NumberOfChecks() == 0) { | 3515 if (ic_data().NumberOfChecks() == 0) { |
3502 __ jmp(deopt); | 3516 __ jmp(deopt); |
3503 return; | 3517 return; |
3504 } | 3518 } |
3505 ASSERT(ic_data().num_args_tested() == 1); | 3519 ASSERT(ic_data().num_args_tested() == 1); |
3506 if (!with_checks()) { | 3520 if (!with_checks()) { |
3507 ASSERT(ic_data().HasOneTarget()); | 3521 ASSERT(ic_data().HasOneTarget()); |
3508 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 3522 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
3509 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3523 compiler->GenerateStaticCall(deopt_id(), |
3510 instance_call()->token_pos(), | 3524 instance_call()->token_pos(), |
3511 target, | 3525 target, |
3512 instance_call()->ArgumentCount(), | 3526 instance_call()->ArgumentCount(), |
3513 instance_call()->argument_names(), | 3527 instance_call()->argument_names(), |
3514 locs()); | 3528 locs()); |
3515 return; | 3529 return; |
3516 } | 3530 } |
3517 | 3531 |
3518 // Load receiver into EAX. | 3532 // Load receiver into EAX. |
3519 __ movl(EAX, | 3533 __ movl(EAX, |
3520 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); | 3534 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); |
3521 | 3535 |
3522 LoadValueCid(compiler, EDI, EAX, | 3536 LoadValueCid(compiler, EDI, EAX, |
3523 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); | 3537 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); |
3524 | 3538 |
3525 compiler->EmitTestAndCall(ic_data(), | 3539 compiler->EmitTestAndCall(ic_data(), |
3526 EDI, // Class id register. | 3540 EDI, // Class id register. |
3527 instance_call()->ArgumentCount(), | 3541 instance_call()->ArgumentCount(), |
3528 instance_call()->argument_names(), | 3542 instance_call()->argument_names(), |
3529 deopt, | 3543 deopt, |
3530 instance_call()->deopt_id(), | 3544 deopt_id(), |
3531 instance_call()->token_pos(), | 3545 instance_call()->token_pos(), |
3532 locs()); | 3546 locs()); |
3533 } | 3547 } |
3534 | 3548 |
3535 | 3549 |
3536 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3550 LocationSummary* BranchInstr::MakeLocationSummary() const { |
3537 UNREACHABLE(); | 3551 UNREACHABLE(); |
3538 return NULL; | 3552 return NULL; |
3539 } | 3553 } |
3540 | 3554 |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4409 PcDescriptors::kOther, | 4423 PcDescriptors::kOther, |
4410 locs()); | 4424 locs()); |
4411 __ Drop(2); // Discard type arguments and receiver. | 4425 __ Drop(2); // Discard type arguments and receiver. |
4412 } | 4426 } |
4413 | 4427 |
4414 } // namespace dart | 4428 } // namespace dart |
4415 | 4429 |
4416 #undef __ | 4430 #undef __ |
4417 | 4431 |
4418 #endif // defined TARGET_ARCH_IA32 | 4432 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |