[llvm-branch-commits] [llvm-branch] r166326 - in /llvm/branches/R600/lib/Target/AMDGPU: InstPrinter/AMDGPUInstPrinter.cpp InstPrinter/AMDGPUInstPrinter.h MCTargetDesc/R600MCCodeEmitter.cpp R600Defines.h R600ExpandSpecialInstrs.cpp R600InstrInfo.cpp R600InstrInfo.h R600Instructions.td R600RegisterInfo.td

Tom Stellard thomas.stellard at amd.com
Fri Oct 19 14:10:04 PDT 2012


Author: tstellar
Date: Fri Oct 19 16:10:04 2012
New Revision: 166326

URL: http://llvm.org/viewvc/llvm-project?rev=166326&view=rev
Log:
R600: Use native operands for R600_1OP instructions

Modified:
    llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
    llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
    llvm/branches/R600/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
    llvm/branches/R600/lib/Target/AMDGPU/R600Defines.h
    llvm/branches/R600/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp
    llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.cpp
    llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.h
    llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td
    llvm/branches/R600/lib/Target/AMDGPU/R600RegisterInfo.td

Modified: llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp Fri Oct 19 16:10:04 2012
@@ -44,4 +44,65 @@
   printOperand(MI, OpNo, O);
 }
 
+void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
+                                    raw_ostream &O, StringRef Asm) {
+  const MCOperand &Op = MI->getOperand(OpNo);
+  assert(Op.isImm());
+  if (Op.getImm() == 1) {
+    O << Asm;
+  }
+}
+
+void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
+                                 raw_ostream &O) {
+  printIfSet(MI, OpNo, O, "|");
+}
+
+void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
+                                   raw_ostream &O) {
+  printIfSet(MI, OpNo, O, "_SAT");
+}
+
+void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
+                                  raw_ostream &O) {
+  printIfSet(MI, OpNo, O, " *");
+}
+
+void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
+                                 raw_ostream &O) {
+  printIfSet(MI, OpNo, O, "-");
+}
+
+void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
+                                  raw_ostream &O) {
+  switch (MI->getOperand(OpNo).getImm()) {
+  default: break;
+  case 1:
+    O << " * 2.0";
+    break;
+  case 2:
+    O << " * 4.0";
+    break;
+  case 3:
+    O << " / 2.0";
+    break;
+  }
+}
+
+void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
+                                 raw_ostream &O) {
+  const MCOperand &Op = MI->getOperand(OpNo);
+  if (Op.getImm() != 0) {
+    O << " + " + Op.getImm();
+  }
+}
+
+void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
+                                       raw_ostream &O) {
+  const MCOperand &Op = MI->getOperand(OpNo);
+  if (Op.getImm() == 0) {
+    O << " (MASKED)";
+  }
+}
+
 #include "AMDGPUGenAsmWriter.inc"

Modified: llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h Fri Oct 19 16:10:04 2012
@@ -33,8 +33,14 @@
   void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 //  void printUnsignedImm(const MCInst *MI, int OpNo, raw_ostream &O);
   void printMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
-
-
+  void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O, StringRef Asm);
+  void printAbs(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printClamp(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printLast(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printNeg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printOMOD(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printRel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printWrite(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 };
 
 } // End namespace llvm

Modified: llvm/branches/R600/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp Fri Oct 19 16:10:04 2012
@@ -191,20 +191,6 @@
   const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
   unsigned NumOperands = MI.getNumOperands();
 
-  if(MCDesc.findFirstPredOperandIdx() > -1)
-    NumOperands--;
-
-  if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0)
-    NumOperands--;
-
-  if(MI.getOpcode() == AMDGPU::PRED_X)
-    NumOperands = 2;
-
-  // XXX Check if instruction writes a result
-  if (NumOperands < 1) {
-    return;
-  }
-
   // Emit instruction type
   EmitByte(INSTR_ALU, OS);
 
@@ -219,6 +205,40 @@
     InstWord01 |= ISAOpCode << 1;
   }
 
+  if (HAS_NATIVE_OPERANDS(MCDesc.TSFlags)) {
+    unsigned SrcIdx = 0;
+    for (unsigned int OpIdx = 1; OpIdx < NumOperands; ++OpIdx) {
+      if (MI.getOperand(OpIdx).isImm() || MI.getOperand(OpIdx).isFPImm() ||
+          OpIdx == (unsigned)MCDesc.findFirstPredOperandIdx()) {
+        continue;
+      }
+      EmitSrcISA(MI, OpIdx, InstWord01, OS);
+      SrcIdx++;
+    }
+
+    // Emit zeros for unused sources
+    for ( ; SrcIdx < 3; SrcIdx++) {
+      EmitNullBytes(SRC_BYTE_COUNT - 6, OS);
+    }
+
+    Emit(InstWord01, OS);
+    return;
+  }
+
+  if(MCDesc.findFirstPredOperandIdx() > -1)
+    NumOperands--;
+
+  if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0)
+    NumOperands--;
+
+  if(MI.getOpcode() == AMDGPU::PRED_X)
+    NumOperands = 2;
+
+  // XXX Check if instruction writes a result
+  if (NumOperands < 1) {
+    return;
+  }
+
   unsigned int OpIndex;
   for (OpIndex = 1; OpIndex < NumOperands; OpIndex++) {
     // Literal constants are always stored as the last operand.
@@ -383,6 +403,13 @@
     EmitTwoBytes(0, OS);
   }
 
+  // Emit the literal value, if applicable (4 bytes).
+  Emit(InlineConstant.i, OS);
+
+  if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags)) {
+    return;
+  }
+
   // source channel
   uint64_t sourceChannelValue = getHWRegChan(MO.getReg());
   if (OpIdx == 1)
@@ -414,9 +441,6 @@
   // XXX: relative addressing mode
   // XXX: kc_bank
 
-  // Emit the literal value, if applicable (4 bytes).
-  Emit(InlineConstant.i, OS);
-
 }
 
 void R600MCCodeEmitter::EmitTexInstr(const MCInst &MI,
@@ -612,7 +636,11 @@
                                               const MCOperand &MO,
                                         SmallVectorImpl<MCFixup> &Fixup) const {
   if (MO.isReg()) {
-    return getHWReg(MO.getReg());
+    if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags)) {
+      return MRI.getEncodingValue(MO.getReg());
+    } else {
+      return getHWReg(MO.getReg());
+    }
   } else if (MO.isImm()) {
     return MO.getImm();
   } else {

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600Defines.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600Defines.h?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600Defines.h (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600Defines.h Fri Oct 19 16:10:04 2012
@@ -19,27 +19,58 @@
 #define MO_FLAG_MASK  (1 << 3)
 #define MO_FLAG_PUSH  (1 << 4)
 #define MO_FLAG_NOT_LAST  (1 << 5)
-#define NUM_MO_FLAGS 6
+#define MO_FLAG_LAST  (1 << 6)
+#define NUM_MO_FLAGS 7
 
 // Helper for finding getting the operand index for the instruction flags
 // operand.
 #define GET_FLAG_OPERAND_IDX(Flags) (((Flags) >> 7) & 0x3)
 
 namespace R600_InstFlag {
-	enum TIF {
-		TRANS_ONLY = (1 << 0),
-		TEX = (1 << 1),
-		REDUCTION = (1 << 2),
-		FC = (1 << 3),
-		TRIG = (1 << 4),
-		OP3 = (1 << 5),
-		VECTOR = (1 << 6)
+  enum TIF {
+    TRANS_ONLY = (1 << 0),
+    TEX = (1 << 1),
+    REDUCTION = (1 << 2),
+    FC = (1 << 3),
+    TRIG = (1 << 4),
+    OP3 = (1 << 5),
+    VECTOR = (1 << 6),
     //FlagOperand bits 7, 8
-	};
+    NATIVE_OPERANDS = (1 << 9),
+    OP1 = (1 << 10),
+    OP2 = (1 << 11)
+  };
 }
 
+#define HAS_NATIVE_OPERANDS(Flags) ((Flags) & R600_InstFlag::NATIVE_OPERANDS)
+
 // Defines for extracting register infomation from register encoding
 #define HW_REG_MASK 0x1ff
 #define HW_CHAN_SHIFT 9
 
+namespace R600Operands {
+  enum Ops {
+    DST,
+    WRITE,
+    OMOD,
+    DST_REL,
+    CLAMP,
+    SRC0,
+    SRC0_NEG,
+    SRC0_REL,
+    SRC0_ABS,
+    SRC1,
+    SRC1_NEG,
+    SRC1_REL,
+    SRC1_ABS,
+    SRC2,
+    SRC2_NEG,
+    SRC2_REL,
+    LAST,
+    PRED_SEL,
+    IMM,
+    COUNT
+ };
+}
+
 #endif // R600DEFINES_H_

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp Fri Oct 19 16:10:04 2012
@@ -222,13 +222,18 @@
       // T0_Z = CUBE T1_X, T1_Z
       // T0_W = CUBE T1_Y, T1_Z
       for (unsigned Chan = 0; Chan < 4; Chan++) {
-        unsigned DstReg = MI.getOperand(0).getReg();
-        unsigned Src0 = MI.getOperand(1).getReg();
+        unsigned DstReg = MI.getOperand(
+                            TII->getOperandIdx(MI, R600Operands::DST)).getReg();
+        unsigned Src0 = MI.getOperand(
+                           TII->getOperandIdx(MI, R600Operands::SRC0)).getReg();
         unsigned Src1 = 0;
 
         // Determine the correct source registers
         if (!IsCube) {
-          Src1 = MI.getOperand(2).getReg();
+          int Src1Idx = TII->getOperandIdx(MI, R600Operands::SRC1);
+          if (Src1Idx != -1) {
+            Src1 = MI.getOperand(Src1Idx).getReg();
+          }
         }
         if (IsReduction) {
           unsigned SubRegIndex = TRI.getSubRegFromChannel(Chan);

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.cpp?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.cpp Fri Oct 19 16:10:04 2012
@@ -475,6 +475,47 @@
   return 2;
 }
 
+int R600InstrInfo::getOperandIdx(const MachineInstr &MI,
+                                 R600Operands::Ops Op) const
+{
+  const static int OpTable[3][R600Operands::COUNT] = {
+//      W        C     S  S  S     S  S  S     S  S
+//      R  O  D  L  S  R  R  R  S  R  R  R  S  R  R  L  P
+//   D  I  M  R  A  R  C  C  C  C  C  C  C  R  C  C  A  R  I
+//   S  T  O  E  M  C  0  0  0  C  1  1  1  C  2  2  S  E  M
+//   T  E  D  L  P  0  N  R  A  1  N  R  A  2  N  R  T  D  M
+    {0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,-1, 9,10,11},
+    {0, 1, 2, 3, 4 ,5 ,6 ,7, 8, 9,10,11,12,-1,-1,-1,13,14,15},
+    {0, 1, 2, 3, 4, 5, 6, 7,-1, 8, 9,10,-1,11,12,13,14,15,16}
+  };
+  unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
+  unsigned OpTableIdx;
+
+  if (!HAS_NATIVE_OPERANDS(TargetFlags)) {
+    switch (Op) {
+    case R600Operands::DST: return 0;
+    case R600Operands::SRC0: return 1;
+    case R600Operands::SRC1: return 2;
+    case R600Operands::SRC2: return 3;
+    default:
+      assert(!"Unknown operand type for instruction");
+      return -1;
+    }
+  }
+
+  if (TargetFlags & R600_InstFlag::OP1) {
+    OpTableIdx = 0;
+  } else if (TargetFlags & R600_InstFlag::OP2) {
+    OpTableIdx = 1;
+  } else {
+    assert((TargetFlags & R600_InstFlag::OP3) && "OP1, OP2, or OP3 not defined "
+                                                 "for this instruction");
+    OpTableIdx = 2;
+  }
+
+  return OpTable[OpTableIdx][Op];
+}
+
 //===----------------------------------------------------------------------===//
 // Instruction flag getters/setters
 //===----------------------------------------------------------------------===//
@@ -484,11 +525,56 @@
   return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0;
 }
 
-MachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI) const
+MachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx,
+                                         unsigned Flag) const
 {
-  unsigned FlagIndex = GET_FLAG_OPERAND_IDX(get(MI->getOpcode()).TSFlags);
-  assert(FlagIndex != 0 &&
+  unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
+  int FlagIndex = 0;
+  if (Flag != 0) {
+    // If we pass something other than the default value of Flag to this
+    // function, it means we are want to set a flag on an instruction
+    // that uses native encoding.
+    assert(HAS_NATIVE_OPERANDS(TargetFlags));
+    bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3;
+    switch (Flag) {
+    case MO_FLAG_CLAMP:
+      FlagIndex = getOperandIdx(*MI, R600Operands::CLAMP);
+      break;
+    case MO_FLAG_MASK:
+      FlagIndex = getOperandIdx(*MI, R600Operands::WRITE);
+      break;
+    case MO_FLAG_NOT_LAST:
+    case MO_FLAG_LAST:
+      FlagIndex = getOperandIdx(*MI, R600Operands::LAST);
+      break;
+    case MO_FLAG_NEG:
+      switch (SrcIdx) {
+      case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_NEG); break;
+      case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_NEG); break;
+      case 2: FlagIndex = getOperandIdx(*MI, R600Operands::SRC2_NEG); break;
+      }
+      break;
+
+    case MO_FLAG_ABS:
+      assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "
+                       "instructions.");
+      switch (SrcIdx) {
+      case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_ABS); break;
+      case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_ABS); break;
+      }
+      break;
+
+    default:
+      FlagIndex = -1;
+      break;
+    }
+    assert(FlagIndex != -1 && "Flag not supported for this instruction");
+  } else {
+      FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags);
+      assert(FlagIndex != 0 &&
          "Instruction flags not supported for this instruction");
+  }
+
   MachineOperand &FlagOp = MI->getOperand(FlagIndex);
   assert(FlagOp.isImm());
   return FlagOp;
@@ -497,15 +583,36 @@
 void R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand,
                             unsigned Flag) const
 {
-  MachineOperand &FlagOp = getFlagOp(MI);
-  FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
+  unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
+  if (Flag == 0) {
+    return;
+  }
+  if (HAS_NATIVE_OPERANDS(TargetFlags)) {
+    MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
+    if (Flag == MO_FLAG_NOT_LAST) {
+      clearFlag(MI, Operand, MO_FLAG_LAST);
+    } else if (Flag == MO_FLAG_MASK) {
+      clearFlag(MI, Operand, Flag);
+    } else {
+      FlagOp.setImm(1);
+    }
+  } else {
+      MachineOperand &FlagOp = getFlagOp(MI, Operand);
+      FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
+  }
 }
 
 void R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand,
                               unsigned Flag) const
 {
-  MachineOperand &FlagOp = getFlagOp(MI);
-  unsigned InstFlags = FlagOp.getImm();
-  InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
-  FlagOp.setImm(InstFlags);
+  unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
+  if (HAS_NATIVE_OPERANDS(TargetFlags)) {
+    MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
+    FlagOp.setImm(0);
+  } else {
+    MachineOperand &FlagOp = getFlagOp(MI);
+    unsigned InstFlags = FlagOp.getImm();
+    InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
+    FlagOp.setImm(InstFlags);
+  }
 }

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.h?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.h (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600InstrInfo.h Fri Oct 19 16:10:04 2012
@@ -16,6 +16,7 @@
 
 #include "AMDIL.h"
 #include "AMDGPUInstrInfo.h"
+#include "R600Defines.h"
 #include "R600RegisterInfo.h"
 
 #include <map>
@@ -109,6 +110,10 @@
   virtual int getInstrLatency(const InstrItineraryData *ItinData,
                               SDNode *Node) const { return 1;}
 
+  /// getOperandIdx - Get the index of Op in the MachineInstr.  Returns -1
+  /// if the Instruction does not contain the specified Op.
+  int getOperandIdx(const MachineInstr &MI, R600Operands::Ops Op) const;
+
   ///hasFlagOperand - Returns true if this instruction has an operand for
   /// storing target flags.
   bool hasFlagOperand(const MachineInstr &MI) const;
@@ -120,7 +125,10 @@
   bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const;
 
   ///getFlagOp - Return the operand containing the flags for this instruction.
-  MachineOperand &getFlagOp(MachineInstr *MI) const;
+  /// SrcIdx is the register source to set the flag on (e.g src0, src1, src2)
+  /// Flag is the flag being set.
+  MachineOperand &getFlagOp(MachineInstr *MI, unsigned SrcIdx = 0,
+                            unsigned Flag = 0) const;
 
   ///clearFlag - Clear the specified flag on the instruction.
   void clearFlag(MachineInstr *MI, unsigned Operand, unsigned Flag) const;

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td Fri Oct 19 16:10:04 2012
@@ -22,6 +22,9 @@
   bit Op3 = 0;
   bit isVector = 0;
   bits<2> FlagOperandIdx = 0;
+  bit Op1 = 0;
+  bit Op2 = 0;
+  bit HasNativeOperands = 0;
 
   bits<11> op_code = inst;
   //let Inst = inst;
@@ -39,6 +42,9 @@
   // instruction group
   let TSFlags{6} = isVector;
   let TSFlags{8-7} = FlagOperandIdx;
+  let TSFlags{9} = HasNativeOperands;
+  let TSFlags{10} = Op1;
+  let TSFlags{11} = Op2;
 }
 
 class InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern> :
@@ -57,43 +63,162 @@
   let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index);
 }
 
-def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>;
+// Operands for non-registers
+
+class InstFlag<string PM = "printOperand", int Default = 0>
+    : OperandWithDefaultOps <i32, (ops (i32 Default))> {
+  let PrintMethod = PM;
+}
+
+def LITERAL : InstFlag;
+
+def WRITE : InstFlag <"printWrite", 1>;
+def OMOD : InstFlag <"printOMOD">;
+def REL : InstFlag <"printRel">;
+def CLAMP : InstFlag <"printClamp">;
+def NEG : InstFlag <"printNeg">;
+def ABS : InstFlag <"printAbs">;
+
+// XXX: The r600g finalizer in Mesa expects last to be one in most cases.
+// Once we start using the packetizer in this backend we should have this
+// default to 0.
+def LAST : InstFlag<"printLast", 1>;
 
 def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>;
 def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>;
 def ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>;
 
-class R600_ALU {
+class R600ALU_Word0 {
+  field bits<32> Word0;
 
-  bits<7> DST_GPR = 0;
-  bits<9> SRC0_SEL = 0;
-  bits<1> SRC0_NEG = 0;
-  bits<9> SRC1_SEL = 0;
-  bits<1> SRC1_NEG = 0;
-  bits<1> CLAMP = 0;
-  
+  bits<11> src0;
+  bits<1>  src0_neg;
+  bits<1>  src0_rel;
+  bits<11> src1;
+  bits<1>  src1_rel;
+  bits<1>  src1_neg;
+  bits<3>  index_mode = 0;
+  bits<2>  pred_sel;
+  bits<1>  last;
+
+  bits<9>  src0_sel  = src0{8-0};
+  bits<2>  src0_chan = src0{10-9};
+  bits<9>  src1_sel  = src1{8-0};
+  bits<2>  src1_chan = src1{10-9};
+
+  let Word0{8-0}   = src0_sel;
+  let Word0{9}     = src0_rel;
+  let Word0{11-10} = src0_chan;
+  let Word0{12}    = src0_neg;
+  let Word0{21-13} = src1_sel;
+  let Word0{22}    = src1_rel;
+  let Word0{24-23} = src1_chan;
+  let Word0{25}    = src1_neg;
+  let Word0{28-26} = index_mode;
+  let Word0{30-29} = pred_sel;
+  let Word0{31}    = last;
+}
+
+class R600ALU_Word1_OP2 <bits<11> alu_inst> {
+  field bits<32> Word1;
+
+  bits<1>  src0_abs;
+  bits<1>  src1_abs;
+  bits<1>  update_exec_mask = 0;
+  bits<1>  update_pred = 0;
+  bits<1>  write;
+  bits<2>  omod;
+  bits<3>  bank_swizzle = 0;
+  bits<11> dst;
+  bits<1>  dst_rel;
+  bits<1>  clamp;
+
+  bits<7>  dst_sel  = dst{6-0};
+  bits<2>  dst_chan = dst{10-9};
+
+  let Word1{0}     = src0_abs;
+  let Word1{1}     = src1_abs;
+  let Word1{2}     = update_exec_mask;
+  let Word1{3}     = update_pred;
+  let Word1{4}     = write;
+  let Word1{6-5}   = omod;
+  let Word1{17-7}  = alu_inst;
+  let Word1{20-18} = bank_swizzle;
+  let Word1{27-21} = dst_sel;
+  let Word1{28}    = dst_rel;
+  let Word1{30-29} = dst_chan;
+  let Word1{31}    = clamp;
+}
+
+/*
+XXX: R600 subtarget uses a slightly different encoding than the other
+subtargets.  We currently handle this in R600MCCodeEmitter, but we may
+want to use these instruction classes in the future.
+
+class R600ALU_Word1_OP2_r600 : R600ALU_Word1_OP2 {
+
+  bits<1>  fog_merge;
+  bits<10> alu_inst;
+
+  let Inst{37}    = fog_merge;
+  let Inst{39-38} = omod;
+  let Inst{49-40} = alu_inst;
 }
 
+class R600ALU_Word1_OP2_r700 : R600ALU_Word1_OP2 {
+
+  bits<11> alu_inst;
+
+  let Inst{38-37} = omod;
+  let Inst{49-39} = alu_inst;
+}
+*/
+
 def R600_Pred : PredicateOperand<i32, (ops R600_Predicate),
                                      (ops PRED_SEL_OFF)>;
 
 
 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
 
+// Class for instructions with only one source register.
+// If you add new ins to this instruction, make sure they are listed before
+// $literal, because the backend currently assumes that the last operand is
+// a literal.  Also be sure to update the enum R600Op1OperandIndex::ROI in
+// R600Defines.h, R600InstrInfo::buildDefaultInstruction(),
+// and R600InstrInfo::getOperandIdx().
 class R600_1OP <bits<11> inst, string opName, list<dag> pattern,
                 InstrItinClass itin = AnyALU> :
-  InstR600 <inst,
-          (outs R600_Reg32:$dst),
-          (ins R600_Reg32:$src, R600_Pred:$p, variable_ops),
-          !strconcat(opName, " $dst, $src $p"),
-          pattern,
-          itin>{
-    bits<7> dst;
-    bits<9> src;
-    let Inst{8-0}   = src;
-    let Inst{49-39} = inst;
-    let Inst{59-53} = dst;
-  }
+    InstR600 <0,
+              (outs R600_Reg32:$dst),
+              (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
+                   R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs,
+                   LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
+              !strconcat(opName,
+                   "$clamp $dst$write$dst_rel$omod, "
+                   "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
+                   "$literal $pred_sel$last"),
+              pattern,
+              itin>,
+    R600ALU_Word0,
+    R600ALU_Word1_OP2 <inst> {
+
+  let src1 = 0;
+  let src1_rel = 0;
+  let src1_neg = 0;
+  let src1_abs = 0;
+  let HasNativeOperands = 1;
+  let Op1 = 1;
+  let DisableEncoding = "$literal";
+
+  let Inst{31-0}  = Word0;
+  let Inst{63-32} = Word1;
+}
+
+class R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
+                    InstrItinClass itin = AnyALU> :
+    R600_1OP <inst, opName,
+              [(set R600_Reg32:$dst, (node R600_Reg32:$src0))]
+>;
 
 class R600_2OP <bits<11> inst, string opName, list<dag> pattern,
                 InstrItinClass itin = AnyALU> :
@@ -383,30 +508,11 @@
     COND_NE))]
 >;
 
-def FRACT : R600_1OP <
-  0x10, "FRACT",
-  [(set R600_Reg32:$dst, (AMDGPUfract R600_Reg32:$src))]
->;
-
-def TRUNC : R600_1OP <
-  0x11, "TRUNC",
-  [(set R600_Reg32:$dst, (int_AMDGPU_trunc R600_Reg32:$src))]
->;
-
-def CEIL : R600_1OP <
-  0x12, "CEIL",
-  [(set R600_Reg32:$dst, (fceil R600_Reg32:$src))]
->;
-
-def RNDNE : R600_1OP <
-  0x13, "RNDNE",
-  [(set R600_Reg32:$dst, (frint R600_Reg32:$src))]
->;
-
-def FLOOR : R600_1OP <
-  0x14, "FLOOR",
-  [(set R600_Reg32:$dst, (ffloor R600_Reg32:$src))]
->;
+def FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>;
+def TRUNC : R600_1OP_Helper <0x11, "TRUNC", int_AMDGPU_trunc>;
+def CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>;
+def RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>;
+def FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>;
 
 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
 
@@ -482,10 +588,7 @@
   [(set R600_Reg32:$dst, (xor R600_Reg32:$src0, R600_Reg32:$src1))]
 >;
 
-def NOT_INT : R600_1OP <
-  0x33, "NOT_INT",
-  [(set R600_Reg32:$dst, (not R600_Reg32:$src))]
->;
+def NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>;
 
 def ADD_INT : R600_2OP <
   0x34, "ADD_INT",
@@ -740,45 +843,34 @@
 }
 } // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
 
-class FLT_TO_INT_Common <bits<11> inst> : R600_1OP <
-  inst, "FLT_TO_INT",
-  [(set R600_Reg32:$dst, (fp_to_sint R600_Reg32:$src))]
+class EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "EXP_IEEE", fexp2
 >;
 
-class INT_TO_FLT_Common <bits<11> inst> : R600_1OP <
-  inst, "INT_TO_FLT",
-  [(set R600_Reg32:$dst, (sint_to_fp R600_Reg32:$src))]
+class FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "FLT_TO_INT", fp_to_sint
 >;
 
-class FLT_TO_UINT_Common <bits<11> inst> : R600_1OP <
-  inst, "FLT_TO_UINT",
-  [(set R600_Reg32:$dst, (fp_to_uint R600_Reg32:$src))]
+class INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "INT_TO_FLT", sint_to_fp
 >;
 
-class UINT_TO_FLT_Common <bits<11> inst> : R600_1OP <
-  inst, "UINT_TO_FLT",
-  [(set R600_Reg32:$dst, (uint_to_fp R600_Reg32:$src))]
+class FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "FLT_TO_UINT", fp_to_uint
 >;
 
-class LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
-  inst, "LOG_CLAMPED",
-  []
+class UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "UINT_TO_FLT", uint_to_fp
 >;
 
-let FlagOperandIdx = 3 in {
-
-class EXP_IEEE_Common <bits<11> inst> : R600_1OP <
-  inst, "EXP_IEEE",
-  [(set R600_Reg32:$dst, (fexp2 R600_Reg32:$src))]
+class LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
+  inst, "LOG_CLAMPED", []
 >;
 
-class LOG_IEEE_Common <bits<11> inst> : R600_1OP <
-  inst, "LOG_IEEE",
-  [(set R600_Reg32:$dst, (flog2 R600_Reg32:$src))]
+class LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "LOG_IEEE", flog2
 >;
 
-} // End let FlagOperandIdx = 3
-
 class LSHL_Common <bits<11> inst> : R600_2OP <
   inst, "LSHL $dst, $src0, $src1",
   [(set R600_Reg32:$dst, (shl R600_Reg32:$src0, R600_Reg32:$src1))]
@@ -815,32 +907,23 @@
 >;
 
 class RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP <
-  inst, "RECIP_CLAMPED",
-  []
+  inst, "RECIP_CLAMPED", []
 >;
 
-class RECIP_UINT_Common <bits<11> inst> : R600_1OP <
-  inst, "RECIP_INT $dst, $src",
-  [(set R600_Reg32:$dst, (AMDGPUurecip R600_Reg32:$src))]
+class RECIP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "RECIP_IEEE", int_AMDGPU_rcp
 >;
 
-let FlagOperandIdx = 3 in {
-
-class RECIP_IEEE_Common <bits<11> inst> : R600_1OP <
-  inst, "RECIP_IEEE",
-  [(set R600_Reg32:$dst, (int_AMDGPU_rcp R600_Reg32:$src))]
+class RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "RECIP_UINT", AMDGPUurecip
 >;
 
-class RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP <
-  inst, "RECIPSQRT_CLAMPED",
-  [(set R600_Reg32:$dst, (int_AMDGPU_rsq R600_Reg32:$src))]
+class RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper <
+  inst, "RECIPSQRT_CLAMPED", int_AMDGPU_rsq
 >;
 
-} // End let FlagOperandIdx = 3
-
 class RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP <
-  inst, "RECIPSQRT_IEEE",
-  []
+  inst, "RECIPSQRT_IEEE", []
 >;
 
 class SIN_Common <bits<11> inst> : R600_1OP <
@@ -1036,11 +1119,11 @@
   // XXX: Lowering SELECT_CC will sometimes generate fp_to_[su]int nodes,
   // which do not need to be truncated since the fp values are 0.0f or 1.0f.
   // We should look into handling these cases separately.
-  def : Pat<(fp_to_sint R600_Reg32:$src),
-    (FLT_TO_INT_eg (TRUNC R600_Reg32:$src))>;
+  def : Pat<(fp_to_sint R600_Reg32:$src0),
+    (FLT_TO_INT_eg (TRUNC R600_Reg32:$src0))>;
 
-  def : Pat<(fp_to_uint R600_Reg32:$src),
-    (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src))>;
+  def : Pat<(fp_to_uint R600_Reg32:$src0),
+    (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src0))>;
 
   def : Pat<(fsqrt R600_Reg32:$src),
     (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_eg R600_Reg32:$src))>;

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600RegisterInfo.td?rev=166326&r1=166325&r2=166326&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600RegisterInfo.td (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600RegisterInfo.td Fri Oct 19 16:10:04 2012
@@ -53,8 +53,8 @@
 def PV_X : R600Reg<"pv.x", 254>;
 def PREDICATE_BIT : R600Reg<"PredicateBit", 0>;
 def PRED_SEL_OFF: R600Reg<"Pred_sel_off", 0>;
-def PRED_SEL_ZERO : R600Reg<"Pred_sel_zero", 0>;
-def PRED_SEL_ONE : R600Reg<"Pred_sel_one", 0>;
+def PRED_SEL_ZERO : R600Reg<"Pred_sel_zero", 2>;
+def PRED_SEL_ONE : R600Reg<"Pred_sel_one", 3>;
 
 def R600_CReg32 : RegisterClass <"AMDGPU", [f32, i32], 32,
                           (add (interleave





More information about the llvm-branch-commits mailing list