Chromium Code Reviews| 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)); | |
|
srdjan
2013/05/02 20:06:30
We may be able to determine that object is never S
| |
| 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 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3177 } | 3194 } |
| 3178 | 3195 |
| 3179 | 3196 |
| 3180 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3197 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3181 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3198 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
| 3182 } | 3199 } |
| 3183 | 3200 |
| 3184 | 3201 |
| 3185 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3202 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3186 const intptr_t kNumInputs = 1; | 3203 const intptr_t kNumInputs = 1; |
| 3187 const intptr_t kNumTemps = 0; | 3204 return LocationSummary::Make(kNumInputs, |
| 3188 LocationSummary* summary = | 3205 Location::SameAsFirstInput(), |
| 3189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3206 LocationSummary::kNoCall); |
| 3190 summary->set_in(0, Location::RequiresRegister()); | |
| 3191 summary->set_out(Location::SameAsFirstInput()); | |
| 3192 return summary; | |
| 3193 } | 3207 } |
| 3194 | 3208 |
| 3195 | 3209 |
| 3196 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3210 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3197 Register value = locs()->in(0).reg(); | 3211 Register value = locs()->in(0).reg(); |
| 3198 ASSERT(value == locs()->out().reg()); | 3212 ASSERT(value == locs()->out().reg()); |
| 3199 switch (op_kind()) { | 3213 switch (op_kind()) { |
| 3200 case Token::kNEGATE: { | 3214 case Token::kNEGATE: { |
| 3201 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3215 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3202 kDeoptUnaryOp); | 3216 kDeoptUnaryOp); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3260 __ SmiTag(result); | 3274 __ SmiTag(result); |
| 3261 __ jmp(&done); | 3275 __ jmp(&done); |
| 3262 __ Bind(&do_call); | 3276 __ Bind(&do_call); |
| 3263 __ pushl(value_obj); | 3277 __ pushl(value_obj); |
| 3264 ASSERT(instance_call()->HasICData()); | 3278 ASSERT(instance_call()->HasICData()); |
| 3265 const ICData& ic_data = *instance_call()->ic_data(); | 3279 const ICData& ic_data = *instance_call()->ic_data(); |
| 3266 ASSERT((ic_data.NumberOfChecks() == 1)); | 3280 ASSERT((ic_data.NumberOfChecks() == 1)); |
| 3267 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); | 3281 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); |
| 3268 | 3282 |
| 3269 const intptr_t kNumberOfArguments = 1; | 3283 const intptr_t kNumberOfArguments = 1; |
| 3270 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3284 compiler->GenerateStaticCall(deopt_id(), |
| 3271 instance_call()->token_pos(), | 3285 instance_call()->token_pos(), |
| 3272 target, | 3286 target, |
| 3273 kNumberOfArguments, | 3287 kNumberOfArguments, |
| 3274 Array::Handle(), // No argument names., | 3288 Array::Handle(), // No argument names., |
| 3275 locs()); | 3289 locs()); |
| 3276 __ Bind(&done); | 3290 __ Bind(&done); |
| 3277 } | 3291 } |
| 3278 | 3292 |
| 3279 | 3293 |
| 3280 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3294 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3356 __ leave(); | 3370 __ leave(); |
| 3357 } | 3371 } |
| 3358 | 3372 |
| 3359 | 3373 |
| 3360 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3374 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 3361 return MakeCallSummary(); | 3375 return MakeCallSummary(); |
| 3362 } | 3376 } |
| 3363 | 3377 |
| 3364 | 3378 |
| 3365 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3379 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3366 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 3380 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3367 kDeoptPolymorphicInstanceCallTestFail); | 3381 kDeoptPolymorphicInstanceCallTestFail); |
| 3368 if (ic_data().NumberOfChecks() == 0) { | 3382 if (ic_data().NumberOfChecks() == 0) { |
| 3369 __ jmp(deopt); | 3383 __ jmp(deopt); |
| 3370 return; | 3384 return; |
| 3371 } | 3385 } |
| 3372 ASSERT(ic_data().num_args_tested() == 1); | 3386 ASSERT(ic_data().num_args_tested() == 1); |
| 3373 if (!with_checks()) { | 3387 if (!with_checks()) { |
| 3374 ASSERT(ic_data().HasOneTarget()); | 3388 ASSERT(ic_data().HasOneTarget()); |
| 3375 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 3389 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 3376 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 3390 compiler->GenerateStaticCall(deopt_id(), |
| 3377 instance_call()->token_pos(), | 3391 instance_call()->token_pos(), |
| 3378 target, | 3392 target, |
| 3379 instance_call()->ArgumentCount(), | 3393 instance_call()->ArgumentCount(), |
| 3380 instance_call()->argument_names(), | 3394 instance_call()->argument_names(), |
| 3381 locs()); | 3395 locs()); |
| 3382 return; | 3396 return; |
| 3383 } | 3397 } |
| 3384 | 3398 |
| 3385 // Load receiver into EAX. | 3399 // Load receiver into EAX. |
| 3386 __ movl(EAX, | 3400 __ movl(EAX, |
| 3387 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); | 3401 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); |
| 3388 | 3402 |
| 3389 LoadValueCid(compiler, EDI, EAX, | 3403 LoadValueCid(compiler, EDI, EAX, |
| 3390 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); | 3404 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); |
| 3391 | 3405 |
| 3392 compiler->EmitTestAndCall(ic_data(), | 3406 compiler->EmitTestAndCall(ic_data(), |
| 3393 EDI, // Class id register. | 3407 EDI, // Class id register. |
| 3394 instance_call()->ArgumentCount(), | 3408 instance_call()->ArgumentCount(), |
| 3395 instance_call()->argument_names(), | 3409 instance_call()->argument_names(), |
| 3396 deopt, | 3410 deopt, |
| 3397 instance_call()->deopt_id(), | 3411 deopt_id(), |
| 3398 instance_call()->token_pos(), | 3412 instance_call()->token_pos(), |
| 3399 locs()); | 3413 locs()); |
| 3400 } | 3414 } |
| 3401 | 3415 |
| 3402 | 3416 |
| 3403 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3417 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 3404 UNREACHABLE(); | 3418 UNREACHABLE(); |
| 3405 return NULL; | 3419 return NULL; |
| 3406 } | 3420 } |
| 3407 | 3421 |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4276 PcDescriptors::kOther, | 4290 PcDescriptors::kOther, |
| 4277 locs()); | 4291 locs()); |
| 4278 __ Drop(2); // Discard type arguments and receiver. | 4292 __ Drop(2); // Discard type arguments and receiver. |
| 4279 } | 4293 } |
| 4280 | 4294 |
| 4281 } // namespace dart | 4295 } // namespace dart |
| 4282 | 4296 |
| 4283 #undef __ | 4297 #undef __ |
| 4284 | 4298 |
| 4285 #endif // defined TARGET_ARCH_IA32 | 4299 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |