blob: 14ba01f0d67c63e86aaabcacf5b69e804fad9351 [file] [log] [blame]
//===-- EXPInstructions.td - Export Instruction Definitions ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// EXP classes
//===----------------------------------------------------------------------===//
class EXPCommon<bit row, bit done, string asm = ""> : InstSI<
(outs),
(ins exp_tgt:$tgt,
ExpSrc0:$src0, ExpSrc1:$src1, ExpSrc2:$src2, ExpSrc3:$src3,
exp_vm:$vm, exp_compr:$compr, i32imm:$en),
asm> {
let EXP = 1;
let EXP_CNT = 1;
let mayLoad = done;
let mayStore = 1;
let UseNamedOperandTable = 1;
let Uses = !if(row, [EXEC, M0], [EXEC]);
let SchedRW = [WriteExport];
let DisableWQM = 1;
}
class EXP_Pseudo<bit row, bit done>
: EXPCommon<row, done>, SIMCInstr<NAME, SIEncodingFamily.NONE> {
let isPseudo = 1;
let isCodeGenOnly = 1;
}
// Real instruction with optional asm operands "compr" and "vm".
class EXP_Real_ComprVM<bit done, string pseudo, int subtarget>
: EXPCommon<0, done, "exp$tgt $src0, $src1, $src2, $src3"
#!if(done, " done", "")#"$compr$vm">,
SIMCInstr<pseudo, subtarget> {
let AsmMatchConverter = "cvtExp";
}
// Real instruction with optional asm operand "row_en".
class EXP_Real_Row<bit row, bit done, string pseudo, int subtarget>
: EXPCommon<row, done, "exp$tgt $src0, $src1, $src2, $src3"
#!if(done, " done", "")#!if(row, " row_en", "")>,
SIMCInstr<pseudo, subtarget> {
let AsmMatchConverter = "cvtExp";
}
//===----------------------------------------------------------------------===//
// EXP Instructions
//===----------------------------------------------------------------------===//
// DONE variants have mayLoad = 1.
// ROW variants have an implicit use of M0.
let SubtargetPredicate = isNotGFX90APlus in {
def EXP : EXP_Pseudo<0, 0>;
def EXP_DONE : EXP_Pseudo<0, 1>;
def EXP_ROW : EXP_Pseudo<1, 0>;
def EXP_ROW_DONE : EXP_Pseudo<1, 1>;
} // let SubtargetPredicate = isNotGFX90APlus
//===----------------------------------------------------------------------===//
// SI
//===----------------------------------------------------------------------===//
class EXP_Real_si<bit _done, string pseudo>
: EXP_Real_ComprVM<_done, pseudo, SIEncodingFamily.SI>, EXPe_ComprVM {
let AssemblerPredicate = isGFX6GFX7;
let DecoderNamespace = "GFX6GFX7";
let done = _done;
}
def EXP_si : EXP_Real_si<0, "EXP">;
def EXP_DONE_si : EXP_Real_si<1, "EXP_DONE">;
//===----------------------------------------------------------------------===//
// VI
//===----------------------------------------------------------------------===//
class EXP_Real_vi<bit _done, string pseudo>
: EXP_Real_ComprVM<_done, pseudo, SIEncodingFamily.VI>, EXPe_vi {
let AssemblerPredicate = isGFX8GFX9;
let SubtargetPredicate = isNotGFX90APlus;
let DecoderNamespace = "GFX8";
let done = _done;
}
def EXP_vi : EXP_Real_vi<0, "EXP">;
def EXP_DONE_vi : EXP_Real_vi<1, "EXP_DONE">;
//===----------------------------------------------------------------------===//
// GFX10
//===----------------------------------------------------------------------===//
class EXP_Real_gfx10<bit _done, string pseudo>
: EXP_Real_ComprVM<_done, pseudo, SIEncodingFamily.GFX10>, EXPe_ComprVM {
let AssemblerPredicate = isGFX10Only;
let DecoderNamespace = "GFX10";
let done = _done;
}
def EXP_gfx10 : EXP_Real_gfx10<0, "EXP">;
def EXP_DONE_gfx10 : EXP_Real_gfx10<1, "EXP_DONE">;
//===----------------------------------------------------------------------===//
// GFX11+
//===----------------------------------------------------------------------===//
class EXP_Real_gfx11<bit _row, bit _done, string pseudo>
: EXP_Real_Row<_row, _done, pseudo, SIEncodingFamily.GFX11>, EXPe_Row {
let AssemblerPredicate = isGFX11Plus;
let DecoderNamespace = "GFX11";
let row = _row;
let done = _done;
}
def EXP_gfx11 : EXP_Real_gfx11<0, 0, "EXP">;
def EXP_DONE_gfx11 : EXP_Real_gfx11<0, 1, "EXP_DONE">;
def EXP_ROW_gfx11 : EXP_Real_gfx11<1, 0, "EXP_ROW">;
def EXP_ROW_DONE_gfx11 : EXP_Real_gfx11<1, 1, "EXP_ROW_DONE">;
//===----------------------------------------------------------------------===//
// EXP Patterns
//===----------------------------------------------------------------------===//
class ExpPattern<ValueType vt, Instruction Inst, int done_val> : GCNPat<
(int_amdgcn_exp timm:$tgt, timm:$en,
(vt ExpSrc0:$src0), (vt ExpSrc1:$src1),
(vt ExpSrc2:$src2), (vt ExpSrc3:$src3),
done_val, timm:$vm),
(Inst timm:$tgt, ExpSrc0:$src0, ExpSrc1:$src1,
ExpSrc2:$src2, ExpSrc3:$src3, timm:$vm, 0, timm:$en)
>;
class ExpRowPattern<ValueType vt, Instruction Inst, int done_val> : GCNPat<
(int_amdgcn_exp_row timm:$tgt, timm:$en,
(vt ExpSrc0:$src0), (vt ExpSrc1:$src1),
(vt ExpSrc2:$src2), (vt ExpSrc3:$src3),
done_val, M0),
(Inst timm:$tgt, ExpSrc0:$src0, ExpSrc1:$src1,
ExpSrc2:$src2, ExpSrc3:$src3, 0, 0, timm:$en)
>;
class ExpComprPattern<ValueType vt, Instruction Inst, int done_val> : GCNPat<
(int_amdgcn_exp_compr timm:$tgt, timm:$en,
(vt ExpSrc0:$src0), (vt ExpSrc1:$src1),
done_val, timm:$vm),
(Inst timm:$tgt, ExpSrc0:$src0, ExpSrc1:$src1,
(IMPLICIT_DEF), (IMPLICIT_DEF), timm:$vm, 1, timm:$en)
>;
// FIXME: The generated DAG matcher seems to have strange behavior
// with a 1-bit literal to match, so use a -1 for checking a true
// 1-bit value.
def : ExpPattern<i32, EXP, 0>;
def : ExpPattern<i32, EXP_DONE, -1>;
def : ExpPattern<f32, EXP, 0>;
def : ExpPattern<f32, EXP_DONE, -1>;
def : ExpRowPattern<i32, EXP_ROW, 0>;
def : ExpRowPattern<i32, EXP_ROW_DONE, -1>;
def : ExpRowPattern<f32, EXP_ROW, 0>;
def : ExpRowPattern<f32, EXP_ROW_DONE, -1>;
def : ExpComprPattern<v2i16, EXP, 0>;
def : ExpComprPattern<v2i16, EXP_DONE, -1>;
def : ExpComprPattern<v2f16, EXP, 0>;
def : ExpComprPattern<v2f16, EXP_DONE, -1>;