//===-- AMDGPUInstructions.td - Common instruction 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 // //===----------------------------------------------------------------------===// // // This file contains instruction defs that are common to all hw codegen // targets. // //===----------------------------------------------------------------------===// class AddressSpacesImpl { int Flat = 0; int Global = 1; int Region = 2; int Local = 3; int Constant = 4; int Private = 5; } def AddrSpaces : AddressSpacesImpl; class AMDGPUInst pattern = []> : Instruction { field bit isRegisterLoad = 0; field bit isRegisterStore = 0; let Namespace = "AMDGPU"; let OutOperandList = outs; let InOperandList = ins; let AsmString = asm; let Pattern = pattern; let Itinerary = NullALU; // SoftFail is a field the disassembler can use to provide a way for // instructions to not match without killing the whole decode process. It is // mainly used for ARM, but Tablegen expects this field to exist or it fails // to build the decode table. field bits<64> SoftFail = 0; let DecoderNamespace = Namespace; let TSFlags{63} = isRegisterLoad; let TSFlags{62} = isRegisterStore; } class AMDGPUShaderInst pattern = []> : AMDGPUInst { field bits<32> Inst = 0xffffffff; } //===---------------------------------------------------------------------===// // Return instruction //===---------------------------------------------------------------------===// class ILFormat pattern> : Instruction { let Namespace = "AMDGPU"; dag OutOperandList = outs; dag InOperandList = ins; let Pattern = pattern; let AsmString = !strconcat(asmstr, "\n"); let isPseudo = 1; let Itinerary = NullALU; bit hasIEEEFlag = 0; bit hasZeroOpFlag = 0; let mayLoad = 0; let mayStore = 0; let hasSideEffects = 0; let isCodeGenOnly = 1; } def TruePredicate : Predicate<"">; class PredicateControl { Predicate SubtargetPredicate = TruePredicate; list AssemblerPredicates = []; Predicate AssemblerPredicate = TruePredicate; Predicate WaveSizePredicate = TruePredicate; list OtherPredicates = []; list Predicates = !listconcat([SubtargetPredicate, AssemblerPredicate, WaveSizePredicate], AssemblerPredicates, OtherPredicates); } class AMDGPUPat : Pat, PredicateControl; def FP16Denormals : Predicate<"Subtarget->hasFP16Denormals()">; def FP32Denormals : Predicate<"Subtarget->hasFP32Denormals()">; def FP64Denormals : Predicate<"Subtarget->hasFP64Denormals()">; def NoFP16Denormals : Predicate<"!Subtarget->hasFP16Denormals()">; def NoFP32Denormals : Predicate<"!Subtarget->hasFP32Denormals()">; def NoFP64Denormals : Predicate<"!Subtarget->hasFP64Denormals()">; def UnsafeFPMath : Predicate<"TM.Options.UnsafeFPMath">; def FMA : Predicate<"Subtarget->hasFMA()">; def InstFlag : OperandWithDefaultOps ; def u16ImmTarget : AsmOperandClass { let Name = "U16Imm"; let RenderMethod = "addImmOperands"; } def s16ImmTarget : AsmOperandClass { let Name = "S16Imm"; let RenderMethod = "addImmOperands"; } let OperandType = "OPERAND_IMMEDIATE" in { def u32imm : Operand { let PrintMethod = "printU32ImmOperand"; } def u16imm : Operand { let PrintMethod = "printU16ImmOperand"; let ParserMatchClass = u16ImmTarget; } def s16imm : Operand { let PrintMethod = "printU16ImmOperand"; let ParserMatchClass = s16ImmTarget; } def u8imm : Operand { let PrintMethod = "printU8ImmOperand"; } } // End OperandType = "OPERAND_IMMEDIATE" //===--------------------------------------------------------------------===// // Custom Operands //===--------------------------------------------------------------------===// def brtarget : Operand; //===----------------------------------------------------------------------===// // Misc. PatFrags //===----------------------------------------------------------------------===// class HasOneUseUnaryOp : PatFrag< (ops node:$src0), (op $src0), [{ return N->hasOneUse(); }] >; class HasOneUseBinOp : PatFrag< (ops node:$src0, node:$src1), (op $src0, $src1), [{ return N->hasOneUse(); }] >; class HasOneUseTernaryOp : PatFrag< (ops node:$src0, node:$src1, node:$src2), (op $src0, $src1, $src2), [{ return N->hasOneUse(); }] >; let Properties = [SDNPCommutative, SDNPAssociative] in { def smax_oneuse : HasOneUseBinOp; def smin_oneuse : HasOneUseBinOp; def umax_oneuse : HasOneUseBinOp; def umin_oneuse : HasOneUseBinOp; def fminnum_oneuse : HasOneUseBinOp; def fmaxnum_oneuse : HasOneUseBinOp; def fminnum_ieee_oneuse : HasOneUseBinOp; def fmaxnum_ieee_oneuse : HasOneUseBinOp; def and_oneuse : HasOneUseBinOp; def or_oneuse : HasOneUseBinOp; def xor_oneuse : HasOneUseBinOp; } // Properties = [SDNPCommutative, SDNPAssociative] def not_oneuse : HasOneUseUnaryOp; def add_oneuse : HasOneUseBinOp; def sub_oneuse : HasOneUseBinOp; def srl_oneuse : HasOneUseBinOp; def shl_oneuse : HasOneUseBinOp; def select_oneuse : HasOneUseTernaryOp