Go through all kinds of trouble to mark 'blr' as having a predicate operand
authorChris Lattner <sabre@nondot.org>
Sat, 4 Nov 2006 05:27:39 +0000 (05:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 4 Nov 2006 05:27:39 +0000 (05:27 +0000)
that takes a register and condition code.  Print these pieces of BLR the
right way, even though it is currently set to 'always'.

Next up: get the JIT encoding right, then enhance branch folding to produce
predicated blr for simple examples.

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

lib/Target/PowerPC/PPC.h
lib/Target/PowerPC/PPCAsmPrinter.cpp
lib/Target/PowerPC/PPCInstrInfo.td

index 8fef9662010cb21ccb30c577a44067b4584f4e89..c8ea2829c467d4f0412340bfce9d23053b583ff5 100644 (file)
 
 #include <iosfwd>
 
-namespace llvm {
 
-class PPCTargetMachine;
-class FunctionPassManager;
-class FunctionPass;
-class MachineCodeEmitter;
+// GCC #defines PPC on Linux but we use it as our namespace name
+#undef PPC
 
+namespace llvm {
+  class PPCTargetMachine;
+  class FunctionPassManager;
+  class FunctionPass;
+  class MachineCodeEmitter;
+  
+  namespace PPC {
+    /// Predicate - These are "(BO << 5) | BI"  for various predicates.
+    enum Predicate {
+      PRED_ALWAYS = (20 << 5) | 0,
+      PRED_LT     = (12 << 5) | 0,
+      PRED_LE     = ( 4 << 5) | 1,
+      PRED_EQ     = (12 << 5) | 2,
+      PRED_GE     = ( 4 << 5) | 0,
+      PRED_GT     = (12 << 5) | 1,
+      PRED_NE     = ( 4 << 5) | 2,
+      PRED_UN     = (12 << 5) | 3,
+      PRED_NU     = ( 4 << 5) | 3
+    };
+  }
+  
 FunctionPass *createPPCBranchSelectionPass();
 FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
 FunctionPass *createPPCAsmPrinterPass(std::ostream &OS,
@@ -34,9 +52,6 @@ void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
                                  PPCTargetMachine &tm);
 } // end namespace llvm;
 
-// GCC #defines PPC on Linux but we use it as our namespace name
-#undef PPC
-
 // Defines symbolic names for PowerPC registers.  This defines a mapping from
 // register name to register number.
 //
index ee57cbaaba8405b01f2b06e1a69734b43977c0c9..47056de2ab74471539bcbaa6327756397d4d929e 100644 (file)
@@ -236,6 +236,9 @@ namespace {
       printOperand(MI, OpNo+1);
     }
     
+    void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 
+                               const char *Modifier);
+    
     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
     virtual bool doFinalization(Module &M) = 0;
   };
@@ -363,6 +366,33 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
   return false;
 }
 
+void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 
+                                          const char *Modifier) {
+  assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
+  unsigned Code = MI->getOperand(OpNo).getImm();
+  if (!strcmp(Modifier, "cc")) {
+    switch ((PPC::Predicate)Code) {
+    case PPC::PRED_ALWAYS: return; // Don't print anything for always.
+    case PPC::PRED_LT: O << "lt"; return;
+    case PPC::PRED_LE: O << "le"; return;
+    case PPC::PRED_EQ: O << "eq"; return;
+    case PPC::PRED_GE: O << "ge"; return;
+    case PPC::PRED_GT: O << "gt"; return;
+    case PPC::PRED_NE: O << "ne"; return;
+    case PPC::PRED_UN: O << "un"; return;
+    case PPC::PRED_NU: O << "nu"; return;
+    }
+      
+  } else {
+    assert(!strcmp(Modifier, "reg") &&
+           "Need to specify 'cc' or 'reg' as predicate op modifier!");
+    // Don't print the register for 'always'.
+    if (Code == PPC::PRED_ALWAYS) return;
+    printOperand(MI, OpNo+1);
+  }
+}
+
+
 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
 /// the current output stream.
 ///
index 02b066f58257ff25da652ae3397172a112450fcd..81332c1acd137d3d8fc9fb556f184634283adc9a 100644 (file)
@@ -255,9 +255,11 @@ def memrix : Operand<iPTR> {   // memri where the imm is shifted 2 bits.
   let MIOperandInfo = (ops i32imm, ptr_rc);
 }
 
-// PowerPC Predicate operand.  20 = always, CR0 is a dummy reg that doesn't
-// matter.
-def pred : PredicateOperand<(ops imm, CRRC), (ops 20, CR0)>;
+// PowerPC Predicate operand.  640 = ((20<<5)|0) = always, CR0 is a dummy reg
+// that doesn't matter.
+def pred : PredicateOperand<(ops imm, CRRC), (ops (i32 640), CR0)> {
+  let PrintMethod = "printPredicateOperand";
+}
 
 // Define PowerPC specific addressing mode.
 def iaddr  : ComplexPattern<iPTR, 2, "SelectAddrImm",    [], []>;
@@ -315,10 +317,13 @@ let usesCustomDAGSchedInserter = 1,    // Expanded by the scheduler.
 
 let isTerminator = 1, isBarrier = 1, noResults = 1, PPC970_Unit = 7 in {
   let isReturn = 1 in
-    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(retflag)]>;
+    def BLR : XLForm_2_ext<19, 16, 20, 0, 0,
+                           (ops pred:$p),
+                           "b${p:cc}lr ${p:reg}", BrB, [(retflag)]>;
   def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
 }
 
+
 let Defs = [LR] in
   def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
                    PPC970_Unit_BRU;