[PowerPC] Use mtocrf when available
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Wed, 3 Jul 2013 17:59:07 +0000 (17:59 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Wed, 3 Jul 2013 17:59:07 +0000 (17:59 +0000)
Just as with mfocrf, it is also preferable to use mtocrf instead of
mtcrf when only a single CR register is to be written.

Current code however always emits mtcrf.  This probably does not matter
when using an external assembler, since the GNU assembler will in fact
automatically replace mtcrf with mtocrf when possible.  It does create
inefficient code with the integrated assembler, however.

To fix this, this patch adds MTOCRF/MTOCRF8 instruction patterns and
uses those instead of MTCRF/MTCRF8 everything.  Just as done in the
MFOCRF patch committed as 185556, these patterns will be converted
back to MTCRF if MTOCRF is not available on the machine.

As a side effect, this allows to modify the MTCRF pattern to accept
the full range of mask operands for the benefit of the asm parser.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185561 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
lib/Target/PowerPC/PPCAsmPrinter.cpp
lib/Target/PowerPC/PPCCodeEmitter.cpp
lib/Target/PowerPC/PPCFrameLowering.cpp
lib/Target/PowerPC/PPCInstr64Bit.td
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/PowerPC/PPCRegisterInfo.cpp
test/CodeGen/PowerPC/crsave.ll
test/MC/PowerPC/ppc64-encoding-ext.s
test/MC/PowerPC/ppc64-encoding.s

index cb7f08b044ca58633728e0e2b7cc17c002abaf63..27ad980703ac48c4e760fbbedd7dd3de0223dd52 100644 (file)
@@ -228,7 +228,7 @@ unsigned PPCMCCodeEmitter::
 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
                     SmallVectorImpl<MCFixup> &Fixups) const {
   const MCOperand &MO = MI.getOperand(OpNo);
-  assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MTCRF8 ||
+  assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
   return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
@@ -239,9 +239,9 @@ unsigned PPCMCCodeEmitter::
 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                   SmallVectorImpl<MCFixup> &Fixups) const {
   if (MO.isReg()) {
-    // MTCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
+    // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
     // The GPR operand should come through here though.
-    assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MTCRF8 &&
+    assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
             MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
            MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
     return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
index 5129287e17c0b06a5e0910c0236773e4e0a1222d..8f41b2e7f745bc44e9d0f807ba07a37c7bb93b00 100644 (file)
@@ -676,6 +676,23 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
       return;
     }
     break;
+  case PPC::MTOCRF:
+  case PPC::MTOCRF8:
+    if (!Subtarget.hasMFOCRF()) {
+      // Transform: %CR7 = MTOCRF %R3
+      // Into:      MTCRF mask, %R3 ;; cr7
+      unsigned NewOpcode =
+        MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
+      unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
+                              ->getEncodingValue(MI->getOperand(0).getReg());
+      OutStreamer.AddComment(PPCInstPrinter::
+                             getRegisterName(MI->getOperand(0).getReg()));
+      OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode)
+                                  .addImm(Mask)
+                                  .addReg(MI->getOperand(1).getReg()));
+      return;
+    }
+    break;
   case PPC::SYNC:
     // In Book E sync is called msync, handle this special case here...
     if (Subtarget.isBookE()) {
index e9aa4c07ad71ead7d36446909b433b710192b8a2..418736e21e86f2dee01484d95ffd335c59f54b2a 100644 (file)
@@ -142,7 +142,7 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
 unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI,
                                              unsigned OpNo) const {
   const MachineOperand &MO = MI.getOperand(OpNo);
-  assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MTCRF8 ||
+  assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
   return 0x80 >> TM.getRegisterInfo()->getEncodingValue(MO.getReg());
@@ -274,9 +274,9 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {
 
   if (MO.isReg()) {
-    // MTCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
+    // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
     // The GPR operand should come through here though.
-    assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MTCRF8 &&
+    assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
             MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
            MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
     return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
index 4c57cf632fb4d099fc316749344691c76e6329ce..a19ce239377e6fe3f0f291413a21ca20f33e3ad8 100644 (file)
@@ -753,7 +753,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
 
     if (!MustSaveCRs.empty())
       for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
-        BuildMI(MBB, MBBI, dl, TII.get(PPC::MTCRF8), MustSaveCRs[i])
+        BuildMI(MBB, MBBI, dl, TII.get(PPC::MTOCRF8), MustSaveCRs[i])
           .addReg(PPC::X12, getKillRegState(i == e-1));
 
     if (MustSaveLR)
@@ -1212,7 +1212,7 @@ restoreCRs(bool isPPC64, bool is31,
     MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ),
                                             PPC::R12),
                                     CSI[CSIIndex].getFrameIdx()));
-    RestoreOp = PPC::MTCRF;
+    RestoreOp = PPC::MTOCRF;
     MoveReg = PPC::R12;
   }
   
index 2426dcda1a6314963cff19b4e500807dc6318c32..d19a7d439fd904805a71bfa60e37f93a54518bb8 100644 (file)
@@ -257,7 +257,11 @@ def : Pat<(PPCtc_return CTRRC8:$dst, imm:$imm),
 // 64-bit CR instructions
 let Interpretation64Bit = 1 in {
 let neverHasSideEffects = 1 in {
-def MTCRF8 : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins g8rc:$rS),
+def MTOCRF8: XFXForm_5a<31, 144, (outs crbitm:$FXM), (ins g8rc:$ST),
+                        "mtocrf $FXM, $ST", BrMCRX>,
+            PPC970_DGroup_First, PPC970_Unit_CRU;
+
+def MTCRF8 : XFXForm_5<31, 144, (outs), (ins i32imm:$FXM, g8rc:$rS),
                       "mtcrf $FXM, $rS", BrMCRX>,
             PPC970_MicroCode, PPC970_Unit_CRU;
 
index e52adeeb29dc503f4378f60e185a9be1f5dfb3d2..9a8e33b79d598ca4e3525c7d56ef8bd09b737a32 100644 (file)
@@ -1898,7 +1898,11 @@ def RESTORE_VRSAVE : Pseudo<(outs VRSAVERC:$vrsave), (ins memri:$F),
                      "#RESTORE_VRSAVE", []>;
 
 let neverHasSideEffects = 1 in {
-def MTCRF : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins gprc:$rS),
+def MTOCRF: XFXForm_5a<31, 144, (outs crbitm:$FXM), (ins gprc:$ST),
+                       "mtocrf $FXM, $ST", BrMCRX>,
+            PPC970_DGroup_First, PPC970_Unit_CRU;
+
+def MTCRF : XFXForm_5<31, 144, (outs), (ins i32imm:$FXM, gprc:$rS),
                       "mtcrf $FXM, $rS", BrMCRX>,
             PPC970_MicroCode, PPC970_Unit_CRU;
 
@@ -2322,6 +2326,8 @@ def : InstAlias<"mr. $rA, $rB", (OR8o g8rc:$rA, g8rc:$rB, g8rc:$rB)>;
 def : InstAlias<"not $rA, $rB", (NOR8 g8rc:$rA, g8rc:$rB, g8rc:$rB)>;
 def : InstAlias<"not. $rA, $rB", (NOR8o g8rc:$rA, g8rc:$rB, g8rc:$rB)>;
 
+def : InstAlias<"mtcr $rA", (MTCRF8 255, g8rc:$rA)>;
+
 def LAx : PPCAsmPseudo<"la $rA, $addr", (ins gprc:$rA, memri:$addr)>;
 
 def SUBI : PPCAsmPseudo<"subi $rA, $rB, $imm",
index e5b43051b71f5a62edb95d105fcd7ee2320762e7..8a0954c5bb5f8338994e5d0ecd467d7f6dbdbbed 100644 (file)
@@ -403,7 +403,7 @@ void PPCRegisterInfo::lowerCRRestore(MachineBasicBlock::iterator II,
              .addImm(31);
   }
 
-  BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MTCRF8 : PPC::MTCRF), DestReg)
+  BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MTOCRF8 : PPC::MTOCRF), DestReg)
              .addReg(Reg, RegState::Kill);
 
   // Discard the pseudo instruction.
index b15011d92845a730192a93b0e65f266c2d6fc0ed..a9b4b3607830821fc1f7362d139a4ea871517394 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC32
-; RUN: llc -O0 -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64
+; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC32
+; RUN: llc -O0 -mtriple=powerpc64-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC64
 
 declare void @foo()
 
@@ -18,7 +18,7 @@ entry:
 ; PPC32: mfcr 12
 ; PPC32-NEXT: stw 12, 24(31)
 ; PPC32: lwz 12, 24(31)
-; PPC32-NEXT: mtcrf 32, 12
+; PPC32-NEXT: mtocrf 32, 12
 
 ; PPC64: .cfi_startproc
 ; PPC64: mfcr 12
@@ -29,7 +29,7 @@ entry:
 ; PPC64: .cfi_offset cr2, 8
 ; PPC64: addi 1, 1, [[AMT]]
 ; PPC64: lwz 12, 8(1)
-; PPC64: mtcrf 32, 12
+; PPC64: mtocrf 32, 12
 ; PPC64: .cfi_endproc
 
 define i32 @test_cr234() nounwind {
@@ -47,16 +47,16 @@ entry:
 ; PPC32: mfcr 12
 ; PPC32-NEXT: stw 12, 24(31)
 ; PPC32: lwz 12, 24(31)
-; PPC32-NEXT: mtcrf 32, 12
-; PPC32-NEXT: mtcrf 16, 12
-; PPC32-NEXT: mtcrf 8, 12
+; PPC32-NEXT: mtocrf 32, 12
+; PPC32-NEXT: mtocrf 16, 12
+; PPC32-NEXT: mtocrf 8, 12
 
 ; PPC64: mfcr 12
 ; PPC64: stw 12, 8(1)
 ; PPC64: stdu 1, -[[AMT:[0-9]+]](1)
 ; PPC64: addi 1, 1, [[AMT]]
 ; PPC64: lwz 12, 8(1)
-; PPC64: mtcrf 32, 12
-; PPC64: mtcrf 16, 12
-; PPC64: mtcrf 8, 12
+; PPC64: mtocrf 32, 12
+; PPC64: mtocrf 16, 12
+; PPC64: mtocrf 8, 12
 
index 79c8fdb39210e0b6773639490fcefe9a65e2d9f5..0bc1a398355d24c6381bc22b63a9bf33de695ba5 100644 (file)
          not 2, 3
 # CHECK: nor. 2, 3, 3                    # encoding: [0x7c,0x62,0x18,0xf9]
          not. 2, 3
+# CHECK: mtcrf 255, 2                    # encoding: [0x7c,0x4f,0xf1,0x20]
+         mtcr 2
 
index fbedf43d480e2352a74bb8ccd5c9fa7473522298..03d513ccc4d4007bf6bbadb866074c9917383b91 100644 (file)
          mtspr 600, 2
 # CHECK: mfspr 2, 600                    # encoding: [0x7c,0x58,0x92,0xa6]
          mfspr 2, 600
-# CHECK: mtcrf 16, 2                     # encoding: [0x7c,0x41,0x01,0x20]
-         mtcrf 16, 2
+# CHECK: mtcrf 123, 2                    # encoding: [0x7c,0x47,0xb1,0x20]
+         mtcrf 123, 2
 # CHECK: mfcr 2                          # encoding: [0x7c,0x40,0x00,0x26]
          mfcr 2
-# FIXME: mtocrf 16, 2
+# CHECK: mtocrf 16, 2                    # encoding: [0x7c,0x51,0x01,0x20]
+         mtocrf 16, 2
 # CHECK: mfocrf 16, 8                    # encoding: [0x7e,0x10,0x80,0x26]
          mfocrf 16, 8
-# FIXME: mcrxr 2