| 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 11 matching lines...) Expand all Loading... |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DECLARE_FLAG(int, optimization_counter_threshold); | 24 DECLARE_FLAG(int, optimization_counter_threshold); |
| 25 DECLARE_FLAG(bool, propagate_ic_data); | 25 DECLARE_FLAG(bool, propagate_ic_data); |
| 26 DECLARE_FLAG(bool, use_osr); | 26 DECLARE_FLAG(bool, use_osr); |
| 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(0, Location::RegisterLocation(R0)); |
| 33 return result; | 33 return result; |
| 34 } | 34 } |
| 35 | 35 |
| 36 | 36 |
| 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) 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())); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { | 125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { |
| 126 comparison()->InitializeLocationSummary(opt); | 126 comparison()->InitializeLocationSummary(opt); |
| 127 return comparison()->locs(); | 127 return comparison()->locs(); |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 132 const Register result = locs()->out().reg(); | 132 const Register result = locs()->out(0).reg(); |
| 133 | 133 |
| 134 Location left = locs()->in(0); | 134 Location left = locs()->in(0); |
| 135 Location right = locs()->in(1); | 135 Location right = locs()->in(1); |
| 136 ASSERT(!left.IsConstant() || !right.IsConstant()); | 136 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 137 | 137 |
| 138 // Clear out register. | 138 // Clear out register. |
| 139 __ eor(result, result, ShifterOperand(result)); | 139 __ eor(result, result, ShifterOperand(result)); |
| 140 | 140 |
| 141 // Emit comparison code. This must not overwrite the result register. | 141 // Emit comparison code. This must not overwrite the result register. |
| 142 BranchLabels labels = { NULL, NULL, NULL }; | 142 BranchLabels labels = { NULL, NULL, NULL }; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 | 183 |
| 184 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { | 184 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
| 185 const intptr_t kNumInputs = 0; | 185 const intptr_t kNumInputs = 0; |
| 186 const intptr_t kNumTemps = 1; | 186 const intptr_t kNumTemps = 1; |
| 187 LocationSummary* result = | 187 LocationSummary* result = |
| 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 189 result->set_out(Location::RegisterLocation(R0)); | 189 result->set_out(0, Location::RegisterLocation(R0)); |
| 190 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. | 190 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. |
| 191 return result; | 191 return result; |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 195 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 196 // The arguments to the stub include the closure, as does the arguments | 196 // The arguments to the stub include the closure, as does the arguments |
| 197 // descriptor. | 197 // descriptor. |
| 198 Register temp_reg = locs()->temp(0).reg(); | 198 Register temp_reg = locs()->temp(0).reg(); |
| 199 int argument_count = ArgumentCount(); | 199 int argument_count = ArgumentCount(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 212 | 212 |
| 213 | 213 |
| 214 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { | 214 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
| 215 return LocationSummary::Make(0, | 215 return LocationSummary::Make(0, |
| 216 Location::RequiresRegister(), | 216 Location::RequiresRegister(), |
| 217 LocationSummary::kNoCall); | 217 LocationSummary::kNoCall); |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 221 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 222 Register result = locs()->out().reg(); | 222 Register result = locs()->out(0).reg(); |
| 223 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); | 223 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); |
| 224 } | 224 } |
| 225 | 225 |
| 226 | 226 |
| 227 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { | 227 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
| 228 return LocationSummary::Make(1, | 228 return LocationSummary::Make(1, |
| 229 Location::SameAsFirstInput(), | 229 Location::SameAsFirstInput(), |
| 230 LocationSummary::kNoCall); | 230 LocationSummary::kNoCall); |
| 231 } | 231 } |
| 232 | 232 |
| 233 | 233 |
| 234 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 234 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 235 Register value = locs()->in(0).reg(); | 235 Register value = locs()->in(0).reg(); |
| 236 Register result = locs()->out().reg(); | 236 Register result = locs()->out(0).reg(); |
| 237 ASSERT(result == value); // Assert that register assignment is correct. | 237 ASSERT(result == value); // Assert that register assignment is correct. |
| 238 __ str(value, Address(FP, local().index() * kWordSize)); | 238 __ str(value, Address(FP, local().index() * kWordSize)); |
| 239 } | 239 } |
| 240 | 240 |
| 241 | 241 |
| 242 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { | 242 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
| 243 return LocationSummary::Make(0, | 243 return LocationSummary::Make(0, |
| 244 Location::RequiresRegister(), | 244 Location::RequiresRegister(), |
| 245 LocationSummary::kNoCall); | 245 LocationSummary::kNoCall); |
| 246 } | 246 } |
| 247 | 247 |
| 248 | 248 |
| 249 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 249 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 250 // The register allocator drops constant definitions that have no uses. | 250 // The register allocator drops constant definitions that have no uses. |
| 251 if (!locs()->out().IsInvalid()) { | 251 if (!locs()->out(0).IsInvalid()) { |
| 252 Register result = locs()->out().reg(); | 252 Register result = locs()->out(0).reg(); |
| 253 __ LoadObject(result, value()); | 253 __ LoadObject(result, value()); |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 | 257 |
| 258 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { | 258 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { |
| 259 const intptr_t kNumInputs = 3; | 259 const intptr_t kNumInputs = 3; |
| 260 const intptr_t kNumTemps = 0; | 260 const intptr_t kNumTemps = 0; |
| 261 LocationSummary* summary = | 261 LocationSummary* summary = |
| 262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 263 summary->set_in(0, Location::RegisterLocation(R0)); // Value. | 263 summary->set_in(0, Location::RegisterLocation(R0)); // Value. |
| 264 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. | 264 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. |
| 265 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. | 265 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. |
| 266 summary->set_out(Location::RegisterLocation(R0)); | 266 summary->set_out(0, Location::RegisterLocation(R0)); |
| 267 return summary; | 267 return summary; |
| 268 } | 268 } |
| 269 | 269 |
| 270 | 270 |
| 271 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { | 271 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { |
| 272 const intptr_t kNumInputs = 1; | 272 const intptr_t kNumInputs = 1; |
| 273 const intptr_t kNumTemps = 0; | 273 const intptr_t kNumTemps = 0; |
| 274 LocationSummary* locs = | 274 LocationSummary* locs = |
| 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 276 locs->set_in(0, Location::RegisterLocation(R0)); | 276 locs->set_in(0, Location::RegisterLocation(R0)); |
| 277 locs->set_out(Location::RegisterLocation(R0)); | 277 locs->set_out(0, Location::RegisterLocation(R0)); |
| 278 return locs; | 278 return locs; |
| 279 } | 279 } |
| 280 | 280 |
| 281 | 281 |
| 282 static void EmitAssertBoolean(Register reg, | 282 static void EmitAssertBoolean(Register reg, |
| 283 intptr_t token_pos, | 283 intptr_t token_pos, |
| 284 intptr_t deopt_id, | 284 intptr_t deopt_id, |
| 285 LocationSummary* locs, | 285 LocationSummary* locs, |
| 286 FlowGraphCompiler* compiler) { | 286 FlowGraphCompiler* compiler) { |
| 287 // Check that the type of the value is allowed in conditional context. | 287 // Check that the type of the value is allowed in conditional context. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 300 1, | 300 1, |
| 301 locs); | 301 locs); |
| 302 // We should never return here. | 302 // We should never return here. |
| 303 __ bkpt(0); | 303 __ bkpt(0); |
| 304 __ Bind(&done); | 304 __ Bind(&done); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 308 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 309 Register obj = locs()->in(0).reg(); | 309 Register obj = locs()->in(0).reg(); |
| 310 Register result = locs()->out().reg(); | 310 Register result = locs()->out(0).reg(); |
| 311 | 311 |
| 312 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); | 312 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); |
| 313 ASSERT(obj == result); | 313 ASSERT(obj == result); |
| 314 } | 314 } |
| 315 | 315 |
| 316 | 316 |
| 317 static Condition TokenKindToSmiCondition(Token::Kind kind) { | 317 static Condition TokenKindToSmiCondition(Token::Kind kind) { |
| 318 switch (kind) { | 318 switch (kind) { |
| 319 case Token::kEQ: return EQ; | 319 case Token::kEQ: return EQ; |
| 320 case Token::kNE: return NE; | 320 case Token::kNE: return NE; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 331 | 331 |
| 332 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { | 332 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
| 333 const intptr_t kNumInputs = 2; | 333 const intptr_t kNumInputs = 2; |
| 334 if (operation_cid() == kMintCid) { | 334 if (operation_cid() == kMintCid) { |
| 335 const intptr_t kNumTemps = 1; | 335 const intptr_t kNumTemps = 1; |
| 336 LocationSummary* locs = | 336 LocationSummary* locs = |
| 337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 338 locs->set_in(0, Location::RequiresFpuRegister()); | 338 locs->set_in(0, Location::RequiresFpuRegister()); |
| 339 locs->set_in(1, Location::RequiresFpuRegister()); | 339 locs->set_in(1, Location::RequiresFpuRegister()); |
| 340 locs->set_temp(0, Location::RequiresRegister()); | 340 locs->set_temp(0, Location::RequiresRegister()); |
| 341 locs->set_out(Location::RequiresRegister()); | 341 locs->set_out(0, Location::RequiresRegister()); |
| 342 return locs; | 342 return locs; |
| 343 } | 343 } |
| 344 if (operation_cid() == kDoubleCid) { | 344 if (operation_cid() == kDoubleCid) { |
| 345 const intptr_t kNumTemps = 0; | 345 const intptr_t kNumTemps = 0; |
| 346 LocationSummary* locs = | 346 LocationSummary* locs = |
| 347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 348 locs->set_in(0, Location::RequiresFpuRegister()); | 348 locs->set_in(0, Location::RequiresFpuRegister()); |
| 349 locs->set_in(1, Location::RequiresFpuRegister()); | 349 locs->set_in(1, Location::RequiresFpuRegister()); |
| 350 locs->set_out(Location::RequiresRegister()); | 350 locs->set_out(0, Location::RequiresRegister()); |
| 351 return locs; | 351 return locs; |
| 352 } | 352 } |
| 353 if (operation_cid() == kSmiCid) { | 353 if (operation_cid() == kSmiCid) { |
| 354 const intptr_t kNumTemps = 0; | 354 const intptr_t kNumTemps = 0; |
| 355 LocationSummary* locs = | 355 LocationSummary* locs = |
| 356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 357 locs->set_in(0, Location::RegisterOrConstant(left())); | 357 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 358 // Only one input can be a constant operand. The case of two constant | 358 // Only one input can be a constant operand. The case of two constant |
| 359 // operands should be handled by constant propagation. | 359 // operands should be handled by constant propagation. |
| 360 locs->set_in(1, locs->in(0).IsConstant() | 360 locs->set_in(1, locs->in(0).IsConstant() |
| 361 ? Location::RequiresRegister() | 361 ? Location::RequiresRegister() |
| 362 : Location::RegisterOrConstant(right())); | 362 : Location::RegisterOrConstant(right())); |
| 363 locs->set_out(Location::RequiresRegister()); | 363 locs->set_out(0, Location::RequiresRegister()); |
| 364 return locs; | 364 return locs; |
| 365 } | 365 } |
| 366 UNREACHABLE(); | 366 UNREACHABLE(); |
| 367 return NULL; | 367 return NULL; |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 static void LoadValueCid(FlowGraphCompiler* compiler, | 371 static void LoadValueCid(FlowGraphCompiler* compiler, |
| 372 Register value_cid_reg, | 372 Register value_cid_reg, |
| 373 Register value_reg, | 373 Register value_reg, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 } | 486 } |
| 487 | 487 |
| 488 | 488 |
| 489 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 489 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 490 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 490 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 491 | 491 |
| 492 // The ARM code does not use true- and false-labels here. | 492 // The ARM code does not use true- and false-labels here. |
| 493 BranchLabels labels = { NULL, NULL, NULL }; | 493 BranchLabels labels = { NULL, NULL, NULL }; |
| 494 Condition true_condition = EmitComparisonCode(compiler, labels); | 494 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 495 | 495 |
| 496 Register result = locs()->out().reg(); | 496 Register result = locs()->out(0).reg(); |
| 497 if (operation_cid() == kSmiCid) { | 497 if (operation_cid() == kSmiCid) { |
| 498 __ LoadObject(result, Bool::True(), true_condition); | 498 __ LoadObject(result, Bool::True(), true_condition); |
| 499 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); | 499 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); |
| 500 } else { | 500 } else { |
| 501 ASSERT(operation_cid() == kDoubleCid); | 501 ASSERT(operation_cid() == kDoubleCid); |
| 502 Label done; | 502 Label done; |
| 503 __ LoadObject(result, Bool::False()); | 503 __ LoadObject(result, Bool::False()); |
| 504 if (true_condition != NE) { | 504 if (true_condition != NE) { |
| 505 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. | 505 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. |
| 506 } | 506 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 const intptr_t kNumInputs = 2; | 573 const intptr_t kNumInputs = 2; |
| 574 const intptr_t kNumTemps = 0; | 574 const intptr_t kNumTemps = 0; |
| 575 if (operation_cid() == kMintCid) { | 575 if (operation_cid() == kMintCid) { |
| 576 const intptr_t kNumTemps = 2; | 576 const intptr_t kNumTemps = 2; |
| 577 LocationSummary* locs = | 577 LocationSummary* locs = |
| 578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 579 locs->set_in(0, Location::RequiresFpuRegister()); | 579 locs->set_in(0, Location::RequiresFpuRegister()); |
| 580 locs->set_in(1, Location::RequiresFpuRegister()); | 580 locs->set_in(1, Location::RequiresFpuRegister()); |
| 581 locs->set_temp(0, Location::RequiresRegister()); | 581 locs->set_temp(0, Location::RequiresRegister()); |
| 582 locs->set_temp(1, Location::RequiresRegister()); | 582 locs->set_temp(1, Location::RequiresRegister()); |
| 583 locs->set_out(Location::RequiresRegister()); | 583 locs->set_out(0, Location::RequiresRegister()); |
| 584 return locs; | 584 return locs; |
| 585 } | 585 } |
| 586 if (operation_cid() == kDoubleCid) { | 586 if (operation_cid() == kDoubleCid) { |
| 587 LocationSummary* summary = | 587 LocationSummary* summary = |
| 588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 589 summary->set_in(0, Location::RequiresFpuRegister()); | 589 summary->set_in(0, Location::RequiresFpuRegister()); |
| 590 summary->set_in(1, Location::RequiresFpuRegister()); | 590 summary->set_in(1, Location::RequiresFpuRegister()); |
| 591 summary->set_out(Location::RequiresRegister()); | 591 summary->set_out(0, Location::RequiresRegister()); |
| 592 return summary; | 592 return summary; |
| 593 } | 593 } |
| 594 ASSERT(operation_cid() == kSmiCid); | 594 ASSERT(operation_cid() == kSmiCid); |
| 595 LocationSummary* summary = | 595 LocationSummary* summary = |
| 596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 597 summary->set_in(0, Location::RegisterOrConstant(left())); | 597 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 598 // Only one input can be a constant operand. The case of two constant | 598 // Only one input can be a constant operand. The case of two constant |
| 599 // operands should be handled by constant propagation. | 599 // operands should be handled by constant propagation. |
| 600 summary->set_in(1, summary->in(0).IsConstant() | 600 summary->set_in(1, summary->in(0).IsConstant() |
| 601 ? Location::RequiresRegister() | 601 ? Location::RequiresRegister() |
| 602 : Location::RegisterOrConstant(right())); | 602 : Location::RegisterOrConstant(right())); |
| 603 summary->set_out(Location::RequiresRegister()); | 603 summary->set_out(0, Location::RequiresRegister()); |
| 604 return summary; | 604 return summary; |
| 605 } | 605 } |
| 606 | 606 |
| 607 | 607 |
| 608 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 608 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 609 BranchLabels labels) { | 609 BranchLabels labels) { |
| 610 if (operation_cid() == kSmiCid) { | 610 if (operation_cid() == kSmiCid) { |
| 611 return EmitSmiComparisonOp(compiler, locs(), kind()); | 611 return EmitSmiComparisonOp(compiler, locs(), kind()); |
| 612 } else { | 612 } else { |
| 613 ASSERT(operation_cid() == kDoubleCid); | 613 ASSERT(operation_cid() == kDoubleCid); |
| 614 return EmitDoubleComparisonOp(compiler, locs(), kind()); | 614 return EmitDoubleComparisonOp(compiler, locs(), kind()); |
| 615 } | 615 } |
| 616 } | 616 } |
| 617 | 617 |
| 618 | 618 |
| 619 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 619 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 620 // The ARM code does not use true- and false-labels here. | 620 // The ARM code does not use true- and false-labels here. |
| 621 BranchLabels labels = { NULL, NULL, NULL }; | 621 BranchLabels labels = { NULL, NULL, NULL }; |
| 622 Condition true_condition = EmitComparisonCode(compiler, labels); | 622 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 623 | 623 |
| 624 Register result = locs()->out().reg(); | 624 Register result = locs()->out(0).reg(); |
| 625 if (operation_cid() == kSmiCid) { | 625 if (operation_cid() == kSmiCid) { |
| 626 __ LoadObject(result, Bool::True(), true_condition); | 626 __ LoadObject(result, Bool::True(), true_condition); |
| 627 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); | 627 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); |
| 628 } else { | 628 } else { |
| 629 ASSERT(operation_cid() == kDoubleCid); | 629 ASSERT(operation_cid() == kDoubleCid); |
| 630 Label done; | 630 Label done; |
| 631 __ LoadObject(result, Bool::False()); | 631 __ LoadObject(result, Bool::False()); |
| 632 if (true_condition != NE) { | 632 if (true_condition != NE) { |
| 633 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. | 633 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. |
| 634 } | 634 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 653 | 653 |
| 654 | 654 |
| 655 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { | 655 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
| 656 const intptr_t kNumInputs = 0; | 656 const intptr_t kNumInputs = 0; |
| 657 const intptr_t kNumTemps = 3; | 657 const intptr_t kNumTemps = 3; |
| 658 LocationSummary* locs = | 658 LocationSummary* locs = |
| 659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 660 locs->set_temp(0, Location::RegisterLocation(R1)); | 660 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 661 locs->set_temp(1, Location::RegisterLocation(R2)); | 661 locs->set_temp(1, Location::RegisterLocation(R2)); |
| 662 locs->set_temp(2, Location::RegisterLocation(R5)); | 662 locs->set_temp(2, Location::RegisterLocation(R5)); |
| 663 locs->set_out(Location::RegisterLocation(R0)); | 663 locs->set_out(0, Location::RegisterLocation(R0)); |
| 664 return locs; | 664 return locs; |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 668 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 669 ASSERT(locs()->temp(0).reg() == R1); | 669 ASSERT(locs()->temp(0).reg() == R1); |
| 670 ASSERT(locs()->temp(1).reg() == R2); | 670 ASSERT(locs()->temp(1).reg() == R2); |
| 671 ASSERT(locs()->temp(2).reg() == R5); | 671 ASSERT(locs()->temp(2).reg() == R5); |
| 672 Register result = locs()->out().reg(); | 672 Register result = locs()->out(0).reg(); |
| 673 | 673 |
| 674 // Push the result place holder initialized to NULL. | 674 // Push the result place holder initialized to NULL. |
| 675 __ PushObject(Object::ZoneHandle()); | 675 __ PushObject(Object::ZoneHandle()); |
| 676 // Pass a pointer to the first argument in R2. | 676 // Pass a pointer to the first argument in R2. |
| 677 if (!function().HasOptionalParameters()) { | 677 if (!function().HasOptionalParameters()) { |
| 678 __ AddImmediate(R2, FP, (kParamEndSlotFromFp + | 678 __ AddImmediate(R2, FP, (kParamEndSlotFromFp + |
| 679 function().NumParameters()) * kWordSize); | 679 function().NumParameters()) * kWordSize); |
| 680 } else { | 680 } else { |
| 681 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize); | 681 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize); |
| 682 } | 682 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 const intptr_t kNumInputs = 1; | 717 const intptr_t kNumInputs = 1; |
| 718 // TODO(fschneider): Allow immediate operands for the char code. | 718 // TODO(fschneider): Allow immediate operands for the char code. |
| 719 return LocationSummary::Make(kNumInputs, | 719 return LocationSummary::Make(kNumInputs, |
| 720 Location::RequiresRegister(), | 720 Location::RequiresRegister(), |
| 721 LocationSummary::kNoCall); | 721 LocationSummary::kNoCall); |
| 722 } | 722 } |
| 723 | 723 |
| 724 | 724 |
| 725 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 725 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 726 Register char_code = locs()->in(0).reg(); | 726 Register char_code = locs()->in(0).reg(); |
| 727 Register result = locs()->out().reg(); | 727 Register result = locs()->out(0).reg(); |
| 728 __ LoadImmediate(result, | 728 __ LoadImmediate(result, |
| 729 reinterpret_cast<uword>(Symbols::PredefinedAddress())); | 729 reinterpret_cast<uword>(Symbols::PredefinedAddress())); |
| 730 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); | 730 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
| 731 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. | 731 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. |
| 732 } | 732 } |
| 733 | 733 |
| 734 | 734 |
| 735 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { | 735 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { |
| 736 const intptr_t kNumInputs = 1; | 736 const intptr_t kNumInputs = 1; |
| 737 return LocationSummary::Make(kNumInputs, | 737 return LocationSummary::Make(kNumInputs, |
| 738 Location::RequiresRegister(), | 738 Location::RequiresRegister(), |
| 739 LocationSummary::kNoCall); | 739 LocationSummary::kNoCall); |
| 740 } | 740 } |
| 741 | 741 |
| 742 | 742 |
| 743 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 743 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 744 ASSERT(cid_ == kOneByteStringCid); | 744 ASSERT(cid_ == kOneByteStringCid); |
| 745 Register str = locs()->in(0).reg(); | 745 Register str = locs()->in(0).reg(); |
| 746 Register result = locs()->out().reg(); | 746 Register result = locs()->out(0).reg(); |
| 747 __ ldr(result, FieldAddress(str, String::length_offset())); | 747 __ ldr(result, FieldAddress(str, String::length_offset())); |
| 748 __ cmp(result, ShifterOperand(Smi::RawValue(1))); | 748 __ cmp(result, ShifterOperand(Smi::RawValue(1))); |
| 749 __ LoadImmediate(result, Smi::RawValue(-1), NE); | 749 __ LoadImmediate(result, Smi::RawValue(-1), NE); |
| 750 __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ); | 750 __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ); |
| 751 __ SmiTag(result); | 751 __ SmiTag(result); |
| 752 } | 752 } |
| 753 | 753 |
| 754 | 754 |
| 755 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { | 755 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { |
| 756 const intptr_t kNumInputs = 1; | 756 const intptr_t kNumInputs = 1; |
| 757 const intptr_t kNumTemps = 0; | 757 const intptr_t kNumTemps = 0; |
| 758 LocationSummary* summary = | 758 LocationSummary* summary = |
| 759 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 759 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 760 summary->set_in(0, Location::RegisterLocation(R0)); | 760 summary->set_in(0, Location::RegisterLocation(R0)); |
| 761 summary->set_out(Location::RegisterLocation(R0)); | 761 summary->set_out(0, Location::RegisterLocation(R0)); |
| 762 return summary; | 762 return summary; |
| 763 } | 763 } |
| 764 | 764 |
| 765 | 765 |
| 766 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 766 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 767 Register array = locs()->in(0).reg(); | 767 Register array = locs()->in(0).reg(); |
| 768 __ Push(array); | 768 __ Push(array); |
| 769 const int kNumberOfArguments = 1; | 769 const int kNumberOfArguments = 1; |
| 770 const Array& kNoArgumentNames = Object::null_array(); | 770 const Array& kNoArgumentNames = Object::null_array(); |
| 771 compiler->GenerateStaticCall(deopt_id(), | 771 compiler->GenerateStaticCall(deopt_id(), |
| 772 token_pos(), | 772 token_pos(), |
| 773 CallFunction(), | 773 CallFunction(), |
| 774 kNumberOfArguments, | 774 kNumberOfArguments, |
| 775 kNoArgumentNames, | 775 kNoArgumentNames, |
| 776 locs()); | 776 locs()); |
| 777 ASSERT(locs()->out().reg() == R0); | 777 ASSERT(locs()->out(0).reg() == R0); |
| 778 } | 778 } |
| 779 | 779 |
| 780 | 780 |
| 781 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { | 781 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
| 782 const intptr_t kNumInputs = 1; | 782 const intptr_t kNumInputs = 1; |
| 783 return LocationSummary::Make(kNumInputs, | 783 return LocationSummary::Make(kNumInputs, |
| 784 Location::RequiresRegister(), | 784 Location::RequiresRegister(), |
| 785 LocationSummary::kNoCall); | 785 LocationSummary::kNoCall); |
| 786 } | 786 } |
| 787 | 787 |
| 788 | 788 |
| 789 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 789 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 790 Register object = locs()->in(0).reg(); | 790 Register object = locs()->in(0).reg(); |
| 791 Register result = locs()->out().reg(); | 791 Register result = locs()->out(0).reg(); |
| 792 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); | 792 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); |
| 793 } | 793 } |
| 794 | 794 |
| 795 | 795 |
| 796 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { | 796 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { |
| 797 const intptr_t kNumInputs = 1; | 797 const intptr_t kNumInputs = 1; |
| 798 return LocationSummary::Make(kNumInputs, | 798 return LocationSummary::Make(kNumInputs, |
| 799 Location::RequiresRegister(), | 799 Location::RequiresRegister(), |
| 800 LocationSummary::kNoCall); | 800 LocationSummary::kNoCall); |
| 801 } | 801 } |
| 802 | 802 |
| 803 | 803 |
| 804 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 804 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 805 Register object = locs()->in(0).reg(); | 805 Register object = locs()->in(0).reg(); |
| 806 Register result = locs()->out().reg(); | 806 Register result = locs()->out(0).reg(); |
| 807 Label load, done; | 807 Label load, done; |
| 808 __ tst(object, ShifterOperand(kSmiTagMask)); | 808 __ tst(object, ShifterOperand(kSmiTagMask)); |
| 809 __ b(&load, NE); | 809 __ b(&load, NE); |
| 810 __ LoadImmediate(result, Smi::RawValue(kSmiCid)); | 810 __ LoadImmediate(result, Smi::RawValue(kSmiCid)); |
| 811 __ b(&done); | 811 __ b(&done); |
| 812 __ Bind(&load); | 812 __ Bind(&load); |
| 813 __ LoadClassId(result, object); | 813 __ LoadClassId(result, object); |
| 814 __ SmiTag(result); | 814 __ SmiTag(result); |
| 815 __ Bind(&done); | 815 __ Bind(&done); |
| 816 } | 816 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 // TODO(regis): Revisit and see if the index can be immediate. | 904 // TODO(regis): Revisit and see if the index can be immediate. |
| 905 locs->set_in(1, Location::WritableRegister()); | 905 locs->set_in(1, Location::WritableRegister()); |
| 906 if ((representation() == kUnboxedDouble) || | 906 if ((representation() == kUnboxedDouble) || |
| 907 (representation() == kUnboxedFloat32x4) || | 907 (representation() == kUnboxedFloat32x4) || |
| 908 (representation() == kUnboxedInt32x4) || | 908 (representation() == kUnboxedInt32x4) || |
| 909 (representation() == kUnboxedFloat64x2)) { | 909 (representation() == kUnboxedFloat64x2)) { |
| 910 if (class_id() == kTypedDataFloat32ArrayCid) { | 910 if (class_id() == kTypedDataFloat32ArrayCid) { |
| 911 // Need register <= Q7 for float operations. | 911 // Need register <= Q7 for float operations. |
| 912 // TODO(fschneider): Add a register policy to specify a subset of | 912 // TODO(fschneider): Add a register policy to specify a subset of |
| 913 // registers. | 913 // registers. |
| 914 locs->set_out(Location::FpuRegisterLocation(Q7)); | 914 locs->set_out(0, Location::FpuRegisterLocation(Q7)); |
| 915 } else { | 915 } else { |
| 916 locs->set_out(Location::RequiresFpuRegister()); | 916 locs->set_out(0, Location::RequiresFpuRegister()); |
| 917 } | 917 } |
| 918 } else { | 918 } else { |
| 919 locs->set_out(Location::RequiresRegister()); | 919 locs->set_out(0, Location::RequiresRegister()); |
| 920 } | 920 } |
| 921 return locs; | 921 return locs; |
| 922 } | 922 } |
| 923 | 923 |
| 924 | 924 |
| 925 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 925 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 926 Register array = locs()->in(0).reg(); | 926 Register array = locs()->in(0).reg(); |
| 927 Location index = locs()->in(1); | 927 Location index = locs()->in(1); |
| 928 | 928 |
| 929 Address element_address(kNoRegister, 0); | 929 Address element_address(kNoRegister, 0); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 __ AddImmediate(index.reg(), | 961 __ AddImmediate(index.reg(), |
| 962 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 962 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 963 } | 963 } |
| 964 element_address = Address(array, index.reg(), LSL, 0); | 964 element_address = Address(array, index.reg(), LSL, 0); |
| 965 | 965 |
| 966 if ((representation() == kUnboxedDouble) || | 966 if ((representation() == kUnboxedDouble) || |
| 967 (representation() == kUnboxedMint) || | 967 (representation() == kUnboxedMint) || |
| 968 (representation() == kUnboxedFloat32x4) || | 968 (representation() == kUnboxedFloat32x4) || |
| 969 (representation() == kUnboxedInt32x4) || | 969 (representation() == kUnboxedInt32x4) || |
| 970 (representation() == kUnboxedFloat64x2)) { | 970 (representation() == kUnboxedFloat64x2)) { |
| 971 QRegister result = locs()->out().fpu_reg(); | 971 QRegister result = locs()->out(0).fpu_reg(); |
| 972 DRegister dresult0 = EvenDRegisterOf(result); | 972 DRegister dresult0 = EvenDRegisterOf(result); |
| 973 DRegister dresult1 = OddDRegisterOf(result); | 973 DRegister dresult1 = OddDRegisterOf(result); |
| 974 switch (class_id()) { | 974 switch (class_id()) { |
| 975 case kTypedDataInt32ArrayCid: | 975 case kTypedDataInt32ArrayCid: |
| 976 UNIMPLEMENTED(); | 976 UNIMPLEMENTED(); |
| 977 break; | 977 break; |
| 978 case kTypedDataUint32ArrayCid: | 978 case kTypedDataUint32ArrayCid: |
| 979 UNIMPLEMENTED(); | 979 UNIMPLEMENTED(); |
| 980 break; | 980 break; |
| 981 case kTypedDataFloat32ArrayCid: | 981 case kTypedDataFloat32ArrayCid: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 996 case kTypedDataFloat32x4ArrayCid: | 996 case kTypedDataFloat32x4ArrayCid: |
| 997 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 997 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 998 // TODO(zra): Maybe use vldmd here. | 998 // TODO(zra): Maybe use vldmd here. |
| 999 __ LoadDFromOffset(dresult0, index.reg(), 0); | 999 __ LoadDFromOffset(dresult0, index.reg(), 0); |
| 1000 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize); | 1000 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize); |
| 1001 break; | 1001 break; |
| 1002 } | 1002 } |
| 1003 return; | 1003 return; |
| 1004 } | 1004 } |
| 1005 | 1005 |
| 1006 Register result = locs()->out().reg(); | 1006 Register result = locs()->out(0).reg(); |
| 1007 switch (class_id()) { | 1007 switch (class_id()) { |
| 1008 case kTypedDataInt8ArrayCid: | 1008 case kTypedDataInt8ArrayCid: |
| 1009 ASSERT(index_scale() == 1); | 1009 ASSERT(index_scale() == 1); |
| 1010 __ ldrsb(result, element_address); | 1010 __ ldrsb(result, element_address); |
| 1011 __ SmiTag(result); | 1011 __ SmiTag(result); |
| 1012 break; | 1012 break; |
| 1013 case kTypedDataUint8ArrayCid: | 1013 case kTypedDataUint8ArrayCid: |
| 1014 case kTypedDataUint8ClampedArrayCid: | 1014 case kTypedDataUint8ClampedArrayCid: |
| 1015 case kExternalTypedDataUint8ArrayCid: | 1015 case kExternalTypedDataUint8ArrayCid: |
| 1016 case kExternalTypedDataUint8ClampedArrayCid: | 1016 case kExternalTypedDataUint8ClampedArrayCid: |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 | 1608 |
| 1609 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1609 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1610 __ Comment("StoreInstanceFieldSlowPath"); | 1610 __ Comment("StoreInstanceFieldSlowPath"); |
| 1611 __ Bind(entry_label()); | 1611 __ Bind(entry_label()); |
| 1612 | 1612 |
| 1613 const Code& stub = | 1613 const Code& stub = |
| 1614 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); | 1614 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); |
| 1615 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); | 1615 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); |
| 1616 | 1616 |
| 1617 LocationSummary* locs = instruction_->locs(); | 1617 LocationSummary* locs = instruction_->locs(); |
| 1618 locs->live_registers()->Remove(locs->out()); | 1618 locs->live_registers()->Remove(locs->out(0)); |
| 1619 | 1619 |
| 1620 compiler->SaveLiveRegisters(locs); | 1620 compiler->SaveLiveRegisters(locs); |
| 1621 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 1621 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 1622 &label, | 1622 &label, |
| 1623 PcDescriptors::kOther, | 1623 PcDescriptors::kOther, |
| 1624 locs); | 1624 locs); |
| 1625 __ MoveRegister(locs->temp(0).reg(), R0); | 1625 __ MoveRegister(locs->temp(0).reg(), R0); |
| 1626 compiler->RestoreLiveRegisters(locs); | 1626 compiler->RestoreLiveRegisters(locs); |
| 1627 | 1627 |
| 1628 __ b(exit_label()); | 1628 __ b(exit_label()); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 __ Bind(&skip_store); | 1901 __ Bind(&skip_store); |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 | 1904 |
| 1905 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { | 1905 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1906 const intptr_t kNumInputs = 1; | 1906 const intptr_t kNumInputs = 1; |
| 1907 const intptr_t kNumTemps = 0; | 1907 const intptr_t kNumTemps = 0; |
| 1908 LocationSummary* summary = | 1908 LocationSummary* summary = |
| 1909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1910 summary->set_in(0, Location::RequiresRegister()); | 1910 summary->set_in(0, Location::RequiresRegister()); |
| 1911 summary->set_out(Location::RequiresRegister()); | 1911 summary->set_out(0, Location::RequiresRegister()); |
| 1912 return summary; | 1912 return summary; |
| 1913 } | 1913 } |
| 1914 | 1914 |
| 1915 | 1915 |
| 1916 // When the parser is building an implicit static getter for optimization, | 1916 // When the parser is building an implicit static getter for optimization, |
| 1917 // it can generate a function body where deoptimization ids do not line up | 1917 // it can generate a function body where deoptimization ids do not line up |
| 1918 // with the unoptimized code. | 1918 // with the unoptimized code. |
| 1919 // | 1919 // |
| 1920 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. | 1920 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. |
| 1921 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1921 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1922 Register field = locs()->in(0).reg(); | 1922 Register field = locs()->in(0).reg(); |
| 1923 Register result = locs()->out().reg(); | 1923 Register result = locs()->out(0).reg(); |
| 1924 __ LoadFromOffset(kWord, result, | 1924 __ LoadFromOffset(kWord, result, |
| 1925 field, Field::value_offset() - kHeapObjectTag); | 1925 field, Field::value_offset() - kHeapObjectTag); |
| 1926 } | 1926 } |
| 1927 | 1927 |
| 1928 | 1928 |
| 1929 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { | 1929 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1930 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1930 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1931 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 1931 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 1932 : Location::RequiresRegister()); | 1932 : Location::RequiresRegister()); |
| 1933 locs->set_temp(0, Location::RequiresRegister()); | 1933 locs->set_temp(0, Location::RequiresRegister()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1951 | 1951 |
| 1952 | 1952 |
| 1953 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { | 1953 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { |
| 1954 const intptr_t kNumInputs = 3; | 1954 const intptr_t kNumInputs = 3; |
| 1955 const intptr_t kNumTemps = 0; | 1955 const intptr_t kNumTemps = 0; |
| 1956 LocationSummary* summary = | 1956 LocationSummary* summary = |
| 1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1958 summary->set_in(0, Location::RegisterLocation(R0)); | 1958 summary->set_in(0, Location::RegisterLocation(R0)); |
| 1959 summary->set_in(1, Location::RegisterLocation(R2)); | 1959 summary->set_in(1, Location::RegisterLocation(R2)); |
| 1960 summary->set_in(2, Location::RegisterLocation(R1)); | 1960 summary->set_in(2, Location::RegisterLocation(R1)); |
| 1961 summary->set_out(Location::RegisterLocation(R0)); | 1961 summary->set_out(0, Location::RegisterLocation(R0)); |
| 1962 return summary; | 1962 return summary; |
| 1963 } | 1963 } |
| 1964 | 1964 |
| 1965 | 1965 |
| 1966 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1966 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1967 ASSERT(locs()->in(0).reg() == R0); // Value. | 1967 ASSERT(locs()->in(0).reg() == R0); // Value. |
| 1968 ASSERT(locs()->in(1).reg() == R2); // Instantiator. | 1968 ASSERT(locs()->in(1).reg() == R2); // Instantiator. |
| 1969 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. | 1969 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. |
| 1970 | 1970 |
| 1971 compiler->GenerateInstanceOf(token_pos(), | 1971 compiler->GenerateInstanceOf(token_pos(), |
| 1972 deopt_id(), | 1972 deopt_id(), |
| 1973 type(), | 1973 type(), |
| 1974 negate_result(), | 1974 negate_result(), |
| 1975 locs()); | 1975 locs()); |
| 1976 ASSERT(locs()->out().reg() == R0); | 1976 ASSERT(locs()->out(0).reg() == R0); |
| 1977 } | 1977 } |
| 1978 | 1978 |
| 1979 | 1979 |
| 1980 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { | 1980 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
| 1981 const intptr_t kNumInputs = 2; | 1981 const intptr_t kNumInputs = 2; |
| 1982 const intptr_t kNumTemps = 0; | 1982 const intptr_t kNumTemps = 0; |
| 1983 LocationSummary* locs = | 1983 LocationSummary* locs = |
| 1984 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1984 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1985 locs->set_in(kElementTypePos, Location::RegisterLocation(R1)); | 1985 locs->set_in(kElementTypePos, Location::RegisterLocation(R1)); |
| 1986 locs->set_in(kLengthPos, Location::RegisterLocation(R2)); | 1986 locs->set_in(kLengthPos, Location::RegisterLocation(R2)); |
| 1987 locs->set_out(Location::RegisterLocation(R0)); | 1987 locs->set_out(0, Location::RegisterLocation(R0)); |
| 1988 return locs; | 1988 return locs; |
| 1989 } | 1989 } |
| 1990 | 1990 |
| 1991 | 1991 |
| 1992 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1992 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1993 // Allocate the array. R2 = length, R1 = element type. | 1993 // Allocate the array. R2 = length, R1 = element type. |
| 1994 ASSERT(locs()->in(kElementTypePos).reg() == R1); | 1994 ASSERT(locs()->in(kElementTypePos).reg() == R1); |
| 1995 ASSERT(locs()->in(kLengthPos).reg() == R2); | 1995 ASSERT(locs()->in(kLengthPos).reg() == R2); |
| 1996 compiler->GenerateCall(token_pos(), | 1996 compiler->GenerateCall(token_pos(), |
| 1997 &StubCode::AllocateArrayLabel(), | 1997 &StubCode::AllocateArrayLabel(), |
| 1998 PcDescriptors::kOther, | 1998 PcDescriptors::kOther, |
| 1999 locs()); | 1999 locs()); |
| 2000 ASSERT(locs()->out().reg() == R0); | 2000 ASSERT(locs()->out(0).reg() == R0); |
| 2001 } | 2001 } |
| 2002 | 2002 |
| 2003 | 2003 |
| 2004 class BoxDoubleSlowPath : public SlowPathCode { | 2004 class BoxDoubleSlowPath : public SlowPathCode { |
| 2005 public: | 2005 public: |
| 2006 explicit BoxDoubleSlowPath(Instruction* instruction) | 2006 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 2007 : instruction_(instruction) { } | 2007 : instruction_(instruction) { } |
| 2008 | 2008 |
| 2009 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2009 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2010 __ Comment("BoxDoubleSlowPath"); | 2010 __ Comment("BoxDoubleSlowPath"); |
| 2011 __ Bind(entry_label()); | 2011 __ Bind(entry_label()); |
| 2012 const Class& double_class = compiler->double_class(); | 2012 const Class& double_class = compiler->double_class(); |
| 2013 const Code& stub = | 2013 const Code& stub = |
| 2014 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 2014 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 2015 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 2015 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 2016 | 2016 |
| 2017 LocationSummary* locs = instruction_->locs(); | 2017 LocationSummary* locs = instruction_->locs(); |
| 2018 locs->live_registers()->Remove(locs->out()); | 2018 locs->live_registers()->Remove(locs->out(0)); |
| 2019 | 2019 |
| 2020 compiler->SaveLiveRegisters(locs); | 2020 compiler->SaveLiveRegisters(locs); |
| 2021 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 2021 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 2022 &label, | 2022 &label, |
| 2023 PcDescriptors::kOther, | 2023 PcDescriptors::kOther, |
| 2024 locs); | 2024 locs); |
| 2025 __ MoveRegister(locs->out().reg(), R0); | 2025 __ MoveRegister(locs->out(0).reg(), R0); |
| 2026 compiler->RestoreLiveRegisters(locs); | 2026 compiler->RestoreLiveRegisters(locs); |
| 2027 | 2027 |
| 2028 __ b(exit_label()); | 2028 __ b(exit_label()); |
| 2029 } | 2029 } |
| 2030 | 2030 |
| 2031 private: | 2031 private: |
| 2032 Instruction* instruction_; | 2032 Instruction* instruction_; |
| 2033 }; | 2033 }; |
| 2034 | 2034 |
| 2035 | 2035 |
| 2036 class BoxFloat32x4SlowPath : public SlowPathCode { | 2036 class BoxFloat32x4SlowPath : public SlowPathCode { |
| 2037 public: | 2037 public: |
| 2038 explicit BoxFloat32x4SlowPath(Instruction* instruction) | 2038 explicit BoxFloat32x4SlowPath(Instruction* instruction) |
| 2039 : instruction_(instruction) { } | 2039 : instruction_(instruction) { } |
| 2040 | 2040 |
| 2041 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2041 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2042 __ Comment("BoxFloat32x4SlowPath"); | 2042 __ Comment("BoxFloat32x4SlowPath"); |
| 2043 __ Bind(entry_label()); | 2043 __ Bind(entry_label()); |
| 2044 const Class& float32x4_class = compiler->float32x4_class(); | 2044 const Class& float32x4_class = compiler->float32x4_class(); |
| 2045 const Code& stub = | 2045 const Code& stub = |
| 2046 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); | 2046 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); |
| 2047 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); | 2047 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); |
| 2048 | 2048 |
| 2049 LocationSummary* locs = instruction_->locs(); | 2049 LocationSummary* locs = instruction_->locs(); |
| 2050 locs->live_registers()->Remove(locs->out()); | 2050 locs->live_registers()->Remove(locs->out(0)); |
| 2051 | 2051 |
| 2052 compiler->SaveLiveRegisters(locs); | 2052 compiler->SaveLiveRegisters(locs); |
| 2053 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 2053 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 2054 &label, | 2054 &label, |
| 2055 PcDescriptors::kOther, | 2055 PcDescriptors::kOther, |
| 2056 locs); | 2056 locs); |
| 2057 __ mov(locs->out().reg(), ShifterOperand(R0)); | 2057 __ mov(locs->out(0).reg(), ShifterOperand(R0)); |
| 2058 compiler->RestoreLiveRegisters(locs); | 2058 compiler->RestoreLiveRegisters(locs); |
| 2059 | 2059 |
| 2060 __ b(exit_label()); | 2060 __ b(exit_label()); |
| 2061 } | 2061 } |
| 2062 | 2062 |
| 2063 private: | 2063 private: |
| 2064 Instruction* instruction_; | 2064 Instruction* instruction_; |
| 2065 }; | 2065 }; |
| 2066 | 2066 |
| 2067 | 2067 |
| 2068 class BoxFloat64x2SlowPath : public SlowPathCode { | 2068 class BoxFloat64x2SlowPath : public SlowPathCode { |
| 2069 public: | 2069 public: |
| 2070 explicit BoxFloat64x2SlowPath(Instruction* instruction) | 2070 explicit BoxFloat64x2SlowPath(Instruction* instruction) |
| 2071 : instruction_(instruction) { } | 2071 : instruction_(instruction) { } |
| 2072 | 2072 |
| 2073 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2073 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2074 __ Comment("BoxFloat64x2SlowPath"); | 2074 __ Comment("BoxFloat64x2SlowPath"); |
| 2075 __ Bind(entry_label()); | 2075 __ Bind(entry_label()); |
| 2076 const Class& float64x2_class = compiler->float64x2_class(); | 2076 const Class& float64x2_class = compiler->float64x2_class(); |
| 2077 const Code& stub = | 2077 const Code& stub = |
| 2078 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); | 2078 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); |
| 2079 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); | 2079 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); |
| 2080 | 2080 |
| 2081 LocationSummary* locs = instruction_->locs(); | 2081 LocationSummary* locs = instruction_->locs(); |
| 2082 locs->live_registers()->Remove(locs->out()); | 2082 locs->live_registers()->Remove(locs->out(0)); |
| 2083 | 2083 |
| 2084 compiler->SaveLiveRegisters(locs); | 2084 compiler->SaveLiveRegisters(locs); |
| 2085 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 2085 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 2086 &label, | 2086 &label, |
| 2087 PcDescriptors::kOther, | 2087 PcDescriptors::kOther, |
| 2088 locs); | 2088 locs); |
| 2089 __ mov(locs->out().reg(), ShifterOperand(R0)); | 2089 __ mov(locs->out(0).reg(), ShifterOperand(R0)); |
| 2090 compiler->RestoreLiveRegisters(locs); | 2090 compiler->RestoreLiveRegisters(locs); |
| 2091 | 2091 |
| 2092 __ b(exit_label()); | 2092 __ b(exit_label()); |
| 2093 } | 2093 } |
| 2094 | 2094 |
| 2095 private: | 2095 private: |
| 2096 Instruction* instruction_; | 2096 Instruction* instruction_; |
| 2097 }; | 2097 }; |
| 2098 | 2098 |
| 2099 | 2099 |
| 2100 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { | 2100 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 2101 const intptr_t kNumInputs = 1; | 2101 const intptr_t kNumInputs = 1; |
| 2102 const intptr_t kNumTemps = 0; | 2102 const intptr_t kNumTemps = 0; |
| 2103 LocationSummary* locs = | 2103 LocationSummary* locs = |
| 2104 new LocationSummary( | 2104 new LocationSummary( |
| 2105 kNumInputs, kNumTemps, | 2105 kNumInputs, kNumTemps, |
| 2106 (opt && !IsPotentialUnboxedLoad()) | 2106 (opt && !IsPotentialUnboxedLoad()) |
| 2107 ? LocationSummary::kNoCall | 2107 ? LocationSummary::kNoCall |
| 2108 : LocationSummary::kCallOnSlowPath); | 2108 : LocationSummary::kCallOnSlowPath); |
| 2109 | 2109 |
| 2110 locs->set_in(0, Location::RequiresRegister()); | 2110 locs->set_in(0, Location::RequiresRegister()); |
| 2111 | 2111 |
| 2112 if (IsUnboxedLoad() && opt) { | 2112 if (IsUnboxedLoad() && opt) { |
| 2113 locs->AddTemp(Location::RequiresRegister()); | 2113 locs->AddTemp(Location::RequiresRegister()); |
| 2114 } else if (IsPotentialUnboxedLoad()) { | 2114 } else if (IsPotentialUnboxedLoad()) { |
| 2115 locs->AddTemp(opt ? Location::RequiresFpuRegister() | 2115 locs->AddTemp(opt ? Location::RequiresFpuRegister() |
| 2116 : Location::FpuRegisterLocation(Q1)); | 2116 : Location::FpuRegisterLocation(Q1)); |
| 2117 locs->AddTemp(Location::RequiresRegister()); | 2117 locs->AddTemp(Location::RequiresRegister()); |
| 2118 } | 2118 } |
| 2119 locs->set_out(Location::RequiresRegister()); | 2119 locs->set_out(0, Location::RequiresRegister()); |
| 2120 return locs; | 2120 return locs; |
| 2121 } | 2121 } |
| 2122 | 2122 |
| 2123 | 2123 |
| 2124 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2124 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2125 Register instance_reg = locs()->in(0).reg(); | 2125 Register instance_reg = locs()->in(0).reg(); |
| 2126 if (IsUnboxedLoad() && compiler->is_optimizing()) { | 2126 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 2127 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 2127 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 2128 DRegister result_odd = OddDRegisterOf(locs()->out().fpu_reg()); | 2128 DRegister result_odd = OddDRegisterOf(locs()->out(0).fpu_reg()); |
| 2129 Register temp = locs()->temp(0).reg(); | 2129 Register temp = locs()->temp(0).reg(); |
| 2130 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2130 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2131 intptr_t cid = field()->UnboxedFieldCid(); | 2131 intptr_t cid = field()->UnboxedFieldCid(); |
| 2132 switch (cid) { | 2132 switch (cid) { |
| 2133 case kDoubleCid: | 2133 case kDoubleCid: |
| 2134 __ Comment("UnboxedDoubleLoadFieldInstr"); | 2134 __ Comment("UnboxedDoubleLoadFieldInstr"); |
| 2135 __ LoadDFromOffset(result, temp, | 2135 __ LoadDFromOffset(result, temp, |
| 2136 Double::value_offset() - kHeapObjectTag); | 2136 Double::value_offset() - kHeapObjectTag); |
| 2137 break; | 2137 break; |
| 2138 case kFloat32x4Cid: | 2138 case kFloat32x4Cid: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2151 __ LoadDFromOffset(result_odd, temp, | 2151 __ LoadDFromOffset(result_odd, temp, |
| 2152 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | 2152 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2153 break; | 2153 break; |
| 2154 default: | 2154 default: |
| 2155 UNREACHABLE(); | 2155 UNREACHABLE(); |
| 2156 } | 2156 } |
| 2157 return; | 2157 return; |
| 2158 } | 2158 } |
| 2159 | 2159 |
| 2160 Label done; | 2160 Label done; |
| 2161 Register result_reg = locs()->out().reg(); | 2161 Register result_reg = locs()->out(0).reg(); |
| 2162 if (IsPotentialUnboxedLoad()) { | 2162 if (IsPotentialUnboxedLoad()) { |
| 2163 Register temp = locs()->temp(1).reg(); | 2163 Register temp = locs()->temp(1).reg(); |
| 2164 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); | 2164 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |
| 2165 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); | 2165 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); |
| 2166 | 2166 |
| 2167 Label load_pointer; | 2167 Label load_pointer; |
| 2168 Label load_double; | 2168 Label load_double; |
| 2169 Label load_float32x4; | 2169 Label load_float32x4; |
| 2170 Label load_float64x2; | 2170 Label load_float64x2; |
| 2171 | 2171 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2269 __ Bind(&done); | 2269 __ Bind(&done); |
| 2270 } | 2270 } |
| 2271 | 2271 |
| 2272 | 2272 |
| 2273 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { | 2273 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
| 2274 const intptr_t kNumInputs = 1; | 2274 const intptr_t kNumInputs = 1; |
| 2275 const intptr_t kNumTemps = 0; | 2275 const intptr_t kNumTemps = 0; |
| 2276 LocationSummary* locs = | 2276 LocationSummary* locs = |
| 2277 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2277 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2278 locs->set_in(0, Location::RegisterLocation(R0)); | 2278 locs->set_in(0, Location::RegisterLocation(R0)); |
| 2279 locs->set_out(Location::RegisterLocation(R0)); | 2279 locs->set_out(0, Location::RegisterLocation(R0)); |
| 2280 return locs; | 2280 return locs; |
| 2281 } | 2281 } |
| 2282 | 2282 |
| 2283 | 2283 |
| 2284 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2284 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2285 Register instantiator_reg = locs()->in(0).reg(); | 2285 Register instantiator_reg = locs()->in(0).reg(); |
| 2286 Register result_reg = locs()->out().reg(); | 2286 Register result_reg = locs()->out(0).reg(); |
| 2287 | 2287 |
| 2288 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2288 // 'instantiator_reg' is the instantiator TypeArguments object (or null). |
| 2289 // A runtime call to instantiate the type is required. | 2289 // A runtime call to instantiate the type is required. |
| 2290 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2290 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 2291 __ PushObject(type()); | 2291 __ PushObject(type()); |
| 2292 __ Push(instantiator_reg); // Push instantiator type arguments. | 2292 __ Push(instantiator_reg); // Push instantiator type arguments. |
| 2293 compiler->GenerateRuntimeCall(token_pos(), | 2293 compiler->GenerateRuntimeCall(token_pos(), |
| 2294 deopt_id(), | 2294 deopt_id(), |
| 2295 kInstantiateTypeRuntimeEntry, | 2295 kInstantiateTypeRuntimeEntry, |
| 2296 2, | 2296 2, |
| 2297 locs()); | 2297 locs()); |
| 2298 __ Drop(2); // Drop instantiator and uninstantiated type. | 2298 __ Drop(2); // Drop instantiator and uninstantiated type. |
| 2299 __ Pop(result_reg); // Pop instantiated type. | 2299 __ Pop(result_reg); // Pop instantiated type. |
| 2300 ASSERT(instantiator_reg == result_reg); | 2300 ASSERT(instantiator_reg == result_reg); |
| 2301 } | 2301 } |
| 2302 | 2302 |
| 2303 | 2303 |
| 2304 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2304 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 2305 bool opt) const { | 2305 bool opt) const { |
| 2306 const intptr_t kNumInputs = 1; | 2306 const intptr_t kNumInputs = 1; |
| 2307 const intptr_t kNumTemps = 0; | 2307 const intptr_t kNumTemps = 0; |
| 2308 LocationSummary* locs = | 2308 LocationSummary* locs = |
| 2309 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2309 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2310 locs->set_in(0, Location::RegisterLocation(R0)); | 2310 locs->set_in(0, Location::RegisterLocation(R0)); |
| 2311 locs->set_out(Location::RegisterLocation(R0)); | 2311 locs->set_out(0, Location::RegisterLocation(R0)); |
| 2312 return locs; | 2312 return locs; |
| 2313 } | 2313 } |
| 2314 | 2314 |
| 2315 | 2315 |
| 2316 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2316 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
| 2317 FlowGraphCompiler* compiler) { | 2317 FlowGraphCompiler* compiler) { |
| 2318 Register instantiator_reg = locs()->in(0).reg(); | 2318 Register instantiator_reg = locs()->in(0).reg(); |
| 2319 Register result_reg = locs()->out().reg(); | 2319 Register result_reg = locs()->out(0).reg(); |
| 2320 ASSERT(instantiator_reg == R0); | 2320 ASSERT(instantiator_reg == R0); |
| 2321 ASSERT(instantiator_reg == result_reg); | 2321 ASSERT(instantiator_reg == result_reg); |
| 2322 | 2322 |
| 2323 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2323 // 'instantiator_reg' is the instantiator TypeArguments object (or null). |
| 2324 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2324 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| 2325 !type_arguments().CanShareInstantiatorTypeArguments( | 2325 !type_arguments().CanShareInstantiatorTypeArguments( |
| 2326 instantiator_class())); | 2326 instantiator_class())); |
| 2327 // If the instantiator is null and if the type argument vector | 2327 // If the instantiator is null and if the type argument vector |
| 2328 // instantiated from null becomes a vector of dynamic, then use null as | 2328 // instantiated from null becomes a vector of dynamic, then use null as |
| 2329 // the type arguments. | 2329 // the type arguments. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 __ Bind(&type_arguments_instantiated); | 2369 __ Bind(&type_arguments_instantiated); |
| 2370 } | 2370 } |
| 2371 | 2371 |
| 2372 | 2372 |
| 2373 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { | 2373 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
| 2374 const intptr_t kNumInputs = 0; | 2374 const intptr_t kNumInputs = 0; |
| 2375 const intptr_t kNumTemps = 1; | 2375 const intptr_t kNumTemps = 1; |
| 2376 LocationSummary* locs = | 2376 LocationSummary* locs = |
| 2377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2378 locs->set_temp(0, Location::RegisterLocation(R1)); | 2378 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 2379 locs->set_out(Location::RegisterLocation(R0)); | 2379 locs->set_out(0, Location::RegisterLocation(R0)); |
| 2380 return locs; | 2380 return locs; |
| 2381 } | 2381 } |
| 2382 | 2382 |
| 2383 | 2383 |
| 2384 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2384 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2385 ASSERT(locs()->temp(0).reg() == R1); | 2385 ASSERT(locs()->temp(0).reg() == R1); |
| 2386 ASSERT(locs()->out().reg() == R0); | 2386 ASSERT(locs()->out(0).reg() == R0); |
| 2387 | 2387 |
| 2388 __ LoadImmediate(R1, num_context_variables()); | 2388 __ LoadImmediate(R1, num_context_variables()); |
| 2389 const ExternalLabel label("alloc_context", | 2389 const ExternalLabel label("alloc_context", |
| 2390 StubCode::AllocateContextEntryPoint()); | 2390 StubCode::AllocateContextEntryPoint()); |
| 2391 compiler->GenerateCall(token_pos(), | 2391 compiler->GenerateCall(token_pos(), |
| 2392 &label, | 2392 &label, |
| 2393 PcDescriptors::kOther, | 2393 PcDescriptors::kOther, |
| 2394 locs()); | 2394 locs()); |
| 2395 } | 2395 } |
| 2396 | 2396 |
| 2397 | 2397 |
| 2398 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { | 2398 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { |
| 2399 const intptr_t kNumInputs = 1; | 2399 const intptr_t kNumInputs = 1; |
| 2400 const intptr_t kNumTemps = 0; | 2400 const intptr_t kNumTemps = 0; |
| 2401 LocationSummary* locs = | 2401 LocationSummary* locs = |
| 2402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2403 locs->set_in(0, Location::RegisterLocation(R0)); | 2403 locs->set_in(0, Location::RegisterLocation(R0)); |
| 2404 locs->set_out(Location::RegisterLocation(R0)); | 2404 locs->set_out(0, Location::RegisterLocation(R0)); |
| 2405 return locs; | 2405 return locs; |
| 2406 } | 2406 } |
| 2407 | 2407 |
| 2408 | 2408 |
| 2409 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2409 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2410 Register context_value = locs()->in(0).reg(); | 2410 Register context_value = locs()->in(0).reg(); |
| 2411 Register result = locs()->out().reg(); | 2411 Register result = locs()->out(0).reg(); |
| 2412 | 2412 |
| 2413 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2413 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 2414 __ Push(context_value); | 2414 __ Push(context_value); |
| 2415 compiler->GenerateRuntimeCall(token_pos(), | 2415 compiler->GenerateRuntimeCall(token_pos(), |
| 2416 deopt_id(), | 2416 deopt_id(), |
| 2417 kCloneContextRuntimeEntry, | 2417 kCloneContextRuntimeEntry, |
| 2418 1, | 2418 1, |
| 2419 locs()); | 2419 locs()); |
| 2420 __ Drop(1); // Remove argument. | 2420 __ Drop(1); // Remove argument. |
| 2421 __ Pop(result); // Get result (cloned context). | 2421 __ Pop(result); // Get result (cloned context). |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2529 } | 2529 } |
| 2530 __ Bind(slow_path->exit_label()); | 2530 __ Bind(slow_path->exit_label()); |
| 2531 } | 2531 } |
| 2532 | 2532 |
| 2533 | 2533 |
| 2534 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2534 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2535 BinarySmiOpInstr* shift_left) { | 2535 BinarySmiOpInstr* shift_left) { |
| 2536 const bool is_truncating = shift_left->is_truncating(); | 2536 const bool is_truncating = shift_left->is_truncating(); |
| 2537 const LocationSummary& locs = *shift_left->locs(); | 2537 const LocationSummary& locs = *shift_left->locs(); |
| 2538 Register left = locs.in(0).reg(); | 2538 Register left = locs.in(0).reg(); |
| 2539 Register result = locs.out().reg(); | 2539 Register result = locs.out(0).reg(); |
| 2540 Label* deopt = shift_left->CanDeoptimize() ? | 2540 Label* deopt = shift_left->CanDeoptimize() ? |
| 2541 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; | 2541 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; |
| 2542 if (locs.in(1).IsConstant()) { | 2542 if (locs.in(1).IsConstant()) { |
| 2543 const Object& constant = locs.in(1).constant(); | 2543 const Object& constant = locs.in(1).constant(); |
| 2544 ASSERT(constant.IsSmi()); | 2544 ASSERT(constant.IsSmi()); |
| 2545 // Immediate shift operation takes 5 bits for the count. | 2545 // Immediate shift operation takes 5 bits for the count. |
| 2546 const intptr_t kCountLimit = 0x1F; | 2546 const intptr_t kCountLimit = 0x1F; |
| 2547 const intptr_t value = Smi::Cast(constant).Value(); | 2547 const intptr_t value = Smi::Cast(constant).Value(); |
| 2548 if (value == 0) { | 2548 if (value == 0) { |
| 2549 __ MoveRegister(result, left); | 2549 __ MoveRegister(result, left); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2651 summary->set_in(0, Location::RequiresRegister()); | 2651 summary->set_in(0, Location::RequiresRegister()); |
| 2652 if (RightIsPowerOfTwoConstant()) { | 2652 if (RightIsPowerOfTwoConstant()) { |
| 2653 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2653 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 2654 summary->set_in(1, Location::Constant(right_constant->value())); | 2654 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2655 summary->AddTemp(Location::RequiresRegister()); | 2655 summary->AddTemp(Location::RequiresRegister()); |
| 2656 } else { | 2656 } else { |
| 2657 summary->set_in(1, Location::RequiresRegister()); | 2657 summary->set_in(1, Location::RequiresRegister()); |
| 2658 summary->AddTemp(Location::RequiresRegister()); | 2658 summary->AddTemp(Location::RequiresRegister()); |
| 2659 summary->AddTemp(Location::RequiresFpuRegister()); | 2659 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2660 } | 2660 } |
| 2661 summary->set_out(Location::RequiresRegister()); | 2661 summary->set_out(0, Location::RequiresRegister()); |
| 2662 return summary; | 2662 return summary; |
| 2663 } | 2663 } |
| 2664 if (op_kind() == Token::kMOD) { | 2664 if (op_kind() == Token::kMOD) { |
| 2665 summary->set_in(0, Location::RequiresRegister()); | 2665 summary->set_in(0, Location::RequiresRegister()); |
| 2666 summary->set_in(1, Location::RequiresRegister()); | 2666 summary->set_in(1, Location::RequiresRegister()); |
| 2667 summary->AddTemp(Location::RequiresRegister()); | 2667 summary->AddTemp(Location::RequiresRegister()); |
| 2668 summary->AddTemp(Location::RequiresFpuRegister()); | 2668 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2669 summary->set_out(Location::RequiresRegister()); | 2669 summary->set_out(0, Location::RequiresRegister()); |
| 2670 return summary; | 2670 return summary; |
| 2671 } | 2671 } |
| 2672 summary->set_in(0, Location::RequiresRegister()); | 2672 summary->set_in(0, Location::RequiresRegister()); |
| 2673 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 2673 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 2674 if (((op_kind() == Token::kSHL) && !is_truncating()) || | 2674 if (((op_kind() == Token::kSHL) && !is_truncating()) || |
| 2675 (op_kind() == Token::kSHR)) { | 2675 (op_kind() == Token::kSHR)) { |
| 2676 summary->AddTemp(Location::RequiresRegister()); | 2676 summary->AddTemp(Location::RequiresRegister()); |
| 2677 } | 2677 } |
| 2678 // We make use of 3-operand instructions by not requiring result register | 2678 // We make use of 3-operand instructions by not requiring result register |
| 2679 // to be identical to first input register as on Intel. | 2679 // to be identical to first input register as on Intel. |
| 2680 summary->set_out(Location::RequiresRegister()); | 2680 summary->set_out(0, Location::RequiresRegister()); |
| 2681 return summary; | 2681 return summary; |
| 2682 } | 2682 } |
| 2683 | 2683 |
| 2684 | 2684 |
| 2685 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2685 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2686 if (op_kind() == Token::kSHL) { | 2686 if (op_kind() == Token::kSHL) { |
| 2687 EmitSmiShiftLeft(compiler, this); | 2687 EmitSmiShiftLeft(compiler, this); |
| 2688 return; | 2688 return; |
| 2689 } | 2689 } |
| 2690 | 2690 |
| 2691 ASSERT(!is_truncating()); | 2691 ASSERT(!is_truncating()); |
| 2692 Register left = locs()->in(0).reg(); | 2692 Register left = locs()->in(0).reg(); |
| 2693 Register result = locs()->out().reg(); | 2693 Register result = locs()->out(0).reg(); |
| 2694 Label* deopt = NULL; | 2694 Label* deopt = NULL; |
| 2695 if (CanDeoptimize()) { | 2695 if (CanDeoptimize()) { |
| 2696 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 2696 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
| 2697 } | 2697 } |
| 2698 | 2698 |
| 2699 if (locs()->in(1).IsConstant()) { | 2699 if (locs()->in(1).IsConstant()) { |
| 2700 const Object& constant = locs()->in(1).constant(); | 2700 const Object& constant = locs()->in(1).constant(); |
| 2701 ASSERT(constant.IsSmi()); | 2701 ASSERT(constant.IsSmi()); |
| 2702 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); | 2702 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); |
| 2703 switch (op_kind()) { | 2703 switch (op_kind()) { |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 | 3007 |
| 3008 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { | 3008 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3009 const intptr_t kNumInputs = 1; | 3009 const intptr_t kNumInputs = 1; |
| 3010 const intptr_t kNumTemps = 1; | 3010 const intptr_t kNumTemps = 1; |
| 3011 LocationSummary* summary = | 3011 LocationSummary* summary = |
| 3012 new LocationSummary(kNumInputs, | 3012 new LocationSummary(kNumInputs, |
| 3013 kNumTemps, | 3013 kNumTemps, |
| 3014 LocationSummary::kCallOnSlowPath); | 3014 LocationSummary::kCallOnSlowPath); |
| 3015 summary->set_in(0, Location::RequiresFpuRegister()); | 3015 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3016 summary->set_temp(0, Location::RequiresRegister()); | 3016 summary->set_temp(0, Location::RequiresRegister()); |
| 3017 summary->set_out(Location::RequiresRegister()); | 3017 summary->set_out(0, Location::RequiresRegister()); |
| 3018 return summary; | 3018 return summary; |
| 3019 } | 3019 } |
| 3020 | 3020 |
| 3021 | 3021 |
| 3022 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3022 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3023 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 3023 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 3024 compiler->AddSlowPathCode(slow_path); | 3024 compiler->AddSlowPathCode(slow_path); |
| 3025 | 3025 |
| 3026 const Register out_reg = locs()->out().reg(); | 3026 const Register out_reg = locs()->out(0).reg(); |
| 3027 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3027 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3028 | 3028 |
| 3029 __ TryAllocate(compiler->double_class(), | 3029 __ TryAllocate(compiler->double_class(), |
| 3030 slow_path->entry_label(), | 3030 slow_path->entry_label(), |
| 3031 out_reg, | 3031 out_reg, |
| 3032 locs()->temp(0).reg()); | 3032 locs()->temp(0).reg()); |
| 3033 __ Bind(slow_path->exit_label()); | 3033 __ Bind(slow_path->exit_label()); |
| 3034 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 3034 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 3035 } | 3035 } |
| 3036 | 3036 |
| 3037 | 3037 |
| 3038 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { | 3038 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { |
| 3039 const intptr_t kNumInputs = 1; | 3039 const intptr_t kNumInputs = 1; |
| 3040 const intptr_t value_cid = value()->Type()->ToCid(); | 3040 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3041 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | 3041 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
| 3042 const bool needs_writable_input = (value_cid == kSmiCid); | 3042 const bool needs_writable_input = (value_cid == kSmiCid); |
| 3043 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 3043 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 3044 LocationSummary* summary = | 3044 LocationSummary* summary = |
| 3045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3046 summary->set_in(0, needs_writable_input | 3046 summary->set_in(0, needs_writable_input |
| 3047 ? Location::WritableRegister() | 3047 ? Location::WritableRegister() |
| 3048 : Location::RequiresRegister()); | 3048 : Location::RequiresRegister()); |
| 3049 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); | 3049 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); |
| 3050 summary->set_out(Location::RequiresFpuRegister()); | 3050 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3051 return summary; | 3051 return summary; |
| 3052 } | 3052 } |
| 3053 | 3053 |
| 3054 | 3054 |
| 3055 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3055 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3056 const intptr_t value_cid = value()->Type()->ToCid(); | 3056 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3057 const Register value = locs()->in(0).reg(); | 3057 const Register value = locs()->in(0).reg(); |
| 3058 const DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3058 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 3059 | 3059 |
| 3060 if (value_cid == kDoubleCid) { | 3060 if (value_cid == kDoubleCid) { |
| 3061 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3061 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 3062 } else if (value_cid == kSmiCid) { | 3062 } else if (value_cid == kSmiCid) { |
| 3063 __ SmiUntag(value); // Untag input before conversion. | 3063 __ SmiUntag(value); // Untag input before conversion. |
| 3064 __ vmovsr(STMP, value); | 3064 __ vmovsr(STMP, value); |
| 3065 __ vcvtdi(result, STMP); | 3065 __ vcvtdi(result, STMP); |
| 3066 } else { | 3066 } else { |
| 3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
| 3068 Register temp = locs()->temp(0).reg(); | 3068 Register temp = locs()->temp(0).reg(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3085 | 3085 |
| 3086 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { | 3086 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 3087 const intptr_t kNumInputs = 1; | 3087 const intptr_t kNumInputs = 1; |
| 3088 const intptr_t kNumTemps = 1; | 3088 const intptr_t kNumTemps = 1; |
| 3089 LocationSummary* summary = | 3089 LocationSummary* summary = |
| 3090 new LocationSummary(kNumInputs, | 3090 new LocationSummary(kNumInputs, |
| 3091 kNumTemps, | 3091 kNumTemps, |
| 3092 LocationSummary::kCallOnSlowPath); | 3092 LocationSummary::kCallOnSlowPath); |
| 3093 summary->set_in(0, Location::RequiresFpuRegister()); | 3093 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3094 summary->set_temp(0, Location::RequiresRegister()); | 3094 summary->set_temp(0, Location::RequiresRegister()); |
| 3095 summary->set_out(Location::RequiresRegister()); | 3095 summary->set_out(0, Location::RequiresRegister()); |
| 3096 return summary; | 3096 return summary; |
| 3097 } | 3097 } |
| 3098 | 3098 |
| 3099 | 3099 |
| 3100 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3100 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3101 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 3101 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); |
| 3102 compiler->AddSlowPathCode(slow_path); | 3102 compiler->AddSlowPathCode(slow_path); |
| 3103 | 3103 |
| 3104 Register out_reg = locs()->out().reg(); | 3104 Register out_reg = locs()->out(0).reg(); |
| 3105 QRegister value = locs()->in(0).fpu_reg(); | 3105 QRegister value = locs()->in(0).fpu_reg(); |
| 3106 DRegister value_even = EvenDRegisterOf(value); | 3106 DRegister value_even = EvenDRegisterOf(value); |
| 3107 DRegister value_odd = OddDRegisterOf(value); | 3107 DRegister value_odd = OddDRegisterOf(value); |
| 3108 | 3108 |
| 3109 __ TryAllocate(compiler->float32x4_class(), | 3109 __ TryAllocate(compiler->float32x4_class(), |
| 3110 slow_path->entry_label(), | 3110 slow_path->entry_label(), |
| 3111 out_reg, | 3111 out_reg, |
| 3112 locs()->temp(0).reg()); | 3112 locs()->temp(0).reg()); |
| 3113 __ Bind(slow_path->exit_label()); | 3113 __ Bind(slow_path->exit_label()); |
| 3114 | 3114 |
| 3115 __ StoreDToOffset(value_even, out_reg, | 3115 __ StoreDToOffset(value_even, out_reg, |
| 3116 Float32x4::value_offset() - kHeapObjectTag); | 3116 Float32x4::value_offset() - kHeapObjectTag); |
| 3117 __ StoreDToOffset(value_odd, out_reg, | 3117 __ StoreDToOffset(value_odd, out_reg, |
| 3118 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3118 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3119 } | 3119 } |
| 3120 | 3120 |
| 3121 | 3121 |
| 3122 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { | 3122 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 3123 const intptr_t value_cid = value()->Type()->ToCid(); | 3123 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3124 const intptr_t kNumInputs = 1; | 3124 const intptr_t kNumInputs = 1; |
| 3125 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 3125 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
| 3126 LocationSummary* summary = | 3126 LocationSummary* summary = |
| 3127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3128 summary->set_in(0, Location::RequiresRegister()); | 3128 summary->set_in(0, Location::RequiresRegister()); |
| 3129 if (kNumTemps > 0) { | 3129 if (kNumTemps > 0) { |
| 3130 ASSERT(kNumTemps == 1); | 3130 ASSERT(kNumTemps == 1); |
| 3131 summary->set_temp(0, Location::RequiresRegister()); | 3131 summary->set_temp(0, Location::RequiresRegister()); |
| 3132 } | 3132 } |
| 3133 summary->set_out(Location::RequiresFpuRegister()); | 3133 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3134 return summary; | 3134 return summary; |
| 3135 } | 3135 } |
| 3136 | 3136 |
| 3137 | 3137 |
| 3138 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3138 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3139 const intptr_t value_cid = value()->Type()->ToCid(); | 3139 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3140 const Register value = locs()->in(0).reg(); | 3140 const Register value = locs()->in(0).reg(); |
| 3141 const QRegister result = locs()->out().fpu_reg(); | 3141 const QRegister result = locs()->out(0).fpu_reg(); |
| 3142 | 3142 |
| 3143 if (value_cid != kFloat32x4Cid) { | 3143 if (value_cid != kFloat32x4Cid) { |
| 3144 const Register temp = locs()->temp(0).reg(); | 3144 const Register temp = locs()->temp(0).reg(); |
| 3145 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3145 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3146 __ tst(value, ShifterOperand(kSmiTagMask)); | 3146 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3147 __ b(deopt, EQ); | 3147 __ b(deopt, EQ); |
| 3148 __ CompareClassId(value, kFloat32x4Cid, temp); | 3148 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 3149 __ b(deopt, NE); | 3149 __ b(deopt, NE); |
| 3150 } | 3150 } |
| 3151 | 3151 |
| 3152 const DRegister result_even = EvenDRegisterOf(result); | 3152 const DRegister result_even = EvenDRegisterOf(result); |
| 3153 const DRegister result_odd = OddDRegisterOf(result); | 3153 const DRegister result_odd = OddDRegisterOf(result); |
| 3154 // TODO(zra): Maybe use vldmd here. | 3154 // TODO(zra): Maybe use vldmd here. |
| 3155 __ LoadDFromOffset(result_even, value, | 3155 __ LoadDFromOffset(result_even, value, |
| 3156 Float32x4::value_offset() - kHeapObjectTag); | 3156 Float32x4::value_offset() - kHeapObjectTag); |
| 3157 __ LoadDFromOffset(result_odd, value, | 3157 __ LoadDFromOffset(result_odd, value, |
| 3158 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3158 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3159 } | 3159 } |
| 3160 | 3160 |
| 3161 | 3161 |
| 3162 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3162 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3163 const intptr_t kNumInputs = 1; | 3163 const intptr_t kNumInputs = 1; |
| 3164 const intptr_t kNumTemps = 1; | 3164 const intptr_t kNumTemps = 1; |
| 3165 LocationSummary* summary = | 3165 LocationSummary* summary = |
| 3166 new LocationSummary(kNumInputs, | 3166 new LocationSummary(kNumInputs, |
| 3167 kNumTemps, | 3167 kNumTemps, |
| 3168 LocationSummary::kCallOnSlowPath); | 3168 LocationSummary::kCallOnSlowPath); |
| 3169 summary->set_in(0, Location::RequiresFpuRegister()); | 3169 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3170 summary->set_temp(0, Location::RequiresRegister()); | 3170 summary->set_temp(0, Location::RequiresRegister()); |
| 3171 summary->set_out(Location::RequiresRegister()); | 3171 summary->set_out(0, Location::RequiresRegister()); |
| 3172 return summary; | 3172 return summary; |
| 3173 } | 3173 } |
| 3174 | 3174 |
| 3175 | 3175 |
| 3176 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3176 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3177 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 3177 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 3178 compiler->AddSlowPathCode(slow_path); | 3178 compiler->AddSlowPathCode(slow_path); |
| 3179 | 3179 |
| 3180 Register out_reg = locs()->out().reg(); | 3180 Register out_reg = locs()->out(0).reg(); |
| 3181 QRegister value = locs()->in(0).fpu_reg(); | 3181 QRegister value = locs()->in(0).fpu_reg(); |
| 3182 DRegister value_even = EvenDRegisterOf(value); | 3182 DRegister value_even = EvenDRegisterOf(value); |
| 3183 DRegister value_odd = OddDRegisterOf(value); | 3183 DRegister value_odd = OddDRegisterOf(value); |
| 3184 | 3184 |
| 3185 __ TryAllocate(compiler->float64x2_class(), | 3185 __ TryAllocate(compiler->float64x2_class(), |
| 3186 slow_path->entry_label(), | 3186 slow_path->entry_label(), |
| 3187 out_reg, | 3187 out_reg, |
| 3188 locs()->temp(0).reg()); | 3188 locs()->temp(0).reg()); |
| 3189 __ Bind(slow_path->exit_label()); | 3189 __ Bind(slow_path->exit_label()); |
| 3190 | 3190 |
| 3191 __ StoreDToOffset(value_even, out_reg, | 3191 __ StoreDToOffset(value_even, out_reg, |
| 3192 Float64x2::value_offset() - kHeapObjectTag); | 3192 Float64x2::value_offset() - kHeapObjectTag); |
| 3193 __ StoreDToOffset(value_odd, out_reg, | 3193 __ StoreDToOffset(value_odd, out_reg, |
| 3194 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3194 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3195 } | 3195 } |
| 3196 | 3196 |
| 3197 | 3197 |
| 3198 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3198 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3199 const intptr_t value_cid = value()->Type()->ToCid(); | 3199 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3200 const intptr_t kNumInputs = 1; | 3200 const intptr_t kNumInputs = 1; |
| 3201 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | 3201 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
| 3202 LocationSummary* summary = | 3202 LocationSummary* summary = |
| 3203 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3203 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3204 summary->set_in(0, Location::RequiresRegister()); | 3204 summary->set_in(0, Location::RequiresRegister()); |
| 3205 if (kNumTemps > 0) { | 3205 if (kNumTemps > 0) { |
| 3206 ASSERT(kNumTemps == 1); | 3206 ASSERT(kNumTemps == 1); |
| 3207 summary->set_temp(0, Location::RequiresRegister()); | 3207 summary->set_temp(0, Location::RequiresRegister()); |
| 3208 } | 3208 } |
| 3209 summary->set_out(Location::RequiresFpuRegister()); | 3209 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3210 return summary; | 3210 return summary; |
| 3211 } | 3211 } |
| 3212 | 3212 |
| 3213 | 3213 |
| 3214 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3214 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3215 const intptr_t value_cid = value()->Type()->ToCid(); | 3215 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3216 const Register value = locs()->in(0).reg(); | 3216 const Register value = locs()->in(0).reg(); |
| 3217 const QRegister result = locs()->out().fpu_reg(); | 3217 const QRegister result = locs()->out(0).fpu_reg(); |
| 3218 | 3218 |
| 3219 if (value_cid != kFloat64x2Cid) { | 3219 if (value_cid != kFloat64x2Cid) { |
| 3220 const Register temp = locs()->temp(0).reg(); | 3220 const Register temp = locs()->temp(0).reg(); |
| 3221 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3221 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3222 __ tst(value, ShifterOperand(kSmiTagMask)); | 3222 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3223 __ b(deopt, EQ); | 3223 __ b(deopt, EQ); |
| 3224 __ CompareClassId(value, kFloat64x2Cid, temp); | 3224 __ CompareClassId(value, kFloat64x2Cid, temp); |
| 3225 __ b(deopt, NE); | 3225 __ b(deopt, NE); |
| 3226 } | 3226 } |
| 3227 | 3227 |
| 3228 const DRegister result_even = EvenDRegisterOf(result); | 3228 const DRegister result_even = EvenDRegisterOf(result); |
| 3229 const DRegister result_odd = OddDRegisterOf(result); | 3229 const DRegister result_odd = OddDRegisterOf(result); |
| 3230 // TODO(zra): Maybe use vldmd here. | 3230 // TODO(zra): Maybe use vldmd here. |
| 3231 __ LoadDFromOffset(result_even, value, | 3231 __ LoadDFromOffset(result_even, value, |
| 3232 Float64x2::value_offset() - kHeapObjectTag); | 3232 Float64x2::value_offset() - kHeapObjectTag); |
| 3233 __ LoadDFromOffset(result_odd, value, | 3233 __ LoadDFromOffset(result_odd, value, |
| 3234 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3234 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3235 } | 3235 } |
| 3236 | 3236 |
| 3237 | 3237 |
| 3238 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3238 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3239 const intptr_t kNumInputs = 1; | 3239 const intptr_t kNumInputs = 1; |
| 3240 const intptr_t kNumTemps = 1; | 3240 const intptr_t kNumTemps = 1; |
| 3241 LocationSummary* summary = | 3241 LocationSummary* summary = |
| 3242 new LocationSummary(kNumInputs, | 3242 new LocationSummary(kNumInputs, |
| 3243 kNumTemps, | 3243 kNumTemps, |
| 3244 LocationSummary::kCallOnSlowPath); | 3244 LocationSummary::kCallOnSlowPath); |
| 3245 summary->set_in(0, Location::RequiresFpuRegister()); | 3245 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3246 summary->set_temp(0, Location::RequiresRegister()); | 3246 summary->set_temp(0, Location::RequiresRegister()); |
| 3247 summary->set_out(Location::RequiresRegister()); | 3247 summary->set_out(0, Location::RequiresRegister()); |
| 3248 return summary; | 3248 return summary; |
| 3249 } | 3249 } |
| 3250 | 3250 |
| 3251 | 3251 |
| 3252 class BoxInt32x4SlowPath : public SlowPathCode { | 3252 class BoxInt32x4SlowPath : public SlowPathCode { |
| 3253 public: | 3253 public: |
| 3254 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) | 3254 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
| 3255 : instruction_(instruction) { } | 3255 : instruction_(instruction) { } |
| 3256 | 3256 |
| 3257 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 3257 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3258 __ Comment("BoxInt32x4SlowPath"); | 3258 __ Comment("BoxInt32x4SlowPath"); |
| 3259 __ Bind(entry_label()); | 3259 __ Bind(entry_label()); |
| 3260 const Class& int32x4_class = compiler->int32x4_class(); | 3260 const Class& int32x4_class = compiler->int32x4_class(); |
| 3261 const Code& stub = | 3261 const Code& stub = |
| 3262 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); | 3262 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
| 3263 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); | 3263 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
| 3264 | 3264 |
| 3265 LocationSummary* locs = instruction_->locs(); | 3265 LocationSummary* locs = instruction_->locs(); |
| 3266 locs->live_registers()->Remove(locs->out()); | 3266 locs->live_registers()->Remove(locs->out(0)); |
| 3267 | 3267 |
| 3268 compiler->SaveLiveRegisters(locs); | 3268 compiler->SaveLiveRegisters(locs); |
| 3269 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 3269 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 3270 &label, | 3270 &label, |
| 3271 PcDescriptors::kOther, | 3271 PcDescriptors::kOther, |
| 3272 locs); | 3272 locs); |
| 3273 __ mov(locs->out().reg(), ShifterOperand(R0)); | 3273 __ mov(locs->out(0).reg(), ShifterOperand(R0)); |
| 3274 compiler->RestoreLiveRegisters(locs); | 3274 compiler->RestoreLiveRegisters(locs); |
| 3275 | 3275 |
| 3276 __ b(exit_label()); | 3276 __ b(exit_label()); |
| 3277 } | 3277 } |
| 3278 | 3278 |
| 3279 private: | 3279 private: |
| 3280 BoxInt32x4Instr* instruction_; | 3280 BoxInt32x4Instr* instruction_; |
| 3281 }; | 3281 }; |
| 3282 | 3282 |
| 3283 | 3283 |
| 3284 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3284 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3285 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); | 3285 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 3286 compiler->AddSlowPathCode(slow_path); | 3286 compiler->AddSlowPathCode(slow_path); |
| 3287 | 3287 |
| 3288 Register out_reg = locs()->out().reg(); | 3288 Register out_reg = locs()->out(0).reg(); |
| 3289 QRegister value = locs()->in(0).fpu_reg(); | 3289 QRegister value = locs()->in(0).fpu_reg(); |
| 3290 DRegister value_even = EvenDRegisterOf(value); | 3290 DRegister value_even = EvenDRegisterOf(value); |
| 3291 DRegister value_odd = OddDRegisterOf(value); | 3291 DRegister value_odd = OddDRegisterOf(value); |
| 3292 | 3292 |
| 3293 __ TryAllocate(compiler->int32x4_class(), | 3293 __ TryAllocate(compiler->int32x4_class(), |
| 3294 slow_path->entry_label(), | 3294 slow_path->entry_label(), |
| 3295 out_reg, | 3295 out_reg, |
| 3296 locs()->temp(0).reg()); | 3296 locs()->temp(0).reg()); |
| 3297 __ Bind(slow_path->exit_label()); | 3297 __ Bind(slow_path->exit_label()); |
| 3298 __ StoreDToOffset(value_even, out_reg, | 3298 __ StoreDToOffset(value_even, out_reg, |
| 3299 Int32x4::value_offset() - kHeapObjectTag); | 3299 Int32x4::value_offset() - kHeapObjectTag); |
| 3300 __ StoreDToOffset(value_odd, out_reg, | 3300 __ StoreDToOffset(value_odd, out_reg, |
| 3301 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3301 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3302 } | 3302 } |
| 3303 | 3303 |
| 3304 | 3304 |
| 3305 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3305 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3306 const intptr_t value_cid = value()->Type()->ToCid(); | 3306 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3307 const intptr_t kNumInputs = 1; | 3307 const intptr_t kNumInputs = 1; |
| 3308 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3308 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 3309 LocationSummary* summary = | 3309 LocationSummary* summary = |
| 3310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3311 summary->set_in(0, Location::RequiresRegister()); | 3311 summary->set_in(0, Location::RequiresRegister()); |
| 3312 if (kNumTemps > 0) { | 3312 if (kNumTemps > 0) { |
| 3313 ASSERT(kNumTemps == 1); | 3313 ASSERT(kNumTemps == 1); |
| 3314 summary->set_temp(0, Location::RequiresRegister()); | 3314 summary->set_temp(0, Location::RequiresRegister()); |
| 3315 } | 3315 } |
| 3316 summary->set_out(Location::RequiresFpuRegister()); | 3316 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3317 return summary; | 3317 return summary; |
| 3318 } | 3318 } |
| 3319 | 3319 |
| 3320 | 3320 |
| 3321 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3321 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3322 const intptr_t value_cid = value()->Type()->ToCid(); | 3322 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3323 const Register value = locs()->in(0).reg(); | 3323 const Register value = locs()->in(0).reg(); |
| 3324 const QRegister result = locs()->out().fpu_reg(); | 3324 const QRegister result = locs()->out(0).fpu_reg(); |
| 3325 | 3325 |
| 3326 if (value_cid != kInt32x4Cid) { | 3326 if (value_cid != kInt32x4Cid) { |
| 3327 const Register temp = locs()->temp(0).reg(); | 3327 const Register temp = locs()->temp(0).reg(); |
| 3328 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3328 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3329 __ tst(value, ShifterOperand(kSmiTagMask)); | 3329 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3330 __ b(deopt, EQ); | 3330 __ b(deopt, EQ); |
| 3331 __ CompareClassId(value, kInt32x4Cid, temp); | 3331 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3332 __ b(deopt, NE); | 3332 __ b(deopt, NE); |
| 3333 } | 3333 } |
| 3334 | 3334 |
| 3335 const DRegister result_even = EvenDRegisterOf(result); | 3335 const DRegister result_even = EvenDRegisterOf(result); |
| 3336 const DRegister result_odd = OddDRegisterOf(result); | 3336 const DRegister result_odd = OddDRegisterOf(result); |
| 3337 // TODO(zra): Maybe use vldmd here. | 3337 // TODO(zra): Maybe use vldmd here. |
| 3338 __ LoadDFromOffset(result_even, value, | 3338 __ LoadDFromOffset(result_even, value, |
| 3339 Int32x4::value_offset() - kHeapObjectTag); | 3339 Int32x4::value_offset() - kHeapObjectTag); |
| 3340 __ LoadDFromOffset(result_odd, value, | 3340 __ LoadDFromOffset(result_odd, value, |
| 3341 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 3341 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3342 } | 3342 } |
| 3343 | 3343 |
| 3344 | 3344 |
| 3345 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { | 3345 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 3346 const intptr_t kNumInputs = 2; | 3346 const intptr_t kNumInputs = 2; |
| 3347 const intptr_t kNumTemps = 0; | 3347 const intptr_t kNumTemps = 0; |
| 3348 LocationSummary* summary = | 3348 LocationSummary* summary = |
| 3349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3350 summary->set_in(0, Location::RequiresFpuRegister()); | 3350 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3351 summary->set_in(1, Location::RequiresFpuRegister()); | 3351 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3352 summary->set_out(Location::RequiresFpuRegister()); | 3352 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3353 return summary; | 3353 return summary; |
| 3354 } | 3354 } |
| 3355 | 3355 |
| 3356 | 3356 |
| 3357 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3357 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3358 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3358 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3359 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3359 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 3360 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3360 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 3361 switch (op_kind()) { | 3361 switch (op_kind()) { |
| 3362 case Token::kADD: __ vaddd(result, left, right); break; | 3362 case Token::kADD: __ vaddd(result, left, right); break; |
| 3363 case Token::kSUB: __ vsubd(result, left, right); break; | 3363 case Token::kSUB: __ vsubd(result, left, right); break; |
| 3364 case Token::kMUL: __ vmuld(result, left, right); break; | 3364 case Token::kMUL: __ vmuld(result, left, right); break; |
| 3365 case Token::kDIV: __ vdivd(result, left, right); break; | 3365 case Token::kDIV: __ vdivd(result, left, right); break; |
| 3366 default: UNREACHABLE(); | 3366 default: UNREACHABLE(); |
| 3367 } | 3367 } |
| 3368 } | 3368 } |
| 3369 | 3369 |
| 3370 | 3370 |
| 3371 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { | 3371 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 3372 const intptr_t kNumInputs = 2; | 3372 const intptr_t kNumInputs = 2; |
| 3373 const intptr_t kNumTemps = 0; | 3373 const intptr_t kNumTemps = 0; |
| 3374 LocationSummary* summary = | 3374 LocationSummary* summary = |
| 3375 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3375 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3376 summary->set_in(0, Location::RequiresFpuRegister()); | 3376 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3377 summary->set_in(1, Location::RequiresFpuRegister()); | 3377 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3378 summary->set_out(Location::RequiresFpuRegister()); | 3378 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3379 return summary; | 3379 return summary; |
| 3380 } | 3380 } |
| 3381 | 3381 |
| 3382 | 3382 |
| 3383 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3383 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3384 QRegister left = locs()->in(0).fpu_reg(); | 3384 QRegister left = locs()->in(0).fpu_reg(); |
| 3385 QRegister right = locs()->in(1).fpu_reg(); | 3385 QRegister right = locs()->in(1).fpu_reg(); |
| 3386 QRegister result = locs()->out().fpu_reg(); | 3386 QRegister result = locs()->out(0).fpu_reg(); |
| 3387 | 3387 |
| 3388 switch (op_kind()) { | 3388 switch (op_kind()) { |
| 3389 case Token::kADD: __ vaddqs(result, left, right); break; | 3389 case Token::kADD: __ vaddqs(result, left, right); break; |
| 3390 case Token::kSUB: __ vsubqs(result, left, right); break; | 3390 case Token::kSUB: __ vsubqs(result, left, right); break; |
| 3391 case Token::kMUL: __ vmulqs(result, left, right); break; | 3391 case Token::kMUL: __ vmulqs(result, left, right); break; |
| 3392 case Token::kDIV: __ Vdivqs(result, left, right); break; | 3392 case Token::kDIV: __ Vdivqs(result, left, right); break; |
| 3393 default: UNREACHABLE(); | 3393 default: UNREACHABLE(); |
| 3394 } | 3394 } |
| 3395 } | 3395 } |
| 3396 | 3396 |
| 3397 | 3397 |
| 3398 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { | 3398 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { |
| 3399 const intptr_t kNumInputs = 2; | 3399 const intptr_t kNumInputs = 2; |
| 3400 const intptr_t kNumTemps = 0; | 3400 const intptr_t kNumTemps = 0; |
| 3401 LocationSummary* summary = | 3401 LocationSummary* summary = |
| 3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3403 summary->set_in(0, Location::RequiresFpuRegister()); | 3403 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3404 summary->set_in(1, Location::RequiresFpuRegister()); | 3404 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3405 summary->set_out(Location::RequiresFpuRegister()); | 3405 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3406 return summary; | 3406 return summary; |
| 3407 } | 3407 } |
| 3408 | 3408 |
| 3409 | 3409 |
| 3410 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3410 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3411 QRegister left = locs()->in(0).fpu_reg(); | 3411 QRegister left = locs()->in(0).fpu_reg(); |
| 3412 QRegister right = locs()->in(1).fpu_reg(); | 3412 QRegister right = locs()->in(1).fpu_reg(); |
| 3413 QRegister result = locs()->out().fpu_reg(); | 3413 QRegister result = locs()->out(0).fpu_reg(); |
| 3414 | 3414 |
| 3415 DRegister left0 = EvenDRegisterOf(left); | 3415 DRegister left0 = EvenDRegisterOf(left); |
| 3416 DRegister left1 = OddDRegisterOf(left); | 3416 DRegister left1 = OddDRegisterOf(left); |
| 3417 | 3417 |
| 3418 DRegister right0 = EvenDRegisterOf(right); | 3418 DRegister right0 = EvenDRegisterOf(right); |
| 3419 DRegister right1 = OddDRegisterOf(right); | 3419 DRegister right1 = OddDRegisterOf(right); |
| 3420 | 3420 |
| 3421 DRegister result0 = EvenDRegisterOf(result); | 3421 DRegister result0 = EvenDRegisterOf(result); |
| 3422 DRegister result1 = OddDRegisterOf(result); | 3422 DRegister result1 = OddDRegisterOf(result); |
| 3423 | 3423 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3443 } | 3443 } |
| 3444 | 3444 |
| 3445 | 3445 |
| 3446 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { | 3446 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
| 3447 const intptr_t kNumInputs = 1; | 3447 const intptr_t kNumInputs = 1; |
| 3448 const intptr_t kNumTemps = 0; | 3448 const intptr_t kNumTemps = 0; |
| 3449 LocationSummary* summary = | 3449 LocationSummary* summary = |
| 3450 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3450 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3451 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3451 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
| 3452 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3452 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
| 3453 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3453 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 3454 return summary; | 3454 return summary; |
| 3455 } | 3455 } |
| 3456 | 3456 |
| 3457 | 3457 |
| 3458 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3458 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3459 QRegister value = locs()->in(0).fpu_reg(); | 3459 QRegister value = locs()->in(0).fpu_reg(); |
| 3460 QRegister result = locs()->out().fpu_reg(); | 3460 QRegister result = locs()->out(0).fpu_reg(); |
| 3461 DRegister dresult0 = EvenDRegisterOf(result); | 3461 DRegister dresult0 = EvenDRegisterOf(result); |
| 3462 DRegister dresult1 = OddDRegisterOf(result); | 3462 DRegister dresult1 = OddDRegisterOf(result); |
| 3463 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3463 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 3464 SRegister sresult1 = OddSRegisterOf(dresult0); | 3464 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 3465 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3465 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 3466 SRegister sresult3 = OddSRegisterOf(dresult1); | 3466 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 3467 | 3467 |
| 3468 DRegister dvalue0 = EvenDRegisterOf(value); | 3468 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3469 DRegister dvalue1 = OddDRegisterOf(value); | 3469 DRegister dvalue1 = OddDRegisterOf(value); |
| 3470 | 3470 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3524 | 3524 |
| 3525 | 3525 |
| 3526 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { | 3526 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { |
| 3527 const intptr_t kNumInputs = 2; | 3527 const intptr_t kNumInputs = 2; |
| 3528 const intptr_t kNumTemps = 0; | 3528 const intptr_t kNumTemps = 0; |
| 3529 LocationSummary* summary = | 3529 LocationSummary* summary = |
| 3530 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3530 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3531 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3531 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
| 3532 summary->set_in(0, Location::FpuRegisterLocation(Q4)); | 3532 summary->set_in(0, Location::FpuRegisterLocation(Q4)); |
| 3533 summary->set_in(1, Location::FpuRegisterLocation(Q5)); | 3533 summary->set_in(1, Location::FpuRegisterLocation(Q5)); |
| 3534 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3534 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 3535 return summary; | 3535 return summary; |
| 3536 } | 3536 } |
| 3537 | 3537 |
| 3538 | 3538 |
| 3539 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3539 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3540 QRegister left = locs()->in(0).fpu_reg(); | 3540 QRegister left = locs()->in(0).fpu_reg(); |
| 3541 QRegister right = locs()->in(1).fpu_reg(); | 3541 QRegister right = locs()->in(1).fpu_reg(); |
| 3542 QRegister result = locs()->out().fpu_reg(); | 3542 QRegister result = locs()->out(0).fpu_reg(); |
| 3543 | 3543 |
| 3544 DRegister dresult0 = EvenDRegisterOf(result); | 3544 DRegister dresult0 = EvenDRegisterOf(result); |
| 3545 DRegister dresult1 = OddDRegisterOf(result); | 3545 DRegister dresult1 = OddDRegisterOf(result); |
| 3546 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3546 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 3547 SRegister sresult1 = OddSRegisterOf(dresult0); | 3547 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 3548 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3548 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 3549 SRegister sresult3 = OddSRegisterOf(dresult1); | 3549 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 3550 | 3550 |
| 3551 DRegister dleft0 = EvenDRegisterOf(left); | 3551 DRegister dleft0 = EvenDRegisterOf(left); |
| 3552 DRegister dleft1 = OddDRegisterOf(left); | 3552 DRegister dleft1 = OddDRegisterOf(left); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3579 } | 3579 } |
| 3580 | 3580 |
| 3581 | 3581 |
| 3582 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { | 3582 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { |
| 3583 const intptr_t kNumInputs = 1; | 3583 const intptr_t kNumInputs = 1; |
| 3584 const intptr_t kNumTemps = 1; | 3584 const intptr_t kNumTemps = 1; |
| 3585 LocationSummary* summary = | 3585 LocationSummary* summary = |
| 3586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3587 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3587 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
| 3588 summary->set_temp(0, Location::RequiresRegister()); | 3588 summary->set_temp(0, Location::RequiresRegister()); |
| 3589 summary->set_out(Location::RequiresRegister()); | 3589 summary->set_out(0, Location::RequiresRegister()); |
| 3590 return summary; | 3590 return summary; |
| 3591 } | 3591 } |
| 3592 | 3592 |
| 3593 | 3593 |
| 3594 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3594 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3595 QRegister value = locs()->in(0).fpu_reg(); | 3595 QRegister value = locs()->in(0).fpu_reg(); |
| 3596 DRegister dvalue0 = EvenDRegisterOf(value); | 3596 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3597 DRegister dvalue1 = OddDRegisterOf(value); | 3597 DRegister dvalue1 = OddDRegisterOf(value); |
| 3598 | 3598 |
| 3599 Register out = locs()->out().reg(); | 3599 Register out = locs()->out(0).reg(); |
| 3600 Register temp = locs()->temp(0).reg(); | 3600 Register temp = locs()->temp(0).reg(); |
| 3601 | 3601 |
| 3602 // X lane. | 3602 // X lane. |
| 3603 __ vmovrs(out, EvenSRegisterOf(dvalue0)); | 3603 __ vmovrs(out, EvenSRegisterOf(dvalue0)); |
| 3604 __ Lsr(out, out, 31); | 3604 __ Lsr(out, out, 31); |
| 3605 // Y lane. | 3605 // Y lane. |
| 3606 __ vmovrs(temp, OddSRegisterOf(dvalue0)); | 3606 __ vmovrs(temp, OddSRegisterOf(dvalue0)); |
| 3607 __ Lsr(temp, temp, 31); | 3607 __ Lsr(temp, temp, 31); |
| 3608 __ orr(out, out, ShifterOperand(temp, LSL, 1)); | 3608 __ orr(out, out, ShifterOperand(temp, LSL, 1)); |
| 3609 // Z lane. | 3609 // Z lane. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3623 bool opt) const { | 3623 bool opt) const { |
| 3624 const intptr_t kNumInputs = 4; | 3624 const intptr_t kNumInputs = 4; |
| 3625 const intptr_t kNumTemps = 0; | 3625 const intptr_t kNumTemps = 0; |
| 3626 LocationSummary* summary = | 3626 LocationSummary* summary = |
| 3627 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3627 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3628 summary->set_in(0, Location::RequiresFpuRegister()); | 3628 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3629 summary->set_in(1, Location::RequiresFpuRegister()); | 3629 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3630 summary->set_in(2, Location::RequiresFpuRegister()); | 3630 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3631 summary->set_in(3, Location::RequiresFpuRegister()); | 3631 summary->set_in(3, Location::RequiresFpuRegister()); |
| 3632 // Low (< 7) Q registers are needed for the vcvtsd instruction. | 3632 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 3633 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3633 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 3634 return summary; | 3634 return summary; |
| 3635 } | 3635 } |
| 3636 | 3636 |
| 3637 | 3637 |
| 3638 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3638 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3639 QRegister q0 = locs()->in(0).fpu_reg(); | 3639 QRegister q0 = locs()->in(0).fpu_reg(); |
| 3640 QRegister q1 = locs()->in(1).fpu_reg(); | 3640 QRegister q1 = locs()->in(1).fpu_reg(); |
| 3641 QRegister q2 = locs()->in(2).fpu_reg(); | 3641 QRegister q2 = locs()->in(2).fpu_reg(); |
| 3642 QRegister q3 = locs()->in(3).fpu_reg(); | 3642 QRegister q3 = locs()->in(3).fpu_reg(); |
| 3643 QRegister r = locs()->out().fpu_reg(); | 3643 QRegister r = locs()->out(0).fpu_reg(); |
| 3644 | 3644 |
| 3645 DRegister dr0 = EvenDRegisterOf(r); | 3645 DRegister dr0 = EvenDRegisterOf(r); |
| 3646 DRegister dr1 = OddDRegisterOf(r); | 3646 DRegister dr1 = OddDRegisterOf(r); |
| 3647 | 3647 |
| 3648 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); | 3648 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); |
| 3649 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); | 3649 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); |
| 3650 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); | 3650 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); |
| 3651 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); | 3651 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); |
| 3652 } | 3652 } |
| 3653 | 3653 |
| 3654 | 3654 |
| 3655 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { | 3655 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { |
| 3656 const intptr_t kNumInputs = 0; | 3656 const intptr_t kNumInputs = 0; |
| 3657 const intptr_t kNumTemps = 0; | 3657 const intptr_t kNumTemps = 0; |
| 3658 LocationSummary* summary = | 3658 LocationSummary* summary = |
| 3659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3660 summary->set_out(Location::RequiresFpuRegister()); | 3660 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3661 return summary; | 3661 return summary; |
| 3662 } | 3662 } |
| 3663 | 3663 |
| 3664 | 3664 |
| 3665 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3665 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3666 QRegister q = locs()->out().fpu_reg(); | 3666 QRegister q = locs()->out(0).fpu_reg(); |
| 3667 __ veorq(q, q, q); | 3667 __ veorq(q, q, q); |
| 3668 } | 3668 } |
| 3669 | 3669 |
| 3670 | 3670 |
| 3671 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { | 3671 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { |
| 3672 const intptr_t kNumInputs = 1; | 3672 const intptr_t kNumInputs = 1; |
| 3673 const intptr_t kNumTemps = 0; | 3673 const intptr_t kNumTemps = 0; |
| 3674 LocationSummary* summary = | 3674 LocationSummary* summary = |
| 3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3676 summary->set_in(0, Location::RequiresFpuRegister()); | 3676 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3677 summary->set_out(Location::RequiresFpuRegister()); | 3677 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3678 return summary; | 3678 return summary; |
| 3679 } | 3679 } |
| 3680 | 3680 |
| 3681 | 3681 |
| 3682 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3682 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3683 QRegister value = locs()->in(0).fpu_reg(); | 3683 QRegister value = locs()->in(0).fpu_reg(); |
| 3684 QRegister result = locs()->out().fpu_reg(); | 3684 QRegister result = locs()->out(0).fpu_reg(); |
| 3685 | 3685 |
| 3686 DRegister dvalue0 = EvenDRegisterOf(value); | 3686 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3687 | 3687 |
| 3688 // Convert to Float32. | 3688 // Convert to Float32. |
| 3689 __ vcvtsd(STMP, dvalue0); | 3689 __ vcvtsd(STMP, dvalue0); |
| 3690 | 3690 |
| 3691 // Splat across all lanes. | 3691 // Splat across all lanes. |
| 3692 __ vdup(kWord, result, DTMP, 0); | 3692 __ vdup(kWord, result, DTMP, 0); |
| 3693 } | 3693 } |
| 3694 | 3694 |
| 3695 | 3695 |
| 3696 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { | 3696 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { |
| 3697 const intptr_t kNumInputs = 2; | 3697 const intptr_t kNumInputs = 2; |
| 3698 const intptr_t kNumTemps = 0; | 3698 const intptr_t kNumTemps = 0; |
| 3699 LocationSummary* summary = | 3699 LocationSummary* summary = |
| 3700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3701 summary->set_in(0, Location::RequiresFpuRegister()); | 3701 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3702 summary->set_in(1, Location::RequiresFpuRegister()); | 3702 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3703 summary->set_out(Location::RequiresFpuRegister()); | 3703 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3704 return summary; | 3704 return summary; |
| 3705 } | 3705 } |
| 3706 | 3706 |
| 3707 | 3707 |
| 3708 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3708 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3709 QRegister left = locs()->in(0).fpu_reg(); | 3709 QRegister left = locs()->in(0).fpu_reg(); |
| 3710 QRegister right = locs()->in(1).fpu_reg(); | 3710 QRegister right = locs()->in(1).fpu_reg(); |
| 3711 QRegister result = locs()->out().fpu_reg(); | 3711 QRegister result = locs()->out(0).fpu_reg(); |
| 3712 | 3712 |
| 3713 switch (op_kind()) { | 3713 switch (op_kind()) { |
| 3714 case MethodRecognizer::kFloat32x4Equal: | 3714 case MethodRecognizer::kFloat32x4Equal: |
| 3715 __ vceqqs(result, left, right); | 3715 __ vceqqs(result, left, right); |
| 3716 break; | 3716 break; |
| 3717 case MethodRecognizer::kFloat32x4NotEqual: | 3717 case MethodRecognizer::kFloat32x4NotEqual: |
| 3718 __ vceqqs(result, left, right); | 3718 __ vceqqs(result, left, right); |
| 3719 // Invert the result. | 3719 // Invert the result. |
| 3720 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. | 3720 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. |
| 3721 __ vornq(result, QTMP, result); // result <- ~result. | 3721 __ vornq(result, QTMP, result); // result <- ~result. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3738 } | 3738 } |
| 3739 | 3739 |
| 3740 | 3740 |
| 3741 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { | 3741 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { |
| 3742 const intptr_t kNumInputs = 2; | 3742 const intptr_t kNumInputs = 2; |
| 3743 const intptr_t kNumTemps = 0; | 3743 const intptr_t kNumTemps = 0; |
| 3744 LocationSummary* summary = | 3744 LocationSummary* summary = |
| 3745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3746 summary->set_in(0, Location::RequiresFpuRegister()); | 3746 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3747 summary->set_in(1, Location::RequiresFpuRegister()); | 3747 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3748 summary->set_out(Location::RequiresFpuRegister()); | 3748 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3749 return summary; | 3749 return summary; |
| 3750 } | 3750 } |
| 3751 | 3751 |
| 3752 | 3752 |
| 3753 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3753 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3754 QRegister left = locs()->in(0).fpu_reg(); | 3754 QRegister left = locs()->in(0).fpu_reg(); |
| 3755 QRegister right = locs()->in(1).fpu_reg(); | 3755 QRegister right = locs()->in(1).fpu_reg(); |
| 3756 QRegister result = locs()->out().fpu_reg(); | 3756 QRegister result = locs()->out(0).fpu_reg(); |
| 3757 | 3757 |
| 3758 switch (op_kind()) { | 3758 switch (op_kind()) { |
| 3759 case MethodRecognizer::kFloat32x4Min: | 3759 case MethodRecognizer::kFloat32x4Min: |
| 3760 __ vminqs(result, left, right); | 3760 __ vminqs(result, left, right); |
| 3761 break; | 3761 break; |
| 3762 case MethodRecognizer::kFloat32x4Max: | 3762 case MethodRecognizer::kFloat32x4Max: |
| 3763 __ vmaxqs(result, left, right); | 3763 __ vmaxqs(result, left, right); |
| 3764 break; | 3764 break; |
| 3765 default: UNREACHABLE(); | 3765 default: UNREACHABLE(); |
| 3766 } | 3766 } |
| 3767 } | 3767 } |
| 3768 | 3768 |
| 3769 | 3769 |
| 3770 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { | 3770 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { |
| 3771 const intptr_t kNumInputs = 1; | 3771 const intptr_t kNumInputs = 1; |
| 3772 const intptr_t kNumTemps = 1; | 3772 const intptr_t kNumTemps = 1; |
| 3773 LocationSummary* summary = | 3773 LocationSummary* summary = |
| 3774 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3774 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3775 summary->set_in(0, Location::RequiresFpuRegister()); | 3775 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3776 summary->set_out(Location::RequiresFpuRegister()); | 3776 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3777 summary->set_temp(0, Location::RequiresFpuRegister()); | 3777 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3778 return summary; | 3778 return summary; |
| 3779 } | 3779 } |
| 3780 | 3780 |
| 3781 | 3781 |
| 3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3783 QRegister left = locs()->in(0).fpu_reg(); | 3783 QRegister left = locs()->in(0).fpu_reg(); |
| 3784 QRegister result = locs()->out().fpu_reg(); | 3784 QRegister result = locs()->out(0).fpu_reg(); |
| 3785 QRegister temp = locs()->temp(0).fpu_reg(); | 3785 QRegister temp = locs()->temp(0).fpu_reg(); |
| 3786 | 3786 |
| 3787 switch (op_kind()) { | 3787 switch (op_kind()) { |
| 3788 case MethodRecognizer::kFloat32x4Sqrt: | 3788 case MethodRecognizer::kFloat32x4Sqrt: |
| 3789 __ Vsqrtqs(result, left, temp); | 3789 __ Vsqrtqs(result, left, temp); |
| 3790 break; | 3790 break; |
| 3791 case MethodRecognizer::kFloat32x4Reciprocal: | 3791 case MethodRecognizer::kFloat32x4Reciprocal: |
| 3792 __ Vreciprocalqs(result, left); | 3792 __ Vreciprocalqs(result, left); |
| 3793 break; | 3793 break; |
| 3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt: | 3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt: |
| 3795 __ VreciprocalSqrtqs(result, left); | 3795 __ VreciprocalSqrtqs(result, left); |
| 3796 break; | 3796 break; |
| 3797 default: UNREACHABLE(); | 3797 default: UNREACHABLE(); |
| 3798 } | 3798 } |
| 3799 } | 3799 } |
| 3800 | 3800 |
| 3801 | 3801 |
| 3802 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { | 3802 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { |
| 3803 const intptr_t kNumInputs = 2; | 3803 const intptr_t kNumInputs = 2; |
| 3804 const intptr_t kNumTemps = 0; | 3804 const intptr_t kNumTemps = 0; |
| 3805 LocationSummary* summary = | 3805 LocationSummary* summary = |
| 3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3807 summary->set_in(0, Location::RequiresFpuRegister()); | 3807 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3808 summary->set_in(1, Location::RequiresFpuRegister()); | 3808 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3809 summary->set_out(Location::RequiresFpuRegister()); | 3809 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3810 return summary; | 3810 return summary; |
| 3811 } | 3811 } |
| 3812 | 3812 |
| 3813 | 3813 |
| 3814 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3814 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3815 QRegister left = locs()->in(0).fpu_reg(); | 3815 QRegister left = locs()->in(0).fpu_reg(); |
| 3816 QRegister right = locs()->in(1).fpu_reg(); | 3816 QRegister right = locs()->in(1).fpu_reg(); |
| 3817 QRegister result = locs()->out().fpu_reg(); | 3817 QRegister result = locs()->out(0).fpu_reg(); |
| 3818 | 3818 |
| 3819 switch (op_kind()) { | 3819 switch (op_kind()) { |
| 3820 case MethodRecognizer::kFloat32x4Scale: | 3820 case MethodRecognizer::kFloat32x4Scale: |
| 3821 __ vcvtsd(STMP, EvenDRegisterOf(left)); | 3821 __ vcvtsd(STMP, EvenDRegisterOf(left)); |
| 3822 __ vdup(kWord, result, DTMP, 0); | 3822 __ vdup(kWord, result, DTMP, 0); |
| 3823 __ vmulqs(result, result, right); | 3823 __ vmulqs(result, result, right); |
| 3824 break; | 3824 break; |
| 3825 default: UNREACHABLE(); | 3825 default: UNREACHABLE(); |
| 3826 } | 3826 } |
| 3827 } | 3827 } |
| 3828 | 3828 |
| 3829 | 3829 |
| 3830 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { | 3830 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { |
| 3831 const intptr_t kNumInputs = 1; | 3831 const intptr_t kNumInputs = 1; |
| 3832 const intptr_t kNumTemps = 0; | 3832 const intptr_t kNumTemps = 0; |
| 3833 LocationSummary* summary = | 3833 LocationSummary* summary = |
| 3834 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3834 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3835 summary->set_in(0, Location::RequiresFpuRegister()); | 3835 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3836 summary->set_out(Location::RequiresFpuRegister()); | 3836 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3837 return summary; | 3837 return summary; |
| 3838 } | 3838 } |
| 3839 | 3839 |
| 3840 | 3840 |
| 3841 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3841 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3842 QRegister left = locs()->in(0).fpu_reg(); | 3842 QRegister left = locs()->in(0).fpu_reg(); |
| 3843 QRegister result = locs()->out().fpu_reg(); | 3843 QRegister result = locs()->out(0).fpu_reg(); |
| 3844 | 3844 |
| 3845 switch (op_kind()) { | 3845 switch (op_kind()) { |
| 3846 case MethodRecognizer::kFloat32x4Negate: | 3846 case MethodRecognizer::kFloat32x4Negate: |
| 3847 __ vnegqs(result, left); | 3847 __ vnegqs(result, left); |
| 3848 break; | 3848 break; |
| 3849 case MethodRecognizer::kFloat32x4Absolute: | 3849 case MethodRecognizer::kFloat32x4Absolute: |
| 3850 __ vabsqs(result, left); | 3850 __ vabsqs(result, left); |
| 3851 break; | 3851 break; |
| 3852 default: UNREACHABLE(); | 3852 default: UNREACHABLE(); |
| 3853 } | 3853 } |
| 3854 } | 3854 } |
| 3855 | 3855 |
| 3856 | 3856 |
| 3857 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { | 3857 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { |
| 3858 const intptr_t kNumInputs = 3; | 3858 const intptr_t kNumInputs = 3; |
| 3859 const intptr_t kNumTemps = 0; | 3859 const intptr_t kNumTemps = 0; |
| 3860 LocationSummary* summary = | 3860 LocationSummary* summary = |
| 3861 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3861 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3862 summary->set_in(0, Location::RequiresFpuRegister()); | 3862 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3863 summary->set_in(1, Location::RequiresFpuRegister()); | 3863 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3864 summary->set_in(2, Location::RequiresFpuRegister()); | 3864 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3865 summary->set_out(Location::RequiresFpuRegister()); | 3865 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3866 return summary; | 3866 return summary; |
| 3867 } | 3867 } |
| 3868 | 3868 |
| 3869 | 3869 |
| 3870 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3870 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3871 QRegister left = locs()->in(0).fpu_reg(); | 3871 QRegister left = locs()->in(0).fpu_reg(); |
| 3872 QRegister lower = locs()->in(1).fpu_reg(); | 3872 QRegister lower = locs()->in(1).fpu_reg(); |
| 3873 QRegister upper = locs()->in(2).fpu_reg(); | 3873 QRegister upper = locs()->in(2).fpu_reg(); |
| 3874 QRegister result = locs()->out().fpu_reg(); | 3874 QRegister result = locs()->out(0).fpu_reg(); |
| 3875 __ vminqs(result, left, upper); | 3875 __ vminqs(result, left, upper); |
| 3876 __ vmaxqs(result, result, lower); | 3876 __ vmaxqs(result, result, lower); |
| 3877 } | 3877 } |
| 3878 | 3878 |
| 3879 | 3879 |
| 3880 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { | 3880 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { |
| 3881 const intptr_t kNumInputs = 2; | 3881 const intptr_t kNumInputs = 2; |
| 3882 const intptr_t kNumTemps = 0; | 3882 const intptr_t kNumTemps = 0; |
| 3883 LocationSummary* summary = | 3883 LocationSummary* summary = |
| 3884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3885 summary->set_in(0, Location::RequiresFpuRegister()); | 3885 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3886 summary->set_in(1, Location::RequiresFpuRegister()); | 3886 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3887 // Low (< 7) Q registers are needed for the vmovs instruction. | 3887 // Low (< 7) Q registers are needed for the vmovs instruction. |
| 3888 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3888 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 3889 return summary; | 3889 return summary; |
| 3890 } | 3890 } |
| 3891 | 3891 |
| 3892 | 3892 |
| 3893 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3893 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3894 QRegister replacement = locs()->in(0).fpu_reg(); | 3894 QRegister replacement = locs()->in(0).fpu_reg(); |
| 3895 QRegister value = locs()->in(1).fpu_reg(); | 3895 QRegister value = locs()->in(1).fpu_reg(); |
| 3896 QRegister result = locs()->out().fpu_reg(); | 3896 QRegister result = locs()->out(0).fpu_reg(); |
| 3897 | 3897 |
| 3898 DRegister dresult0 = EvenDRegisterOf(result); | 3898 DRegister dresult0 = EvenDRegisterOf(result); |
| 3899 DRegister dresult1 = OddDRegisterOf(result); | 3899 DRegister dresult1 = OddDRegisterOf(result); |
| 3900 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3900 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 3901 SRegister sresult1 = OddSRegisterOf(dresult0); | 3901 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 3902 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3902 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 3903 SRegister sresult3 = OddSRegisterOf(dresult1); | 3903 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 3904 | 3904 |
| 3905 __ vcvtsd(STMP, EvenDRegisterOf(replacement)); | 3905 __ vcvtsd(STMP, EvenDRegisterOf(replacement)); |
| 3906 if (result != value) { | 3906 if (result != value) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3924 } | 3924 } |
| 3925 } | 3925 } |
| 3926 | 3926 |
| 3927 | 3927 |
| 3928 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { | 3928 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3929 const intptr_t kNumInputs = 1; | 3929 const intptr_t kNumInputs = 1; |
| 3930 const intptr_t kNumTemps = 0; | 3930 const intptr_t kNumTemps = 0; |
| 3931 LocationSummary* summary = | 3931 LocationSummary* summary = |
| 3932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3933 summary->set_in(0, Location::RequiresFpuRegister()); | 3933 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3934 summary->set_out(Location::RequiresFpuRegister()); | 3934 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3935 return summary; | 3935 return summary; |
| 3936 } | 3936 } |
| 3937 | 3937 |
| 3938 | 3938 |
| 3939 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3939 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3940 QRegister value = locs()->in(0).fpu_reg(); | 3940 QRegister value = locs()->in(0).fpu_reg(); |
| 3941 QRegister result = locs()->out().fpu_reg(); | 3941 QRegister result = locs()->out(0).fpu_reg(); |
| 3942 | 3942 |
| 3943 if (value != result) { | 3943 if (value != result) { |
| 3944 __ vmovq(result, value); | 3944 __ vmovq(result, value); |
| 3945 } | 3945 } |
| 3946 } | 3946 } |
| 3947 | 3947 |
| 3948 | 3948 |
| 3949 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { | 3949 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { |
| 3950 const intptr_t kNumInputs = 1; | 3950 const intptr_t kNumInputs = 1; |
| 3951 const intptr_t kNumTemps = 0; | 3951 const intptr_t kNumTemps = 0; |
| 3952 LocationSummary* summary = | 3952 LocationSummary* summary = |
| 3953 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3953 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3954 summary->set_in(0, Location::RequiresFpuRegister()); | 3954 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3955 summary->set_out(Location::RequiresFpuRegister()); | 3955 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3956 return summary; | 3956 return summary; |
| 3957 } | 3957 } |
| 3958 | 3958 |
| 3959 | 3959 |
| 3960 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3960 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3961 QRegister value = locs()->in(0).fpu_reg(); | 3961 QRegister value = locs()->in(0).fpu_reg(); |
| 3962 | 3962 |
| 3963 DRegister dvalue0 = EvenDRegisterOf(value); | 3963 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3964 DRegister dvalue1 = OddDRegisterOf(value); | 3964 DRegister dvalue1 = OddDRegisterOf(value); |
| 3965 | 3965 |
| 3966 QRegister result = locs()->out().fpu_reg(); | 3966 QRegister result = locs()->out(0).fpu_reg(); |
| 3967 | 3967 |
| 3968 DRegister dresult0 = EvenDRegisterOf(result); | 3968 DRegister dresult0 = EvenDRegisterOf(result); |
| 3969 | 3969 |
| 3970 switch (op_kind()) { | 3970 switch (op_kind()) { |
| 3971 case MethodRecognizer::kFloat64x2GetX: | 3971 case MethodRecognizer::kFloat64x2GetX: |
| 3972 __ vmovd(dresult0, dvalue0); | 3972 __ vmovd(dresult0, dvalue0); |
| 3973 break; | 3973 break; |
| 3974 case MethodRecognizer::kFloat64x2GetY: | 3974 case MethodRecognizer::kFloat64x2GetY: |
| 3975 __ vmovd(dresult0, dvalue1); | 3975 __ vmovd(dresult0, dvalue1); |
| 3976 break; | 3976 break; |
| 3977 default: UNREACHABLE(); | 3977 default: UNREACHABLE(); |
| 3978 } | 3978 } |
| 3979 } | 3979 } |
| 3980 | 3980 |
| 3981 | 3981 |
| 3982 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { | 3982 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { |
| 3983 const intptr_t kNumInputs = 0; | 3983 const intptr_t kNumInputs = 0; |
| 3984 const intptr_t kNumTemps = 0; | 3984 const intptr_t kNumTemps = 0; |
| 3985 LocationSummary* summary = | 3985 LocationSummary* summary = |
| 3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3987 summary->set_out(Location::RequiresFpuRegister()); | 3987 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3988 return summary; | 3988 return summary; |
| 3989 } | 3989 } |
| 3990 | 3990 |
| 3991 | 3991 |
| 3992 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3992 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3993 QRegister q = locs()->out().fpu_reg(); | 3993 QRegister q = locs()->out(0).fpu_reg(); |
| 3994 __ veorq(q, q, q); | 3994 __ veorq(q, q, q); |
| 3995 } | 3995 } |
| 3996 | 3996 |
| 3997 | 3997 |
| 3998 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { | 3998 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { |
| 3999 const intptr_t kNumInputs = 1; | 3999 const intptr_t kNumInputs = 1; |
| 4000 const intptr_t kNumTemps = 0; | 4000 const intptr_t kNumTemps = 0; |
| 4001 LocationSummary* summary = | 4001 LocationSummary* summary = |
| 4002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4003 summary->set_in(0, Location::RequiresFpuRegister()); | 4003 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4004 summary->set_out(Location::RequiresFpuRegister()); | 4004 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4005 return summary; | 4005 return summary; |
| 4006 } | 4006 } |
| 4007 | 4007 |
| 4008 | 4008 |
| 4009 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4009 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4010 QRegister value = locs()->in(0).fpu_reg(); | 4010 QRegister value = locs()->in(0).fpu_reg(); |
| 4011 | 4011 |
| 4012 DRegister dvalue = EvenDRegisterOf(value); | 4012 DRegister dvalue = EvenDRegisterOf(value); |
| 4013 | 4013 |
| 4014 QRegister result = locs()->out().fpu_reg(); | 4014 QRegister result = locs()->out(0).fpu_reg(); |
| 4015 | 4015 |
| 4016 DRegister dresult0 = EvenDRegisterOf(result); | 4016 DRegister dresult0 = EvenDRegisterOf(result); |
| 4017 DRegister dresult1 = OddDRegisterOf(result); | 4017 DRegister dresult1 = OddDRegisterOf(result); |
| 4018 | 4018 |
| 4019 // Splat across all lanes. | 4019 // Splat across all lanes. |
| 4020 __ vmovd(dresult0, dvalue); | 4020 __ vmovd(dresult0, dvalue); |
| 4021 __ vmovd(dresult1, dvalue); | 4021 __ vmovd(dresult1, dvalue); |
| 4022 } | 4022 } |
| 4023 | 4023 |
| 4024 | 4024 |
| 4025 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( | 4025 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( |
| 4026 bool opt) const { | 4026 bool opt) const { |
| 4027 const intptr_t kNumInputs = 2; | 4027 const intptr_t kNumInputs = 2; |
| 4028 const intptr_t kNumTemps = 0; | 4028 const intptr_t kNumTemps = 0; |
| 4029 LocationSummary* summary = | 4029 LocationSummary* summary = |
| 4030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4031 summary->set_in(0, Location::RequiresFpuRegister()); | 4031 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4032 summary->set_in(1, Location::RequiresFpuRegister()); | 4032 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4033 summary->set_out(Location::RequiresFpuRegister()); | 4033 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4034 return summary; | 4034 return summary; |
| 4035 } | 4035 } |
| 4036 | 4036 |
| 4037 | 4037 |
| 4038 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4038 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4039 QRegister q0 = locs()->in(0).fpu_reg(); | 4039 QRegister q0 = locs()->in(0).fpu_reg(); |
| 4040 QRegister q1 = locs()->in(1).fpu_reg(); | 4040 QRegister q1 = locs()->in(1).fpu_reg(); |
| 4041 QRegister r = locs()->out().fpu_reg(); | 4041 QRegister r = locs()->out(0).fpu_reg(); |
| 4042 | 4042 |
| 4043 DRegister d0 = EvenDRegisterOf(q0); | 4043 DRegister d0 = EvenDRegisterOf(q0); |
| 4044 DRegister d1 = EvenDRegisterOf(q1); | 4044 DRegister d1 = EvenDRegisterOf(q1); |
| 4045 | 4045 |
| 4046 DRegister dr0 = EvenDRegisterOf(r); | 4046 DRegister dr0 = EvenDRegisterOf(r); |
| 4047 DRegister dr1 = OddDRegisterOf(r); | 4047 DRegister dr1 = OddDRegisterOf(r); |
| 4048 | 4048 |
| 4049 __ vmovd(dr0, d0); | 4049 __ vmovd(dr0, d0); |
| 4050 __ vmovd(dr1, d1); | 4050 __ vmovd(dr1, d1); |
| 4051 } | 4051 } |
| 4052 | 4052 |
| 4053 | 4053 |
| 4054 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( | 4054 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( |
| 4055 bool opt) const { | 4055 bool opt) const { |
| 4056 const intptr_t kNumInputs = 1; | 4056 const intptr_t kNumInputs = 1; |
| 4057 const intptr_t kNumTemps = 0; | 4057 const intptr_t kNumTemps = 0; |
| 4058 LocationSummary* summary = | 4058 LocationSummary* summary = |
| 4059 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4059 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4060 summary->set_in(0, Location::RequiresFpuRegister()); | 4060 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4061 // Low (< 7) Q registers are needed for the vcvtsd instruction. | 4061 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 4062 summary->set_out(Location::FpuRegisterLocation(Q6)); | 4062 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 4063 return summary; | 4063 return summary; |
| 4064 } | 4064 } |
| 4065 | 4065 |
| 4066 | 4066 |
| 4067 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4067 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4068 QRegister q = locs()->in(0).fpu_reg(); | 4068 QRegister q = locs()->in(0).fpu_reg(); |
| 4069 QRegister r = locs()->out().fpu_reg(); | 4069 QRegister r = locs()->out(0).fpu_reg(); |
| 4070 | 4070 |
| 4071 DRegister dq0 = EvenDRegisterOf(q); | 4071 DRegister dq0 = EvenDRegisterOf(q); |
| 4072 DRegister dq1 = OddDRegisterOf(q); | 4072 DRegister dq1 = OddDRegisterOf(q); |
| 4073 | 4073 |
| 4074 DRegister dr0 = EvenDRegisterOf(r); | 4074 DRegister dr0 = EvenDRegisterOf(r); |
| 4075 | 4075 |
| 4076 // Zero register. | 4076 // Zero register. |
| 4077 __ veorq(r, r, r); | 4077 __ veorq(r, r, r); |
| 4078 // Set X lane. | 4078 // Set X lane. |
| 4079 __ vcvtsd(EvenSRegisterOf(dr0), dq0); | 4079 __ vcvtsd(EvenSRegisterOf(dr0), dq0); |
| 4080 // Set Y lane. | 4080 // Set Y lane. |
| 4081 __ vcvtsd(OddSRegisterOf(dr0), dq1); | 4081 __ vcvtsd(OddSRegisterOf(dr0), dq1); |
| 4082 } | 4082 } |
| 4083 | 4083 |
| 4084 | 4084 |
| 4085 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( | 4085 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( |
| 4086 bool opt) const { | 4086 bool opt) const { |
| 4087 const intptr_t kNumInputs = 1; | 4087 const intptr_t kNumInputs = 1; |
| 4088 const intptr_t kNumTemps = 0; | 4088 const intptr_t kNumTemps = 0; |
| 4089 LocationSummary* summary = | 4089 LocationSummary* summary = |
| 4090 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4090 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4091 summary->set_in(0, Location::RequiresFpuRegister()); | 4091 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4092 // Low (< 7) Q registers are needed for the vcvtsd instruction. | 4092 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
| 4093 summary->set_out(Location::FpuRegisterLocation(Q6)); | 4093 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 4094 return summary; | 4094 return summary; |
| 4095 } | 4095 } |
| 4096 | 4096 |
| 4097 | 4097 |
| 4098 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4098 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4099 QRegister q = locs()->in(0).fpu_reg(); | 4099 QRegister q = locs()->in(0).fpu_reg(); |
| 4100 QRegister r = locs()->out().fpu_reg(); | 4100 QRegister r = locs()->out(0).fpu_reg(); |
| 4101 | 4101 |
| 4102 DRegister dq0 = EvenDRegisterOf(q); | 4102 DRegister dq0 = EvenDRegisterOf(q); |
| 4103 | 4103 |
| 4104 DRegister dr0 = EvenDRegisterOf(r); | 4104 DRegister dr0 = EvenDRegisterOf(r); |
| 4105 DRegister dr1 = OddDRegisterOf(r); | 4105 DRegister dr1 = OddDRegisterOf(r); |
| 4106 | 4106 |
| 4107 // Set X. | 4107 // Set X. |
| 4108 __ vcvtds(dr0, EvenSRegisterOf(dq0)); | 4108 __ vcvtds(dr0, EvenSRegisterOf(dq0)); |
| 4109 // Set Y. | 4109 // Set Y. |
| 4110 __ vcvtds(dr1, OddSRegisterOf(dq0)); | 4110 __ vcvtds(dr1, OddSRegisterOf(dq0)); |
| 4111 } | 4111 } |
| 4112 | 4112 |
| 4113 | 4113 |
| 4114 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const { | 4114 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const { |
| 4115 const intptr_t kNumInputs = 1; | 4115 const intptr_t kNumInputs = 1; |
| 4116 const intptr_t kNumTemps = 0; | 4116 const intptr_t kNumTemps = 0; |
| 4117 LocationSummary* summary = | 4117 LocationSummary* summary = |
| 4118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4119 | 4119 |
| 4120 if (representation() == kTagged) { | 4120 if (representation() == kTagged) { |
| 4121 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); | 4121 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); |
| 4122 // Grabbing the S components means we need a low (< 7) Q. | 4122 // Grabbing the S components means we need a low (< 7) Q. |
| 4123 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 4123 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
| 4124 summary->set_out(Location::RequiresRegister()); | 4124 summary->set_out(0, Location::RequiresRegister()); |
| 4125 summary->AddTemp(Location::RequiresRegister()); | 4125 summary->AddTemp(Location::RequiresRegister()); |
| 4126 } else { | 4126 } else { |
| 4127 summary->set_in(0, Location::RequiresFpuRegister()); | 4127 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4128 summary->set_out(Location::RequiresFpuRegister()); | 4128 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4129 } | 4129 } |
| 4130 return summary; | 4130 return summary; |
| 4131 } | 4131 } |
| 4132 | 4132 |
| 4133 | 4133 |
| 4134 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4134 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4135 QRegister q = locs()->in(0).fpu_reg(); | 4135 QRegister q = locs()->in(0).fpu_reg(); |
| 4136 | 4136 |
| 4137 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { | 4137 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { |
| 4138 DRegister dvalue0 = EvenDRegisterOf(q); | 4138 DRegister dvalue0 = EvenDRegisterOf(q); |
| 4139 DRegister dvalue1 = OddDRegisterOf(q); | 4139 DRegister dvalue1 = OddDRegisterOf(q); |
| 4140 | 4140 |
| 4141 Register out = locs()->out().reg(); | 4141 Register out = locs()->out(0).reg(); |
| 4142 Register temp = locs()->temp(0).reg(); | 4142 Register temp = locs()->temp(0).reg(); |
| 4143 | 4143 |
| 4144 // Upper 32-bits of X lane. | 4144 // Upper 32-bits of X lane. |
| 4145 __ vmovrs(out, OddSRegisterOf(dvalue0)); | 4145 __ vmovrs(out, OddSRegisterOf(dvalue0)); |
| 4146 __ Lsr(out, out, 31); | 4146 __ Lsr(out, out, 31); |
| 4147 // Upper 32-bits of Y lane. | 4147 // Upper 32-bits of Y lane. |
| 4148 __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 4148 __ vmovrs(temp, OddSRegisterOf(dvalue1)); |
| 4149 __ Lsr(temp, temp, 31); | 4149 __ Lsr(temp, temp, 31); |
| 4150 __ orr(out, out, ShifterOperand(temp, LSL, 1)); | 4150 __ orr(out, out, ShifterOperand(temp, LSL, 1)); |
| 4151 // Tag. | 4151 // Tag. |
| 4152 __ SmiTag(out); | 4152 __ SmiTag(out); |
| 4153 return; | 4153 return; |
| 4154 } | 4154 } |
| 4155 ASSERT(representation() == kUnboxedFloat64x2); | 4155 ASSERT(representation() == kUnboxedFloat64x2); |
| 4156 QRegister r = locs()->out().fpu_reg(); | 4156 QRegister r = locs()->out(0).fpu_reg(); |
| 4157 | 4157 |
| 4158 DRegister dvalue0 = EvenDRegisterOf(q); | 4158 DRegister dvalue0 = EvenDRegisterOf(q); |
| 4159 DRegister dvalue1 = OddDRegisterOf(q); | 4159 DRegister dvalue1 = OddDRegisterOf(q); |
| 4160 DRegister dresult0 = EvenDRegisterOf(r); | 4160 DRegister dresult0 = EvenDRegisterOf(r); |
| 4161 DRegister dresult1 = OddDRegisterOf(r); | 4161 DRegister dresult1 = OddDRegisterOf(r); |
| 4162 | 4162 |
| 4163 switch (op_kind()) { | 4163 switch (op_kind()) { |
| 4164 case MethodRecognizer::kFloat64x2Negate: | 4164 case MethodRecognizer::kFloat64x2Negate: |
| 4165 __ vnegd(dresult0, dvalue0); | 4165 __ vnegd(dresult0, dvalue0); |
| 4166 __ vnegd(dresult1, dvalue1); | 4166 __ vnegd(dresult1, dvalue1); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4178 } | 4178 } |
| 4179 | 4179 |
| 4180 | 4180 |
| 4181 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const { | 4181 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const { |
| 4182 const intptr_t kNumInputs = 2; | 4182 const intptr_t kNumInputs = 2; |
| 4183 const intptr_t kNumTemps = 0; | 4183 const intptr_t kNumTemps = 0; |
| 4184 LocationSummary* summary = | 4184 LocationSummary* summary = |
| 4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4186 summary->set_in(0, Location::RequiresFpuRegister()); | 4186 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4187 summary->set_in(1, Location::RequiresFpuRegister()); | 4187 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4188 summary->set_out(Location::SameAsFirstInput()); | 4188 summary->set_out(0, Location::SameAsFirstInput()); |
| 4189 return summary; | 4189 return summary; |
| 4190 } | 4190 } |
| 4191 | 4191 |
| 4192 | 4192 |
| 4193 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4193 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4194 QRegister left = locs()->in(0).fpu_reg(); | 4194 QRegister left = locs()->in(0).fpu_reg(); |
| 4195 DRegister left0 = EvenDRegisterOf(left); | 4195 DRegister left0 = EvenDRegisterOf(left); |
| 4196 DRegister left1 = OddDRegisterOf(left); | 4196 DRegister left1 = OddDRegisterOf(left); |
| 4197 QRegister right = locs()->in(1).fpu_reg(); | 4197 QRegister right = locs()->in(1).fpu_reg(); |
| 4198 DRegister right0 = EvenDRegisterOf(right); | 4198 DRegister right0 = EvenDRegisterOf(right); |
| 4199 DRegister right1 = OddDRegisterOf(right); | 4199 DRegister right1 = OddDRegisterOf(right); |
| 4200 QRegister out = locs()->out().fpu_reg(); | 4200 QRegister out = locs()->out(0).fpu_reg(); |
| 4201 ASSERT(left == out); | 4201 ASSERT(left == out); |
| 4202 | 4202 |
| 4203 switch (op_kind()) { | 4203 switch (op_kind()) { |
| 4204 case MethodRecognizer::kFloat64x2Scale: | 4204 case MethodRecognizer::kFloat64x2Scale: |
| 4205 __ vmuld(left0, left0, right0); | 4205 __ vmuld(left0, left0, right0); |
| 4206 __ vmuld(left1, left1, right0); | 4206 __ vmuld(left1, left1, right0); |
| 4207 break; | 4207 break; |
| 4208 case MethodRecognizer::kFloat64x2WithX: | 4208 case MethodRecognizer::kFloat64x2WithX: |
| 4209 __ vmovd(left0, right0); | 4209 __ vmovd(left0, right0); |
| 4210 break; | 4210 break; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4255 const intptr_t kNumInputs = 4; | 4255 const intptr_t kNumInputs = 4; |
| 4256 const intptr_t kNumTemps = 1; | 4256 const intptr_t kNumTemps = 1; |
| 4257 LocationSummary* summary = | 4257 LocationSummary* summary = |
| 4258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4259 summary->set_in(0, Location::RequiresRegister()); | 4259 summary->set_in(0, Location::RequiresRegister()); |
| 4260 summary->set_in(1, Location::RequiresRegister()); | 4260 summary->set_in(1, Location::RequiresRegister()); |
| 4261 summary->set_in(2, Location::RequiresRegister()); | 4261 summary->set_in(2, Location::RequiresRegister()); |
| 4262 summary->set_in(3, Location::RequiresRegister()); | 4262 summary->set_in(3, Location::RequiresRegister()); |
| 4263 summary->set_temp(0, Location::RequiresRegister()); | 4263 summary->set_temp(0, Location::RequiresRegister()); |
| 4264 // Low (< 7) Q register needed for the vmovsr instruction. | 4264 // Low (< 7) Q register needed for the vmovsr instruction. |
| 4265 summary->set_out(Location::FpuRegisterLocation(Q6)); | 4265 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 4266 return summary; | 4266 return summary; |
| 4267 } | 4267 } |
| 4268 | 4268 |
| 4269 | 4269 |
| 4270 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4270 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4271 Register v0 = locs()->in(0).reg(); | 4271 Register v0 = locs()->in(0).reg(); |
| 4272 Register v1 = locs()->in(1).reg(); | 4272 Register v1 = locs()->in(1).reg(); |
| 4273 Register v2 = locs()->in(2).reg(); | 4273 Register v2 = locs()->in(2).reg(); |
| 4274 Register v3 = locs()->in(3).reg(); | 4274 Register v3 = locs()->in(3).reg(); |
| 4275 Register temp = locs()->temp(0).reg(); | 4275 Register temp = locs()->temp(0).reg(); |
| 4276 QRegister result = locs()->out().fpu_reg(); | 4276 QRegister result = locs()->out(0).fpu_reg(); |
| 4277 DRegister dresult0 = EvenDRegisterOf(result); | 4277 DRegister dresult0 = EvenDRegisterOf(result); |
| 4278 DRegister dresult1 = OddDRegisterOf(result); | 4278 DRegister dresult1 = OddDRegisterOf(result); |
| 4279 SRegister sresult0 = EvenSRegisterOf(dresult0); | 4279 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 4280 SRegister sresult1 = OddSRegisterOf(dresult0); | 4280 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 4281 SRegister sresult2 = EvenSRegisterOf(dresult1); | 4281 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 4282 SRegister sresult3 = OddSRegisterOf(dresult1); | 4282 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 4283 | 4283 |
| 4284 __ veorq(result, result, result); | 4284 __ veorq(result, result, result); |
| 4285 __ LoadImmediate(temp, 0xffffffff); | 4285 __ LoadImmediate(temp, 0xffffffff); |
| 4286 | 4286 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4298 } | 4298 } |
| 4299 | 4299 |
| 4300 | 4300 |
| 4301 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { | 4301 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { |
| 4302 const intptr_t kNumInputs = 1; | 4302 const intptr_t kNumInputs = 1; |
| 4303 const intptr_t kNumTemps = 0; | 4303 const intptr_t kNumTemps = 0; |
| 4304 LocationSummary* summary = | 4304 LocationSummary* summary = |
| 4305 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4305 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4306 // Low (< 7) Q registers are needed for the vmovrs instruction. | 4306 // Low (< 7) Q registers are needed for the vmovrs instruction. |
| 4307 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 4307 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
| 4308 summary->set_out(Location::RequiresRegister()); | 4308 summary->set_out(0, Location::RequiresRegister()); |
| 4309 return summary; | 4309 return summary; |
| 4310 } | 4310 } |
| 4311 | 4311 |
| 4312 | 4312 |
| 4313 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4313 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4314 QRegister value = locs()->in(0).fpu_reg(); | 4314 QRegister value = locs()->in(0).fpu_reg(); |
| 4315 Register result = locs()->out().reg(); | 4315 Register result = locs()->out(0).reg(); |
| 4316 | 4316 |
| 4317 DRegister dvalue0 = EvenDRegisterOf(value); | 4317 DRegister dvalue0 = EvenDRegisterOf(value); |
| 4318 DRegister dvalue1 = OddDRegisterOf(value); | 4318 DRegister dvalue1 = OddDRegisterOf(value); |
| 4319 SRegister svalue0 = EvenSRegisterOf(dvalue0); | 4319 SRegister svalue0 = EvenSRegisterOf(dvalue0); |
| 4320 SRegister svalue1 = OddSRegisterOf(dvalue0); | 4320 SRegister svalue1 = OddSRegisterOf(dvalue0); |
| 4321 SRegister svalue2 = EvenSRegisterOf(dvalue1); | 4321 SRegister svalue2 = EvenSRegisterOf(dvalue1); |
| 4322 SRegister svalue3 = OddSRegisterOf(dvalue1); | 4322 SRegister svalue3 = OddSRegisterOf(dvalue1); |
| 4323 | 4323 |
| 4324 switch (op_kind()) { | 4324 switch (op_kind()) { |
| 4325 case MethodRecognizer::kInt32x4GetFlagX: | 4325 case MethodRecognizer::kInt32x4GetFlagX: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4345 | 4345 |
| 4346 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { | 4346 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { |
| 4347 const intptr_t kNumInputs = 3; | 4347 const intptr_t kNumInputs = 3; |
| 4348 const intptr_t kNumTemps = 1; | 4348 const intptr_t kNumTemps = 1; |
| 4349 LocationSummary* summary = | 4349 LocationSummary* summary = |
| 4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4351 summary->set_in(0, Location::RequiresFpuRegister()); | 4351 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4352 summary->set_in(1, Location::RequiresFpuRegister()); | 4352 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4353 summary->set_in(2, Location::RequiresFpuRegister()); | 4353 summary->set_in(2, Location::RequiresFpuRegister()); |
| 4354 summary->set_temp(0, Location::RequiresFpuRegister()); | 4354 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 4355 summary->set_out(Location::RequiresFpuRegister()); | 4355 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4356 return summary; | 4356 return summary; |
| 4357 } | 4357 } |
| 4358 | 4358 |
| 4359 | 4359 |
| 4360 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4360 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4361 QRegister mask = locs()->in(0).fpu_reg(); | 4361 QRegister mask = locs()->in(0).fpu_reg(); |
| 4362 QRegister trueValue = locs()->in(1).fpu_reg(); | 4362 QRegister trueValue = locs()->in(1).fpu_reg(); |
| 4363 QRegister falseValue = locs()->in(2).fpu_reg(); | 4363 QRegister falseValue = locs()->in(2).fpu_reg(); |
| 4364 QRegister out = locs()->out().fpu_reg(); | 4364 QRegister out = locs()->out(0).fpu_reg(); |
| 4365 QRegister temp = locs()->temp(0).fpu_reg(); | 4365 QRegister temp = locs()->temp(0).fpu_reg(); |
| 4366 | 4366 |
| 4367 // Copy mask. | 4367 // Copy mask. |
| 4368 __ vmovq(temp, mask); | 4368 __ vmovq(temp, mask); |
| 4369 // Invert it. | 4369 // Invert it. |
| 4370 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. | 4370 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. |
| 4371 __ vornq(temp, QTMP, temp); // temp <- ~temp. | 4371 __ vornq(temp, QTMP, temp); // temp <- ~temp. |
| 4372 // mask = mask & trueValue. | 4372 // mask = mask & trueValue. |
| 4373 __ vandq(mask, mask, trueValue); | 4373 __ vandq(mask, mask, trueValue); |
| 4374 // temp = temp & falseValue. | 4374 // temp = temp & falseValue. |
| 4375 __ vandq(temp, temp, falseValue); | 4375 __ vandq(temp, temp, falseValue); |
| 4376 // out = mask | temp. | 4376 // out = mask | temp. |
| 4377 __ vorrq(out, mask, temp); | 4377 __ vorrq(out, mask, temp); |
| 4378 } | 4378 } |
| 4379 | 4379 |
| 4380 | 4380 |
| 4381 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { | 4381 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { |
| 4382 const intptr_t kNumInputs = 2; | 4382 const intptr_t kNumInputs = 2; |
| 4383 const intptr_t kNumTemps = 0; | 4383 const intptr_t kNumTemps = 0; |
| 4384 LocationSummary* summary = | 4384 LocationSummary* summary = |
| 4385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4386 summary->set_in(0, Location::RequiresFpuRegister()); | 4386 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4387 summary->set_in(1, Location::RequiresRegister()); | 4387 summary->set_in(1, Location::RequiresRegister()); |
| 4388 // Low (< 7) Q register needed for the vmovsr instruction. | 4388 // Low (< 7) Q register needed for the vmovsr instruction. |
| 4389 summary->set_out(Location::FpuRegisterLocation(Q6)); | 4389 summary->set_out(0, Location::FpuRegisterLocation(Q6)); |
| 4390 return summary; | 4390 return summary; |
| 4391 } | 4391 } |
| 4392 | 4392 |
| 4393 | 4393 |
| 4394 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4394 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4395 QRegister mask = locs()->in(0).fpu_reg(); | 4395 QRegister mask = locs()->in(0).fpu_reg(); |
| 4396 Register flag = locs()->in(1).reg(); | 4396 Register flag = locs()->in(1).reg(); |
| 4397 QRegister result = locs()->out().fpu_reg(); | 4397 QRegister result = locs()->out(0).fpu_reg(); |
| 4398 | 4398 |
| 4399 DRegister dresult0 = EvenDRegisterOf(result); | 4399 DRegister dresult0 = EvenDRegisterOf(result); |
| 4400 DRegister dresult1 = OddDRegisterOf(result); | 4400 DRegister dresult1 = OddDRegisterOf(result); |
| 4401 SRegister sresult0 = EvenSRegisterOf(dresult0); | 4401 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 4402 SRegister sresult1 = OddSRegisterOf(dresult0); | 4402 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 4403 SRegister sresult2 = EvenSRegisterOf(dresult1); | 4403 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 4404 SRegister sresult3 = OddSRegisterOf(dresult1); | 4404 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 4405 | 4405 |
| 4406 if (result != mask) { | 4406 if (result != mask) { |
| 4407 __ vmovq(result, mask); | 4407 __ vmovq(result, mask); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4427 } | 4427 } |
| 4428 } | 4428 } |
| 4429 | 4429 |
| 4430 | 4430 |
| 4431 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { | 4431 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 4432 const intptr_t kNumInputs = 1; | 4432 const intptr_t kNumInputs = 1; |
| 4433 const intptr_t kNumTemps = 0; | 4433 const intptr_t kNumTemps = 0; |
| 4434 LocationSummary* summary = | 4434 LocationSummary* summary = |
| 4435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4436 summary->set_in(0, Location::RequiresFpuRegister()); | 4436 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4437 summary->set_out(Location::RequiresFpuRegister()); | 4437 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4438 return summary; | 4438 return summary; |
| 4439 } | 4439 } |
| 4440 | 4440 |
| 4441 | 4441 |
| 4442 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4442 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4443 QRegister value = locs()->in(0).fpu_reg(); | 4443 QRegister value = locs()->in(0).fpu_reg(); |
| 4444 QRegister result = locs()->out().fpu_reg(); | 4444 QRegister result = locs()->out(0).fpu_reg(); |
| 4445 | 4445 |
| 4446 if (value != result) { | 4446 if (value != result) { |
| 4447 __ vmovq(result, value); | 4447 __ vmovq(result, value); |
| 4448 } | 4448 } |
| 4449 } | 4449 } |
| 4450 | 4450 |
| 4451 | 4451 |
| 4452 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { | 4452 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { |
| 4453 const intptr_t kNumInputs = 2; | 4453 const intptr_t kNumInputs = 2; |
| 4454 const intptr_t kNumTemps = 0; | 4454 const intptr_t kNumTemps = 0; |
| 4455 LocationSummary* summary = | 4455 LocationSummary* summary = |
| 4456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4457 summary->set_in(0, Location::RequiresFpuRegister()); | 4457 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4458 summary->set_in(1, Location::RequiresFpuRegister()); | 4458 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4459 summary->set_out(Location::RequiresFpuRegister()); | 4459 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4460 return summary; | 4460 return summary; |
| 4461 } | 4461 } |
| 4462 | 4462 |
| 4463 | 4463 |
| 4464 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4464 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4465 QRegister left = locs()->in(0).fpu_reg(); | 4465 QRegister left = locs()->in(0).fpu_reg(); |
| 4466 QRegister right = locs()->in(1).fpu_reg(); | 4466 QRegister right = locs()->in(1).fpu_reg(); |
| 4467 QRegister result = locs()->out().fpu_reg(); | 4467 QRegister result = locs()->out(0).fpu_reg(); |
| 4468 switch (op_kind()) { | 4468 switch (op_kind()) { |
| 4469 case Token::kBIT_AND: { | 4469 case Token::kBIT_AND: { |
| 4470 __ vandq(result, left, right); | 4470 __ vandq(result, left, right); |
| 4471 break; | 4471 break; |
| 4472 } | 4472 } |
| 4473 case Token::kBIT_OR: { | 4473 case Token::kBIT_OR: { |
| 4474 __ vorrq(result, left, right); | 4474 __ vorrq(result, left, right); |
| 4475 break; | 4475 break; |
| 4476 } | 4476 } |
| 4477 case Token::kBIT_XOR: { | 4477 case Token::kBIT_XOR: { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4490 | 4490 |
| 4491 | 4491 |
| 4492 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { | 4492 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
| 4493 if ((kind() == MethodRecognizer::kMathSin) || | 4493 if ((kind() == MethodRecognizer::kMathSin) || |
| 4494 (kind() == MethodRecognizer::kMathCos)) { | 4494 (kind() == MethodRecognizer::kMathCos)) { |
| 4495 const intptr_t kNumInputs = 1; | 4495 const intptr_t kNumInputs = 1; |
| 4496 const intptr_t kNumTemps = 0; | 4496 const intptr_t kNumTemps = 0; |
| 4497 LocationSummary* summary = | 4497 LocationSummary* summary = |
| 4498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 4499 summary->set_in(0, Location::FpuRegisterLocation(Q0)); | 4499 summary->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 4500 summary->set_out(Location::FpuRegisterLocation(Q0)); | 4500 summary->set_out(0, Location::FpuRegisterLocation(Q0)); |
| 4501 #if !defined(ARM_FLOAT_ABI_HARD) | 4501 #if !defined(ARM_FLOAT_ABI_HARD) |
| 4502 summary->AddTemp(Location::RegisterLocation(R0)); | 4502 summary->AddTemp(Location::RegisterLocation(R0)); |
| 4503 summary->AddTemp(Location::RegisterLocation(R1)); | 4503 summary->AddTemp(Location::RegisterLocation(R1)); |
| 4504 summary->AddTemp(Location::RegisterLocation(R2)); | 4504 summary->AddTemp(Location::RegisterLocation(R2)); |
| 4505 summary->AddTemp(Location::RegisterLocation(R3)); | 4505 summary->AddTemp(Location::RegisterLocation(R3)); |
| 4506 #endif | 4506 #endif |
| 4507 return summary; | 4507 return summary; |
| 4508 } | 4508 } |
| 4509 // Sqrt. | 4509 // Sqrt. |
| 4510 const intptr_t kNumInputs = 1; | 4510 const intptr_t kNumInputs = 1; |
| 4511 const intptr_t kNumTemps = 0; | 4511 const intptr_t kNumTemps = 0; |
| 4512 LocationSummary* summary = | 4512 LocationSummary* summary = |
| 4513 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4513 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4514 summary->set_in(0, Location::RequiresFpuRegister()); | 4514 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4515 summary->set_out(Location::RequiresFpuRegister()); | 4515 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4516 return summary; | 4516 return summary; |
| 4517 } | 4517 } |
| 4518 | 4518 |
| 4519 | 4519 |
| 4520 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4520 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4521 if (kind() == MethodRecognizer::kMathSqrt) { | 4521 if (kind() == MethodRecognizer::kMathSqrt) { |
| 4522 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4522 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4523 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4523 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4524 __ vsqrtd(result, val); | 4524 __ vsqrtd(result, val); |
| 4525 } else { | 4525 } else { |
| 4526 #if defined(ARM_FLOAT_ABI_HARD) | 4526 #if defined(ARM_FLOAT_ABI_HARD) |
| 4527 __ CallRuntime(TargetFunction(), InputCount()); | 4527 __ CallRuntime(TargetFunction(), InputCount()); |
| 4528 #else | 4528 #else |
| 4529 // If we aren't doing "hardfp", then we have to move the double arguments | 4529 // If we aren't doing "hardfp", then we have to move the double arguments |
| 4530 // to the integer registers, and take the results from the integer | 4530 // to the integer registers, and take the results from the integer |
| 4531 // registers. | 4531 // registers. |
| 4532 __ vmovrrd(R0, R1, D0); | 4532 __ vmovrrd(R0, R1, D0); |
| 4533 __ vmovrrd(R2, R3, D1); | 4533 __ vmovrrd(R2, R3, D1); |
| 4534 __ CallRuntime(TargetFunction(), InputCount()); | 4534 __ CallRuntime(TargetFunction(), InputCount()); |
| 4535 __ vmovdrr(D0, R0, R1); | 4535 __ vmovdrr(D0, R0, R1); |
| 4536 __ vmovdrr(D1, R2, R3); | 4536 __ vmovdrr(D1, R2, R3); |
| 4537 #endif | 4537 #endif |
| 4538 } | 4538 } |
| 4539 } | 4539 } |
| 4540 | 4540 |
| 4541 | 4541 |
| 4542 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { | 4542 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
| 4543 if (result_cid() == kDoubleCid) { | 4543 if (result_cid() == kDoubleCid) { |
| 4544 const intptr_t kNumInputs = 2; | 4544 const intptr_t kNumInputs = 2; |
| 4545 const intptr_t kNumTemps = 1; | 4545 const intptr_t kNumTemps = 1; |
| 4546 LocationSummary* summary = | 4546 LocationSummary* summary = |
| 4547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4548 summary->set_in(0, Location::RequiresFpuRegister()); | 4548 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4549 summary->set_in(1, Location::RequiresFpuRegister()); | 4549 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4550 // Reuse the left register so that code can be made shorter. | 4550 // Reuse the left register so that code can be made shorter. |
| 4551 summary->set_out(Location::SameAsFirstInput()); | 4551 summary->set_out(0, Location::SameAsFirstInput()); |
| 4552 summary->set_temp(0, Location::RequiresRegister()); | 4552 summary->set_temp(0, Location::RequiresRegister()); |
| 4553 return summary; | 4553 return summary; |
| 4554 } | 4554 } |
| 4555 ASSERT(result_cid() == kSmiCid); | 4555 ASSERT(result_cid() == kSmiCid); |
| 4556 const intptr_t kNumInputs = 2; | 4556 const intptr_t kNumInputs = 2; |
| 4557 const intptr_t kNumTemps = 0; | 4557 const intptr_t kNumTemps = 0; |
| 4558 LocationSummary* summary = | 4558 LocationSummary* summary = |
| 4559 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4559 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4560 summary->set_in(0, Location::RequiresRegister()); | 4560 summary->set_in(0, Location::RequiresRegister()); |
| 4561 summary->set_in(1, Location::RequiresRegister()); | 4561 summary->set_in(1, Location::RequiresRegister()); |
| 4562 // Reuse the left register so that code can be made shorter. | 4562 // Reuse the left register so that code can be made shorter. |
| 4563 summary->set_out(Location::SameAsFirstInput()); | 4563 summary->set_out(0, Location::SameAsFirstInput()); |
| 4564 return summary; | 4564 return summary; |
| 4565 } | 4565 } |
| 4566 | 4566 |
| 4567 | 4567 |
| 4568 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4568 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4569 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 4569 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 4570 (op_kind() == MethodRecognizer::kMathMax)); | 4570 (op_kind() == MethodRecognizer::kMathMax)); |
| 4571 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | 4571 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
| 4572 if (result_cid() == kDoubleCid) { | 4572 if (result_cid() == kDoubleCid) { |
| 4573 Label done, returns_nan, are_equal; | 4573 Label done, returns_nan, are_equal; |
| 4574 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4574 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4575 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 4575 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 4576 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4576 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4577 Register temp = locs()->temp(0).reg(); | 4577 Register temp = locs()->temp(0).reg(); |
| 4578 __ vcmpd(left, right); | 4578 __ vcmpd(left, right); |
| 4579 __ vmstat(); | 4579 __ vmstat(); |
| 4580 __ b(&returns_nan, VS); | 4580 __ b(&returns_nan, VS); |
| 4581 __ b(&are_equal, EQ); | 4581 __ b(&are_equal, EQ); |
| 4582 const Condition neg_double_condition = | 4582 const Condition neg_double_condition = |
| 4583 is_min ? TokenKindToDoubleCondition(Token::kGTE) | 4583 is_min ? TokenKindToDoubleCondition(Token::kGTE) |
| 4584 : TokenKindToDoubleCondition(Token::kLTE); | 4584 : TokenKindToDoubleCondition(Token::kLTE); |
| 4585 ASSERT(left == result); | 4585 ASSERT(left == result); |
| 4586 __ vmovd(result, right, neg_double_condition); | 4586 __ vmovd(result, right, neg_double_condition); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4606 __ vmovd(result, right, LT); | 4606 __ vmovd(result, right, LT); |
| 4607 ASSERT(left == result); | 4607 ASSERT(left == result); |
| 4608 } | 4608 } |
| 4609 __ Bind(&done); | 4609 __ Bind(&done); |
| 4610 return; | 4610 return; |
| 4611 } | 4611 } |
| 4612 | 4612 |
| 4613 ASSERT(result_cid() == kSmiCid); | 4613 ASSERT(result_cid() == kSmiCid); |
| 4614 Register left = locs()->in(0).reg(); | 4614 Register left = locs()->in(0).reg(); |
| 4615 Register right = locs()->in(1).reg(); | 4615 Register right = locs()->in(1).reg(); |
| 4616 Register result = locs()->out().reg(); | 4616 Register result = locs()->out(0).reg(); |
| 4617 __ cmp(left, ShifterOperand(right)); | 4617 __ cmp(left, ShifterOperand(right)); |
| 4618 ASSERT(result == left); | 4618 ASSERT(result == left); |
| 4619 if (is_min) { | 4619 if (is_min) { |
| 4620 __ mov(result, ShifterOperand(right), GT); | 4620 __ mov(result, ShifterOperand(right), GT); |
| 4621 } else { | 4621 } else { |
| 4622 __ mov(result, ShifterOperand(right), LT); | 4622 __ mov(result, ShifterOperand(right), LT); |
| 4623 } | 4623 } |
| 4624 } | 4624 } |
| 4625 | 4625 |
| 4626 | 4626 |
| 4627 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { | 4627 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { |
| 4628 const intptr_t kNumInputs = 1; | 4628 const intptr_t kNumInputs = 1; |
| 4629 const intptr_t kNumTemps = 0; | 4629 const intptr_t kNumTemps = 0; |
| 4630 LocationSummary* summary = | 4630 LocationSummary* summary = |
| 4631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4632 summary->set_in(0, Location::RequiresRegister()); | 4632 summary->set_in(0, Location::RequiresRegister()); |
| 4633 // We make use of 3-operand instructions by not requiring result register | 4633 // We make use of 3-operand instructions by not requiring result register |
| 4634 // to be identical to first input register as on Intel. | 4634 // to be identical to first input register as on Intel. |
| 4635 summary->set_out(Location::RequiresRegister()); | 4635 summary->set_out(0, Location::RequiresRegister()); |
| 4636 return summary; | 4636 return summary; |
| 4637 } | 4637 } |
| 4638 | 4638 |
| 4639 | 4639 |
| 4640 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4640 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4641 Register value = locs()->in(0).reg(); | 4641 Register value = locs()->in(0).reg(); |
| 4642 Register result = locs()->out().reg(); | 4642 Register result = locs()->out(0).reg(); |
| 4643 switch (op_kind()) { | 4643 switch (op_kind()) { |
| 4644 case Token::kNEGATE: { | 4644 case Token::kNEGATE: { |
| 4645 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4645 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 4646 kDeoptUnaryOp); | 4646 kDeoptUnaryOp); |
| 4647 __ rsbs(result, value, ShifterOperand(0)); | 4647 __ rsbs(result, value, ShifterOperand(0)); |
| 4648 __ b(deopt, VS); | 4648 __ b(deopt, VS); |
| 4649 break; | 4649 break; |
| 4650 } | 4650 } |
| 4651 case Token::kBIT_NOT: | 4651 case Token::kBIT_NOT: |
| 4652 __ mvn(result, ShifterOperand(value)); | 4652 __ mvn(result, ShifterOperand(value)); |
| 4653 // Remove inverted smi-tag. | 4653 // Remove inverted smi-tag. |
| 4654 __ bic(result, result, ShifterOperand(kSmiTagMask)); | 4654 __ bic(result, result, ShifterOperand(kSmiTagMask)); |
| 4655 break; | 4655 break; |
| 4656 default: | 4656 default: |
| 4657 UNREACHABLE(); | 4657 UNREACHABLE(); |
| 4658 } | 4658 } |
| 4659 } | 4659 } |
| 4660 | 4660 |
| 4661 | 4661 |
| 4662 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { | 4662 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 4663 const intptr_t kNumInputs = 1; | 4663 const intptr_t kNumInputs = 1; |
| 4664 const intptr_t kNumTemps = 0; | 4664 const intptr_t kNumTemps = 0; |
| 4665 LocationSummary* summary = | 4665 LocationSummary* summary = |
| 4666 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4666 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4667 summary->set_in(0, Location::RequiresFpuRegister()); | 4667 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4668 summary->set_out(Location::RequiresFpuRegister()); | 4668 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4669 return summary; | 4669 return summary; |
| 4670 } | 4670 } |
| 4671 | 4671 |
| 4672 | 4672 |
| 4673 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4673 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4674 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4674 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4675 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4675 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4676 __ vnegd(result, value); | 4676 __ vnegd(result, value); |
| 4677 } | 4677 } |
| 4678 | 4678 |
| 4679 | 4679 |
| 4680 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { | 4680 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 4681 const intptr_t kNumInputs = 1; | 4681 const intptr_t kNumInputs = 1; |
| 4682 const intptr_t kNumTemps = 0; | 4682 const intptr_t kNumTemps = 0; |
| 4683 LocationSummary* result = | 4683 LocationSummary* result = |
| 4684 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4684 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4685 result->set_in(0, Location::WritableRegister()); | 4685 result->set_in(0, Location::WritableRegister()); |
| 4686 result->set_out(Location::RequiresFpuRegister()); | 4686 result->set_out(0, Location::RequiresFpuRegister()); |
| 4687 return result; | 4687 return result; |
| 4688 } | 4688 } |
| 4689 | 4689 |
| 4690 | 4690 |
| 4691 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4691 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4692 Register value = locs()->in(0).reg(); | 4692 Register value = locs()->in(0).reg(); |
| 4693 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4693 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4694 __ SmiUntag(value); | 4694 __ SmiUntag(value); |
| 4695 __ vmovsr(STMP, value); | 4695 __ vmovsr(STMP, value); |
| 4696 __ vcvtdi(result, STMP); | 4696 __ vcvtdi(result, STMP); |
| 4697 } | 4697 } |
| 4698 | 4698 |
| 4699 | 4699 |
| 4700 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { | 4700 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { |
| 4701 const intptr_t kNumInputs = 1; | 4701 const intptr_t kNumInputs = 1; |
| 4702 const intptr_t kNumTemps = 0; | 4702 const intptr_t kNumTemps = 0; |
| 4703 LocationSummary* result = | 4703 LocationSummary* result = |
| 4704 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4704 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 4705 result->set_in(0, Location::RegisterLocation(R1)); | 4705 result->set_in(0, Location::RegisterLocation(R1)); |
| 4706 result->set_out(Location::RegisterLocation(R0)); | 4706 result->set_out(0, Location::RegisterLocation(R0)); |
| 4707 return result; | 4707 return result; |
| 4708 } | 4708 } |
| 4709 | 4709 |
| 4710 | 4710 |
| 4711 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4711 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4712 Register result = locs()->out().reg(); | 4712 Register result = locs()->out(0).reg(); |
| 4713 Register value_obj = locs()->in(0).reg(); | 4713 Register value_obj = locs()->in(0).reg(); |
| 4714 ASSERT(result == R0); | 4714 ASSERT(result == R0); |
| 4715 ASSERT(result != value_obj); | 4715 ASSERT(result != value_obj); |
| 4716 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); | 4716 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); |
| 4717 | 4717 |
| 4718 Label do_call, done; | 4718 Label do_call, done; |
| 4719 // First check for NaN. Checking for minint after the conversion doesn't work | 4719 // First check for NaN. Checking for minint after the conversion doesn't work |
| 4720 // on ARM because vcvtid gives 0 for NaN. | 4720 // on ARM because vcvtid gives 0 for NaN. |
| 4721 __ vcmpd(DTMP, DTMP); | 4721 __ vcmpd(DTMP, DTMP); |
| 4722 __ vmstat(); | 4722 __ vmstat(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4748 __ Bind(&done); | 4748 __ Bind(&done); |
| 4749 } | 4749 } |
| 4750 | 4750 |
| 4751 | 4751 |
| 4752 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { | 4752 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { |
| 4753 const intptr_t kNumInputs = 1; | 4753 const intptr_t kNumInputs = 1; |
| 4754 const intptr_t kNumTemps = 0; | 4754 const intptr_t kNumTemps = 0; |
| 4755 LocationSummary* result = new LocationSummary( | 4755 LocationSummary* result = new LocationSummary( |
| 4756 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4756 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4757 result->set_in(0, Location::RequiresFpuRegister()); | 4757 result->set_in(0, Location::RequiresFpuRegister()); |
| 4758 result->set_out(Location::RequiresRegister()); | 4758 result->set_out(0, Location::RequiresRegister()); |
| 4759 return result; | 4759 return result; |
| 4760 } | 4760 } |
| 4761 | 4761 |
| 4762 | 4762 |
| 4763 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4763 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4764 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4764 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
| 4765 Register result = locs()->out().reg(); | 4765 Register result = locs()->out(0).reg(); |
| 4766 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4766 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4767 // First check for NaN. Checking for minint after the conversion doesn't work | 4767 // First check for NaN. Checking for minint after the conversion doesn't work |
| 4768 // on ARM because vcvtid gives 0 for NaN. | 4768 // on ARM because vcvtid gives 0 for NaN. |
| 4769 __ vcmpd(value, value); | 4769 __ vcmpd(value, value); |
| 4770 __ vmstat(); | 4770 __ vmstat(); |
| 4771 __ b(deopt, VS); | 4771 __ b(deopt, VS); |
| 4772 | 4772 |
| 4773 __ vcvtid(STMP, value); | 4773 __ vcvtid(STMP, value); |
| 4774 __ vmovrs(result, STMP); | 4774 __ vmovrs(result, STMP); |
| 4775 // Check for overflow and that it fits into Smi. | 4775 // Check for overflow and that it fits into Smi. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4790 } | 4790 } |
| 4791 | 4791 |
| 4792 | 4792 |
| 4793 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { | 4793 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { |
| 4794 const intptr_t kNumInputs = 1; | 4794 const intptr_t kNumInputs = 1; |
| 4795 const intptr_t kNumTemps = 0; | 4795 const intptr_t kNumTemps = 0; |
| 4796 LocationSummary* result = | 4796 LocationSummary* result = |
| 4797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4798 // Low (<= Q7) Q registers are needed for the conversion instructions. | 4798 // Low (<= Q7) Q registers are needed for the conversion instructions. |
| 4799 result->set_in(0, Location::RequiresFpuRegister()); | 4799 result->set_in(0, Location::RequiresFpuRegister()); |
| 4800 result->set_out(Location::FpuRegisterLocation(Q7)); | 4800 result->set_out(0, Location::FpuRegisterLocation(Q7)); |
| 4801 return result; | 4801 return result; |
| 4802 } | 4802 } |
| 4803 | 4803 |
| 4804 | 4804 |
| 4805 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4805 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4806 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4806 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4807 SRegister result = EvenSRegisterOf(EvenDRegisterOf(locs()->out().fpu_reg())); | 4807 SRegister result = EvenSRegisterOf(EvenDRegisterOf(locs()->out(0).fpu_reg())); |
| 4808 __ vcvtsd(result, value); | 4808 __ vcvtsd(result, value); |
| 4809 } | 4809 } |
| 4810 | 4810 |
| 4811 | 4811 |
| 4812 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { | 4812 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { |
| 4813 const intptr_t kNumInputs = 1; | 4813 const intptr_t kNumInputs = 1; |
| 4814 const intptr_t kNumTemps = 0; | 4814 const intptr_t kNumTemps = 0; |
| 4815 LocationSummary* result = | 4815 LocationSummary* result = |
| 4816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4817 // Low (<= Q7) Q registers are needed for the conversion instructions. | 4817 // Low (<= Q7) Q registers are needed for the conversion instructions. |
| 4818 result->set_in(0, Location::FpuRegisterLocation(Q7)); | 4818 result->set_in(0, Location::FpuRegisterLocation(Q7)); |
| 4819 result->set_out(Location::RequiresFpuRegister()); | 4819 result->set_out(0, Location::RequiresFpuRegister()); |
| 4820 return result; | 4820 return result; |
| 4821 } | 4821 } |
| 4822 | 4822 |
| 4823 | 4823 |
| 4824 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4824 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4825 SRegister value = EvenSRegisterOf(EvenDRegisterOf(locs()->in(0).fpu_reg())); | 4825 SRegister value = EvenSRegisterOf(EvenDRegisterOf(locs()->in(0).fpu_reg())); |
| 4826 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4826 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4827 __ vcvtds(result, value); | 4827 __ vcvtds(result, value); |
| 4828 } | 4828 } |
| 4829 | 4829 |
| 4830 | 4830 |
| 4831 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { | 4831 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { |
| 4832 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 4832 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 4833 const intptr_t kNumTemps = 0; | 4833 const intptr_t kNumTemps = 0; |
| 4834 LocationSummary* result = | 4834 LocationSummary* result = |
| 4835 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 4835 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 4836 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 4836 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 4837 if (InputCount() == 2) { | 4837 if (InputCount() == 2) { |
| 4838 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 4838 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 4839 } | 4839 } |
| 4840 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4840 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 4841 result->AddTemp(Location::RegisterLocation(R2)); | 4841 result->AddTemp(Location::RegisterLocation(R2)); |
| 4842 result->AddTemp(Location::FpuRegisterLocation(Q2)); | 4842 result->AddTemp(Location::FpuRegisterLocation(Q2)); |
| 4843 } | 4843 } |
| 4844 #if !defined(ARM_FLOAT_ABI_HARD) | 4844 #if !defined(ARM_FLOAT_ABI_HARD) |
| 4845 result->AddTemp(Location::RegisterLocation(R0)); | 4845 result->AddTemp(Location::RegisterLocation(R0)); |
| 4846 result->AddTemp(Location::RegisterLocation(R1)); | 4846 result->AddTemp(Location::RegisterLocation(R1)); |
| 4847 // Check if R2 is already added. | 4847 // Check if R2 is already added. |
| 4848 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { | 4848 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { |
| 4849 result->AddTemp(Location::RegisterLocation(R2)); | 4849 result->AddTemp(Location::RegisterLocation(R2)); |
| 4850 } | 4850 } |
| 4851 result->AddTemp(Location::RegisterLocation(R3)); | 4851 result->AddTemp(Location::RegisterLocation(R3)); |
| 4852 #endif | 4852 #endif |
| 4853 result->set_out(Location::FpuRegisterLocation(Q0)); | 4853 result->set_out(0, Location::FpuRegisterLocation(Q0)); |
| 4854 return result; | 4854 return result; |
| 4855 } | 4855 } |
| 4856 | 4856 |
| 4857 | 4857 |
| 4858 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4858 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4859 // For pow-function return NaN if exponent is NaN. | 4859 // For pow-function return NaN if exponent is NaN. |
| 4860 Label do_call, skip_call; | 4860 Label do_call, skip_call; |
| 4861 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4861 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 4862 // Pseudo code: | 4862 // Pseudo code: |
| 4863 // if (exponent == 0.0) return 0.0; | 4863 // if (exponent == 0.0) return 0.0; |
| 4864 // if (base == 1.0) return 1.0; | 4864 // if (base == 1.0) return 1.0; |
| 4865 // if (base.isNaN || exponent.isNaN) { | 4865 // if (base.isNaN || exponent.isNaN) { |
| 4866 // return double.NAN; | 4866 // return double.NAN; |
| 4867 // } | 4867 // } |
| 4868 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4868 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4869 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 4869 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 4870 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4870 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 4871 Register temp = locs()->temp(0).reg(); | 4871 Register temp = locs()->temp(0).reg(); |
| 4872 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 4872 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 4873 ASSERT((base == result) && (result != saved_base)); | 4873 ASSERT((base == result) && (result != saved_base)); |
| 4874 Label check_base_is_one; | 4874 Label check_base_is_one; |
| 4875 // Check if exponent is 0.0 -> return 1.0; | 4875 // Check if exponent is 0.0 -> return 1.0; |
| 4876 __ vmovd(saved_base, base); | 4876 __ vmovd(saved_base, base); |
| 4877 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); | 4877 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); |
| 4878 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); | 4878 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); |
| 4879 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); | 4879 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); |
| 4880 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); | 4880 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4917 const intptr_t kNumInputs = 2; | 4917 const intptr_t kNumInputs = 2; |
| 4918 const intptr_t kNumTemps = 4; | 4918 const intptr_t kNumTemps = 4; |
| 4919 LocationSummary* summary = | 4919 LocationSummary* summary = |
| 4920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4921 summary->set_in(0, Location::RequiresRegister()); | 4921 summary->set_in(0, Location::RequiresRegister()); |
| 4922 summary->set_in(1, Location::RequiresRegister()); | 4922 summary->set_in(1, Location::RequiresRegister()); |
| 4923 summary->set_temp(0, Location::RequiresRegister()); | 4923 summary->set_temp(0, Location::RequiresRegister()); |
| 4924 summary->set_temp(1, Location::RequiresFpuRegister()); | 4924 summary->set_temp(1, Location::RequiresFpuRegister()); |
| 4925 summary->set_temp(2, Location::RequiresRegister()); // result_div. | 4925 summary->set_temp(2, Location::RequiresRegister()); // result_div. |
| 4926 summary->set_temp(3, Location::RequiresRegister()); // result_mod. | 4926 summary->set_temp(3, Location::RequiresRegister()); // result_mod. |
| 4927 summary->set_out(Location::RequiresRegister()); | 4927 summary->set_out(0, Location::RequiresRegister()); |
| 4928 return summary; | 4928 return summary; |
| 4929 } | 4929 } |
| 4930 UNIMPLEMENTED(); | 4930 UNIMPLEMENTED(); |
| 4931 return NULL; | 4931 return NULL; |
| 4932 } | 4932 } |
| 4933 | 4933 |
| 4934 | 4934 |
| 4935 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4935 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4936 Label* deopt = NULL; | 4936 Label* deopt = NULL; |
| 4937 if (CanDeoptimize()) { | 4937 if (CanDeoptimize()) { |
| 4938 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 4938 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
| 4939 } | 4939 } |
| 4940 if (kind() == MergedMathInstr::kTruncDivMod) { | 4940 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4941 Register left = locs()->in(0).reg(); | 4941 Register left = locs()->in(0).reg(); |
| 4942 Register right = locs()->in(1).reg(); | 4942 Register right = locs()->in(1).reg(); |
| 4943 Register result = locs()->out().reg(); | 4943 Register result = locs()->out(0).reg(); |
| 4944 Range* right_range = InputAt(1)->definition()->range(); | 4944 Range* right_range = InputAt(1)->definition()->range(); |
| 4945 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 4945 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
| 4946 // Handle divide by zero in runtime. | 4946 // Handle divide by zero in runtime. |
| 4947 __ cmp(right, ShifterOperand(0)); | 4947 __ cmp(right, ShifterOperand(0)); |
| 4948 __ b(deopt, EQ); | 4948 __ b(deopt, EQ); |
| 4949 } | 4949 } |
| 4950 Register temp = locs()->temp(0).reg(); | 4950 Register temp = locs()->temp(0).reg(); |
| 4951 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 4951 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 4952 Register result_div = locs()->temp(2).reg(); | 4952 Register result_div = locs()->temp(2).reg(); |
| 4953 Register result_mod = locs()->temp(3).reg(); | 4953 Register result_mod = locs()->temp(3).reg(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5041 deopt, | 5041 deopt, |
| 5042 deopt_id(), | 5042 deopt_id(), |
| 5043 instance_call()->token_pos(), | 5043 instance_call()->token_pos(), |
| 5044 locs()); | 5044 locs()); |
| 5045 } | 5045 } |
| 5046 | 5046 |
| 5047 | 5047 |
| 5048 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { | 5048 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
| 5049 comparison()->InitializeLocationSummary(opt); | 5049 comparison()->InitializeLocationSummary(opt); |
| 5050 // Branches don't produce a result. | 5050 // Branches don't produce a result. |
| 5051 comparison()->locs()->set_out(Location::NoLocation()); | 5051 comparison()->locs()->set_out(0, Location::NoLocation()); |
| 5052 return comparison()->locs(); | 5052 return comparison()->locs(); |
| 5053 } | 5053 } |
| 5054 | 5054 |
| 5055 | 5055 |
| 5056 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5056 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5057 comparison()->EmitBranchCode(compiler, this); | 5057 comparison()->EmitBranchCode(compiler, this); |
| 5058 } | 5058 } |
| 5059 | 5059 |
| 5060 | 5060 |
| 5061 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { | 5061 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5325 | 5325 |
| 5326 | 5326 |
| 5327 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { | 5327 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
| 5328 return LocationSummary::Make(0, | 5328 return LocationSummary::Make(0, |
| 5329 Location::RequiresRegister(), | 5329 Location::RequiresRegister(), |
| 5330 LocationSummary::kNoCall); | 5330 LocationSummary::kNoCall); |
| 5331 } | 5331 } |
| 5332 | 5332 |
| 5333 | 5333 |
| 5334 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5334 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5335 __ mov(locs()->out().reg(), ShifterOperand(CTX)); | 5335 __ mov(locs()->out(0).reg(), ShifterOperand(CTX)); |
| 5336 } | 5336 } |
| 5337 | 5337 |
| 5338 | 5338 |
| 5339 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { | 5339 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
| 5340 const intptr_t kNumInputs = 2; | 5340 const intptr_t kNumInputs = 2; |
| 5341 const intptr_t kNumTemps = 0; | 5341 const intptr_t kNumTemps = 0; |
| 5342 if (needs_number_check()) { | 5342 if (needs_number_check()) { |
| 5343 LocationSummary* locs = | 5343 LocationSummary* locs = |
| 5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 5345 locs->set_in(0, Location::RegisterLocation(R0)); | 5345 locs->set_in(0, Location::RegisterLocation(R0)); |
| 5346 locs->set_in(1, Location::RegisterLocation(R1)); | 5346 locs->set_in(1, Location::RegisterLocation(R1)); |
| 5347 locs->set_out(Location::RegisterLocation(R0)); | 5347 locs->set_out(0, Location::RegisterLocation(R0)); |
| 5348 return locs; | 5348 return locs; |
| 5349 } | 5349 } |
| 5350 LocationSummary* locs = | 5350 LocationSummary* locs = |
| 5351 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5351 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5352 locs->set_in(0, Location::RegisterOrConstant(left())); | 5352 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 5353 // Only one of the inputs can be a constant. Choose register if the first one | 5353 // Only one of the inputs can be a constant. Choose register if the first one |
| 5354 // is a constant. | 5354 // is a constant. |
| 5355 locs->set_in(1, locs->in(0).IsConstant() | 5355 locs->set_in(1, locs->in(0).IsConstant() |
| 5356 ? Location::RequiresRegister() | 5356 ? Location::RequiresRegister() |
| 5357 : Location::RegisterOrConstant(right())); | 5357 : Location::RegisterOrConstant(right())); |
| 5358 locs->set_out(Location::RequiresRegister()); | 5358 locs->set_out(0, Location::RequiresRegister()); |
| 5359 return locs; | 5359 return locs; |
| 5360 } | 5360 } |
| 5361 | 5361 |
| 5362 | 5362 |
| 5363 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 5363 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 5364 BranchLabels labels) { | 5364 BranchLabels labels) { |
| 5365 Location left = locs()->in(0); | 5365 Location left = locs()->in(0); |
| 5366 Location right = locs()->in(1); | 5366 Location right = locs()->in(1); |
| 5367 ASSERT(!left.IsConstant() || !right.IsConstant()); | 5367 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 5368 if (left.IsConstant()) { | 5368 if (left.IsConstant()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5386 } | 5386 } |
| 5387 | 5387 |
| 5388 | 5388 |
| 5389 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5389 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5390 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 5390 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 5391 | 5391 |
| 5392 // The ARM code does not use true- and false-labels here. | 5392 // The ARM code does not use true- and false-labels here. |
| 5393 BranchLabels labels = { NULL, NULL, NULL }; | 5393 BranchLabels labels = { NULL, NULL, NULL }; |
| 5394 Condition true_condition = EmitComparisonCode(compiler, labels); | 5394 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 5395 | 5395 |
| 5396 Register result = locs()->out().reg(); | 5396 Register result = locs()->out(0).reg(); |
| 5397 __ LoadObject(result, Bool::True(), true_condition); | 5397 __ LoadObject(result, Bool::True(), true_condition); |
| 5398 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); | 5398 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); |
| 5399 } | 5399 } |
| 5400 | 5400 |
| 5401 | 5401 |
| 5402 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 5402 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 5403 BranchInstr* branch) { | 5403 BranchInstr* branch) { |
| 5404 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 5404 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 5405 | 5405 |
| 5406 BranchLabels labels = compiler->CreateBranchLabels(branch); | 5406 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 5407 Condition true_condition = EmitComparisonCode(compiler, labels); | 5407 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 5408 EmitBranchOnCondition(compiler, true_condition, labels); | 5408 EmitBranchOnCondition(compiler, true_condition, labels); |
| 5409 } | 5409 } |
| 5410 | 5410 |
| 5411 | 5411 |
| 5412 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { | 5412 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
| 5413 return LocationSummary::Make(1, | 5413 return LocationSummary::Make(1, |
| 5414 Location::RequiresRegister(), | 5414 Location::RequiresRegister(), |
| 5415 LocationSummary::kNoCall); | 5415 LocationSummary::kNoCall); |
| 5416 } | 5416 } |
| 5417 | 5417 |
| 5418 | 5418 |
| 5419 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5419 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5420 Register value = locs()->in(0).reg(); | 5420 Register value = locs()->in(0).reg(); |
| 5421 Register result = locs()->out().reg(); | 5421 Register result = locs()->out(0).reg(); |
| 5422 | 5422 |
| 5423 __ LoadObject(result, Bool::True()); | 5423 __ LoadObject(result, Bool::True()); |
| 5424 __ cmp(result, ShifterOperand(value)); | 5424 __ cmp(result, ShifterOperand(value)); |
| 5425 __ LoadObject(result, Bool::False(), EQ); | 5425 __ LoadObject(result, Bool::False(), EQ); |
| 5426 } | 5426 } |
| 5427 | 5427 |
| 5428 | 5428 |
| 5429 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { | 5429 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
| 5430 return MakeCallSummary(); | 5430 return MakeCallSummary(); |
| 5431 } | 5431 } |
| 5432 | 5432 |
| 5433 | 5433 |
| 5434 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5434 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5435 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 5435 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
| 5436 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 5436 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
| 5437 compiler->GenerateCall(token_pos(), | 5437 compiler->GenerateCall(token_pos(), |
| 5438 &label, | 5438 &label, |
| 5439 PcDescriptors::kOther, | 5439 PcDescriptors::kOther, |
| 5440 locs()); | 5440 locs()); |
| 5441 __ Drop(ArgumentCount()); // Discard arguments. | 5441 __ Drop(ArgumentCount()); // Discard arguments. |
| 5442 } | 5442 } |
| 5443 | 5443 |
| 5444 } // namespace dart | 5444 } // namespace dart |
| 5445 | 5445 |
| 5446 #endif // defined TARGET_ARCH_ARM | 5446 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |