@@ -181,6 +181,9 @@ class AArch64AsmPrinter : public AsmPrinter {
181
181
// / pseudo instructions.
182
182
bool lowerPseudoInstExpansion (const MachineInstr *MI, MCInst &Inst);
183
183
184
+ // Emit expansion of Compare-and-branch pseudo instructions
185
+ void emitCBPseudoExpansion (const MachineInstr *MI);
186
+
184
187
void EmitToStreamer (MCStreamer &S, const MCInst &Inst);
185
188
void EmitToStreamer (const MCInst &Inst) {
186
189
EmitToStreamer (*OutStreamer, Inst);
@@ -2427,6 +2430,150 @@ AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
2427
2430
return BAE;
2428
2431
}
2429
2432
2433
+ void AArch64AsmPrinter::emitCBPseudoExpansion (const MachineInstr *MI) {
2434
+ bool IsImm = false ;
2435
+ bool Is32Bit = false ;
2436
+
2437
+ switch (MI->getOpcode ()) {
2438
+ default :
2439
+ llvm_unreachable (" This is not a CB pseudo instruction" );
2440
+ case AArch64::CBWPrr:
2441
+ IsImm = false ;
2442
+ Is32Bit = true ;
2443
+ break ;
2444
+ case AArch64::CBXPrr:
2445
+ IsImm = false ;
2446
+ Is32Bit = false ;
2447
+ break ;
2448
+ case AArch64::CBWPri:
2449
+ IsImm = true ;
2450
+ Is32Bit = true ;
2451
+ break ;
2452
+ case AArch64::CBXPri:
2453
+ IsImm = true ;
2454
+ Is32Bit = false ;
2455
+ break ;
2456
+ }
2457
+
2458
+ AArch64CC::CondCode CC =
2459
+ static_cast <AArch64CC::CondCode>(MI->getOperand (0 ).getImm ());
2460
+ bool NeedsRegSwap = false ;
2461
+ bool NeedsImmDec = false ;
2462
+ bool NeedsImmInc = false ;
2463
+
2464
+ unsigned MCOpC;
2465
+ switch (CC) {
2466
+ default :
2467
+ llvm_unreachable (" Invalid CB condition code" );
2468
+ case AArch64CC::EQ:
2469
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBEQWri : AArch64::CBEQXri)
2470
+ : (Is32Bit ? AArch64::CBEQWrr : AArch64::CBEQXrr);
2471
+ NeedsRegSwap = false ;
2472
+ NeedsImmDec = false ;
2473
+ NeedsImmInc = false ;
2474
+ break ;
2475
+ case AArch64CC::NE:
2476
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBNEWri : AArch64::CBNEXri)
2477
+ : (Is32Bit ? AArch64::CBNEWrr : AArch64::CBNEXrr);
2478
+ NeedsRegSwap = false ;
2479
+ NeedsImmDec = false ;
2480
+ NeedsImmInc = false ;
2481
+ break ;
2482
+ case AArch64CC::HS:
2483
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
2484
+ : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
2485
+ NeedsRegSwap = false ;
2486
+ NeedsImmDec = true ;
2487
+ NeedsImmInc = false ;
2488
+ break ;
2489
+ case AArch64CC::LO:
2490
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
2491
+ : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
2492
+ NeedsRegSwap = true ;
2493
+ NeedsImmDec = false ;
2494
+ NeedsImmInc = false ;
2495
+ break ;
2496
+ case AArch64CC::HI:
2497
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
2498
+ : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
2499
+ NeedsRegSwap = false ;
2500
+ NeedsImmDec = false ;
2501
+ NeedsImmInc = false ;
2502
+ break ;
2503
+ case AArch64CC::LS:
2504
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
2505
+ : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
2506
+ NeedsRegSwap = !IsImm;
2507
+ NeedsImmDec = false ;
2508
+ NeedsImmInc = IsImm;
2509
+ break ;
2510
+ case AArch64CC::GE:
2511
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
2512
+ : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
2513
+ NeedsRegSwap = false ;
2514
+ NeedsImmDec = IsImm;
2515
+ NeedsImmInc = false ;
2516
+ break ;
2517
+ case AArch64CC::LT:
2518
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
2519
+ : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
2520
+ NeedsRegSwap = !IsImm;
2521
+ NeedsImmDec = false ;
2522
+ NeedsImmInc = false ;
2523
+ break ;
2524
+ case AArch64CC::GT:
2525
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
2526
+ : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
2527
+ NeedsRegSwap = false ;
2528
+ NeedsImmDec = false ;
2529
+ NeedsImmInc = false ;
2530
+ break ;
2531
+ case AArch64CC::LE:
2532
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
2533
+ : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
2534
+ NeedsRegSwap = !IsImm;
2535
+ NeedsImmDec = false ;
2536
+ NeedsImmInc = IsImm;
2537
+ break ;
2538
+ }
2539
+
2540
+ MCInst Inst;
2541
+ Inst.setOpcode (MCOpC);
2542
+
2543
+ MCOperand Lhs, Rhs, Trgt;
2544
+ lowerOperand (MI->getOperand (1 ), Lhs);
2545
+ lowerOperand (MI->getOperand (2 ), Rhs);
2546
+ lowerOperand (MI->getOperand (3 ), Trgt);
2547
+
2548
+ if (NeedsRegSwap) {
2549
+ assert (
2550
+ !IsImm &&
2551
+ " Unexpected register swap for CB instruction with immediate operand" );
2552
+ assert (Lhs.isReg () && " Expected register operand for CB" );
2553
+ assert (Rhs.isReg () && " Expected register operand for CB" );
2554
+ // Swap register operands
2555
+ Inst.addOperand (Rhs);
2556
+ Inst.addOperand (Lhs);
2557
+ } else if (IsImm && NeedsImmDec) {
2558
+ assert (IsImm && " Unexpected immediate decrement for CB instruction with "
2559
+ " reg-reg operands" );
2560
+ Rhs.setImm (Rhs.getImm () - 1 );
2561
+ Inst.addOperand (Lhs);
2562
+ Inst.addOperand (Rhs);
2563
+ } else if (NeedsImmInc) {
2564
+ assert (IsImm && " Unexpected immediate increment for CB instruction with "
2565
+ " reg-reg operands" );
2566
+ Rhs.setImm (Rhs.getImm () + 1 );
2567
+ Inst.addOperand (Lhs);
2568
+ Inst.addOperand (Rhs);
2569
+ } else {
2570
+ Inst.addOperand (Lhs);
2571
+ Inst.addOperand (Rhs);
2572
+ }
2573
+ Inst.addOperand (Trgt);
2574
+ EmitToStreamer (*OutStreamer, Inst);
2575
+ }
2576
+
2430
2577
// Simple pseudo-instructions have their lowering (with expansion to real
2431
2578
// instructions) auto-generated.
2432
2579
#include " AArch64GenMCPseudoLowering.inc"
@@ -2948,6 +3095,13 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
2948
3095
TS->emitARM64WinCFISaveAnyRegQPX (MI->getOperand (0 ).getImm (),
2949
3096
-MI->getOperand (2 ).getImm ());
2950
3097
return ;
3098
+
3099
+ case AArch64::CBWPri:
3100
+ case AArch64::CBXPri:
3101
+ case AArch64::CBWPrr:
3102
+ case AArch64::CBXPrr:
3103
+ emitCBPseudoExpansion (MI);
3104
+ return ;
2951
3105
}
2952
3106
2953
3107
// Finally, do the automated lowerings for everything else.
0 commit comments