[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp PPC64ISelSimple.cpp PowerPCInstrInfo.td

Nate Begeman natebegeman at mac.com
Thu Oct 7 15:30:13 PDT 2004



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelSimple.cpp updated: 1.88 -> 1.89
PPC64ISelSimple.cpp updated: 1.15 -> 1.16
PowerPCInstrInfo.td updated: 1.36 -> 1.37
---
Log message:

Several fixes and enhancements to the PPC32 backend.

1. Fix an illegal argument to getClassB when deciding whether or not to
   sign extend a byte load.

2. Initial addition of isLoad and isStore flags to the instruction .td file
   for eventual use in a scheduler.

3. Rewrite of how constants are handled in emitSimpleBinaryOperation so
   that we can emit the PowerPC shifted immediate instructions far more
   often.  This allows us to emit the following code:

int foo(int x) { return x | 0x00F0000; }

_foo:
.LBB_foo_0:     ; entry
        ; IMPLICIT_DEF
        oris r3, r3, 15
        blr


---
Diffs of the changes:  (+154 -147)

Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.88 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.89
--- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.88	Wed Oct  6 11:28:24 2004
+++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp	Thu Oct  7 17:30:03 2004
@@ -32,6 +32,8 @@
 using namespace llvm;
 
 namespace {
+  Statistic<> ShiftedImm("ppc-codegen", "Number of shifted immediates used");
+
   /// TypeClass - Used by the PowerPC backend to group LLVM types by their basic
   /// PPC Representation.
   ///
@@ -315,8 +317,19 @@
     void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
                            Value *Src, const Type *DestTy, unsigned TargetReg);
 
-    /// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary
-    /// and constant expression support.
+
+    /// emitBinaryConstOperation - Used by several functions to emit simple
+    /// arithmetic and logical operations with constants on a register rather
+    /// than a Value.
+    ///
+    void emitBinaryConstOperation(MachineBasicBlock *MBB, 
+                                  MachineBasicBlock::iterator IP,
+                                  unsigned Op0Reg, ConstantInt *Op1, 
+                                  unsigned Opcode, unsigned DestReg);
+
+    /// emitSimpleBinaryOperation - Implement simple binary operators for 
+    /// integral types.  OperatorClass is one of: 0 for Add, 1 for Sub, 
+    /// 2 for And, 3 for Or, 4 for Xor.
     ///
     void emitSimpleBinaryOperation(MachineBasicBlock *BB,
                                    MachineBasicBlock::iterator IP,
@@ -389,13 +402,6 @@
     void emitUCOM(MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI,
                    unsigned LHS, unsigned RHS);
 
-    /// emitAdd - A convenience function to emit the necessary code to add a
-    /// constant signed value to a register.
-    ///
-    void emitAdd(MachineBasicBlock *MBB, 
-                 MachineBasicBlock::iterator IP,
-                 unsigned Op0Reg, ConstantSInt *Op1, unsigned DestReg);
-
     /// makeAnotherReg - This method returns the next register number we haven't
     /// yet used.
     ///
@@ -434,7 +440,8 @@
     
     /// canUseAsImmediateForOpcode - This method returns whether a ConstantInt
     /// is okay to use as an immediate argument to a certain binary operation
-    bool canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Opcode);
+    bool canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Opcode,
+                                    bool Shifted);
 
     /// getFixedSizedAllocaFI - Return the frame index for a fixed sized alloca
     /// that is to be statically allocated with the initial stack frame
@@ -481,34 +488,41 @@
 
 /// canUseAsImmediateForOpcode - This method returns whether a ConstantInt
 /// is okay to use as an immediate argument to a certain binary operator.
+/// The shifted argument determines if the immediate is suitable to be used with
+/// the PowerPC instructions such as addis which concatenate 16 bits of the
+/// immediate with 16 bits of zeroes.
 ///
-/// Operator is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or, 4 for Xor.
-bool PPC32ISel::canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Operator) {
+bool PPC32ISel::canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Opcode,
+                                           bool Shifted) {
   ConstantSInt *Op1Cs;
   ConstantUInt *Op1Cu;
+
+  // For shifted immediates, any value with the low halfword cleared may be used
+  if (Shifted) {
+    if (((int32_t)CI->getRawValue() & 0x0000FFFF) == 0) {
+      ++ShiftedImm;
+      return true;
+    }
+    return false;
+  }
       
   // ADDI, Compare, and non-indexed Load take SIMM
-  bool cond1 = (Operator == 0)
+  bool cond1 = (Opcode < 2)
     && ((int32_t)CI->getRawValue() <= 32767)
     && ((int32_t)CI->getRawValue() >= -32768);
 
-  // SUBI takes -SIMM since it is a mnemonic for ADDI
-  bool cond2 = (Operator == 1)
-    && ((int32_t)CI->getRawValue() <= 32768)
-    && ((int32_t)CI->getRawValue() >= -32767);
-      
   // ANDIo, ORI, and XORI take unsigned values
-  bool cond3 = (Operator >= 2)
+  bool cond2 = (Opcode >= 2)
     && (Op1Cs = dyn_cast<ConstantSInt>(CI))
     && (Op1Cs->getValue() >= 0)
     && (Op1Cs->getValue() <= 65535);
 
   // ANDIo, ORI, and XORI take UIMMs, so they can be larger
-  bool cond4 = (Operator >= 2)
+  bool cond3 = (Opcode >= 2)
     && (Op1Cu = dyn_cast<ConstantUInt>(CI))
     && (Op1Cu->getValue() <= 65535);
 
-  if (cond1 || cond2 || cond3 || cond4)
+  if (cond1 || cond2 || cond3)
     return true;
 
   return false;
@@ -606,7 +620,7 @@
       } else {
         unsigned Temp = makeAnotherReg(Type::IntTy);
         BuildMI(*MBB, IP, PPC::LIS, 1, Temp).addSImm(uval >> 16);
-        BuildMI(*MBB, IP, PPC::ORI, 2, R).addReg(Temp).addImm(uval);
+        BuildMI(*MBB, IP, PPC::ORI, 2, R).addReg(Temp).addImm(uval & 0xFFFF);
       }
       return;
     } else if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(C)) {
@@ -616,7 +630,7 @@
       } else {
         unsigned Temp = makeAnotherReg(Type::IntTy);
         BuildMI(*MBB, IP, PPC::LIS, 1, Temp).addSImm(sval >> 16);
-        BuildMI(*MBB, IP, PPC::ORI, 2, R).addReg(Temp).addImm(sval);
+        BuildMI(*MBB, IP, PPC::ORI, 2, R).addReg(Temp).addImm(sval & 0xFFFF);
       }
       return;
     }
@@ -1047,7 +1061,7 @@
       unsigned OpClass = (CompTy->isSigned()) ? 0 : 2;
       
       // Treat compare like ADDI for the purposes of immediate suitability
-      if (canUseAsImmediateForOpcode(CI, OpClass)) {
+      if (canUseAsImmediateForOpcode(CI, OpClass, false)) {
         BuildMI(*MBB, IP, OpcodeImm, 2, PPC::CR0).addReg(Op0r).addSImm(Op1v);
       } else {
         unsigned Op1r = getReg(Op1, MBB, IP);
@@ -2012,39 +2026,94 @@
   BuildMI(*BB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
 }
 
+// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N.  It
+// returns zero when the input is not exactly a power of two.
+static unsigned ExactLog2(unsigned Val) {
+  if (Val == 0 || (Val & (Val-1))) return 0;
+  unsigned Count = 0;
+  while (Val != 1) {
+    Val >>= 1;
+    ++Count;
+  }
+  return Count;
+}
+
+/// emitBinaryConstOperation - Implement simple binary operators for integral
+/// types with a constant operand.  Opcode is one of: 0 for Add, 1 for Sub, 
+/// 2 for And, 3 for Or, 4 for Xor, and 5 for Subtract-From.
+///
+void PPC32ISel::emitBinaryConstOperation(MachineBasicBlock *MBB, 
+                                         MachineBasicBlock::iterator IP,
+                                         unsigned Op0Reg, ConstantInt *Op1, 
+                                         unsigned Opcode, unsigned DestReg) {
+  static const unsigned OpTab[] = {
+    PPC::ADD, PPC::SUB, PPC::AND, PPC::OR, PPC::XOR, PPC::SUBF
+  };
+  static const unsigned ImmOpTab[2][6] = {
+    {  PPC::ADDI,  PPC::ADDI,  PPC::ANDIo,  PPC::ORI,  PPC::XORI, PPC::SUBFIC },
+    { PPC::ADDIS, PPC::ADDIS, PPC::ANDISo, PPC::ORIS, PPC::XORIS, PPC::SUBFIC }
+  };
+
+  // Handle subtract now by inverting the constant value
+  ConstantInt *CI = Op1;
+  if (Opcode == 1) {
+    ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op1);
+    CI = ConstantSInt::get(Op1->getType(), -CSI->getValue());
+  }
+  
+  // xor X, -1 -> not X
+  if (Opcode == 4) {
+    ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op1);
+    ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1);
+    if ((CSI && CSI->isAllOnesValue()) || (CUI && CUI->isAllOnesValue())) {
+      BuildMI(*MBB, IP, PPC::NOR, 2, DestReg).addReg(Op0Reg).addReg(Op0Reg);
+      return;
+    }
+  }
+
+  // For Add, Sub, and SubF the instruction takes a signed immediate.  For And,
+  // Or, and Xor, the instruction takes an unsigned immediate.  There is no 
+  // shifted immediate form of SubF so disallow its opcode for those constants.
+  if (canUseAsImmediateForOpcode(CI, Opcode, false)) {
+    if (Opcode < 2 || Opcode == 5)
+      BuildMI(*MBB, IP, ImmOpTab[0][Opcode], 2, DestReg).addReg(Op0Reg)
+        .addSImm(Op1->getRawValue());
+    else
+      BuildMI(*MBB, IP, ImmOpTab[0][Opcode], 2, DestReg).addReg(Op0Reg)
+        .addZImm(Op1->getRawValue());
+  } else if (canUseAsImmediateForOpcode(CI, Opcode, true) && (Opcode < 5)) {
+    if (Opcode < 2)
+      BuildMI(*MBB, IP, ImmOpTab[1][Opcode], 2, DestReg).addReg(Op0Reg)
+        .addSImm(Op1->getRawValue() >> 16);
+    else
+      BuildMI(*MBB, IP, ImmOpTab[1][Opcode], 2, DestReg).addReg(Op0Reg)
+        .addZImm(Op1->getRawValue() >> 16);
+  } else {
+    unsigned Op1Reg = getReg(Op1, MBB, IP);
+    BuildMI(*MBB, IP, OpTab[Opcode], 2, DestReg).addReg(Op0Reg).addReg(Op1Reg);
+  }
+}
+
 /// emitSimpleBinaryOperation - Implement simple binary operators for integral
 /// types...  OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for
 /// Or, 4 for Xor.
 ///
-/// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary
-/// and constant expression support.
-///
 void PPC32ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
                                           MachineBasicBlock::iterator IP,
                                           Value *Op0, Value *Op1,
                                           unsigned OperatorClass, 
                                           unsigned DestReg) {
-  unsigned Class = getClassB(Op0->getType());
-
   // Arithmetic and Bitwise operators
   static const unsigned OpcodeTab[] = {
     PPC::ADD, PPC::SUB, PPC::AND, PPC::OR, PPC::XOR
   };
-  static const unsigned ImmOpcodeTab[] = {
-    PPC::ADDI, PPC::SUBI, PPC::ANDIo, PPC::ORI, PPC::XORI
-  };
-  static const unsigned RImmOpcodeTab[] = {
-    PPC::ADDI, PPC::SUBFIC, PPC::ANDIo, PPC::ORI, PPC::XORI
-  };
-
-  // Otherwise, code generate the full operation with a constant.
-  static const unsigned BottomTab[] = {
-    PPC::ADDC, PPC::SUBC, PPC::AND, PPC::OR, PPC::XOR
-  };
-  static const unsigned TopTab[] = {
-    PPC::ADDE, PPC::SUBFE, PPC::AND, PPC::OR, PPC::XOR
+  static const unsigned LongOpTab[2][5] = {
+    { PPC::ADDC,  PPC::SUBC, PPC::AND, PPC::OR, PPC::XOR },
+    { PPC::ADDE, PPC::SUBFE, PPC::AND, PPC::OR, PPC::XOR }
   };
   
+  unsigned Class = getClassB(Op0->getType());
+
   if (Class == cFP32 || Class == cFP64) {
     assert(OperatorClass < 2 && "No logical ops for FP!");
     emitBinaryFPOperation(MBB, IP, Op0, Op1, OperatorClass, DestReg);
@@ -2068,78 +2137,21 @@
   }
 
   // Special case: op <const int>, Reg
-  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0)) {
-    // sub 0, X -> subfic
-    if (OperatorClass == 1 && canUseAsImmediateForOpcode(CI, 0)) {
-      unsigned Op1r = getReg(Op1, MBB, IP);
-      int imm = CI->getRawValue() & 0xFFFF;
-
-      if (Class == cLong) {
-        BuildMI(*MBB, IP, PPC::SUBFIC, 2, DestReg+1).addReg(Op1r+1)
-          .addSImm(imm);
-        BuildMI(*MBB, IP, PPC::SUBFZE, 1, DestReg).addReg(Op1r);
-      } else {
-        BuildMI(*MBB, IP, PPC::SUBFIC, 2, DestReg).addReg(Op1r).addSImm(imm);
-      }
-      return;
-    }
-    
-    // If it is easy to do, swap the operands and emit an immediate op
-    if (Class != cLong && OperatorClass != 1 && 
-        canUseAsImmediateForOpcode(CI, OperatorClass)) {
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0))
+    if (Class != cLong) {
+      unsigned Opcode = (OperatorClass == 1) ? 5 : OperatorClass;
       unsigned Op1r = getReg(Op1, MBB, IP);
-      int imm = CI->getRawValue() & 0xFFFF;
-    
-      if (OperatorClass < 2)
-        BuildMI(*MBB, IP, RImmOpcodeTab[OperatorClass], 2, DestReg).addReg(Op1r)
-          .addSImm(imm);
-      else
-        BuildMI(*MBB, IP, RImmOpcodeTab[OperatorClass], 2, DestReg).addReg(Op1r)
-          .addZImm(imm);
+      emitBinaryConstOperation(MBB, IP, Op1r, CI, Opcode, DestReg);
       return;
     }
-  }
-
   // Special case: op Reg, <const int>
-  if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
-    unsigned Op0r = getReg(Op0, MBB, IP);
-
-    // xor X, -1 -> not X
-    if (OperatorClass == 4 && Op1C->isAllOnesValue()) {
-      BuildMI(*MBB, IP, PPC::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r);
-      if (Class == cLong)  // Invert the low part too
-        BuildMI(*MBB, IP, PPC::NOR, 2, DestReg+1).addReg(Op0r+1)
-          .addReg(Op0r+1);
-      return;
-    }
-    
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
     if (Class != cLong) {
-      if (canUseAsImmediateForOpcode(Op1C, OperatorClass)) {
-        int immediate = Op1C->getRawValue() & 0xFFFF;
-        
-        if (OperatorClass < 2)
-          BuildMI(*MBB, IP, ImmOpcodeTab[OperatorClass], 2,DestReg).addReg(Op0r)
-            .addSImm(immediate);
-        else
-          BuildMI(*MBB, IP, ImmOpcodeTab[OperatorClass], 2,DestReg).addReg(Op0r)
-            .addZImm(immediate);
-      } else {
-        unsigned Op1r = getReg(Op1, MBB, IP);
-        BuildMI(*MBB, IP, OpcodeTab[OperatorClass], 2, DestReg).addReg(Op0r)
-          .addReg(Op1r);
-      }
+      unsigned Op0r = getReg(Op0, MBB, IP);
+      emitBinaryConstOperation(MBB, IP, Op0r, CI, OperatorClass, DestReg);
       return;
     }
 
-    unsigned Op1r = getReg(Op1, MBB, IP);
-
-    BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
-      .addReg(Op1r+1);
-    BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg).addReg(Op0r)
-      .addReg(Op1r);
-    return;
-  }
-  
   // We couldn't generate an immediate variant of the op, load both halves into
   // registers and emit the appropriate opcode.
   unsigned Op0r = getReg(Op0, MBB, IP);
@@ -2149,26 +2161,14 @@
     unsigned Opcode = OpcodeTab[OperatorClass];
     BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
   } else {
-    BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
+    BuildMI(*MBB, IP, LongOpTab[0][OperatorClass], 2, DestReg+1).addReg(Op0r+1)
       .addReg(Op1r+1);
-    BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg).addReg(Op0r)
+    BuildMI(*MBB, IP, LongOpTab[1][OperatorClass], 2, DestReg).addReg(Op0r)
       .addReg(Op1r);
   }
   return;
 }
 
-// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N.  It
-// returns zero when the input is not exactly a power of two.
-static unsigned ExactLog2(unsigned Val) {
-  if (Val == 0 || (Val & (Val-1))) return 0;
-  unsigned Count = 0;
-  while (Val != 1) {
-    Val >>= 1;
-    ++Count;
-  }
-  return Count;
-}
-
 /// doMultiply - Emit appropriate instructions to multiply together the
 /// Values Op0 and Op1, and put the result in DestReg.
 ///
@@ -2258,7 +2258,7 @@
   
   // If 32 bits or less and immediate is in right range, emit mul by immediate
   if (Class == cByte || Class == cShort || Class == cInt) {
-    if (canUseAsImmediateForOpcode(CI, 0)) {
+    if (canUseAsImmediateForOpcode(CI, 0, false)) {
       unsigned Op0r = getReg(Op0, MBB, IP);
       unsigned imm = CI->getRawValue() & 0xFFFF;
       BuildMI(*MBB, IP, PPC::MULLI, 2, DestReg).addReg(Op0r).addSImm(imm);
@@ -2423,7 +2423,7 @@
     unsigned TmpReg1 = makeAnotherReg(Op0->getType());
     unsigned TmpReg2 = makeAnotherReg(Op0->getType());
     emitDivRemOperation(MBB, IP, Op0, Op1, true, TmpReg1);
-    if (CI && canUseAsImmediateForOpcode(CI, 0)) {
+    if (CI && canUseAsImmediateForOpcode(CI, 0, false)) {
       BuildMI(*MBB, IP, PPC::MULLI, 2, TmpReg2).addReg(TmpReg1)
         .addSImm(CI->getRawValue());
     } else {
@@ -2639,7 +2639,7 @@
       if (isa<SetCondInst>(*I))
         continue;
       if (StoreInst *SI = dyn_cast<StoreInst>(*I))
-        if (cByte == getClassB(SI->getType()))
+        if (cByte == getClassB(SI->getOperand(0)->getType()))
         continue;
       AllUsesAreStoresOrSetCC = false;
       break;
@@ -3392,21 +3392,6 @@
   emitGEPOperation(BB, BB->end(), &I, false);
 }
 
-/// emitAdd - A convenience function to emit the necessary code to add a
-/// constant signed value to a register.
-///
-void PPC32ISel::emitAdd(MachineBasicBlock *MBB, 
-                        MachineBasicBlock::iterator IP,
-                        unsigned Op0Reg, ConstantSInt *Op1, unsigned DestReg) {
-  if (canUseAsImmediateForOpcode(Op1, 0)) {
-    BuildMI(*MBB, IP, PPC::ADDI, 2, DestReg).addReg(Op0Reg)
-      .addSImm(Op1->getValue());
-  } else {
-    unsigned Op1Reg = getReg(Op1, MBB, IP);
-    BuildMI(*MBB, IP, PPC::ADD, 2, DestReg).addReg(Op0Reg).addReg(Op1Reg);
-  }
-}
-
 /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
 /// constant expression GEP support.
 ///
@@ -3490,7 +3475,7 @@
     unsigned TmpReg1 = makeAnotherReg(Type::IntTy);
     unsigned TmpReg2 = makeAnotherReg(Type::IntTy);
     doMultiplyConst(MBB, IP, TmpReg1, cgo.index, cgo.size);
-    emitAdd(MBB, IP, TmpReg1, cgo.offset, TmpReg2);
+    emitBinaryConstOperation(MBB, IP, TmpReg1, cgo.offset, 0, TmpReg2);
     
     if (indexReg == 0)
       indexReg = TmpReg2;
@@ -3513,13 +3498,13 @@
   // store can try and use it as an immediate.
   if (GEPIsFolded) {
     if (indexReg == 0) {
-      if (!canUseAsImmediateForOpcode(remainder, 0)) {
+      if (!canUseAsImmediateForOpcode(remainder, 0, false)) {
         indexReg = getReg(remainder, MBB, IP);
         remainder = 0;
       }
     } else {
       unsigned TmpReg = makeAnotherReg(Type::IntTy);
-      emitAdd(MBB, IP, indexReg, remainder, TmpReg);
+      emitBinaryConstOperation(MBB, IP, indexReg, remainder, 0, TmpReg);
       indexReg = TmpReg;
       remainder = 0;
     }
@@ -3536,7 +3521,7 @@
     BuildMI(*MBB, IP, PPC::ADD, 2, TmpReg).addReg(indexReg).addReg(basePtrReg);
     basePtrReg = TmpReg;
   }
-  emitAdd(MBB, IP, basePtrReg, remainder, TargetReg);
+  emitBinaryConstOperation(MBB, IP, basePtrReg, remainder, 0, TargetReg);
 }
 
 /// visitAllocaInst - If this is a fixed size alloca, allocate space from the
@@ -3606,7 +3591,6 @@
   TM.CalledFunctions.insert(mallocFn);
 }
 
-
 /// visitFreeInst - Free instructions are code gen'd to call the free libc
 /// function.
 ///


Index: llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.15 llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.16
--- llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.15	Tue Sep 21 13:22:33 2004
+++ llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp	Thu Oct  7 17:30:03 2004
@@ -1664,8 +1664,9 @@
   static const unsigned OpcodeTab[] = {
     PPC::ADD, PPC::SUB, PPC::AND, PPC::OR, PPC::XOR
   };
+  // FIXME: Convert this to the version from PPC32ISel
   static const unsigned ImmOpcodeTab[] = {
-    PPC::ADDI, PPC::SUBI, PPC::ANDIo, PPC::ORI, PPC::XORI
+    PPC::ADDI, PPC::ADDI, PPC::ANDIo, PPC::ORI, PPC::XORI
   };
   static const unsigned RImmOpcodeTab[] = {
     PPC::ADDI, PPC::SUBFIC, PPC::ANDIo, PPC::ORI, PPC::XORI


Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.36 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.37
--- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.36	Tue Sep 21 23:40:25 2004
+++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td	Thu Oct  7 17:30:03 2004
@@ -44,8 +44,10 @@
 
 // Pseudo-instructions:
 def PHI : Pseudo<(ops), "; PHI">;
+let isLoad = 1 in {
 def ADJCALLSTACKDOWN : Pseudo<(ops), "; ADJCALLSTACKDOWN">;
 def ADJCALLSTACKUP : Pseudo<(ops), "; ADJCALLSTACKUP">;
+}
 def IMPLICIT_DEF : Pseudo<(ops), "; IMPLICIT_DEF">;
 def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">;
 
@@ -82,6 +84,7 @@
 // D-Form instructions.  Most instructions that perform an operation on a
 // register and an immediate are of this type.
 //
+let isLoad = 1 in {
 def LBZ : DForm_1<35, 0, 0, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA),
                   "lbz $rD, $disp($rA)">;
 def LHA : DForm_1<42, 0, 0, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA),
@@ -92,6 +95,7 @@
                   "lmw $rD, $disp($rA)">;
 def LWZ : DForm_1<32, 0, 0, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
                   "lwz $rD, $disp($rA)">;
+}
 def ADDI   : DForm_2<14, 0, 0, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      "addi $rD, $rA, $imm">;
 def ADDIC  : DForm_2<12, 0, 0, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
@@ -108,12 +112,11 @@
                      "mulli $rD, $rA, $imm">;
 def SUBFIC : DForm_2< 8, 0, 0, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      "subfic $rD, $rA, $imm">;
-def SUBI   : DForm_2<14, 0, 0, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "subi $rD, $rA, $imm">;
 def LI  : DForm_2_r0<14, 0, 0, (ops GPRC:$rD, s16imm:$imm),
                      "li $rD, $imm">;
 def LIS : DForm_2_r0<15, 0, 0, (ops GPRC:$rD, s16imm:$imm),
                      "lis $rD, $imm">;
+let isStore = 1 in {
 def STMW : DForm_3<47, 0, 0, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stmw $rS, $disp($rA)">;
 def STB  : DForm_3<38, 0, 0, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
@@ -128,9 +131,13 @@
                    "stw $rS, $disp($rA)">;
 def STWU : DForm_3<37, 0, 0, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stwu $rS, $disp($rA)">;
+}
 def ANDIo : DForm_4<28, 0, 0,
                     (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                     "andi. $dst, $src1, $src2">;
+def ANDISo : DForm_4<29, 0, 0,
+                    (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
+                    "andis. $dst, $src1, $src2">;
 def ORI   : DForm_4<24, 0, 0,
                     (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                     "ori $dst, $src1, $src2">;
@@ -159,30 +166,38 @@
 def CMPLDI : DForm_6_ext<10, 1, 0,
                          (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
                          "cmpldi $dst, $src1, $src2">;
+let isLoad = 1 in {
 def LFS : DForm_8<48, 0, 0, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
                   "lfs $rD, $disp($rA)">;
 def LFD : DForm_8<50, 0, 0, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
                   "lfd $rD, $disp($rA)">;
+}
+let isStore = 1 in {
 def STFS : DForm_9<52, 0, 0, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stfs $rS, $disp($rA)">;
 def STFD : DForm_9<54, 0, 0, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stfd $rS, $disp($rA)">;
-
+}
 
 // DS-Form instructions.  Load/Store instructions available in PPC-64
 //
+let isLoad = 1 in {
 def LWA  : DSForm_1<58, 2, 1, 0, (ops GPRC:$rT, s16imm:$DS, GPRC:$rA),
                     "lwa $rT, $DS($rA)">;
 def LD   : DSForm_2<58, 0, 1, 0, (ops GPRC:$rT, s16imm:$DS, GPRC:$rA),
                     "ld $rT, $DS($rA)">;
+}
+let isStore = 1 in {
 def STD  : DSForm_2<62, 0, 1, 0, (ops GPRC:$rT, s16imm:$DS, GPRC:$rA),
                     "std $rT, $DS($rA)">;
 def STDU : DSForm_2<62, 1, 1, 0, (ops GPRC:$rT, s16imm:$DS, GPRC:$rA),
                     "stdu $rT, $DS($rA)">;
+}
 
 // X-Form instructions.  Most instructions that perform an operation on a
 // register and another register are of this type.
 //
+let isLoad = 1 in {
 def LBZX : XForm_1<31,  87, 0, 0, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
                    "lbzx $dst, $base, $index">;
 def LHAX : XForm_1<31, 343, 0, 0, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
@@ -195,6 +210,7 @@
                    "lwzx $dst, $base, $index">;
 def LDX  : XForm_1<31,  21, 1, 0, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
                    "ldx $dst, $base, $index">;
+}
 def MFCR : XForm_5<31,  19, 0, 0, (ops GPRC:$dst), "mfcr $dst">;
 def AND  : XForm_6<31,  28, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "and $rA, $rS, $rB">;
@@ -226,6 +242,7 @@
                    "sraw $rA, $rS, $rB">;
 def XOR  : XForm_6<31, 316, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "xor $rA, $rS, $rB">;
+let isStore = 1 in {
 def STBX  : XForm_8<31, 215, 0, 0, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
                    "stbx $rS, $rA, $rB">;
 def STHX  : XForm_8<31, 407, 0, 0, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
@@ -238,6 +255,7 @@
                    "stdx $rS, $rA, $rB">;
 def STDUX : XForm_8<31, 181, 1, 0, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
                    "stdux $rS, $rA, $rB">;
+}
 def SRAWI : XForm_10<31, 824, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), 
                      "srawi $rA, $rS, $SH">;
 def CNTLZW : XForm_11<31,  26, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS),
@@ -268,10 +286,12 @@
                           "cmpld $crD, $rA, $rB">;
 def FCMPU  : XForm_17<63, 0, 0, 0, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
                       "fcmpu $crD, $fA, $fB">;
+let isLoad = 1 in {
 def LFSX   : XForm_25<31, 535, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
                       "lfsx $dst, $base, $index">;
 def LFDX   : XForm_25<31, 599, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
                       "lfdx $dst, $base, $index">;
+}
 def FCFID  : XForm_26<63, 846, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB),
                       "fcfid $frD, $frB">;
 def FCTIDZ : XForm_26<63, 815, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB),
@@ -284,10 +304,12 @@
                       "fneg $frD, $frB">;
 def FRSP   : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
                       "frsp $frD, $frB">;
+let isStore = 1 in {
 def STFSX : XForm_28<31, 663, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
                      "stfsx $frS, $rA, $rB">;
 def STFDX : XForm_28<31, 727, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
                      "stfdx $frS, $rA, $rB">;
+}
 
 // XL-Form instructions.  condition register logical ops.
 //






More information about the llvm-commits mailing list