[llvm] 40114dd - [SPIR-V](2/6) Add SPIRV target description files

Michal Paszkowski via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 19 16:28:07 PDT 2022


Author: Ilia Diachkov
Date: 2022-04-20T01:10:25+02:00
New Revision: 40114dd5bf41f0d504a45ee5f7de9663d85251b8

URL: https://github.com/llvm/llvm-project/commit/40114dd5bf41f0d504a45ee5f7de9663d85251b8
DIFF: https://github.com/llvm/llvm-project/commit/40114dd5bf41f0d504a45ee5f7de9663d85251b8.diff

LOG: [SPIR-V](2/6) Add SPIRV target description files

Differential Revision: https://reviews.llvm.org/D115786

Authors: Aleksandr Bezzubikov, Lewis Crawford, Ilia Diachkov,
Michal Paszkowski, Andrey Tretyakov, Konrad Trifunovic

Co-authored-by: Aleksandr Bezzubikov <zuban32s at gmail.com>
Co-authored-by: Ilia Diachkov <iliya.diyachkov at intel.com>
Co-authored-by: Michal Paszkowski <michal.paszkowski at outlook.com>
Co-authored-by: Andrey Tretyakov <andrey1.tretyakov at intel.com>
Co-authored-by: Konrad Trifunovic <konrad.trifunovic at intel.com>

Added: 
    llvm/lib/Target/SPIRV/SPIRV.td
    llvm/lib/Target/SPIRV/SPIRVEnums.td
    llvm/lib/Target/SPIRV/SPIRVInstrFormats.td
    llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
    llvm/lib/Target/SPIRV/SPIRVRegisterBanks.td
    llvm/lib/Target/SPIRV/SPIRVRegisterInfo.td

Modified: 
    llvm/lib/Target/SPIRV/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt
index ebda7593539b4..a0b3fe50df134 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -1,5 +1,17 @@
 add_llvm_component_group(SPIRV)
 
+set(LLVM_TARGET_DEFINITIONS SPIRV.td)
+
+tablegen(LLVM SPIRVGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM SPIRVGenGlobalISel.inc -gen-global-isel)
+tablegen(LLVM SPIRVGenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM SPIRVGenMCCodeEmitter.inc -gen-emitter)
+tablegen(LLVM SPIRVGenRegisterBank.inc -gen-register-bank)
+tablegen(LLVM SPIRVGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM SPIRVGenSubtargetInfo.inc -gen-subtarget)
+
+add_public_tablegen_target(SPIRVCommonTableGen)
+
 add_llvm_target(SPIRVCodeGen
   SPIRVTargetMachine.cpp
 

diff  --git a/llvm/lib/Target/SPIRV/SPIRV.td b/llvm/lib/Target/SPIRV/SPIRV.td
new file mode 100644
index 0000000000000..27374acb8882e
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRV.td
@@ -0,0 +1,43 @@
+//===-- SPIRV.td - Describe the SPIR-V Target Machine ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/Target.td"
+
+include "SPIRVRegisterInfo.td"
+include "SPIRVRegisterBanks.td"
+include "SPIRVInstrInfo.td"
+
+def SPIRVInstrInfo : InstrInfo;
+
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+def : Proc<"generic", []>;
+
+def SPIRV10 : SubtargetFeature<"spirv1.0", "SPIRVVersion", "10",
+                             "Use SPIR-V version 1.0">;
+def SPIRV11 : SubtargetFeature<"spirv1.1", "SPIRVVersion", "11",
+                             "Use SPIR-V version 1.1">;
+def SPIRV12 : SubtargetFeature<"spirv1.2", "SPIRVVersion", "12",
+                             "Use SPIR-V version 1.2">;
+def SPIRV13 : SubtargetFeature<"spirv1.3", "SPIRVVersion", "13",
+                             "Use SPIR-V version 1.3">;
+def SPIRV14 : SubtargetFeature<"spirv1.4", "SPIRVVersion", "14",
+                             "Use SPIR-V version 1.4">;
+def SPIRV15 : SubtargetFeature<"spirv1.5", "SPIRVVersion", "15",
+                             "Use SPIR-V version 1.5">;
+
+def SPIRVInstPrinter : AsmWriter {
+  string AsmWriterClassName  = "InstPrinter";
+  bit isMCAsmWriter = 1;
+}
+
+def SPIRV : Target {
+  let InstructionSet = SPIRVInstrInfo;
+  let AssemblyWriters = [SPIRVInstPrinter];
+}

diff  --git a/llvm/lib/Target/SPIRV/SPIRVEnums.td b/llvm/lib/Target/SPIRV/SPIRVEnums.td
new file mode 100644
index 0000000000000..1d0c6ffd6e37f
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVEnums.td
@@ -0,0 +1,51 @@
+//===-- SPIRVEnums.td - Describe SPIRV Enum Operands -------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// All SPIRV enums defined in SPIRVBaseInfo.h should have a corresponding enum
+// operand here. This enables the correct PrintMethod to be defined so
+// its name or mask bits can be automatically printed in SPIRVInstPrinter
+// when referred to in SPIRVInstrInfo.td.
+//
+//===----------------------------------------------------------------------===//
+
+class EnumOperand<string Name> : Operand<i32>{
+  let PrintMethod = "print"#Name;
+}
+
+def ExtInst : EnumOperand<"ExtInst">;
+
+def Capability : EnumOperand<"Capability">;
+def SourceLanguage : EnumOperand<"SourceLanguage">;
+def ExecutionModel : EnumOperand<"ExecutionModel">;
+def AddressingModel : EnumOperand<"AddressingModel">;
+def MemoryModel : EnumOperand<"MemoryModel">;
+def ExecutionMode : EnumOperand<"ExecutionMode">;
+def StorageClass : EnumOperand<"StorageClass">;
+def Dim : EnumOperand<"Dim">;
+def SamplerAddressingMode : EnumOperand<"SamplerAddressingMode">;
+def SamplerFilterMode : EnumOperand<"SamplerFilterMode">;
+def ImageFormat : EnumOperand<"ImageFormat">;
+def ImageChannelOrder : EnumOperand<"ImageChannelOrder">;
+def ImageChannelDataType : EnumOperand<"ImageChannelDataType">;
+def ImageOperand : EnumOperand<"ImageOperand">;
+def FPFastMathMode : EnumOperand<"FPFastMathMode">;
+def FProundingMode : EnumOperand<"FPRoundingMode">;
+def LinkageType : EnumOperand<"LinkageType">;
+def AccessQualifier : EnumOperand<"AccessQualifier">;
+def FunctionParameterAttribute : EnumOperand<"FunctionParameterAttribute">;
+def Decoration : EnumOperand<"Decoration">;
+def Builtin : EnumOperand<"Builtin">;
+def SelectionControl: EnumOperand<"SelectionControl">;
+def LoopControl: EnumOperand<"LoopControl">;
+def FunctionControl : EnumOperand<"FunctionControl">;
+def MemorySemantics : EnumOperand<"MemorySemantics">;
+def MemoryOperand : EnumOperand<"MemoryOperand">;
+def Scope : EnumOperand<"Scope">;
+def GroupOperation : EnumOperand<"GroupOperation">;
+def KernelEnqueueFlags : EnumOperand<"KernelEnqueueFlags">;
+def KernelProfilingInfo : EnumOperand<"KernelProfilingInfo">;

diff  --git a/llvm/lib/Target/SPIRV/SPIRVInstrFormats.td b/llvm/lib/Target/SPIRV/SPIRVInstrFormats.td
new file mode 100644
index 0000000000000..c78c8ee115901
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrFormats.td
@@ -0,0 +1,31 @@
+//===-- SPIRVInstrFormats.td - SPIR-V Instruction Formats --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+def StringImm: Operand<i32>{
+  let PrintMethod="printStringImm";
+}
+
+class Op<bits<16> Opcode, dag outs, dag ins, string asmstr, list<dag> pattern = []>
+  : Instruction {
+  field bits<16> Inst;
+
+  let Inst = Opcode;
+
+  let Namespace = "SPIRV";
+  let DecoderNamespace = "SPIRV";
+
+  dag OutOperandList = outs;
+  dag InOperandList = ins;
+  let AsmString = asmstr;
+  let Pattern = pattern;
+}
+
+// Pseudo instructions
+class Pseudo<dag outs, dag ins> : Op<0, outs, ins, ""> {
+  let isPseudo = 1;
+}

diff  --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
new file mode 100644
index 0000000000000..d6fec5fd07855
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -0,0 +1,732 @@
+//===-- SPIRVInstrInfo.td - Target Description for SPIR-V Target ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the SPIR-V instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+include "SPIRVInstrFormats.td"
+include "SPIRVEnums.td"
+
+// Codegen only metadata instructions
+let isCodeGenOnly=1 in {
+  def ASSIGN_TYPE: Pseudo<(outs ANYID:$dst_id), (ins ANYID:$src_id, TYPE:$src_ty)>;
+  def DECL_TYPE: Pseudo<(outs ANYID:$dst_id), (ins ANYID:$src_id, TYPE:$src_ty)>;
+  def GET_ID: Pseudo<(outs ID:$dst_id), (ins ANYID:$src)>;
+  def GET_fID: Pseudo<(outs fID:$dst_id), (ins ANYID:$src)>;
+  def GET_pID: Pseudo<(outs pID:$dst_id), (ins ANYID:$src)>;
+  def GET_vID: Pseudo<(outs vID:$dst_id), (ins ANYID:$src)>;
+  def GET_vfID: Pseudo<(outs vfID:$dst_id), (ins ANYID:$src)>;
+}
+
+def SPVTypeBin : SDTypeProfile<1, 2, []>;
+
+def assigntype : SDNode<"SPIRVISD::AssignType", SPVTypeBin>;
+
+def : GINodeEquiv<ASSIGN_TYPE, assigntype>;
+
+class BinOp<string name, bits<16> opCode, list<dag> pattern=[]>
+                : Op<opCode, (outs ANYID:$dst), (ins TYPE:$src_ty, ANYID:$src, ANYID:$src2),
+                  "$dst = "#name#" $src_ty $src $src2", pattern>;
+
+class BinOpTyped<string name, bits<16> opCode, RegisterClass CID, SDNode node>
+                : Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, CID:$src, CID:$src2),
+                  "$dst = "#name#" $src_ty $src $src2", [(set ID:$dst, (assigntype (node CID:$src, CID:$src2), TYPE:$src_ty))]>;
+
+class TernOpTyped<string name, bits<16> opCode, RegisterClass CCond, RegisterClass CID, SDNode node>
+                : Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, CCond:$cond, CID:$src1, CID:$src2),
+                  "$dst = "#name#" $src_ty $cond $src1 $src2", [(set ID:$dst, (assigntype (node CCond:$cond, CID:$src1, CID:$src2), TYPE:$src_ty))]>;
+
+multiclass BinOpTypedGen<string name, bits<16> opCode, SDNode node, bit genF = 0, bit genV = 0> {
+  if genF then
+    def S: BinOpTyped<name, opCode, fID, node>;
+  else
+    def S: BinOpTyped<name, opCode, ID, node>;
+  if genV then {
+    if genF then
+      def V: BinOpTyped<name, opCode, vfID, node>;
+    else
+      def V: BinOpTyped<name, opCode, vID, node>;
+  }
+}
+
+multiclass TernOpTypedGen<string name, bits<16> opCode, SDNode node, bit genI = 1, bit genF = 0, bit genV = 0> {
+  if genF then {
+    def SFSCond: TernOpTyped<name, opCode, ID, fID, node>;
+    def SFVCond: TernOpTyped<name, opCode, vID, fID, node>;
+  }
+  if genI then {
+    def SISCond: TernOpTyped<name, opCode, ID, ID, node>;
+    def SIVCond: TernOpTyped<name, opCode, vID, ID, node>;
+  }
+  if genV then {
+    if genF then {
+      def VFSCond: TernOpTyped<name, opCode, ID, vfID, node>;
+      def VFVCond: TernOpTyped<name, opCode, vID, vfID, node>;
+    }
+    if genI then {
+      def VISCond: TernOpTyped<name, opCode, ID, vID, node>;
+      def VIVCond: TernOpTyped<name, opCode, vID, vID, node>;
+    }
+  }
+}
+
+class UnOp<string name, bits<16> opCode, list<dag> pattern=[]>
+                : Op<opCode, (outs ANYID:$dst), (ins TYPE:$type, ANYID:$src),
+                  "$dst = "#name#" $type $src", pattern>;
+class UnOpTyped<string name, bits<16> opCode, RegisterClass CID, SDNode node>
+                : Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, CID:$src),
+                  "$dst = "#name#" $src_ty $src", [(set ID:$dst, (assigntype (node CID:$src), TYPE:$src_ty))]>;
+
+class SimpleOp<string name, bits<16> opCode>: Op<opCode, (outs), (ins), name>;
+
+// 3.42.1 Miscellaneous Instructions
+
+def OpNop: SimpleOp<"OpNop", 0>;
+def OpUndef: Op<1, (outs ID:$res), (ins TYPE:$type), "$res = OpUndef $type">;
+def OpSizeOf: Op<321, (outs ID:$res), (ins TYPE:$ty, ID:$ptr), "$res = OpSizeOf $ty $ptr">;
+
+// 3.42.2 Debug Instructions
+
+def OpSourceContinued: Op<2, (outs), (ins StringImm:$str, variable_ops),
+                  "OpSourceContinued $str">;
+def OpSource: Op<3, (outs), (ins SourceLanguage:$lang, i32imm:$version, variable_ops),
+                  "OpSource $lang $version">;
+def OpSourceExtension: Op<4, (outs), (ins StringImm:$extension, variable_ops),
+                  "OpSourceExtension $extension">;
+def OpName: Op<5, (outs), (ins ANY:$tar, StringImm:$name, variable_ops), "OpName $tar $name">;
+def OpMemberName: Op<6, (outs), (ins TYPE:$ty, i32imm:$mem, StringImm:$name, variable_ops),
+                  "OpMemberName $ty $mem $name">;
+def OpString: Op<7, (outs ID:$r), (ins StringImm:$s, variable_ops), "$r = OpString $s">;
+def OpLine: Op<8, (outs), (ins ID:$file, i32imm:$ln, i32imm:$col), "OpLine $file $ln $col">;
+def OpNoLine: Op<317, (outs), (ins), "OpNoLine">;
+def OpModuleProcessed: Op<330, (outs), (ins StringImm:$process, variable_ops),
+                  "OpModuleProcessed $process">;
+
+// 3.42.3 Annotation Instructions
+
+def OpDecorate: Op<71, (outs), (ins ANY:$target, Decoration:$dec, variable_ops),
+                  "OpDecorate $target $dec">;
+def OpMemberDecorate: Op<72, (outs), (ins TYPE:$t, i32imm:$m, Decoration:$d, variable_ops),
+                  "OpMemberDecorate $t $m $d">;
+
+// TODO Currently some deprecated opcodes are missing: OpDecorationGroup,
+// OpGroupDecorate and OpGroupMemberDecorate
+
+def OpDecorateId: Op<332, (outs), (ins ANY:$target, Decoration:$dec, variable_ops),
+                  "OpDecorateId $target $dec">;
+def OpDecorateString: Op<5632, (outs), (ins ANY:$t, Decoration:$d, StringImm:$s, variable_ops),
+                  "OpDecorateString $t $d $s">;
+def OpMemberDecorateString: Op<5633, (outs),
+                  (ins TYPE:$ty, i32imm:$mem, Decoration:$dec, StringImm:$str, variable_ops),
+                  "OpMemberDecorateString $ty $mem $dec $str">;
+
+// 3.42.4 Extension Instructions
+
+def OpExtension: Op<10, (outs), (ins StringImm:$name, variable_ops), "OpExtension $name">;
+def OpExtInstImport: Op<11, (outs ID:$res), (ins StringImm:$extInstsName, variable_ops),
+                  "$res = OpExtInstImport $extInstsName">;
+def OpExtInst: Op<12, (outs ID:$res), (ins TYPE:$ty, ID:$set, ExtInst:$inst, variable_ops),
+                  "$res = OpExtInst $ty $set $inst">;
+
+// 3.42.5 Mode-Setting Instructions
+
+def OpMemoryModel: Op<14, (outs), (ins AddressingModel:$addr, MemoryModel:$mem),
+                  "OpMemoryModel $addr $mem">;
+def OpEntryPoint: Op<15, (outs),
+                  (ins ExecutionModel:$model, ID:$entry, StringImm:$name, variable_ops),
+                  "OpEntryPoint $model $entry $name">;
+def OpExecutionMode: Op<16, (outs), (ins ID:$entry, ExecutionMode:$mode, variable_ops),
+                  "OpExecutionMode $entry $mode">;
+def OpCapability: Op<17, (outs), (ins Capability:$cap), "OpCapability $cap">;
+def OpExecutionModeId: Op<331, (outs), (ins ID:$entry, ExecutionMode:$mode, variable_ops),
+                  "OpExecutionModeId $entry $mode">;
+
+// 3.42.6 Type-Declaration Instructions
+
+def OpTypeVoid: Op<19, (outs TYPE:$type), (ins), "$type = OpTypeVoid">;
+def OpTypeBool: Op<20, (outs TYPE:$type), (ins), "$type = OpTypeBool">;
+def OpTypeInt: Op<21, (outs TYPE:$type), (ins i32imm:$width, i32imm:$signedness),
+                  "$type = OpTypeInt $width $signedness">;
+def OpTypeFloat: Op<22, (outs TYPE:$type), (ins i32imm:$width),
+                  "$type = OpTypeFloat $width">;
+def OpTypeVector: Op<23, (outs TYPE:$type), (ins TYPE:$compType, i32imm:$compCount),
+                  "$type = OpTypeVector $compType $compCount">;
+def OpTypeMatrix: Op<24, (outs TYPE:$type), (ins TYPE:$colType, i32imm:$colCount),
+                  "$type = OpTypeMatrix $colType $colCount">;
+def OpTypeImage: Op<25, (outs TYPE:$res), (ins TYPE:$sampTy, Dim:$dim, i32imm:$depth,
+      i32imm:$arrayed, i32imm:$MS, i32imm:$sampled, ImageFormat:$imFormat, variable_ops),
+                  "$res = OpTypeImage $sampTy $dim $depth $arrayed $MS $sampled $imFormat">;
+def OpTypeSampler: Op<26, (outs TYPE:$res), (ins), "$res = OpTypeSampler">;
+def OpTypeSampledImage: Op<27, (outs TYPE:$res), (ins TYPE:$imageType),
+                  "$res = OpTypeSampledImage $imageType">;
+def OpTypeArray: Op<28, (outs TYPE:$type), (ins TYPE:$elementType, ID:$length),
+                  "$type = OpTypeArray $elementType $length">;
+def OpTypeRuntimeArray: Op<29, (outs TYPE:$type), (ins TYPE:$elementType),
+                  "$type = OpTypeRuntimeArray $elementType">;
+def OpTypeStruct: Op<30, (outs TYPE:$res), (ins variable_ops), "$res = OpTypeStruct">;
+def OpTypeOpaque: Op<31, (outs TYPE:$res), (ins StringImm:$name, variable_ops),
+                  "$res = OpTypeOpaque $name">;
+def OpTypePointer: Op<32, (outs TYPE:$res), (ins StorageClass:$storage, TYPE:$type),
+                  "$res = OpTypePointer $storage $type">;
+def OpTypeFunction: Op<33, (outs TYPE:$funcType), (ins TYPE:$returnType, variable_ops),
+                  "$funcType = OpTypeFunction $returnType">;
+def OpTypeEvent: Op<34, (outs TYPE:$res), (ins), "$res = OpTypeEvent">;
+def OpTypeDeviceEvent: Op<35, (outs TYPE:$res), (ins), "$res = OpTypeDeviceEvent">;
+def OpTypeReserveId: Op<36, (outs TYPE:$res), (ins), "$res = OpTypeReserveId">;
+def OpTypeQueue: Op<37, (outs TYPE:$res), (ins), "$res = OpTypeQueue">;
+def OpTypePipe: Op<38, (outs TYPE:$res), (ins AccessQualifier:$a), "$res = OpTypePipe $a">;
+def OpTypeForwardPointer: Op<39, (outs), (ins TYPE:$ptrType, StorageClass:$storageClass),
+                  "OpTypeForwardPointer $ptrType $storageClass">;
+def OpTypePipeStorage: Op<322, (outs TYPE:$res), (ins), "$res = OpTypePipeStorage">;
+def OpTypeNamedBarrier: Op<327, (outs TYPE:$res), (ins), "$res = OpTypeNamedBarrier">;
+def OpTypeAccelerationStructureNV: Op<5341, (outs TYPE:$res), (ins),
+                  "$res = OpTypeAccelerationStructureNV">;
+def OpTypeCooperativeMatrixNV: Op<5358, (outs TYPE:$res),
+                  (ins TYPE:$compType, ID:$scope, ID:$rows, ID:$cols),
+                  "$res = OpTypeCooperativeMatrixNV $compType $scope $rows $cols">;
+
+// 3.42.7 Constant-Creation Instructions
+
+def imm_to_i32 : SDNodeXForm<imm, [{
+return CurDAG->getTargetConstant(
+  N->getValueAP().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
+}]>;
+
+def fimm_to_i32 : SDNodeXForm<imm, [{
+return CurDAG->getTargetConstant(
+  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
+}]>;
+
+def gi_bitcast_fimm_to_i32 : GICustomOperandRenderer<"renderFImm32">,
+  GISDNodeXFormEquiv<fimm_to_i32>;
+
+def gi_bitcast_imm_to_i32 : GICustomOperandRenderer<"renderImm32">,
+  GISDNodeXFormEquiv<imm_to_i32>;
+
+def PseudoConstI: IntImmLeaf<i32, [{ return Imm.getBitWidth() <= 32; }], imm_to_i32>;
+def PseudoConstF: FPImmLeaf<f32, [{  return true; }], fimm_to_i32>;
+def ConstPseudoTrue: IntImmLeaf<i32, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 1; }]>;
+def ConstPseudoFalse: IntImmLeaf<i32, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 0; }]>;
+def ConstPseudoNull: IntImmLeaf<i64, [{ return Imm.isNullValue(); }]>;
+
+multiclass IntFPImm<bits<16> opCode, string name> {
+  def I: Op<opCode, (outs ID:$dst), (ins TYPE:$type, ID:$src, variable_ops),
+                  "$dst = "#name#" $type $src", [(set ID:$dst, (assigntype PseudoConstI:$src, TYPE:$type))]>;
+  def F: Op<opCode, (outs ID:$dst), (ins TYPE:$type, fID:$src, variable_ops),
+                  "$dst = "#name#" $type $src", [(set ID:$dst, (assigntype PseudoConstF:$src, TYPE:$type))]>;
+}
+
+def OpConstantTrue: Op<41, (outs ID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantTrue $src_ty",
+                      [(set ID:$dst, (assigntype ConstPseudoTrue, TYPE:$src_ty))]>;
+def OpConstantFalse: Op<42, (outs ID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantFalse $src_ty",
+                      [(set ID:$dst, (assigntype ConstPseudoFalse, TYPE:$src_ty))]>;
+
+defm OpConstant: IntFPImm<43, "OpConstant">;
+
+def OpConstantComposite: Op<44, (outs ID:$res), (ins TYPE:$type, variable_ops),
+                  "$res = OpConstantComposite $type">;
+def OpConstantSampler: Op<45, (outs ID:$res),
+                  (ins TYPE:$t, SamplerAddressingMode:$s, i32imm:$p, SamplerFilterMode:$f),
+                  "$res = OpConstantSampler $t $s $p $f">;
+def OpConstantNull: Op<46, (outs ID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantNull $src_ty",
+                      [(set ID:$dst, (assigntype ConstPseudoNull, TYPE:$src_ty))]>;
+
+def OpSpecConstantTrue: Op<48, (outs ID:$r), (ins TYPE:$t), "$r = OpSpecConstantTrue $t">;
+def OpSpecConstantFalse: Op<49, (outs ID:$r), (ins TYPE:$t), "$r = OpSpecConstantFalse $t">;
+def OpSpecConstant: Op<50, (outs ID:$res), (ins TYPE:$type, i32imm:$imm, variable_ops),
+                  "$res = OpSpecConstant $type $imm">;
+def OpSpecConstantComposite: Op<51, (outs ID:$res), (ins TYPE:$type, variable_ops),
+                  "$res = OpSpecConstantComposite $type">;
+def OpSpecConstantOp: Op<52, (outs ID:$res), (ins TYPE:$t, i32imm:$c, ID:$o, variable_ops),
+                  "$res = OpSpecConstantOp $t $c $o">;
+
+// 3.42.8 Memory Instructions
+
+def OpVariable: Op<59, (outs ID:$res), (ins TYPE:$type, StorageClass:$sc, variable_ops),
+                  "$res = OpVariable $type $sc">;
+def OpImageTexelPointer: Op<60, (outs ID:$res),
+                  (ins TYPE:$resType, ID:$image, ID:$coord, ID:$sample),
+                  "$res = OpImageTexelPointer $resType $image $coord $sample">;
+def OpLoad: Op<61, (outs ID:$res), (ins TYPE:$resType, ID:$pointer, variable_ops),
+                  "$res = OpLoad $resType $pointer">;
+def OpStore: Op<62, (outs), (ins ID:$pointer, ID:$objectToStore, variable_ops),
+                  "OpStore $pointer $objectToStore">;
+def OpCopyMemory: Op<63, (outs), (ins ID:$dest, ID:$src, variable_ops),
+                  "OpCopyMemory $dest $src">;
+def OpCopyMemorySized: Op<64, (outs), (ins ID:$dest, ID:$src, ID:$size, variable_ops),
+                  "OpCopyMemorySized $dest $src $size">;
+def OpAccessChain: Op<65, (outs ID:$res), (ins TYPE:$type, ID:$base, variable_ops),
+                  "$res = OpAccessChain $type $base">;
+def OpInBoundsAccessChain: Op<66, (outs ID:$res),
+                  (ins TYPE:$type, ID:$base, variable_ops),
+                  "$res = OpInBoundsAccessChain $type $base">;
+def OpPtrAccessChain: Op<67, (outs ID:$res),
+                  (ins TYPE:$type, ID:$base, ID:$element, variable_ops),
+                  "$res = OpPtrAccessChain $type $base $element">;
+def OpArrayLength: Op<68, (outs ID:$res), (ins TYPE:$resTy, ID:$struct, i32imm:$arrayMember),
+                  "$res = OpArrayLength $resTy $struct $arrayMember">;
+def OpGenericPtrMemSemantics: Op<69, (outs ID:$res), (ins TYPE:$resType, ID:$pointer),
+                  "$res = OpGenericPtrMemSemantics $resType $pointer">;
+def OpInBoundsPtrAccessChain: Op<70, (outs ID:$res),
+                  (ins TYPE:$type, ID:$base, ID:$element, variable_ops),
+                  "$res = OpInBoundsPtrAccessChain $type $base $element">;
+def OpPtrEqual: Op<401, (outs ID:$res), (ins TYPE:$resType, ID:$a, ID:$b),
+                  "$res = OpPtrEqual $resType $a $b">;
+def OpPtrNotEqual: Op<402, (outs ID:$res), (ins TYPE:$resType, ID:$a, ID:$b),
+                  "$res = OpPtrNotEqual $resType $a $b">;
+def OpPtrDiff: Op<403, (outs ID:$res), (ins TYPE:$resType, ID:$a, ID:$b),
+                  "$res = OpPtrDiff $resType $a $b">;
+
+// 3.42.9 Function Instructions
+
+def OpFunction: Op<54, (outs ID:$func),
+                  (ins TYPE:$resType, FunctionControl:$funcControl, TYPE:$funcType),
+                  "$func = OpFunction $resType $funcControl $funcType">;
+def OpFunctionParameter: Op<55, (outs ID:$arg), (ins TYPE:$type),
+                  "$arg = OpFunctionParameter $type">;
+def OpFunctionEnd: Op<56, (outs), (ins), "OpFunctionEnd"> {
+  let isTerminator=1;
+}
+def OpFunctionCall: Op<57, (outs ID:$res), (ins TYPE:$resType, ID:$function, variable_ops),
+                  "$res = OpFunctionCall $resType $function">;
+
+// 3.42.10 Image Instructions
+
+def OpSampledImage: BinOp<"OpSampledImage", 86>;
+
+def OpImageSampleImplicitLod: Op<87, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, variable_ops),
+                  "$res = OpImageSampleImplicitLod $type $sampledImage $coord">;
+def OpImageSampleExplicitLod: Op<88, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$sImage, ID:$uv, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSampleExplicitLod $ty $sImage $uv $op $i">;
+
+def OpImageSampleDrefImplicitLod: Op<89, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageSampleDrefImplicitLod $type $sampledImage $dref $coord">;
+def OpImageSampleDrefExplicitLod: Op<90, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSampleDrefExplicitLod $ty $im $uv $d $op $i">;
+
+def OpImageSampleProjImplicitLod: Op<91, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, variable_ops),
+                  "$res = OpImageSampleProjImplicitLod $type $sampledImage $coord">;
+def OpImageSampleProjExplicitLod: Op<92, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSampleProjExplicitLod $ty $im $uv $op $i">;
+
+def OpImageSampleProjDrefImplicitLod: Op<93, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageSampleProjDrefImplicitLod $type $sampledImage $dref $coord">;
+def OpImageSampleProjDrefExplicitLod: Op<94, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSampleProjDrefExplicitLod $ty $im $uv $d $op $i">;
+
+def OpImageFetch: Op<95, (outs ID:$res),
+                  (ins TYPE:$type, ID:$image, ID:$coord, variable_ops),
+                  "$res = OpImageFetch $type $image $coord">;
+def OpImageGather: Op<96, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$component, variable_ops),
+                  "$res = OpImageGather $type $sampledImage $coord $component">;
+def OpImageDrefGather: Op<97, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageDrefGather $type $sampledImage $coord $dref">;
+
+def OpImageRead: Op<98, (outs ID:$res),
+                  (ins TYPE:$type, ID:$image, ID:$coord, variable_ops),
+                  "$res = OpImageRead $type $image $coord">;
+def OpImageWrite: Op<99, (outs), (ins ID:$image, ID:$coord, ID:$texel, variable_ops),
+                  "OpImageWrite $image $coord $texel">;
+
+def OpImage: UnOp<"OpImage", 100>;
+def OpImageQueryFormat: UnOp<"OpImageQueryFormat", 101>;
+def OpImageQueryOrder: UnOp<"OpImageQueryOrder", 102>;
+def OpImageQuerySizeLod: BinOp<"OpImageQuerySizeLod", 103>;
+def OpImageQuerySize: UnOp<"OpImageQuerySize", 104>;
+def OpImageQueryLod: BinOp<"OpImageQueryLod", 105>;
+def OpImageQueryLevels: UnOp<"OpImageQueryLevels", 106>;
+def OpImageQuerySamples: UnOp<"OpImageQuerySamples", 107>;
+
+def OpImageSparseSampleImplicitLod: Op<305, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, variable_ops),
+                  "$res = OpImageSparseSampleImplicitLod $type $sampledImage $coord">;
+def OpImageSparseSampleExplicitLod: Op<306, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$sImage, ID:$uv, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSparseSampleExplicitLod $ty $sImage $uv $op $i">;
+
+def OpImageSparseSampleDrefImplicitLod: Op<307, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImg, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageSparseSampleDrefImplicitLod $type $sampledImg $dref $coord">;
+def OpImageSparseSampleDrefExplicitLod: Op<308, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSparseSampleDrefExplicitLod $ty $im $uv $d $op $i">;
+
+def OpImageSparseSampleProjImplicitLod: Op<309, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, variable_ops),
+                  "$res = OpImageSparseSampleProjImplicitLod $type $sampledImage $coord">;
+def OpImageSparseSampleProjExplicitLod: Op<310, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSparseSampleProjExplicitLod $ty $im $uv $op $i">;
+
+def OpImageSparseSampleProjDrefImplicitLod: Op<311, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sImage, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageSparseSampleProjDrefImplicitLod $type $sImage $dref $coord">;
+def OpImageSparseSampleProjDrefExplicitLod: Op<312, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$im, ID:$uv, ID:$d, ImageOperand:$op, ID:$i, variable_ops),
+                  "$res = OpImageSparseSampleProjDrefExplicitLod $ty $im $uv $d $op $i">;
+
+def OpImageSparseFetch: Op<313, (outs ID:$res),
+                  (ins TYPE:$type, ID:$image, ID:$coord, variable_ops),
+                  "$res = OpImageSparseFetch $type $image $coord">;
+def OpImageSparseGather: Op<314, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$component, variable_ops),
+                  "$res = OpImageSparseGather $type $sampledImage $coord $component">;
+def OpImageSparseDrefGather: Op<315, (outs ID:$res),
+                  (ins TYPE:$type, ID:$sampledImage, ID:$coord, ID:$dref, variable_ops),
+                  "$res = OpImageSparseDrefGather $type $sampledImage $coord $dref">;
+
+def OpImageSparseTexelsResident: UnOp<"OpImageSparseTexelsResident", 316>;
+
+def OpImageSparseRead: Op<320, (outs ID:$res),
+                  (ins TYPE:$type, ID:$image, ID:$coord, variable_ops),
+                  "$res = OpImageSparseRead $type $image $coord">;
+
+def OpImageSampleFootprintNV: Op<5283, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$sImg, ID:$uv, ID:$granularity, ID:$coarse, variable_ops),
+                  "$res = OpImageSampleFootprintNV $ty $sImg $uv $granularity $coarse">;
+
+// 3.42.11 Conversion instructions
+
+def OpConvertFToU : UnOp<"OpConvertFToU", 109>;
+def OpConvertFToS : UnOp<"OpConvertFToS", 110>;
+def OpConvertSToF : UnOp<"OpConvertSToF", 111>;
+def OpConvertUToF : UnOp<"OpConvertUToF", 112>;
+
+def OpUConvert : UnOp<"OpUConvert", 113>;
+def OpSConvert : UnOp<"OpSConvert", 114>;
+def OpFConvert : UnOp<"OpFConvert", 115>;
+
+def OpQuantizeToF16 : UnOp<"OpQuantizeToF16", 116>;
+
+def OpConvertPtrToU : UnOp<"OpConvertPtrToU", 117>;
+
+def OpSatConvertSToU : UnOp<"OpSatConvertSToU", 118>;
+def OpSatConvertUToS : UnOp<"OpSatConvertUToS", 119>;
+
+def OpConvertUToPtr : UnOp<"OpConvertUToPtr", 120>;
+def OpPtrCastToGeneric : UnOp<"OpPtrCastToGeneric", 121>;
+def OpGenericCastToPtr : UnOp<"OpGenericCastToPtr", 122>;
+def OpGenericCastToPtrExplicit : Op<123, (outs ID:$r), (ins TYPE:$t, ID:$p, StorageClass:$s),
+                              "$r = OpGenericCastToPtrExplicit $t $p $s">;
+def OpBitcast : UnOp<"OpBitcast", 124>;
+
+// 3.42.12 Composite Instructions
+
+def OpVectorExtractDynamic: Op<77, (outs ID:$res), (ins TYPE:$type, vID:$vec, ID:$idx),
+                  "$res = OpVectorExtractDynamic $type $vec $idx", [(set ID:$res, (assigntype (extractelt vID:$vec, ID:$idx), TYPE:$type))]>;
+
+def OpVectorInsertDynamic: Op<78, (outs ID:$res), (ins TYPE:$ty, ID:$vec, ID:$comp, ID:$idx),
+                  "$res = OpVectorInsertDynamic $ty $vec $comp $idx">;
+def OpVectorShuffle: Op<79, (outs ID:$res), (ins TYPE:$ty, ID:$v1, ID:$v2, variable_ops),
+                  "$res = OpVectorShuffle $ty $v1 $v2">;
+def OpCompositeConstruct: Op<80, (outs ID:$res), (ins TYPE:$type, variable_ops),
+                  "$res = OpCompositeConstruct $type">;
+def OpCompositeExtract: Op<81, (outs ID:$res), (ins TYPE:$type, ID:$base, variable_ops),
+                  "$res = OpCompositeExtract $type $base">;
+def OpCompositeInsert: Op<82, (outs ID:$r), (ins TYPE:$ty, ID:$obj, ID:$base, variable_ops),
+                  "$r = OpCompositeInsert $ty $obj $base">;
+def OpCopyObject: UnOp<"OpCopyObject", 83>;
+def OpTranspose: UnOp<"OpTranspose", 84>;
+def OpCopyLogical: UnOp<"OpCopyLogical", 400>;
+
+// 3.42.13 Arithmetic Instructions
+
+def OpSNegate: UnOp<"OpSNegate", 126>;
+def OpFNegate: UnOpTyped<"OpFNegate", 127, fID, fneg>;
+defm OpIAdd: BinOpTypedGen<"OpIAdd", 128, add, 0, 1>;
+defm OpFAdd: BinOpTypedGen<"OpFAdd", 129, fadd, 1, 1>;
+
+defm OpISub: BinOpTypedGen<"OpISub", 130, sub, 0, 1>;
+defm OpFSub: BinOpTypedGen<"OpFSub", 131, fsub, 1, 1>;
+
+defm OpIMul: BinOpTypedGen<"OpIMul", 132, mul, 0, 1>;
+defm OpFMul: BinOpTypedGen<"OpFMul", 133, fmul, 1, 1>;
+
+defm OpUDiv: BinOpTypedGen<"OpUDiv", 134, udiv, 0, 1>;
+defm OpSDiv: BinOpTypedGen<"OpSDiv", 135, sdiv, 0, 1>;
+defm OpFDiv: BinOpTypedGen<"OpFDiv", 136, fdiv, 1, 1>;
+
+defm OpUMod: BinOpTypedGen<"OpUMod", 137, urem, 0, 1>;
+defm OpSRem: BinOpTypedGen<"OpSRem", 138, srem, 0, 1>;
+
+def OpSMod: BinOp<"OpSMod", 139>;
+
+defm OpFRem: BinOpTypedGen<"OpFRem", 140, frem, 1, 1>;
+def OpFMod: BinOp<"OpFMod", 141>;
+
+def OpVectorTimesScalar: BinOp<"OpVectorTimesScalar", 142>;
+def OpMatrixTimesScalar: BinOp<"OpMatrixTimesScalar", 143>;
+def OpVectorTimesMatrix: BinOp<"OpVectorTimesMatrix", 144>;
+def OpMatrixTimesVector: BinOp<"OpMatrixTimesVector", 145>;
+def OpMatrixTimesMatrix: BinOp<"OpMatrixTimesMatrix", 146>;
+
+def OpOuterProduct: BinOp<"OpOuterProduct", 147>;
+def OpDot: BinOp<"OpDot", 148>;
+
+def OpIAddCarry: BinOpTyped<"OpIAddCarry", 149, ID, addc>;
+def OpISubBorrow: BinOpTyped<"OpISubBorrow", 150, ID, subc>;
+def OpUMulExtended: BinOp<"OpUMulExtended", 151>;
+def OpSMulExtended: BinOp<"OpSMulExtended", 152>;
+
+// 3.42.14 Bit Instructions
+
+defm OpShiftRightLogical: BinOpTypedGen<"OpShiftRightLogical", 194, srl, 0, 1>;
+defm OpShiftRightArithmetic: BinOpTypedGen<"OpShiftRightArithmetic", 195, sra, 0, 1>;
+defm OpShiftLeftLogical: BinOpTypedGen<"OpShiftLeftLogical", 196, shl, 0, 1>;
+
+defm OpBitwiseOr: BinOpTypedGen<"OpBitwiseOr", 197, or, 0, 1>;
+defm OpBitwiseXor: BinOpTypedGen<"OpBitwiseXor", 198, xor, 0, 1>;
+defm OpBitwiseAnd: BinOpTypedGen<"OpBitwiseAnd", 199, and, 0, 1>;
+def OpNot: UnOp<"OpNot", 200>;
+
+def OpBitFieldInsert: Op<201, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$base, ID:$insert, ID:$offset, ID:$count),
+                  "$res = OpBitFieldInsert $ty $base $insert $offset $count">;
+def OpBitFieldSExtract: Op<202, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$base, ID:$offset, ID:$count),
+                  "$res = OpBitFieldSExtract $ty $base $offset $count">;
+def OpBitFieldUExtract: Op<203, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$base, ID:$offset, ID:$count),
+                  "$res = OpBitFieldUExtract $ty $base $offset $count">;
+def OpBitReverse: Op<204, (outs ID:$r), (ins TYPE:$ty, ID:$b), "$r = OpBitReverse $ty $b">;
+def OpBitCount: Op<205, (outs ID:$r), (ins TYPE:$ty, ID:$b), "$r = OpBitCount $ty $b">;
+
+// 3.42.15 Relational and Logical Instructions
+
+def OpAny: Op<154, (outs ID:$res), (ins TYPE:$ty, ID:$vec),
+                  "$res = OpAny $ty $vec">;
+def OpAll: Op<155, (outs ID:$res), (ins TYPE:$ty, ID:$vec),
+                  "$res = OpAll $ty $vec">;
+
+def OpIsNan: UnOp<"OpIsNan", 156>;
+def OpIsInf: UnOp<"OpIsInf", 157>;
+def OpIsFinite: UnOp<"OpIsFinite", 158>;
+def OpIsNormal: UnOp<"OpIsNormal", 159>;
+def OpSignBitSet: UnOp<"OpSignBitSet", 160>;
+
+def OpLessOrGreater: BinOp<"OpLessOrGreater", 161>;
+def OpOrdered: BinOp<"OpOrdered", 162>;
+def OpUnordered: BinOp<"OpUnordered", 163>;
+
+def OpLogicalEqual: BinOp<"OpLogicalEqual", 164>;
+def OpLogicalNotEqual: BinOp<"OpLogicalNotEqual", 165>;
+def OpLogicalOr: BinOp<"OpLogicalOr", 166>;
+def OpLogicalAnd: BinOp<"OpLogicalAnd", 167>;
+def OpLogicalNot: UnOp<"OpLogicalNot", 168>;
+
+defm OpSelect: TernOpTypedGen<"OpSelect", 169, select, 1, 1, 1>;
+
+def OpIEqual: BinOp<"OpIEqual", 170>;
+def OpINotEqual: BinOp<"OpINotEqual", 171>;
+
+def OpUGreaterThan: BinOp<"OpUGreaterThan", 172>;
+def OpSGreaterThan: BinOp<"OpSGreaterThan", 173>;
+def OpUGreaterThanEqual: BinOp<"OpUGreaterThanEqual", 174>;
+def OpSGreaterThanEqual: BinOp<"OpSGreaterThanEqual", 175>;
+def OpULessThan: BinOp<"OpULessThan", 176>;
+def OpSLessThan: BinOp<"OpSLessThan", 177>;
+def OpULessThanEqual: BinOp<"OpULessThanEqual", 178>;
+def OpSLessThanEqual: BinOp<"OpSLessThanEqual", 179>;
+
+def OpFOrdEqual: BinOp<"OpFOrdEqual", 180>;
+def OpFUnordEqual: BinOp<"OpFUnordEqual", 181>;
+def OpFOrdNotEqual: BinOp<"OpFOrdNotEqual", 182>;
+def OpFUnordNotEqual: BinOp<"OpFUnordNotEqual", 183>;
+
+def OpFOrdLessThan: BinOp<"OpFOrdLessThan", 184>;
+def OpFUnordLessThan: BinOp<"OpFUnordLessThan", 185>;
+def OpFOrdGreaterThan: BinOp<"OpFOrdGreaterThan", 186>;
+def OpFUnordGreaterThan: BinOp<"OpFUnordGreaterThan", 187>;
+
+def OpFOrdLessThanEqual: BinOp<"OpFOrdLessThanEqual", 188>;
+def OpFUnordLessThanEqual: BinOp<"OpFUnordLessThanEqual", 189>;
+def OpFOrdGreaterThanEqual: BinOp<"OpFOrdGreaterThanEqual", 190>;
+def OpFUnordGreaterThanEqual: BinOp<"OpFUnordGreaterThanEqual", 191>;
+
+// 3.42.16 Derivative Instructions
+
+def OpDPdx: UnOp<"OpDPdx", 207>;
+def OpDPdy: UnOp<"OpDPdy", 208>;
+def OpFwidth: UnOp<"OpFwidth", 209>;
+
+def OpDPdxFine: UnOp<"OpDPdxFine", 210>;
+def OpDPdyFine: UnOp<"OpDPdyFine", 211>;
+def OpFwidthFine: UnOp<"OpFwidthFine", 212>;
+
+def OpDPdxCoarse: UnOp<"OpDPdxCoarse", 213>;
+def OpDPdyCoarse: UnOp<"OpDPdyCoarse", 214>;
+def OpFwidthCoarse: UnOp<"OpFwidthCoarse", 215>;
+
+// 3.42.17 Control-Flow Instructions
+
+def OpPhi: Op<245, (outs ID:$res), (ins TYPE:$type, ID:$var0, ID:$block0, variable_ops),
+                  "$res = OpPhi $type $var0 $block0">;
+def OpLoopMerge: Op<246, (outs), (ins ID:$merge, ID:$continue, LoopControl:$lc, variable_ops),
+                  "OpLoopMerge $merge $merge $continue $lc">;
+def OpSelectionMerge: Op<247, (outs), (ins ID:$merge, SelectionControl:$sc),
+                  "OpSelectionMerge $merge $sc">;
+def OpLabel: Op<248, (outs ID:$label), (ins), "$label = OpLabel">;
+let isTerminator=1 in {
+  def OpBranch: Op<249, (outs), (ins ID:$label), "OpBranch $label">;
+  def OpBranchConditional: Op<250, (outs), (ins ID:$cond, ID:$true, ID:$false, variable_ops),
+                  "OpBranchConditional $cond $true $false">;
+  def OpSwitch: Op<251, (outs), (ins ID:$sel, ID:$dflt, variable_ops), "OpSwitch $sel $dflt">;
+}
+let isReturn = 1, hasDelaySlot=0, isBarrier = 0, isTerminator=1, isNotDuplicable = 1 in {
+  def OpKill: SimpleOp<"OpKill", 252>;
+  def OpReturn: SimpleOp<"OpReturn", 253>;
+  def OpReturnValue: Op<254, (outs), (ins ANYID:$ret), "OpReturnValue $ret">;
+  def OpUnreachable: SimpleOp<"OpUnreachable", 255>;
+}
+def OpLifetimeStart: Op<256, (outs), (ins ID:$ptr, i32imm:$sz), "OpLifetimeStart $ptr, $sz">;
+def OpLifetimeStop: Op<257, (outs), (ins ID:$ptr, i32imm:$sz), "OpLifetimeStop $ptr, $sz">;
+
+// 3.42.18 Atomic Instructions
+
+class AtomicOp<string name, bits<16> opCode>: Op<opCode, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$ptr, ID:$sc, ID:$sem),
+                  "$res = "#name#" $ty $ptr $sc $sem">;
+
+class AtomicOpVal<string name, bits<16> opCode>: Op<opCode, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$ptr, ID:$sc, ID:$sem, ID:$val),
+                  "$res = "#name#" $ty $ptr $sc $sem $val">;
+
+def OpAtomicLoad: AtomicOp<"OpAtomicLoad", 227>;
+
+def OpAtomicStore: Op<228, (outs), (ins ID:$ptr, ID:$sc, ID:$sem, ID:$val),
+                  "OpAtomicStore $ptr $sc $sem $val">;
+def OpAtomicExchange: Op<229, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$ptr, ID:$sc, ID:$sem, ID:$val),
+                  "$res = OpAtomicExchange $ty $ptr $sc $sem $val">;
+def OpAtomicCompareExchange: Op<230, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$ptr, ID:$sc, ID:$eq,
+                   ID:$neq, ID:$val, ID:$cmp),
+                  "$res = OpAtomicCompareExchange $ty $ptr $sc $eq $neq $val $cmp">;
+// TODO Currently the following deprecated opcode is missing:
+// OpAtomicCompareExchangeWeak
+
+def OpAtomicIIncrement: AtomicOp<"OpAtomicIIncrement", 232>;
+def OpAtomicIDecrement: AtomicOp<"OpAtomicIDecrement", 233>;
+
+def OpAtomicIAdd: AtomicOpVal<"OpAtomicIAdd", 234>;
+def OpAtomicISub: AtomicOpVal<"OpAtomicISub", 235>;
+
+def OpAtomicSMin: AtomicOpVal<"OpAtomicSMin", 236>;
+def OpAtomicUMin: AtomicOpVal<"OpAtomicUMin", 237>;
+def OpAtomicSMax: AtomicOpVal<"OpAtomicSMax", 238>;
+def OpAtomicUMax: AtomicOpVal<"OpAtomicUMax", 239>;
+
+def OpAtomicAnd: AtomicOpVal<"OpAtomicAnd", 240>;
+def OpAtomicOr: AtomicOpVal<"OpAtomicOr", 241>;
+def OpAtomicXor: AtomicOpVal<"OpAtomicXor", 242>;
+
+
+def OpAtomicFlagTestAndSet: AtomicOp<"OpAtomicFlagTestAndSet", 318>;
+def OpAtomicFlagClear: Op<319, (outs), (ins ID:$ptr, ID:$sc, ID:$sem),
+                  "OpAtomicFlagClear $ptr $sc $sem">;
+
+// 3.42.19 Primitive Instructions
+
+def OpEmitVertex: SimpleOp<"OpEmitVertex", 218>;
+def OpEndPrimitive: SimpleOp<"OpEndPrimitive", 219>;
+def OpEmitStreamVertex: Op<220, (outs), (ins ID:$stream), "OpEmitStreamVertex $stream">;
+def OpEndStreamPrimitive: Op<221, (outs), (ins ID:$stream), "OpEndStreamPrimitive $stream">;
+
+// 3.42.20 Barrier Instructions
+
+def OpControlBarrier: Op<224, (outs), (ins ID:$exec, ID:$mem, ID:$sem),
+                  "OpControlBarrier $exec $mem $sem">;
+def OpMemoryBarrier: Op<225, (outs), (ins ID:$mem, ID:$sem),
+                  "OpMemoryBarrier $mem $sem">;
+def OpNamedBarrierInitialize: UnOp<"OpNamedBarrierInitialize", 328>;
+def OpMemoryNamedBarrier: Op<329, (outs), (ins ID:$barr, ID:$mem, ID:$sem),
+                  "OpMemoryNamedBarrier $barr $mem $sem">;
+
+// 3.42.21. Group and Subgroup Instructions
+
+def OpGroupAll: Op<261, (outs ID:$res), (ins TYPE:$ty, ID:$scope, ID:$pr),
+                  "$res = OpGroupAll $ty $scope $pr">;
+def OpGroupAny: Op<262, (outs ID:$res), (ins TYPE:$ty, ID:$scope, ID:$pr),
+                  "$res = OpGroupAny $ty $scope $pr">;
+def OpGroupBroadcast: Op<263, (outs ID:$res), (ins TYPE:$ty, ID:$scope,
+                               ID:$val, ID:$id),
+                  "$res = OpGroupBroadcast $ty $scope $val $id">;
+class OpGroup<string name, bits<16> opCode>: Op<opCode, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$scope, GroupOperation:$groupOp, ID:$x),
+                  "$res = OpGroup"#name#" $ty $scope $groupOp $x">;
+def OpGroupIAdd: OpGroup<"IAdd", 264>;
+def OpGroupFAdd: OpGroup<"FAdd", 265>;
+def OpGroupFMin: OpGroup<"FMin", 266>;
+def OpGroupUMin: OpGroup<"UMin", 267>;
+def OpGroupSMin: OpGroup<"SMin", 268>;
+def OpGroupFMax: OpGroup<"FMax", 269>;
+def OpGroupUMax: OpGroup<"UMax", 270>;
+def OpGroupSMax: OpGroup<"SMax", 271>;
+
+// TODO: 3.42.22. Device-Side Enqueue Instructions
+// TODO: 3.42.23. Pipe Instructions
+
+// 3.42.24. Non-Uniform Instructions
+
+def OpGroupNonUniformElect: Op<333, (outs ID:$res), (ins TYPE:$ty, ID:$scope),
+                  "$res = OpGroupNonUniformElect $ty $scope">;
+class OpGroupNU3<string name, bits<16> opCode>: Op<opCode,
+                  (outs ID:$res), (ins TYPE:$ty, ID:$scope, ID:$pred),
+                  "$res = OpGroupNonUniform"#name#" $ty $scope $pred">;
+class OpGroupNU4<string name, bits<16> opCode>: Op<opCode,
+                  (outs ID:$res), (ins TYPE:$ty, ID:$scope, ID:$val, ID:$id),
+                  "$res = OpGroupNonUniform"#name#" $ty $scope $val $id">;
+def OpGroupNonUniformAll: OpGroupNU3<"All", 334>;
+def OpGroupNonUniformAny: OpGroupNU3<"Any", 335>;
+def OpGroupNonUniformAllEqual: OpGroupNU3<"AllEqual", 336>;
+def OpGroupNonUniformBroadcast: OpGroupNU4<"Broadcast", 337>;
+def OpGroupNonUniformBroadcastFirst: OpGroupNU3<"BroadcastFirst", 338>;
+def OpGroupNonUniformBallot: OpGroupNU3<"Ballot", 339>;
+def OpGroupNonUniformInverseBallot: OpGroupNU3<"InverseBallot", 340>;
+def OpGroupNonUniformBallotBitExtract: OpGroupNU4<"BallotBitExtract", 341>;
+def OpGroupNonUniformBallotBitCount: Op<342, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$scope, GroupOperation:$groupOp, ID:$val),
+                  "$res = OpGroupNonUniformBallotBitCount "
+                          "$ty $scope $groupOp $val">;
+def OpGroupNonUniformBallotFindLSB: OpGroupNU3<"BallotFindLSB", 343>;
+def OpGroupNonUniformBallotFindMSB: OpGroupNU3<"BallotFindMSB", 344>;
+def OpGroupNonUniformShuffle: OpGroupNU4<"Shuffle", 345>;
+def OpGroupNonUniformShuffleXor: OpGroupNU4<"ShuffleXor", 346>;
+def OpGroupNonUniformShuffleUp: OpGroupNU4<"ShuffleUp", 347>;
+def OpGroupNonUniformShuffleDown: OpGroupNU4<"ShuffleDown", 348>;
+class OpGroupNUGroup<string name, bits<16> opCode>: Op<opCode, (outs ID:$res),
+                  (ins TYPE:$ty, ID:$scope, GroupOperation:$groupOp,
+                   ID:$val, variable_ops),
+                  "$res = OpGroupNonUniform"#name#" $ty $scope $groupOp $val">;
+def OpGroupNonUniformIAdd: OpGroupNUGroup<"IAdd", 349>;
+def OpGroupNonUniformFAdd: OpGroupNUGroup<"FAdd", 350>;
+def OpGroupNonUniformIMul: OpGroupNUGroup<"IMul", 351>;
+def OpGroupNonUniformFMul: OpGroupNUGroup<"FMul", 352>;
+def OpGroupNonUniformSMin: OpGroupNUGroup<"SMin", 353>;
+def OpGroupNonUniformUMin: OpGroupNUGroup<"UMin", 354>;
+def OpGroupNonUniformFMin: OpGroupNUGroup<"FMin", 355>;
+def OpGroupNonUniformSMax: OpGroupNUGroup<"SMax", 356>;
+def OpGroupNonUniformUMax: OpGroupNUGroup<"UMax", 357>;
+def OpGroupNonUniformFMax: OpGroupNUGroup<"FMax", 358>;
+def OpGroupNonUniformBitwiseAnd: OpGroupNUGroup<"BitwiseAnd", 359>;
+def OpGroupNonUniformBitwiseOr: OpGroupNUGroup<"BitwiseOr", 360>;
+def OpGroupNonUniformBitwiseXor: OpGroupNUGroup<"BitwiseXor", 361>;
+def OpGroupNonUniformLogicalAnd: OpGroupNUGroup<"LogicalAnd", 362>;
+def OpGroupNonUniformLogicalOr: OpGroupNUGroup<"LogicalOr", 363>;
+def OpGroupNonUniformLogicalXor: OpGroupNUGroup<"LogicalXor", 364>;

diff  --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBanks.td b/llvm/lib/Target/SPIRV/SPIRVRegisterBanks.td
new file mode 100644
index 0000000000000..90c7f3a6e6726
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBanks.td
@@ -0,0 +1,15 @@
+//===-- SPIRVRegisterBanks.td - Describe SPIR-V RegBanks ---*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Although RegisterBankSelection is disabled we need to distinct the banks
+// as InstructionSelector RegClass checking code relies on them
+def IDRegBank : RegisterBank<"IDBank", [ID]>;
+def fIDRegBank : RegisterBank<"fIDBank", [fID]>;
+def vIDRegBank : RegisterBank<"vIDBank", [vID]>;
+def vfIDRegBank : RegisterBank<"vfIDBank", [vfID]>;
+def TYPERegBank : RegisterBank<"TYPEBank", [TYPE]>;

diff  --git a/llvm/lib/Target/SPIRV/SPIRVRegisterInfo.td b/llvm/lib/Target/SPIRV/SPIRVRegisterInfo.td
new file mode 100644
index 0000000000000..d0b64b6895d03
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterInfo.td
@@ -0,0 +1,39 @@
+//===-- SPIRVRegisterInfo.td - SPIR-V Register defs --------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  Declarations that describe the SPIR-V register file.
+//
+//===----------------------------------------------------------------------===//
+
+let Namespace = "SPIRV" in {
+  def p0 : PtrValueType <i32, 0>;
+  // All registers are for 32-bit identifiers, so have a single dummy register
+
+  // Class for registers that are the result of OpTypeXXX instructions
+  def TYPE0 : Register<"TYPE0">;
+  def TYPE : RegisterClass<"SPIRV", [i32], 32, (add TYPE0)>;
+
+  // Class for every other non-type ID
+  def ID0 : Register<"ID0">;
+  def ID : RegisterClass<"SPIRV", [i32], 32, (add ID0)>;
+  def fID0 : Register<"FID0">;
+  def fID : RegisterClass<"SPIRV", [f32], 32, (add fID0)>;
+  def pID0 : Register<"pID0">;
+  def pID : RegisterClass<"SPIRV", [p0], 32, (add pID0)>;
+  def vID0 : Register<"pID0">;
+  def vID : RegisterClass<"SPIRV", [v2i32], 32, (add vID0)>;
+  def vfID0 : Register<"pID0">;
+  def vfID : RegisterClass<"SPIRV", [v2f32], 32, (add vfID0)>;
+
+  def ANYID : RegisterClass<"SPIRV", [i32, f32, p0, v2i32, v2f32], 32, (add ID, fID, pID, vID, vfID)>;
+
+  // A few instructions like OpName can take ids from both type and non-type
+  // instructions, so we need a super-class to allow for both to count as valid
+  // arguments for these instructions.
+  def ANY : RegisterClass<"SPIRV", [i32], 32, (add TYPE, ID)>;
+}


        


More information about the llvm-commits mailing list