| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 // Generic summary for call instructions that have all arguments pushed | 28 // Generic summary for call instructions that have all arguments pushed |
| 29 // on the stack and return the result in a fixed register V0. | 29 // on the stack and return the result in a fixed register V0. |
| 30 LocationSummary* Instruction::MakeCallSummary() { | 30 LocationSummary* Instruction::MakeCallSummary() { |
| 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 32 result->set_out(Location::RegisterLocation(V0)); | 32 result->set_out(Location::RegisterLocation(V0)); |
| 33 return result; | 33 return result; |
| 34 } | 34 } |
| 35 | 35 |
| 36 | 36 |
| 37 LocationSummary* PushArgumentInstr::MakeLocationSummary() const { | 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { |
| 38 const intptr_t kNumInputs = 1; | 38 const intptr_t kNumInputs = 1; |
| 39 const intptr_t kNumTemps= 0; | 39 const intptr_t kNumTemps= 0; |
| 40 LocationSummary* locs = | 40 LocationSummary* locs = |
| 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 42 locs->set_in(0, Location::AnyOrConstant(value())); | 42 locs->set_in(0, Location::AnyOrConstant(value())); |
| 43 return locs; | 43 return locs; |
| 44 } | 44 } |
| 45 | 45 |
| 46 | 46 |
| 47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode | 48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode |
| 49 // where PushArgument is handled by BindInstr::EmitNativeCode. | 49 // where PushArgument is handled by BindInstr::EmitNativeCode. |
| 50 __ TraceSimMsg("PushArgumentInstr"); | 50 __ TraceSimMsg("PushArgumentInstr"); |
| 51 if (compiler->is_optimizing()) { | 51 if (compiler->is_optimizing()) { |
| 52 Location value = locs()->in(0); | 52 Location value = locs()->in(0); |
| 53 if (value.IsRegister()) { | 53 if (value.IsRegister()) { |
| 54 __ Push(value.reg()); | 54 __ Push(value.reg()); |
| 55 } else if (value.IsConstant()) { | 55 } else if (value.IsConstant()) { |
| 56 __ PushObject(value.constant()); | 56 __ PushObject(value.constant()); |
| 57 } else { | 57 } else { |
| 58 ASSERT(value.IsStackSlot()); | 58 ASSERT(value.IsStackSlot()); |
| 59 const intptr_t value_offset = value.ToStackSlotOffset(); | 59 const intptr_t value_offset = value.ToStackSlotOffset(); |
| 60 __ LoadFromOffset(TMP, FP, value_offset); | 60 __ LoadFromOffset(TMP, FP, value_offset); |
| 61 __ Push(TMP); | 61 __ Push(TMP); |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 67 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { |
| 68 const intptr_t kNumInputs = 1; | 68 const intptr_t kNumInputs = 1; |
| 69 const intptr_t kNumTemps = 0; | 69 const intptr_t kNumTemps = 0; |
| 70 LocationSummary* locs = | 70 LocationSummary* locs = |
| 71 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 71 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 72 locs->set_in(0, Location::RegisterLocation(V0)); | 72 locs->set_in(0, Location::RegisterLocation(V0)); |
| 73 return locs; | 73 return locs; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 // Attempt optimized compilation at return instruction instead of at the entry. | 77 // Attempt optimized compilation at return instruction instead of at the entry. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 // Detect pattern when one value is zero and another is a power of 2. | 130 // Detect pattern when one value is zero and another is a power of 2. |
| 131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 134 } | 134 } |
| 135 | 135 |
| 136 | 136 |
| 137 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 137 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { |
| 138 return comparison()->MakeLocationSummary(); | 138 comparison()->InitializeLocationSummary(opt); |
| 139 return comparison()->locs(); |
| 139 } | 140 } |
| 140 | 141 |
| 141 | 142 |
| 142 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 143 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 143 const Register result = locs()->out().reg(); | 144 const Register result = locs()->out().reg(); |
| 144 | 145 |
| 145 Location left = locs()->in(0); | 146 Location left = locs()->in(0); |
| 146 Location right = locs()->in(1); | 147 Location right = locs()->in(1); |
| 147 ASSERT(!left.IsConstant() || !right.IsConstant()); | 148 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 148 | 149 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 const int32_t val = | 209 const int32_t val = |
| 209 Smi::RawValue(true_value) - Smi::RawValue(false_value); | 210 Smi::RawValue(true_value) - Smi::RawValue(false_value); |
| 210 __ AndImmediate(result, result, val); | 211 __ AndImmediate(result, result, val); |
| 211 if (false_value != 0) { | 212 if (false_value != 0) { |
| 212 __ AddImmediate(result, result, Smi::RawValue(false_value)); | 213 __ AddImmediate(result, result, Smi::RawValue(false_value)); |
| 213 } | 214 } |
| 214 } | 215 } |
| 215 } | 216 } |
| 216 | 217 |
| 217 | 218 |
| 218 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 219 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
| 219 const intptr_t kNumInputs = 0; | 220 const intptr_t kNumInputs = 0; |
| 220 const intptr_t kNumTemps = 1; | 221 const intptr_t kNumTemps = 1; |
| 221 LocationSummary* result = | 222 LocationSummary* result = |
| 222 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 223 result->set_out(Location::RegisterLocation(V0)); | 224 result->set_out(Location::RegisterLocation(V0)); |
| 224 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor. | 225 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor. |
| 225 return result; | 226 return result; |
| 226 } | 227 } |
| 227 | 228 |
| 228 | 229 |
| 229 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 230 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 230 // The arguments to the stub include the closure, as does the arguments | 231 // The arguments to the stub include the closure, as does the arguments |
| 231 // descriptor. | 232 // descriptor. |
| 232 Register temp_reg = locs()->temp(0).reg(); | 233 Register temp_reg = locs()->temp(0).reg(); |
| 233 int argument_count = ArgumentCount(); | 234 int argument_count = ArgumentCount(); |
| 234 const Array& arguments_descriptor = | 235 const Array& arguments_descriptor = |
| 235 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 236 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
| 236 argument_names())); | 237 argument_names())); |
| 237 ASSERT(temp_reg == S4); | 238 ASSERT(temp_reg == S4); |
| 238 __ LoadObject(temp_reg, arguments_descriptor); | 239 __ LoadObject(temp_reg, arguments_descriptor); |
| 239 compiler->GenerateDartCall(deopt_id(), | 240 compiler->GenerateDartCall(deopt_id(), |
| 240 token_pos(), | 241 token_pos(), |
| 241 &StubCode::CallClosureFunctionLabel(), | 242 &StubCode::CallClosureFunctionLabel(), |
| 242 PcDescriptors::kClosureCall, | 243 PcDescriptors::kClosureCall, |
| 243 locs()); | 244 locs()); |
| 244 __ Drop(argument_count); | 245 __ Drop(argument_count); |
| 245 } | 246 } |
| 246 | 247 |
| 247 | 248 |
| 248 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 249 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
| 249 return LocationSummary::Make(0, | 250 return LocationSummary::Make(0, |
| 250 Location::RequiresRegister(), | 251 Location::RequiresRegister(), |
| 251 LocationSummary::kNoCall); | 252 LocationSummary::kNoCall); |
| 252 } | 253 } |
| 253 | 254 |
| 254 | 255 |
| 255 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 256 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 256 __ TraceSimMsg("LoadLocalInstr"); | 257 __ TraceSimMsg("LoadLocalInstr"); |
| 257 Register result = locs()->out().reg(); | 258 Register result = locs()->out().reg(); |
| 258 __ lw(result, Address(FP, local().index() * kWordSize)); | 259 __ lw(result, Address(FP, local().index() * kWordSize)); |
| 259 } | 260 } |
| 260 | 261 |
| 261 | 262 |
| 262 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 263 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
| 263 return LocationSummary::Make(1, | 264 return LocationSummary::Make(1, |
| 264 Location::SameAsFirstInput(), | 265 Location::SameAsFirstInput(), |
| 265 LocationSummary::kNoCall); | 266 LocationSummary::kNoCall); |
| 266 } | 267 } |
| 267 | 268 |
| 268 | 269 |
| 269 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 270 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 270 __ TraceSimMsg("StoreLocalInstr"); | 271 __ TraceSimMsg("StoreLocalInstr"); |
| 271 Register value = locs()->in(0).reg(); | 272 Register value = locs()->in(0).reg(); |
| 272 Register result = locs()->out().reg(); | 273 Register result = locs()->out().reg(); |
| 273 ASSERT(result == value); // Assert that register assignment is correct. | 274 ASSERT(result == value); // Assert that register assignment is correct. |
| 274 __ sw(value, Address(FP, local().index() * kWordSize)); | 275 __ sw(value, Address(FP, local().index() * kWordSize)); |
| 275 } | 276 } |
| 276 | 277 |
| 277 | 278 |
| 278 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 279 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
| 279 return LocationSummary::Make(0, | 280 return LocationSummary::Make(0, |
| 280 Location::RequiresRegister(), | 281 Location::RequiresRegister(), |
| 281 LocationSummary::kNoCall); | 282 LocationSummary::kNoCall); |
| 282 } | 283 } |
| 283 | 284 |
| 284 | 285 |
| 285 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 286 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 286 // The register allocator drops constant definitions that have no uses. | 287 // The register allocator drops constant definitions that have no uses. |
| 287 if (!locs()->out().IsInvalid()) { | 288 if (!locs()->out().IsInvalid()) { |
| 288 __ TraceSimMsg("ConstantInstr"); | 289 __ TraceSimMsg("ConstantInstr"); |
| 289 Register result = locs()->out().reg(); | 290 Register result = locs()->out().reg(); |
| 290 __ LoadObject(result, value()); | 291 __ LoadObject(result, value()); |
| 291 } | 292 } |
| 292 } | 293 } |
| 293 | 294 |
| 294 | 295 |
| 295 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 296 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { |
| 296 const intptr_t kNumInputs = 3; | 297 const intptr_t kNumInputs = 3; |
| 297 const intptr_t kNumTemps = 0; | 298 const intptr_t kNumTemps = 0; |
| 298 LocationSummary* summary = | 299 LocationSummary* summary = |
| 299 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 300 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 300 summary->set_in(0, Location::RegisterLocation(A0)); // Value. | 301 summary->set_in(0, Location::RegisterLocation(A0)); // Value. |
| 301 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator. | 302 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator. |
| 302 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments. | 303 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments. |
| 303 summary->set_out(Location::RegisterLocation(A0)); | 304 summary->set_out(Location::RegisterLocation(A0)); |
| 304 return summary; | 305 return summary; |
| 305 } | 306 } |
| 306 | 307 |
| 307 | 308 |
| 308 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 309 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { |
| 309 const intptr_t kNumInputs = 1; | 310 const intptr_t kNumInputs = 1; |
| 310 const intptr_t kNumTemps = 0; | 311 const intptr_t kNumTemps = 0; |
| 311 LocationSummary* locs = | 312 LocationSummary* locs = |
| 312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 313 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 313 locs->set_in(0, Location::RegisterLocation(A0)); | 314 locs->set_in(0, Location::RegisterLocation(A0)); |
| 314 locs->set_out(Location::RegisterLocation(A0)); | 315 locs->set_out(Location::RegisterLocation(A0)); |
| 315 return locs; | 316 return locs; |
| 316 } | 317 } |
| 317 | 318 |
| 318 | 319 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 343 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 344 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 344 Register obj = locs()->in(0).reg(); | 345 Register obj = locs()->in(0).reg(); |
| 345 Register result = locs()->out().reg(); | 346 Register result = locs()->out().reg(); |
| 346 | 347 |
| 347 __ TraceSimMsg("AssertBooleanInstr"); | 348 __ TraceSimMsg("AssertBooleanInstr"); |
| 348 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); | 349 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); |
| 349 ASSERT(obj == result); | 350 ASSERT(obj == result); |
| 350 } | 351 } |
| 351 | 352 |
| 352 | 353 |
| 353 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 354 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
| 354 const intptr_t kNumInputs = 2; | 355 const intptr_t kNumInputs = 2; |
| 355 if (operation_cid() == kMintCid) { | 356 if (operation_cid() == kMintCid) { |
| 356 const intptr_t kNumTemps = 1; | 357 const intptr_t kNumTemps = 1; |
| 357 LocationSummary* locs = | 358 LocationSummary* locs = |
| 358 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 359 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 359 locs->set_in(0, Location::RequiresFpuRegister()); | 360 locs->set_in(0, Location::RequiresFpuRegister()); |
| 360 locs->set_in(1, Location::RequiresFpuRegister()); | 361 locs->set_in(1, Location::RequiresFpuRegister()); |
| 361 locs->set_temp(0, Location::RequiresRegister()); | 362 locs->set_temp(0, Location::RequiresRegister()); |
| 362 locs->set_out(Location::RequiresRegister()); | 363 locs->set_out(Location::RequiresRegister()); |
| 363 return locs; | 364 return locs; |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 __ TraceSimMsg("EqualityCompareInstr"); | 596 __ TraceSimMsg("EqualityCompareInstr"); |
| 596 __ Comment("EqualityCompareInstr:BranchCode"); | 597 __ Comment("EqualityCompareInstr:BranchCode"); |
| 597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 598 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 598 | 599 |
| 599 BranchLabels labels = compiler->CreateBranchLabels(branch); | 600 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 600 Condition true_condition = EmitComparisonCode(compiler, labels); | 601 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 601 EmitBranchOnCondition(compiler, true_condition, labels); | 602 EmitBranchOnCondition(compiler, true_condition, labels); |
| 602 } | 603 } |
| 603 | 604 |
| 604 | 605 |
| 605 LocationSummary* TestSmiInstr::MakeLocationSummary() const { | 606 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const { |
| 606 const intptr_t kNumInputs = 2; | 607 const intptr_t kNumInputs = 2; |
| 607 const intptr_t kNumTemps = 0; | 608 const intptr_t kNumTemps = 0; |
| 608 LocationSummary* locs = | 609 LocationSummary* locs = |
| 609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 610 locs->set_in(0, Location::RequiresRegister()); | 611 locs->set_in(0, Location::RequiresRegister()); |
| 611 // Only one input can be a constant operand. The case of two constant | 612 // Only one input can be a constant operand. The case of two constant |
| 612 // operands should be handled by constant propagation. | 613 // operands should be handled by constant propagation. |
| 613 locs->set_in(1, Location::RegisterOrConstant(right())); | 614 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 614 return locs; | 615 return locs; |
| 615 } | 616 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 640 | 641 |
| 641 | 642 |
| 642 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 643 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 643 BranchInstr* branch) { | 644 BranchInstr* branch) { |
| 644 BranchLabels labels = compiler->CreateBranchLabels(branch); | 645 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 645 Condition true_condition = EmitComparisonCode(compiler, labels); | 646 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 646 EmitBranchOnCondition(compiler, true_condition, labels); | 647 EmitBranchOnCondition(compiler, true_condition, labels); |
| 647 } | 648 } |
| 648 | 649 |
| 649 | 650 |
| 650 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 651 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
| 651 const intptr_t kNumInputs = 2; | 652 const intptr_t kNumInputs = 2; |
| 652 const intptr_t kNumTemps = 0; | 653 const intptr_t kNumTemps = 0; |
| 653 if (operation_cid() == kMintCid) { | 654 if (operation_cid() == kMintCid) { |
| 654 const intptr_t kNumTemps = 2; | 655 const intptr_t kNumTemps = 2; |
| 655 LocationSummary* locs = | 656 LocationSummary* locs = |
| 656 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 657 locs->set_in(0, Location::RequiresFpuRegister()); | 658 locs->set_in(0, Location::RequiresFpuRegister()); |
| 658 locs->set_in(1, Location::RequiresFpuRegister()); | 659 locs->set_in(1, Location::RequiresFpuRegister()); |
| 659 locs->set_temp(0, Location::RequiresRegister()); | 660 locs->set_temp(0, Location::RequiresRegister()); |
| 660 locs->set_temp(1, Location::RequiresRegister()); | 661 locs->set_temp(1, Location::RequiresRegister()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 717 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 717 BranchInstr* branch) { | 718 BranchInstr* branch) { |
| 718 __ TraceSimMsg("RelationalOpInstr"); | 719 __ TraceSimMsg("RelationalOpInstr"); |
| 719 | 720 |
| 720 BranchLabels labels = compiler->CreateBranchLabels(branch); | 721 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 721 Condition true_condition = EmitComparisonCode(compiler, labels); | 722 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 722 EmitBranchOnCondition(compiler, true_condition, labels); | 723 EmitBranchOnCondition(compiler, true_condition, labels); |
| 723 } | 724 } |
| 724 | 725 |
| 725 | 726 |
| 726 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 727 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
| 727 const intptr_t kNumInputs = 0; | 728 const intptr_t kNumInputs = 0; |
| 728 const intptr_t kNumTemps = 3; | 729 const intptr_t kNumTemps = 3; |
| 729 LocationSummary* locs = | 730 LocationSummary* locs = |
| 730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 731 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 731 locs->set_temp(0, Location::RegisterLocation(A1)); | 732 locs->set_temp(0, Location::RegisterLocation(A1)); |
| 732 locs->set_temp(1, Location::RegisterLocation(A2)); | 733 locs->set_temp(1, Location::RegisterLocation(A2)); |
| 733 locs->set_temp(2, Location::RegisterLocation(T5)); | 734 locs->set_temp(2, Location::RegisterLocation(T5)); |
| 734 locs->set_out(Location::RegisterLocation(V0)); | 735 locs->set_out(Location::RegisterLocation(V0)); |
| 735 return locs; | 736 return locs; |
| 736 } | 737 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 __ LoadImmediate(T5, entry); | 773 __ LoadImmediate(T5, entry); |
| 773 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function())); | 774 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function())); |
| 774 compiler->GenerateCall(token_pos(), | 775 compiler->GenerateCall(token_pos(), |
| 775 stub_entry, | 776 stub_entry, |
| 776 PcDescriptors::kOther, | 777 PcDescriptors::kOther, |
| 777 locs()); | 778 locs()); |
| 778 __ Pop(result); | 779 __ Pop(result); |
| 779 } | 780 } |
| 780 | 781 |
| 781 | 782 |
| 782 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 783 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { |
| 783 const intptr_t kNumInputs = 1; | 784 const intptr_t kNumInputs = 1; |
| 784 // TODO(fschneider): Allow immediate operands for the char code. | 785 // TODO(fschneider): Allow immediate operands for the char code. |
| 785 return LocationSummary::Make(kNumInputs, | 786 return LocationSummary::Make(kNumInputs, |
| 786 Location::RequiresRegister(), | 787 Location::RequiresRegister(), |
| 787 LocationSummary::kNoCall); | 788 LocationSummary::kNoCall); |
| 788 } | 789 } |
| 789 | 790 |
| 790 | 791 |
| 791 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 792 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 792 Register char_code = locs()->in(0).reg(); | 793 Register char_code = locs()->in(0).reg(); |
| 793 Register result = locs()->out().reg(); | 794 Register result = locs()->out().reg(); |
| 794 | 795 |
| 795 __ TraceSimMsg("StringFromCharCodeInstr"); | 796 __ TraceSimMsg("StringFromCharCodeInstr"); |
| 796 | 797 |
| 797 __ LoadImmediate(result, | 798 __ LoadImmediate(result, |
| 798 reinterpret_cast<uword>(Symbols::PredefinedAddress())); | 799 reinterpret_cast<uword>(Symbols::PredefinedAddress())); |
| 799 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); | 800 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
| 800 __ sll(TMP, char_code, 1); // Char code is a smi. | 801 __ sll(TMP, char_code, 1); // Char code is a smi. |
| 801 __ addu(TMP, TMP, result); | 802 __ addu(TMP, TMP, result); |
| 802 __ lw(result, Address(TMP)); | 803 __ lw(result, Address(TMP)); |
| 803 } | 804 } |
| 804 | 805 |
| 805 | 806 |
| 806 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { | 807 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { |
| 807 const intptr_t kNumInputs = 1; | 808 const intptr_t kNumInputs = 1; |
| 808 const intptr_t kNumTemps = 0; | 809 const intptr_t kNumTemps = 0; |
| 809 LocationSummary* summary = | 810 LocationSummary* summary = |
| 810 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 811 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 811 summary->set_in(0, Location::RegisterLocation(A0)); | 812 summary->set_in(0, Location::RegisterLocation(A0)); |
| 812 summary->set_out(Location::RegisterLocation(V0)); | 813 summary->set_out(Location::RegisterLocation(V0)); |
| 813 return summary; | 814 return summary; |
| 814 } | 815 } |
| 815 | 816 |
| 816 | 817 |
| 817 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 818 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 818 Register array = locs()->in(0).reg(); | 819 Register array = locs()->in(0).reg(); |
| 819 __ Push(array); | 820 __ Push(array); |
| 820 const int kNumberOfArguments = 1; | 821 const int kNumberOfArguments = 1; |
| 821 const Array& kNoArgumentNames = Object::null_array(); | 822 const Array& kNoArgumentNames = Object::null_array(); |
| 822 compiler->GenerateStaticCall(deopt_id(), | 823 compiler->GenerateStaticCall(deopt_id(), |
| 823 token_pos(), | 824 token_pos(), |
| 824 CallFunction(), | 825 CallFunction(), |
| 825 kNumberOfArguments, | 826 kNumberOfArguments, |
| 826 kNoArgumentNames, | 827 kNoArgumentNames, |
| 827 locs()); | 828 locs()); |
| 828 ASSERT(locs()->out().reg() == V0); | 829 ASSERT(locs()->out().reg() == V0); |
| 829 } | 830 } |
| 830 | 831 |
| 831 | 832 |
| 832 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 833 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
| 833 const intptr_t kNumInputs = 1; | 834 const intptr_t kNumInputs = 1; |
| 834 return LocationSummary::Make(kNumInputs, | 835 return LocationSummary::Make(kNumInputs, |
| 835 Location::RequiresRegister(), | 836 Location::RequiresRegister(), |
| 836 LocationSummary::kNoCall); | 837 LocationSummary::kNoCall); |
| 837 } | 838 } |
| 838 | 839 |
| 839 | 840 |
| 840 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 841 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 841 Register object = locs()->in(0).reg(); | 842 Register object = locs()->in(0).reg(); |
| 842 Register result = locs()->out().reg(); | 843 Register result = locs()->out().reg(); |
| 843 __ LoadFromOffset(result, object, offset() - kHeapObjectTag); | 844 __ LoadFromOffset(result, object, offset() - kHeapObjectTag); |
| 844 } | 845 } |
| 845 | 846 |
| 846 | 847 |
| 847 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { | 848 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { |
| 848 const intptr_t kNumInputs = 1; | 849 const intptr_t kNumInputs = 1; |
| 849 return LocationSummary::Make(kNumInputs, | 850 return LocationSummary::Make(kNumInputs, |
| 850 Location::RequiresRegister(), | 851 Location::RequiresRegister(), |
| 851 LocationSummary::kNoCall); | 852 LocationSummary::kNoCall); |
| 852 } | 853 } |
| 853 | 854 |
| 854 | 855 |
| 855 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 856 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 856 Register object = locs()->in(0).reg(); | 857 Register object = locs()->in(0).reg(); |
| 857 Register result = locs()->out().reg(); | 858 Register result = locs()->out().reg(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 return kUnboxedInt32x4; | 934 return kUnboxedInt32x4; |
| 934 case kTypedDataFloat32x4ArrayCid: | 935 case kTypedDataFloat32x4ArrayCid: |
| 935 return kUnboxedFloat32x4; | 936 return kUnboxedFloat32x4; |
| 936 default: | 937 default: |
| 937 UNIMPLEMENTED(); | 938 UNIMPLEMENTED(); |
| 938 return kTagged; | 939 return kTagged; |
| 939 } | 940 } |
| 940 } | 941 } |
| 941 | 942 |
| 942 | 943 |
| 943 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 944 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
| 944 const intptr_t kNumInputs = 2; | 945 const intptr_t kNumInputs = 2; |
| 945 const intptr_t kNumTemps = 0; | 946 const intptr_t kNumTemps = 0; |
| 946 LocationSummary* locs = | 947 LocationSummary* locs = |
| 947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 948 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 948 locs->set_in(0, Location::RequiresRegister()); | 949 locs->set_in(0, Location::RequiresRegister()); |
| 949 // The smi index is either untagged (element size == 1), or it is left smi | 950 // The smi index is either untagged (element size == 1), or it is left smi |
| 950 // tagged (for all element sizes > 1). | 951 // tagged (for all element sizes > 1). |
| 951 // TODO(regis): Revisit and see if the index can be immediate. | 952 // TODO(regis): Revisit and see if the index can be immediate. |
| 952 locs->set_in(1, Location::WritableRegister()); | 953 locs->set_in(1, Location::WritableRegister()); |
| 953 if ((representation() == kUnboxedDouble) || | 954 if ((representation() == kUnboxedDouble) || |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 return kUnboxedFloat32x4; | 1117 return kUnboxedFloat32x4; |
| 1117 case kTypedDataInt32x4ArrayCid: | 1118 case kTypedDataInt32x4ArrayCid: |
| 1118 return kUnboxedInt32x4; | 1119 return kUnboxedInt32x4; |
| 1119 default: | 1120 default: |
| 1120 UNIMPLEMENTED(); | 1121 UNIMPLEMENTED(); |
| 1121 return kTagged; | 1122 return kTagged; |
| 1122 } | 1123 } |
| 1123 } | 1124 } |
| 1124 | 1125 |
| 1125 | 1126 |
| 1126 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1127 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
| 1127 const intptr_t kNumInputs = 3; | 1128 const intptr_t kNumInputs = 3; |
| 1128 const intptr_t kNumTemps = 0; | 1129 const intptr_t kNumTemps = 0; |
| 1129 LocationSummary* locs = | 1130 LocationSummary* locs = |
| 1130 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1131 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1131 locs->set_in(0, Location::RequiresRegister()); | 1132 locs->set_in(0, Location::RequiresRegister()); |
| 1132 // The smi index is either untagged (element size == 1), or it is left smi | 1133 // The smi index is either untagged (element size == 1), or it is left smi |
| 1133 // tagged (for all element sizes > 1). | 1134 // tagged (for all element sizes > 1). |
| 1134 // TODO(regis): Revisit and see if the index can be immediate. | 1135 // TODO(regis): Revisit and see if the index can be immediate. |
| 1135 locs->set_in(1, Location::WritableRegister()); | 1136 locs->set_in(1, Location::WritableRegister()); |
| 1136 switch (class_id()) { | 1137 switch (class_id()) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 case kTypedDataInt32x4ArrayCid: | 1301 case kTypedDataInt32x4ArrayCid: |
| 1301 case kTypedDataFloat32x4ArrayCid: | 1302 case kTypedDataFloat32x4ArrayCid: |
| 1302 UNIMPLEMENTED(); | 1303 UNIMPLEMENTED(); |
| 1303 break; | 1304 break; |
| 1304 default: | 1305 default: |
| 1305 UNREACHABLE(); | 1306 UNREACHABLE(); |
| 1306 } | 1307 } |
| 1307 } | 1308 } |
| 1308 | 1309 |
| 1309 | 1310 |
| 1310 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1311 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
| 1311 const intptr_t kNumInputs = 1; | 1312 const intptr_t kNumInputs = 1; |
| 1312 LocationSummary* summary = | 1313 LocationSummary* summary = |
| 1313 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1314 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| 1314 summary->set_in(0, Location::RequiresRegister()); | 1315 summary->set_in(0, Location::RequiresRegister()); |
| 1315 const bool field_has_length = field().needs_length_check(); | 1316 const bool field_has_length = field().needs_length_check(); |
| 1316 const bool need_value_temp_reg = | 1317 const bool need_value_temp_reg = |
| 1317 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && | 1318 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && |
| 1318 (field().guarded_cid() != kSmiCid))); | 1319 (field().guarded_cid() != kSmiCid))); |
| 1319 if (need_value_temp_reg) { | 1320 if (need_value_temp_reg) { |
| 1320 summary->AddTemp(Location::RequiresRegister()); | 1321 summary->AddTemp(Location::RequiresRegister()); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1633 __ bne(CMPRES1, ZR, fail); | 1634 __ bne(CMPRES1, ZR, fail); |
| 1634 } else { | 1635 } else { |
| 1635 UNREACHABLE(); | 1636 UNREACHABLE(); |
| 1636 } | 1637 } |
| 1637 } | 1638 } |
| 1638 } | 1639 } |
| 1639 __ Bind(&ok); | 1640 __ Bind(&ok); |
| 1640 } | 1641 } |
| 1641 | 1642 |
| 1642 | 1643 |
| 1643 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1644 class StoreInstanceFieldSlowPath : public SlowPathCode { |
| 1645 public: |
| 1646 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) |
| 1647 : instruction_(instruction) { } |
| 1648 |
| 1649 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1650 __ Comment("StoreInstanceFieldSlowPath"); |
| 1651 __ Bind(entry_label()); |
| 1652 const Class& double_class = compiler->double_class(); |
| 1653 const Code& stub = |
| 1654 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1655 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1656 |
| 1657 LocationSummary* locs = instruction_->locs(); |
| 1658 locs->live_registers()->Remove(locs->out()); |
| 1659 |
| 1660 compiler->SaveLiveRegisters(locs); |
| 1661 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1662 &label, |
| 1663 PcDescriptors::kOther, |
| 1664 locs); |
| 1665 __ mov(locs->temp(0).reg(), V0); |
| 1666 compiler->RestoreLiveRegisters(locs); |
| 1667 |
| 1668 __ b(exit_label()); |
| 1669 } |
| 1670 |
| 1671 private: |
| 1672 StoreInstanceFieldInstr* instruction_; |
| 1673 }; |
| 1674 |
| 1675 |
| 1676 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { |
| 1644 const intptr_t kNumInputs = 2; | 1677 const intptr_t kNumInputs = 2; |
| 1645 const intptr_t kNumTemps = 0; | 1678 const intptr_t kNumTemps = 0; |
| 1646 LocationSummary* summary = | 1679 LocationSummary* summary = |
| 1647 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1680 new LocationSummary(kNumInputs, kNumTemps, |
| 1681 (field().guarded_cid() == kIllegalCid) || (is_initialization_) |
| 1682 ? LocationSummary::kCallOnSlowPath |
| 1683 : LocationSummary::kNoCall); |
| 1684 |
| 1648 summary->set_in(0, Location::RequiresRegister()); | 1685 summary->set_in(0, Location::RequiresRegister()); |
| 1649 summary->set_in(1, ShouldEmitStoreBarrier() | 1686 if (IsUnboxedStore() && opt) { |
| 1687 summary->set_in(1, Location::RequiresFpuRegister()); |
| 1688 summary->AddTemp(Location::RequiresRegister()); |
| 1689 summary->AddTemp(Location::RequiresRegister()); |
| 1690 } else if (IsPotentialUnboxedStore()) { |
| 1691 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1692 ? Location::WritableRegister() |
| 1693 : Location::RequiresRegister()); |
| 1694 summary->AddTemp(Location::RequiresRegister()); |
| 1695 summary->AddTemp(Location::RequiresRegister()); |
| 1696 summary->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1697 : Location::FpuRegisterLocation(D1)); |
| 1698 } else { |
| 1699 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1650 ? Location::WritableRegister() | 1700 ? Location::WritableRegister() |
| 1651 : Location::RegisterOrConstant(value())); | 1701 : Location::RegisterOrConstant(value())); |
| 1702 } |
| 1652 return summary; | 1703 return summary; |
| 1653 } | 1704 } |
| 1654 | 1705 |
| 1655 | 1706 |
| 1656 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1707 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1708 Label skip_store; |
| 1709 |
| 1657 Register instance_reg = locs()->in(0).reg(); | 1710 Register instance_reg = locs()->in(0).reg(); |
| 1711 |
| 1712 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1713 DRegister value = locs()->in(1).fpu_reg(); |
| 1714 Register temp = locs()->temp(0).reg(); |
| 1715 Register temp2 = locs()->temp(1).reg(); |
| 1716 |
| 1717 if (is_initialization_) { |
| 1718 StoreInstanceFieldSlowPath* slow_path = |
| 1719 new StoreInstanceFieldSlowPath(this); |
| 1720 compiler->AddSlowPathCode(slow_path); |
| 1721 __ TryAllocate(compiler->double_class(), |
| 1722 slow_path->entry_label(), |
| 1723 temp); |
| 1724 __ Bind(slow_path->exit_label()); |
| 1725 __ mov(temp2, temp); |
| 1726 __ StoreIntoObject(instance_reg, |
| 1727 FieldAddress(instance_reg, field().Offset()), |
| 1728 temp2); |
| 1729 } else { |
| 1730 __ lw(temp, FieldAddress(instance_reg, field().Offset())); |
| 1731 } |
| 1732 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1733 return; |
| 1734 } |
| 1735 |
| 1736 if (IsPotentialUnboxedStore()) { |
| 1737 Register value_reg = locs()->in(1).reg(); |
| 1738 Register temp = locs()->temp(0).reg(); |
| 1739 Register temp2 = locs()->temp(1).reg(); |
| 1740 DRegister fpu_temp = locs()->temp(2).fpu_reg(); |
| 1741 |
| 1742 Label store_pointer, copy_payload; |
| 1743 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1744 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1745 __ BranchNotEqual(temp2, kDoubleCid, &store_pointer); |
| 1746 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1747 __ BranchEqual(temp2, kNullCid, &store_pointer); |
| 1748 |
| 1749 __ lw(temp, FieldAddress(instance_reg, field().Offset())); |
| 1750 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), |
| 1751 ©_payload); |
| 1752 |
| 1753 StoreInstanceFieldSlowPath* slow_path = |
| 1754 new StoreInstanceFieldSlowPath(this); |
| 1755 compiler->AddSlowPathCode(slow_path); |
| 1756 |
| 1757 if (!compiler->is_optimizing()) { |
| 1758 locs()->live_registers()->Add(locs()->in(0)); |
| 1759 locs()->live_registers()->Add(locs()->in(1)); |
| 1760 } |
| 1761 |
| 1762 __ TryAllocate(compiler->double_class(), |
| 1763 slow_path->entry_label(), |
| 1764 temp); |
| 1765 __ Bind(slow_path->exit_label()); |
| 1766 __ mov(temp2, temp); |
| 1767 __ StoreIntoObject(instance_reg, |
| 1768 FieldAddress(instance_reg, field().Offset()), |
| 1769 temp2); |
| 1770 |
| 1771 __ Bind(©_payload); |
| 1772 __ LoadDFromOffset(fpu_temp, |
| 1773 value_reg, |
| 1774 Double::value_offset() - kHeapObjectTag); |
| 1775 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); |
| 1776 __ b(&skip_store); |
| 1777 __ Bind(&store_pointer); |
| 1778 } |
| 1779 |
| 1658 if (ShouldEmitStoreBarrier()) { | 1780 if (ShouldEmitStoreBarrier()) { |
| 1659 Register value_reg = locs()->in(1).reg(); | 1781 Register value_reg = locs()->in(1).reg(); |
| 1660 __ StoreIntoObject(instance_reg, | 1782 __ StoreIntoObject(instance_reg, |
| 1661 FieldAddress(instance_reg, field().Offset()), | 1783 FieldAddress(instance_reg, field().Offset()), |
| 1662 value_reg, | 1784 value_reg, |
| 1663 CanValueBeSmi()); | 1785 CanValueBeSmi()); |
| 1664 } else { | 1786 } else { |
| 1665 if (locs()->in(1).IsConstant()) { | 1787 if (locs()->in(1).IsConstant()) { |
| 1666 __ StoreIntoObjectNoBarrier( | 1788 __ StoreIntoObjectNoBarrier( |
| 1667 instance_reg, | 1789 instance_reg, |
| 1668 FieldAddress(instance_reg, field().Offset()), | 1790 FieldAddress(instance_reg, field().Offset()), |
| 1669 locs()->in(1).constant()); | 1791 locs()->in(1).constant()); |
| 1670 } else { | 1792 } else { |
| 1671 Register value_reg = locs()->in(1).reg(); | 1793 Register value_reg = locs()->in(1).reg(); |
| 1672 __ StoreIntoObjectNoBarrier(instance_reg, | 1794 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1673 FieldAddress(instance_reg, field().Offset()), value_reg); | 1795 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1674 } | 1796 } |
| 1675 } | 1797 } |
| 1798 __ Bind(&skip_store); |
| 1676 } | 1799 } |
| 1677 | 1800 |
| 1678 | 1801 |
| 1679 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 1802 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1680 const intptr_t kNumInputs = 1; | 1803 const intptr_t kNumInputs = 1; |
| 1681 const intptr_t kNumTemps = 0; | 1804 const intptr_t kNumTemps = 0; |
| 1682 LocationSummary* summary = | 1805 LocationSummary* summary = |
| 1683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1684 summary->set_in(0, Location::RequiresRegister()); | 1807 summary->set_in(0, Location::RequiresRegister()); |
| 1685 summary->set_out(Location::RequiresRegister()); | 1808 summary->set_out(Location::RequiresRegister()); |
| 1686 return summary; | 1809 return summary; |
| 1687 } | 1810 } |
| 1688 | 1811 |
| 1689 | 1812 |
| 1690 // When the parser is building an implicit static getter for optimization, | 1813 // When the parser is building an implicit static getter for optimization, |
| 1691 // it can generate a function body where deoptimization ids do not line up | 1814 // it can generate a function body where deoptimization ids do not line up |
| 1692 // with the unoptimized code. | 1815 // with the unoptimized code. |
| 1693 // | 1816 // |
| 1694 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. | 1817 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. |
| 1695 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1818 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1696 __ TraceSimMsg("LoadStaticFieldInstr"); | 1819 __ TraceSimMsg("LoadStaticFieldInstr"); |
| 1697 Register field = locs()->in(0).reg(); | 1820 Register field = locs()->in(0).reg(); |
| 1698 Register result = locs()->out().reg(); | 1821 Register result = locs()->out().reg(); |
| 1699 __ lw(result, FieldAddress(field, Field::value_offset())); | 1822 __ lw(result, FieldAddress(field, Field::value_offset())); |
| 1700 } | 1823 } |
| 1701 | 1824 |
| 1702 | 1825 |
| 1703 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1826 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1704 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1827 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1705 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 1828 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 1706 : Location::RequiresRegister()); | 1829 : Location::RequiresRegister()); |
| 1707 locs->set_temp(0, Location::RequiresRegister()); | 1830 locs->set_temp(0, Location::RequiresRegister()); |
| 1708 return locs; | 1831 return locs; |
| 1709 } | 1832 } |
| 1710 | 1833 |
| 1711 | 1834 |
| 1712 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1835 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1713 __ TraceSimMsg("StoreStaticFieldInstr"); | 1836 __ TraceSimMsg("StoreStaticFieldInstr"); |
| 1714 Register value = locs()->in(0).reg(); | 1837 Register value = locs()->in(0).reg(); |
| 1715 Register temp = locs()->temp(0).reg(); | 1838 Register temp = locs()->temp(0).reg(); |
| 1716 | 1839 |
| 1717 __ LoadObject(temp, field()); | 1840 __ LoadObject(temp, field()); |
| 1718 if (this->value()->NeedsStoreBuffer()) { | 1841 if (this->value()->NeedsStoreBuffer()) { |
| 1719 __ StoreIntoObject(temp, | 1842 __ StoreIntoObject(temp, |
| 1720 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); | 1843 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); |
| 1721 } else { | 1844 } else { |
| 1722 __ StoreIntoObjectNoBarrier( | 1845 __ StoreIntoObjectNoBarrier( |
| 1723 temp, FieldAddress(temp, Field::value_offset()), value); | 1846 temp, FieldAddress(temp, Field::value_offset()), value); |
| 1724 } | 1847 } |
| 1725 } | 1848 } |
| 1726 | 1849 |
| 1727 | 1850 |
| 1728 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1851 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { |
| 1729 const intptr_t kNumInputs = 3; | 1852 const intptr_t kNumInputs = 3; |
| 1730 const intptr_t kNumTemps = 0; | 1853 const intptr_t kNumTemps = 0; |
| 1731 LocationSummary* summary = | 1854 LocationSummary* summary = |
| 1732 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1855 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1733 summary->set_in(0, Location::RegisterLocation(A0)); | 1856 summary->set_in(0, Location::RegisterLocation(A0)); |
| 1734 summary->set_in(1, Location::RegisterLocation(A2)); | 1857 summary->set_in(1, Location::RegisterLocation(A2)); |
| 1735 summary->set_in(2, Location::RegisterLocation(A1)); | 1858 summary->set_in(2, Location::RegisterLocation(A1)); |
| 1736 summary->set_out(Location::RegisterLocation(V0)); | 1859 summary->set_out(Location::RegisterLocation(V0)); |
| 1737 return summary; | 1860 return summary; |
| 1738 } | 1861 } |
| 1739 | 1862 |
| 1740 | 1863 |
| 1741 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1864 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1742 ASSERT(locs()->in(0).reg() == A0); // Value. | 1865 ASSERT(locs()->in(0).reg() == A0); // Value. |
| 1743 ASSERT(locs()->in(1).reg() == A2); // Instantiator. | 1866 ASSERT(locs()->in(1).reg() == A2); // Instantiator. |
| 1744 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments. | 1867 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments. |
| 1745 | 1868 |
| 1746 __ Comment("InstanceOfInstr"); | 1869 __ Comment("InstanceOfInstr"); |
| 1747 compiler->GenerateInstanceOf(token_pos(), | 1870 compiler->GenerateInstanceOf(token_pos(), |
| 1748 deopt_id(), | 1871 deopt_id(), |
| 1749 type(), | 1872 type(), |
| 1750 negate_result(), | 1873 negate_result(), |
| 1751 locs()); | 1874 locs()); |
| 1752 ASSERT(locs()->out().reg() == V0); | 1875 ASSERT(locs()->out().reg() == V0); |
| 1753 } | 1876 } |
| 1754 | 1877 |
| 1755 | 1878 |
| 1756 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1879 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
| 1757 const intptr_t kNumInputs = 1; | 1880 const intptr_t kNumInputs = 1; |
| 1758 const intptr_t kNumTemps = 0; | 1881 const intptr_t kNumTemps = 0; |
| 1759 LocationSummary* locs = | 1882 LocationSummary* locs = |
| 1760 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1883 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1761 locs->set_in(0, Location::RegisterLocation(A0)); | 1884 locs->set_in(0, Location::RegisterLocation(A0)); |
| 1762 locs->set_out(Location::RegisterLocation(V0)); | 1885 locs->set_out(Location::RegisterLocation(V0)); |
| 1763 return locs; | 1886 return locs; |
| 1764 } | 1887 } |
| 1765 | 1888 |
| 1766 | 1889 |
| 1767 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1890 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1768 __ TraceSimMsg("CreateArrayInstr"); | 1891 __ TraceSimMsg("CreateArrayInstr"); |
| 1769 // Allocate the array. A1 = length, A0 = element type. | 1892 // Allocate the array. A1 = length, A0 = element type. |
| 1770 ASSERT(locs()->in(0).reg() == A0); | 1893 ASSERT(locs()->in(0).reg() == A0); |
| 1771 __ LoadImmediate(A1, Smi::RawValue(num_elements())); | 1894 __ LoadImmediate(A1, Smi::RawValue(num_elements())); |
| 1772 compiler->GenerateCall(token_pos(), | 1895 compiler->GenerateCall(token_pos(), |
| 1773 &StubCode::AllocateArrayLabel(), | 1896 &StubCode::AllocateArrayLabel(), |
| 1774 PcDescriptors::kOther, | 1897 PcDescriptors::kOther, |
| 1775 locs()); | 1898 locs()); |
| 1776 ASSERT(locs()->out().reg() == V0); | 1899 ASSERT(locs()->out().reg() == V0); |
| 1777 } | 1900 } |
| 1778 | 1901 |
| 1779 | 1902 |
| 1780 LocationSummary* | 1903 LocationSummary* |
| 1781 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1904 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const { |
| 1782 return MakeCallSummary(); | 1905 return MakeCallSummary(); |
| 1783 } | 1906 } |
| 1784 | 1907 |
| 1785 | 1908 |
| 1786 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1909 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
| 1787 FlowGraphCompiler* compiler) { | 1910 FlowGraphCompiler* compiler) { |
| 1788 compiler->GenerateRuntimeCall(token_pos(), | 1911 compiler->GenerateRuntimeCall(token_pos(), |
| 1789 deopt_id(), | 1912 deopt_id(), |
| 1790 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1913 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1791 3, | 1914 3, |
| 1792 locs()); | 1915 locs()); |
| 1793 __ Drop(3); | 1916 __ Drop(3); |
| 1794 ASSERT(locs()->out().reg() == V0); | 1917 ASSERT(locs()->out().reg() == V0); |
| 1795 __ Pop(V0); // Pop new instance. | 1918 __ Pop(V0); // Pop new instance. |
| 1796 } | 1919 } |
| 1797 | 1920 |
| 1798 | 1921 |
| 1799 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 1922 class BoxDoubleSlowPath : public SlowPathCode { |
| 1800 return LocationSummary::Make(1, | 1923 public: |
| 1801 Location::RequiresRegister(), | 1924 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 1802 LocationSummary::kNoCall); | 1925 : instruction_(instruction) { } |
| 1926 |
| 1927 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1928 __ Comment("BoxDoubleSlowPath"); |
| 1929 __ Bind(entry_label()); |
| 1930 const Class& double_class = compiler->double_class(); |
| 1931 const Code& stub = |
| 1932 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1933 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1934 |
| 1935 LocationSummary* locs = instruction_->locs(); |
| 1936 locs->live_registers()->Remove(locs->out()); |
| 1937 |
| 1938 compiler->SaveLiveRegisters(locs); |
| 1939 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1940 &label, |
| 1941 PcDescriptors::kOther, |
| 1942 locs); |
| 1943 if (locs->out().reg() != V0) { |
| 1944 __ mov(locs->out().reg(), V0); |
| 1945 } |
| 1946 compiler->RestoreLiveRegisters(locs); |
| 1947 |
| 1948 __ b(exit_label()); |
| 1949 } |
| 1950 |
| 1951 private: |
| 1952 Instruction* instruction_; |
| 1953 }; |
| 1954 |
| 1955 |
| 1956 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 1957 const intptr_t kNumInputs = 1; |
| 1958 const intptr_t kNumTemps = 0; |
| 1959 LocationSummary* locs = |
| 1960 new LocationSummary( |
| 1961 kNumInputs, kNumTemps, |
| 1962 (opt && !IsPotentialUnboxedLoad()) |
| 1963 ? LocationSummary::kNoCall |
| 1964 : LocationSummary::kCallOnSlowPath); |
| 1965 |
| 1966 locs->set_in(0, Location::RequiresRegister()); |
| 1967 |
| 1968 if (IsUnboxedLoad() && opt) { |
| 1969 locs->AddTemp(Location::RequiresRegister()); |
| 1970 } else if (IsPotentialUnboxedLoad()) { |
| 1971 locs->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1972 : Location::FpuRegisterLocation(D1)); |
| 1973 locs->AddTemp(Location::RequiresRegister()); |
| 1974 } |
| 1975 locs->set_out(Location::RequiresRegister()); |
| 1976 return locs; |
| 1803 } | 1977 } |
| 1804 | 1978 |
| 1805 | 1979 |
| 1806 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1980 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1807 Register instance_reg = locs()->in(0).reg(); | 1981 Register instance_reg = locs()->in(0).reg(); |
| 1982 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 1983 DRegister result = locs()->out().fpu_reg(); |
| 1984 Register temp = locs()->temp(0).reg(); |
| 1985 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1986 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| 1987 return; |
| 1988 } |
| 1989 |
| 1990 Label done; |
| 1808 Register result_reg = locs()->out().reg(); | 1991 Register result_reg = locs()->out().reg(); |
| 1992 if (IsPotentialUnboxedLoad()) { |
| 1993 Register temp = locs()->temp(1).reg(); |
| 1994 DRegister value = locs()->temp(0).fpu_reg(); |
| 1809 | 1995 |
| 1996 Label load_pointer; |
| 1997 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 1998 |
| 1999 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 2000 FieldAddress field_nullability_operand(result_reg, |
| 2001 Field::is_nullable_offset()); |
| 2002 |
| 2003 __ lw(temp, field_cid_operand); |
| 2004 __ BranchNotEqual(temp, kDoubleCid, &load_pointer); |
| 2005 |
| 2006 __ lw(temp, field_nullability_operand); |
| 2007 __ BranchEqual(temp, kNullCid, &load_pointer); |
| 2008 |
| 2009 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 2010 compiler->AddSlowPathCode(slow_path); |
| 2011 |
| 2012 if (!compiler->is_optimizing()) { |
| 2013 locs()->live_registers()->Add(locs()->in(0)); |
| 2014 } |
| 2015 |
| 2016 __ TryAllocate(compiler->double_class(), |
| 2017 slow_path->entry_label(), |
| 2018 result_reg); |
| 2019 __ Bind(slow_path->exit_label()); |
| 2020 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2021 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 2022 __ StoreDToOffset(value, |
| 2023 result_reg, |
| 2024 Double::value_offset() - kHeapObjectTag); |
| 2025 __ b(&done); |
| 2026 __ Bind(&load_pointer); |
| 2027 } |
| 1810 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); | 2028 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); |
| 2029 __ Bind(&done); |
| 1811 } | 2030 } |
| 1812 | 2031 |
| 1813 | 2032 |
| 1814 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { | 2033 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
| 1815 const intptr_t kNumInputs = 1; | 2034 const intptr_t kNumInputs = 1; |
| 1816 const intptr_t kNumTemps = 0; | 2035 const intptr_t kNumTemps = 0; |
| 1817 LocationSummary* locs = | 2036 LocationSummary* locs = |
| 1818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2037 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1819 locs->set_in(0, Location::RegisterLocation(T0)); | 2038 locs->set_in(0, Location::RegisterLocation(T0)); |
| 1820 locs->set_out(Location::RegisterLocation(T0)); | 2039 locs->set_out(Location::RegisterLocation(T0)); |
| 1821 return locs; | 2040 return locs; |
| 1822 } | 2041 } |
| 1823 | 2042 |
| 1824 | 2043 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1844 2, | 2063 2, |
| 1845 locs()); | 2064 locs()); |
| 1846 // Pop instantiated type. | 2065 // Pop instantiated type. |
| 1847 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2066 __ lw(result_reg, Address(SP, 2 * kWordSize)); |
| 1848 // Drop instantiator and uninstantiated type. | 2067 // Drop instantiator and uninstantiated type. |
| 1849 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2068 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1850 ASSERT(instantiator_reg == result_reg); | 2069 ASSERT(instantiator_reg == result_reg); |
| 1851 } | 2070 } |
| 1852 | 2071 |
| 1853 | 2072 |
| 1854 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 2073 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 2074 bool opt) const { |
| 1855 const intptr_t kNumInputs = 1; | 2075 const intptr_t kNumInputs = 1; |
| 1856 const intptr_t kNumTemps = 0; | 2076 const intptr_t kNumTemps = 0; |
| 1857 LocationSummary* locs = | 2077 LocationSummary* locs = |
| 1858 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1859 locs->set_in(0, Location::RegisterLocation(T0)); | 2079 locs->set_in(0, Location::RegisterLocation(T0)); |
| 1860 locs->set_out(Location::RegisterLocation(T0)); | 2080 locs->set_out(Location::RegisterLocation(T0)); |
| 1861 return locs; | 2081 return locs; |
| 1862 } | 2082 } |
| 1863 | 2083 |
| 1864 | 2084 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1900 // Pop instantiated type arguments. | 2120 // Pop instantiated type arguments. |
| 1901 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2121 __ lw(result_reg, Address(SP, 2 * kWordSize)); |
| 1902 // Drop instantiator and uninstantiated type arguments. | 2122 // Drop instantiator and uninstantiated type arguments. |
| 1903 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2123 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1904 __ Bind(&type_arguments_instantiated); | 2124 __ Bind(&type_arguments_instantiated); |
| 1905 ASSERT(instantiator_reg == result_reg); | 2125 ASSERT(instantiator_reg == result_reg); |
| 1906 } | 2126 } |
| 1907 | 2127 |
| 1908 | 2128 |
| 1909 LocationSummary* | 2129 LocationSummary* |
| 1910 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2130 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const { |
| 1911 const intptr_t kNumInputs = 1; | 2131 const intptr_t kNumInputs = 1; |
| 1912 const intptr_t kNumTemps = 0; | 2132 const intptr_t kNumTemps = 0; |
| 1913 LocationSummary* locs = | 2133 LocationSummary* locs = |
| 1914 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1915 locs->set_in(0, Location::RequiresRegister()); | 2135 locs->set_in(0, Location::RequiresRegister()); |
| 1916 locs->set_out(Location::SameAsFirstInput()); | 2136 locs->set_out(Location::SameAsFirstInput()); |
| 1917 return locs; | 2137 return locs; |
| 1918 } | 2138 } |
| 1919 | 2139 |
| 1920 | 2140 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1941 // instantiate the type arguments. | 2161 // instantiate the type arguments. |
| 1942 __ LoadObject(result_reg, type_arguments()); | 2162 __ LoadObject(result_reg, type_arguments()); |
| 1943 // result_reg: uninstantiated type arguments. | 2163 // result_reg: uninstantiated type arguments. |
| 1944 __ Bind(&type_arguments_instantiated); | 2164 __ Bind(&type_arguments_instantiated); |
| 1945 | 2165 |
| 1946 // result_reg: uninstantiated or instantiated type arguments. | 2166 // result_reg: uninstantiated or instantiated type arguments. |
| 1947 } | 2167 } |
| 1948 | 2168 |
| 1949 | 2169 |
| 1950 LocationSummary* | 2170 LocationSummary* |
| 1951 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 2171 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const { |
| 1952 const intptr_t kNumInputs = 1; | 2172 const intptr_t kNumInputs = 1; |
| 1953 const intptr_t kNumTemps = 0; | 2173 const intptr_t kNumTemps = 0; |
| 1954 LocationSummary* locs = | 2174 LocationSummary* locs = |
| 1955 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2175 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1956 locs->set_in(0, Location::RequiresRegister()); | 2176 locs->set_in(0, Location::RequiresRegister()); |
| 1957 locs->set_out(Location::SameAsFirstInput()); | 2177 locs->set_out(Location::SameAsFirstInput()); |
| 1958 return locs; | 2178 return locs; |
| 1959 } | 2179 } |
| 1960 | 2180 |
| 1961 | 2181 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1979 &instantiator_not_null); | 2199 &instantiator_not_null); |
| 1980 // Null was used in VisitExtractConstructorTypeArguments as the | 2200 // Null was used in VisitExtractConstructorTypeArguments as the |
| 1981 // instantiated type arguments, no proper instantiator needed. | 2201 // instantiated type arguments, no proper instantiator needed. |
| 1982 __ LoadImmediate(instantiator_reg, | 2202 __ LoadImmediate(instantiator_reg, |
| 1983 Smi::RawValue(StubCode::kNoInstantiator)); | 2203 Smi::RawValue(StubCode::kNoInstantiator)); |
| 1984 __ Bind(&instantiator_not_null); | 2204 __ Bind(&instantiator_not_null); |
| 1985 // instantiator_reg: instantiator or kNoInstantiator. | 2205 // instantiator_reg: instantiator or kNoInstantiator. |
| 1986 } | 2206 } |
| 1987 | 2207 |
| 1988 | 2208 |
| 1989 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 2209 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
| 1990 const intptr_t kNumInputs = 0; | 2210 const intptr_t kNumInputs = 0; |
| 1991 const intptr_t kNumTemps = 1; | 2211 const intptr_t kNumTemps = 1; |
| 1992 LocationSummary* locs = | 2212 LocationSummary* locs = |
| 1993 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2213 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1994 locs->set_temp(0, Location::RegisterLocation(T1)); | 2214 locs->set_temp(0, Location::RegisterLocation(T1)); |
| 1995 locs->set_out(Location::RegisterLocation(V0)); | 2215 locs->set_out(Location::RegisterLocation(V0)); |
| 1996 return locs; | 2216 return locs; |
| 1997 } | 2217 } |
| 1998 | 2218 |
| 1999 | 2219 |
| 2000 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2220 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2001 Register temp = T1; | 2221 Register temp = T1; |
| 2002 ASSERT(locs()->temp(0).reg() == temp); | 2222 ASSERT(locs()->temp(0).reg() == temp); |
| 2003 ASSERT(locs()->out().reg() == V0); | 2223 ASSERT(locs()->out().reg() == V0); |
| 2004 | 2224 |
| 2005 __ TraceSimMsg("AllocateContextInstr"); | 2225 __ TraceSimMsg("AllocateContextInstr"); |
| 2006 __ LoadImmediate(temp, num_context_variables()); | 2226 __ LoadImmediate(temp, num_context_variables()); |
| 2007 const ExternalLabel label("alloc_context", | 2227 const ExternalLabel label("alloc_context", |
| 2008 StubCode::AllocateContextEntryPoint()); | 2228 StubCode::AllocateContextEntryPoint()); |
| 2009 compiler->GenerateCall(token_pos(), | 2229 compiler->GenerateCall(token_pos(), |
| 2010 &label, | 2230 &label, |
| 2011 PcDescriptors::kOther, | 2231 PcDescriptors::kOther, |
| 2012 locs()); | 2232 locs()); |
| 2013 } | 2233 } |
| 2014 | 2234 |
| 2015 | 2235 |
| 2016 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 2236 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { |
| 2017 const intptr_t kNumInputs = 1; | 2237 const intptr_t kNumInputs = 1; |
| 2018 const intptr_t kNumTemps = 0; | 2238 const intptr_t kNumTemps = 0; |
| 2019 LocationSummary* locs = | 2239 LocationSummary* locs = |
| 2020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2240 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2021 locs->set_in(0, Location::RegisterLocation(T0)); | 2241 locs->set_in(0, Location::RegisterLocation(T0)); |
| 2022 locs->set_out(Location::RegisterLocation(T0)); | 2242 locs->set_out(Location::RegisterLocation(T0)); |
| 2023 return locs; | 2243 return locs; |
| 2024 } | 2244 } |
| 2025 | 2245 |
| 2026 | 2246 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2038 compiler->GenerateRuntimeCall(token_pos(), | 2258 compiler->GenerateRuntimeCall(token_pos(), |
| 2039 deopt_id(), | 2259 deopt_id(), |
| 2040 kCloneContextRuntimeEntry, | 2260 kCloneContextRuntimeEntry, |
| 2041 1, | 2261 1, |
| 2042 locs()); | 2262 locs()); |
| 2043 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context). | 2263 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context). |
| 2044 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 2264 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 2045 } | 2265 } |
| 2046 | 2266 |
| 2047 | 2267 |
| 2048 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2268 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const { |
| 2049 UNREACHABLE(); | 2269 UNREACHABLE(); |
| 2050 return NULL; | 2270 return NULL; |
| 2051 } | 2271 } |
| 2052 | 2272 |
| 2053 | 2273 |
| 2054 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2274 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2055 __ Bind(compiler->GetJumpLabel(this)); | 2275 __ Bind(compiler->GetJumpLabel(this)); |
| 2056 compiler->AddExceptionHandler(catch_try_index(), | 2276 compiler->AddExceptionHandler(catch_try_index(), |
| 2057 try_index(), | 2277 try_index(), |
| 2058 compiler->assembler()->CodeSize(), | 2278 compiler->assembler()->CodeSize(), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2078 | 2298 |
| 2079 // Restore stack and initialize the two exception variables: | 2299 // Restore stack and initialize the two exception variables: |
| 2080 // exception and stack trace variables. | 2300 // exception and stack trace variables. |
| 2081 __ sw(kExceptionObjectReg, | 2301 __ sw(kExceptionObjectReg, |
| 2082 Address(FP, exception_var().index() * kWordSize)); | 2302 Address(FP, exception_var().index() * kWordSize)); |
| 2083 __ sw(kStackTraceObjectReg, | 2303 __ sw(kStackTraceObjectReg, |
| 2084 Address(FP, stacktrace_var().index() * kWordSize)); | 2304 Address(FP, stacktrace_var().index() * kWordSize)); |
| 2085 } | 2305 } |
| 2086 | 2306 |
| 2087 | 2307 |
| 2088 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2308 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const { |
| 2089 const intptr_t kNumInputs = 0; | 2309 const intptr_t kNumInputs = 0; |
| 2090 const intptr_t kNumTemps = 1; | 2310 const intptr_t kNumTemps = 1; |
| 2091 LocationSummary* summary = | 2311 LocationSummary* summary = |
| 2092 new LocationSummary(kNumInputs, | 2312 new LocationSummary(kNumInputs, |
| 2093 kNumTemps, | 2313 kNumTemps, |
| 2094 LocationSummary::kCallOnSlowPath); | 2314 LocationSummary::kCallOnSlowPath); |
| 2095 summary->set_temp(0, Location::RequiresRegister()); | 2315 summary->set_temp(0, Location::RequiresRegister()); |
| 2096 return summary; | 2316 return summary; |
| 2097 } | 2317 } |
| 2098 | 2318 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 // Overflow test (preserve left, right, and temp); | 2486 // Overflow test (preserve left, right, and temp); |
| 2267 __ sllv(CMPRES1, left, temp); | 2487 __ sllv(CMPRES1, left, temp); |
| 2268 __ srav(CMPRES1, CMPRES1, temp); | 2488 __ srav(CMPRES1, CMPRES1, temp); |
| 2269 __ bne(CMPRES1, left, deopt); // Overflow. | 2489 __ bne(CMPRES1, left, deopt); // Overflow. |
| 2270 // Shift for result now we know there is no overflow. | 2490 // Shift for result now we know there is no overflow. |
| 2271 __ sllv(result, left, temp); | 2491 __ sllv(result, left, temp); |
| 2272 } | 2492 } |
| 2273 } | 2493 } |
| 2274 | 2494 |
| 2275 | 2495 |
| 2276 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 2496 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const { |
| 2277 const intptr_t kNumInputs = 2; | 2497 const intptr_t kNumInputs = 2; |
| 2278 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0; | 2498 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0; |
| 2279 LocationSummary* summary = | 2499 LocationSummary* summary = |
| 2280 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2500 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2281 if (op_kind() == Token::kTRUNCDIV) { | 2501 if (op_kind() == Token::kTRUNCDIV) { |
| 2282 summary->set_in(0, Location::RequiresRegister()); | 2502 summary->set_in(0, Location::RequiresRegister()); |
| 2283 if (RightIsPowerOfTwoConstant()) { | 2503 if (RightIsPowerOfTwoConstant()) { |
| 2284 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2504 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 2285 summary->set_in(1, Location::Constant(right_constant->value())); | 2505 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2286 } else { | 2506 } else { |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 UNREACHABLE(); | 2832 UNREACHABLE(); |
| 2613 break; | 2833 break; |
| 2614 } | 2834 } |
| 2615 default: | 2835 default: |
| 2616 UNREACHABLE(); | 2836 UNREACHABLE(); |
| 2617 break; | 2837 break; |
| 2618 } | 2838 } |
| 2619 } | 2839 } |
| 2620 | 2840 |
| 2621 | 2841 |
| 2622 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 2842 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const { |
| 2623 intptr_t left_cid = left()->Type()->ToCid(); | 2843 intptr_t left_cid = left()->Type()->ToCid(); |
| 2624 intptr_t right_cid = right()->Type()->ToCid(); | 2844 intptr_t right_cid = right()->Type()->ToCid(); |
| 2625 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); | 2845 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); |
| 2626 const intptr_t kNumInputs = 2; | 2846 const intptr_t kNumInputs = 2; |
| 2627 const intptr_t kNumTemps = 0; | 2847 const intptr_t kNumTemps = 0; |
| 2628 LocationSummary* summary = | 2848 LocationSummary* summary = |
| 2629 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2849 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2630 summary->set_in(0, Location::RequiresRegister()); | 2850 summary->set_in(0, Location::RequiresRegister()); |
| 2631 summary->set_in(1, Location::RequiresRegister()); | 2851 summary->set_in(1, Location::RequiresRegister()); |
| 2632 return summary; | 2852 return summary; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2644 } else if (right_cid == kSmiCid) { | 2864 } else if (right_cid == kSmiCid) { |
| 2645 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); | 2865 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); |
| 2646 } else { | 2866 } else { |
| 2647 __ or_(TMP, left, right); | 2867 __ or_(TMP, left, right); |
| 2648 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); | 2868 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); |
| 2649 } | 2869 } |
| 2650 __ beq(CMPRES1, ZR, deopt); | 2870 __ beq(CMPRES1, ZR, deopt); |
| 2651 } | 2871 } |
| 2652 | 2872 |
| 2653 | 2873 |
| 2654 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 2874 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 2655 const intptr_t kNumInputs = 1; | 2875 const intptr_t kNumInputs = 1; |
| 2656 const intptr_t kNumTemps = 0; | 2876 const intptr_t kNumTemps = 0; |
| 2657 LocationSummary* summary = | 2877 LocationSummary* summary = |
| 2658 new LocationSummary(kNumInputs, | 2878 new LocationSummary(kNumInputs, |
| 2659 kNumTemps, | 2879 kNumTemps, |
| 2660 LocationSummary::kCallOnSlowPath); | 2880 LocationSummary::kCallOnSlowPath); |
| 2661 summary->set_in(0, Location::RequiresFpuRegister()); | 2881 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2662 summary->set_out(Location::RequiresRegister()); | 2882 summary->set_out(Location::RequiresRegister()); |
| 2663 return summary; | 2883 return summary; |
| 2664 } | 2884 } |
| 2665 | 2885 |
| 2666 | 2886 |
| 2667 class BoxDoubleSlowPath : public SlowPathCode { | |
| 2668 public: | |
| 2669 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | |
| 2670 : instruction_(instruction) { } | |
| 2671 | |
| 2672 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2673 __ Comment("BoxDoubleSlowPath"); | |
| 2674 __ Bind(entry_label()); | |
| 2675 const Class& double_class = compiler->double_class(); | |
| 2676 const Code& stub = | |
| 2677 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
| 2678 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
| 2679 | |
| 2680 LocationSummary* locs = instruction_->locs(); | |
| 2681 locs->live_registers()->Remove(locs->out()); | |
| 2682 | |
| 2683 compiler->SaveLiveRegisters(locs); | |
| 2684 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | |
| 2685 &label, | |
| 2686 PcDescriptors::kOther, | |
| 2687 locs); | |
| 2688 if (locs->out().reg() != V0) { | |
| 2689 __ mov(locs->out().reg(), V0); | |
| 2690 } | |
| 2691 compiler->RestoreLiveRegisters(locs); | |
| 2692 | |
| 2693 __ b(exit_label()); | |
| 2694 } | |
| 2695 | |
| 2696 private: | |
| 2697 BoxDoubleInstr* instruction_; | |
| 2698 }; | |
| 2699 | |
| 2700 | |
| 2701 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2887 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2702 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2888 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 2703 compiler->AddSlowPathCode(slow_path); | 2889 compiler->AddSlowPathCode(slow_path); |
| 2704 | 2890 |
| 2705 Register out_reg = locs()->out().reg(); | 2891 Register out_reg = locs()->out().reg(); |
| 2706 DRegister value = locs()->in(0).fpu_reg(); | 2892 DRegister value = locs()->in(0).fpu_reg(); |
| 2707 | 2893 |
| 2708 __ TryAllocate(compiler->double_class(), | 2894 __ TryAllocate(compiler->double_class(), |
| 2709 slow_path->entry_label(), | 2895 slow_path->entry_label(), |
| 2710 out_reg); | 2896 out_reg); |
| 2711 __ Bind(slow_path->exit_label()); | 2897 __ Bind(slow_path->exit_label()); |
| 2712 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 2898 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 2713 } | 2899 } |
| 2714 | 2900 |
| 2715 | 2901 |
| 2716 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2902 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 2717 const intptr_t kNumInputs = 1; | 2903 const intptr_t kNumInputs = 1; |
| 2718 const intptr_t value_cid = value()->Type()->ToCid(); | 2904 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2719 const bool needs_writable_input = (value_cid == kSmiCid); | 2905 const bool needs_writable_input = (value_cid == kSmiCid); |
| 2720 const intptr_t kNumTemps = 0; | 2906 const intptr_t kNumTemps = 0; |
| 2721 LocationSummary* summary = | 2907 LocationSummary* summary = |
| 2722 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2908 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2723 summary->set_in(0, needs_writable_input | 2909 summary->set_in(0, needs_writable_input |
| 2724 ? Location::WritableRegister() | 2910 ? Location::WritableRegister() |
| 2725 : Location::RequiresRegister()); | 2911 : Location::RequiresRegister()); |
| 2726 summary->set_out(Location::RequiresFpuRegister()); | 2912 summary->set_out(Location::RequiresFpuRegister()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2752 __ Bind(&is_smi); | 2938 __ Bind(&is_smi); |
| 2753 // TODO(regis): Why do we preserve value here but not above? | 2939 // TODO(regis): Why do we preserve value here but not above? |
| 2754 __ sra(TMP, value, 1); | 2940 __ sra(TMP, value, 1); |
| 2755 __ mtc1(TMP, STMP1); | 2941 __ mtc1(TMP, STMP1); |
| 2756 __ cvtdw(result, STMP1); | 2942 __ cvtdw(result, STMP1); |
| 2757 __ Bind(&done); | 2943 __ Bind(&done); |
| 2758 } | 2944 } |
| 2759 } | 2945 } |
| 2760 | 2946 |
| 2761 | 2947 |
| 2762 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | 2948 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 2763 UNIMPLEMENTED(); | 2949 UNIMPLEMENTED(); |
| 2764 return NULL; | 2950 return NULL; |
| 2765 } | 2951 } |
| 2766 | 2952 |
| 2767 | 2953 |
| 2768 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2954 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2769 UNIMPLEMENTED(); | 2955 UNIMPLEMENTED(); |
| 2770 } | 2956 } |
| 2771 | 2957 |
| 2772 | 2958 |
| 2773 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2959 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 2774 UNIMPLEMENTED(); | 2960 UNIMPLEMENTED(); |
| 2775 return NULL; | 2961 return NULL; |
| 2776 } | 2962 } |
| 2777 | 2963 |
| 2778 | 2964 |
| 2779 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2965 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2780 UNIMPLEMENTED(); | 2966 UNIMPLEMENTED(); |
| 2781 } | 2967 } |
| 2782 | 2968 |
| 2783 | 2969 |
| 2784 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { | 2970 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 2785 UNIMPLEMENTED(); | 2971 UNIMPLEMENTED(); |
| 2786 return NULL; | 2972 return NULL; |
| 2787 } | 2973 } |
| 2788 | 2974 |
| 2789 | 2975 |
| 2790 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2976 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2791 UNIMPLEMENTED(); | 2977 UNIMPLEMENTED(); |
| 2792 } | 2978 } |
| 2793 | 2979 |
| 2794 | 2980 |
| 2795 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { | 2981 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 2796 UNIMPLEMENTED(); | 2982 UNIMPLEMENTED(); |
| 2797 return NULL; | 2983 return NULL; |
| 2798 } | 2984 } |
| 2799 | 2985 |
| 2800 | 2986 |
| 2801 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2987 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2802 UNIMPLEMENTED(); | 2988 UNIMPLEMENTED(); |
| 2803 } | 2989 } |
| 2804 | 2990 |
| 2805 | 2991 |
| 2806 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2992 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 2807 const intptr_t kNumInputs = 2; | 2993 const intptr_t kNumInputs = 2; |
| 2808 const intptr_t kNumTemps = 0; | 2994 const intptr_t kNumTemps = 0; |
| 2809 LocationSummary* summary = | 2995 LocationSummary* summary = |
| 2810 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2996 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2811 summary->set_in(0, Location::RequiresFpuRegister()); | 2997 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2812 summary->set_in(1, Location::RequiresFpuRegister()); | 2998 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2813 summary->set_out(Location::RequiresFpuRegister()); | 2999 summary->set_out(Location::RequiresFpuRegister()); |
| 2814 return summary; | 3000 return summary; |
| 2815 } | 3001 } |
| 2816 | 3002 |
| 2817 | 3003 |
| 2818 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3004 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2819 DRegister left = locs()->in(0).fpu_reg(); | 3005 DRegister left = locs()->in(0).fpu_reg(); |
| 2820 DRegister right = locs()->in(1).fpu_reg(); | 3006 DRegister right = locs()->in(1).fpu_reg(); |
| 2821 DRegister result = locs()->out().fpu_reg(); | 3007 DRegister result = locs()->out().fpu_reg(); |
| 2822 switch (op_kind()) { | 3008 switch (op_kind()) { |
| 2823 case Token::kADD: __ addd(result, left, right); break; | 3009 case Token::kADD: __ addd(result, left, right); break; |
| 2824 case Token::kSUB: __ subd(result, left, right); break; | 3010 case Token::kSUB: __ subd(result, left, right); break; |
| 2825 case Token::kMUL: __ muld(result, left, right); break; | 3011 case Token::kMUL: __ muld(result, left, right); break; |
| 2826 case Token::kDIV: __ divd(result, left, right); break; | 3012 case Token::kDIV: __ divd(result, left, right); break; |
| 2827 default: UNREACHABLE(); | 3013 default: UNREACHABLE(); |
| 2828 } | 3014 } |
| 2829 } | 3015 } |
| 2830 | 3016 |
| 2831 | 3017 |
| 2832 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { | 3018 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 2833 UNIMPLEMENTED(); | 3019 UNIMPLEMENTED(); |
| 2834 return NULL; | 3020 return NULL; |
| 2835 } | 3021 } |
| 2836 | 3022 |
| 2837 | 3023 |
| 2838 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3024 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2839 UNIMPLEMENTED(); | 3025 UNIMPLEMENTED(); |
| 2840 } | 3026 } |
| 2841 | 3027 |
| 2842 | 3028 |
| 2843 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { | 3029 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
| 2844 UNIMPLEMENTED(); | 3030 UNIMPLEMENTED(); |
| 2845 return NULL; | 3031 return NULL; |
| 2846 } | 3032 } |
| 2847 | 3033 |
| 2848 | 3034 |
| 2849 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3035 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2850 UNIMPLEMENTED(); | 3036 UNIMPLEMENTED(); |
| 2851 } | 3037 } |
| 2852 | 3038 |
| 2853 | 3039 |
| 2854 | 3040 |
| 2855 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3041 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { |
| 2856 UNIMPLEMENTED(); | 3042 UNIMPLEMENTED(); |
| 2857 return NULL; | 3043 return NULL; |
| 2858 } | 3044 } |
| 2859 | 3045 |
| 2860 | 3046 |
| 2861 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3047 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2862 UNIMPLEMENTED(); | 3048 UNIMPLEMENTED(); |
| 2863 } | 3049 } |
| 2864 | 3050 |
| 2865 | 3051 |
| 2866 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { | 3052 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 3053 bool opt) const { |
| 2867 UNIMPLEMENTED(); | 3054 UNIMPLEMENTED(); |
| 2868 return NULL; | 3055 return NULL; |
| 2869 } | 3056 } |
| 2870 | 3057 |
| 2871 | 3058 |
| 2872 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3059 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2873 UNIMPLEMENTED(); | 3060 UNIMPLEMENTED(); |
| 2874 } | 3061 } |
| 2875 | 3062 |
| 2876 | 3063 |
| 2877 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { | 3064 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { |
| 2878 UNIMPLEMENTED(); | 3065 UNIMPLEMENTED(); |
| 2879 return NULL; | 3066 return NULL; |
| 2880 } | 3067 } |
| 2881 | 3068 |
| 2882 | 3069 |
| 2883 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3070 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2884 UNIMPLEMENTED(); | 3071 UNIMPLEMENTED(); |
| 2885 } | 3072 } |
| 2886 | 3073 |
| 2887 | 3074 |
| 2888 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { | 3075 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { |
| 2889 UNIMPLEMENTED(); | 3076 UNIMPLEMENTED(); |
| 2890 return NULL; | 3077 return NULL; |
| 2891 } | 3078 } |
| 2892 | 3079 |
| 2893 | 3080 |
| 2894 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3081 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2895 UNIMPLEMENTED(); | 3082 UNIMPLEMENTED(); |
| 2896 } | 3083 } |
| 2897 | 3084 |
| 2898 | 3085 |
| 2899 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { | 3086 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { |
| 2900 UNIMPLEMENTED(); | 3087 UNIMPLEMENTED(); |
| 2901 return NULL; | 3088 return NULL; |
| 2902 } | 3089 } |
| 2903 | 3090 |
| 2904 | 3091 |
| 2905 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3092 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2906 UNIMPLEMENTED(); | 3093 UNIMPLEMENTED(); |
| 2907 } | 3094 } |
| 2908 | 3095 |
| 2909 | 3096 |
| 2910 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { | 3097 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { |
| 2911 UNIMPLEMENTED(); | 3098 UNIMPLEMENTED(); |
| 2912 return NULL; | 3099 return NULL; |
| 2913 } | 3100 } |
| 2914 | 3101 |
| 2915 | 3102 |
| 2916 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3103 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2917 UNIMPLEMENTED(); | 3104 UNIMPLEMENTED(); |
| 2918 } | 3105 } |
| 2919 | 3106 |
| 2920 | 3107 |
| 2921 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { | 3108 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { |
| 2922 UNIMPLEMENTED(); | 3109 UNIMPLEMENTED(); |
| 2923 return NULL; | 3110 return NULL; |
| 2924 } | 3111 } |
| 2925 | 3112 |
| 2926 | 3113 |
| 2927 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3114 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2928 UNIMPLEMENTED(); | 3115 UNIMPLEMENTED(); |
| 2929 } | 3116 } |
| 2930 | 3117 |
| 2931 | 3118 |
| 2932 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { | 3119 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { |
| 2933 UNIMPLEMENTED(); | 3120 UNIMPLEMENTED(); |
| 2934 return NULL; | 3121 return NULL; |
| 2935 } | 3122 } |
| 2936 | 3123 |
| 2937 | 3124 |
| 2938 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3125 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2939 UNIMPLEMENTED(); | 3126 UNIMPLEMENTED(); |
| 2940 } | 3127 } |
| 2941 | 3128 |
| 2942 | 3129 |
| 2943 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { | 3130 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { |
| 2944 UNIMPLEMENTED(); | 3131 UNIMPLEMENTED(); |
| 2945 return NULL; | 3132 return NULL; |
| 2946 } | 3133 } |
| 2947 | 3134 |
| 2948 | 3135 |
| 2949 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3136 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2950 UNIMPLEMENTED(); | 3137 UNIMPLEMENTED(); |
| 2951 } | 3138 } |
| 2952 | 3139 |
| 2953 | 3140 |
| 2954 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { | 3141 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { |
| 2955 UNIMPLEMENTED(); | 3142 UNIMPLEMENTED(); |
| 2956 return NULL; | 3143 return NULL; |
| 2957 } | 3144 } |
| 2958 | 3145 |
| 2959 | 3146 |
| 2960 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3147 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2961 UNIMPLEMENTED(); | 3148 UNIMPLEMENTED(); |
| 2962 } | 3149 } |
| 2963 | 3150 |
| 2964 | 3151 |
| 2965 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { | 3152 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { |
| 2966 UNIMPLEMENTED(); | 3153 UNIMPLEMENTED(); |
| 2967 return NULL; | 3154 return NULL; |
| 2968 } | 3155 } |
| 2969 | 3156 |
| 2970 | 3157 |
| 2971 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3158 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2972 UNIMPLEMENTED(); | 3159 UNIMPLEMENTED(); |
| 2973 } | 3160 } |
| 2974 | 3161 |
| 2975 | 3162 |
| 2976 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { | 3163 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 2977 UNIMPLEMENTED(); | 3164 UNIMPLEMENTED(); |
| 2978 return NULL; | 3165 return NULL; |
| 2979 } | 3166 } |
| 2980 | 3167 |
| 2981 | 3168 |
| 2982 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3169 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2983 UNIMPLEMENTED(); | 3170 UNIMPLEMENTED(); |
| 2984 } | 3171 } |
| 2985 | 3172 |
| 2986 | 3173 |
| 2987 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { | 3174 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
| 3175 bool opt) const { |
| 2988 UNIMPLEMENTED(); | 3176 UNIMPLEMENTED(); |
| 2989 return NULL; | 3177 return NULL; |
| 2990 } | 3178 } |
| 2991 | 3179 |
| 2992 | 3180 |
| 2993 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3181 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2994 UNIMPLEMENTED(); | 3182 UNIMPLEMENTED(); |
| 2995 } | 3183 } |
| 2996 | 3184 |
| 2997 | 3185 |
| 2998 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { | 3186 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { |
| 2999 UNIMPLEMENTED(); | 3187 UNIMPLEMENTED(); |
| 3000 return NULL; | 3188 return NULL; |
| 3001 } | 3189 } |
| 3002 | 3190 |
| 3003 | 3191 |
| 3004 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3192 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3005 UNIMPLEMENTED(); | 3193 UNIMPLEMENTED(); |
| 3006 } | 3194 } |
| 3007 | 3195 |
| 3008 | 3196 |
| 3009 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3197 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { |
| 3010 UNIMPLEMENTED(); | 3198 UNIMPLEMENTED(); |
| 3011 return NULL; | 3199 return NULL; |
| 3012 } | 3200 } |
| 3013 | 3201 |
| 3014 | 3202 |
| 3015 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3203 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3016 UNIMPLEMENTED(); | 3204 UNIMPLEMENTED(); |
| 3017 } | 3205 } |
| 3018 | 3206 |
| 3019 | 3207 |
| 3020 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { | 3208 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { |
| 3021 UNIMPLEMENTED(); | 3209 UNIMPLEMENTED(); |
| 3022 return NULL; | 3210 return NULL; |
| 3023 } | 3211 } |
| 3024 | 3212 |
| 3025 | 3213 |
| 3026 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3214 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3027 UNIMPLEMENTED(); | 3215 UNIMPLEMENTED(); |
| 3028 } | 3216 } |
| 3029 | 3217 |
| 3030 | 3218 |
| 3031 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { | 3219 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { |
| 3032 UNIMPLEMENTED(); | 3220 UNIMPLEMENTED(); |
| 3033 return NULL; | 3221 return NULL; |
| 3034 } | 3222 } |
| 3035 | 3223 |
| 3036 | 3224 |
| 3037 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3225 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3038 UNIMPLEMENTED(); | 3226 UNIMPLEMENTED(); |
| 3039 } | 3227 } |
| 3040 | 3228 |
| 3041 | 3229 |
| 3042 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3230 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 3043 UNIMPLEMENTED(); | 3231 UNIMPLEMENTED(); |
| 3044 return NULL; | 3232 return NULL; |
| 3045 } | 3233 } |
| 3046 | 3234 |
| 3047 | 3235 |
| 3048 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3236 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3049 UNIMPLEMENTED(); | 3237 UNIMPLEMENTED(); |
| 3050 } | 3238 } |
| 3051 | 3239 |
| 3052 | 3240 |
| 3053 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { | 3241 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 3054 UNIMPLEMENTED(); | 3242 UNIMPLEMENTED(); |
| 3055 return NULL; | 3243 return NULL; |
| 3056 } | 3244 } |
| 3057 | 3245 |
| 3058 | 3246 |
| 3059 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3247 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3060 UNIMPLEMENTED(); | 3248 UNIMPLEMENTED(); |
| 3061 } | 3249 } |
| 3062 | 3250 |
| 3063 | 3251 |
| 3064 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { | 3252 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
| 3065 if ((kind() == MethodRecognizer::kMathSin) || | 3253 if ((kind() == MethodRecognizer::kMathSin) || |
| 3066 (kind() == MethodRecognizer::kMathCos)) { | 3254 (kind() == MethodRecognizer::kMathCos)) { |
| 3067 const intptr_t kNumInputs = 1; | 3255 const intptr_t kNumInputs = 1; |
| 3068 const intptr_t kNumTemps = 0; | 3256 const intptr_t kNumTemps = 0; |
| 3069 LocationSummary* summary = | 3257 LocationSummary* summary = |
| 3070 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3071 summary->set_in(0, Location::FpuRegisterLocation(D6)); | 3259 summary->set_in(0, Location::FpuRegisterLocation(D6)); |
| 3072 summary->set_out(Location::FpuRegisterLocation(D0)); | 3260 summary->set_out(Location::FpuRegisterLocation(D0)); |
| 3073 return summary; | 3261 return summary; |
| 3074 } | 3262 } |
| 3075 const intptr_t kNumInputs = 1; | 3263 const intptr_t kNumInputs = 1; |
| 3076 const intptr_t kNumTemps = 0; | 3264 const intptr_t kNumTemps = 0; |
| 3077 LocationSummary* summary = | 3265 LocationSummary* summary = |
| 3078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3266 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3079 summary->set_in(0, Location::RequiresFpuRegister()); | 3267 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3080 summary->set_out(Location::RequiresFpuRegister()); | 3268 summary->set_out(Location::RequiresFpuRegister()); |
| 3081 return summary; | 3269 return summary; |
| 3082 } | 3270 } |
| 3083 | 3271 |
| 3084 | 3272 |
| 3085 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3273 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3086 if (kind() == MethodRecognizer::kMathSqrt) { | 3274 if (kind() == MethodRecognizer::kMathSqrt) { |
| 3087 __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3275 __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
| 3088 } else { | 3276 } else { |
| 3089 __ CallRuntime(TargetFunction(), InputCount()); | 3277 __ CallRuntime(TargetFunction(), InputCount()); |
| 3090 } | 3278 } |
| 3091 } | 3279 } |
| 3092 | 3280 |
| 3093 | 3281 |
| 3094 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3282 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
| 3095 if (result_cid() == kDoubleCid) { | 3283 if (result_cid() == kDoubleCid) { |
| 3096 const intptr_t kNumInputs = 2; | 3284 const intptr_t kNumInputs = 2; |
| 3097 const intptr_t kNumTemps = 1; | 3285 const intptr_t kNumTemps = 1; |
| 3098 LocationSummary* summary = | 3286 LocationSummary* summary = |
| 3099 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3287 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3100 summary->set_in(0, Location::RequiresFpuRegister()); | 3288 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3101 summary->set_in(1, Location::RequiresFpuRegister()); | 3289 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3102 // Reuse the left register so that code can be made shorter. | 3290 // Reuse the left register so that code can be made shorter. |
| 3103 summary->set_out(Location::SameAsFirstInput()); | 3291 summary->set_out(Location::SameAsFirstInput()); |
| 3104 summary->set_temp(0, Location::RequiresRegister()); | 3292 summary->set_temp(0, Location::RequiresRegister()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 if (is_min) { | 3363 if (is_min) { |
| 3176 __ BranchSignedLessEqual(left, right, &done); | 3364 __ BranchSignedLessEqual(left, right, &done); |
| 3177 } else { | 3365 } else { |
| 3178 __ BranchSignedGreaterEqual(left, right, &done); | 3366 __ BranchSignedGreaterEqual(left, right, &done); |
| 3179 } | 3367 } |
| 3180 __ mov(result, right); | 3368 __ mov(result, right); |
| 3181 __ Bind(&done); | 3369 __ Bind(&done); |
| 3182 } | 3370 } |
| 3183 | 3371 |
| 3184 | 3372 |
| 3185 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3373 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { |
| 3186 const intptr_t kNumInputs = 1; | 3374 const intptr_t kNumInputs = 1; |
| 3187 const intptr_t kNumTemps = 0; | 3375 const intptr_t kNumTemps = 0; |
| 3188 LocationSummary* summary = | 3376 LocationSummary* summary = |
| 3189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3190 summary->set_in(0, Location::RequiresRegister()); | 3378 summary->set_in(0, Location::RequiresRegister()); |
| 3191 // We make use of 3-operand instructions by not requiring result register | 3379 // We make use of 3-operand instructions by not requiring result register |
| 3192 // to be identical to first input register as on Intel. | 3380 // to be identical to first input register as on Intel. |
| 3193 summary->set_out(Location::RequiresRegister()); | 3381 summary->set_out(Location::RequiresRegister()); |
| 3194 return summary; | 3382 return summary; |
| 3195 } | 3383 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3209 case Token::kBIT_NOT: | 3397 case Token::kBIT_NOT: |
| 3210 __ nor(result, value, ZR); | 3398 __ nor(result, value, ZR); |
| 3211 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag. | 3399 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag. |
| 3212 break; | 3400 break; |
| 3213 default: | 3401 default: |
| 3214 UNREACHABLE(); | 3402 UNREACHABLE(); |
| 3215 } | 3403 } |
| 3216 } | 3404 } |
| 3217 | 3405 |
| 3218 | 3406 |
| 3219 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { | 3407 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 3220 const intptr_t kNumInputs = 1; | 3408 const intptr_t kNumInputs = 1; |
| 3221 const intptr_t kNumTemps = 1; | 3409 const intptr_t kNumTemps = 1; |
| 3222 LocationSummary* summary = | 3410 LocationSummary* summary = |
| 3223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3411 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3224 summary->set_in(0, Location::RequiresFpuRegister()); | 3412 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3225 summary->set_out(Location::RequiresFpuRegister()); | 3413 summary->set_out(Location::RequiresFpuRegister()); |
| 3226 summary->set_temp(0, Location::RequiresFpuRegister()); | 3414 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3227 return summary; | 3415 return summary; |
| 3228 } | 3416 } |
| 3229 | 3417 |
| 3230 | 3418 |
| 3231 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3419 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3232 // TODO(zra): Implement vneg. | 3420 // TODO(zra): Implement vneg. |
| 3233 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1)); | 3421 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1)); |
| 3234 __ LoadObject(TMP, minus_one); | 3422 __ LoadObject(TMP, minus_one); |
| 3235 FpuRegister result = locs()->out().fpu_reg(); | 3423 FpuRegister result = locs()->out().fpu_reg(); |
| 3236 FpuRegister value = locs()->in(0).fpu_reg(); | 3424 FpuRegister value = locs()->in(0).fpu_reg(); |
| 3237 FpuRegister temp_fp = locs()->temp(0).fpu_reg(); | 3425 FpuRegister temp_fp = locs()->temp(0).fpu_reg(); |
| 3238 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag); | 3426 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag); |
| 3239 __ muld(result, value, temp_fp); | 3427 __ muld(result, value, temp_fp); |
| 3240 } | 3428 } |
| 3241 | 3429 |
| 3242 | 3430 |
| 3243 | 3431 |
| 3244 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 3432 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3245 const intptr_t kNumInputs = 1; | 3433 const intptr_t kNumInputs = 1; |
| 3246 const intptr_t kNumTemps = 0; | 3434 const intptr_t kNumTemps = 0; |
| 3247 LocationSummary* result = | 3435 LocationSummary* result = |
| 3248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3436 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3249 result->set_in(0, Location::WritableRegister()); | 3437 result->set_in(0, Location::WritableRegister()); |
| 3250 result->set_out(Location::RequiresFpuRegister()); | 3438 result->set_out(Location::RequiresFpuRegister()); |
| 3251 return result; | 3439 return result; |
| 3252 } | 3440 } |
| 3253 | 3441 |
| 3254 | 3442 |
| 3255 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3443 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3256 Register value = locs()->in(0).reg(); | 3444 Register value = locs()->in(0).reg(); |
| 3257 FpuRegister result = locs()->out().fpu_reg(); | 3445 FpuRegister result = locs()->out().fpu_reg(); |
| 3258 __ SmiUntag(value); | 3446 __ SmiUntag(value); |
| 3259 __ mtc1(value, STMP1); | 3447 __ mtc1(value, STMP1); |
| 3260 __ cvtdw(result, STMP1); | 3448 __ cvtdw(result, STMP1); |
| 3261 } | 3449 } |
| 3262 | 3450 |
| 3263 | 3451 |
| 3264 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 3452 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { |
| 3265 const intptr_t kNumInputs = 1; | 3453 const intptr_t kNumInputs = 1; |
| 3266 const intptr_t kNumTemps = 0; | 3454 const intptr_t kNumTemps = 0; |
| 3267 LocationSummary* result = | 3455 LocationSummary* result = |
| 3268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3269 result->set_in(0, Location::RegisterLocation(T1)); | 3457 result->set_in(0, Location::RegisterLocation(T1)); |
| 3270 result->set_out(Location::RegisterLocation(V0)); | 3458 result->set_out(Location::RegisterLocation(V0)); |
| 3271 return result; | 3459 return result; |
| 3272 } | 3460 } |
| 3273 | 3461 |
| 3274 | 3462 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3300 compiler->GenerateStaticCall(deopt_id(), | 3488 compiler->GenerateStaticCall(deopt_id(), |
| 3301 instance_call()->token_pos(), | 3489 instance_call()->token_pos(), |
| 3302 target, | 3490 target, |
| 3303 kNumberOfArguments, | 3491 kNumberOfArguments, |
| 3304 Object::null_array(), // No argument names., | 3492 Object::null_array(), // No argument names., |
| 3305 locs()); | 3493 locs()); |
| 3306 __ Bind(&done); | 3494 __ Bind(&done); |
| 3307 } | 3495 } |
| 3308 | 3496 |
| 3309 | 3497 |
| 3310 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3498 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { |
| 3311 const intptr_t kNumInputs = 1; | 3499 const intptr_t kNumInputs = 1; |
| 3312 const intptr_t kNumTemps = 0; | 3500 const intptr_t kNumTemps = 0; |
| 3313 LocationSummary* result = new LocationSummary( | 3501 LocationSummary* result = new LocationSummary( |
| 3314 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3502 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3315 result->set_in(0, Location::RequiresFpuRegister()); | 3503 result->set_in(0, Location::RequiresFpuRegister()); |
| 3316 result->set_out(Location::RequiresRegister()); | 3504 result->set_out(Location::RequiresRegister()); |
| 3317 return result; | 3505 return result; |
| 3318 } | 3506 } |
| 3319 | 3507 |
| 3320 | 3508 |
| 3321 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3509 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3322 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 3510 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
| 3323 Register result = locs()->out().reg(); | 3511 Register result = locs()->out().reg(); |
| 3324 DRegister value = locs()->in(0).fpu_reg(); | 3512 DRegister value = locs()->in(0).fpu_reg(); |
| 3325 __ cvtwd(STMP1, value); | 3513 __ cvtwd(STMP1, value); |
| 3326 __ mfc1(result, STMP1); | 3514 __ mfc1(result, STMP1); |
| 3327 | 3515 |
| 3328 // Check for overflow and that it fits into Smi. | 3516 // Check for overflow and that it fits into Smi. |
| 3329 __ LoadImmediate(TMP, 0xC0000000); | 3517 __ LoadImmediate(TMP, 0xC0000000); |
| 3330 __ subu(CMPRES1, result, TMP); | 3518 __ subu(CMPRES1, result, TMP); |
| 3331 __ bltz(CMPRES1, deopt); | 3519 __ bltz(CMPRES1, deopt); |
| 3332 __ SmiTag(result); | 3520 __ SmiTag(result); |
| 3333 } | 3521 } |
| 3334 | 3522 |
| 3335 | 3523 |
| 3336 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 3524 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3337 UNIMPLEMENTED(); | 3525 UNIMPLEMENTED(); |
| 3338 return NULL; | 3526 return NULL; |
| 3339 } | 3527 } |
| 3340 | 3528 |
| 3341 | 3529 |
| 3342 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3530 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3343 UNIMPLEMENTED(); | 3531 UNIMPLEMENTED(); |
| 3344 } | 3532 } |
| 3345 | 3533 |
| 3346 | 3534 |
| 3347 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 3535 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { |
| 3348 // Calling convetion on MIPS uses D6 and D7 to pass the first two | 3536 // Calling convetion on MIPS uses D6 and D7 to pass the first two |
| 3349 // double arguments. | 3537 // double arguments. |
| 3350 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 3538 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 3351 const intptr_t kNumTemps = 0; | 3539 const intptr_t kNumTemps = 0; |
| 3352 LocationSummary* result = | 3540 LocationSummary* result = |
| 3353 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 3541 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 3354 result->set_in(0, Location::FpuRegisterLocation(D6)); | 3542 result->set_in(0, Location::FpuRegisterLocation(D6)); |
| 3355 if (InputCount() == 2) { | 3543 if (InputCount() == 2) { |
| 3356 result->set_in(1, Location::FpuRegisterLocation(D7)); | 3544 result->set_in(1, Location::FpuRegisterLocation(D7)); |
| 3357 } | 3545 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 __ movd(result, base); // base is NaN, return NaN. | 3587 __ movd(result, base); // base is NaN, return NaN. |
| 3400 __ b(&skip_call); | 3588 __ b(&skip_call); |
| 3401 } | 3589 } |
| 3402 __ Bind(&do_call); | 3590 __ Bind(&do_call); |
| 3403 // double values are passed and returned in vfp registers. | 3591 // double values are passed and returned in vfp registers. |
| 3404 __ CallRuntime(TargetFunction(), InputCount()); | 3592 __ CallRuntime(TargetFunction(), InputCount()); |
| 3405 __ Bind(&skip_call); | 3593 __ Bind(&skip_call); |
| 3406 } | 3594 } |
| 3407 | 3595 |
| 3408 | 3596 |
| 3409 LocationSummary* MergedMathInstr::MakeLocationSummary() const { | 3597 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| 3410 if (kind() == MergedMathInstr::kTruncDivMod) { | 3598 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 3411 const intptr_t kNumInputs = 2; | 3599 const intptr_t kNumInputs = 2; |
| 3412 const intptr_t kNumTemps = 3; | 3600 const intptr_t kNumTemps = 3; |
| 3413 LocationSummary* summary = | 3601 LocationSummary* summary = |
| 3414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3602 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3415 summary->set_in(0, Location::RequiresRegister()); | 3603 summary->set_in(0, Location::RequiresRegister()); |
| 3416 summary->set_in(1, Location::RequiresRegister()); | 3604 summary->set_in(1, Location::RequiresRegister()); |
| 3417 summary->set_temp(0, Location::RequiresRegister()); | 3605 summary->set_temp(0, Location::RequiresRegister()); |
| 3418 summary->set_temp(1, Location::RequiresRegister()); // result_div. | 3606 summary->set_temp(1, Location::RequiresRegister()); // result_div. |
| 3419 summary->set_temp(2, Location::RequiresRegister()); // result_mod. | 3607 summary->set_temp(2, Location::RequiresRegister()); // result_mod. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3487 Address div_result_address(temp, 0); | 3675 Address div_result_address(temp, 0); |
| 3488 Address mod_result_address(temp, kWordSize); | 3676 Address mod_result_address(temp, kWordSize); |
| 3489 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div); | 3677 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div); |
| 3490 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod); | 3678 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod); |
| 3491 return; | 3679 return; |
| 3492 } | 3680 } |
| 3493 UNIMPLEMENTED(); | 3681 UNIMPLEMENTED(); |
| 3494 } | 3682 } |
| 3495 | 3683 |
| 3496 | 3684 |
| 3497 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3685 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 3686 bool opt) const { |
| 3498 return MakeCallSummary(); | 3687 return MakeCallSummary(); |
| 3499 } | 3688 } |
| 3500 | 3689 |
| 3501 | 3690 |
| 3502 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3691 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3503 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3692 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3504 kDeoptPolymorphicInstanceCallTestFail); | 3693 kDeoptPolymorphicInstanceCallTestFail); |
| 3505 __ TraceSimMsg("PolymorphicInstanceCallInstr"); | 3694 __ TraceSimMsg("PolymorphicInstanceCallInstr"); |
| 3506 if (ic_data().NumberOfChecks() == 0) { | 3695 if (ic_data().NumberOfChecks() == 0) { |
| 3507 __ b(deopt); | 3696 __ b(deopt); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3530 T2, // Class id register. | 3719 T2, // Class id register. |
| 3531 instance_call()->ArgumentCount(), | 3720 instance_call()->ArgumentCount(), |
| 3532 instance_call()->argument_names(), | 3721 instance_call()->argument_names(), |
| 3533 deopt, | 3722 deopt, |
| 3534 deopt_id(), | 3723 deopt_id(), |
| 3535 instance_call()->token_pos(), | 3724 instance_call()->token_pos(), |
| 3536 locs()); | 3725 locs()); |
| 3537 } | 3726 } |
| 3538 | 3727 |
| 3539 | 3728 |
| 3540 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3729 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
| 3541 UNREACHABLE(); | 3730 comparison()->InitializeLocationSummary(opt); |
| 3542 return NULL; | 3731 // Branches don't produce a result. |
| 3732 comparison()->locs()->set_out(Location::NoLocation()); |
| 3733 return comparison()->locs(); |
| 3543 } | 3734 } |
| 3544 | 3735 |
| 3545 | 3736 |
| 3546 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3737 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3547 __ TraceSimMsg("BranchInstr"); | 3738 __ TraceSimMsg("BranchInstr"); |
| 3548 comparison()->EmitBranchCode(compiler, this); | 3739 comparison()->EmitBranchCode(compiler, this); |
| 3549 } | 3740 } |
| 3550 | 3741 |
| 3551 | 3742 |
| 3552 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 3743 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
| 3553 const intptr_t kNumInputs = 1; | 3744 const intptr_t kNumInputs = 1; |
| 3554 const intptr_t kNumTemps = 0; | 3745 const intptr_t kNumTemps = 0; |
| 3555 LocationSummary* summary = | 3746 LocationSummary* summary = |
| 3556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3747 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3557 summary->set_in(0, Location::RequiresRegister()); | 3748 summary->set_in(0, Location::RequiresRegister()); |
| 3558 if (!IsNullCheck()) { | 3749 if (!IsNullCheck()) { |
| 3559 summary->AddTemp(Location::RequiresRegister()); | 3750 summary->AddTemp(Location::RequiresRegister()); |
| 3560 } | 3751 } |
| 3561 return summary; | 3752 return summary; |
| 3562 } | 3753 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3596 if (i == (num_checks - 1)) { | 3787 if (i == (num_checks - 1)) { |
| 3597 __ bne(CMPRES1, ZR, deopt); | 3788 __ bne(CMPRES1, ZR, deopt); |
| 3598 } else { | 3789 } else { |
| 3599 __ beq(CMPRES1, ZR, &is_ok); | 3790 __ beq(CMPRES1, ZR, &is_ok); |
| 3600 } | 3791 } |
| 3601 } | 3792 } |
| 3602 __ Bind(&is_ok); | 3793 __ Bind(&is_ok); |
| 3603 } | 3794 } |
| 3604 | 3795 |
| 3605 | 3796 |
| 3606 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 3797 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { |
| 3607 const intptr_t kNumInputs = 1; | 3798 const intptr_t kNumInputs = 1; |
| 3608 const intptr_t kNumTemps = 0; | 3799 const intptr_t kNumTemps = 0; |
| 3609 LocationSummary* summary = | 3800 LocationSummary* summary = |
| 3610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3801 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3611 summary->set_in(0, Location::RequiresRegister()); | 3802 summary->set_in(0, Location::RequiresRegister()); |
| 3612 return summary; | 3803 return summary; |
| 3613 } | 3804 } |
| 3614 | 3805 |
| 3615 | 3806 |
| 3616 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3807 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3617 __ TraceSimMsg("CheckSmiInstr"); | 3808 __ TraceSimMsg("CheckSmiInstr"); |
| 3618 Register value = locs()->in(0).reg(); | 3809 Register value = locs()->in(0).reg(); |
| 3619 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3810 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3620 kDeoptCheckSmi); | 3811 kDeoptCheckSmi); |
| 3621 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 3812 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 3622 __ bne(CMPRES1, ZR, deopt); | 3813 __ bne(CMPRES1, ZR, deopt); |
| 3623 } | 3814 } |
| 3624 | 3815 |
| 3625 | 3816 |
| 3626 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 3817 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
| 3627 const intptr_t kNumInputs = 2; | 3818 const intptr_t kNumInputs = 2; |
| 3628 const intptr_t kNumTemps = 0; | 3819 const intptr_t kNumTemps = 0; |
| 3629 LocationSummary* locs = | 3820 LocationSummary* locs = |
| 3630 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3631 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 3822 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 3632 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 3823 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 3633 return locs; | 3824 return locs; |
| 3634 } | 3825 } |
| 3635 | 3826 |
| 3636 | 3827 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3668 __ BranchUnsignedGreaterEqual( | 3859 __ BranchUnsignedGreaterEqual( |
| 3669 index, reinterpret_cast<int32_t>(length.raw()), deopt); | 3860 index, reinterpret_cast<int32_t>(length.raw()), deopt); |
| 3670 } else { | 3861 } else { |
| 3671 Register length = length_loc.reg(); | 3862 Register length = length_loc.reg(); |
| 3672 Register index = index_loc.reg(); | 3863 Register index = index_loc.reg(); |
| 3673 __ BranchUnsignedGreaterEqual(index, length, deopt); | 3864 __ BranchUnsignedGreaterEqual(index, length, deopt); |
| 3674 } | 3865 } |
| 3675 } | 3866 } |
| 3676 | 3867 |
| 3677 | 3868 |
| 3678 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 3869 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
| 3679 UNIMPLEMENTED(); | 3870 UNIMPLEMENTED(); |
| 3680 return NULL; | 3871 return NULL; |
| 3681 } | 3872 } |
| 3682 | 3873 |
| 3683 | 3874 |
| 3684 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3875 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3685 UNIMPLEMENTED(); | 3876 UNIMPLEMENTED(); |
| 3686 } | 3877 } |
| 3687 | 3878 |
| 3688 | 3879 |
| 3689 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { | 3880 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const { |
| 3690 UNIMPLEMENTED(); | 3881 UNIMPLEMENTED(); |
| 3691 return NULL; | 3882 return NULL; |
| 3692 } | 3883 } |
| 3693 | 3884 |
| 3694 | 3885 |
| 3695 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3886 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3696 UNIMPLEMENTED(); | 3887 UNIMPLEMENTED(); |
| 3697 } | 3888 } |
| 3698 | 3889 |
| 3699 | 3890 |
| 3700 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 3891 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
| 3701 UNIMPLEMENTED(); | 3892 UNIMPLEMENTED(); |
| 3702 return NULL; | 3893 return NULL; |
| 3703 } | 3894 } |
| 3704 | 3895 |
| 3705 | 3896 |
| 3706 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3897 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3707 UNIMPLEMENTED(); | 3898 UNIMPLEMENTED(); |
| 3708 } | 3899 } |
| 3709 | 3900 |
| 3710 | 3901 |
| 3711 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { | 3902 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
| 3712 UNIMPLEMENTED(); | 3903 UNIMPLEMENTED(); |
| 3713 return NULL; | 3904 return NULL; |
| 3714 } | 3905 } |
| 3715 | 3906 |
| 3716 | 3907 |
| 3717 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3908 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3718 UNIMPLEMENTED(); | 3909 UNIMPLEMENTED(); |
| 3719 } | 3910 } |
| 3720 | 3911 |
| 3721 | 3912 |
| 3722 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { | 3913 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
| 3723 UNIMPLEMENTED(); | 3914 UNIMPLEMENTED(); |
| 3724 return NULL; | 3915 return NULL; |
| 3725 } | 3916 } |
| 3726 | 3917 |
| 3727 | 3918 |
| 3728 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3919 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3729 UNIMPLEMENTED(); | 3920 UNIMPLEMENTED(); |
| 3730 } | 3921 } |
| 3731 | 3922 |
| 3732 | 3923 |
| 3733 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 3924 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const { |
| 3734 return new LocationSummary(0, 0, LocationSummary::kCall); | 3925 return new LocationSummary(0, 0, LocationSummary::kCall); |
| 3735 } | 3926 } |
| 3736 | 3927 |
| 3737 | 3928 |
| 3738 | 3929 |
| 3739 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3930 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3740 compiler->GenerateRuntimeCall(token_pos(), | 3931 compiler->GenerateRuntimeCall(token_pos(), |
| 3741 deopt_id(), | 3932 deopt_id(), |
| 3742 kThrowRuntimeEntry, | 3933 kThrowRuntimeEntry, |
| 3743 1, | 3934 1, |
| 3744 locs()); | 3935 locs()); |
| 3745 __ break_(0); | 3936 __ break_(0); |
| 3746 } | 3937 } |
| 3747 | 3938 |
| 3748 | 3939 |
| 3749 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 3940 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const { |
| 3750 return new LocationSummary(0, 0, LocationSummary::kCall); | 3941 return new LocationSummary(0, 0, LocationSummary::kCall); |
| 3751 } | 3942 } |
| 3752 | 3943 |
| 3753 | 3944 |
| 3754 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3945 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3755 compiler->SetNeedsStacktrace(catch_try_index()); | 3946 compiler->SetNeedsStacktrace(catch_try_index()); |
| 3756 compiler->GenerateRuntimeCall(token_pos(), | 3947 compiler->GenerateRuntimeCall(token_pos(), |
| 3757 deopt_id(), | 3948 deopt_id(), |
| 3758 kReThrowRuntimeEntry, | 3949 kReThrowRuntimeEntry, |
| 3759 2, | 3950 2, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3779 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 3970 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 3780 deopt_id_, | 3971 deopt_id_, |
| 3781 Scanner::kDummyTokenIndex); | 3972 Scanner::kDummyTokenIndex); |
| 3782 } | 3973 } |
| 3783 if (HasParallelMove()) { | 3974 if (HasParallelMove()) { |
| 3784 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 3975 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 3785 } | 3976 } |
| 3786 } | 3977 } |
| 3787 | 3978 |
| 3788 | 3979 |
| 3789 LocationSummary* GotoInstr::MakeLocationSummary() const { | 3980 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { |
| 3790 return new LocationSummary(0, 0, LocationSummary::kNoCall); | 3981 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
| 3791 } | 3982 } |
| 3792 | 3983 |
| 3793 | 3984 |
| 3794 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3985 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3795 __ TraceSimMsg("GotoInstr"); | 3986 __ TraceSimMsg("GotoInstr"); |
| 3796 if (!compiler->is_optimizing()) { | 3987 if (!compiler->is_optimizing()) { |
| 3797 compiler->EmitEdgeCounter(); | 3988 compiler->EmitEdgeCounter(); |
| 3798 // Add a deoptimization descriptor for deoptimizing instructions that | 3989 // Add a deoptimization descriptor for deoptimizing instructions that |
| 3799 // may be inserted before this instruction. On MIPS this descriptor | 3990 // may be inserted before this instruction. On MIPS this descriptor |
| 3800 // points after the edge counter code so that we can reuse the same | 3991 // points after the edge counter code so that we can reuse the same |
| 3801 // pattern matching code as at call sites, which matches backwards from | 3992 // pattern matching code as at call sites, which matches backwards from |
| 3802 // the end of the pattern. | 3993 // the end of the pattern. |
| 3803 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 3994 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 3804 GetDeoptId(), | 3995 GetDeoptId(), |
| 3805 Scanner::kDummyTokenIndex); | 3996 Scanner::kDummyTokenIndex); |
| 3806 } | 3997 } |
| 3807 if (HasParallelMove()) { | 3998 if (HasParallelMove()) { |
| 3808 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 3999 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 3809 } | 4000 } |
| 3810 | 4001 |
| 3811 // We can fall through if the successor is the next block in the list. | 4002 // We can fall through if the successor is the next block in the list. |
| 3812 // Otherwise, we need a jump. | 4003 // Otherwise, we need a jump. |
| 3813 if (!compiler->CanFallThroughTo(successor())) { | 4004 if (!compiler->CanFallThroughTo(successor())) { |
| 3814 __ b(compiler->GetJumpLabel(successor())); | 4005 __ b(compiler->GetJumpLabel(successor())); |
| 3815 } | 4006 } |
| 3816 } | 4007 } |
| 3817 | 4008 |
| 3818 | 4009 |
| 3819 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 4010 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
| 3820 return LocationSummary::Make(0, | 4011 return LocationSummary::Make(0, |
| 3821 Location::RequiresRegister(), | 4012 Location::RequiresRegister(), |
| 3822 LocationSummary::kNoCall); | 4013 LocationSummary::kNoCall); |
| 3823 } | 4014 } |
| 3824 | 4015 |
| 3825 | 4016 |
| 3826 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4017 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3827 __ mov(locs()->out().reg(), CTX); | 4018 __ mov(locs()->out().reg(), CTX); |
| 3828 } | 4019 } |
| 3829 | 4020 |
| 3830 | 4021 |
| 3831 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { | 4022 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
| 3832 const intptr_t kNumInputs = 2; | 4023 const intptr_t kNumInputs = 2; |
| 3833 const intptr_t kNumTemps = 0; | 4024 const intptr_t kNumTemps = 0; |
| 3834 if (needs_number_check()) { | 4025 if (needs_number_check()) { |
| 3835 LocationSummary* locs = | 4026 LocationSummary* locs = |
| 3836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4027 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3837 locs->set_in(0, Location::RegisterLocation(A0)); | 4028 locs->set_in(0, Location::RegisterLocation(A0)); |
| 3838 locs->set_in(1, Location::RegisterLocation(A1)); | 4029 locs->set_in(1, Location::RegisterLocation(A1)); |
| 3839 locs->set_out(Location::RegisterLocation(A0)); | 4030 locs->set_out(Location::RegisterLocation(A0)); |
| 3840 return locs; | 4031 return locs; |
| 3841 } | 4032 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3903 BranchInstr* branch) { | 4094 BranchInstr* branch) { |
| 3904 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); | 4095 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); |
| 3905 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4096 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 3906 | 4097 |
| 3907 BranchLabels labels = compiler->CreateBranchLabels(branch); | 4098 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3908 Condition true_condition = EmitComparisonCode(compiler, labels); | 4099 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3909 EmitBranchOnCondition(compiler, true_condition, labels); | 4100 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3910 } | 4101 } |
| 3911 | 4102 |
| 3912 | 4103 |
| 3913 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { | 4104 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
| 3914 return LocationSummary::Make(1, | 4105 return LocationSummary::Make(1, |
| 3915 Location::RequiresRegister(), | 4106 Location::RequiresRegister(), |
| 3916 LocationSummary::kNoCall); | 4107 LocationSummary::kNoCall); |
| 3917 } | 4108 } |
| 3918 | 4109 |
| 3919 | 4110 |
| 3920 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4111 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3921 Register value = locs()->in(0).reg(); | 4112 Register value = locs()->in(0).reg(); |
| 3922 Register result = locs()->out().reg(); | 4113 Register result = locs()->out().reg(); |
| 3923 | 4114 |
| 3924 __ LoadObject(result, Bool::True()); | 4115 __ LoadObject(result, Bool::True()); |
| 3925 __ LoadObject(TMP, Bool::False()); | 4116 __ LoadObject(TMP, Bool::False()); |
| 3926 __ subu(CMPRES1, value, result); | 4117 __ subu(CMPRES1, value, result); |
| 3927 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. | 4118 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. |
| 3928 } | 4119 } |
| 3929 | 4120 |
| 3930 | 4121 |
| 3931 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 4122 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const { |
| 3932 const intptr_t kNumInputs = 2; | 4123 const intptr_t kNumInputs = 2; |
| 3933 const intptr_t kNumTemps = 0; | 4124 const intptr_t kNumTemps = 0; |
| 3934 LocationSummary* locs = | 4125 LocationSummary* locs = |
| 3935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3936 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 4127 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 3937 : Location::RequiresRegister()); | 4128 : Location::RequiresRegister()); |
| 3938 locs->set_in(1, Location::RequiresRegister()); | 4129 locs->set_in(1, Location::RequiresRegister()); |
| 3939 return locs; | 4130 return locs; |
| 3940 } | 4131 } |
| 3941 | 4132 |
| 3942 | 4133 |
| 3943 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4134 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3944 Register value_reg = locs()->in(0).reg(); | 4135 Register value_reg = locs()->in(0).reg(); |
| 3945 Register dest_reg = locs()->in(1).reg(); | 4136 Register dest_reg = locs()->in(1).reg(); |
| 3946 | 4137 |
| 3947 if (value()->NeedsStoreBuffer()) { | 4138 if (value()->NeedsStoreBuffer()) { |
| 3948 __ StoreIntoObject(dest_reg, | 4139 __ StoreIntoObject(dest_reg, |
| 3949 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4140 FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
| 3950 } else { | 4141 } else { |
| 3951 __ StoreIntoObjectNoBarrier(dest_reg, | 4142 __ StoreIntoObjectNoBarrier(dest_reg, |
| 3952 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4143 FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
| 3953 } | 4144 } |
| 3954 } | 4145 } |
| 3955 | 4146 |
| 3956 | 4147 |
| 3957 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 4148 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
| 3958 return MakeCallSummary(); | 4149 return MakeCallSummary(); |
| 3959 } | 4150 } |
| 3960 | 4151 |
| 3961 | 4152 |
| 3962 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4153 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3963 __ TraceSimMsg("AllocateObjectInstr"); | 4154 __ TraceSimMsg("AllocateObjectInstr"); |
| 3964 __ Comment("AllocateObjectInstr"); | 4155 __ Comment("AllocateObjectInstr"); |
| 3965 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 4156 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
| 3966 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 4157 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
| 3967 compiler->GenerateCall(token_pos(), | 4158 compiler->GenerateCall(token_pos(), |
| 3968 &label, | 4159 &label, |
| 3969 PcDescriptors::kOther, | 4160 PcDescriptors::kOther, |
| 3970 locs()); | 4161 locs()); |
| 3971 __ Drop(ArgumentCount()); // Discard arguments. | 4162 __ Drop(ArgumentCount()); // Discard arguments. |
| 3972 } | 4163 } |
| 3973 | 4164 |
| 3974 | 4165 |
| 3975 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { | 4166 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const { |
| 3976 return MakeCallSummary(); | 4167 return MakeCallSummary(); |
| 3977 } | 4168 } |
| 3978 | 4169 |
| 3979 | 4170 |
| 3980 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4171 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3981 __ Comment("CreateClosureInstr"); | 4172 __ Comment("CreateClosureInstr"); |
| 3982 const Function& closure_function = function(); | 4173 const Function& closure_function = function(); |
| 3983 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); | 4174 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); |
| 3984 const Code& stub = Code::Handle( | 4175 const Code& stub = Code::Handle( |
| 3985 StubCode::GetAllocationStubForClosure(closure_function)); | 4176 StubCode::GetAllocationStubForClosure(closure_function)); |
| 3986 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 4177 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 3987 compiler->GenerateCall(token_pos(), | 4178 compiler->GenerateCall(token_pos(), |
| 3988 &label, | 4179 &label, |
| 3989 PcDescriptors::kOther, | 4180 PcDescriptors::kOther, |
| 3990 locs()); | 4181 locs()); |
| 3991 __ Drop(2); // Discard type arguments and receiver. | 4182 __ Drop(2); // Discard type arguments and receiver. |
| 3992 } | 4183 } |
| 3993 | 4184 |
| 3994 } // namespace dart | 4185 } // namespace dart |
| 3995 | 4186 |
| 3996 #endif // defined TARGET_ARCH_MIPS | 4187 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |