TableGen: Allow target specific MCOI operand types

Tom Stellard tom at stellard.net
Tue Jan 6 07:59:31 PST 2015


Ping.

On Mon, Dec 29, 2014 at 09:26:26AM -0800, Tom Stellard wrote:
> Hi,
> 
> I'm resending these, in case the they were lost during the mailing
> list outage.
> 
> The attached patches allow targets to specify their own operand types
> to be used in MCOperandInfo objects.  The first patch makes this
> change to tablegen, and the second updates the R600 backend to take
> advantage of this.
> 
> This replaces my previous patch which added an AsmOperandClass member
> to the TableGen Register class.
> 
> -Tom
> 

> From ed48732f4e73d25e4bd2209e81bad46732d8eb95 Mon Sep 17 00:00:00 2001
> From: Tom Stellard <thomas.stellard at amd.com>
> Date: Sat, 15 Nov 2014 16:44:52 -0500
> Subject: [PATCH] Target: Allow target specific operand types
> 
> This adds two new fields to the RegisterOperand TableGen class:
> 
> string OperandNamespace = "MCOI";
> string OperandType = "OPERAND_REGISTER";
> 
> These fields can be used to specify a target specific operand type,
> which will be stored in the OperandType member of the MCOperandInfo
> object.
> 
> This can be useful for targets that need to store some extra information
> about operands that cannot be expressed using the target independent
> types.  For example, in the R600 backend, there are operands which
> can take either registers or immediates and it is convenient to be able
> to specify this in the TableGen definitions.
> ---
>  include/llvm/MC/MCInstrDesc.h         | 11 ++++++-----
>  include/llvm/Target/Target.td         |  3 +++
>  utils/TableGen/CodeGenInstruction.cpp |  7 +++++--
>  utils/TableGen/InstrInfoEmitter.cpp   |  2 +-
>  4 files changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
> index d4f93c1..3609893 100644
> --- a/include/llvm/MC/MCInstrDesc.h
> +++ b/include/llvm/MC/MCInstrDesc.h
> @@ -44,11 +44,12 @@ namespace MCOI {
>  
>    /// Operand Type - Operands are tagged with one of the values of this enum.
>    enum OperandType {
> -    OPERAND_UNKNOWN,
> -    OPERAND_IMMEDIATE,
> -    OPERAND_REGISTER,
> -    OPERAND_MEMORY,
> -    OPERAND_PCREL
> +    OPERAND_UNKNOWN      = 0,
> +    OPERAND_IMMEDIATE    = 1,
> +    OPERAND_REGISTER     = 2,
> +    OPERAND_MEMORY       = 3,
> +    OPERAND_PCREL        = 4,
> +    OPERAND_FIRST_TARGET = 5
>    };
>  }
>  
> diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
> index 688c03f..7a5ae09 100644
> --- a/include/llvm/Target/Target.td
> +++ b/include/llvm/Target/Target.td
> @@ -624,6 +624,9 @@ class RegisterOperand<RegisterClass regclass, string pm = "printOperand">
>    // can match a subset of some other class, in which case the AsmOperandClass
>    // should declare the other operand as one of its super classes.
>    AsmOperandClass ParserMatchClass;
> +
> +  string OperandNamespace = "MCOI";
> +  string OperandType = "OPERAND_REGISTER";
>  }
>  
>  let OperandType = "OPERAND_IMMEDIATE" in {
> diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
> index 7c5e6fc..aa06a29 100644
> --- a/utils/TableGen/CodeGenInstruction.cpp
> +++ b/utils/TableGen/CodeGenInstruction.cpp
> @@ -68,10 +68,13 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
>      std::string PrintMethod = "printOperand";
>      std::string EncoderMethod;
>      std::string OperandType = "OPERAND_UNKNOWN";
> +    std::string OperandNamespace = "MCOI";
>      unsigned NumOps = 1;
>      DagInit *MIOpInfo = nullptr;
>      if (Rec->isSubClassOf("RegisterOperand")) {
>        PrintMethod = Rec->getValueAsString("PrintMethod");
> +      OperandType = Rec->getValueAsString("OperandType");
> +      OperandNamespace = Rec->getValueAsString("OperandNamespace");
>      } else if (Rec->isSubClassOf("Operand")) {
>        PrintMethod = Rec->getValueAsString("PrintMethod");
>        OperandType = Rec->getValueAsString("OperandType");
> @@ -113,8 +116,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
>                        Twine(i) + " has the same name as a previous operand!");
>  
>      OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
> -                                      OperandType, MIOperandNo, NumOps,
> -                                      MIOpInfo));
> +                                      OperandNamespace + "::" + OperandType,
> +				      MIOperandNo, NumOps, MIOpInfo));
>      MIOperandNo += NumOps;
>    }
>  
> diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
> index 36afd61..fe30d60 100644
> --- a/utils/TableGen/InstrInfoEmitter.cpp
> +++ b/utils/TableGen/InstrInfoEmitter.cpp
> @@ -143,7 +143,7 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
>          Res += "|(1<<MCOI::OptionalDef)";
>  
>        // Fill in operand type.
> -      Res += ", MCOI::";
> +      Res += ", ";
>        assert(!Op.OperandType.empty() && "Invalid operand type.");
>        Res += Op.OperandType;
>  
> -- 
> 1.8.1.5
> 

> From 1e3aecfb8ba4367ac22863a6b3f11b9feea4f4d7 Mon Sep 17 00:00:00 2001
> From: Tom Stellard <thomas.stellard at amd.com>
> Date: Thu, 11 Dec 2014 16:19:16 -0500
> Subject: [PATCH] R600/SI: Use RegisterOperands to specify which operands can
>  accept immediates
> 
> There are some operands which can take either immediates or registers
> and we were previously using different register class to distinguish
> between operands that could take immediates and those that could not.
> 
> This patch switches to using RegisterOperands which should simplify the
> backend by reducing the number of register classes and also make it
> easier to implement the assembler.
> ---
>  lib/Target/R600/AMDGPUISelDAGToDAG.cpp             |  4 ++-
>  .../R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp       |  1 +
>  lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp   | 16 ++++++----
>  lib/Target/R600/SIDefines.h                        | 19 ++++++++++++
>  lib/Target/R600/SIISelLowering.cpp                 |  6 ++--
>  lib/Target/R600/SIInstrInfo.cpp                    |  4 +--
>  lib/Target/R600/SIInstrInfo.td                     | 22 +++++++-------
>  lib/Target/R600/SIRegisterInfo.cpp                 | 33 ++++-----------------
>  lib/Target/R600/SIRegisterInfo.h                   | 16 +++-------
>  lib/Target/R600/SIRegisterInfo.td                  | 34 ++++++++++++++++++----
>  test/CodeGen/R600/srl.ll                           |  2 +-
>  test/CodeGen/R600/sub.ll                           |  2 +-
>  test/CodeGen/R600/xor.ll                           |  2 +-
>  13 files changed, 88 insertions(+), 73 deletions(-)
> 
> diff --git a/lib/Target/R600/AMDGPUISelDAGToDAG.cpp b/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
> index ad5a541..10c5b47 100644
> --- a/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
> +++ b/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
> @@ -1083,7 +1083,9 @@ SDNode *AMDGPUDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
>    if (DestSize > SrcSize) {
>      assert(SrcSize == 32 && DestSize == 64);
>  
> -    SDValue RC = CurDAG->getTargetConstant(AMDGPU::VSrc_64RegClassID, MVT::i32);
> +    // FIXME: This is probably wrong, we should never be defining
> +    // a register class with both VGPRs and SGPRs
> +    SDValue RC = CurDAG->getTargetConstant(AMDGPU::VS_64RegClassID, MVT::i32);
>  
>      const SDValue Ops[] = {
>        RC,
> diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp
> index 8731055..bbcce02 100644
> --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp
> +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp
> @@ -14,6 +14,7 @@
>  
>  #include "AMDGPUMCTargetDesc.h"
>  #include "AMDGPUMCAsmInfo.h"
> +#include "SIDefines.h"
>  #include "InstPrinter/AMDGPUInstPrinter.h"
>  #include "llvm/MC/MCCodeGenInfo.h"
>  #include "llvm/MC/MCInstrInfo.h"
> diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> index 999fd0d..3189952 100644
> --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> @@ -86,12 +86,16 @@ MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
>  bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
>                                     unsigned OpNo) const {
>    unsigned RegClass = Desc.OpInfo[OpNo].RegClass;
> -  return (AMDGPU::SSrc_32RegClassID == RegClass) ||
> -         (AMDGPU::SSrc_64RegClassID == RegClass) ||
> -         (AMDGPU::VSrc_32RegClassID == RegClass) ||
> -         (AMDGPU::VSrc_64RegClassID == RegClass) ||
> -	 (AMDGPU::VCSrc_32RegClassID == RegClass) ||
> -	 (AMDGPU::VCSrc_64RegClassID == RegClass);
> +  unsigned OpType = Desc.OpInfo[OpNo].OperandType;
> +
> +  return (OpType == AMDGPU::OPERAND_REG_IMM32 &&
> +            (AMDGPU::SReg_32RegClassID == RegClass ||
> +            AMDGPU::SReg_64RegClassID == RegClass ||
> +            AMDGPU::VS_32RegClassID == RegClass ||
> +            AMDGPU::VS_64RegClassID == RegClass)) ||
> +         (OpType == AMDGPU::OPERAND_REG_INLINE_C &&
> +            (AMDGPU::VS_32RegClassID == RegClass ||
> +            (AMDGPU::VS_64RegClassID == RegClass)));
>  }
>  
>  uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const {
> diff --git a/lib/Target/R600/SIDefines.h b/lib/Target/R600/SIDefines.h
> index 759ed1b..09322e5 100644
> --- a/lib/Target/R600/SIDefines.h
> +++ b/lib/Target/R600/SIDefines.h
> @@ -8,6 +8,8 @@
>  /// \file
>  //===----------------------------------------------------------------------===//
>  
> +#include "llvm/MC/MCInstrDesc.h"
> +
>  #ifndef LLVM_LIB_TARGET_R600_SIDEFINES_H
>  #define LLVM_LIB_TARGET_R600_SIDEFINES_H
>  
> @@ -37,6 +39,23 @@ enum {
>  };
>  }
>  
> +namespace llvm {
> +namespace AMDGPU {
> +  enum OperandType {
> +    /// Operand with an SGPR or 32-bit immediate
> +    OPERAND_SSRC = llvm::MCOI::OPERAND_FIRST_TARGET,
> +    /// Operand with SGPR, VGPR, or 32-bit immediate
> +    OPERAND_VSRC,
> +    /// Operand with SGPR, VGPR, or inline constant
> +    OPERAND_VCSRC,
> +    /// Operand with register or 32-bit immediate
> +    OPERAND_REG_IMM32,
> +    /// Operand with register or inline constant
> +    OPERAND_REG_INLINE_C
> +  };
> +}
> +}
> +
>  namespace SIInstrFlags {
>    enum Flags {
>      // First 4 bits are the instruction encoding
> diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp
> index 19a8423..78ea49f 100644
> --- a/lib/Target/R600/SIISelLowering.cpp
> +++ b/lib/Target/R600/SIISelLowering.cpp
> @@ -1560,10 +1560,8 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
>  static bool isVSrc(unsigned RegClass) {
>    switch(RegClass) {
>      default: return false;
> -    case AMDGPU::VSrc_32RegClassID:
> -    case AMDGPU::VCSrc_32RegClassID:
> -    case AMDGPU::VSrc_64RegClassID:
> -    case AMDGPU::VCSrc_64RegClassID:
> +    case AMDGPU::VS_32RegClassID:
> +    case AMDGPU::VS_64RegClassID:
>        return true;
>    }
>  }
> diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp
> index 32b29a5..c0fb68e 100644
> --- a/lib/Target/R600/SIInstrInfo.cpp
> +++ b/lib/Target/R600/SIInstrInfo.cpp
> @@ -966,9 +966,9 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
>      return false;
>  
>    if (isLiteralConstant(MO))
> -    return RI.regClassCanUseLiteralConstant(OpInfo.RegClass);
> +    return RI.opCanUseLiteralConstant(OpInfo.OperandType);
>  
> -  return RI.regClassCanUseInlineConstant(OpInfo.RegClass);
> +  return RI.opCanUseInlineConstant(OpInfo.OperandType);
>  }
>  
>  bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const {
> diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td
> index 27a63c0..aa40378 100644
> --- a/lib/Target/R600/SIInstrInfo.td
> +++ b/lib/Target/R600/SIInstrInfo.td
> @@ -487,7 +487,7 @@ multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> {
>  }
>  
>  
> -class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
> +class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
>                      string opName, PatLeaf cond> : SOPC <
>    op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
>    opName#" $dst, $src0, $src1", []>;
> @@ -613,7 +613,7 @@ class getVALUDstForVT<ValueType VT> {
>  // Returns the register class to use for source 0 of VOP[12C]
>  // instructions for the given VT.
>  class getVOPSrc0ForVT<ValueType VT> {
> -  RegisterClass ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
> +  RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
>  }
>  
>  // Returns the register class to use for source 1 of VOP[12C] for the
> @@ -625,7 +625,7 @@ class getVOPSrc1ForVT<ValueType VT> {
>  // Returns the register class to use for sources of VOP3 instructions for the
>  // given VT.
>  class getVOP3SrcForVT<ValueType VT> {
> -  RegisterClass ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
> +  RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
>  }
>  
>  // Returns 1 if the source arguments have modifiers, 0 if they do not.
> @@ -635,15 +635,15 @@ class hasModifiers<ValueType SrcVT> {
>  }
>  
>  // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
> -class getIns32 <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
> +class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
>    dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
>              !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
>                                      (ins)));
>  }
>  
>  // Returns the input arguments for VOP3 instructions for the given SrcVT.
> -class getIns64 <RegisterClass Src0RC, RegisterClass Src1RC,
> -                RegisterClass Src2RC, int NumSrcArgs,
> +class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
> +                RegisterOperand Src2RC, int NumSrcArgs,
>                  bit HasModifiers> {
>  
>    dag ret =
> @@ -714,11 +714,11 @@ class VOPProfile <list<ValueType> _ArgVT> {
>    field ValueType Src1VT = ArgVT[2];
>    field ValueType Src2VT = ArgVT[3];
>    field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret;
> -  field RegisterClass Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
> +  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
>    field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
> -  field RegisterClass Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
> -  field RegisterClass Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
> -  field RegisterClass Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
> +  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
> +  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
> +  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
>  
>    field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
>    field bit HasModifiers = hasModifiers<Src0VT>.ret;
> @@ -1178,7 +1178,7 @@ class VOP3InstVI <bits<10> op, string opName, VOPProfile P,
>    P.NumSrcArgs, P.HasModifiers
>  >;
>  
> -multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterClass arc,
> +multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
>                      string opName, list<dag> pattern> :
>    VOP3b_2_m <
>    op, (outs vrc:$vdst, SReg_64:$sdst),
> diff --git a/lib/Target/R600/SIRegisterInfo.cpp b/lib/Target/R600/SIRegisterInfo.cpp
> index 5dc0f75..4ef6673 100644
> --- a/lib/Target/R600/SIRegisterInfo.cpp
> +++ b/lib/Target/R600/SIRegisterInfo.cpp
> @@ -390,40 +390,17 @@ unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
>    return SubRC->getRegister(Index + Channel);
>  }
>  
> -bool SIRegisterInfo::regClassCanUseLiteralConstant(int RCID) const {
> -  switch (RCID) {
> -  default: return false;
> -  case AMDGPU::SSrc_32RegClassID:
> -  case AMDGPU::SSrc_64RegClassID:
> -  case AMDGPU::VSrc_32RegClassID:
> -  case AMDGPU::VSrc_64RegClassID:
> -    return true;
> -  }
> +bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const {
> +  return OpType == AMDGPU::OPERAND_REG_IMM32;
>  }
>  
> -bool SIRegisterInfo::regClassCanUseLiteralConstant(
> -                             const TargetRegisterClass *RC) const {
> -  return regClassCanUseLiteralConstant(RC->getID());
> -}
> -
> -bool SIRegisterInfo::regClassCanUseInlineConstant(int RCID) const {
> -  if (regClassCanUseLiteralConstant(RCID))
> +bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const {
> +  if (opCanUseLiteralConstant(OpType))
>      return true;
>  
> -  switch (RCID) {
> -  default: return false;
> -  case AMDGPU::VCSrc_32RegClassID:
> -  case AMDGPU::VCSrc_64RegClassID:
> -    return true;
> -  }
> -}
> -
> -bool SIRegisterInfo::regClassCanUseInlineConstant(
> -                            const TargetRegisterClass *RC) const {
> -  return regClassCanUseInlineConstant(RC->getID());
> +  return OpType == AMDGPU::OPERAND_REG_INLINE_C;
>  }
>  
> -
>  unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
>                                             enum PreloadedValue Value) const {
>  
> diff --git a/lib/Target/R600/SIRegisterInfo.h b/lib/Target/R600/SIRegisterInfo.h
> index c7e54db..0f11687 100644
> --- a/lib/Target/R600/SIRegisterInfo.h
> +++ b/lib/Target/R600/SIRegisterInfo.h
> @@ -80,22 +80,14 @@ struct SIRegisterInfo : public AMDGPURegisterInfo {
>    unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC,
>                              unsigned Channel) const;
>  
> -  /// \returns True if operands defined with this register class can accept
> +  /// \returns True if operands defined with this operand type can accept
>    /// a literal constant (i.e. any 32-bit immediate).
> -  bool regClassCanUseLiteralConstant(int RCID) const;
> +  bool opCanUseLiteralConstant(unsigned OpType) const;
>  
> -  /// \returns True if operands defined with this register class can accept
> -  /// a literal constant (i.e. any 32-bit immediate).
> -  bool regClassCanUseLiteralConstant(const TargetRegisterClass *RC) const;
> -
> -  /// \returns True if operands defined with this register class can accept
> +  /// \returns True if operands defined with this operand type can accept
>    /// an inline constant. i.e. An integer value in the range (-16, 64) or
>    /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 
> -  bool regClassCanUseInlineConstant(int RCID) const;
> -
> -  /// \returns True if operands defined with this register class can accept
> -  /// a literal constant. i.e. A value in the range (-16, 64).
> -  bool regClassCanUseInlineConstant(const TargetRegisterClass *RC) const;
> +  bool opCanUseInlineConstant(unsigned OpType) const;
>  
>    enum PreloadedValue {
>      TGID_X,
> diff --git a/lib/Target/R600/SIRegisterInfo.td b/lib/Target/R600/SIRegisterInfo.td
> index 45c2b41..f938ed6 100644
> --- a/lib/Target/R600/SIRegisterInfo.td
> +++ b/lib/Target/R600/SIRegisterInfo.td
> @@ -217,25 +217,47 @@ def VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add VGPR_32)>;
>  //  SSrc_* Operands with an SGPR or a 32-bit immediate
>  //===----------------------------------------------------------------------===//
>  
> -def SSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add SReg_32)>;
> +def SSrc_32 : RegisterOperand<SReg_32> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_IMM32";
> +}
>  
> -def SSrc_64 : RegisterClass<"AMDGPU", [i64, f64, i1], 64, (add SReg_64)>;
> +def SSrc_64 : RegisterOperand<SReg_64> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_IMM32";
> +}
>  
>  //===----------------------------------------------------------------------===//
>  //  VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate
>  //===----------------------------------------------------------------------===//
>  
> -def VSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
> +def VS_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
> +
> +def VS_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
> +
> +def VSrc_32 : RegisterOperand<VS_32> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_IMM32";
> +}
>  
> -def VSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
> +def VSrc_64 : RegisterOperand<VS_64> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_IMM32";
> +}
>  
>  //===----------------------------------------------------------------------===//
>  //  VCSrc_* Operands with an SGPR, VGPR or an inline constant
>  //===----------------------------------------------------------------------===//
>  
> -def VCSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
> +def VCSrc_32 : RegisterOperand<VS_32> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_INLINE_C";
> +}
>  
> -def VCSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
> +def VCSrc_64 : RegisterOperand<VS_64> {
> +  let OperandNamespace = "AMDGPU";
> +  let OperandType = "OPERAND_REG_INLINE_C";
> +}
>  
>  //===----------------------------------------------------------------------===//
>  // SGPR and VGPR register classes
> diff --git a/test/CodeGen/R600/srl.ll b/test/CodeGen/R600/srl.ll
> index bb68cbf..3b19c15 100644
> --- a/test/CodeGen/R600/srl.ll
> +++ b/test/CodeGen/R600/srl.ll
> @@ -2,7 +2,7 @@
>  ; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
>  
>  ; FUNC-LABEL: {{^}}lshr_i32:
> -; SI: v_lshr_b32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
> +; SI: v_lshrrev_b32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
>  ; EG: LSHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
>  define void @lshr_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
>    %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1
> diff --git a/test/CodeGen/R600/sub.ll b/test/CodeGen/R600/sub.ll
> index 1f129a6..5d7bc00 100644
> --- a/test/CodeGen/R600/sub.ll
> +++ b/test/CodeGen/R600/sub.ll
> @@ -7,7 +7,7 @@ declare i32 @llvm.r600.read.tidig.x() readnone
>  ; FUNC-LABEL: {{^}}test_sub_i32:
>  ; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
>  
> -; SI: v_sub_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
> +; SI: v_subrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
>  define void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
>    %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1
>    %a = load i32 addrspace(1)* %in
> diff --git a/test/CodeGen/R600/xor.ll b/test/CodeGen/R600/xor.ll
> index bf98e7d..d6816c8 100644
> --- a/test/CodeGen/R600/xor.ll
> +++ b/test/CodeGen/R600/xor.ll
> @@ -59,7 +59,7 @@ define void @xor_i1(float addrspace(1)* %out, float addrspace(1)* %in0, float ad
>  ; FUNC-LABEL: {{^}}v_xor_i1:
>  ; SI: buffer_load_ubyte [[A:v[0-9]+]]
>  ; SI: buffer_load_ubyte [[B:v[0-9]+]]
> -; SI: v_xor_b32_e32 [[XOR:v[0-9]+]], [[B]], [[A]]
> +; SI: v_xor_b32_e32 [[XOR:v[0-9]+]], [[A]], [[B]]
>  ; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[XOR]]
>  ; SI: buffer_store_byte [[RESULT]]
>  define void @v_xor_i1(i1 addrspace(1)* %out, i1 addrspace(1)* %in0, i1 addrspace(1)* %in1) {
> -- 
> 1.8.1.5
> 

> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list