Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1527143003: Subzero. Introduces a new LoweringContext::insert() method. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: More changes Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringMIPS32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 case InstArithmetic::Urem: 350 case InstArithmetic::Urem:
351 TargetHelper = Ctx->getConstantExternSym(H_urem_i64); 351 TargetHelper = Ctx->getConstantExternSym(H_urem_i64);
352 break; 352 break;
353 case InstArithmetic::Srem: 353 case InstArithmetic::Srem:
354 TargetHelper = Ctx->getConstantExternSym(H_srem_i64); 354 TargetHelper = Ctx->getConstantExternSym(H_srem_i64);
355 break; 355 break;
356 } 356 }
357 assert(TargetHelper != nullptr); 357 assert(TargetHelper != nullptr);
358 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; 358 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
359 constexpr SizeT MaxArgs = 2; 359 constexpr SizeT MaxArgs = 2;
360 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 360 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
361 NoTailCall, IsTargetHelperCall); 361 NoTailCall, IsTargetHelperCall);
362 Call->addArg(Instr->getSrc(0)); 362 Call->addArg(Instr->getSrc(0));
363 Call->addArg(Instr->getSrc(1)); 363 Call->addArg(Instr->getSrc(1));
364 Context.insert(Call);
365 Instr->setDeleted(); 364 Instr->setDeleted();
366 return; 365 return;
367 } 366 }
368 case IceType_i32: 367 case IceType_i32:
369 case IceType_i16: 368 case IceType_i16:
370 case IceType_i8: { 369 case IceType_i8: {
371 const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm); 370 const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm);
372 InstCast::OpKind CastKind; 371 InstCast::OpKind CastKind;
373 Operand *TargetHelper; 372 Operand *TargetHelper;
374 switch (Op) { 373 switch (Op) {
(...skipping 26 matching lines...) Expand all
401 // the following assert will have to be modified. 400 // the following assert will have to be modified.
402 assert(HasHWDiv); 401 assert(HasHWDiv);
403 return; 402 return;
404 } 403 }
405 Operand *Src0 = Instr->getSrc(0); 404 Operand *Src0 = Instr->getSrc(0);
406 Operand *Src1 = Instr->getSrc(1); 405 Operand *Src1 = Instr->getSrc(1);
407 if (DestTy != IceType_i32) { 406 if (DestTy != IceType_i32) {
408 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0, 407 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0,
409 // we just insert a InstCast right before the call to the helper. 408 // we just insert a InstCast right before the call to the helper.
410 Variable *Src0_32 = Func->makeVariable(IceType_i32); 409 Variable *Src0_32 = Func->makeVariable(IceType_i32);
411 Context.insert(InstCast::create(Func, CastKind, Src0_32, Src0)); 410 Context.insert<InstCast>(CastKind, Src0_32, Src0);
412 Src0 = Src0_32; 411 Src0 = Src0_32;
413 412
414 // For extending Src1, we will just insert an InstCast if Src1 is not a 413 // For extending Src1, we will just insert an InstCast if Src1 is not a
415 // Constant. If it is, then we extend it here, and not during program 414 // Constant. If it is, then we extend it here, and not during program
416 // runtime. This allows preambleDivRem to optimize-out the div-by-0 415 // runtime. This allows preambleDivRem to optimize-out the div-by-0
417 // check. 416 // check.
418 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) { 417 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
419 const int32_t ShAmt = (DestTy == IceType_i16) ? 16 : 24; 418 const int32_t ShAmt = (DestTy == IceType_i16) ? 16 : 24;
420 int32_t NewC = C->getValue(); 419 int32_t NewC = C->getValue();
421 if (CastKind == InstCast::Zext) { 420 if (CastKind == InstCast::Zext) {
422 NewC &= ~(0x80000000l >> ShAmt); 421 NewC &= ~(0x80000000l >> ShAmt);
423 } else { 422 } else {
424 NewC = (NewC << ShAmt) >> ShAmt; 423 NewC = (NewC << ShAmt) >> ShAmt;
425 } 424 }
426 Src1 = Ctx->getConstantInt32(NewC); 425 Src1 = Ctx->getConstantInt32(NewC);
427 } else { 426 } else {
428 Variable *Src1_32 = Func->makeVariable(IceType_i32); 427 Variable *Src1_32 = Func->makeVariable(IceType_i32);
429 Context.insert(InstCast::create(Func, CastKind, Src1_32, Src1)); 428 Context.insert<InstCast>(CastKind, Src1_32, Src1);
430 Src1 = Src1_32; 429 Src1 = Src1_32;
431 } 430 }
432 } 431 }
433 assert(TargetHelper != nullptr); 432 assert(TargetHelper != nullptr);
434 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; 433 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
435 constexpr SizeT MaxArgs = 2; 434 constexpr SizeT MaxArgs = 2;
436 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 435 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
437 NoTailCall, IsTargetHelperCall); 436 NoTailCall, IsTargetHelperCall);
438 assert(Src0->getType() == IceType_i32); 437 assert(Src0->getType() == IceType_i32);
439 Call->addArg(Src0); 438 Call->addArg(Src0);
440 assert(Src1->getType() == IceType_i32); 439 assert(Src1->getType() == IceType_i32);
441 Call->addArg(Src1); 440 Call->addArg(Src1);
442 Context.insert(Call);
443 Instr->setDeleted(); 441 Instr->setDeleted();
444 return; 442 return;
445 } 443 }
446 case IceType_f64: 444 case IceType_f64:
447 case IceType_f32: { 445 case IceType_f32: {
448 if (Op != InstArithmetic::Frem) { 446 if (Op != InstArithmetic::Frem) {
449 return; 447 return;
450 } 448 }
451 constexpr SizeT MaxArgs = 2; 449 constexpr SizeT MaxArgs = 2;
452 Operand *TargetHelper = Ctx->getConstantExternSym( 450 Operand *TargetHelper = Ctx->getConstantExternSym(
453 DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); 451 DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64);
454 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 452 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
455 NoTailCall, IsTargetHelperCall); 453 NoTailCall, IsTargetHelperCall);
456 Call->addArg(Instr->getSrc(0)); 454 Call->addArg(Instr->getSrc(0));
457 Call->addArg(Instr->getSrc(1)); 455 Call->addArg(Instr->getSrc(1));
458 Context.insert(Call);
459 Instr->setDeleted(); 456 Instr->setDeleted();
460 return; 457 return;
461 } 458 }
462 } 459 }
463 llvm::report_fatal_error("Control flow should never have reached here."); 460 llvm::report_fatal_error("Control flow should never have reached here.");
464 } 461 }
465 case Inst::Cast: { 462 case Inst::Cast: {
466 Variable *Dest = Instr->getDest(); 463 Variable *Dest = Instr->getDest();
467 Operand *Src0 = Instr->getSrc(0); 464 Operand *Src0 = Instr->getSrc(0);
468 const Type DestTy = Dest->getType(); 465 const Type DestTy = Dest->getType();
469 const InstCast::OpKind CastKind = 466 const InstCast::OpKind CastKind =
470 llvm::cast<InstCast>(Instr)->getCastKind(); 467 llvm::cast<InstCast>(Instr)->getCastKind();
471 switch (CastKind) { 468 switch (CastKind) {
472 default: 469 default:
473 return; 470 return;
474 case InstCast::Fptosi: 471 case InstCast::Fptosi:
475 case InstCast::Fptoui: { 472 case InstCast::Fptoui: {
476 if (DestTy != IceType_i64) { 473 if (DestTy != IceType_i64) {
477 return; 474 return;
478 } 475 }
479 const bool DestIsSigned = CastKind == InstCast::Fptosi; 476 const bool DestIsSigned = CastKind == InstCast::Fptosi;
480 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType()); 477 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType());
481 Operand *TargetHelper = Ctx->getConstantExternSym( 478 Operand *TargetHelper = Ctx->getConstantExternSym(
482 Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) 479 Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64)
483 : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); 480 : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64));
484 static constexpr SizeT MaxArgs = 1; 481 static constexpr SizeT MaxArgs = 1;
485 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 482 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
486 NoTailCall, IsTargetHelperCall); 483 NoTailCall, IsTargetHelperCall);
487 Call->addArg(Src0); 484 Call->addArg(Src0);
488 Context.insert(Call);
489 Instr->setDeleted(); 485 Instr->setDeleted();
490 return; 486 return;
491 } 487 }
492 case InstCast::Sitofp: 488 case InstCast::Sitofp:
493 case InstCast::Uitofp: { 489 case InstCast::Uitofp: {
494 if (Src0->getType() != IceType_i64) { 490 if (Src0->getType() != IceType_i64) {
495 return; 491 return;
496 } 492 }
497 const bool SourceIsSigned = CastKind == InstCast::Sitofp; 493 const bool SourceIsSigned = CastKind == InstCast::Sitofp;
498 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); 494 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
499 Operand *TargetHelper = Ctx->getConstantExternSym( 495 Operand *TargetHelper = Ctx->getConstantExternSym(
500 DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) 496 DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32)
501 : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); 497 : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64));
502 static constexpr SizeT MaxArgs = 1; 498 static constexpr SizeT MaxArgs = 1;
503 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 499 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
504 NoTailCall, IsTargetHelperCall); 500 NoTailCall, IsTargetHelperCall);
505 Call->addArg(Src0); 501 Call->addArg(Src0);
506 Context.insert(Call);
507 Instr->setDeleted(); 502 Instr->setDeleted();
508 return; 503 return;
509 } 504 }
510 } 505 }
511 llvm::report_fatal_error("Control flow should never have reached here."); 506 llvm::report_fatal_error("Control flow should never have reached here.");
512 } 507 }
513 case Inst::IntrinsicCall: { 508 case Inst::IntrinsicCall: {
514 Variable *Dest = Instr->getDest(); 509 Variable *Dest = Instr->getDest();
515 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); 510 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr);
516 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; 511 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID;
517 switch (ID) { 512 switch (ID) {
518 default: 513 default:
519 return; 514 return;
520 case Intrinsics::Ctpop: { 515 case Intrinsics::Ctpop: {
521 Operand *Src0 = IntrinsicCall->getArg(0); 516 Operand *Src0 = IntrinsicCall->getArg(0);
522 Operand *TargetHelper = Ctx->getConstantExternSym( 517 Operand *TargetHelper = Ctx->getConstantExternSym(
523 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 518 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32
524 : H_call_ctpop_i64); 519 : H_call_ctpop_i64);
525 static constexpr SizeT MaxArgs = 1; 520 static constexpr SizeT MaxArgs = 1;
526 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 521 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
527 NoTailCall, IsTargetHelperCall); 522 NoTailCall, IsTargetHelperCall);
528 Call->addArg(Src0); 523 Call->addArg(Src0);
529 Context.insert(Call);
530 Instr->setDeleted(); 524 Instr->setDeleted();
531 if (Src0->getType() == IceType_i64) { 525 if (Src0->getType() == IceType_i64) {
532 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; 526 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64;
533 } 527 }
534 return; 528 return;
535 } 529 }
536 case Intrinsics::Longjmp: { 530 case Intrinsics::Longjmp: {
537 static constexpr SizeT MaxArgs = 2; 531 static constexpr SizeT MaxArgs = 2;
538 static constexpr Variable *NoDest = nullptr; 532 static constexpr Variable *NoDest = nullptr;
539 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_longjmp); 533 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_longjmp);
540 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper, 534 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
541 NoTailCall, IsTargetHelperCall); 535 NoTailCall, IsTargetHelperCall);
542 Call->addArg(IntrinsicCall->getArg(0)); 536 Call->addArg(IntrinsicCall->getArg(0));
543 Call->addArg(IntrinsicCall->getArg(1)); 537 Call->addArg(IntrinsicCall->getArg(1));
544 Context.insert(Call);
545 Instr->setDeleted(); 538 Instr->setDeleted();
546 return; 539 return;
547 } 540 }
548 case Intrinsics::Memcpy: { 541 case Intrinsics::Memcpy: {
549 // In the future, we could potentially emit an inline memcpy/memset, etc. 542 // In the future, we could potentially emit an inline memcpy/memset, etc.
550 // for intrinsic calls w/ a known length. 543 // for intrinsic calls w/ a known length.
551 static constexpr SizeT MaxArgs = 3; 544 static constexpr SizeT MaxArgs = 3;
552 static constexpr Variable *NoDest = nullptr; 545 static constexpr Variable *NoDest = nullptr;
553 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memcpy); 546 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memcpy);
554 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper, 547 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
555 NoTailCall, IsTargetHelperCall); 548 NoTailCall, IsTargetHelperCall);
556 Call->addArg(IntrinsicCall->getArg(0)); 549 Call->addArg(IntrinsicCall->getArg(0));
557 Call->addArg(IntrinsicCall->getArg(1)); 550 Call->addArg(IntrinsicCall->getArg(1));
558 Call->addArg(IntrinsicCall->getArg(2)); 551 Call->addArg(IntrinsicCall->getArg(2));
559 Context.insert(Call);
560 Instr->setDeleted(); 552 Instr->setDeleted();
561 return; 553 return;
562 } 554 }
563 case Intrinsics::Memmove: { 555 case Intrinsics::Memmove: {
564 static constexpr SizeT MaxArgs = 3; 556 static constexpr SizeT MaxArgs = 3;
565 static constexpr Variable *NoDest = nullptr; 557 static constexpr Variable *NoDest = nullptr;
566 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memmove); 558 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memmove);
567 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper, 559 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
568 NoTailCall, IsTargetHelperCall); 560 NoTailCall, IsTargetHelperCall);
569 Call->addArg(IntrinsicCall->getArg(0)); 561 Call->addArg(IntrinsicCall->getArg(0));
570 Call->addArg(IntrinsicCall->getArg(1)); 562 Call->addArg(IntrinsicCall->getArg(1));
571 Call->addArg(IntrinsicCall->getArg(2)); 563 Call->addArg(IntrinsicCall->getArg(2));
572 Context.insert(Call);
573 Instr->setDeleted(); 564 Instr->setDeleted();
574 return; 565 return;
575 } 566 }
576 case Intrinsics::Memset: { 567 case Intrinsics::Memset: {
577 // The value operand needs to be extended to a stack slot size because the 568 // The value operand needs to be extended to a stack slot size because the
578 // PNaCl ABI requires arguments to be at least 32 bits wide. 569 // PNaCl ABI requires arguments to be at least 32 bits wide.
579 Operand *ValOp = IntrinsicCall->getArg(1); 570 Operand *ValOp = IntrinsicCall->getArg(1);
580 assert(ValOp->getType() == IceType_i8); 571 assert(ValOp->getType() == IceType_i8);
581 Variable *ValExt = Func->makeVariable(stackSlotType()); 572 Variable *ValExt = Func->makeVariable(stackSlotType());
582 Context.insert(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); 573 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp);
583 574
584 // Technically, ARM has its own __aeabi_memset, but we can use plain 575 // Technically, ARM has its own __aeabi_memset, but we can use plain
585 // memset too. The value and size argument need to be flipped if we ever 576 // memset too. The value and size argument need to be flipped if we ever
586 // decide to use __aeabi_memset. 577 // decide to use __aeabi_memset.
587 static constexpr SizeT MaxArgs = 3; 578 static constexpr SizeT MaxArgs = 3;
588 static constexpr Variable *NoDest = nullptr; 579 static constexpr Variable *NoDest = nullptr;
589 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memset); 580 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memset);
590 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper, 581 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
591 NoTailCall, IsTargetHelperCall); 582 NoTailCall, IsTargetHelperCall);
592 Call->addArg(IntrinsicCall->getArg(0)); 583 Call->addArg(IntrinsicCall->getArg(0));
593 Call->addArg(ValExt); 584 Call->addArg(ValExt);
594 Call->addArg(IntrinsicCall->getArg(2)); 585 Call->addArg(IntrinsicCall->getArg(2));
595 Context.insert(Call);
596 Instr->setDeleted(); 586 Instr->setDeleted();
597 return; 587 return;
598 } 588 }
599 case Intrinsics::NaClReadTP: { 589 case Intrinsics::NaClReadTP: {
600 if (NeedSandboxing) { 590 if (NeedSandboxing) {
601 return; 591 return;
602 } 592 }
603 static constexpr SizeT MaxArgs = 0; 593 static constexpr SizeT MaxArgs = 0;
604 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp); 594 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp);
605 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 595 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall,
606 NoTailCall, IsTargetHelperCall); 596 IsTargetHelperCall);
607 Context.insert(Call);
608 Instr->setDeleted(); 597 Instr->setDeleted();
609 return; 598 return;
610 } 599 }
611 case Intrinsics::Setjmp: { 600 case Intrinsics::Setjmp: {
612 static constexpr SizeT MaxArgs = 1; 601 static constexpr SizeT MaxArgs = 1;
613 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_setjmp); 602 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_setjmp);
614 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 603 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
615 NoTailCall, IsTargetHelperCall); 604 NoTailCall, IsTargetHelperCall);
616 Call->addArg(IntrinsicCall->getArg(0)); 605 Call->addArg(IntrinsicCall->getArg(0));
617 Context.insert(Call);
618 Instr->setDeleted(); 606 Instr->setDeleted();
619 return; 607 return;
620 } 608 }
621 } 609 }
622 llvm::report_fatal_error("Control flow should never have reached here."); 610 llvm::report_fatal_error("Control flow should never have reached here.");
623 } 611 }
624 } 612 }
625 } 613 }
626 614
627 void TargetARM32::findMaxStackOutArgsSize() { 615 void TargetARM32::findMaxStackOutArgsSize() {
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 default: { RegisterArg->setRegNum(RegNum); } break; 1011 default: { RegisterArg->setRegNum(RegNum); } break;
1024 case IceType_i64: { 1012 case IceType_i64: {
1025 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); 1013 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg);
1026 RegisterArg64->initHiLo(Func); 1014 RegisterArg64->initHiLo(Func);
1027 RegisterArg64->getLo()->setRegNum( 1015 RegisterArg64->getLo()->setRegNum(
1028 RegARM32::getI64PairFirstGPRNum(RegNum)); 1016 RegARM32::getI64PairFirstGPRNum(RegNum));
1029 RegisterArg64->getHi()->setRegNum( 1017 RegisterArg64->getHi()->setRegNum(
1030 RegARM32::getI64PairSecondGPRNum(RegNum)); 1018 RegARM32::getI64PairSecondGPRNum(RegNum));
1031 } break; 1019 } break;
1032 } 1020 }
1033 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 1021 Context.insert<InstAssign>(Arg, RegisterArg);
1034 } 1022 }
1035 } 1023 }
1036 1024
1037 // Helper function for addProlog(). 1025 // Helper function for addProlog().
1038 // 1026 //
1039 // This assumes Arg is an argument passed on the stack. This sets the frame 1027 // This assumes Arg is an argument passed on the stack. This sets the frame
1040 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an 1028 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an
1041 // I64 arg that has been split into Lo and Hi components, it calls itself 1029 // I64 arg that has been split into Lo and Hi components, it calls itself
1042 // recursively on the components, taking care to handle Lo first because of the 1030 // recursively on the components, taking care to handle Lo first because of the
1043 // little-endian architecture. Lastly, this function generates an instruction 1031 // little-endian architecture. Lastly, this function generates an instruction
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 _push(PreservedSRegs); 1212 _push(PreservedSRegs);
1225 if (!PreservedGPRs.empty()) 1213 if (!PreservedGPRs.empty())
1226 _push(PreservedGPRs); 1214 _push(PreservedGPRs);
1227 1215
1228 // Generate "mov FP, SP" if needed. 1216 // Generate "mov FP, SP" if needed.
1229 if (UsesFramePointer) { 1217 if (UsesFramePointer) {
1230 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp); 1218 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp);
1231 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 1219 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
1232 _mov(FP, SP); 1220 _mov(FP, SP);
1233 // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode). 1221 // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode).
1234 Context.insert(InstFakeUse::create(Func, FP)); 1222 Context.insert<InstFakeUse>(FP);
1235 } 1223 }
1236 1224
1237 // Align the variables area. SpillAreaPaddingBytes is the size of the region 1225 // Align the variables area. SpillAreaPaddingBytes is the size of the region
1238 // after the preserved registers and before the spill areas. 1226 // after the preserved registers and before the spill areas.
1239 // LocalsSlotsPaddingBytes is the amount of padding between the globals and 1227 // LocalsSlotsPaddingBytes is the amount of padding between the globals and
1240 // locals area if they are separate. 1228 // locals area if they are separate.
1241 assert(SpillAreaAlignmentBytes <= ARM32_STACK_ALIGNMENT_BYTES); 1229 assert(SpillAreaAlignmentBytes <= ARM32_STACK_ALIGNMENT_BYTES);
1242 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); 1230 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes);
1243 uint32_t SpillAreaPaddingBytes = 0; 1231 uint32_t SpillAreaPaddingBytes = 0;
1244 uint32_t LocalsSlotsPaddingBytes = 0; 1232 uint32_t LocalsSlotsPaddingBytes = 0;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 --InsertPoint; 1341 --InsertPoint;
1354 Context.init(Node); 1342 Context.init(Node);
1355 Context.setInsertPoint(InsertPoint); 1343 Context.setInsertPoint(InsertPoint);
1356 1344
1357 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 1345 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
1358 if (UsesFramePointer) { 1346 if (UsesFramePointer) {
1359 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp); 1347 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp);
1360 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake 1348 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
1361 // use of SP before the assignment of SP=FP keeps previous SP adjustments 1349 // use of SP before the assignment of SP=FP keeps previous SP adjustments
1362 // from being dead-code eliminated. 1350 // from being dead-code eliminated.
1363 Context.insert(InstFakeUse::create(Func, SP)); 1351 Context.insert<InstFakeUse>(SP);
1364 Sandboxer(this).reset_sp(FP); 1352 Sandboxer(this).reset_sp(FP);
1365 } else { 1353 } else {
1366 // add SP, SpillAreaSizeBytes 1354 // add SP, SpillAreaSizeBytes
1367 if (SpillAreaSizeBytes) { 1355 if (SpillAreaSizeBytes) {
1368 // Use the scratch register if needed to legalize the immediate. 1356 // Use the scratch register if needed to legalize the immediate.
1369 Operand *AddAmount = 1357 Operand *AddAmount =
1370 legalize(Ctx->getConstantInt32(SpillAreaSizeBytes), 1358 legalize(Ctx->getConstantInt32(SpillAreaSizeBytes),
1371 Legal_Reg | Legal_Flex, getReservedTmpReg()); 1359 Legal_Reg | Legal_Flex, getReservedTmpReg());
1372 Sandboxer(this).add_sp(AddAmount); 1360 Sandboxer(this).add_sp(AddAmount);
1373 } 1361 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 if (!Dest->hasReg()) { 1505 if (!Dest->hasReg()) {
1518 auto *SrcR = llvm::cast<Variable>(Src); 1506 auto *SrcR = llvm::cast<Variable>(Src);
1519 assert(SrcR->hasReg()); 1507 assert(SrcR->hasReg());
1520 assert(!SrcR->isRematerializable()); 1508 assert(!SrcR->isRematerializable());
1521 const int32_t Offset = Dest->getStackOffset(); 1509 const int32_t Offset = Dest->getStackOffset();
1522 // This is a _mov(Mem(), Variable), i.e., a store. 1510 // This is a _mov(Mem(), Variable), i.e., a store.
1523 TargetARM32::Sandboxer(Target) 1511 TargetARM32::Sandboxer(Target)
1524 .str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset), 1512 .str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset),
1525 MovInstr->getPredicate()); 1513 MovInstr->getPredicate());
1526 // _str() does not have a Dest, so we add a fake-def(Dest). 1514 // _str() does not have a Dest, so we add a fake-def(Dest).
1527 Target->Context.insert(InstFakeDef::create(Target->Func, Dest)); 1515 Target->Context.insert<InstFakeDef>(Dest);
1528 Legalized = true; 1516 Legalized = true;
1529 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1517 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1530 if (Var->isRematerializable()) { 1518 if (Var->isRematerializable()) {
1531 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1519 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1532 1520
1533 // ExtraOffset is only needed for frame-pointer based frames as we have 1521 // ExtraOffset is only needed for frame-pointer based frames as we have
1534 // to account for spill storage. 1522 // to account for spill storage.
1535 const int32_t ExtraOffset = 1523 const int32_t ExtraOffset =
1536 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) 1524 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg())
1537 ? Target->getFrameFixedAllocaOffset() 1525 ? Target->getFrameFixedAllocaOffset()
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { 1880 llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
1893 const uint32_t Value = 1881 const uint32_t Value =
1894 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); 1882 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment);
1895 // Constant size alloca. 1883 // Constant size alloca.
1896 if (!UseFramePointer) { 1884 if (!UseFramePointer) {
1897 // If we don't need a Frame Pointer, this alloca has a known offset to the 1885 // If we don't need a Frame Pointer, this alloca has a known offset to the
1898 // stack pointer. We don't need adjust the stack pointer, nor assign any 1886 // stack pointer. We don't need adjust the stack pointer, nor assign any
1899 // value to Dest, as Dest is rematerializable. 1887 // value to Dest, as Dest is rematerializable.
1900 assert(Dest->isRematerializable()); 1888 assert(Dest->isRematerializable());
1901 FixedAllocaSizeBytes += Value; 1889 FixedAllocaSizeBytes += Value;
1902 Context.insert(InstFakeDef::create(Func, Dest)); 1890 Context.insert<InstFakeDef>(Dest);
1903 return; 1891 return;
1904 } 1892 }
1905 1893
1906 // If a frame pointer is required, then we need to store the alloca'd result 1894 // If a frame pointer is required, then we need to store the alloca'd result
1907 // in Dest. 1895 // in Dest.
1908 Operand *SubAmountRF = 1896 Operand *SubAmountRF =
1909 legalize(Ctx->getConstantInt32(Value), Legal_Reg | Legal_Flex); 1897 legalize(Ctx->getConstantInt32(Value), Legal_Reg | Legal_Flex);
1910 Sandboxer(this).sub_sp(SubAmountRF); 1898 Sandboxer(this).sub_sp(SubAmountRF);
1911 } else { 1899 } else {
1912 // Non-constant sizes need to be adjusted to the next highest multiple of 1900 // Non-constant sizes need to be adjusted to the next highest multiple of
(...skipping 24 matching lines...) Expand all
1937 return; 1925 return;
1938 Variable *SrcLoReg = legalizeToReg(SrcLo); 1926 Variable *SrcLoReg = legalizeToReg(SrcLo);
1939 switch (Ty) { 1927 switch (Ty) {
1940 default: 1928 default:
1941 llvm::report_fatal_error("Unexpected type"); 1929 llvm::report_fatal_error("Unexpected type");
1942 case IceType_i8: 1930 case IceType_i8:
1943 case IceType_i16: { 1931 case IceType_i16: {
1944 Operand *ShAmtImm = shAmtImm(32 - getScalarIntBitWidth(Ty)); 1932 Operand *ShAmtImm = shAmtImm(32 - getScalarIntBitWidth(Ty));
1945 Variable *T = makeReg(IceType_i32); 1933 Variable *T = makeReg(IceType_i32);
1946 _lsls(T, SrcLoReg, ShAmtImm); 1934 _lsls(T, SrcLoReg, ShAmtImm);
1947 Context.insert(InstFakeUse::create(Func, T)); 1935 Context.insert<InstFakeUse>(T);
1948 } break; 1936 } break;
1949 case IceType_i32: { 1937 case IceType_i32: {
1950 _tst(SrcLoReg, SrcLoReg); 1938 _tst(SrcLoReg, SrcLoReg);
1951 break; 1939 break;
1952 } 1940 }
1953 case IceType_i64: { 1941 case IceType_i64: {
1954 Variable *T = makeReg(IceType_i32); 1942 Variable *T = makeReg(IceType_i32);
1955 _orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex)); 1943 _orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex));
1956 // T isn't going to be used, but we need the side-effect of setting flags 1944 // T isn't going to be used, but we need the side-effect of setting flags
1957 // from this operation. 1945 // from this operation.
1958 Context.insert(InstFakeUse::create(Func, T)); 1946 Context.insert<InstFakeUse>(T);
1959 } 1947 }
1960 } 1948 }
1961 auto *Label = InstARM32Label::create(Func, this); 1949 auto *Label = InstARM32Label::create(Func, this);
1962 _br(Label, CondARM32::NE); 1950 _br(Label, CondARM32::NE);
1963 _trap(); 1951 _trap();
1964 Context.insert(Label); 1952 Context.insert(Label);
1965 } 1953 }
1966 1954
1967 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, 1955 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R,
1968 Operand *Src1, ExtInstr ExtFunc, 1956 Operand *Src1, ExtInstr ExtFunc,
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 2692
2705 return Src == 0; 2693 return Src == 0;
2706 } 2694 }
2707 } // end of namespace StrengthReduction 2695 } // end of namespace StrengthReduction
2708 } // end of anonymous namespace 2696 } // end of anonymous namespace
2709 2697
2710 void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { 2698 void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
2711 Variable *Dest = Instr->getDest(); 2699 Variable *Dest = Instr->getDest();
2712 2700
2713 if (Dest->isRematerializable()) { 2701 if (Dest->isRematerializable()) {
2714 Context.insert(InstFakeDef::create(Func, Dest)); 2702 Context.insert<InstFakeDef>(Dest);
2715 return; 2703 return;
2716 } 2704 }
2717 2705
2718 Type DestTy = Dest->getType(); 2706 Type DestTy = Dest->getType();
2719 if (DestTy == IceType_i1) { 2707 if (DestTy == IceType_i1) {
2720 lowerInt1Arithmetic(Instr); 2708 lowerInt1Arithmetic(Instr);
2721 return; 2709 return;
2722 } 2710 }
2723 2711
2724 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); 2712 Operand *Src0 = legalizeUndef(Instr->getSrc(0));
2725 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); 2713 Operand *Src1 = legalizeUndef(Instr->getSrc(1));
2726 if (DestTy == IceType_i64) { 2714 if (DestTy == IceType_i64) {
2727 lowerInt64Arithmetic(Instr->getOp(), Instr->getDest(), Src0, Src1); 2715 lowerInt64Arithmetic(Instr->getOp(), Instr->getDest(), Src0, Src1);
2728 return; 2716 return;
2729 } 2717 }
2730 2718
2731 if (isVectorType(DestTy)) { 2719 if (isVectorType(DestTy)) {
2732 // Add a fake def to keep liveness consistent in the meantime. 2720 // Add a fake def to keep liveness consistent in the meantime.
2733 Variable *T = makeReg(DestTy); 2721 Variable *T = makeReg(DestTy);
2734 Context.insert(InstFakeDef::create(Func, T)); 2722 Context.insert<InstFakeDef>(T);
2735 _mov(Dest, T); 2723 _mov(Dest, T);
2736 UnimplementedError(Func->getContext()->getFlags()); 2724 UnimplementedError(Func->getContext()->getFlags());
2737 return; 2725 return;
2738 } 2726 }
2739 2727
2740 // DestTy is a non-i64 scalar. 2728 // DestTy is a non-i64 scalar.
2741 Variable *T = makeReg(DestTy); 2729 Variable *T = makeReg(DestTy);
2742 2730
2743 // * Handle div/rem separately. They require a non-legalized Src1 to inspect 2731 // * Handle div/rem separately. They require a non-legalized Src1 to inspect
2744 // whether or not Src1 is a non-zero constant. Once legalized it is more 2732 // whether or not Src1 is a non-zero constant. Once legalized it is more
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 llvm::report_fatal_error( 3044 llvm::report_fatal_error(
3057 "Floating point arith should have been handled earlier."); 3045 "Floating point arith should have been handled earlier.");
3058 return; 3046 return;
3059 } 3047 }
3060 } 3048 }
3061 3049
3062 void TargetARM32::lowerAssign(const InstAssign *Inst) { 3050 void TargetARM32::lowerAssign(const InstAssign *Inst) {
3063 Variable *Dest = Inst->getDest(); 3051 Variable *Dest = Inst->getDest();
3064 3052
3065 if (Dest->isRematerializable()) { 3053 if (Dest->isRematerializable()) {
3066 Context.insert(InstFakeDef::create(Func, Dest)); 3054 Context.insert<InstFakeDef>(Dest);
3067 return; 3055 return;
3068 } 3056 }
3069 3057
3070 Operand *Src0 = Inst->getSrc(0); 3058 Operand *Src0 = Inst->getSrc(0);
3071 assert(Dest->getType() == Src0->getType()); 3059 assert(Dest->getType() == Src0->getType());
3072 if (Dest->getType() == IceType_i64) { 3060 if (Dest->getType() == IceType_i64) {
3073 Src0 = legalizeUndef(Src0); 3061 Src0 = legalizeUndef(Src0);
3074 3062
3075 Variable *T_Lo = makeReg(IceType_i32); 3063 Variable *T_Lo = makeReg(IceType_i32);
3076 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 3064 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 // Allow ConstantRelocatable to be left alone as a direct call, but force 3348 // Allow ConstantRelocatable to be left alone as a direct call, but force
3361 // other constants like ConstantInteger32 to be in a register and make it an 3349 // other constants like ConstantInteger32 to be in a register and make it an
3362 // indirect call. 3350 // indirect call.
3363 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { 3351 if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
3364 CallTarget = legalize(CallTarget, Legal_Reg); 3352 CallTarget = legalize(CallTarget, Legal_Reg);
3365 } 3353 }
3366 3354
3367 // Copy arguments to be passed in registers to the appropriate registers. 3355 // Copy arguments to be passed in registers to the appropriate registers.
3368 for (auto &FPArg : FPArgs) { 3356 for (auto &FPArg : FPArgs) {
3369 Variable *Reg = legalizeToReg(FPArg.first, FPArg.second); 3357 Variable *Reg = legalizeToReg(FPArg.first, FPArg.second);
3370 Context.insert(InstFakeUse::create(Func, Reg)); 3358 Context.insert<InstFakeUse>(Reg);
3371 } 3359 }
3372 for (auto &GPRArg : GPRArgs) { 3360 for (auto &GPRArg : GPRArgs) {
3373 Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second); 3361 Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second);
3374 // Generate a FakeUse of register arguments so that they do not get dead 3362 // Generate a FakeUse of register arguments so that they do not get dead
3375 // code eliminated as a result of the FakeKill of scratch registers after 3363 // code eliminated as a result of the FakeKill of scratch registers after
3376 // the call. 3364 // the call.
3377 Context.insert(InstFakeUse::create(Func, Reg)); 3365 Context.insert<InstFakeUse>(Reg);
3378 } 3366 }
3379 3367
3380 InstARM32Call *NewCall = 3368 InstARM32Call *NewCall =
3381 Sandboxer(this, InstBundleLock::Opt_AlignToEnd).bl(ReturnReg, CallTarget); 3369 Sandboxer(this, InstBundleLock::Opt_AlignToEnd).bl(ReturnReg, CallTarget);
3382 3370
3383 if (ReturnRegHi) 3371 if (ReturnRegHi)
3384 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 3372 Context.insert<InstFakeDef>(ReturnRegHi);
3385 3373
3386 // Insert a register-kill pseudo instruction. 3374 // Insert a register-kill pseudo instruction.
3387 Context.insert(InstFakeKill::create(Func, NewCall)); 3375 Context.insert<InstFakeKill>(NewCall);
3388 3376
3389 // Generate a FakeUse to keep the call live if necessary. 3377 // Generate a FakeUse to keep the call live if necessary.
3390 if (Instr->hasSideEffects() && ReturnReg) { 3378 if (Instr->hasSideEffects() && ReturnReg) {
3391 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); 3379 Context.insert<InstFakeUse>(ReturnReg);
3392 Context.insert(FakeUse);
3393 } 3380 }
3394 3381
3395 if (Dest != nullptr) { 3382 if (Dest != nullptr) {
3396 // Assign the result of the call to Dest. 3383 // Assign the result of the call to Dest.
3397 if (ReturnReg != nullptr) { 3384 if (ReturnReg != nullptr) {
3398 if (ReturnRegHi) { 3385 if (ReturnRegHi) {
3399 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); 3386 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
3400 Variable *DestLo = Dest64On32->getLo(); 3387 Variable *DestLo = Dest64On32->getLo();
3401 Variable *DestHi = Dest64On32->getHi(); 3388 Variable *DestHi = Dest64On32->getHi();
3402 _mov(DestLo, ReturnReg); 3389 _mov(DestLo, ReturnReg);
(...skipping 30 matching lines...) Expand all
3433 InstCast::OpKind CastKind = Inst->getCastKind(); 3420 InstCast::OpKind CastKind = Inst->getCastKind();
3434 Variable *Dest = Inst->getDest(); 3421 Variable *Dest = Inst->getDest();
3435 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); 3422 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
3436 switch (CastKind) { 3423 switch (CastKind) {
3437 default: 3424 default:
3438 Func->setError("Cast type not supported"); 3425 Func->setError("Cast type not supported");
3439 return; 3426 return;
3440 case InstCast::Sext: { 3427 case InstCast::Sext: {
3441 if (isVectorType(Dest->getType())) { 3428 if (isVectorType(Dest->getType())) {
3442 Variable *T = makeReg(Dest->getType()); 3429 Variable *T = makeReg(Dest->getType());
3443 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3430 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3444 _mov(Dest, T); 3431 _mov(Dest, T);
3445 UnimplementedError(Func->getContext()->getFlags()); 3432 UnimplementedError(Func->getContext()->getFlags());
3446 } else if (Dest->getType() == IceType_i64) { 3433 } else if (Dest->getType() == IceType_i64) {
3447 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 3434 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2
3448 Constant *ShiftAmt = Ctx->getConstantInt32(31); 3435 Constant *ShiftAmt = Ctx->getConstantInt32(31);
3449 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 3436 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
3450 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 3437 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
3451 Variable *T_Lo = makeReg(DestLo->getType()); 3438 Variable *T_Lo = makeReg(DestLo->getType());
3452 if (Src0->getType() == IceType_i32) { 3439 if (Src0->getType() == IceType_i32) {
3453 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 3440 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
(...skipping 27 matching lines...) Expand all
3481 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1); 3468 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1);
3482 Variable *T = makeReg(Dest->getType()); 3469 Variable *T = makeReg(Dest->getType());
3483 lowerInt1ForSelect(T, Src0, _m1, _0); 3470 lowerInt1ForSelect(T, Src0, _m1, _0);
3484 _mov(Dest, T); 3471 _mov(Dest, T);
3485 } 3472 }
3486 break; 3473 break;
3487 } 3474 }
3488 case InstCast::Zext: { 3475 case InstCast::Zext: {
3489 if (isVectorType(Dest->getType())) { 3476 if (isVectorType(Dest->getType())) {
3490 Variable *T = makeReg(Dest->getType()); 3477 Variable *T = makeReg(Dest->getType());
3491 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3478 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3492 _mov(Dest, T); 3479 _mov(Dest, T);
3493 UnimplementedError(Func->getContext()->getFlags()); 3480 UnimplementedError(Func->getContext()->getFlags());
3494 } else if (Dest->getType() == IceType_i64) { 3481 } else if (Dest->getType() == IceType_i64) {
3495 // t1=uxtb src; dst.lo=t1; dst.hi=0 3482 // t1=uxtb src; dst.lo=t1; dst.hi=0
3496 Operand *_0 = 3483 Operand *_0 =
3497 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 3484 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
3498 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 3485 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
3499 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 3486 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
3500 Variable *T_Lo = makeReg(DestLo->getType()); 3487 Variable *T_Lo = makeReg(DestLo->getType());
3501 3488
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3537 Variable *Src0R = legalizeToReg(Src0); 3524 Variable *Src0R = legalizeToReg(Src0);
3538 Variable *T = makeReg(Dest->getType()); 3525 Variable *T = makeReg(Dest->getType());
3539 _uxt(T, Src0R); 3526 _uxt(T, Src0R);
3540 _mov(Dest, T); 3527 _mov(Dest, T);
3541 } 3528 }
3542 break; 3529 break;
3543 } 3530 }
3544 case InstCast::Trunc: { 3531 case InstCast::Trunc: {
3545 if (isVectorType(Dest->getType())) { 3532 if (isVectorType(Dest->getType())) {
3546 Variable *T = makeReg(Dest->getType()); 3533 Variable *T = makeReg(Dest->getType());
3547 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3534 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3548 _mov(Dest, T); 3535 _mov(Dest, T);
3549 UnimplementedError(Func->getContext()->getFlags()); 3536 UnimplementedError(Func->getContext()->getFlags());
3550 } else { 3537 } else {
3551 if (Src0->getType() == IceType_i64) 3538 if (Src0->getType() == IceType_i64)
3552 Src0 = loOperand(Src0); 3539 Src0 = loOperand(Src0);
3553 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 3540 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
3554 // t1 = trunc Src0RF; Dest = t1 3541 // t1 = trunc Src0RF; Dest = t1
3555 Variable *T = makeReg(Dest->getType()); 3542 Variable *T = makeReg(Dest->getType());
3556 _mov(T, Src0RF); 3543 _mov(T, Src0RF);
3557 if (Dest->getType() == IceType_i1) 3544 if (Dest->getType() == IceType_i1)
3558 _and(T, T, Ctx->getConstantInt1(1)); 3545 _and(T, T, Ctx->getConstantInt1(1));
3559 _mov(Dest, T); 3546 _mov(Dest, T);
3560 } 3547 }
3561 break; 3548 break;
3562 } 3549 }
3563 case InstCast::Fptrunc: 3550 case InstCast::Fptrunc:
3564 case InstCast::Fpext: { 3551 case InstCast::Fpext: {
3565 // fptrunc: dest.f32 = fptrunc src0.fp64 3552 // fptrunc: dest.f32 = fptrunc src0.fp64
3566 // fpext: dest.f64 = fptrunc src0.fp32 3553 // fpext: dest.f64 = fptrunc src0.fp32
3567 const bool IsTrunc = CastKind == InstCast::Fptrunc; 3554 const bool IsTrunc = CastKind == InstCast::Fptrunc;
3568 if (isVectorType(Dest->getType())) { 3555 if (isVectorType(Dest->getType())) {
3569 Variable *T = makeReg(Dest->getType()); 3556 Variable *T = makeReg(Dest->getType());
3570 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3557 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3571 _mov(Dest, T); 3558 _mov(Dest, T);
3572 UnimplementedError(Func->getContext()->getFlags()); 3559 UnimplementedError(Func->getContext()->getFlags());
3573 break; 3560 break;
3574 } 3561 }
3575 assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64)); 3562 assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64));
3576 assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32)); 3563 assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32));
3577 Variable *Src0R = legalizeToReg(Src0); 3564 Variable *Src0R = legalizeToReg(Src0);
3578 Variable *T = makeReg(Dest->getType()); 3565 Variable *T = makeReg(Dest->getType());
3579 _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d); 3566 _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d);
3580 _mov(Dest, T); 3567 _mov(Dest, T);
3581 break; 3568 break;
3582 } 3569 }
3583 case InstCast::Fptosi: 3570 case InstCast::Fptosi:
3584 case InstCast::Fptoui: { 3571 case InstCast::Fptoui: {
3585 if (isVectorType(Dest->getType())) { 3572 if (isVectorType(Dest->getType())) {
3586 Variable *T = makeReg(Dest->getType()); 3573 Variable *T = makeReg(Dest->getType());
3587 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3574 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3588 _mov(Dest, T); 3575 _mov(Dest, T);
3589 UnimplementedError(Func->getContext()->getFlags()); 3576 UnimplementedError(Func->getContext()->getFlags());
3590 break; 3577 break;
3591 } 3578 }
3592 3579
3593 const bool DestIsSigned = CastKind == InstCast::Fptosi; 3580 const bool DestIsSigned = CastKind == InstCast::Fptosi;
3594 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType()); 3581 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType());
3595 if (llvm::isa<Variable64On32>(Dest)) { 3582 if (llvm::isa<Variable64On32>(Dest)) {
3596 llvm::report_fatal_error("fp-to-i64 should have been pre-lowered."); 3583 llvm::report_fatal_error("fp-to-i64 should have been pre-lowered.");
3597 } 3584 }
(...skipping 18 matching lines...) Expand all
3616 lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T)); 3603 lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T));
3617 T = T_1; 3604 T = T_1;
3618 } 3605 }
3619 _mov(Dest, T); 3606 _mov(Dest, T);
3620 break; 3607 break;
3621 } 3608 }
3622 case InstCast::Sitofp: 3609 case InstCast::Sitofp:
3623 case InstCast::Uitofp: { 3610 case InstCast::Uitofp: {
3624 if (isVectorType(Dest->getType())) { 3611 if (isVectorType(Dest->getType())) {
3625 Variable *T = makeReg(Dest->getType()); 3612 Variable *T = makeReg(Dest->getType());
3626 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3613 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3627 _mov(Dest, T); 3614 _mov(Dest, T);
3628 UnimplementedError(Func->getContext()->getFlags()); 3615 UnimplementedError(Func->getContext()->getFlags());
3629 break; 3616 break;
3630 } 3617 }
3631 const bool SourceIsSigned = CastKind == InstCast::Sitofp; 3618 const bool SourceIsSigned = CastKind == InstCast::Sitofp;
3632 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); 3619 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
3633 if (Src0->getType() == IceType_i64) { 3620 if (Src0->getType() == IceType_i64) {
3634 llvm::report_fatal_error("i64-to-fp should have been pre-lowered."); 3621 llvm::report_fatal_error("i64-to-fp should have been pre-lowered.");
3635 } 3622 }
3636 // sitofp: 3623 // sitofp:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3693 case IceType_i64: { 3680 case IceType_i64: {
3694 // t0, t1 <- src0 3681 // t0, t1 <- src0
3695 // dest[31..0] = t0 3682 // dest[31..0] = t0
3696 // dest[63..32] = t1 3683 // dest[63..32] = t1
3697 assert(Src0->getType() == IceType_f64); 3684 assert(Src0->getType() == IceType_f64);
3698 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 3685 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
3699 T->initHiLo(Func); 3686 T->initHiLo(Func);
3700 configureBitcastTemporary(T); 3687 configureBitcastTemporary(T);
3701 Variable *Src0R = legalizeToReg(Src0); 3688 Variable *Src0R = legalizeToReg(Src0);
3702 _mov(T, Src0R); 3689 _mov(T, Src0R);
3703 Context.insert(InstFakeUse::create(Func, T->getHi())); 3690 Context.insert<InstFakeUse>(T->getHi());
3704 Context.insert(InstFakeUse::create(Func, T->getLo())); 3691 Context.insert<InstFakeUse>(T->getLo());
3705 lowerAssign(InstAssign::create(Func, Dest, T)); 3692 lowerAssign(InstAssign::create(Func, Dest, T));
3706 break; 3693 break;
3707 } 3694 }
3708 case IceType_f64: { 3695 case IceType_f64: {
3709 // T0 <- lo(src) 3696 // T0 <- lo(src)
3710 // T1 <- hi(src) 3697 // T1 <- hi(src)
3711 // vmov T2, T0, T1 3698 // vmov T2, T0, T1
3712 // Dest <- T2 3699 // Dest <- T2
3713 assert(Src0->getType() == IceType_i64); 3700 assert(Src0->getType() == IceType_i64);
3714 Variable *T = makeReg(DestType); 3701 Variable *T = makeReg(DestType);
3715 auto *Src64 = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 3702 auto *Src64 = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
3716 Src64->initHiLo(Func); 3703 Src64->initHiLo(Func);
3717 configureBitcastTemporary(Src64); 3704 configureBitcastTemporary(Src64);
3718 lowerAssign(InstAssign::create(Func, Src64, Src0)); 3705 lowerAssign(InstAssign::create(Func, Src64, Src0));
3719 _mov(T, Src64); 3706 _mov(T, Src64);
3720 lowerAssign(InstAssign::create(Func, Dest, T)); 3707 lowerAssign(InstAssign::create(Func, Dest, T));
3721 break; 3708 break;
3722 } 3709 }
3723 case IceType_v4i1: 3710 case IceType_v4i1:
3724 case IceType_v8i1: 3711 case IceType_v8i1:
3725 case IceType_v16i1: 3712 case IceType_v16i1:
3726 case IceType_v8i16: 3713 case IceType_v8i16:
3727 case IceType_v16i8: 3714 case IceType_v16i8:
3728 case IceType_v4f32: 3715 case IceType_v4f32:
3729 case IceType_v4i32: { 3716 case IceType_v4i32: {
3730 // avoid liveness errors 3717 // avoid liveness errors
3731 Variable *T = makeReg(DestType); 3718 Variable *T = makeReg(DestType);
3732 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); 3719 Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
3733 _mov(Dest, T); 3720 _mov(Dest, T);
3734 UnimplementedError(Func->getContext()->getFlags()); 3721 UnimplementedError(Func->getContext()->getFlags());
3735 break; 3722 break;
3736 } 3723 }
3737 } 3724 }
3738 break; 3725 break;
3739 } 3726 }
3740 } 3727 }
3741 } 3728 }
3742 3729
3743 void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) { 3730 void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
3744 Variable *Dest = Inst->getDest(); 3731 Variable *Dest = Inst->getDest();
3745 Type DestType = Dest->getType(); 3732 Type DestType = Dest->getType();
3746 Variable *T = makeReg(DestType); 3733 Variable *T = makeReg(DestType);
3747 Context.insert(InstFakeDef::create(Func, T)); 3734 Context.insert<InstFakeDef>(T);
3748 _mov(Dest, T); 3735 _mov(Dest, T);
3749 UnimplementedError(Func->getContext()->getFlags()); 3736 UnimplementedError(Func->getContext()->getFlags());
3750 } 3737 }
3751 3738
3752 namespace { 3739 namespace {
3753 // Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering 3740 // Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering
3754 // (and naming). 3741 // (and naming).
3755 enum { 3742 enum {
3756 #define X(val, CC0, CC1) _fcmp_ll_##val, 3743 #define X(val, CC0, CC1) _fcmp_ll_##val,
3757 FCMPARM32_TABLE 3744 FCMPARM32_TABLE
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3819 assert(Condition < llvm::array_lengthof(TableFcmp)); 3806 assert(Condition < llvm::array_lengthof(TableFcmp));
3820 return CondWhenTrue(TableFcmp[Condition].CC0, TableFcmp[Condition].CC1); 3807 return CondWhenTrue(TableFcmp[Condition].CC0, TableFcmp[Condition].CC1);
3821 } 3808 }
3822 } 3809 }
3823 } 3810 }
3824 3811
3825 void TargetARM32::lowerFcmp(const InstFcmp *Instr) { 3812 void TargetARM32::lowerFcmp(const InstFcmp *Instr) {
3826 Variable *Dest = Instr->getDest(); 3813 Variable *Dest = Instr->getDest();
3827 if (isVectorType(Dest->getType())) { 3814 if (isVectorType(Dest->getType())) {
3828 Variable *T = makeReg(Dest->getType()); 3815 Variable *T = makeReg(Dest->getType());
3829 Context.insert(InstFakeDef::create(Func, T)); 3816 Context.insert<InstFakeDef>(T);
3830 _mov(Dest, T); 3817 _mov(Dest, T);
3831 UnimplementedError(Func->getContext()->getFlags()); 3818 UnimplementedError(Func->getContext()->getFlags());
3832 return; 3819 return;
3833 } 3820 }
3834 3821
3835 Variable *T = makeReg(IceType_i1); 3822 Variable *T = makeReg(IceType_i1);
3836 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); 3823 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex);
3837 Operand *_0 = 3824 Operand *_0 =
3838 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 3825 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
3839 3826
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 if (SrcsLo.hasConstOperand()) { 3864 if (SrcsLo.hasConstOperand()) {
3878 const uint32_t ValueLo = SrcsLo.getConstantValue(); 3865 const uint32_t ValueLo = SrcsLo.getConstantValue();
3879 const uint32_t ValueHi = SrcsHi.getConstantValue(); 3866 const uint32_t ValueHi = SrcsHi.getConstantValue();
3880 const uint64_t Value = (static_cast<uint64_t>(ValueHi) << 32) | ValueLo; 3867 const uint64_t Value = (static_cast<uint64_t>(ValueHi) << 32) | ValueLo;
3881 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) && 3868 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) &&
3882 Value == 0) { 3869 Value == 0) {
3883 Variable *T = makeReg(IceType_i32); 3870 Variable *T = makeReg(IceType_i32);
3884 Variable *Src0LoR = SrcsLo.src0R(this); 3871 Variable *Src0LoR = SrcsLo.src0R(this);
3885 Variable *Src0HiR = SrcsHi.src0R(this); 3872 Variable *Src0HiR = SrcsHi.src0R(this);
3886 _orrs(T, Src0LoR, Src0HiR); 3873 _orrs(T, Src0LoR, Src0HiR);
3887 Context.insert(InstFakeUse::create(Func, T)); 3874 Context.insert<InstFakeUse>(T);
3888 return CondWhenTrue(TableIcmp64[Index].C1); 3875 return CondWhenTrue(TableIcmp64[Index].C1);
3889 } 3876 }
3890 3877
3891 Variable *Src0RLo = SrcsLo.src0R(this); 3878 Variable *Src0RLo = SrcsLo.src0R(this);
3892 Variable *Src0RHi = SrcsHi.src0R(this); 3879 Variable *Src0RHi = SrcsHi.src0R(this);
3893 Operand *Src1RFLo = SrcsLo.src1RF(this); 3880 Operand *Src1RFLo = SrcsLo.src1RF(this);
3894 Operand *Src1RFHi = ValueLo == ValueHi ? Src1RFLo : SrcsHi.src1RF(this); 3881 Operand *Src1RFHi = ValueLo == ValueHi ? Src1RFLo : SrcsHi.src1RF(this);
3895 3882
3896 const bool UseRsb = TableIcmp64[Index].Swapped != SrcsLo.swappedOperands(); 3883 const bool UseRsb = TableIcmp64[Index].Swapped != SrcsLo.swappedOperands();
3897 3884
3898 if (UseRsb) { 3885 if (UseRsb) {
3899 if (TableIcmp64[Index].IsSigned) { 3886 if (TableIcmp64[Index].IsSigned) {
3900 Variable *T = makeReg(IceType_i32); 3887 Variable *T = makeReg(IceType_i32);
3901 _rsbs(T, Src0RLo, Src1RFLo); 3888 _rsbs(T, Src0RLo, Src1RFLo);
3902 Context.insert(InstFakeUse::create(Func, T)); 3889 Context.insert<InstFakeUse>(T);
3903 3890
3904 T = makeReg(IceType_i32); 3891 T = makeReg(IceType_i32);
3905 _rscs(T, Src0RHi, Src1RFHi); 3892 _rscs(T, Src0RHi, Src1RFHi);
3906 // We need to add a FakeUse here because liveness gets mad at us (Def 3893 // We need to add a FakeUse here because liveness gets mad at us (Def
3907 // without Use.) Note that flag-setting instructions are considered to 3894 // without Use.) Note that flag-setting instructions are considered to
3908 // have side effects and, therefore, are not DCE'ed. 3895 // have side effects and, therefore, are not DCE'ed.
3909 Context.insert(InstFakeUse::create(Func, T)); 3896 Context.insert<InstFakeUse>(T);
3910 } else { 3897 } else {
3911 Variable *T = makeReg(IceType_i32); 3898 Variable *T = makeReg(IceType_i32);
3912 _rsbs(T, Src0RHi, Src1RFHi); 3899 _rsbs(T, Src0RHi, Src1RFHi);
3913 Context.insert(InstFakeUse::create(Func, T)); 3900 Context.insert<InstFakeUse>(T);
3914 3901
3915 T = makeReg(IceType_i32); 3902 T = makeReg(IceType_i32);
3916 _rsbs(T, Src0RLo, Src1RFLo, CondARM32::EQ); 3903 _rsbs(T, Src0RLo, Src1RFLo, CondARM32::EQ);
3917 Context.insert(InstFakeUse::create(Func, T)); 3904 Context.insert<InstFakeUse>(T);
3918 } 3905 }
3919 } else { 3906 } else {
3920 if (TableIcmp64[Index].IsSigned) { 3907 if (TableIcmp64[Index].IsSigned) {
3921 _cmp(Src0RLo, Src1RFLo); 3908 _cmp(Src0RLo, Src1RFLo);
3922 Variable *T = makeReg(IceType_i32); 3909 Variable *T = makeReg(IceType_i32);
3923 _sbcs(T, Src0RHi, Src1RFHi); 3910 _sbcs(T, Src0RHi, Src1RFHi);
3924 Context.insert(InstFakeUse::create(Func, T)); 3911 Context.insert<InstFakeUse>(T);
3925 } else { 3912 } else {
3926 _cmp(Src0RHi, Src1RFHi); 3913 _cmp(Src0RHi, Src1RFHi);
3927 _cmp(Src0RLo, Src1RFLo, CondARM32::EQ); 3914 _cmp(Src0RLo, Src1RFLo, CondARM32::EQ);
3928 } 3915 }
3929 } 3916 }
3930 3917
3931 return CondWhenTrue(TableIcmp64[Index].C1); 3918 return CondWhenTrue(TableIcmp64[Index].C1);
3932 } 3919 }
3933 3920
3934 Variable *Src0RLo, *Src0RHi; 3921 Variable *Src0RLo, *Src0RHi;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 // longer sequence. 3960 // longer sequence.
3974 // 3961 //
3975 // So, we are going with the GCC version since it's usually better (except 3962 // So, we are going with the GCC version since it's usually better (except
3976 // perhaps for eq/ne). We could revisit special-casing eq/ne later. 3963 // perhaps for eq/ne). We could revisit special-casing eq/ne later.
3977 if (TableIcmp64[Index].IsSigned) { 3964 if (TableIcmp64[Index].IsSigned) {
3978 Variable *ScratchReg = makeReg(IceType_i32); 3965 Variable *ScratchReg = makeReg(IceType_i32);
3979 _cmp(Src0RLo, Src1RFLo); 3966 _cmp(Src0RLo, Src1RFLo);
3980 _sbcs(ScratchReg, Src0RHi, Src1RFHi); 3967 _sbcs(ScratchReg, Src0RHi, Src1RFHi);
3981 // ScratchReg isn't going to be used, but we need the side-effect of 3968 // ScratchReg isn't going to be used, but we need the side-effect of
3982 // setting flags from this operation. 3969 // setting flags from this operation.
3983 Context.insert(InstFakeUse::create(Func, ScratchReg)); 3970 Context.insert<InstFakeUse>(ScratchReg);
3984 } else { 3971 } else {
3985 _cmp(Src0RHi, Src1RFHi); 3972 _cmp(Src0RHi, Src1RFHi);
3986 _cmp(Src0RLo, Src1RFLo, CondARM32::EQ); 3973 _cmp(Src0RLo, Src1RFLo, CondARM32::EQ);
3987 } 3974 }
3988 return CondWhenTrue(TableIcmp64[Index].C1); 3975 return CondWhenTrue(TableIcmp64[Index].C1);
3989 } 3976 }
3990 3977
3991 TargetARM32::CondWhenTrue 3978 TargetARM32::CondWhenTrue
3992 TargetARM32::lowerInt32IcmpCond(InstIcmp::ICond Condition, Operand *Src0, 3979 TargetARM32::lowerInt32IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
3993 Operand *Src1) { 3980 Operand *Src1) {
(...skipping 19 matching lines...) Expand all
4013 _cmn(Src0R, Src1F); 4000 _cmn(Src0R, Src1F);
4014 return CondWhenTrue(getIcmp32Mapping(Condition)); 4001 return CondWhenTrue(getIcmp32Mapping(Condition));
4015 } 4002 }
4016 4003
4017 Operand *Src1RF = Srcs.src1RF(this); 4004 Operand *Src1RF = Srcs.src1RF(this);
4018 if (!Srcs.swappedOperands()) { 4005 if (!Srcs.swappedOperands()) {
4019 _cmp(Src0R, Src1RF); 4006 _cmp(Src0R, Src1RF);
4020 } else { 4007 } else {
4021 Variable *T = makeReg(IceType_i32); 4008 Variable *T = makeReg(IceType_i32);
4022 _rsbs(T, Src0R, Src1RF); 4009 _rsbs(T, Src0R, Src1RF);
4023 Context.insert(InstFakeUse::create(Func, T)); 4010 Context.insert<InstFakeUse>(T);
4024 } 4011 }
4025 return CondWhenTrue(getIcmp32Mapping(Condition)); 4012 return CondWhenTrue(getIcmp32Mapping(Condition));
4026 } 4013 }
4027 4014
4028 TargetARM32::CondWhenTrue 4015 TargetARM32::CondWhenTrue
4029 TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0, 4016 TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
4030 Operand *Src1) { 4017 Operand *Src1) {
4031 Int32Operands Srcs(Src0, Src1); 4018 Int32Operands Srcs(Src0, Src1);
4032 const int32_t ShAmt = 32 - getScalarIntBitWidth(Src0->getType()); 4019 const int32_t ShAmt = 32 - getScalarIntBitWidth(Src0->getType());
4033 assert(ShAmt >= 0); 4020 assert(ShAmt >= 0);
4034 4021
4035 if (!Srcs.hasConstOperand()) { 4022 if (!Srcs.hasConstOperand()) {
4036 Variable *Src0R = makeReg(IceType_i32); 4023 Variable *Src0R = makeReg(IceType_i32);
4037 Operand *ShAmtImm = shAmtImm(ShAmt); 4024 Operand *ShAmtImm = shAmtImm(ShAmt);
4038 _lsl(Src0R, legalizeToReg(Src0), ShAmtImm); 4025 _lsl(Src0R, legalizeToReg(Src0), ShAmtImm);
4039 4026
4040 Variable *Src1R = legalizeToReg(Src1); 4027 Variable *Src1R = legalizeToReg(Src1);
4041 auto *Src1F = OperandARM32FlexReg::create(Func, IceType_i32, Src1R, 4028 auto *Src1F = OperandARM32FlexReg::create(Func, IceType_i32, Src1R,
4042 OperandARM32::LSL, ShAmtImm); 4029 OperandARM32::LSL, ShAmtImm);
4043 _cmp(Src0R, Src1F); 4030 _cmp(Src0R, Src1F);
4044 return CondWhenTrue(getIcmp32Mapping(Condition)); 4031 return CondWhenTrue(getIcmp32Mapping(Condition));
4045 } 4032 }
4046 4033
4047 const int32_t Value = Srcs.getConstantValue(); 4034 const int32_t Value = Srcs.getConstantValue();
4048 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) && Value == 0) { 4035 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) && Value == 0) {
4049 Operand *ShAmtImm = shAmtImm(ShAmt); 4036 Operand *ShAmtImm = shAmtImm(ShAmt);
4050 Variable *T = makeReg(IceType_i32); 4037 Variable *T = makeReg(IceType_i32);
4051 _lsls(T, Srcs.src0R(this), ShAmtImm); 4038 _lsls(T, Srcs.src0R(this), ShAmtImm);
4052 Context.insert(InstFakeUse::create(Func, T)); 4039 Context.insert<InstFakeUse>(T);
4053 return CondWhenTrue(getIcmp32Mapping(Condition)); 4040 return CondWhenTrue(getIcmp32Mapping(Condition));
4054 } 4041 }
4055 4042
4056 Variable *ConstR = makeReg(IceType_i32); 4043 Variable *ConstR = makeReg(IceType_i32);
4057 _mov(ConstR, 4044 _mov(ConstR,
4058 legalize(Ctx->getConstantInt32(Value << ShAmt), Legal_Reg | Legal_Flex)); 4045 legalize(Ctx->getConstantInt32(Value << ShAmt), Legal_Reg | Legal_Flex));
4059 Operand *NonConstF = OperandARM32FlexReg::create( 4046 Operand *NonConstF = OperandARM32FlexReg::create(
4060 Func, IceType_i32, Srcs.src0R(this), OperandARM32::LSL, 4047 Func, IceType_i32, Srcs.src0R(this), OperandARM32::LSL,
4061 Ctx->getConstantInt32(ShAmt)); 4048 Ctx->getConstantInt32(ShAmt));
4062 4049
4063 if (Srcs.swappedOperands()) { 4050 if (Srcs.swappedOperands()) {
4064 _cmp(ConstR, NonConstF); 4051 _cmp(ConstR, NonConstF);
4065 } else { 4052 } else {
4066 Variable *T = makeReg(IceType_i32); 4053 Variable *T = makeReg(IceType_i32);
4067 _rsbs(T, ConstR, NonConstF); 4054 _rsbs(T, ConstR, NonConstF);
4068 Context.insert(InstFakeUse::create(Func, T)); 4055 Context.insert<InstFakeUse>(T);
4069 } 4056 }
4070 return CondWhenTrue(getIcmp32Mapping(Condition)); 4057 return CondWhenTrue(getIcmp32Mapping(Condition));
4071 } 4058 }
4072 4059
4073 TargetARM32::CondWhenTrue TargetARM32::lowerIcmpCond(const InstIcmp *Inst) { 4060 TargetARM32::CondWhenTrue TargetARM32::lowerIcmpCond(const InstIcmp *Inst) {
4074 assert(Inst->getSrc(0)->getType() != IceType_i1); 4061 assert(Inst->getSrc(0)->getType() != IceType_i1);
4075 assert(Inst->getSrc(1)->getType() != IceType_i1); 4062 assert(Inst->getSrc(1)->getType() != IceType_i1);
4076 4063
4077 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); 4064 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
4078 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); 4065 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4118 case IceType_i64: 4105 case IceType_i64:
4119 return lowerInt64IcmpCond(Condition, Src0, Src1); 4106 return lowerInt64IcmpCond(Condition, Src0, Src1);
4120 } 4107 }
4121 } 4108 }
4122 4109
4123 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { 4110 void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
4124 Variable *Dest = Inst->getDest(); 4111 Variable *Dest = Inst->getDest();
4125 4112
4126 if (isVectorType(Dest->getType())) { 4113 if (isVectorType(Dest->getType())) {
4127 Variable *T = makeReg(Dest->getType()); 4114 Variable *T = makeReg(Dest->getType());
4128 Context.insert(InstFakeDef::create(Func, T)); 4115 Context.insert<InstFakeDef>(T);
4129 _mov(Dest, T); 4116 _mov(Dest, T);
4130 UnimplementedError(Func->getContext()->getFlags()); 4117 UnimplementedError(Func->getContext()->getFlags());
4131 return; 4118 return;
4132 } 4119 }
4133 4120
4134 Operand *_0 = 4121 Operand *_0 =
4135 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 4122 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4136 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); 4123 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex);
4137 Variable *T = makeReg(IceType_i1); 4124 Variable *T = makeReg(IceType_i1);
4138 4125
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 ValueReg = makeReg(DestTy); 4199 ValueReg = makeReg(DestTy);
4213 ValueHiReg = nullptr; 4200 ValueHiReg = nullptr;
4214 ValueLoReg = ValueReg; 4201 ValueLoReg = ValueReg;
4215 4202
4216 TmpReg = makeReg(DestTy); 4203 TmpReg = makeReg(DestTy);
4217 TmpHiReg = nullptr; 4204 TmpHiReg = nullptr;
4218 TmpLoReg = TmpReg; 4205 TmpLoReg = TmpReg;
4219 } 4206 }
4220 4207
4221 if (DestTy == IceType_i64) { 4208 if (DestTy == IceType_i64) {
4222 Context.insert(InstFakeDef::create(Func, Value)); 4209 Context.insert<InstFakeDef>(Value);
4223 } 4210 }
4224 lowerAssign(InstAssign::create(Func, Value, Val)); 4211 lowerAssign(InstAssign::create(Func, Value, Val));
4225 4212
4226 Variable *PtrVar = Func->makeVariable(IceType_i32); 4213 Variable *PtrVar = Func->makeVariable(IceType_i32);
4227 lowerAssign(InstAssign::create(Func, PtrVar, Ptr)); 4214 lowerAssign(InstAssign::create(Func, PtrVar, Ptr));
4228 4215
4229 _dmb(); 4216 _dmb();
4230 Context.insert(Retry); 4217 Context.insert(Retry);
4231 Mem = formMemoryOperand(PtrVar, DestTy); 4218 Mem = formMemoryOperand(PtrVar, DestTy);
4232 if (DestTy == IceType_i64) { 4219 if (DestTy == IceType_i64) {
4233 Context.insert(InstFakeDef::create(Func, ValueReg, Value)); 4220 Context.insert<InstFakeDef>(ValueReg, Value);
4234 } 4221 }
4235 lowerAssign(InstAssign::create(Func, ValueReg, Value)); 4222 lowerAssign(InstAssign::create(Func, ValueReg, Value));
4236 if (DestTy == IceType_i8 || DestTy == IceType_i16) { 4223 if (DestTy == IceType_i8 || DestTy == IceType_i16) {
4237 _uxt(ValueReg, ValueReg); 4224 _uxt(ValueReg, ValueReg);
4238 } 4225 }
4239 _ldrex(PtrContentsReg, Mem); 4226 _ldrex(PtrContentsReg, Mem);
4240 4227
4241 if (DestTy == IceType_i64) { 4228 if (DestTy == IceType_i64) {
4242 Context.insert(InstFakeDef::create(Func, TmpReg, ValueReg)); 4229 Context.insert<InstFakeDef>(TmpReg, ValueReg);
4243 } 4230 }
4244 switch (Operation) { 4231 switch (Operation) {
4245 default: 4232 default:
4246 Func->setError("Unknown AtomicRMW operation"); 4233 Func->setError("Unknown AtomicRMW operation");
4247 return; 4234 return;
4248 case Intrinsics::AtomicAdd: 4235 case Intrinsics::AtomicAdd:
4249 if (DestTy == IceType_i64) { 4236 if (DestTy == IceType_i64) {
4250 _adds(TmpLoReg, PtrContentsLoReg, ValueLoReg); 4237 _adds(TmpLoReg, PtrContentsLoReg, ValueLoReg);
4251 _adc(TmpHiReg, PtrContentsHiReg, ValueHiReg); 4238 _adc(TmpHiReg, PtrContentsHiReg, ValueHiReg);
4252 } else { 4239 } else {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4286 } 4273 }
4287 break; 4274 break;
4288 } 4275 }
4289 _strex(Success, TmpReg, Mem); 4276 _strex(Success, TmpReg, Mem);
4290 _cmp(Success, _0); 4277 _cmp(Success, _0);
4291 _br(Retry, CondARM32::NE); 4278 _br(Retry, CondARM32::NE);
4292 4279
4293 // The following fake-uses ensure that Subzero will not clobber them in the 4280 // The following fake-uses ensure that Subzero will not clobber them in the
4294 // load-linked/store-conditional loop above. We might have to spill them, but 4281 // load-linked/store-conditional loop above. We might have to spill them, but
4295 // spilling is preferable over incorrect behavior. 4282 // spilling is preferable over incorrect behavior.
4296 Context.insert(InstFakeUse::create(Func, PtrVar)); 4283 Context.insert<InstFakeUse>(PtrVar);
4297 if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) { 4284 if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) {
4298 Context.insert(InstFakeUse::create(Func, Value64->getHi())); 4285 Context.insert<InstFakeUse>(Value64->getHi());
4299 Context.insert(InstFakeUse::create(Func, Value64->getLo())); 4286 Context.insert<InstFakeUse>(Value64->getLo());
4300 } else { 4287 } else {
4301 Context.insert(InstFakeUse::create(Func, Value)); 4288 Context.insert<InstFakeUse>(Value);
4302 } 4289 }
4303 _dmb(); 4290 _dmb();
4304 if (DestTy == IceType_i8 || DestTy == IceType_i16) { 4291 if (DestTy == IceType_i8 || DestTy == IceType_i16) {
4305 _uxt(PtrContentsReg, PtrContentsReg); 4292 _uxt(PtrContentsReg, PtrContentsReg);
4306 } 4293 }
4307 4294
4308 if (DestTy == IceType_i64) { 4295 if (DestTy == IceType_i64) {
4309 Context.insert(InstFakeUse::create(Func, PtrContentsReg)); 4296 Context.insert<InstFakeUse>(PtrContentsReg);
4310 } 4297 }
4311 lowerAssign(InstAssign::create(Func, Dest, PtrContentsReg)); 4298 lowerAssign(InstAssign::create(Func, Dest, PtrContentsReg));
4312 if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) { 4299 if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
4313 Context.insert(InstFakeUse::create(Func, Dest64->getLo())); 4300 Context.insert<InstFakeUse>(Dest64->getLo());
4314 Context.insert(InstFakeUse::create(Func, Dest64->getHi())); 4301 Context.insert<InstFakeUse>(Dest64->getHi());
4315 } else { 4302 } else {
4316 Context.insert(InstFakeUse::create(Func, Dest)); 4303 Context.insert<InstFakeUse>(Dest);
4317 } 4304 }
4318 } 4305 }
4319 4306
4320 void TargetARM32::postambleCtpop64(const InstCall *Instr) { 4307 void TargetARM32::postambleCtpop64(const InstCall *Instr) {
4321 Operand *Arg0 = Instr->getArg(0); 4308 Operand *Arg0 = Instr->getArg(0);
4322 if (isInt32Asserting32Or64(Arg0->getType())) { 4309 if (isInt32Asserting32Or64(Arg0->getType())) {
4323 return; 4310 return;
4324 } 4311 }
4325 // The popcount helpers always return 32-bit values, while the intrinsic's 4312 // The popcount helpers always return 32-bit values, while the intrinsic's
4326 // signature matches some 64-bit platform's native instructions and expect to 4313 // signature matches some 64-bit platform's native instructions and expect to
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4384 _ldrex(T, formMemoryOperand(Instr->getArg(0), IceType_i64)); 4371 _ldrex(T, formMemoryOperand(Instr->getArg(0), IceType_i64));
4385 } else { 4372 } else {
4386 T = makeReg(DestTy); 4373 T = makeReg(DestTy);
4387 _ldr(T, formMemoryOperand(Instr->getArg(0), DestTy)); 4374 _ldr(T, formMemoryOperand(Instr->getArg(0), DestTy));
4388 } 4375 }
4389 _dmb(); 4376 _dmb();
4390 lowerAssign(InstAssign::create(Func, Dest, T)); 4377 lowerAssign(InstAssign::create(Func, Dest, T));
4391 // Make sure the atomic load isn't elided when unused, by adding a FakeUse. 4378 // Make sure the atomic load isn't elided when unused, by adding a FakeUse.
4392 // Since lowerLoad may fuse the load w/ an arithmetic instruction, insert 4379 // Since lowerLoad may fuse the load w/ an arithmetic instruction, insert
4393 // the FakeUse on the last-inserted instruction's dest. 4380 // the FakeUse on the last-inserted instruction's dest.
4394 Context.insert( 4381 Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
4395 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
4396 return; 4382 return;
4397 } 4383 }
4398 case Intrinsics::AtomicStore: { 4384 case Intrinsics::AtomicStore: {
4399 // We require the memory address to be naturally aligned. Given that is the 4385 // We require the memory address to be naturally aligned. Given that is the
4400 // case, then normal loads are atomic. 4386 // case, then normal loads are atomic.
4401 if (!Intrinsics::isMemoryOrderValid( 4387 if (!Intrinsics::isMemoryOrderValid(
4402 ID, getConstantMemoryOrder(Instr->getArg(2)))) { 4388 ID, getConstantMemoryOrder(Instr->getArg(2)))) {
4403 Func->setError("Unexpected memory ordering for AtomicStore"); 4389 Func->setError("Unexpected memory ordering for AtomicStore");
4404 return; 4390 return;
4405 } 4391 }
(...skipping 25 matching lines...) Expand all
4431 auto *Retry = InstARM32Label::create(Func, this); 4417 auto *Retry = InstARM32Label::create(Func, this);
4432 Variable64On32 *NewReg = makeI64RegPair(); 4418 Variable64On32 *NewReg = makeI64RegPair();
4433 ValueVar->initHiLo(Func); 4419 ValueVar->initHiLo(Func);
4434 ValueVar->mustNotHaveReg(); 4420 ValueVar->mustNotHaveReg();
4435 4421
4436 _dmb(); 4422 _dmb();
4437 lowerAssign(InstAssign::create(Func, ValueVar, Value)); 4423 lowerAssign(InstAssign::create(Func, ValueVar, Value));
4438 lowerAssign(InstAssign::create(Func, AddrVar, Addr)); 4424 lowerAssign(InstAssign::create(Func, AddrVar, Addr));
4439 4425
4440 Context.insert(Retry); 4426 Context.insert(Retry);
4441 Context.insert(InstFakeDef::create(Func, NewReg)); 4427 Context.insert<InstFakeDef>(NewReg);
4442 lowerAssign(InstAssign::create(Func, NewReg, ValueVar)); 4428 lowerAssign(InstAssign::create(Func, NewReg, ValueVar));
4443 Mem = formMemoryOperand(AddrVar, IceType_i64); 4429 Mem = formMemoryOperand(AddrVar, IceType_i64);
4444 _ldrex(Tmp, Mem); 4430 _ldrex(Tmp, Mem);
4445 // This fake-use both prevents the ldrex from being dead-code eliminated, 4431 // This fake-use both prevents the ldrex from being dead-code eliminated,
4446 // while also keeping liveness happy about all defs being used. 4432 // while also keeping liveness happy about all defs being used.
4447 Context.insert( 4433 Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
4448 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
4449 _strex(Success, NewReg, Mem); 4434 _strex(Success, NewReg, Mem);
4450 _cmp(Success, _0); 4435 _cmp(Success, _0);
4451 _br(Retry, CondARM32::NE); 4436 _br(Retry, CondARM32::NE);
4452 4437
4453 Context.insert(InstFakeUse::create(Func, ValueVar->getLo())); 4438 Context.insert<InstFakeUse>(ValueVar->getLo());
4454 Context.insert(InstFakeUse::create(Func, ValueVar->getHi())); 4439 Context.insert<InstFakeUse>(ValueVar->getHi());
4455 Context.insert(InstFakeUse::create(Func, AddrVar)); 4440 Context.insert<InstFakeUse>(AddrVar);
4456 _dmb(); 4441 _dmb();
4457 return; 4442 return;
4458 } 4443 }
4459 // non-64-bit stores are atomically as long as the address is aligned. This 4444 // non-64-bit stores are atomically as long as the address is aligned. This
4460 // is PNaCl, so addresses are aligned. 4445 // is PNaCl, so addresses are aligned.
4461 Variable *T = makeReg(ValueTy); 4446 Variable *T = makeReg(ValueTy);
4462 4447
4463 _dmb(); 4448 _dmb();
4464 lowerAssign(InstAssign::create(Func, T, Value)); 4449 lowerAssign(InstAssign::create(Func, T, Value));
4465 _str(T, formMemoryOperand(Addr, ValueTy)); 4450 _str(T, formMemoryOperand(Addr, ValueTy));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 } else { 4528 } else {
4544 TmpReg = makeReg(DestTy); 4529 TmpReg = makeReg(DestTy);
4545 New = Func->makeVariable(DestTy); 4530 New = Func->makeVariable(DestTy);
4546 NewReg = makeReg(DestTy); 4531 NewReg = makeReg(DestTy);
4547 Expected = Func->makeVariable(DestTy); 4532 Expected = Func->makeVariable(DestTy);
4548 ExpectedReg = makeReg(DestTy); 4533 ExpectedReg = makeReg(DestTy);
4549 } 4534 }
4550 4535
4551 Mem = formMemoryOperand(Instr->getArg(0), DestTy); 4536 Mem = formMemoryOperand(Instr->getArg(0), DestTy);
4552 if (DestTy == IceType_i64) { 4537 if (DestTy == IceType_i64) {
4553 Context.insert(InstFakeDef::create(Func, Expected)); 4538 Context.insert<InstFakeDef>(Expected);
4554 } 4539 }
4555 lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1))); 4540 lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1)));
4556 if (DestTy == IceType_i64) { 4541 if (DestTy == IceType_i64) {
4557 Context.insert(InstFakeDef::create(Func, New)); 4542 Context.insert<InstFakeDef>(New);
4558 } 4543 }
4559 lowerAssign(InstAssign::create(Func, New, Instr->getArg(2))); 4544 lowerAssign(InstAssign::create(Func, New, Instr->getArg(2)));
4560 _dmb(); 4545 _dmb();
4561 4546
4562 Context.insert(Retry); 4547 Context.insert(Retry);
4563 if (DestTy == IceType_i64) { 4548 if (DestTy == IceType_i64) {
4564 Context.insert(InstFakeDef::create(Func, ExpectedReg, Expected)); 4549 Context.insert<InstFakeDef>(ExpectedReg, Expected);
4565 } 4550 }
4566 lowerAssign(InstAssign::create(Func, ExpectedReg, Expected)); 4551 lowerAssign(InstAssign::create(Func, ExpectedReg, Expected));
4567 if (DestTy == IceType_i64) { 4552 if (DestTy == IceType_i64) {
4568 Context.insert(InstFakeDef::create(Func, NewReg, New)); 4553 Context.insert<InstFakeDef>(NewReg, New);
4569 } 4554 }
4570 lowerAssign(InstAssign::create(Func, NewReg, New)); 4555 lowerAssign(InstAssign::create(Func, NewReg, New));
4571 4556
4572 _ldrex(TmpReg, Mem); 4557 _ldrex(TmpReg, Mem);
4573 Context.insert( 4558 Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
4574 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
4575 if (DestTy == IceType_i64) { 4559 if (DestTy == IceType_i64) {
4576 auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg); 4560 auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg);
4577 auto *ExpectedReg64 = llvm::cast<Variable64On32>(ExpectedReg); 4561 auto *ExpectedReg64 = llvm::cast<Variable64On32>(ExpectedReg);
4578 // lowerAssign above has added fake-defs for TmpReg and ExpectedReg. Let's 4562 // lowerAssign above has added fake-defs for TmpReg and ExpectedReg. Let's
4579 // keep liveness happy, shall we? 4563 // keep liveness happy, shall we?
4580 Context.insert(InstFakeUse::create(Func, TmpReg)); 4564 Context.insert<InstFakeUse>(TmpReg);
4581 Context.insert(InstFakeUse::create(Func, ExpectedReg)); 4565 Context.insert<InstFakeUse>(ExpectedReg);
4582 _cmp(TmpReg64->getHi(), ExpectedReg64->getHi()); 4566 _cmp(TmpReg64->getHi(), ExpectedReg64->getHi());
4583 _cmp(TmpReg64->getLo(), ExpectedReg64->getLo(), CondARM32::EQ); 4567 _cmp(TmpReg64->getLo(), ExpectedReg64->getLo(), CondARM32::EQ);
4584 } else { 4568 } else {
4585 _cmp(TmpReg, ExpectedReg); 4569 _cmp(TmpReg, ExpectedReg);
4586 } 4570 }
4587 _strex(Success, NewReg, Mem, CondARM32::EQ); 4571 _strex(Success, NewReg, Mem, CondARM32::EQ);
4588 if (DestTy == IceType_i64) { 4572 if (DestTy == IceType_i64) {
4589 auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg); 4573 auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg);
4590 auto *Expected64 = llvm::cast<Variable64On32>(Expected); 4574 auto *Expected64 = llvm::cast<Variable64On32>(Expected);
4591 _mov_redefined(Expected64->getHi(), TmpReg64->getHi(), CondARM32::NE); 4575 _mov_redefined(Expected64->getHi(), TmpReg64->getHi(), CondARM32::NE);
4592 _mov_redefined(Expected64->getLo(), TmpReg64->getLo(), CondARM32::NE); 4576 _mov_redefined(Expected64->getLo(), TmpReg64->getLo(), CondARM32::NE);
4593 auto *FakeDef = InstFakeDef::create(Func, Expected, TmpReg); 4577 Context.insert<InstFakeDef>(Expected, TmpReg);
4594 Context.insert(FakeDef); 4578 _set_dest_redefined();
4595 FakeDef->setDestRedefined();
4596 } else { 4579 } else {
4597 _mov_redefined(Expected, TmpReg, CondARM32::NE); 4580 _mov_redefined(Expected, TmpReg, CondARM32::NE);
4598 } 4581 }
4599 _cmp(Success, _0, CondARM32::EQ); 4582 _cmp(Success, _0, CondARM32::EQ);
4600 _br(Retry, CondARM32::NE); 4583 _br(Retry, CondARM32::NE);
4601 _dmb(); 4584 _dmb();
4602 lowerAssign(InstAssign::create(Func, Dest, Expected)); 4585 lowerAssign(InstAssign::create(Func, Dest, Expected));
4603 Context.insert(InstFakeUse::create(Func, Expected)); 4586 Context.insert<InstFakeUse>(Expected);
4604 if (auto *New64 = llvm::dyn_cast<Variable64On32>(New)) { 4587 if (auto *New64 = llvm::dyn_cast<Variable64On32>(New)) {
4605 Context.insert(InstFakeUse::create(Func, New64->getLo())); 4588 Context.insert<InstFakeUse>(New64->getLo());
4606 Context.insert(InstFakeUse::create(Func, New64->getHi())); 4589 Context.insert<InstFakeUse>(New64->getHi());
4607 } else { 4590 } else {
4608 Context.insert(InstFakeUse::create(Func, New)); 4591 Context.insert<InstFakeUse>(New);
4609 } 4592 }
4610 return; 4593 return;
4611 } 4594 }
4612 case Intrinsics::AtomicRMW: { 4595 case Intrinsics::AtomicRMW: {
4613 if (!Intrinsics::isMemoryOrderValid( 4596 if (!Intrinsics::isMemoryOrderValid(
4614 ID, getConstantMemoryOrder(Instr->getArg(3)))) { 4597 ID, getConstantMemoryOrder(Instr->getArg(3)))) {
4615 Func->setError("Unexpected memory ordering for AtomicRMW"); 4598 Func->setError("Unexpected memory ordering for AtomicRMW");
4616 return; 4599 return;
4617 } 4600 }
4618 lowerAtomicRMW( 4601 lowerAtomicRMW(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4690 ValLoR = T; 4673 ValLoR = T;
4691 } 4674 }
4692 lowerCLZ(Dest, ValLoR, ValHiR); 4675 lowerCLZ(Dest, ValLoR, ValHiR);
4693 return; 4676 return;
4694 } 4677 }
4695 case Intrinsics::Fabs: { 4678 case Intrinsics::Fabs: {
4696 Type DestTy = Dest->getType(); 4679 Type DestTy = Dest->getType();
4697 Variable *T = makeReg(DestTy); 4680 Variable *T = makeReg(DestTy);
4698 if (isVectorType(DestTy)) { 4681 if (isVectorType(DestTy)) {
4699 // Add a fake def to keep liveness consistent in the meantime. 4682 // Add a fake def to keep liveness consistent in the meantime.
4700 Context.insert(InstFakeDef::create(Func, T)); 4683 Context.insert<InstFakeDef>(T);
4701 _mov(Dest, T); 4684 _mov(Dest, T);
4702 UnimplementedError(Func->getContext()->getFlags()); 4685 UnimplementedError(Func->getContext()->getFlags());
4703 return; 4686 return;
4704 } 4687 }
4705 _vabs(T, legalizeToReg(Instr->getArg(0))); 4688 _vabs(T, legalizeToReg(Instr->getArg(0)));
4706 _mov(Dest, T); 4689 _mov(Dest, T);
4707 return; 4690 return;
4708 } 4691 }
4709 case Intrinsics::Longjmp: { 4692 case Intrinsics::Longjmp: {
4710 llvm::report_fatal_error("longjmp should have been prelowered."); 4693 llvm::report_fatal_error("longjmp should have been prelowered.");
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
5155 // [OffsetReg{, LSL Shamt}{, #OffsetImm}] is not legal in ARM, so we have to 5138 // [OffsetReg{, LSL Shamt}{, #OffsetImm}] is not legal in ARM, so we have to
5156 // legalize the addressing mode to [BaseReg, OffsetReg{, LSL Shamt}]. 5139 // legalize the addressing mode to [BaseReg, OffsetReg{, LSL Shamt}].
5157 // Instead of a zeroed BaseReg, we initialize it with OffsetImm: 5140 // Instead of a zeroed BaseReg, we initialize it with OffsetImm:
5158 // 5141 //
5159 // [OffsetReg{, LSL Shamt}{, #OffsetImm}] -> 5142 // [OffsetReg{, LSL Shamt}{, #OffsetImm}] ->
5160 // mov BaseReg, #OffsetImm 5143 // mov BaseReg, #OffsetImm
5161 // use of [BaseReg, OffsetReg{, LSL Shamt}] 5144 // use of [BaseReg, OffsetReg{, LSL Shamt}]
5162 // 5145 //
5163 const Type PointerType = getPointerType(); 5146 const Type PointerType = getPointerType();
5164 BaseVar = makeReg(PointerType); 5147 BaseVar = makeReg(PointerType);
5165 Context.insert( 5148 Context.insert<InstAssign>(BaseVar, Ctx->getConstantInt32(OffsetImm));
5166 InstAssign::create(Func, BaseVar, Ctx->getConstantInt32(OffsetImm)));
5167 OffsetImm = 0; 5149 OffsetImm = 0;
5168 } else if (OffsetImm != 0) { 5150 } else if (OffsetImm != 0) {
5169 // ARM Ldr/Str instructions have limited range immediates. The formation 5151 // ARM Ldr/Str instructions have limited range immediates. The formation
5170 // loop above materialized an Immediate carelessly, so we ensure the 5152 // loop above materialized an Immediate carelessly, so we ensure the
5171 // generated offset is sane. 5153 // generated offset is sane.
5172 const int32_t PositiveOffset = OffsetImm > 0 ? OffsetImm : -OffsetImm; 5154 const int32_t PositiveOffset = OffsetImm > 0 ? OffsetImm : -OffsetImm;
5173 const InstArithmetic::OpKind Op = 5155 const InstArithmetic::OpKind Op =
5174 OffsetImm > 0 ? InstArithmetic::Add : InstArithmetic::Sub; 5156 OffsetImm > 0 ? InstArithmetic::Add : InstArithmetic::Sub;
5175 5157
5176 if (!CanHaveImm || !isLegalMemOffset(Ty, OffsetImm) || 5158 if (!CanHaveImm || !isLegalMemOffset(Ty, OffsetImm) ||
(...skipping 10 matching lines...) Expand all
5187 // here and don't form any address mode. 5169 // here and don't form any address mode.
5188 return nullptr; 5170 return nullptr;
5189 } 5171 }
5190 // We formed [Base, Offset {, LSL Amnt}, #const]. Oops. Legalize it to 5172 // We formed [Base, Offset {, LSL Amnt}, #const]. Oops. Legalize it to
5191 // 5173 //
5192 // [Base, Offset, {LSL amount}, #const] -> 5174 // [Base, Offset, {LSL amount}, #const] ->
5193 // add T, Base, #const 5175 // add T, Base, #const
5194 // use of [T, Offset {, LSL amount}] 5176 // use of [T, Offset {, LSL amount}]
5195 const Type PointerType = getPointerType(); 5177 const Type PointerType = getPointerType();
5196 Variable *T = makeReg(PointerType); 5178 Variable *T = makeReg(PointerType);
5197 Context.insert(InstArithmetic::create( 5179 Context.insert<InstArithmetic>(Op, T, BaseVar,
5198 Func, Op, T, BaseVar, Ctx->getConstantInt32(PositiveOffset))); 5180 Ctx->getConstantInt32(PositiveOffset));
5199 BaseVar = T; 5181 BaseVar = T;
5200 OffsetImm = 0; 5182 OffsetImm = 0;
5201 } 5183 }
5202 } 5184 }
5203 5185
5204 assert(BaseVar != nullptr); 5186 assert(BaseVar != nullptr);
5205 assert(OffsetImm == 0 || OffsetReg == nullptr); 5187 assert(OffsetImm == 0 || OffsetReg == nullptr);
5206 assert(OffsetReg == nullptr || CanHaveIndex); 5188 assert(OffsetReg == nullptr || CanHaveIndex);
5207 assert(OffsetImm < 0 ? (ValidImmMask & -OffsetImm) == -OffsetImm 5189 assert(OffsetImm < 0 ? (ValidImmMask & -OffsetImm) == -OffsetImm
5208 : (ValidImmMask & OffsetImm) == OffsetImm); 5190 : (ValidImmMask & OffsetImm) == OffsetImm);
5209 5191
5210 if (OffsetReg != nullptr) { 5192 if (OffsetReg != nullptr) {
5211 Variable *OffsetR = makeReg(getPointerType()); 5193 Variable *OffsetR = makeReg(getPointerType());
5212 Context.insert(InstAssign::create(Func, OffsetR, OffsetReg)); 5194 Context.insert<InstAssign>(OffsetR, OffsetReg);
5213 return OperandARM32Mem::create(Func, Ty, BaseVar, OffsetR, ShiftKind, 5195 return OperandARM32Mem::create(Func, Ty, BaseVar, OffsetR, ShiftKind,
5214 OffsetRegShamt); 5196 OffsetRegShamt);
5215 } 5197 }
5216 5198
5217 return OperandARM32Mem::create( 5199 return OperandARM32Mem::create(
5218 Func, Ty, BaseVar, 5200 Func, Ty, BaseVar,
5219 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(OffsetImm))); 5201 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(OffsetImm)));
5220 } 5202 }
5221 5203
5222 void TargetARM32::doAddressOptLoad() { 5204 void TargetARM32::doAddressOptLoad() {
5223 Inst *Instr = Context.getCur(); 5205 Inst *Instr = Context.getCur();
5224 assert(llvm::isa<InstLoad>(Instr)); 5206 assert(llvm::isa<InstLoad>(Instr));
5225 Variable *Dest = Instr->getDest(); 5207 Variable *Dest = Instr->getDest();
5226 Operand *Addr = Instr->getSrc(0); 5208 Operand *Addr = Instr->getSrc(0);
5227 if (OperandARM32Mem *Mem = 5209 if (OperandARM32Mem *Mem =
5228 formAddressingMode(Dest->getType(), Func, Instr, Addr)) { 5210 formAddressingMode(Dest->getType(), Func, Instr, Addr)) {
5229 Instr->setDeleted(); 5211 Instr->setDeleted();
5230 Context.insert(InstLoad::create(Func, Dest, Mem)); 5212 Context.insert<InstLoad>(Dest, Mem);
5231 } 5213 }
5232 } 5214 }
5233 5215
5234 void TargetARM32::randomlyInsertNop(float Probability, 5216 void TargetARM32::randomlyInsertNop(float Probability,
5235 RandomNumberGenerator &RNG) { 5217 RandomNumberGenerator &RNG) {
5236 RandomNumberGeneratorWrapper RNGW(RNG); 5218 RandomNumberGeneratorWrapper RNGW(RNG);
5237 if (RNGW.getTrueWithProbability(Probability)) { 5219 if (RNGW.getTrueWithProbability(Probability)) {
5238 UnimplementedError(Func->getContext()->getFlags()); 5220 UnimplementedError(Func->getContext()->getFlags());
5239 } 5221 }
5240 } 5222 }
5241 5223
5242 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) { 5224 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) {
5243 Func->setError("Phi found in regular instruction list"); 5225 Func->setError("Phi found in regular instruction list");
5244 } 5226 }
5245 5227
5246 void TargetARM32::lowerRet(const InstRet *Inst) { 5228 void TargetARM32::lowerRet(const InstRet *Inst) {
5247 Variable *Reg = nullptr; 5229 Variable *Reg = nullptr;
5248 if (Inst->hasRetValue()) { 5230 if (Inst->hasRetValue()) {
5249 Operand *Src0 = Inst->getRetValue(); 5231 Operand *Src0 = Inst->getRetValue();
5250 Type Ty = Src0->getType(); 5232 Type Ty = Src0->getType();
5251 if (Ty == IceType_i64) { 5233 if (Ty == IceType_i64) {
5252 Src0 = legalizeUndef(Src0); 5234 Src0 = legalizeUndef(Src0);
5253 Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0); 5235 Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0);
5254 Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1); 5236 Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1);
5255 Reg = R0; 5237 Reg = R0;
5256 Context.insert(InstFakeUse::create(Func, R1)); 5238 Context.insert<InstFakeUse>(R1);
5257 } else if (Ty == IceType_f32) { 5239 } else if (Ty == IceType_f32) {
5258 Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0); 5240 Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0);
5259 Reg = S0; 5241 Reg = S0;
5260 } else if (Ty == IceType_f64) { 5242 } else if (Ty == IceType_f64) {
5261 Variable *D0 = legalizeToReg(Src0, RegARM32::Reg_d0); 5243 Variable *D0 = legalizeToReg(Src0, RegARM32::Reg_d0);
5262 Reg = D0; 5244 Reg = D0;
5263 } else if (isVectorType(Src0->getType())) { 5245 } else if (isVectorType(Src0->getType())) {
5264 Variable *Q0 = legalizeToReg(Src0, RegARM32::Reg_q0); 5246 Variable *Q0 = legalizeToReg(Src0, RegARM32::Reg_q0);
5265 Reg = Q0; 5247 Reg = Q0;
5266 } else { 5248 } else {
5267 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex); 5249 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex);
5268 Reg = makeReg(Src0F->getType(), RegARM32::Reg_r0); 5250 Reg = makeReg(Src0F->getType(), RegARM32::Reg_r0);
5269 _mov(Reg, Src0F, CondARM32::AL); 5251 _mov(Reg, Src0F, CondARM32::AL);
5270 } 5252 }
5271 } 5253 }
5272 // Add a ret instruction even if sandboxing is enabled, because addEpilog 5254 // Add a ret instruction even if sandboxing is enabled, because addEpilog
5273 // explicitly looks for a ret instruction as a marker for where to insert the 5255 // explicitly looks for a ret instruction as a marker for where to insert the
5274 // frame removal instructions. addEpilog is responsible for restoring the 5256 // frame removal instructions. addEpilog is responsible for restoring the
5275 // "lr" register as needed prior to this ret instruction. 5257 // "lr" register as needed prior to this ret instruction.
5276 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg); 5258 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg);
5277 5259
5278 // Add a fake use of sp to make sure sp stays alive for the entire function. 5260 // Add a fake use of sp to make sure sp stays alive for the entire function.
5279 // Otherwise post-call sp adjustments get dead-code eliminated. 5261 // Otherwise post-call sp adjustments get dead-code eliminated.
5280 // TODO: Are there more places where the fake use should be inserted? E.g. 5262 // TODO: Are there more places where the fake use should be inserted? E.g.
5281 // "void f(int n){while(1) g(n);}" may not have a ret instruction. 5263 // "void f(int n){while(1) g(n);}" may not have a ret instruction.
5282 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 5264 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
5283 Context.insert(InstFakeUse::create(Func, SP)); 5265 Context.insert<InstFakeUse>(SP);
5284 } 5266 }
5285 5267
5286 void TargetARM32::lowerSelect(const InstSelect *Inst) { 5268 void TargetARM32::lowerSelect(const InstSelect *Inst) {
5287 Variable *Dest = Inst->getDest(); 5269 Variable *Dest = Inst->getDest();
5288 Type DestTy = Dest->getType(); 5270 Type DestTy = Dest->getType();
5289 Operand *SrcT = Inst->getTrueOperand(); 5271 Operand *SrcT = Inst->getTrueOperand();
5290 Operand *SrcF = Inst->getFalseOperand(); 5272 Operand *SrcF = Inst->getFalseOperand();
5291 Operand *Condition = Inst->getCondition(); 5273 Operand *Condition = Inst->getCondition();
5292 5274
5293 if (isVectorType(DestTy)) { 5275 if (isVectorType(DestTy)) {
5294 Variable *T = makeReg(DestTy); 5276 Variable *T = makeReg(DestTy);
5295 Context.insert(InstFakeDef::create(Func, T)); 5277 Context.insert<InstFakeDef>(T);
5296 _mov(Dest, T); 5278 _mov(Dest, T);
5297 UnimplementedError(Func->getContext()->getFlags()); 5279 UnimplementedError(Func->getContext()->getFlags());
5298 return; 5280 return;
5299 } 5281 }
5300 5282
5301 lowerInt1ForSelect(Dest, Condition, legalizeUndef(SrcT), legalizeUndef(SrcF)); 5283 lowerInt1ForSelect(Dest, Condition, legalizeUndef(SrcT), legalizeUndef(SrcF));
5302 } 5284 }
5303 5285
5304 void TargetARM32::lowerStore(const InstStore *Inst) { 5286 void TargetARM32::lowerStore(const InstStore *Inst) {
5305 Operand *Value = Inst->getData(); 5287 Operand *Value = Inst->getData();
(...skipping 14 matching lines...) Expand all
5320 } 5302 }
5321 5303
5322 void TargetARM32::doAddressOptStore() { 5304 void TargetARM32::doAddressOptStore() {
5323 Inst *Instr = Context.getCur(); 5305 Inst *Instr = Context.getCur();
5324 assert(llvm::isa<InstStore>(Instr)); 5306 assert(llvm::isa<InstStore>(Instr));
5325 Operand *Src = Instr->getSrc(0); 5307 Operand *Src = Instr->getSrc(0);
5326 Operand *Addr = Instr->getSrc(1); 5308 Operand *Addr = Instr->getSrc(1);
5327 if (OperandARM32Mem *Mem = 5309 if (OperandARM32Mem *Mem =
5328 formAddressingMode(Src->getType(), Func, Instr, Addr)) { 5310 formAddressingMode(Src->getType(), Func, Instr, Addr)) {
5329 Instr->setDeleted(); 5311 Instr->setDeleted();
5330 Context.insert(InstStore::create(Func, Src, Mem)); 5312 Context.insert<InstStore>(Src, Mem);
5331 } 5313 }
5332 } 5314 }
5333 5315
5334 void TargetARM32::lowerSwitch(const InstSwitch *Inst) { 5316 void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
5335 // This implements the most naive possible lowering. 5317 // This implements the most naive possible lowering.
5336 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default 5318 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
5337 Operand *Src0 = Inst->getComparison(); 5319 Operand *Src0 = Inst->getComparison();
5338 SizeT NumCases = Inst->getNumCases(); 5320 SizeT NumCases = Inst->getNumCases();
5339 if (Src0->getType() == IceType_i64) { 5321 if (Src0->getType() == IceType_i64) {
5340 Src0 = legalizeUndef(Src0); 5322 Src0 = legalizeUndef(Src0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5378 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) { 5360 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
5379 _trap(); 5361 _trap();
5380 } 5362 }
5381 5363
5382 void TargetARM32::prelowerPhis() { 5364 void TargetARM32::prelowerPhis() {
5383 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); 5365 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func);
5384 } 5366 }
5385 5367
5386 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { 5368 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) {
5387 Variable *Reg = makeReg(Ty, RegNum); 5369 Variable *Reg = makeReg(Ty, RegNum);
5388 Context.insert(InstFakeDef::create(Func, Reg)); 5370 Context.insert<InstFakeDef>(Reg);
5389 UnimplementedError(Func->getContext()->getFlags()); 5371 UnimplementedError(Func->getContext()->getFlags());
5390 return Reg; 5372 return Reg;
5391 } 5373 }
5392 5374
5393 // Helper for legalize() to emit the right code to lower an operand to a 5375 // Helper for legalize() to emit the right code to lower an operand to a
5394 // register of the appropriate type. 5376 // register of the appropriate type.
5395 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { 5377 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) {
5396 Type Ty = Src->getType(); 5378 Type Ty = Src->getType();
5397 Variable *Reg = makeReg(Ty, RegNum); 5379 Variable *Reg = makeReg(Ty, RegNum);
5398 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { 5380 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
5552 Variable *T = makeReg(Ty, RegNum); 5534 Variable *T = makeReg(Ty, RegNum);
5553 _mov(T, 5535 _mov(T,
5554 OperandARM32FlexFpImm::create(Func, From->getType(), ModifiedImm)); 5536 OperandARM32FlexFpImm::create(Func, From->getType(), ModifiedImm));
5555 return T; 5537 return T;
5556 } 5538 }
5557 5539
5558 if (Ty == IceType_f64 && isFloatingPointZero(From)) { 5540 if (Ty == IceType_f64 && isFloatingPointZero(From)) {
5559 // Use T = T ^ T to load a 64-bit fp zero. This does not work for f32 5541 // Use T = T ^ T to load a 64-bit fp zero. This does not work for f32
5560 // because ARM does not have a veor instruction with S registers. 5542 // because ARM does not have a veor instruction with S registers.
5561 Variable *T = makeReg(IceType_f64, RegNum); 5543 Variable *T = makeReg(IceType_f64, RegNum);
5562 Context.insert(InstFakeDef::create(Func, T)); 5544 Context.insert<InstFakeDef>(T);
5563 _veor(T, T, T); 5545 _veor(T, T, T);
5564 return T; 5546 return T;
5565 } 5547 }
5566 5548
5567 // Load floats/doubles from literal pool. 5549 // Load floats/doubles from literal pool.
5568 std::string Buffer; 5550 std::string Buffer;
5569 llvm::raw_string_ostream StrBuf(Buffer); 5551 llvm::raw_string_ostream StrBuf(Buffer);
5570 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx); 5552 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx);
5571 llvm::cast<Constant>(From)->setShouldBePooled(true); 5553 llvm::cast<Constant>(From)->setShouldBePooled(true);
5572 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); 5554 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
6180 } 6162 }
6181 6163
6182 InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg, 6164 InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg,
6183 Operand *CallTarget) { 6165 Operand *CallTarget) {
6184 if (Target->NeedSandboxing) { 6166 if (Target->NeedSandboxing) {
6185 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { 6167 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
6186 Target->_bic(CallTargetR, CallTargetR, 6168 Target->_bic(CallTargetR, CallTargetR,
6187 indirectBranchBicMask(Target->Func)); 6169 indirectBranchBicMask(Target->Func));
6188 } 6170 }
6189 } 6171 }
6190 auto *Call = InstARM32Call::create(Target->Func, ReturnReg, CallTarget); 6172 return Target->Context.insert<InstARM32Call>(ReturnReg, CallTarget);
6191 Target->Context.insert(Call);
6192 return Call;
6193 } 6173 }
6194 6174
6195 void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem, 6175 void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem,
6196 CondARM32::Cond Pred) { 6176 CondARM32::Cond Pred) {
6197 Variable *MemBase = Mem->getBase(); 6177 Variable *MemBase = Mem->getBase();
6198 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) { 6178 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
6199 assert(!Mem->isRegReg()); 6179 assert(!Mem->isRegReg());
6200 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred); 6180 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
6201 } 6181 }
6202 Target->_ldr(Dest, Mem, Pred); 6182 Target->_ldr(Dest, Mem, Pred);
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
6443 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 6423 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
6444 // However, for compatibility with current NaCl LLVM, don't claim that. 6424 // However, for compatibility with current NaCl LLVM, don't claim that.
6445 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6425 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6446 } 6426 }
6447 6427
6448 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; 6428 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM];
6449 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6429 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6450 llvm::SmallBitVector TargetARM32::ScratchRegs; 6430 llvm::SmallBitVector TargetARM32::ScratchRegs;
6451 6431
6452 } // end of namespace Ice 6432 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringMIPS32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698