168 lines · plain
1// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../../include %s | FileCheck -check-prefix=GISEL %s2 3include "llvm/Target/Target.td"4 5def TestTargetInstrInfo : InstrInfo;6 7def TestTarget : Target {8 let InstructionSet = TestTargetInstrInfo;9}10 11def R0 : Register<"r0"> { let Namespace = "MyTarget"; }12def SPECIAL : Register<"special"> { let Namespace = "MyTarget"; }13def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;14def Special32 : RegisterClass<"MyTarget", [i32], 32, (add SPECIAL)>;15 16 17class I<dag OOps, dag IOps, list<dag> Pat>18 : Instruction {19 let Namespace = "MyTarget";20 let OutOperandList = OOps;21 let InOperandList = IOps;22 let Pattern = Pat;23}24 25// Try a nested physical register26 27// GISEL: GIM_Try,28// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,29// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),30// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,31// GISEL-NEXT: // MIs[0] src032// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,33// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),34// GISEL-NEXT: // MIs[0] Operand 135// GISEL-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,36// GISEL-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]37// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,38// GISEL-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_MUL),39// GISEL-NEXT: // MIs[1] Operand 040// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,41// GISEL-NEXT: // MIs[1] src142// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,43// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),44// GISEL-NEXT: // MIs[1] Operand 245// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,46// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::Special32RegClassID),47// GISEL-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,48// GISEL-NEXT: // (st GPR32:{ *:[i32] }:$src0, (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, SPECIAL:{ *:[i32] })) => (MULM_PHYS GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)49// GISEL-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),50// GISEL-NEXT: GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),51// GISEL-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/2, // SPECIAL52// GISEL-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MULM_PHYS),53// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // src054// GISEL-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src155// GISEL-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/2, /*MergeInsnID's*/0, 1,56// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,57// GISEL-NEXT: // GIR_Coverage, 0,58// GISEL-NEXT: GIR_EraseRootFromParent_Done,59def MULM_PHYS : I<(outs), (ins GPR32:$src0, GPR32:$src1),60 [(st GPR32:$src0, (mul GPR32:$src1, SPECIAL))]> {61 let Uses = [SPECIAL];62}63 64// Try nested physical registers and check on duplicated copies65 66// GISEL: GIM_Try,67// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,68// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),69// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,70// GISEL-NEXT: // MIs[0] src071// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,72// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),73// GISEL-NEXT: // MIs[0] Operand 174// GISEL-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,75// GISEL-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]76// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,77// GISEL-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_MUL),78// GISEL-NEXT: // MIs[1] Operand 079// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,80// GISEL-NEXT: // MIs[1] Operand 181// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,82// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),83// GISEL-NEXT: // MIs[1] Operand 284// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,85// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::Special32RegClassID),86// GISEL-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,87// GISEL-NEXT: // (st GPR32:{ *:[i32] }:$src0, (mul:{ *:[i32] } R0:{ *:[i32] }, SPECIAL:{ *:[i32] })) => (MULMR0_PHYS GPR32:{ *:[i32] }:$src0)88// GISEL-NEXT: GIR_BuildMI, /*InsnID*/2, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),89// GISEL-NEXT: GIR_AddRegister, /*InsnID*/2, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),90// GISEL-NEXT: GIR_Copy, /*NewInsnID*/2, /*OldInsnID*/1, /*OpIdx*/2, // SPECIAL91// GISEL-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),92// GISEL-NEXT: GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::R0), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),93// GISEL-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // R094// GISEL-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MULMR0_PHYS),95// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // src096// GISEL-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/2, /*MergeInsnID's*/0, 1,97// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,98// GISEL-NEXT: // GIR_Coverage, 1,99// GISEL-NEXT: GIR_EraseRootFromParent_Done,100def MULMR0_PHYS : I<(outs), (ins GPR32:$src0),101 [(st GPR32:$src0, (mul R0, SPECIAL))]> {102 let Uses = [R0, SPECIAL];103}104 105// Try a normal physical register use.106 107// GISEL: GIM_Try,108// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,109// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_ADD),110// GISEL-NEXT: // MIs[0] DstI[dst]111// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,112// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),113// GISEL-NEXT: // MIs[0] src0114// GISEL-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,115// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),116// GISEL-NEXT: // MIs[0] Operand 2117// GISEL-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,118// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::Special32RegClassID),119// GISEL-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src0, SPECIAL:{ *:[i32] }) => (ADD_PHYS:{ *:[i32] } GPR32:{ *:[i32] }:$src0)120// GISEL-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),121// GISEL-NEXT: GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),122// GISEL-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/2, // SPECIAL123// GISEL-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ADD_PHYS),124// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]125// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src0126// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,127// GISEL-NEXT: // GIR_Coverage, 2,128// GISEL-NEXT: GIR_EraseRootFromParent_Done,129def ADD_PHYS : I<(outs GPR32:$dst), (ins GPR32:$src0),130 [(set GPR32:$dst, (add GPR32:$src0, SPECIAL))]> {131 let Uses = [SPECIAL];132}133 134// Try using the name of the physreg in another operand.135 136// GISEL: GIM_Try,137// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,138// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),139// GISEL-NEXT: // MIs[0] DstI[dst]140// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,141// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),142// GISEL-NEXT: // MIs[0] SPECIAL143// GISEL-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,144// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),145// GISEL-NEXT: // MIs[0] Operand 2146// GISEL-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,147// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::Special32RegClassID),148// GISEL-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$SPECIAL, SPECIAL:{ *:[i32] }) => (MUL_PHYS:{ *:[i32] } GPR32:{ *:[i32] }:$SPECIAL)149// GISEL-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),150// GISEL-NEXT: GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),151// GISEL-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/2, // SPECIAL152// GISEL-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MUL_PHYS),153// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]154// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // SPECIAL155// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,156// GISEL-NEXT: // GIR_Coverage, 3,157// GISEL-NEXT: GIR_EraseRootFromParent_Done,158def MUL_PHYS : I<(outs GPR32:$dst), (ins GPR32:$SPECIAL),159 [(set GPR32:$dst, (mul GPR32:$SPECIAL, SPECIAL))]> {160 let Uses = [SPECIAL];161}162 163// Try giving the physical operand a name164// def ADD_PHYS : I<(outs GPR32:$dst), (ins GPR32:$src0),165// [(set GPR32:$dst, (add GPR32:$src0, SPECIAL:$special))]> {166// let Uses = [SPECIAL];167// }168