188 lines
9.4 KiB
TableGen
188 lines
9.4 KiB
TableGen
// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s
|
|
|
|
include "llvm/Target/Target.td"
|
|
include "GlobalISelEmitterCommon.td"
|
|
|
|
|
|
def SelectClamp : ComplexPattern<untyped, 2, "SelectClamp">;
|
|
def SelectOMod : ComplexPattern<untyped, 2, "SelectOMod">;
|
|
def SelectClampOMod : ComplexPattern<untyped, 3, "SelectClampOMod">;
|
|
def SelectSrcMods : ComplexPattern<untyped, 2, "SelectSrcMods">;
|
|
|
|
def gi_SelectClamp :
|
|
GIComplexOperandMatcher<s32, "selectClamp">,
|
|
GIComplexPatternEquiv<SelectClamp>;
|
|
|
|
def gi_SelectOMod :
|
|
GIComplexOperandMatcher<s32, "selectOMod">,
|
|
GIComplexPatternEquiv<SelectOMod>;
|
|
|
|
def gi_SelectClampOMod :
|
|
GIComplexOperandMatcher<s32, "selectClampOMod">,
|
|
GIComplexPatternEquiv<SelectClampOMod>;
|
|
|
|
def gi_SelectSrcMods :
|
|
GIComplexOperandMatcher<s32, "selectSrcMods">,
|
|
GIComplexPatternEquiv<SelectSrcMods>;
|
|
|
|
|
|
def src_mods : Operand <i32>;
|
|
def omod : OperandWithDefaultOps <i32, (ops (i32 0))>;
|
|
def clamp : OperandWithDefaultOps <i1, (ops (i1 0))>;
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FMAXNUM,
|
|
// CHECK: GIM_CheckComplexPattern, /*MI*/0, /*Op*/1, /*Renderer*/0, GICP_gi_SelectSrcMods,
|
|
// CHECK: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/1, GICP_gi_SelectSrcMods,
|
|
// CHECK: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FMAX,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // mods0
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/1, /*SubOperand*/1, // mods1
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/1, /*SubOperand*/0, // src1
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/0,
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FFLOOR,
|
|
// CHECK: GIM_CheckComplexPattern, /*MI*/0, /*Op*/1, /*Renderer*/0, GICP_gi_SelectClampOMod,
|
|
// CHECK: // (ffloor:{ *:[f32] } (SelectClampOMod:{ *:[f32] } f32:{ *:[f32] }:$src0, omod:{ *:[i32] }:$omod, i1:{ *:[i1] }:$clamp)) => (FLOMP:{ *:[f32] } f32:{ *:[f32] }:$src0, i1:{ *:[i1] }:$clamp, omod:{ *:[i32] }:$omod)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FLOMP,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/2, // clamp
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // omod
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCANONICALIZE,
|
|
// CHECK: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FMAX,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // mods
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // mods
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/0,
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCOS,
|
|
// CHECK: // (fcos:{ *:[f32] } (SelectOMod:{ *:[f32] } f32:{ *:[f32] }:$src0, i32:{ *:[i32] }:$omod)) => (FLAMP:{ *:[f32] } FPR32:{ *:[f32] }:$src0, omod:{ *:[i32] }:$omod)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FLAMP,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // omod
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/0,
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FEXP2,
|
|
// CHECK: // (fexp2:{ *:[f32] } (SelectClamp:{ *:[f32] } f32:{ *:[f32] }:$src0, i1:{ *:[i1] }:$clamp)) => (FEEPLE:{ *:[f32] } FPR32:{ *:[f32] }:$src0, (FFOO:{ *:[f32] } FPR32:{ *:[f32] }:$src0), clamp:{ *:[i1] }:$clamp)
|
|
|
|
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/MyTarget::FFOO,
|
|
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/1, /*TempRegID*/0, /*TempRegFlags*/RegState::Define,
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/1, /*Imm*/0,
|
|
// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/1,
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FEEPLE,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/0,
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // clamp
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FSIN,
|
|
// CHECK: // (fsin:{ *:[f32] } (SelectClamp:{ *:[f32] } f32:{ *:[f32] }:$src0, i1:{ *:[i1] }:$clamp)) => (FFOO:{ *:[f32] } f32:{ *:[f32] }:$src0, i1:{ *:[i1] }:$clamp)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FFOO,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // clamp
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FSQRT,
|
|
// CHECK: // (fsqrt:{ *:[f32] } (SelectClamp:{ *:[f32] } f32:{ *:[f32] }:$src0, i1:{ *:[i1] }:$clamp)) => (FLAMP:{ *:[f32] } FPR32:{ *:[f32] }:$src0, 93:{ *:[i32] }, clamp:{ *:[i1] }:$clamp)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FLAMP,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src0
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/93,
|
|
// CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // clamp
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC_ROUND,
|
|
// CHECK: // (fround:{ *:[f32] } f32:{ *:[f32] }:$src0) => (FBAR:{ *:[f32] } f32:{ *:[f32] }:$src0)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FBAR,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src0
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/0,
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC_TRUNC,
|
|
// CHECK: // (ftrunc:{ *:[f32] } f32:{ *:[f32] }:$src0) => (FFOO:{ *:[f32] } FPR32:{ *:[f32] }:$src0)
|
|
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::FFOO,
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
|
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src0
|
|
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/0,
|
|
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
|
|
|
|
|
// Have default operand with explicit value from complex pattern.
|
|
def FFOO : I<(outs FPR32:$dst), (ins FPR32:$src0, clamp:$clamp),
|
|
[(set FPR32:$dst, (fsin (SelectClamp f32:$src0, i1:$clamp)))]>;
|
|
|
|
|
|
// Have default operand, not explicitly specified in a standalone
|
|
// pattern.
|
|
def : Pat <
|
|
(ftrunc f32:$src0),
|
|
(FFOO FPR32:$src0)
|
|
>;
|
|
|
|
// Have default operand, not explicitly specified in an instruction
|
|
// definition pattern.
|
|
def FBAR : I<(outs FPR32:$dst), (ins FPR32:$src0, clamp:$clamp),
|
|
[(set FPR32:$dst, (fround f32:$src0))]>;
|
|
|
|
|
|
// // Swapped order in instruction from pattern
|
|
def FLOMP : I<
|
|
(outs FPR32:$dst), (ins FPR32:$src0, clamp:$clamp, omod:$omod),
|
|
[(set FPR32:$dst, (ffloor (SelectClampOMod f32:$src0, omod:$omod, i1:$clamp)))]>;
|
|
|
|
def FLAMP : I<(outs FPR32:$dst), (ins FPR32:$src0, omod:$omod, clamp:$clamp), []>;
|
|
|
|
// // Have 2 default operands, and the first is specified
|
|
def : Pat <
|
|
(fcos (SelectOMod f32:$src0, i32:$omod)),
|
|
(FLAMP FPR32:$src0, omod:$omod)
|
|
>;
|
|
|
|
// Immediate used for first defaulted operand
|
|
def : Pat <
|
|
(fsqrt (SelectClamp f32:$src0, i1:$clamp)),
|
|
(FLAMP FPR32:$src0, 93, clamp:$clamp)
|
|
>;
|
|
|
|
def FEEPLE : I<(outs FPR32:$dst),
|
|
(ins FPR32:$src0, FPR32:$src1, clamp:$clamp), []>;
|
|
|
|
// Default operand isn't on the root ouput instruction
|
|
def : Pat <
|
|
(fexp2 (SelectClamp f32:$src0, i1:$clamp)),
|
|
(FEEPLE FPR32:$src0, (FFOO FPR32:$src0), clamp:$clamp)
|
|
>;
|
|
|
|
// Same instruction is used in two different pattern contexts, one
|
|
// uses the default and one does not.
|
|
def FMAX : I<(outs FPR32:$dst),
|
|
(ins src_mods:$mods0, FPR32:$src0, src_mods:$mods1, FPR32:$src1, clamp:$clamp),
|
|
[(set FPR32:$dst, (f32 (fmaxnum (SelectSrcMods f32:$src0, src_mods:$mods0),
|
|
(SelectSrcMods f32:$src1, src_mods:$mods1))))]
|
|
>;
|
|
|
|
def : Pat<
|
|
(fcanonicalize (f32 (SelectSrcMods f32:$src, i32:$mods))),
|
|
(FMAX $mods, $src, $mods, $src, 0)
|
|
>;
|