| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 R0. | 29 // on the stack and return the result in a fixed register R0. |
| 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(R0)); | 32 result->set_out(Location::RegisterLocation(R0)); |
| 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 if (compiler->is_optimizing()) { | 50 if (compiler->is_optimizing()) { |
| 51 Location value = locs()->in(0); | 51 Location value = locs()->in(0); |
| 52 if (value.IsRegister()) { | 52 if (value.IsRegister()) { |
| 53 __ Push(value.reg()); | 53 __ Push(value.reg()); |
| 54 } else if (value.IsConstant()) { | 54 } else if (value.IsConstant()) { |
| 55 __ PushObject(value.constant()); | 55 __ PushObject(value.constant()); |
| 56 } else { | 56 } else { |
| 57 ASSERT(value.IsStackSlot()); | 57 ASSERT(value.IsStackSlot()); |
| 58 const intptr_t value_offset = value.ToStackSlotOffset(); | 58 const intptr_t value_offset = value.ToStackSlotOffset(); |
| 59 __ LoadFromOffset(kWord, IP, FP, value_offset); | 59 __ LoadFromOffset(kWord, IP, FP, value_offset); |
| 60 __ Push(IP); | 60 __ Push(IP); |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 | 65 |
| 66 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 66 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { |
| 67 const intptr_t kNumInputs = 1; | 67 const intptr_t kNumInputs = 1; |
| 68 const intptr_t kNumTemps = 0; | 68 const intptr_t kNumTemps = 0; |
| 69 LocationSummary* locs = | 69 LocationSummary* locs = |
| 70 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 70 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 71 locs->set_in(0, Location::RegisterLocation(R0)); | 71 locs->set_in(0, Location::RegisterLocation(R0)); |
| 72 return locs; | 72 return locs; |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 // Attempt optimized compilation at return instruction instead of at the entry. | 76 // Attempt optimized compilation at return instruction instead of at the entry. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 // Detect pattern when one value is zero and another is a power of 2. | 131 // Detect pattern when one value is zero and another is a power of 2. |
| 132 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 132 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 133 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 133 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 134 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 134 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 135 } | 135 } |
| 136 | 136 |
| 137 | 137 |
| 138 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 138 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { |
| 139 return comparison()->MakeLocationSummary(); | 139 comparison()->InitializeLocationSummary(opt); |
| 140 return comparison()->locs(); |
| 140 } | 141 } |
| 141 | 142 |
| 142 | 143 |
| 143 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 144 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 144 const Register result = locs()->out().reg(); | 145 const Register result = locs()->out().reg(); |
| 145 | 146 |
| 146 Location left = locs()->in(0); | 147 Location left = locs()->in(0); |
| 147 Location right = locs()->in(1); | 148 Location right = locs()->in(1); |
| 148 ASSERT(!left.IsConstant() || !right.IsConstant()); | 149 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 149 | 150 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 const int32_t val = | 187 const int32_t val = |
| 187 Smi::RawValue(true_value) - Smi::RawValue(false_value); | 188 Smi::RawValue(true_value) - Smi::RawValue(false_value); |
| 188 __ AndImmediate(result, result, val); | 189 __ AndImmediate(result, result, val); |
| 189 if (false_value != 0) { | 190 if (false_value != 0) { |
| 190 __ AddImmediate(result, Smi::RawValue(false_value)); | 191 __ AddImmediate(result, Smi::RawValue(false_value)); |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 } | 194 } |
| 194 | 195 |
| 195 | 196 |
| 196 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 197 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
| 197 const intptr_t kNumInputs = 0; | 198 const intptr_t kNumInputs = 0; |
| 198 const intptr_t kNumTemps = 1; | 199 const intptr_t kNumTemps = 1; |
| 199 LocationSummary* result = | 200 LocationSummary* result = |
| 200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 201 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 201 result->set_out(Location::RegisterLocation(R0)); | 202 result->set_out(Location::RegisterLocation(R0)); |
| 202 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. | 203 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. |
| 203 return result; | 204 return result; |
| 204 } | 205 } |
| 205 | 206 |
| 206 | 207 |
| 207 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 208 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 208 // The arguments to the stub include the closure, as does the arguments | 209 // The arguments to the stub include the closure, as does the arguments |
| 209 // descriptor. | 210 // descriptor. |
| 210 Register temp_reg = locs()->temp(0).reg(); | 211 Register temp_reg = locs()->temp(0).reg(); |
| 211 int argument_count = ArgumentCount(); | 212 int argument_count = ArgumentCount(); |
| 212 const Array& arguments_descriptor = | 213 const Array& arguments_descriptor = |
| 213 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 214 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
| 214 argument_names())); | 215 argument_names())); |
| 215 __ LoadObject(temp_reg, arguments_descriptor); | 216 __ LoadObject(temp_reg, arguments_descriptor); |
| 216 ASSERT(temp_reg == R4); | 217 ASSERT(temp_reg == R4); |
| 217 compiler->GenerateDartCall(deopt_id(), | 218 compiler->GenerateDartCall(deopt_id(), |
| 218 token_pos(), | 219 token_pos(), |
| 219 &StubCode::CallClosureFunctionLabel(), | 220 &StubCode::CallClosureFunctionLabel(), |
| 220 PcDescriptors::kClosureCall, | 221 PcDescriptors::kClosureCall, |
| 221 locs()); | 222 locs()); |
| 222 __ Drop(argument_count); | 223 __ Drop(argument_count); |
| 223 } | 224 } |
| 224 | 225 |
| 225 | 226 |
| 226 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 227 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
| 227 return LocationSummary::Make(0, | 228 return LocationSummary::Make(0, |
| 228 Location::RequiresRegister(), | 229 Location::RequiresRegister(), |
| 229 LocationSummary::kNoCall); | 230 LocationSummary::kNoCall); |
| 230 } | 231 } |
| 231 | 232 |
| 232 | 233 |
| 233 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 234 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 234 Register result = locs()->out().reg(); | 235 Register result = locs()->out().reg(); |
| 235 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); | 236 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); |
| 236 } | 237 } |
| 237 | 238 |
| 238 | 239 |
| 239 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 240 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
| 240 return LocationSummary::Make(1, | 241 return LocationSummary::Make(1, |
| 241 Location::SameAsFirstInput(), | 242 Location::SameAsFirstInput(), |
| 242 LocationSummary::kNoCall); | 243 LocationSummary::kNoCall); |
| 243 } | 244 } |
| 244 | 245 |
| 245 | 246 |
| 246 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 247 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 247 Register value = locs()->in(0).reg(); | 248 Register value = locs()->in(0).reg(); |
| 248 Register result = locs()->out().reg(); | 249 Register result = locs()->out().reg(); |
| 249 ASSERT(result == value); // Assert that register assignment is correct. | 250 ASSERT(result == value); // Assert that register assignment is correct. |
| 250 __ str(value, Address(FP, local().index() * kWordSize)); | 251 __ str(value, Address(FP, local().index() * kWordSize)); |
| 251 } | 252 } |
| 252 | 253 |
| 253 | 254 |
| 254 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 255 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
| 255 return LocationSummary::Make(0, | 256 return LocationSummary::Make(0, |
| 256 Location::RequiresRegister(), | 257 Location::RequiresRegister(), |
| 257 LocationSummary::kNoCall); | 258 LocationSummary::kNoCall); |
| 258 } | 259 } |
| 259 | 260 |
| 260 | 261 |
| 261 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 262 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 262 // The register allocator drops constant definitions that have no uses. | 263 // The register allocator drops constant definitions that have no uses. |
| 263 if (!locs()->out().IsInvalid()) { | 264 if (!locs()->out().IsInvalid()) { |
| 264 Register result = locs()->out().reg(); | 265 Register result = locs()->out().reg(); |
| 265 __ LoadObject(result, value()); | 266 __ LoadObject(result, value()); |
| 266 } | 267 } |
| 267 } | 268 } |
| 268 | 269 |
| 269 | 270 |
| 270 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 271 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { |
| 271 const intptr_t kNumInputs = 3; | 272 const intptr_t kNumInputs = 3; |
| 272 const intptr_t kNumTemps = 0; | 273 const intptr_t kNumTemps = 0; |
| 273 LocationSummary* summary = | 274 LocationSummary* summary = |
| 274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 275 summary->set_in(0, Location::RegisterLocation(R0)); // Value. | 276 summary->set_in(0, Location::RegisterLocation(R0)); // Value. |
| 276 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. | 277 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. |
| 277 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. | 278 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. |
| 278 summary->set_out(Location::RegisterLocation(R0)); | 279 summary->set_out(Location::RegisterLocation(R0)); |
| 279 return summary; | 280 return summary; |
| 280 } | 281 } |
| 281 | 282 |
| 282 | 283 |
| 283 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 284 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { |
| 284 const intptr_t kNumInputs = 1; | 285 const intptr_t kNumInputs = 1; |
| 285 const intptr_t kNumTemps = 0; | 286 const intptr_t kNumTemps = 0; |
| 286 LocationSummary* locs = | 287 LocationSummary* locs = |
| 287 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 288 locs->set_in(0, Location::RegisterLocation(R0)); | 289 locs->set_in(0, Location::RegisterLocation(R0)); |
| 289 locs->set_out(Location::RegisterLocation(R0)); | 290 locs->set_out(Location::RegisterLocation(R0)); |
| 290 return locs; | 291 return locs; |
| 291 } | 292 } |
| 292 | 293 |
| 293 | 294 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 case Token::kGT: return GT; | 335 case Token::kGT: return GT; |
| 335 case Token::kLTE: return LE; | 336 case Token::kLTE: return LE; |
| 336 case Token::kGTE: return GE; | 337 case Token::kGTE: return GE; |
| 337 default: | 338 default: |
| 338 UNREACHABLE(); | 339 UNREACHABLE(); |
| 339 return VS; | 340 return VS; |
| 340 } | 341 } |
| 341 } | 342 } |
| 342 | 343 |
| 343 | 344 |
| 344 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 345 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
| 345 const intptr_t kNumInputs = 2; | 346 const intptr_t kNumInputs = 2; |
| 346 if (operation_cid() == kMintCid) { | 347 if (operation_cid() == kMintCid) { |
| 347 const intptr_t kNumTemps = 1; | 348 const intptr_t kNumTemps = 1; |
| 348 LocationSummary* locs = | 349 LocationSummary* locs = |
| 349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 350 locs->set_in(0, Location::RequiresFpuRegister()); | 351 locs->set_in(0, Location::RequiresFpuRegister()); |
| 351 locs->set_in(1, Location::RequiresFpuRegister()); | 352 locs->set_in(1, Location::RequiresFpuRegister()); |
| 352 locs->set_temp(0, Location::RequiresRegister()); | 353 locs->set_temp(0, Location::RequiresRegister()); |
| 353 locs->set_out(Location::RequiresRegister()); | 354 locs->set_out(Location::RequiresRegister()); |
| 354 return locs; | 355 return locs; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 | 532 |
| 532 if (operation_cid() == kDoubleCid) { | 533 if (operation_cid() == kDoubleCid) { |
| 533 Label* nan_result = (true_condition == NE) ? | 534 Label* nan_result = (true_condition == NE) ? |
| 534 labels.true_label : labels.false_label; | 535 labels.true_label : labels.false_label; |
| 535 __ b(nan_result, VS); | 536 __ b(nan_result, VS); |
| 536 } | 537 } |
| 537 EmitBranchOnCondition(compiler, true_condition, labels); | 538 EmitBranchOnCondition(compiler, true_condition, labels); |
| 538 } | 539 } |
| 539 | 540 |
| 540 | 541 |
| 541 LocationSummary* TestSmiInstr::MakeLocationSummary() const { | 542 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const { |
| 542 const intptr_t kNumInputs = 2; | 543 const intptr_t kNumInputs = 2; |
| 543 const intptr_t kNumTemps = 0; | 544 const intptr_t kNumTemps = 0; |
| 544 LocationSummary* locs = | 545 LocationSummary* locs = |
| 545 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 546 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 546 locs->set_in(0, Location::RequiresRegister()); | 547 locs->set_in(0, Location::RequiresRegister()); |
| 547 // Only one input can be a constant operand. The case of two constant | 548 // Only one input can be a constant operand. The case of two constant |
| 548 // operands should be handled by constant propagation. | 549 // operands should be handled by constant propagation. |
| 549 locs->set_in(1, Location::RegisterOrConstant(right())); | 550 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 550 return locs; | 551 return locs; |
| 551 } | 552 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 574 | 575 |
| 575 | 576 |
| 576 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 577 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 577 BranchInstr* branch) { | 578 BranchInstr* branch) { |
| 578 BranchLabels labels = compiler->CreateBranchLabels(branch); | 579 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 579 Condition true_condition = EmitComparisonCode(compiler, labels); | 580 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 580 EmitBranchOnCondition(compiler, true_condition, labels); | 581 EmitBranchOnCondition(compiler, true_condition, labels); |
| 581 } | 582 } |
| 582 | 583 |
| 583 | 584 |
| 584 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 585 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
| 585 const intptr_t kNumInputs = 2; | 586 const intptr_t kNumInputs = 2; |
| 586 const intptr_t kNumTemps = 0; | 587 const intptr_t kNumTemps = 0; |
| 587 if (operation_cid() == kMintCid) { | 588 if (operation_cid() == kMintCid) { |
| 588 const intptr_t kNumTemps = 2; | 589 const intptr_t kNumTemps = 2; |
| 589 LocationSummary* locs = | 590 LocationSummary* locs = |
| 590 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 591 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 591 locs->set_in(0, Location::RequiresFpuRegister()); | 592 locs->set_in(0, Location::RequiresFpuRegister()); |
| 592 locs->set_in(1, Location::RequiresFpuRegister()); | 593 locs->set_in(1, Location::RequiresFpuRegister()); |
| 593 locs->set_temp(0, Location::RequiresRegister()); | 594 locs->set_temp(0, Location::RequiresRegister()); |
| 594 locs->set_temp(1, Location::RequiresRegister()); | 595 locs->set_temp(1, Location::RequiresRegister()); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 | 658 |
| 658 if (operation_cid() == kDoubleCid) { | 659 if (operation_cid() == kDoubleCid) { |
| 659 Label* nan_result = (true_condition == NE) ? | 660 Label* nan_result = (true_condition == NE) ? |
| 660 labels.true_label : labels.false_label; | 661 labels.true_label : labels.false_label; |
| 661 __ b(nan_result, VS); | 662 __ b(nan_result, VS); |
| 662 } | 663 } |
| 663 EmitBranchOnCondition(compiler, true_condition, labels); | 664 EmitBranchOnCondition(compiler, true_condition, labels); |
| 664 } | 665 } |
| 665 | 666 |
| 666 | 667 |
| 667 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 668 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
| 668 const intptr_t kNumInputs = 0; | 669 const intptr_t kNumInputs = 0; |
| 669 const intptr_t kNumTemps = 3; | 670 const intptr_t kNumTemps = 3; |
| 670 LocationSummary* locs = | 671 LocationSummary* locs = |
| 671 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 672 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 672 locs->set_temp(0, Location::RegisterLocation(R1)); | 673 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 673 locs->set_temp(1, Location::RegisterLocation(R2)); | 674 locs->set_temp(1, Location::RegisterLocation(R2)); |
| 674 locs->set_temp(2, Location::RegisterLocation(R5)); | 675 locs->set_temp(2, Location::RegisterLocation(R5)); |
| 675 locs->set_out(Location::RegisterLocation(R0)); | 676 locs->set_out(Location::RegisterLocation(R0)); |
| 676 return locs; | 677 return locs; |
| 677 } | 678 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 __ LoadImmediate(R5, entry); | 713 __ LoadImmediate(R5, entry); |
| 713 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function())); | 714 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function())); |
| 714 compiler->GenerateCall(token_pos(), | 715 compiler->GenerateCall(token_pos(), |
| 715 stub_entry, | 716 stub_entry, |
| 716 PcDescriptors::kOther, | 717 PcDescriptors::kOther, |
| 717 locs()); | 718 locs()); |
| 718 __ Pop(result); | 719 __ Pop(result); |
| 719 } | 720 } |
| 720 | 721 |
| 721 | 722 |
| 722 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 723 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { |
| 723 const intptr_t kNumInputs = 1; | 724 const intptr_t kNumInputs = 1; |
| 724 // TODO(fschneider): Allow immediate operands for the char code. | 725 // TODO(fschneider): Allow immediate operands for the char code. |
| 725 return LocationSummary::Make(kNumInputs, | 726 return LocationSummary::Make(kNumInputs, |
| 726 Location::RequiresRegister(), | 727 Location::RequiresRegister(), |
| 727 LocationSummary::kNoCall); | 728 LocationSummary::kNoCall); |
| 728 } | 729 } |
| 729 | 730 |
| 730 | 731 |
| 731 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 732 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 732 Register char_code = locs()->in(0).reg(); | 733 Register char_code = locs()->in(0).reg(); |
| 733 Register result = locs()->out().reg(); | 734 Register result = locs()->out().reg(); |
| 734 __ LoadImmediate(result, | 735 __ LoadImmediate(result, |
| 735 reinterpret_cast<uword>(Symbols::PredefinedAddress())); | 736 reinterpret_cast<uword>(Symbols::PredefinedAddress())); |
| 736 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); | 737 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
| 737 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. | 738 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. |
| 738 } | 739 } |
| 739 | 740 |
| 740 | 741 |
| 741 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { | 742 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { |
| 742 const intptr_t kNumInputs = 1; | 743 const intptr_t kNumInputs = 1; |
| 743 const intptr_t kNumTemps = 0; | 744 const intptr_t kNumTemps = 0; |
| 744 LocationSummary* summary = | 745 LocationSummary* summary = |
| 745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 746 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 746 summary->set_in(0, Location::RegisterLocation(R0)); | 747 summary->set_in(0, Location::RegisterLocation(R0)); |
| 747 summary->set_out(Location::RegisterLocation(R0)); | 748 summary->set_out(Location::RegisterLocation(R0)); |
| 748 return summary; | 749 return summary; |
| 749 } | 750 } |
| 750 | 751 |
| 751 | 752 |
| 752 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 753 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 753 Register array = locs()->in(0).reg(); | 754 Register array = locs()->in(0).reg(); |
| 754 __ Push(array); | 755 __ Push(array); |
| 755 const int kNumberOfArguments = 1; | 756 const int kNumberOfArguments = 1; |
| 756 const Array& kNoArgumentNames = Object::null_array(); | 757 const Array& kNoArgumentNames = Object::null_array(); |
| 757 compiler->GenerateStaticCall(deopt_id(), | 758 compiler->GenerateStaticCall(deopt_id(), |
| 758 token_pos(), | 759 token_pos(), |
| 759 CallFunction(), | 760 CallFunction(), |
| 760 kNumberOfArguments, | 761 kNumberOfArguments, |
| 761 kNoArgumentNames, | 762 kNoArgumentNames, |
| 762 locs()); | 763 locs()); |
| 763 ASSERT(locs()->out().reg() == R0); | 764 ASSERT(locs()->out().reg() == R0); |
| 764 } | 765 } |
| 765 | 766 |
| 766 | 767 |
| 767 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 768 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
| 768 const intptr_t kNumInputs = 1; | 769 const intptr_t kNumInputs = 1; |
| 769 return LocationSummary::Make(kNumInputs, | 770 return LocationSummary::Make(kNumInputs, |
| 770 Location::RequiresRegister(), | 771 Location::RequiresRegister(), |
| 771 LocationSummary::kNoCall); | 772 LocationSummary::kNoCall); |
| 772 } | 773 } |
| 773 | 774 |
| 774 | 775 |
| 775 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 776 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 776 Register object = locs()->in(0).reg(); | 777 Register object = locs()->in(0).reg(); |
| 777 Register result = locs()->out().reg(); | 778 Register result = locs()->out().reg(); |
| 778 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); | 779 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); |
| 779 } | 780 } |
| 780 | 781 |
| 781 | 782 |
| 782 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { | 783 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { |
| 783 const intptr_t kNumInputs = 1; | 784 const intptr_t kNumInputs = 1; |
| 784 return LocationSummary::Make(kNumInputs, | 785 return LocationSummary::Make(kNumInputs, |
| 785 Location::RequiresRegister(), | 786 Location::RequiresRegister(), |
| 786 LocationSummary::kNoCall); | 787 LocationSummary::kNoCall); |
| 787 } | 788 } |
| 788 | 789 |
| 789 | 790 |
| 790 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 791 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 791 Register object = locs()->in(0).reg(); | 792 Register object = locs()->in(0).reg(); |
| 792 Register result = locs()->out().reg(); | 793 Register result = locs()->out().reg(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 return kUnboxedInt32x4; | 869 return kUnboxedInt32x4; |
| 869 case kTypedDataFloat32x4ArrayCid: | 870 case kTypedDataFloat32x4ArrayCid: |
| 870 return kUnboxedFloat32x4; | 871 return kUnboxedFloat32x4; |
| 871 default: | 872 default: |
| 872 UNREACHABLE(); | 873 UNREACHABLE(); |
| 873 return kTagged; | 874 return kTagged; |
| 874 } | 875 } |
| 875 } | 876 } |
| 876 | 877 |
| 877 | 878 |
| 878 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 879 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
| 879 const intptr_t kNumInputs = 2; | 880 const intptr_t kNumInputs = 2; |
| 880 const intptr_t kNumTemps = 0; | 881 const intptr_t kNumTemps = 0; |
| 881 LocationSummary* locs = | 882 LocationSummary* locs = |
| 882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 883 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 883 locs->set_in(0, Location::RequiresRegister()); | 884 locs->set_in(0, Location::RequiresRegister()); |
| 884 // The smi index is either untagged (element size == 1), or it is left smi | 885 // The smi index is either untagged (element size == 1), or it is left smi |
| 885 // tagged (for all element sizes > 1). | 886 // tagged (for all element sizes > 1). |
| 886 // TODO(regis): Revisit and see if the index can be immediate. | 887 // TODO(regis): Revisit and see if the index can be immediate. |
| 887 locs->set_in(1, Location::WritableRegister()); | 888 locs->set_in(1, Location::WritableRegister()); |
| 888 if ((representation() == kUnboxedDouble) || | 889 if ((representation() == kUnboxedDouble) || |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 return kUnboxedFloat32x4; | 1054 return kUnboxedFloat32x4; |
| 1054 case kTypedDataInt32x4ArrayCid: | 1055 case kTypedDataInt32x4ArrayCid: |
| 1055 return kUnboxedInt32x4; | 1056 return kUnboxedInt32x4; |
| 1056 default: | 1057 default: |
| 1057 UNREACHABLE(); | 1058 UNREACHABLE(); |
| 1058 return kTagged; | 1059 return kTagged; |
| 1059 } | 1060 } |
| 1060 } | 1061 } |
| 1061 | 1062 |
| 1062 | 1063 |
| 1063 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1064 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
| 1064 const intptr_t kNumInputs = 3; | 1065 const intptr_t kNumInputs = 3; |
| 1065 const intptr_t kNumTemps = 0; | 1066 const intptr_t kNumTemps = 0; |
| 1066 LocationSummary* locs = | 1067 LocationSummary* locs = |
| 1067 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1068 locs->set_in(0, Location::RequiresRegister()); | 1069 locs->set_in(0, Location::RequiresRegister()); |
| 1069 // The smi index is either untagged (element size == 1), or it is left smi | 1070 // The smi index is either untagged (element size == 1), or it is left smi |
| 1070 // tagged (for all element sizes > 1). | 1071 // tagged (for all element sizes > 1). |
| 1071 // TODO(regis): Revisit and see if the index can be immediate. | 1072 // TODO(regis): Revisit and see if the index can be immediate. |
| 1072 locs->set_in(1, Location::WritableRegister()); | 1073 locs->set_in(1, Location::WritableRegister()); |
| 1073 switch (class_id()) { | 1074 switch (class_id()) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 __ StoreDToOffset(din0, index.reg(), 0); | 1241 __ StoreDToOffset(din0, index.reg(), 0); |
| 1241 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1242 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); |
| 1242 break; | 1243 break; |
| 1243 } | 1244 } |
| 1244 default: | 1245 default: |
| 1245 UNREACHABLE(); | 1246 UNREACHABLE(); |
| 1246 } | 1247 } |
| 1247 } | 1248 } |
| 1248 | 1249 |
| 1249 | 1250 |
| 1250 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1251 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
| 1251 const intptr_t kNumInputs = 1; | 1252 const intptr_t kNumInputs = 1; |
| 1252 LocationSummary* summary = | 1253 LocationSummary* summary = |
| 1253 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1254 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| 1254 summary->set_in(0, Location::RequiresRegister()); | 1255 summary->set_in(0, Location::RequiresRegister()); |
| 1255 const bool field_has_length = field().needs_length_check(); | 1256 const bool field_has_length = field().needs_length_check(); |
| 1256 summary->AddTemp(Location::RequiresRegister()); | 1257 summary->AddTemp(Location::RequiresRegister()); |
| 1257 summary->AddTemp(Location::RequiresRegister()); | 1258 summary->AddTemp(Location::RequiresRegister()); |
| 1258 const bool need_field_temp_reg = | 1259 const bool need_field_temp_reg = |
| 1259 field_has_length || (field().guarded_cid() == kIllegalCid); | 1260 field_has_length || (field().guarded_cid() == kIllegalCid); |
| 1260 if (need_field_temp_reg) { | 1261 if (need_field_temp_reg) { |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 __ b(fail, NE); | 1566 __ b(fail, NE); |
| 1566 } else { | 1567 } else { |
| 1567 UNREACHABLE(); | 1568 UNREACHABLE(); |
| 1568 } | 1569 } |
| 1569 } | 1570 } |
| 1570 } | 1571 } |
| 1571 __ Bind(&ok); | 1572 __ Bind(&ok); |
| 1572 } | 1573 } |
| 1573 | 1574 |
| 1574 | 1575 |
| 1575 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1576 class StoreInstanceFieldSlowPath : public SlowPathCode { |
| 1577 public: |
| 1578 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) |
| 1579 : instruction_(instruction) { } |
| 1580 |
| 1581 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1582 __ Comment("StoreInstanceFieldSlowPath"); |
| 1583 __ Bind(entry_label()); |
| 1584 const Class& double_class = compiler->double_class(); |
| 1585 const Code& stub = |
| 1586 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1587 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1588 |
| 1589 LocationSummary* locs = instruction_->locs(); |
| 1590 locs->live_registers()->Remove(locs->out()); |
| 1591 |
| 1592 compiler->SaveLiveRegisters(locs); |
| 1593 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1594 &label, |
| 1595 PcDescriptors::kOther, |
| 1596 locs); |
| 1597 __ MoveRegister(locs->temp(0).reg(), R0); |
| 1598 compiler->RestoreLiveRegisters(locs); |
| 1599 |
| 1600 __ b(exit_label()); |
| 1601 } |
| 1602 |
| 1603 private: |
| 1604 StoreInstanceFieldInstr* instruction_; |
| 1605 }; |
| 1606 |
| 1607 |
| 1608 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { |
| 1576 const intptr_t kNumInputs = 2; | 1609 const intptr_t kNumInputs = 2; |
| 1577 const intptr_t kNumTemps = 0; | 1610 const intptr_t kNumTemps = 0; |
| 1578 LocationSummary* summary = | 1611 LocationSummary* summary = |
| 1579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1612 new LocationSummary(kNumInputs, kNumTemps, |
| 1613 (field().guarded_cid() == kIllegalCid) || (is_initialization_) |
| 1614 ? LocationSummary::kCallOnSlowPath |
| 1615 : LocationSummary::kNoCall); |
| 1616 |
| 1580 summary->set_in(0, Location::RequiresRegister()); | 1617 summary->set_in(0, Location::RequiresRegister()); |
| 1581 summary->set_in(1, ShouldEmitStoreBarrier() | 1618 if (IsUnboxedStore() && opt) { |
| 1619 summary->set_in(1, Location::RequiresFpuRegister()); |
| 1620 summary->AddTemp(Location::RequiresRegister()); |
| 1621 summary->AddTemp(Location::RequiresRegister()); |
| 1622 } else if (IsPotentialUnboxedStore()) { |
| 1623 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1624 ? Location::WritableRegister() |
| 1625 : Location::RequiresRegister()); |
| 1626 summary->AddTemp(Location::RequiresRegister()); |
| 1627 summary->AddTemp(Location::RequiresRegister()); |
| 1628 summary->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1629 : Location::FpuRegisterLocation(Q1)); |
| 1630 } else { |
| 1631 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1582 ? Location::WritableRegister() | 1632 ? Location::WritableRegister() |
| 1583 : Location::RegisterOrConstant(value())); | 1633 : Location::RegisterOrConstant(value())); |
| 1634 } |
| 1584 return summary; | 1635 return summary; |
| 1585 } | 1636 } |
| 1586 | 1637 |
| 1587 | 1638 |
| 1588 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1639 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1640 Label skip_store; |
| 1641 |
| 1589 Register instance_reg = locs()->in(0).reg(); | 1642 Register instance_reg = locs()->in(0).reg(); |
| 1643 |
| 1644 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1645 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 1646 Register temp = locs()->temp(0).reg(); |
| 1647 Register temp2 = locs()->temp(1).reg(); |
| 1648 |
| 1649 if (is_initialization_) { |
| 1650 StoreInstanceFieldSlowPath* slow_path = |
| 1651 new StoreInstanceFieldSlowPath(this); |
| 1652 compiler->AddSlowPathCode(slow_path); |
| 1653 __ TryAllocate(compiler->double_class(), |
| 1654 slow_path->entry_label(), |
| 1655 temp); |
| 1656 __ Bind(slow_path->exit_label()); |
| 1657 __ MoveRegister(temp2, temp); |
| 1658 __ StoreIntoObject(instance_reg, |
| 1659 FieldAddress(instance_reg, field().Offset()), |
| 1660 temp2); |
| 1661 } else { |
| 1662 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); |
| 1663 } |
| 1664 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1665 return; |
| 1666 } |
| 1667 |
| 1668 if (IsPotentialUnboxedStore()) { |
| 1669 Register value_reg = locs()->in(1).reg(); |
| 1670 Register temp = locs()->temp(0).reg(); |
| 1671 Register temp2 = locs()->temp(1).reg(); |
| 1672 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); |
| 1673 |
| 1674 Label store_pointer, copy_payload; |
| 1675 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1676 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1677 __ CompareImmediate(temp2, kDoubleCid); |
| 1678 __ b(&store_pointer, NE); |
| 1679 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1680 __ CompareImmediate(temp2, kNullCid); |
| 1681 __ b(&store_pointer, EQ); |
| 1682 |
| 1683 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); |
| 1684 __ CompareImmediate(temp, |
| 1685 reinterpret_cast<intptr_t>(Object::null())); |
| 1686 __ b(©_payload, NE); |
| 1687 |
| 1688 StoreInstanceFieldSlowPath* slow_path = |
| 1689 new StoreInstanceFieldSlowPath(this); |
| 1690 compiler->AddSlowPathCode(slow_path); |
| 1691 |
| 1692 if (!compiler->is_optimizing()) { |
| 1693 locs()->live_registers()->Add(locs()->in(0)); |
| 1694 locs()->live_registers()->Add(locs()->in(1)); |
| 1695 } |
| 1696 |
| 1697 __ TryAllocate(compiler->double_class(), |
| 1698 slow_path->entry_label(), |
| 1699 temp); |
| 1700 __ Bind(slow_path->exit_label()); |
| 1701 __ MoveRegister(temp2, temp); |
| 1702 __ StoreIntoObject(instance_reg, |
| 1703 FieldAddress(instance_reg, field().Offset()), |
| 1704 temp2); |
| 1705 __ Bind(©_payload); |
| 1706 __ LoadDFromOffset(fpu_temp, |
| 1707 value_reg, |
| 1708 Double::value_offset() - kHeapObjectTag); |
| 1709 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); |
| 1710 __ b(&skip_store); |
| 1711 __ Bind(&store_pointer); |
| 1712 } |
| 1713 |
| 1590 if (ShouldEmitStoreBarrier()) { | 1714 if (ShouldEmitStoreBarrier()) { |
| 1591 Register value_reg = locs()->in(1).reg(); | 1715 Register value_reg = locs()->in(1).reg(); |
| 1592 __ StoreIntoObject(instance_reg, | 1716 __ StoreIntoObject(instance_reg, |
| 1593 FieldAddress(instance_reg, field().Offset()), | 1717 FieldAddress(instance_reg, field().Offset()), |
| 1594 value_reg, | 1718 value_reg, |
| 1595 CanValueBeSmi()); | 1719 CanValueBeSmi()); |
| 1596 } else { | 1720 } else { |
| 1597 if (locs()->in(1).IsConstant()) { | 1721 if (locs()->in(1).IsConstant()) { |
| 1598 __ StoreIntoObjectNoBarrier( | 1722 __ StoreIntoObjectNoBarrier( |
| 1599 instance_reg, | 1723 instance_reg, |
| 1600 FieldAddress(instance_reg, field().Offset()), | 1724 FieldAddress(instance_reg, field().Offset()), |
| 1601 locs()->in(1).constant()); | 1725 locs()->in(1).constant()); |
| 1602 } else { | 1726 } else { |
| 1603 Register value_reg = locs()->in(1).reg(); | 1727 Register value_reg = locs()->in(1).reg(); |
| 1604 __ StoreIntoObjectNoBarrier(instance_reg, | 1728 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1605 FieldAddress(instance_reg, field().Offset()), value_reg); | 1729 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1606 } | 1730 } |
| 1607 } | 1731 } |
| 1732 __ Bind(&skip_store); |
| 1608 } | 1733 } |
| 1609 | 1734 |
| 1610 | 1735 |
| 1611 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 1736 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1612 const intptr_t kNumInputs = 1; | 1737 const intptr_t kNumInputs = 1; |
| 1613 const intptr_t kNumTemps = 0; | 1738 const intptr_t kNumTemps = 0; |
| 1614 LocationSummary* summary = | 1739 LocationSummary* summary = |
| 1615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1740 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1616 summary->set_in(0, Location::RequiresRegister()); | 1741 summary->set_in(0, Location::RequiresRegister()); |
| 1617 summary->set_out(Location::RequiresRegister()); | 1742 summary->set_out(Location::RequiresRegister()); |
| 1618 return summary; | 1743 return summary; |
| 1619 } | 1744 } |
| 1620 | 1745 |
| 1621 | 1746 |
| 1622 // When the parser is building an implicit static getter for optimization, | 1747 // When the parser is building an implicit static getter for optimization, |
| 1623 // it can generate a function body where deoptimization ids do not line up | 1748 // it can generate a function body where deoptimization ids do not line up |
| 1624 // with the unoptimized code. | 1749 // with the unoptimized code. |
| 1625 // | 1750 // |
| 1626 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. | 1751 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. |
| 1627 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1752 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1628 Register field = locs()->in(0).reg(); | 1753 Register field = locs()->in(0).reg(); |
| 1629 Register result = locs()->out().reg(); | 1754 Register result = locs()->out().reg(); |
| 1630 __ LoadFromOffset(kWord, result, | 1755 __ LoadFromOffset(kWord, result, |
| 1631 field, Field::value_offset() - kHeapObjectTag); | 1756 field, Field::value_offset() - kHeapObjectTag); |
| 1632 } | 1757 } |
| 1633 | 1758 |
| 1634 | 1759 |
| 1635 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1760 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1636 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1761 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1637 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 1762 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 1638 : Location::RequiresRegister()); | 1763 : Location::RequiresRegister()); |
| 1639 locs->set_temp(0, Location::RequiresRegister()); | 1764 locs->set_temp(0, Location::RequiresRegister()); |
| 1640 return locs; | 1765 return locs; |
| 1641 } | 1766 } |
| 1642 | 1767 |
| 1643 | 1768 |
| 1644 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1769 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1645 Register value = locs()->in(0).reg(); | 1770 Register value = locs()->in(0).reg(); |
| 1646 Register temp = locs()->temp(0).reg(); | 1771 Register temp = locs()->temp(0).reg(); |
| 1647 | 1772 |
| 1648 __ LoadObject(temp, field()); | 1773 __ LoadObject(temp, field()); |
| 1649 if (this->value()->NeedsStoreBuffer()) { | 1774 if (this->value()->NeedsStoreBuffer()) { |
| 1650 __ StoreIntoObject(temp, | 1775 __ StoreIntoObject(temp, |
| 1651 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); | 1776 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); |
| 1652 } else { | 1777 } else { |
| 1653 __ StoreIntoObjectNoBarrier( | 1778 __ StoreIntoObjectNoBarrier( |
| 1654 temp, FieldAddress(temp, Field::value_offset()), value); | 1779 temp, FieldAddress(temp, Field::value_offset()), value); |
| 1655 } | 1780 } |
| 1656 } | 1781 } |
| 1657 | 1782 |
| 1658 | 1783 |
| 1659 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1784 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { |
| 1660 const intptr_t kNumInputs = 3; | 1785 const intptr_t kNumInputs = 3; |
| 1661 const intptr_t kNumTemps = 0; | 1786 const intptr_t kNumTemps = 0; |
| 1662 LocationSummary* summary = | 1787 LocationSummary* summary = |
| 1663 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1788 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1664 summary->set_in(0, Location::RegisterLocation(R0)); | 1789 summary->set_in(0, Location::RegisterLocation(R0)); |
| 1665 summary->set_in(1, Location::RegisterLocation(R2)); | 1790 summary->set_in(1, Location::RegisterLocation(R2)); |
| 1666 summary->set_in(2, Location::RegisterLocation(R1)); | 1791 summary->set_in(2, Location::RegisterLocation(R1)); |
| 1667 summary->set_out(Location::RegisterLocation(R0)); | 1792 summary->set_out(Location::RegisterLocation(R0)); |
| 1668 return summary; | 1793 return summary; |
| 1669 } | 1794 } |
| 1670 | 1795 |
| 1671 | 1796 |
| 1672 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1797 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1673 ASSERT(locs()->in(0).reg() == R0); // Value. | 1798 ASSERT(locs()->in(0).reg() == R0); // Value. |
| 1674 ASSERT(locs()->in(1).reg() == R2); // Instantiator. | 1799 ASSERT(locs()->in(1).reg() == R2); // Instantiator. |
| 1675 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. | 1800 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. |
| 1676 | 1801 |
| 1677 compiler->GenerateInstanceOf(token_pos(), | 1802 compiler->GenerateInstanceOf(token_pos(), |
| 1678 deopt_id(), | 1803 deopt_id(), |
| 1679 type(), | 1804 type(), |
| 1680 negate_result(), | 1805 negate_result(), |
| 1681 locs()); | 1806 locs()); |
| 1682 ASSERT(locs()->out().reg() == R0); | 1807 ASSERT(locs()->out().reg() == R0); |
| 1683 } | 1808 } |
| 1684 | 1809 |
| 1685 | 1810 |
| 1686 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1811 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
| 1687 const intptr_t kNumInputs = 1; | 1812 const intptr_t kNumInputs = 1; |
| 1688 const intptr_t kNumTemps = 0; | 1813 const intptr_t kNumTemps = 0; |
| 1689 LocationSummary* locs = | 1814 LocationSummary* locs = |
| 1690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1815 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1691 locs->set_in(0, Location::RegisterLocation(R1)); | 1816 locs->set_in(0, Location::RegisterLocation(R1)); |
| 1692 locs->set_out(Location::RegisterLocation(R0)); | 1817 locs->set_out(Location::RegisterLocation(R0)); |
| 1693 return locs; | 1818 return locs; |
| 1694 } | 1819 } |
| 1695 | 1820 |
| 1696 | 1821 |
| 1697 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1822 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1698 // Allocate the array. R2 = length, R1 = element type. | 1823 // Allocate the array. R2 = length, R1 = element type. |
| 1699 ASSERT(locs()->in(0).reg() == R1); | 1824 ASSERT(locs()->in(0).reg() == R1); |
| 1700 __ LoadImmediate(R2, Smi::RawValue(num_elements())); | 1825 __ LoadImmediate(R2, Smi::RawValue(num_elements())); |
| 1701 compiler->GenerateCall(token_pos(), | 1826 compiler->GenerateCall(token_pos(), |
| 1702 &StubCode::AllocateArrayLabel(), | 1827 &StubCode::AllocateArrayLabel(), |
| 1703 PcDescriptors::kOther, | 1828 PcDescriptors::kOther, |
| 1704 locs()); | 1829 locs()); |
| 1705 ASSERT(locs()->out().reg() == R0); | 1830 ASSERT(locs()->out().reg() == R0); |
| 1706 } | 1831 } |
| 1707 | 1832 |
| 1708 | 1833 |
| 1709 LocationSummary* | 1834 LocationSummary* |
| 1710 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1835 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const { |
| 1711 return MakeCallSummary(); | 1836 return MakeCallSummary(); |
| 1712 } | 1837 } |
| 1713 | 1838 |
| 1714 | 1839 |
| 1715 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1840 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
| 1716 FlowGraphCompiler* compiler) { | 1841 FlowGraphCompiler* compiler) { |
| 1717 compiler->GenerateRuntimeCall(token_pos(), | 1842 compiler->GenerateRuntimeCall(token_pos(), |
| 1718 deopt_id(), | 1843 deopt_id(), |
| 1719 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1844 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1720 3, | 1845 3, |
| 1721 locs()); | 1846 locs()); |
| 1722 __ Drop(3); | 1847 __ Drop(3); |
| 1723 ASSERT(locs()->out().reg() == R0); | 1848 ASSERT(locs()->out().reg() == R0); |
| 1724 __ Pop(R0); // Pop new instance. | 1849 __ Pop(R0); // Pop new instance. |
| 1725 } | 1850 } |
| 1726 | 1851 |
| 1727 | 1852 |
| 1728 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 1853 class BoxDoubleSlowPath : public SlowPathCode { |
| 1729 return LocationSummary::Make(1, | 1854 public: |
| 1730 Location::RequiresRegister(), | 1855 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 1731 LocationSummary::kNoCall); | 1856 : instruction_(instruction) { } |
| 1857 |
| 1858 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1859 __ Comment("BoxDoubleSlowPath"); |
| 1860 __ Bind(entry_label()); |
| 1861 const Class& double_class = compiler->double_class(); |
| 1862 const Code& stub = |
| 1863 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1864 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1865 |
| 1866 LocationSummary* locs = instruction_->locs(); |
| 1867 locs->live_registers()->Remove(locs->out()); |
| 1868 |
| 1869 compiler->SaveLiveRegisters(locs); |
| 1870 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1871 &label, |
| 1872 PcDescriptors::kOther, |
| 1873 locs); |
| 1874 __ MoveRegister(locs->out().reg(), R0); |
| 1875 compiler->RestoreLiveRegisters(locs); |
| 1876 |
| 1877 __ b(exit_label()); |
| 1878 } |
| 1879 |
| 1880 private: |
| 1881 Instruction* instruction_; |
| 1882 }; |
| 1883 |
| 1884 |
| 1885 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 1886 const intptr_t kNumInputs = 1; |
| 1887 const intptr_t kNumTemps = 0; |
| 1888 LocationSummary* locs = |
| 1889 new LocationSummary( |
| 1890 kNumInputs, kNumTemps, |
| 1891 (opt && !IsPotentialUnboxedLoad()) |
| 1892 ? LocationSummary::kNoCall |
| 1893 : LocationSummary::kCallOnSlowPath); |
| 1894 |
| 1895 locs->set_in(0, Location::RequiresRegister()); |
| 1896 |
| 1897 if (IsUnboxedLoad() && opt) { |
| 1898 locs->AddTemp(Location::RequiresRegister()); |
| 1899 } else if (IsPotentialUnboxedLoad()) { |
| 1900 locs->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1901 : Location::FpuRegisterLocation(Q1)); |
| 1902 locs->AddTemp(Location::RequiresRegister()); |
| 1903 } |
| 1904 locs->set_out(Location::RequiresRegister()); |
| 1905 return locs; |
| 1732 } | 1906 } |
| 1733 | 1907 |
| 1734 | 1908 |
| 1735 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1909 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1736 Register instance_reg = locs()->in(0).reg(); | 1910 Register instance_reg = locs()->in(0).reg(); |
| 1911 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 1912 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 1913 Register temp = locs()->temp(0).reg(); |
| 1914 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1915 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| 1916 return; |
| 1917 } |
| 1918 |
| 1919 Label done; |
| 1737 Register result_reg = locs()->out().reg(); | 1920 Register result_reg = locs()->out().reg(); |
| 1921 if (IsPotentialUnboxedLoad()) { |
| 1922 Register temp = locs()->temp(1).reg(); |
| 1923 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |
| 1738 | 1924 |
| 1925 Label load_pointer; |
| 1926 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 1927 |
| 1928 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 1929 FieldAddress field_nullability_operand(result_reg, |
| 1930 Field::is_nullable_offset()); |
| 1931 |
| 1932 __ ldr(temp, field_cid_operand); |
| 1933 __ CompareImmediate(temp, kDoubleCid); |
| 1934 __ b(&load_pointer, NE); |
| 1935 |
| 1936 __ ldr(temp, field_nullability_operand); |
| 1937 __ CompareImmediate(temp, kNullCid); |
| 1938 __ b(&load_pointer, EQ); |
| 1939 |
| 1940 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1941 compiler->AddSlowPathCode(slow_path); |
| 1942 |
| 1943 if (!compiler->is_optimizing()) { |
| 1944 locs()->live_registers()->Add(locs()->in(0)); |
| 1945 } |
| 1946 |
| 1947 __ TryAllocate(compiler->double_class(), |
| 1948 slow_path->entry_label(), |
| 1949 result_reg); |
| 1950 __ Bind(slow_path->exit_label()); |
| 1951 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1952 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1953 __ StoreDToOffset(value, |
| 1954 result_reg, |
| 1955 Double::value_offset() - kHeapObjectTag); |
| 1956 __ b(&done); |
| 1957 __ Bind(&load_pointer); |
| 1958 } |
| 1739 __ LoadFromOffset(kWord, result_reg, | 1959 __ LoadFromOffset(kWord, result_reg, |
| 1740 instance_reg, offset_in_bytes() - kHeapObjectTag); | 1960 instance_reg, offset_in_bytes() - kHeapObjectTag); |
| 1961 __ Bind(&done); |
| 1741 } | 1962 } |
| 1742 | 1963 |
| 1743 | 1964 |
| 1744 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { | 1965 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
| 1745 const intptr_t kNumInputs = 1; | 1966 const intptr_t kNumInputs = 1; |
| 1746 const intptr_t kNumTemps = 0; | 1967 const intptr_t kNumTemps = 0; |
| 1747 LocationSummary* locs = | 1968 LocationSummary* locs = |
| 1748 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1969 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1749 locs->set_in(0, Location::RegisterLocation(R0)); | 1970 locs->set_in(0, Location::RegisterLocation(R0)); |
| 1750 locs->set_out(Location::RegisterLocation(R0)); | 1971 locs->set_out(Location::RegisterLocation(R0)); |
| 1751 return locs; | 1972 return locs; |
| 1752 } | 1973 } |
| 1753 | 1974 |
| 1754 | 1975 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1766 deopt_id(), | 1987 deopt_id(), |
| 1767 kInstantiateTypeRuntimeEntry, | 1988 kInstantiateTypeRuntimeEntry, |
| 1768 2, | 1989 2, |
| 1769 locs()); | 1990 locs()); |
| 1770 __ Drop(2); // Drop instantiator and uninstantiated type. | 1991 __ Drop(2); // Drop instantiator and uninstantiated type. |
| 1771 __ Pop(result_reg); // Pop instantiated type. | 1992 __ Pop(result_reg); // Pop instantiated type. |
| 1772 ASSERT(instantiator_reg == result_reg); | 1993 ASSERT(instantiator_reg == result_reg); |
| 1773 } | 1994 } |
| 1774 | 1995 |
| 1775 | 1996 |
| 1776 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 1997 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 1998 bool opt) const { |
| 1777 const intptr_t kNumInputs = 1; | 1999 const intptr_t kNumInputs = 1; |
| 1778 const intptr_t kNumTemps = 0; | 2000 const intptr_t kNumTemps = 0; |
| 1779 LocationSummary* locs = | 2001 LocationSummary* locs = |
| 1780 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1781 locs->set_in(0, Location::RegisterLocation(R0)); | 2003 locs->set_in(0, Location::RegisterLocation(R0)); |
| 1782 locs->set_out(Location::RegisterLocation(R0)); | 2004 locs->set_out(Location::RegisterLocation(R0)); |
| 1783 return locs; | 2005 return locs; |
| 1784 } | 2006 } |
| 1785 | 2007 |
| 1786 | 2008 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1815 2, | 2037 2, |
| 1816 locs()); | 2038 locs()); |
| 1817 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2039 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| 1818 __ Pop(result_reg); // Pop instantiated type arguments. | 2040 __ Pop(result_reg); // Pop instantiated type arguments. |
| 1819 __ Bind(&type_arguments_instantiated); | 2041 __ Bind(&type_arguments_instantiated); |
| 1820 ASSERT(instantiator_reg == result_reg); | 2042 ASSERT(instantiator_reg == result_reg); |
| 1821 } | 2043 } |
| 1822 | 2044 |
| 1823 | 2045 |
| 1824 LocationSummary* | 2046 LocationSummary* |
| 1825 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2047 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const { |
| 1826 const intptr_t kNumInputs = 1; | 2048 const intptr_t kNumInputs = 1; |
| 1827 const intptr_t kNumTemps = 0; | 2049 const intptr_t kNumTemps = 0; |
| 1828 LocationSummary* locs = | 2050 LocationSummary* locs = |
| 1829 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1830 locs->set_in(0, Location::RequiresRegister()); | 2052 locs->set_in(0, Location::RequiresRegister()); |
| 1831 locs->set_out(Location::SameAsFirstInput()); | 2053 locs->set_out(Location::SameAsFirstInput()); |
| 1832 return locs; | 2054 return locs; |
| 1833 } | 2055 } |
| 1834 | 2056 |
| 1835 | 2057 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1857 // instantiate the type arguments. | 2079 // instantiate the type arguments. |
| 1858 __ LoadObject(result_reg, type_arguments()); | 2080 __ LoadObject(result_reg, type_arguments()); |
| 1859 // result_reg: uninstantiated type arguments. | 2081 // result_reg: uninstantiated type arguments. |
| 1860 __ Bind(&type_arguments_instantiated); | 2082 __ Bind(&type_arguments_instantiated); |
| 1861 | 2083 |
| 1862 // result_reg: uninstantiated or instantiated type arguments. | 2084 // result_reg: uninstantiated or instantiated type arguments. |
| 1863 } | 2085 } |
| 1864 | 2086 |
| 1865 | 2087 |
| 1866 LocationSummary* | 2088 LocationSummary* |
| 1867 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 2089 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const { |
| 1868 const intptr_t kNumInputs = 1; | 2090 const intptr_t kNumInputs = 1; |
| 1869 const intptr_t kNumTemps = 0; | 2091 const intptr_t kNumTemps = 0; |
| 1870 LocationSummary* locs = | 2092 LocationSummary* locs = |
| 1871 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1872 locs->set_in(0, Location::RequiresRegister()); | 2094 locs->set_in(0, Location::RequiresRegister()); |
| 1873 locs->set_out(Location::SameAsFirstInput()); | 2095 locs->set_out(Location::SameAsFirstInput()); |
| 1874 return locs; | 2096 return locs; |
| 1875 } | 2097 } |
| 1876 | 2098 |
| 1877 | 2099 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1896 __ b(&instantiator_not_null, NE); | 2118 __ b(&instantiator_not_null, NE); |
| 1897 // Null was used in VisitExtractConstructorTypeArguments as the | 2119 // Null was used in VisitExtractConstructorTypeArguments as the |
| 1898 // instantiated type arguments, no proper instantiator needed. | 2120 // instantiated type arguments, no proper instantiator needed. |
| 1899 __ LoadImmediate(instantiator_reg, | 2121 __ LoadImmediate(instantiator_reg, |
| 1900 Smi::RawValue(StubCode::kNoInstantiator)); | 2122 Smi::RawValue(StubCode::kNoInstantiator)); |
| 1901 __ Bind(&instantiator_not_null); | 2123 __ Bind(&instantiator_not_null); |
| 1902 // instantiator_reg: instantiator or kNoInstantiator. | 2124 // instantiator_reg: instantiator or kNoInstantiator. |
| 1903 } | 2125 } |
| 1904 | 2126 |
| 1905 | 2127 |
| 1906 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 2128 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
| 1907 const intptr_t kNumInputs = 0; | 2129 const intptr_t kNumInputs = 0; |
| 1908 const intptr_t kNumTemps = 1; | 2130 const intptr_t kNumTemps = 1; |
| 1909 LocationSummary* locs = | 2131 LocationSummary* locs = |
| 1910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2132 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1911 locs->set_temp(0, Location::RegisterLocation(R1)); | 2133 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 1912 locs->set_out(Location::RegisterLocation(R0)); | 2134 locs->set_out(Location::RegisterLocation(R0)); |
| 1913 return locs; | 2135 return locs; |
| 1914 } | 2136 } |
| 1915 | 2137 |
| 1916 | 2138 |
| 1917 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2139 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1918 ASSERT(locs()->temp(0).reg() == R1); | 2140 ASSERT(locs()->temp(0).reg() == R1); |
| 1919 ASSERT(locs()->out().reg() == R0); | 2141 ASSERT(locs()->out().reg() == R0); |
| 1920 | 2142 |
| 1921 __ LoadImmediate(R1, num_context_variables()); | 2143 __ LoadImmediate(R1, num_context_variables()); |
| 1922 const ExternalLabel label("alloc_context", | 2144 const ExternalLabel label("alloc_context", |
| 1923 StubCode::AllocateContextEntryPoint()); | 2145 StubCode::AllocateContextEntryPoint()); |
| 1924 compiler->GenerateCall(token_pos(), | 2146 compiler->GenerateCall(token_pos(), |
| 1925 &label, | 2147 &label, |
| 1926 PcDescriptors::kOther, | 2148 PcDescriptors::kOther, |
| 1927 locs()); | 2149 locs()); |
| 1928 } | 2150 } |
| 1929 | 2151 |
| 1930 | 2152 |
| 1931 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 2153 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { |
| 1932 const intptr_t kNumInputs = 1; | 2154 const intptr_t kNumInputs = 1; |
| 1933 const intptr_t kNumTemps = 0; | 2155 const intptr_t kNumTemps = 0; |
| 1934 LocationSummary* locs = | 2156 LocationSummary* locs = |
| 1935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2157 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1936 locs->set_in(0, Location::RegisterLocation(R0)); | 2158 locs->set_in(0, Location::RegisterLocation(R0)); |
| 1937 locs->set_out(Location::RegisterLocation(R0)); | 2159 locs->set_out(Location::RegisterLocation(R0)); |
| 1938 return locs; | 2160 return locs; |
| 1939 } | 2161 } |
| 1940 | 2162 |
| 1941 | 2163 |
| 1942 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2164 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1943 Register context_value = locs()->in(0).reg(); | 2165 Register context_value = locs()->in(0).reg(); |
| 1944 Register result = locs()->out().reg(); | 2166 Register result = locs()->out().reg(); |
| 1945 | 2167 |
| 1946 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2168 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1947 __ Push(context_value); | 2169 __ Push(context_value); |
| 1948 compiler->GenerateRuntimeCall(token_pos(), | 2170 compiler->GenerateRuntimeCall(token_pos(), |
| 1949 deopt_id(), | 2171 deopt_id(), |
| 1950 kCloneContextRuntimeEntry, | 2172 kCloneContextRuntimeEntry, |
| 1951 1, | 2173 1, |
| 1952 locs()); | 2174 locs()); |
| 1953 __ Drop(1); // Remove argument. | 2175 __ Drop(1); // Remove argument. |
| 1954 __ Pop(result); // Get result (cloned context). | 2176 __ Pop(result); // Get result (cloned context). |
| 1955 } | 2177 } |
| 1956 | 2178 |
| 1957 | 2179 |
| 1958 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2180 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const { |
| 1959 UNREACHABLE(); | 2181 UNREACHABLE(); |
| 1960 return NULL; | 2182 return NULL; |
| 1961 } | 2183 } |
| 1962 | 2184 |
| 1963 | 2185 |
| 1964 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2186 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1965 __ Bind(compiler->GetJumpLabel(this)); | 2187 __ Bind(compiler->GetJumpLabel(this)); |
| 1966 compiler->AddExceptionHandler(catch_try_index(), | 2188 compiler->AddExceptionHandler(catch_try_index(), |
| 1967 try_index(), | 2189 try_index(), |
| 1968 compiler->assembler()->CodeSize(), | 2190 compiler->assembler()->CodeSize(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1985 | 2207 |
| 1986 // Restore stack and initialize the two exception variables: | 2208 // Restore stack and initialize the two exception variables: |
| 1987 // exception and stack trace variables. | 2209 // exception and stack trace variables. |
| 1988 __ StoreToOffset(kWord, kExceptionObjectReg, | 2210 __ StoreToOffset(kWord, kExceptionObjectReg, |
| 1989 FP, exception_var().index() * kWordSize); | 2211 FP, exception_var().index() * kWordSize); |
| 1990 __ StoreToOffset(kWord, kStackTraceObjectReg, | 2212 __ StoreToOffset(kWord, kStackTraceObjectReg, |
| 1991 FP, stacktrace_var().index() * kWordSize); | 2213 FP, stacktrace_var().index() * kWordSize); |
| 1992 } | 2214 } |
| 1993 | 2215 |
| 1994 | 2216 |
| 1995 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2217 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const { |
| 1996 const intptr_t kNumInputs = 0; | 2218 const intptr_t kNumInputs = 0; |
| 1997 const intptr_t kNumTemps = 1; | 2219 const intptr_t kNumTemps = 1; |
| 1998 LocationSummary* summary = | 2220 LocationSummary* summary = |
| 1999 new LocationSummary(kNumInputs, | 2221 new LocationSummary(kNumInputs, |
| 2000 kNumTemps, | 2222 kNumTemps, |
| 2001 LocationSummary::kCallOnSlowPath); | 2223 LocationSummary::kCallOnSlowPath); |
| 2002 summary->set_temp(0, Location::RequiresRegister()); | 2224 summary->set_temp(0, Location::RequiresRegister()); |
| 2003 return summary; | 2225 return summary; |
| 2004 } | 2226 } |
| 2005 | 2227 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2168 Register temp = locs.temp(0).reg(); | 2390 Register temp = locs.temp(0).reg(); |
| 2169 __ Lsl(temp, left, IP); | 2391 __ Lsl(temp, left, IP); |
| 2170 __ cmp(left, ShifterOperand(temp, ASR, IP)); | 2392 __ cmp(left, ShifterOperand(temp, ASR, IP)); |
| 2171 __ b(deopt, NE); // Overflow. | 2393 __ b(deopt, NE); // Overflow. |
| 2172 // Shift for result now we know there is no overflow. | 2394 // Shift for result now we know there is no overflow. |
| 2173 __ Lsl(result, left, IP); | 2395 __ Lsl(result, left, IP); |
| 2174 } | 2396 } |
| 2175 } | 2397 } |
| 2176 | 2398 |
| 2177 | 2399 |
| 2178 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 2400 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const { |
| 2179 const intptr_t kNumInputs = 2; | 2401 const intptr_t kNumInputs = 2; |
| 2180 const intptr_t kNumTemps = 0; | 2402 const intptr_t kNumTemps = 0; |
| 2181 LocationSummary* summary = | 2403 LocationSummary* summary = |
| 2182 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2404 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2183 if (op_kind() == Token::kTRUNCDIV) { | 2405 if (op_kind() == Token::kTRUNCDIV) { |
| 2184 summary->set_in(0, Location::RequiresRegister()); | 2406 summary->set_in(0, Location::RequiresRegister()); |
| 2185 if (RightIsPowerOfTwoConstant()) { | 2407 if (RightIsPowerOfTwoConstant()) { |
| 2186 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2408 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 2187 summary->set_in(1, Location::Constant(right_constant->value())); | 2409 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2188 summary->AddTemp(Location::RequiresRegister()); | 2410 summary->AddTemp(Location::RequiresRegister()); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 UNREACHABLE(); | 2721 UNREACHABLE(); |
| 2500 break; | 2722 break; |
| 2501 } | 2723 } |
| 2502 default: | 2724 default: |
| 2503 UNREACHABLE(); | 2725 UNREACHABLE(); |
| 2504 break; | 2726 break; |
| 2505 } | 2727 } |
| 2506 } | 2728 } |
| 2507 | 2729 |
| 2508 | 2730 |
| 2509 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 2731 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const { |
| 2510 intptr_t left_cid = left()->Type()->ToCid(); | 2732 intptr_t left_cid = left()->Type()->ToCid(); |
| 2511 intptr_t right_cid = right()->Type()->ToCid(); | 2733 intptr_t right_cid = right()->Type()->ToCid(); |
| 2512 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); | 2734 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); |
| 2513 const intptr_t kNumInputs = 2; | 2735 const intptr_t kNumInputs = 2; |
| 2514 const intptr_t kNumTemps = 0; | 2736 const intptr_t kNumTemps = 0; |
| 2515 LocationSummary* summary = | 2737 LocationSummary* summary = |
| 2516 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2738 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2517 summary->set_in(0, Location::RequiresRegister()); | 2739 summary->set_in(0, Location::RequiresRegister()); |
| 2518 summary->set_in(1, Location::RequiresRegister()); | 2740 summary->set_in(1, Location::RequiresRegister()); |
| 2519 return summary; | 2741 return summary; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2531 } else if (right_cid == kSmiCid) { | 2753 } else if (right_cid == kSmiCid) { |
| 2532 __ tst(left, ShifterOperand(kSmiTagMask)); | 2754 __ tst(left, ShifterOperand(kSmiTagMask)); |
| 2533 } else { | 2755 } else { |
| 2534 __ orr(IP, left, ShifterOperand(right)); | 2756 __ orr(IP, left, ShifterOperand(right)); |
| 2535 __ tst(IP, ShifterOperand(kSmiTagMask)); | 2757 __ tst(IP, ShifterOperand(kSmiTagMask)); |
| 2536 } | 2758 } |
| 2537 __ b(deopt, EQ); | 2759 __ b(deopt, EQ); |
| 2538 } | 2760 } |
| 2539 | 2761 |
| 2540 | 2762 |
| 2541 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 2763 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 2542 const intptr_t kNumInputs = 1; | 2764 const intptr_t kNumInputs = 1; |
| 2543 const intptr_t kNumTemps = 0; | 2765 const intptr_t kNumTemps = 0; |
| 2544 LocationSummary* summary = | 2766 LocationSummary* summary = |
| 2545 new LocationSummary(kNumInputs, | 2767 new LocationSummary(kNumInputs, |
| 2546 kNumTemps, | 2768 kNumTemps, |
| 2547 LocationSummary::kCallOnSlowPath); | 2769 LocationSummary::kCallOnSlowPath); |
| 2548 summary->set_in(0, Location::RequiresFpuRegister()); | 2770 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2549 summary->set_out(Location::RequiresRegister()); | 2771 summary->set_out(Location::RequiresRegister()); |
| 2550 return summary; | 2772 return summary; |
| 2551 } | 2773 } |
| 2552 | 2774 |
| 2553 | 2775 |
| 2554 class BoxDoubleSlowPath : public SlowPathCode { | |
| 2555 public: | |
| 2556 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | |
| 2557 : instruction_(instruction) { } | |
| 2558 | |
| 2559 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2560 __ Comment("BoxDoubleSlowPath"); | |
| 2561 __ Bind(entry_label()); | |
| 2562 const Class& double_class = compiler->double_class(); | |
| 2563 const Code& stub = | |
| 2564 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
| 2565 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
| 2566 | |
| 2567 LocationSummary* locs = instruction_->locs(); | |
| 2568 locs->live_registers()->Remove(locs->out()); | |
| 2569 | |
| 2570 compiler->SaveLiveRegisters(locs); | |
| 2571 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | |
| 2572 &label, | |
| 2573 PcDescriptors::kOther, | |
| 2574 locs); | |
| 2575 __ MoveRegister(locs->out().reg(), R0); | |
| 2576 compiler->RestoreLiveRegisters(locs); | |
| 2577 | |
| 2578 __ b(exit_label()); | |
| 2579 } | |
| 2580 | |
| 2581 private: | |
| 2582 BoxDoubleInstr* instruction_; | |
| 2583 }; | |
| 2584 | |
| 2585 | |
| 2586 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2776 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2587 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2777 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 2588 compiler->AddSlowPathCode(slow_path); | 2778 compiler->AddSlowPathCode(slow_path); |
| 2589 | 2779 |
| 2590 const Register out_reg = locs()->out().reg(); | 2780 const Register out_reg = locs()->out().reg(); |
| 2591 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 2781 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 2592 | 2782 |
| 2593 __ TryAllocate(compiler->double_class(), | 2783 __ TryAllocate(compiler->double_class(), |
| 2594 slow_path->entry_label(), | 2784 slow_path->entry_label(), |
| 2595 out_reg); | 2785 out_reg); |
| 2596 __ Bind(slow_path->exit_label()); | 2786 __ Bind(slow_path->exit_label()); |
| 2597 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 2787 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 2598 } | 2788 } |
| 2599 | 2789 |
| 2600 | 2790 |
| 2601 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2791 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 2602 const intptr_t kNumInputs = 1; | 2792 const intptr_t kNumInputs = 1; |
| 2603 const intptr_t value_cid = value()->Type()->ToCid(); | 2793 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2604 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | 2794 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
| 2605 const bool needs_writable_input = (value_cid == kSmiCid); | 2795 const bool needs_writable_input = (value_cid == kSmiCid); |
| 2606 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 2796 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 2607 LocationSummary* summary = | 2797 LocationSummary* summary = |
| 2608 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2798 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2609 summary->set_in(0, needs_writable_input | 2799 summary->set_in(0, needs_writable_input |
| 2610 ? Location::WritableRegister() | 2800 ? Location::WritableRegister() |
| 2611 : Location::RequiresRegister()); | 2801 : Location::RequiresRegister()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2639 __ Bind(&is_smi); | 2829 __ Bind(&is_smi); |
| 2640 // TODO(regis): Why do we preserve value here but not above? | 2830 // TODO(regis): Why do we preserve value here but not above? |
| 2641 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag. | 2831 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag. |
| 2642 __ vmovsr(STMP, IP); | 2832 __ vmovsr(STMP, IP); |
| 2643 __ vcvtdi(result, STMP); | 2833 __ vcvtdi(result, STMP); |
| 2644 __ Bind(&done); | 2834 __ Bind(&done); |
| 2645 } | 2835 } |
| 2646 } | 2836 } |
| 2647 | 2837 |
| 2648 | 2838 |
| 2649 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | 2839 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 2650 const intptr_t kNumInputs = 1; | 2840 const intptr_t kNumInputs = 1; |
| 2651 const intptr_t kNumTemps = 0; | 2841 const intptr_t kNumTemps = 0; |
| 2652 LocationSummary* summary = | 2842 LocationSummary* summary = |
| 2653 new LocationSummary(kNumInputs, | 2843 new LocationSummary(kNumInputs, |
| 2654 kNumTemps, | 2844 kNumTemps, |
| 2655 LocationSummary::kCallOnSlowPath); | 2845 LocationSummary::kCallOnSlowPath); |
| 2656 summary->set_in(0, Location::RequiresFpuRegister()); | 2846 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2657 summary->set_out(Location::RequiresRegister()); | 2847 summary->set_out(Location::RequiresRegister()); |
| 2658 return summary; | 2848 return summary; |
| 2659 } | 2849 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2705 out_reg); | 2895 out_reg); |
| 2706 __ Bind(slow_path->exit_label()); | 2896 __ Bind(slow_path->exit_label()); |
| 2707 | 2897 |
| 2708 __ StoreDToOffset(value_even, out_reg, | 2898 __ StoreDToOffset(value_even, out_reg, |
| 2709 Float32x4::value_offset() - kHeapObjectTag); | 2899 Float32x4::value_offset() - kHeapObjectTag); |
| 2710 __ StoreDToOffset(value_odd, out_reg, | 2900 __ StoreDToOffset(value_odd, out_reg, |
| 2711 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2901 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2712 } | 2902 } |
| 2713 | 2903 |
| 2714 | 2904 |
| 2715 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2905 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 2716 const intptr_t value_cid = value()->Type()->ToCid(); | 2906 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2717 const intptr_t kNumInputs = 1; | 2907 const intptr_t kNumInputs = 1; |
| 2718 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 2908 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
| 2719 LocationSummary* summary = | 2909 LocationSummary* summary = |
| 2720 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2721 summary->set_in(0, Location::RequiresRegister()); | 2911 summary->set_in(0, Location::RequiresRegister()); |
| 2722 if (kNumTemps > 0) { | 2912 if (kNumTemps > 0) { |
| 2723 ASSERT(kNumTemps == 1); | 2913 ASSERT(kNumTemps == 1); |
| 2724 summary->set_temp(0, Location::RequiresRegister()); | 2914 summary->set_temp(0, Location::RequiresRegister()); |
| 2725 } | 2915 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2744 | 2934 |
| 2745 const DRegister result_even = EvenDRegisterOf(result); | 2935 const DRegister result_even = EvenDRegisterOf(result); |
| 2746 const DRegister result_odd = OddDRegisterOf(result); | 2936 const DRegister result_odd = OddDRegisterOf(result); |
| 2747 __ LoadDFromOffset(result_even, value, | 2937 __ LoadDFromOffset(result_even, value, |
| 2748 Float32x4::value_offset() - kHeapObjectTag); | 2938 Float32x4::value_offset() - kHeapObjectTag); |
| 2749 __ LoadDFromOffset(result_odd, value, | 2939 __ LoadDFromOffset(result_odd, value, |
| 2750 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2940 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2751 } | 2941 } |
| 2752 | 2942 |
| 2753 | 2943 |
| 2754 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { | 2944 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 2755 const intptr_t kNumInputs = 1; | 2945 const intptr_t kNumInputs = 1; |
| 2756 const intptr_t kNumTemps = 0; | 2946 const intptr_t kNumTemps = 0; |
| 2757 LocationSummary* summary = | 2947 LocationSummary* summary = |
| 2758 new LocationSummary(kNumInputs, | 2948 new LocationSummary(kNumInputs, |
| 2759 kNumTemps, | 2949 kNumTemps, |
| 2760 LocationSummary::kCallOnSlowPath); | 2950 LocationSummary::kCallOnSlowPath); |
| 2761 summary->set_in(0, Location::RequiresFpuRegister()); | 2951 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2762 summary->set_out(Location::RequiresRegister()); | 2952 summary->set_out(Location::RequiresRegister()); |
| 2763 return summary; | 2953 return summary; |
| 2764 } | 2954 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2809 slow_path->entry_label(), | 2999 slow_path->entry_label(), |
| 2810 out_reg); | 3000 out_reg); |
| 2811 __ Bind(slow_path->exit_label()); | 3001 __ Bind(slow_path->exit_label()); |
| 2812 __ StoreDToOffset(value_even, out_reg, | 3002 __ StoreDToOffset(value_even, out_reg, |
| 2813 Int32x4::value_offset() - kHeapObjectTag); | 3003 Int32x4::value_offset() - kHeapObjectTag); |
| 2814 __ StoreDToOffset(value_odd, out_reg, | 3004 __ StoreDToOffset(value_odd, out_reg, |
| 2815 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3005 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2816 } | 3006 } |
| 2817 | 3007 |
| 2818 | 3008 |
| 2819 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { | 3009 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 2820 const intptr_t value_cid = value()->Type()->ToCid(); | 3010 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2821 const intptr_t kNumInputs = 1; | 3011 const intptr_t kNumInputs = 1; |
| 2822 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3012 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 2823 LocationSummary* summary = | 3013 LocationSummary* summary = |
| 2824 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3014 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2825 summary->set_in(0, Location::RequiresRegister()); | 3015 summary->set_in(0, Location::RequiresRegister()); |
| 2826 if (kNumTemps > 0) { | 3016 if (kNumTemps > 0) { |
| 2827 ASSERT(kNumTemps == 1); | 3017 ASSERT(kNumTemps == 1); |
| 2828 summary->set_temp(0, Location::RequiresRegister()); | 3018 summary->set_temp(0, Location::RequiresRegister()); |
| 2829 } | 3019 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2848 | 3038 |
| 2849 const DRegister result_even = EvenDRegisterOf(result); | 3039 const DRegister result_even = EvenDRegisterOf(result); |
| 2850 const DRegister result_odd = OddDRegisterOf(result); | 3040 const DRegister result_odd = OddDRegisterOf(result); |
| 2851 __ LoadDFromOffset(result_even, value, | 3041 __ LoadDFromOffset(result_even, value, |
| 2852 Int32x4::value_offset() - kHeapObjectTag); | 3042 Int32x4::value_offset() - kHeapObjectTag); |
| 2853 __ LoadDFromOffset(result_odd, value, | 3043 __ LoadDFromOffset(result_odd, value, |
| 2854 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3044 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2855 } | 3045 } |
| 2856 | 3046 |
| 2857 | 3047 |
| 2858 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 3048 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 2859 const intptr_t kNumInputs = 2; | 3049 const intptr_t kNumInputs = 2; |
| 2860 const intptr_t kNumTemps = 0; | 3050 const intptr_t kNumTemps = 0; |
| 2861 LocationSummary* summary = | 3051 LocationSummary* summary = |
| 2862 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3052 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2863 summary->set_in(0, Location::RequiresFpuRegister()); | 3053 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2864 summary->set_in(1, Location::RequiresFpuRegister()); | 3054 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2865 summary->set_out(Location::RequiresFpuRegister()); | 3055 summary->set_out(Location::RequiresFpuRegister()); |
| 2866 return summary; | 3056 return summary; |
| 2867 } | 3057 } |
| 2868 | 3058 |
| 2869 | 3059 |
| 2870 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3060 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2871 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3061 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 2872 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3062 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 2873 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3063 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 2874 switch (op_kind()) { | 3064 switch (op_kind()) { |
| 2875 case Token::kADD: __ vaddd(result, left, right); break; | 3065 case Token::kADD: __ vaddd(result, left, right); break; |
| 2876 case Token::kSUB: __ vsubd(result, left, right); break; | 3066 case Token::kSUB: __ vsubd(result, left, right); break; |
| 2877 case Token::kMUL: __ vmuld(result, left, right); break; | 3067 case Token::kMUL: __ vmuld(result, left, right); break; |
| 2878 case Token::kDIV: __ vdivd(result, left, right); break; | 3068 case Token::kDIV: __ vdivd(result, left, right); break; |
| 2879 default: UNREACHABLE(); | 3069 default: UNREACHABLE(); |
| 2880 } | 3070 } |
| 2881 } | 3071 } |
| 2882 | 3072 |
| 2883 | 3073 |
| 2884 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { | 3074 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 2885 const intptr_t kNumInputs = 2; | 3075 const intptr_t kNumInputs = 2; |
| 2886 const intptr_t kNumTemps = 0; | 3076 const intptr_t kNumTemps = 0; |
| 2887 LocationSummary* summary = | 3077 LocationSummary* summary = |
| 2888 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2889 summary->set_in(0, Location::RequiresFpuRegister()); | 3079 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2890 summary->set_in(1, Location::RequiresFpuRegister()); | 3080 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2891 summary->set_out(Location::RequiresFpuRegister()); | 3081 summary->set_out(Location::RequiresFpuRegister()); |
| 2892 return summary; | 3082 return summary; |
| 2893 } | 3083 } |
| 2894 | 3084 |
| 2895 | 3085 |
| 2896 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3086 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2897 QRegister left = locs()->in(0).fpu_reg(); | 3087 QRegister left = locs()->in(0).fpu_reg(); |
| 2898 QRegister right = locs()->in(1).fpu_reg(); | 3088 QRegister right = locs()->in(1).fpu_reg(); |
| 2899 QRegister result = locs()->out().fpu_reg(); | 3089 QRegister result = locs()->out().fpu_reg(); |
| 2900 | 3090 |
| 2901 switch (op_kind()) { | 3091 switch (op_kind()) { |
| 2902 case Token::kADD: __ vaddqs(result, left, right); break; | 3092 case Token::kADD: __ vaddqs(result, left, right); break; |
| 2903 case Token::kSUB: __ vsubqs(result, left, right); break; | 3093 case Token::kSUB: __ vsubqs(result, left, right); break; |
| 2904 case Token::kMUL: __ vmulqs(result, left, right); break; | 3094 case Token::kMUL: __ vmulqs(result, left, right); break; |
| 2905 case Token::kDIV: __ Vdivqs(result, left, right); break; | 3095 case Token::kDIV: __ Vdivqs(result, left, right); break; |
| 2906 default: UNREACHABLE(); | 3096 default: UNREACHABLE(); |
| 2907 } | 3097 } |
| 2908 } | 3098 } |
| 2909 | 3099 |
| 2910 | 3100 |
| 2911 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { | 3101 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
| 2912 const intptr_t kNumInputs = 1; | 3102 const intptr_t kNumInputs = 1; |
| 2913 const intptr_t kNumTemps = 0; | 3103 const intptr_t kNumTemps = 0; |
| 2914 LocationSummary* summary = | 3104 LocationSummary* summary = |
| 2915 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2916 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3106 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
| 2917 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3107 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
| 2918 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3108 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 2919 return summary; | 3109 return summary; |
| 2920 } | 3110 } |
| 2921 | 3111 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2981 __ vmovs(sresult1, svalues[(mask_ >> 2) & 0x3]); | 3171 __ vmovs(sresult1, svalues[(mask_ >> 2) & 0x3]); |
| 2982 __ vmovs(sresult2, svalues[(mask_ >> 4) & 0x3]); | 3172 __ vmovs(sresult2, svalues[(mask_ >> 4) & 0x3]); |
| 2983 __ vmovs(sresult3, svalues[(mask_ >> 6) & 0x3]); | 3173 __ vmovs(sresult3, svalues[(mask_ >> 6) & 0x3]); |
| 2984 } | 3174 } |
| 2985 break; | 3175 break; |
| 2986 default: UNREACHABLE(); | 3176 default: UNREACHABLE(); |
| 2987 } | 3177 } |
| 2988 } | 3178 } |
| 2989 | 3179 |
| 2990 | 3180 |
| 2991 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3181 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { |
| 2992 const intptr_t kNumInputs = 2; | 3182 const intptr_t kNumInputs = 2; |
| 2993 const intptr_t kNumTemps = 0; | 3183 const intptr_t kNumTemps = 0; |
| 2994 LocationSummary* summary = | 3184 LocationSummary* summary = |
| 2995 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2996 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3186 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
| 2997 summary->set_in(0, Location::FpuRegisterLocation(Q4)); | 3187 summary->set_in(0, Location::FpuRegisterLocation(Q4)); |
| 2998 summary->set_in(1, Location::FpuRegisterLocation(Q5)); | 3188 summary->set_in(1, Location::FpuRegisterLocation(Q5)); |
| 2999 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3189 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3000 return summary; | 3190 return summary; |
| 3001 } | 3191 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3037 __ vmovs(sresult0, left_svalues[mask_ & 0x3]); | 3227 __ vmovs(sresult0, left_svalues[mask_ & 0x3]); |
| 3038 __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]); | 3228 __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]); |
| 3039 __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]); | 3229 __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]); |
| 3040 __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]); | 3230 __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]); |
| 3041 break; | 3231 break; |
| 3042 default: UNREACHABLE(); | 3232 default: UNREACHABLE(); |
| 3043 } | 3233 } |
| 3044 } | 3234 } |
| 3045 | 3235 |
| 3046 | 3236 |
| 3047 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3237 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { |
| 3048 const intptr_t kNumInputs = 1; | 3238 const intptr_t kNumInputs = 1; |
| 3049 const intptr_t kNumTemps = 1; | 3239 const intptr_t kNumTemps = 1; |
| 3050 LocationSummary* summary = | 3240 LocationSummary* summary = |
| 3051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3241 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3052 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3242 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
| 3053 summary->set_temp(0, Location::RequiresRegister()); | 3243 summary->set_temp(0, Location::RequiresRegister()); |
| 3054 summary->set_out(Location::RequiresRegister()); | 3244 summary->set_out(Location::RequiresRegister()); |
| 3055 return summary; | 3245 return summary; |
| 3056 } | 3246 } |
| 3057 | 3247 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3077 __ orr(out, out, ShifterOperand(temp, LSL, 2)); | 3267 __ orr(out, out, ShifterOperand(temp, LSL, 2)); |
| 3078 // W lane. | 3268 // W lane. |
| 3079 __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 3269 __ vmovrs(temp, OddSRegisterOf(dvalue1)); |
| 3080 __ Lsr(temp, temp, 31); | 3270 __ Lsr(temp, temp, 31); |
| 3081 __ orr(out, out, ShifterOperand(temp, LSL, 3)); | 3271 __ orr(out, out, ShifterOperand(temp, LSL, 3)); |
| 3082 // Tag. | 3272 // Tag. |
| 3083 __ SmiTag(out); | 3273 __ SmiTag(out); |
| 3084 } | 3274 } |
| 3085 | 3275 |
| 3086 | 3276 |
| 3087 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { | 3277 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 3278 bool opt) const { |
| 3088 const intptr_t kNumInputs = 4; | 3279 const intptr_t kNumInputs = 4; |
| 3089 const intptr_t kNumTemps = 0; | 3280 const intptr_t kNumTemps = 0; |
| 3090 LocationSummary* summary = | 3281 LocationSummary* summary = |
| 3091 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3282 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3092 summary->set_in(0, Location::RequiresFpuRegister()); | 3283 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3093 summary->set_in(1, Location::RequiresFpuRegister()); | 3284 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3094 summary->set_in(2, Location::RequiresFpuRegister()); | 3285 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3095 summary->set_in(3, Location::RequiresFpuRegister()); | 3286 summary->set_in(3, Location::RequiresFpuRegister()); |
| 3096 // Low (< 7) Q registers are needed for the vcvtsd instruction. | 3287 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 3097 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3288 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3109 DRegister dr0 = EvenDRegisterOf(r); | 3300 DRegister dr0 = EvenDRegisterOf(r); |
| 3110 DRegister dr1 = OddDRegisterOf(r); | 3301 DRegister dr1 = OddDRegisterOf(r); |
| 3111 | 3302 |
| 3112 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); | 3303 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); |
| 3113 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); | 3304 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); |
| 3114 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); | 3305 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); |
| 3115 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); | 3306 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); |
| 3116 } | 3307 } |
| 3117 | 3308 |
| 3118 | 3309 |
| 3119 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { | 3310 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { |
| 3120 const intptr_t kNumInputs = 0; | 3311 const intptr_t kNumInputs = 0; |
| 3121 const intptr_t kNumTemps = 0; | 3312 const intptr_t kNumTemps = 0; |
| 3122 LocationSummary* summary = | 3313 LocationSummary* summary = |
| 3123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3314 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3124 summary->set_out(Location::RequiresFpuRegister()); | 3315 summary->set_out(Location::RequiresFpuRegister()); |
| 3125 return summary; | 3316 return summary; |
| 3126 } | 3317 } |
| 3127 | 3318 |
| 3128 | 3319 |
| 3129 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3320 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3130 QRegister q = locs()->out().fpu_reg(); | 3321 QRegister q = locs()->out().fpu_reg(); |
| 3131 __ veorq(q, q, q); | 3322 __ veorq(q, q, q); |
| 3132 } | 3323 } |
| 3133 | 3324 |
| 3134 | 3325 |
| 3135 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { | 3326 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { |
| 3136 const intptr_t kNumInputs = 1; | 3327 const intptr_t kNumInputs = 1; |
| 3137 const intptr_t kNumTemps = 0; | 3328 const intptr_t kNumTemps = 0; |
| 3138 LocationSummary* summary = | 3329 LocationSummary* summary = |
| 3139 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3330 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3140 summary->set_in(0, Location::RequiresFpuRegister()); | 3331 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3141 summary->set_out(Location::RequiresFpuRegister()); | 3332 summary->set_out(Location::RequiresFpuRegister()); |
| 3142 return summary; | 3333 return summary; |
| 3143 } | 3334 } |
| 3144 | 3335 |
| 3145 | 3336 |
| 3146 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3337 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3147 QRegister value = locs()->in(0).fpu_reg(); | 3338 QRegister value = locs()->in(0).fpu_reg(); |
| 3148 QRegister result = locs()->out().fpu_reg(); | 3339 QRegister result = locs()->out().fpu_reg(); |
| 3149 | 3340 |
| 3150 DRegister dvalue0 = EvenDRegisterOf(value); | 3341 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3151 | 3342 |
| 3152 // Convert to Float32. | 3343 // Convert to Float32. |
| 3153 __ vcvtsd(STMP, dvalue0); | 3344 __ vcvtsd(STMP, dvalue0); |
| 3154 | 3345 |
| 3155 // Splat across all lanes. | 3346 // Splat across all lanes. |
| 3156 __ vdup(kWord, result, DTMP, 0); | 3347 __ vdup(kWord, result, DTMP, 0); |
| 3157 } | 3348 } |
| 3158 | 3349 |
| 3159 | 3350 |
| 3160 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { | 3351 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { |
| 3161 const intptr_t kNumInputs = 2; | 3352 const intptr_t kNumInputs = 2; |
| 3162 const intptr_t kNumTemps = 0; | 3353 const intptr_t kNumTemps = 0; |
| 3163 LocationSummary* summary = | 3354 LocationSummary* summary = |
| 3164 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3165 summary->set_in(0, Location::RequiresFpuRegister()); | 3356 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3166 summary->set_in(1, Location::RequiresFpuRegister()); | 3357 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3167 summary->set_out(Location::RequiresFpuRegister()); | 3358 summary->set_out(Location::RequiresFpuRegister()); |
| 3168 return summary; | 3359 return summary; |
| 3169 } | 3360 } |
| 3170 | 3361 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3195 break; | 3386 break; |
| 3196 case MethodRecognizer::kFloat32x4LessThanOrEqual: | 3387 case MethodRecognizer::kFloat32x4LessThanOrEqual: |
| 3197 __ vcgeqs(result, right, left); | 3388 __ vcgeqs(result, right, left); |
| 3198 break; | 3389 break; |
| 3199 | 3390 |
| 3200 default: UNREACHABLE(); | 3391 default: UNREACHABLE(); |
| 3201 } | 3392 } |
| 3202 } | 3393 } |
| 3203 | 3394 |
| 3204 | 3395 |
| 3205 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { | 3396 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { |
| 3206 const intptr_t kNumInputs = 2; | 3397 const intptr_t kNumInputs = 2; |
| 3207 const intptr_t kNumTemps = 0; | 3398 const intptr_t kNumTemps = 0; |
| 3208 LocationSummary* summary = | 3399 LocationSummary* summary = |
| 3209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3210 summary->set_in(0, Location::RequiresFpuRegister()); | 3401 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3211 summary->set_in(1, Location::RequiresFpuRegister()); | 3402 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3212 summary->set_out(Location::RequiresFpuRegister()); | 3403 summary->set_out(Location::RequiresFpuRegister()); |
| 3213 return summary; | 3404 return summary; |
| 3214 } | 3405 } |
| 3215 | 3406 |
| 3216 | 3407 |
| 3217 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3408 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3218 QRegister left = locs()->in(0).fpu_reg(); | 3409 QRegister left = locs()->in(0).fpu_reg(); |
| 3219 QRegister right = locs()->in(1).fpu_reg(); | 3410 QRegister right = locs()->in(1).fpu_reg(); |
| 3220 QRegister result = locs()->out().fpu_reg(); | 3411 QRegister result = locs()->out().fpu_reg(); |
| 3221 | 3412 |
| 3222 switch (op_kind()) { | 3413 switch (op_kind()) { |
| 3223 case MethodRecognizer::kFloat32x4Min: | 3414 case MethodRecognizer::kFloat32x4Min: |
| 3224 __ vminqs(result, left, right); | 3415 __ vminqs(result, left, right); |
| 3225 break; | 3416 break; |
| 3226 case MethodRecognizer::kFloat32x4Max: | 3417 case MethodRecognizer::kFloat32x4Max: |
| 3227 __ vmaxqs(result, left, right); | 3418 __ vmaxqs(result, left, right); |
| 3228 break; | 3419 break; |
| 3229 default: UNREACHABLE(); | 3420 default: UNREACHABLE(); |
| 3230 } | 3421 } |
| 3231 } | 3422 } |
| 3232 | 3423 |
| 3233 | 3424 |
| 3234 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { | 3425 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { |
| 3235 const intptr_t kNumInputs = 1; | 3426 const intptr_t kNumInputs = 1; |
| 3236 const intptr_t kNumTemps = 1; | 3427 const intptr_t kNumTemps = 1; |
| 3237 LocationSummary* summary = | 3428 LocationSummary* summary = |
| 3238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3429 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3239 summary->set_in(0, Location::RequiresFpuRegister()); | 3430 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3240 summary->set_out(Location::RequiresFpuRegister()); | 3431 summary->set_out(Location::RequiresFpuRegister()); |
| 3241 summary->set_temp(0, Location::RequiresFpuRegister()); | 3432 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3242 return summary; | 3433 return summary; |
| 3243 } | 3434 } |
| 3244 | 3435 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3256 __ Vreciprocalqs(result, left); | 3447 __ Vreciprocalqs(result, left); |
| 3257 break; | 3448 break; |
| 3258 case MethodRecognizer::kFloat32x4ReciprocalSqrt: | 3449 case MethodRecognizer::kFloat32x4ReciprocalSqrt: |
| 3259 __ VreciprocalSqrtqs(result, left); | 3450 __ VreciprocalSqrtqs(result, left); |
| 3260 break; | 3451 break; |
| 3261 default: UNREACHABLE(); | 3452 default: UNREACHABLE(); |
| 3262 } | 3453 } |
| 3263 } | 3454 } |
| 3264 | 3455 |
| 3265 | 3456 |
| 3266 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { | 3457 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { |
| 3267 const intptr_t kNumInputs = 2; | 3458 const intptr_t kNumInputs = 2; |
| 3268 const intptr_t kNumTemps = 0; | 3459 const intptr_t kNumTemps = 0; |
| 3269 LocationSummary* summary = | 3460 LocationSummary* summary = |
| 3270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3461 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3271 summary->set_in(0, Location::RequiresFpuRegister()); | 3462 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3272 summary->set_in(1, Location::RequiresFpuRegister()); | 3463 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3273 summary->set_out(Location::RequiresFpuRegister()); | 3464 summary->set_out(Location::RequiresFpuRegister()); |
| 3274 return summary; | 3465 return summary; |
| 3275 } | 3466 } |
| 3276 | 3467 |
| 3277 | 3468 |
| 3278 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3469 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3279 QRegister left = locs()->in(0).fpu_reg(); | 3470 QRegister left = locs()->in(0).fpu_reg(); |
| 3280 QRegister right = locs()->in(1).fpu_reg(); | 3471 QRegister right = locs()->in(1).fpu_reg(); |
| 3281 QRegister result = locs()->out().fpu_reg(); | 3472 QRegister result = locs()->out().fpu_reg(); |
| 3282 | 3473 |
| 3283 switch (op_kind()) { | 3474 switch (op_kind()) { |
| 3284 case MethodRecognizer::kFloat32x4Scale: | 3475 case MethodRecognizer::kFloat32x4Scale: |
| 3285 __ vcvtsd(STMP, EvenDRegisterOf(left)); | 3476 __ vcvtsd(STMP, EvenDRegisterOf(left)); |
| 3286 __ vdup(kWord, result, DTMP, 0); | 3477 __ vdup(kWord, result, DTMP, 0); |
| 3287 __ vmulqs(result, result, right); | 3478 __ vmulqs(result, result, right); |
| 3288 break; | 3479 break; |
| 3289 default: UNREACHABLE(); | 3480 default: UNREACHABLE(); |
| 3290 } | 3481 } |
| 3291 } | 3482 } |
| 3292 | 3483 |
| 3293 | 3484 |
| 3294 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { | 3485 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { |
| 3295 const intptr_t kNumInputs = 1; | 3486 const intptr_t kNumInputs = 1; |
| 3296 const intptr_t kNumTemps = 0; | 3487 const intptr_t kNumTemps = 0; |
| 3297 LocationSummary* summary = | 3488 LocationSummary* summary = |
| 3298 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3489 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3299 summary->set_in(0, Location::RequiresFpuRegister()); | 3490 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3300 summary->set_out(Location::RequiresFpuRegister()); | 3491 summary->set_out(Location::RequiresFpuRegister()); |
| 3301 return summary; | 3492 return summary; |
| 3302 } | 3493 } |
| 3303 | 3494 |
| 3304 | 3495 |
| 3305 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3496 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3306 QRegister left = locs()->in(0).fpu_reg(); | 3497 QRegister left = locs()->in(0).fpu_reg(); |
| 3307 QRegister result = locs()->out().fpu_reg(); | 3498 QRegister result = locs()->out().fpu_reg(); |
| 3308 | 3499 |
| 3309 switch (op_kind()) { | 3500 switch (op_kind()) { |
| 3310 case MethodRecognizer::kFloat32x4Negate: | 3501 case MethodRecognizer::kFloat32x4Negate: |
| 3311 __ vnegqs(result, left); | 3502 __ vnegqs(result, left); |
| 3312 break; | 3503 break; |
| 3313 case MethodRecognizer::kFloat32x4Absolute: | 3504 case MethodRecognizer::kFloat32x4Absolute: |
| 3314 __ vabsqs(result, left); | 3505 __ vabsqs(result, left); |
| 3315 break; | 3506 break; |
| 3316 default: UNREACHABLE(); | 3507 default: UNREACHABLE(); |
| 3317 } | 3508 } |
| 3318 } | 3509 } |
| 3319 | 3510 |
| 3320 | 3511 |
| 3321 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { | 3512 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { |
| 3322 const intptr_t kNumInputs = 3; | 3513 const intptr_t kNumInputs = 3; |
| 3323 const intptr_t kNumTemps = 0; | 3514 const intptr_t kNumTemps = 0; |
| 3324 LocationSummary* summary = | 3515 LocationSummary* summary = |
| 3325 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3516 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3326 summary->set_in(0, Location::RequiresFpuRegister()); | 3517 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3327 summary->set_in(1, Location::RequiresFpuRegister()); | 3518 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3328 summary->set_in(2, Location::RequiresFpuRegister()); | 3519 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3329 summary->set_out(Location::RequiresFpuRegister()); | 3520 summary->set_out(Location::RequiresFpuRegister()); |
| 3330 return summary; | 3521 return summary; |
| 3331 } | 3522 } |
| 3332 | 3523 |
| 3333 | 3524 |
| 3334 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3525 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3335 QRegister left = locs()->in(0).fpu_reg(); | 3526 QRegister left = locs()->in(0).fpu_reg(); |
| 3336 QRegister lower = locs()->in(1).fpu_reg(); | 3527 QRegister lower = locs()->in(1).fpu_reg(); |
| 3337 QRegister upper = locs()->in(2).fpu_reg(); | 3528 QRegister upper = locs()->in(2).fpu_reg(); |
| 3338 QRegister result = locs()->out().fpu_reg(); | 3529 QRegister result = locs()->out().fpu_reg(); |
| 3339 __ vminqs(result, left, upper); | 3530 __ vminqs(result, left, upper); |
| 3340 __ vmaxqs(result, result, lower); | 3531 __ vmaxqs(result, result, lower); |
| 3341 } | 3532 } |
| 3342 | 3533 |
| 3343 | 3534 |
| 3344 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { | 3535 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { |
| 3345 const intptr_t kNumInputs = 2; | 3536 const intptr_t kNumInputs = 2; |
| 3346 const intptr_t kNumTemps = 0; | 3537 const intptr_t kNumTemps = 0; |
| 3347 LocationSummary* summary = | 3538 LocationSummary* summary = |
| 3348 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3539 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3349 summary->set_in(0, Location::RequiresFpuRegister()); | 3540 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3350 summary->set_in(1, Location::RequiresFpuRegister()); | 3541 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3351 // Low (< 7) Q registers are needed for the vmovs instruction. | 3542 // Low (< 7) Q registers are needed for the vmovs instruction. |
| 3352 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3543 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3353 return summary; | 3544 return summary; |
| 3354 } | 3545 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3382 __ vmovs(sresult2, STMP); | 3573 __ vmovs(sresult2, STMP); |
| 3383 break; | 3574 break; |
| 3384 case MethodRecognizer::kFloat32x4WithW: | 3575 case MethodRecognizer::kFloat32x4WithW: |
| 3385 __ vmovs(sresult3, STMP); | 3576 __ vmovs(sresult3, STMP); |
| 3386 break; | 3577 break; |
| 3387 default: UNREACHABLE(); | 3578 default: UNREACHABLE(); |
| 3388 } | 3579 } |
| 3389 } | 3580 } |
| 3390 | 3581 |
| 3391 | 3582 |
| 3392 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { | 3583 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3393 const intptr_t kNumInputs = 1; | 3584 const intptr_t kNumInputs = 1; |
| 3394 const intptr_t kNumTemps = 0; | 3585 const intptr_t kNumTemps = 0; |
| 3395 LocationSummary* summary = | 3586 LocationSummary* summary = |
| 3396 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3587 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3397 summary->set_in(0, Location::RequiresFpuRegister()); | 3588 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3398 summary->set_out(Location::RequiresFpuRegister()); | 3589 summary->set_out(Location::RequiresFpuRegister()); |
| 3399 return summary; | 3590 return summary; |
| 3400 } | 3591 } |
| 3401 | 3592 |
| 3402 | 3593 |
| 3403 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3594 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3404 QRegister value = locs()->in(0).fpu_reg(); | 3595 QRegister value = locs()->in(0).fpu_reg(); |
| 3405 QRegister result = locs()->out().fpu_reg(); | 3596 QRegister result = locs()->out().fpu_reg(); |
| 3406 | 3597 |
| 3407 if (value != result) { | 3598 if (value != result) { |
| 3408 __ vmovq(result, value); | 3599 __ vmovq(result, value); |
| 3409 } | 3600 } |
| 3410 } | 3601 } |
| 3411 | 3602 |
| 3412 | 3603 |
| 3413 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { | 3604 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
| 3605 bool opt) const { |
| 3414 const intptr_t kNumInputs = 4; | 3606 const intptr_t kNumInputs = 4; |
| 3415 const intptr_t kNumTemps = 1; | 3607 const intptr_t kNumTemps = 1; |
| 3416 LocationSummary* summary = | 3608 LocationSummary* summary = |
| 3417 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3418 summary->set_in(0, Location::RequiresRegister()); | 3610 summary->set_in(0, Location::RequiresRegister()); |
| 3419 summary->set_in(1, Location::RequiresRegister()); | 3611 summary->set_in(1, Location::RequiresRegister()); |
| 3420 summary->set_in(2, Location::RequiresRegister()); | 3612 summary->set_in(2, Location::RequiresRegister()); |
| 3421 summary->set_in(3, Location::RequiresRegister()); | 3613 summary->set_in(3, Location::RequiresRegister()); |
| 3422 summary->set_temp(0, Location::RequiresRegister()); | 3614 summary->set_temp(0, Location::RequiresRegister()); |
| 3423 // Low (< 7) Q register needed for the vmovsr instruction. | 3615 // Low (< 7) Q register needed for the vmovsr instruction. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3450 __ vmovsr(sresult1, temp, EQ); | 3642 __ vmovsr(sresult1, temp, EQ); |
| 3451 | 3643 |
| 3452 __ CompareObject(v2, Bool::True()); | 3644 __ CompareObject(v2, Bool::True()); |
| 3453 __ vmovsr(sresult2, temp, EQ); | 3645 __ vmovsr(sresult2, temp, EQ); |
| 3454 | 3646 |
| 3455 __ CompareObject(v3, Bool::True()); | 3647 __ CompareObject(v3, Bool::True()); |
| 3456 __ vmovsr(sresult3, temp, EQ); | 3648 __ vmovsr(sresult3, temp, EQ); |
| 3457 } | 3649 } |
| 3458 | 3650 |
| 3459 | 3651 |
| 3460 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { | 3652 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { |
| 3461 const intptr_t kNumInputs = 1; | 3653 const intptr_t kNumInputs = 1; |
| 3462 const intptr_t kNumTemps = 0; | 3654 const intptr_t kNumTemps = 0; |
| 3463 LocationSummary* summary = | 3655 LocationSummary* summary = |
| 3464 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3656 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3465 // Low (< 7) Q registers are needed for the vmovrs instruction. | 3657 // Low (< 7) Q registers are needed for the vmovrs instruction. |
| 3466 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 3658 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
| 3467 summary->set_out(Location::RequiresRegister()); | 3659 summary->set_out(Location::RequiresRegister()); |
| 3468 return summary; | 3660 return summary; |
| 3469 } | 3661 } |
| 3470 | 3662 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3495 break; | 3687 break; |
| 3496 default: UNREACHABLE(); | 3688 default: UNREACHABLE(); |
| 3497 } | 3689 } |
| 3498 | 3690 |
| 3499 __ tst(result, ShifterOperand(result)); | 3691 __ tst(result, ShifterOperand(result)); |
| 3500 __ LoadObject(result, Bool::True(), NE); | 3692 __ LoadObject(result, Bool::True(), NE); |
| 3501 __ LoadObject(result, Bool::False(), EQ); | 3693 __ LoadObject(result, Bool::False(), EQ); |
| 3502 } | 3694 } |
| 3503 | 3695 |
| 3504 | 3696 |
| 3505 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { | 3697 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { |
| 3506 const intptr_t kNumInputs = 3; | 3698 const intptr_t kNumInputs = 3; |
| 3507 const intptr_t kNumTemps = 1; | 3699 const intptr_t kNumTemps = 1; |
| 3508 LocationSummary* summary = | 3700 LocationSummary* summary = |
| 3509 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3701 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3510 summary->set_in(0, Location::RequiresFpuRegister()); | 3702 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3511 summary->set_in(1, Location::RequiresFpuRegister()); | 3703 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3512 summary->set_in(2, Location::RequiresFpuRegister()); | 3704 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3513 summary->set_temp(0, Location::RequiresFpuRegister()); | 3705 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3514 summary->set_out(Location::RequiresFpuRegister()); | 3706 summary->set_out(Location::RequiresFpuRegister()); |
| 3515 return summary; | 3707 return summary; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3530 __ vornq(temp, QTMP, temp); // temp <- ~temp. | 3722 __ vornq(temp, QTMP, temp); // temp <- ~temp. |
| 3531 // mask = mask & trueValue. | 3723 // mask = mask & trueValue. |
| 3532 __ vandq(mask, mask, trueValue); | 3724 __ vandq(mask, mask, trueValue); |
| 3533 // temp = temp & falseValue. | 3725 // temp = temp & falseValue. |
| 3534 __ vandq(temp, temp, falseValue); | 3726 __ vandq(temp, temp, falseValue); |
| 3535 // out = mask | temp. | 3727 // out = mask | temp. |
| 3536 __ vorrq(out, mask, temp); | 3728 __ vorrq(out, mask, temp); |
| 3537 } | 3729 } |
| 3538 | 3730 |
| 3539 | 3731 |
| 3540 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { | 3732 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { |
| 3541 const intptr_t kNumInputs = 2; | 3733 const intptr_t kNumInputs = 2; |
| 3542 const intptr_t kNumTemps = 0; | 3734 const intptr_t kNumTemps = 0; |
| 3543 LocationSummary* summary = | 3735 LocationSummary* summary = |
| 3544 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3736 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3545 summary->set_in(0, Location::RequiresFpuRegister()); | 3737 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3546 summary->set_in(1, Location::RequiresRegister()); | 3738 summary->set_in(1, Location::RequiresRegister()); |
| 3547 // Low (< 7) Q register needed for the vmovsr instruction. | 3739 // Low (< 7) Q register needed for the vmovsr instruction. |
| 3548 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3740 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3549 return summary; | 3741 return summary; |
| 3550 } | 3742 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3580 __ vmovsr(sresult2, TMP); | 3772 __ vmovsr(sresult2, TMP); |
| 3581 break; | 3773 break; |
| 3582 case MethodRecognizer::kInt32x4WithFlagW: | 3774 case MethodRecognizer::kInt32x4WithFlagW: |
| 3583 __ vmovsr(sresult3, TMP); | 3775 __ vmovsr(sresult3, TMP); |
| 3584 break; | 3776 break; |
| 3585 default: UNREACHABLE(); | 3777 default: UNREACHABLE(); |
| 3586 } | 3778 } |
| 3587 } | 3779 } |
| 3588 | 3780 |
| 3589 | 3781 |
| 3590 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3782 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 3591 const intptr_t kNumInputs = 1; | 3783 const intptr_t kNumInputs = 1; |
| 3592 const intptr_t kNumTemps = 0; | 3784 const intptr_t kNumTemps = 0; |
| 3593 LocationSummary* summary = | 3785 LocationSummary* summary = |
| 3594 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3786 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3595 summary->set_in(0, Location::RequiresFpuRegister()); | 3787 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3596 summary->set_out(Location::RequiresFpuRegister()); | 3788 summary->set_out(Location::RequiresFpuRegister()); |
| 3597 return summary; | 3789 return summary; |
| 3598 } | 3790 } |
| 3599 | 3791 |
| 3600 | 3792 |
| 3601 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3793 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3602 QRegister value = locs()->in(0).fpu_reg(); | 3794 QRegister value = locs()->in(0).fpu_reg(); |
| 3603 QRegister result = locs()->out().fpu_reg(); | 3795 QRegister result = locs()->out().fpu_reg(); |
| 3604 | 3796 |
| 3605 if (value != result) { | 3797 if (value != result) { |
| 3606 __ vmovq(result, value); | 3798 __ vmovq(result, value); |
| 3607 } | 3799 } |
| 3608 } | 3800 } |
| 3609 | 3801 |
| 3610 | 3802 |
| 3611 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { | 3803 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 3612 const intptr_t kNumInputs = 2; | 3804 const intptr_t kNumInputs = 2; |
| 3613 const intptr_t kNumTemps = 0; | 3805 const intptr_t kNumTemps = 0; |
| 3614 LocationSummary* summary = | 3806 LocationSummary* summary = |
| 3615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3807 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3616 summary->set_in(0, Location::RequiresFpuRegister()); | 3808 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3617 summary->set_in(1, Location::RequiresFpuRegister()); | 3809 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3618 summary->set_out(Location::RequiresFpuRegister()); | 3810 summary->set_out(Location::RequiresFpuRegister()); |
| 3619 return summary; | 3811 return summary; |
| 3620 } | 3812 } |
| 3621 | 3813 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3641 __ vaddqi(kWord, result, left, right); | 3833 __ vaddqi(kWord, result, left, right); |
| 3642 break; | 3834 break; |
| 3643 case Token::kSUB: | 3835 case Token::kSUB: |
| 3644 __ vsubqi(kWord, result, left, right); | 3836 __ vsubqi(kWord, result, left, right); |
| 3645 break; | 3837 break; |
| 3646 default: UNREACHABLE(); | 3838 default: UNREACHABLE(); |
| 3647 } | 3839 } |
| 3648 } | 3840 } |
| 3649 | 3841 |
| 3650 | 3842 |
| 3651 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { | 3843 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
| 3652 if ((kind() == MethodRecognizer::kMathSin) || | 3844 if ((kind() == MethodRecognizer::kMathSin) || |
| 3653 (kind() == MethodRecognizer::kMathCos)) { | 3845 (kind() == MethodRecognizer::kMathCos)) { |
| 3654 const intptr_t kNumInputs = 1; | 3846 const intptr_t kNumInputs = 1; |
| 3655 const intptr_t kNumTemps = 0; | 3847 const intptr_t kNumTemps = 0; |
| 3656 LocationSummary* summary = | 3848 LocationSummary* summary = |
| 3657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3849 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3658 summary->set_in(0, Location::FpuRegisterLocation(Q0)); | 3850 summary->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 3659 summary->set_out(Location::FpuRegisterLocation(Q0)); | 3851 summary->set_out(Location::FpuRegisterLocation(Q0)); |
| 3660 #if !defined(ARM_FLOAT_ABI_HARD) | 3852 #if !defined(ARM_FLOAT_ABI_HARD) |
| 3661 summary->AddTemp(Location::RegisterLocation(R0)); | 3853 summary->AddTemp(Location::RegisterLocation(R0)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3691 __ vmovrrd(R0, R1, D0); | 3883 __ vmovrrd(R0, R1, D0); |
| 3692 __ vmovrrd(R2, R3, D1); | 3884 __ vmovrrd(R2, R3, D1); |
| 3693 __ CallRuntime(TargetFunction(), InputCount()); | 3885 __ CallRuntime(TargetFunction(), InputCount()); |
| 3694 __ vmovdrr(D0, R0, R1); | 3886 __ vmovdrr(D0, R0, R1); |
| 3695 __ vmovdrr(D1, R2, R3); | 3887 __ vmovdrr(D1, R2, R3); |
| 3696 #endif | 3888 #endif |
| 3697 } | 3889 } |
| 3698 } | 3890 } |
| 3699 | 3891 |
| 3700 | 3892 |
| 3701 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3893 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
| 3702 if (result_cid() == kDoubleCid) { | 3894 if (result_cid() == kDoubleCid) { |
| 3703 const intptr_t kNumInputs = 2; | 3895 const intptr_t kNumInputs = 2; |
| 3704 const intptr_t kNumTemps = 1; | 3896 const intptr_t kNumTemps = 1; |
| 3705 LocationSummary* summary = | 3897 LocationSummary* summary = |
| 3706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3898 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3707 summary->set_in(0, Location::RequiresFpuRegister()); | 3899 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3708 summary->set_in(1, Location::RequiresFpuRegister()); | 3900 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3709 // Reuse the left register so that code can be made shorter. | 3901 // Reuse the left register so that code can be made shorter. |
| 3710 summary->set_out(Location::SameAsFirstInput()); | 3902 summary->set_out(Location::SameAsFirstInput()); |
| 3711 summary->set_temp(0, Location::RequiresRegister()); | 3903 summary->set_temp(0, Location::RequiresRegister()); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3776 __ cmp(left, ShifterOperand(right)); | 3968 __ cmp(left, ShifterOperand(right)); |
| 3777 ASSERT(result == left); | 3969 ASSERT(result == left); |
| 3778 if (is_min) { | 3970 if (is_min) { |
| 3779 __ mov(result, ShifterOperand(right), GT); | 3971 __ mov(result, ShifterOperand(right), GT); |
| 3780 } else { | 3972 } else { |
| 3781 __ mov(result, ShifterOperand(right), LT); | 3973 __ mov(result, ShifterOperand(right), LT); |
| 3782 } | 3974 } |
| 3783 } | 3975 } |
| 3784 | 3976 |
| 3785 | 3977 |
| 3786 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3978 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { |
| 3787 const intptr_t kNumInputs = 1; | 3979 const intptr_t kNumInputs = 1; |
| 3788 const intptr_t kNumTemps = 0; | 3980 const intptr_t kNumTemps = 0; |
| 3789 LocationSummary* summary = | 3981 LocationSummary* summary = |
| 3790 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3982 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3791 summary->set_in(0, Location::RequiresRegister()); | 3983 summary->set_in(0, Location::RequiresRegister()); |
| 3792 // We make use of 3-operand instructions by not requiring result register | 3984 // We make use of 3-operand instructions by not requiring result register |
| 3793 // to be identical to first input register as on Intel. | 3985 // to be identical to first input register as on Intel. |
| 3794 summary->set_out(Location::RequiresRegister()); | 3986 summary->set_out(Location::RequiresRegister()); |
| 3795 return summary; | 3987 return summary; |
| 3796 } | 3988 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3811 __ mvn(result, ShifterOperand(value)); | 4003 __ mvn(result, ShifterOperand(value)); |
| 3812 // Remove inverted smi-tag. | 4004 // Remove inverted smi-tag. |
| 3813 __ bic(result, result, ShifterOperand(kSmiTagMask)); | 4005 __ bic(result, result, ShifterOperand(kSmiTagMask)); |
| 3814 break; | 4006 break; |
| 3815 default: | 4007 default: |
| 3816 UNREACHABLE(); | 4008 UNREACHABLE(); |
| 3817 } | 4009 } |
| 3818 } | 4010 } |
| 3819 | 4011 |
| 3820 | 4012 |
| 3821 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { | 4013 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 3822 const intptr_t kNumInputs = 1; | 4014 const intptr_t kNumInputs = 1; |
| 3823 const intptr_t kNumTemps = 0; | 4015 const intptr_t kNumTemps = 0; |
| 3824 LocationSummary* summary = | 4016 LocationSummary* summary = |
| 3825 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4017 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3826 summary->set_in(0, Location::RequiresFpuRegister()); | 4018 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3827 summary->set_out(Location::RequiresFpuRegister()); | 4019 summary->set_out(Location::RequiresFpuRegister()); |
| 3828 return summary; | 4020 return summary; |
| 3829 } | 4021 } |
| 3830 | 4022 |
| 3831 | 4023 |
| 3832 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4024 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3833 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4025 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3834 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4026 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3835 __ vnegd(result, value); | 4027 __ vnegd(result, value); |
| 3836 } | 4028 } |
| 3837 | 4029 |
| 3838 | 4030 |
| 3839 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 4031 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3840 const intptr_t kNumInputs = 1; | 4032 const intptr_t kNumInputs = 1; |
| 3841 const intptr_t kNumTemps = 0; | 4033 const intptr_t kNumTemps = 0; |
| 3842 LocationSummary* result = | 4034 LocationSummary* result = |
| 3843 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4035 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3844 result->set_in(0, Location::WritableRegister()); | 4036 result->set_in(0, Location::WritableRegister()); |
| 3845 result->set_out(Location::RequiresFpuRegister()); | 4037 result->set_out(Location::RequiresFpuRegister()); |
| 3846 return result; | 4038 return result; |
| 3847 } | 4039 } |
| 3848 | 4040 |
| 3849 | 4041 |
| 3850 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4042 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3851 Register value = locs()->in(0).reg(); | 4043 Register value = locs()->in(0).reg(); |
| 3852 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4044 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3853 __ SmiUntag(value); | 4045 __ SmiUntag(value); |
| 3854 __ vmovsr(STMP, value); | 4046 __ vmovsr(STMP, value); |
| 3855 __ vcvtdi(result, STMP); | 4047 __ vcvtdi(result, STMP); |
| 3856 } | 4048 } |
| 3857 | 4049 |
| 3858 | 4050 |
| 3859 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 4051 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { |
| 3860 const intptr_t kNumInputs = 1; | 4052 const intptr_t kNumInputs = 1; |
| 3861 const intptr_t kNumTemps = 0; | 4053 const intptr_t kNumTemps = 0; |
| 3862 LocationSummary* result = | 4054 LocationSummary* result = |
| 3863 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4055 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3864 result->set_in(0, Location::RegisterLocation(R1)); | 4056 result->set_in(0, Location::RegisterLocation(R1)); |
| 3865 result->set_out(Location::RegisterLocation(R0)); | 4057 result->set_out(Location::RegisterLocation(R0)); |
| 3866 return result; | 4058 return result; |
| 3867 } | 4059 } |
| 3868 | 4060 |
| 3869 | 4061 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3901 compiler->GenerateStaticCall(deopt_id(), | 4093 compiler->GenerateStaticCall(deopt_id(), |
| 3902 instance_call()->token_pos(), | 4094 instance_call()->token_pos(), |
| 3903 target, | 4095 target, |
| 3904 kNumberOfArguments, | 4096 kNumberOfArguments, |
| 3905 Object::null_array(), // No argument names., | 4097 Object::null_array(), // No argument names., |
| 3906 locs()); | 4098 locs()); |
| 3907 __ Bind(&done); | 4099 __ Bind(&done); |
| 3908 } | 4100 } |
| 3909 | 4101 |
| 3910 | 4102 |
| 3911 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 4103 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { |
| 3912 const intptr_t kNumInputs = 1; | 4104 const intptr_t kNumInputs = 1; |
| 3913 const intptr_t kNumTemps = 0; | 4105 const intptr_t kNumTemps = 0; |
| 3914 LocationSummary* result = new LocationSummary( | 4106 LocationSummary* result = new LocationSummary( |
| 3915 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4107 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3916 result->set_in(0, Location::RequiresFpuRegister()); | 4108 result->set_in(0, Location::RequiresFpuRegister()); |
| 3917 result->set_out(Location::RequiresRegister()); | 4109 result->set_out(Location::RequiresRegister()); |
| 3918 return result; | 4110 return result; |
| 3919 } | 4111 } |
| 3920 | 4112 |
| 3921 | 4113 |
| 3922 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4114 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3923 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4115 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
| 3924 Register result = locs()->out().reg(); | 4116 Register result = locs()->out().reg(); |
| 3925 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4117 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3926 // First check for NaN. Checking for minint after the conversion doesn't work | 4118 // First check for NaN. Checking for minint after the conversion doesn't work |
| 3927 // on ARM because vcvtid gives 0 for NaN. | 4119 // on ARM because vcvtid gives 0 for NaN. |
| 3928 __ vcmpd(value, value); | 4120 __ vcmpd(value, value); |
| 3929 __ vmstat(); | 4121 __ vmstat(); |
| 3930 __ b(deopt, VS); | 4122 __ b(deopt, VS); |
| 3931 | 4123 |
| 3932 __ vcvtid(STMP, value); | 4124 __ vcvtid(STMP, value); |
| 3933 __ vmovrs(result, STMP); | 4125 __ vmovrs(result, STMP); |
| 3934 // Check for overflow and that it fits into Smi. | 4126 // Check for overflow and that it fits into Smi. |
| 3935 __ CompareImmediate(result, 0xC0000000); | 4127 __ CompareImmediate(result, 0xC0000000); |
| 3936 __ b(deopt, MI); | 4128 __ b(deopt, MI); |
| 3937 __ SmiTag(result); | 4129 __ SmiTag(result); |
| 3938 } | 4130 } |
| 3939 | 4131 |
| 3940 | 4132 |
| 3941 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 4133 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3942 const intptr_t kNumInputs = 1; | 4134 const intptr_t kNumInputs = 1; |
| 3943 const intptr_t kNumTemps = 0; | 4135 const intptr_t kNumTemps = 0; |
| 3944 LocationSummary* result = | 4136 LocationSummary* result = |
| 3945 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4137 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3946 result->set_in(0, Location::RequiresFpuRegister()); | 4138 result->set_in(0, Location::RequiresFpuRegister()); |
| 3947 result->set_out(Location::RequiresFpuRegister()); | 4139 result->set_out(Location::RequiresFpuRegister()); |
| 3948 return result; | 4140 return result; |
| 3949 } | 4141 } |
| 3950 | 4142 |
| 3951 | 4143 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3964 case MethodRecognizer::kDoubleCeil: | 4156 case MethodRecognizer::kDoubleCeil: |
| 3965 UNIMPLEMENTED(); | 4157 UNIMPLEMENTED(); |
| 3966 // __ roundsd(result, value, Assembler::kRoundUp); | 4158 // __ roundsd(result, value, Assembler::kRoundUp); |
| 3967 break; | 4159 break; |
| 3968 default: | 4160 default: |
| 3969 UNREACHABLE(); | 4161 UNREACHABLE(); |
| 3970 } | 4162 } |
| 3971 } | 4163 } |
| 3972 | 4164 |
| 3973 | 4165 |
| 3974 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 4166 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { |
| 3975 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 4167 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 3976 const intptr_t kNumTemps = 0; | 4168 const intptr_t kNumTemps = 0; |
| 3977 LocationSummary* result = | 4169 LocationSummary* result = |
| 3978 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 4170 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 3979 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 4171 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 3980 if (InputCount() == 2) { | 4172 if (InputCount() == 2) { |
| 3981 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 4173 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 3982 } | 4174 } |
| 3983 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4175 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 3984 result->AddTemp(Location::RegisterLocation(R2)); | 4176 result->AddTemp(Location::RegisterLocation(R2)); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4048 __ vmovrrd(R0, R1, D0); | 4240 __ vmovrrd(R0, R1, D0); |
| 4049 __ vmovrrd(R2, R3, D1); | 4241 __ vmovrrd(R2, R3, D1); |
| 4050 __ CallRuntime(TargetFunction(), InputCount()); | 4242 __ CallRuntime(TargetFunction(), InputCount()); |
| 4051 __ vmovdrr(D0, R0, R1); | 4243 __ vmovdrr(D0, R0, R1); |
| 4052 __ vmovdrr(D1, R2, R3); | 4244 __ vmovdrr(D1, R2, R3); |
| 4053 #endif | 4245 #endif |
| 4054 __ Bind(&skip_call); | 4246 __ Bind(&skip_call); |
| 4055 } | 4247 } |
| 4056 | 4248 |
| 4057 | 4249 |
| 4058 LocationSummary* MergedMathInstr::MakeLocationSummary() const { | 4250 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
| 4059 if (kind() == MergedMathInstr::kTruncDivMod) { | 4251 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4060 const intptr_t kNumInputs = 2; | 4252 const intptr_t kNumInputs = 2; |
| 4061 const intptr_t kNumTemps = 4; | 4253 const intptr_t kNumTemps = 4; |
| 4062 LocationSummary* summary = | 4254 LocationSummary* summary = |
| 4063 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4064 summary->set_in(0, Location::RequiresRegister()); | 4256 summary->set_in(0, Location::RequiresRegister()); |
| 4065 summary->set_in(1, Location::RequiresRegister()); | 4257 summary->set_in(1, Location::RequiresRegister()); |
| 4066 summary->set_temp(0, Location::RequiresRegister()); | 4258 summary->set_temp(0, Location::RequiresRegister()); |
| 4067 summary->set_temp(1, Location::RequiresFpuRegister()); | 4259 summary->set_temp(1, Location::RequiresFpuRegister()); |
| 4068 summary->set_temp(2, Location::RequiresRegister()); // result_div. | 4260 summary->set_temp(2, Location::RequiresRegister()); // result_div. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4137 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); | 4329 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); |
| 4138 return; | 4330 return; |
| 4139 } | 4331 } |
| 4140 if (kind() == MergedMathInstr::kSinCos) { | 4332 if (kind() == MergedMathInstr::kSinCos) { |
| 4141 UNIMPLEMENTED(); | 4333 UNIMPLEMENTED(); |
| 4142 } | 4334 } |
| 4143 UNIMPLEMENTED(); | 4335 UNIMPLEMENTED(); |
| 4144 } | 4336 } |
| 4145 | 4337 |
| 4146 | 4338 |
| 4147 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4339 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 4340 bool opt) const { |
| 4148 return MakeCallSummary(); | 4341 return MakeCallSummary(); |
| 4149 } | 4342 } |
| 4150 | 4343 |
| 4151 | 4344 |
| 4152 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4345 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4153 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4346 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 4154 kDeoptPolymorphicInstanceCallTestFail); | 4347 kDeoptPolymorphicInstanceCallTestFail); |
| 4155 if (ic_data().NumberOfChecks() == 0) { | 4348 if (ic_data().NumberOfChecks() == 0) { |
| 4156 __ b(deopt); | 4349 __ b(deopt); |
| 4157 return; | 4350 return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4180 R2, // Class id register. | 4373 R2, // Class id register. |
| 4181 instance_call()->ArgumentCount(), | 4374 instance_call()->ArgumentCount(), |
| 4182 instance_call()->argument_names(), | 4375 instance_call()->argument_names(), |
| 4183 deopt, | 4376 deopt, |
| 4184 deopt_id(), | 4377 deopt_id(), |
| 4185 instance_call()->token_pos(), | 4378 instance_call()->token_pos(), |
| 4186 locs()); | 4379 locs()); |
| 4187 } | 4380 } |
| 4188 | 4381 |
| 4189 | 4382 |
| 4190 LocationSummary* BranchInstr::MakeLocationSummary() const { | 4383 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
| 4191 UNREACHABLE(); | 4384 comparison()->InitializeLocationSummary(opt); |
| 4192 return NULL; | 4385 // Branches don't produce a result. |
| 4386 comparison()->locs()->set_out(Location::NoLocation()); |
| 4387 return comparison()->locs(); |
| 4193 } | 4388 } |
| 4194 | 4389 |
| 4195 | 4390 |
| 4196 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4391 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4197 comparison()->EmitBranchCode(compiler, this); | 4392 comparison()->EmitBranchCode(compiler, this); |
| 4198 } | 4393 } |
| 4199 | 4394 |
| 4200 | 4395 |
| 4201 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 4396 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
| 4202 const intptr_t kNumInputs = 1; | 4397 const intptr_t kNumInputs = 1; |
| 4203 const intptr_t kNumTemps = 0; | 4398 const intptr_t kNumTemps = 0; |
| 4204 LocationSummary* summary = | 4399 LocationSummary* summary = |
| 4205 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4206 summary->set_in(0, Location::RequiresRegister()); | 4401 summary->set_in(0, Location::RequiresRegister()); |
| 4207 if (!IsNullCheck()) { | 4402 if (!IsNullCheck()) { |
| 4208 summary->AddTemp(Location::RequiresRegister()); | 4403 summary->AddTemp(Location::RequiresRegister()); |
| 4209 } | 4404 } |
| 4210 return summary; | 4405 return summary; |
| 4211 } | 4406 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4245 if (i == (num_checks - 1)) { | 4440 if (i == (num_checks - 1)) { |
| 4246 __ b(deopt, NE); | 4441 __ b(deopt, NE); |
| 4247 } else { | 4442 } else { |
| 4248 __ b(&is_ok, EQ); | 4443 __ b(&is_ok, EQ); |
| 4249 } | 4444 } |
| 4250 } | 4445 } |
| 4251 __ Bind(&is_ok); | 4446 __ Bind(&is_ok); |
| 4252 } | 4447 } |
| 4253 | 4448 |
| 4254 | 4449 |
| 4255 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 4450 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { |
| 4256 const intptr_t kNumInputs = 1; | 4451 const intptr_t kNumInputs = 1; |
| 4257 const intptr_t kNumTemps = 0; | 4452 const intptr_t kNumTemps = 0; |
| 4258 LocationSummary* summary = | 4453 LocationSummary* summary = |
| 4259 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4454 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4260 summary->set_in(0, Location::RequiresRegister()); | 4455 summary->set_in(0, Location::RequiresRegister()); |
| 4261 return summary; | 4456 return summary; |
| 4262 } | 4457 } |
| 4263 | 4458 |
| 4264 | 4459 |
| 4265 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4460 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4266 Register value = locs()->in(0).reg(); | 4461 Register value = locs()->in(0).reg(); |
| 4267 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4462 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 4268 kDeoptCheckSmi); | 4463 kDeoptCheckSmi); |
| 4269 __ tst(value, ShifterOperand(kSmiTagMask)); | 4464 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 4270 __ b(deopt, NE); | 4465 __ b(deopt, NE); |
| 4271 } | 4466 } |
| 4272 | 4467 |
| 4273 | 4468 |
| 4274 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 4469 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
| 4275 const intptr_t kNumInputs = 2; | 4470 const intptr_t kNumInputs = 2; |
| 4276 const intptr_t kNumTemps = 0; | 4471 const intptr_t kNumTemps = 0; |
| 4277 LocationSummary* locs = | 4472 LocationSummary* locs = |
| 4278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4473 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4279 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4474 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 4280 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 4475 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 4281 return locs; | 4476 return locs; |
| 4282 } | 4477 } |
| 4283 | 4478 |
| 4284 | 4479 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4317 __ b(deopt, CS); | 4512 __ b(deopt, CS); |
| 4318 } else { | 4513 } else { |
| 4319 Register length = length_loc.reg(); | 4514 Register length = length_loc.reg(); |
| 4320 Register index = index_loc.reg(); | 4515 Register index = index_loc.reg(); |
| 4321 __ cmp(index, ShifterOperand(length)); | 4516 __ cmp(index, ShifterOperand(length)); |
| 4322 __ b(deopt, CS); | 4517 __ b(deopt, CS); |
| 4323 } | 4518 } |
| 4324 } | 4519 } |
| 4325 | 4520 |
| 4326 | 4521 |
| 4327 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 4522 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
| 4328 UNIMPLEMENTED(); | 4523 UNIMPLEMENTED(); |
| 4329 return NULL; | 4524 return NULL; |
| 4330 } | 4525 } |
| 4331 | 4526 |
| 4332 | 4527 |
| 4333 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4528 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4334 UNIMPLEMENTED(); | 4529 UNIMPLEMENTED(); |
| 4335 } | 4530 } |
| 4336 | 4531 |
| 4337 | 4532 |
| 4338 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { | 4533 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const { |
| 4339 UNIMPLEMENTED(); | 4534 UNIMPLEMENTED(); |
| 4340 return NULL; | 4535 return NULL; |
| 4341 } | 4536 } |
| 4342 | 4537 |
| 4343 | 4538 |
| 4344 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4539 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4345 UNIMPLEMENTED(); | 4540 UNIMPLEMENTED(); |
| 4346 } | 4541 } |
| 4347 | 4542 |
| 4348 | 4543 |
| 4349 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 4544 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
| 4350 UNIMPLEMENTED(); | 4545 UNIMPLEMENTED(); |
| 4351 return NULL; | 4546 return NULL; |
| 4352 } | 4547 } |
| 4353 | 4548 |
| 4354 | 4549 |
| 4355 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4550 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4356 UNIMPLEMENTED(); | 4551 UNIMPLEMENTED(); |
| 4357 } | 4552 } |
| 4358 | 4553 |
| 4359 | 4554 |
| 4360 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { | 4555 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
| 4361 UNIMPLEMENTED(); | 4556 UNIMPLEMENTED(); |
| 4362 return NULL; | 4557 return NULL; |
| 4363 } | 4558 } |
| 4364 | 4559 |
| 4365 | 4560 |
| 4366 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4561 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4367 UNIMPLEMENTED(); | 4562 UNIMPLEMENTED(); |
| 4368 } | 4563 } |
| 4369 | 4564 |
| 4370 | 4565 |
| 4371 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { | 4566 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
| 4372 UNIMPLEMENTED(); | 4567 UNIMPLEMENTED(); |
| 4373 return NULL; | 4568 return NULL; |
| 4374 } | 4569 } |
| 4375 | 4570 |
| 4376 | 4571 |
| 4377 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4572 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4378 UNIMPLEMENTED(); | 4573 UNIMPLEMENTED(); |
| 4379 } | 4574 } |
| 4380 | 4575 |
| 4381 | 4576 |
| 4382 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 4577 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const { |
| 4383 return new LocationSummary(0, 0, LocationSummary::kCall); | 4578 return new LocationSummary(0, 0, LocationSummary::kCall); |
| 4384 } | 4579 } |
| 4385 | 4580 |
| 4386 | 4581 |
| 4387 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4582 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4388 compiler->GenerateRuntimeCall(token_pos(), | 4583 compiler->GenerateRuntimeCall(token_pos(), |
| 4389 deopt_id(), | 4584 deopt_id(), |
| 4390 kThrowRuntimeEntry, | 4585 kThrowRuntimeEntry, |
| 4391 1, | 4586 1, |
| 4392 locs()); | 4587 locs()); |
| 4393 __ bkpt(0); | 4588 __ bkpt(0); |
| 4394 } | 4589 } |
| 4395 | 4590 |
| 4396 | 4591 |
| 4397 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 4592 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const { |
| 4398 return new LocationSummary(0, 0, LocationSummary::kCall); | 4593 return new LocationSummary(0, 0, LocationSummary::kCall); |
| 4399 } | 4594 } |
| 4400 | 4595 |
| 4401 | 4596 |
| 4402 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4597 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4403 compiler->SetNeedsStacktrace(catch_try_index()); | 4598 compiler->SetNeedsStacktrace(catch_try_index()); |
| 4404 compiler->GenerateRuntimeCall(token_pos(), | 4599 compiler->GenerateRuntimeCall(token_pos(), |
| 4405 deopt_id(), | 4600 deopt_id(), |
| 4406 kReThrowRuntimeEntry, | 4601 kReThrowRuntimeEntry, |
| 4407 2, | 4602 2, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4428 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4623 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 4429 deopt_id_, | 4624 deopt_id_, |
| 4430 Scanner::kDummyTokenIndex); | 4625 Scanner::kDummyTokenIndex); |
| 4431 } | 4626 } |
| 4432 if (HasParallelMove()) { | 4627 if (HasParallelMove()) { |
| 4433 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 4628 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 4434 } | 4629 } |
| 4435 } | 4630 } |
| 4436 | 4631 |
| 4437 | 4632 |
| 4438 LocationSummary* GotoInstr::MakeLocationSummary() const { | 4633 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { |
| 4439 return new LocationSummary(0, 0, LocationSummary::kNoCall); | 4634 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
| 4440 } | 4635 } |
| 4441 | 4636 |
| 4442 | 4637 |
| 4443 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4638 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4444 if (!compiler->is_optimizing()) { | 4639 if (!compiler->is_optimizing()) { |
| 4445 compiler->EmitEdgeCounter(); | 4640 compiler->EmitEdgeCounter(); |
| 4446 // Add a deoptimization descriptor for deoptimizing instructions that | 4641 // Add a deoptimization descriptor for deoptimizing instructions that |
| 4447 // may be inserted before this instruction. On ARM this descriptor | 4642 // may be inserted before this instruction. On ARM this descriptor |
| 4448 // points after the edge counter code so that we can reuse the same | 4643 // points after the edge counter code so that we can reuse the same |
| 4449 // pattern matching code as at call sites, which matches backwards from | 4644 // pattern matching code as at call sites, which matches backwards from |
| 4450 // the end of the pattern. | 4645 // the end of the pattern. |
| 4451 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4646 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 4452 GetDeoptId(), | 4647 GetDeoptId(), |
| 4453 Scanner::kDummyTokenIndex); | 4648 Scanner::kDummyTokenIndex); |
| 4454 } | 4649 } |
| 4455 if (HasParallelMove()) { | 4650 if (HasParallelMove()) { |
| 4456 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 4651 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 4457 } | 4652 } |
| 4458 | 4653 |
| 4459 // We can fall through if the successor is the next block in the list. | 4654 // We can fall through if the successor is the next block in the list. |
| 4460 // Otherwise, we need a jump. | 4655 // Otherwise, we need a jump. |
| 4461 if (!compiler->CanFallThroughTo(successor())) { | 4656 if (!compiler->CanFallThroughTo(successor())) { |
| 4462 __ b(compiler->GetJumpLabel(successor())); | 4657 __ b(compiler->GetJumpLabel(successor())); |
| 4463 } | 4658 } |
| 4464 } | 4659 } |
| 4465 | 4660 |
| 4466 | 4661 |
| 4467 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 4662 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
| 4468 return LocationSummary::Make(0, | 4663 return LocationSummary::Make(0, |
| 4469 Location::RequiresRegister(), | 4664 Location::RequiresRegister(), |
| 4470 LocationSummary::kNoCall); | 4665 LocationSummary::kNoCall); |
| 4471 } | 4666 } |
| 4472 | 4667 |
| 4473 | 4668 |
| 4474 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4669 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4475 __ mov(locs()->out().reg(), ShifterOperand(CTX)); | 4670 __ mov(locs()->out().reg(), ShifterOperand(CTX)); |
| 4476 } | 4671 } |
| 4477 | 4672 |
| 4478 | 4673 |
| 4479 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { | 4674 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
| 4480 const intptr_t kNumInputs = 2; | 4675 const intptr_t kNumInputs = 2; |
| 4481 const intptr_t kNumTemps = 0; | 4676 const intptr_t kNumTemps = 0; |
| 4482 if (needs_number_check()) { | 4677 if (needs_number_check()) { |
| 4483 LocationSummary* locs = | 4678 LocationSummary* locs = |
| 4484 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 4485 locs->set_in(0, Location::RegisterLocation(R0)); | 4680 locs->set_in(0, Location::RegisterLocation(R0)); |
| 4486 locs->set_in(1, Location::RegisterLocation(R1)); | 4681 locs->set_in(1, Location::RegisterLocation(R1)); |
| 4487 locs->set_out(Location::RegisterLocation(R0)); | 4682 locs->set_out(Location::RegisterLocation(R0)); |
| 4488 return locs; | 4683 return locs; |
| 4489 } | 4684 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4542 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 4737 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 4543 BranchInstr* branch) { | 4738 BranchInstr* branch) { |
| 4544 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4739 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 4545 | 4740 |
| 4546 BranchLabels labels = compiler->CreateBranchLabels(branch); | 4741 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 4547 Condition true_condition = EmitComparisonCode(compiler, labels); | 4742 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 4548 EmitBranchOnCondition(compiler, true_condition, labels); | 4743 EmitBranchOnCondition(compiler, true_condition, labels); |
| 4549 } | 4744 } |
| 4550 | 4745 |
| 4551 | 4746 |
| 4552 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { | 4747 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
| 4553 return LocationSummary::Make(1, | 4748 return LocationSummary::Make(1, |
| 4554 Location::RequiresRegister(), | 4749 Location::RequiresRegister(), |
| 4555 LocationSummary::kNoCall); | 4750 LocationSummary::kNoCall); |
| 4556 } | 4751 } |
| 4557 | 4752 |
| 4558 | 4753 |
| 4559 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4754 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4560 Register value = locs()->in(0).reg(); | 4755 Register value = locs()->in(0).reg(); |
| 4561 Register result = locs()->out().reg(); | 4756 Register result = locs()->out().reg(); |
| 4562 | 4757 |
| 4563 __ LoadObject(result, Bool::True()); | 4758 __ LoadObject(result, Bool::True()); |
| 4564 __ cmp(result, ShifterOperand(value)); | 4759 __ cmp(result, ShifterOperand(value)); |
| 4565 __ LoadObject(result, Bool::False(), EQ); | 4760 __ LoadObject(result, Bool::False(), EQ); |
| 4566 } | 4761 } |
| 4567 | 4762 |
| 4568 | 4763 |
| 4569 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 4764 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const { |
| 4570 const intptr_t kNumInputs = 2; | 4765 const intptr_t kNumInputs = 2; |
| 4571 const intptr_t kNumTemps = 0; | 4766 const intptr_t kNumTemps = 0; |
| 4572 LocationSummary* locs = | 4767 LocationSummary* locs = |
| 4573 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4768 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4574 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 4769 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 4575 : Location::RequiresRegister()); | 4770 : Location::RequiresRegister()); |
| 4576 locs->set_in(1, Location::RequiresRegister()); | 4771 locs->set_in(1, Location::RequiresRegister()); |
| 4577 return locs; | 4772 return locs; |
| 4578 } | 4773 } |
| 4579 | 4774 |
| 4580 | 4775 |
| 4581 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4776 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4582 Register value_reg = locs()->in(0).reg(); | 4777 Register value_reg = locs()->in(0).reg(); |
| 4583 Register dest_reg = locs()->in(1).reg(); | 4778 Register dest_reg = locs()->in(1).reg(); |
| 4584 | 4779 |
| 4585 if (value()->NeedsStoreBuffer()) { | 4780 if (value()->NeedsStoreBuffer()) { |
| 4586 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), | 4781 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
| 4587 value_reg); | 4782 value_reg); |
| 4588 } else { | 4783 } else { |
| 4589 __ StoreIntoObjectNoBarrier( | 4784 __ StoreIntoObjectNoBarrier( |
| 4590 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4785 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
| 4591 } | 4786 } |
| 4592 } | 4787 } |
| 4593 | 4788 |
| 4594 | 4789 |
| 4595 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 4790 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
| 4596 return MakeCallSummary(); | 4791 return MakeCallSummary(); |
| 4597 } | 4792 } |
| 4598 | 4793 |
| 4599 | 4794 |
| 4600 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4795 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4601 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 4796 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
| 4602 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 4797 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
| 4603 compiler->GenerateCall(token_pos(), | 4798 compiler->GenerateCall(token_pos(), |
| 4604 &label, | 4799 &label, |
| 4605 PcDescriptors::kOther, | 4800 PcDescriptors::kOther, |
| 4606 locs()); | 4801 locs()); |
| 4607 __ Drop(ArgumentCount()); // Discard arguments. | 4802 __ Drop(ArgumentCount()); // Discard arguments. |
| 4608 } | 4803 } |
| 4609 | 4804 |
| 4610 | 4805 |
| 4611 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { | 4806 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const { |
| 4612 return MakeCallSummary(); | 4807 return MakeCallSummary(); |
| 4613 } | 4808 } |
| 4614 | 4809 |
| 4615 | 4810 |
| 4616 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4811 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4617 const Function& closure_function = function(); | 4812 const Function& closure_function = function(); |
| 4618 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); | 4813 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); |
| 4619 const Code& stub = Code::Handle( | 4814 const Code& stub = Code::Handle( |
| 4620 StubCode::GetAllocationStubForClosure(closure_function)); | 4815 StubCode::GetAllocationStubForClosure(closure_function)); |
| 4621 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 4816 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 4622 compiler->GenerateCall(token_pos(), | 4817 compiler->GenerateCall(token_pos(), |
| 4623 &label, | 4818 &label, |
| 4624 PcDescriptors::kOther, | 4819 PcDescriptors::kOther, |
| 4625 locs()); | 4820 locs()); |
| 4626 __ Drop(2); // Discard type arguments and receiver. | 4821 __ Drop(2); // Discard type arguments and receiver. |
| 4627 } | 4822 } |
| 4628 | 4823 |
| 4629 } // namespace dart | 4824 } // namespace dart |
| 4630 | 4825 |
| 4631 #endif // defined TARGET_ARCH_ARM | 4826 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |