Index: lib/Target/NDS32/NDS32Predicate.td =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32Predicate.td @@ -0,0 +1,399 @@ +//===-- NDS32Predicate.td - NDS32 Predicate defs -------*- tablegen -*-----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the NDS32 Predicate defs in TableGen format. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// NDS32 Instruction Predicate Definitions. +// + +def Has16Bit : Predicate<"Subtarget->has16Bit()">; + + +//===----------------------------------------------------------------------===// +// Immediate Operand Predicates +// + +// Transformation Function - get the lower 12 bits. +def LO12 : SDNodeXFormgetZExtValue() & 0xFFF); +}]>; + +// Transformation Function - get the higher 20 bits. +def HI20 : SDNodeXFormgetZExtValue() >> 12) & 0xFFFFF); +}]>; + +class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } + +/// imm5s predicate - Immediate in the range [-(1 << 4) , (1 << 4)]. +def Imm5sAsmOperand: ImmAsmOperand { + let Name = "Imm5s"; + let DiagnosticType = "ImmRange5s"; +} +def imm5s : Operand, ImmLeaf= -(1 << 4) && Imm < (1 << 4); +}]> { + let ParserMatchClass = Imm5sAsmOperand; + let DecoderMethod = "DecodeImm5s"; +} + +/// imm11s predicate - Immediate in the range [-(1 << 10) , (1 << 10)]. +def Imm11sAsmOperand: ImmAsmOperand { + let Name = "Imm11s"; + let DiagnosticType = "ImmRange11s"; +} +def imm11s : Operand, ImmLeaf= -(1 << 10) && Imm < (1 << 10); +}]> { + let ParserMatchClass = Imm11sAsmOperand; + let DecoderMethod = "DecodeImm11s"; +} + +/// imm15s predicate - Immediate in the range [-(1 << 14) , (1 << 14)]. +def Imm15sAsmOperand: ImmAsmOperand { + let Name = "Imm15s"; + let DiagnosticType = "ImmRange15s"; +} +def imm15s : Operand, ImmLeaf= -(1 << 14) && Imm < (1 << 14); +}]> { + let ParserMatchClass = Imm15sAsmOperand; + let DecoderMethod = "DecodeImm15s"; +} + +/// imm20s predicate - Immediate in the range [-(1 << 19) , (1 << 19)]. +def Imm20sAsmOperand: ImmAsmOperand { + let Name = "Imm20s"; + let DiagnosticType = "ImmRange20s"; +} +def imm20s : Operand, ImmLeaf= -(1 << 19) && Imm < (1 << 19); +}]> { + let ParserMatchClass = Imm20sAsmOperand; + let DecoderMethod = "DecodeImm20s"; +} + +/// imm3u predicate - Immediate in the range [0 , (1 << 3)]. +def Imm3uAsmOperand: ImmAsmOperand { + let Name = "Imm3u"; + let DiagnosticType = "ImmRange3u"; +} +def imm3u : Operand, ImmLeaf= 0 && Imm < (1 << 3); +}]> { + let ParserMatchClass = Imm3uAsmOperand; +} + +/// imm5u predicate - Immediate in the range [0 , (1 << 5)]. +def Imm5uAsmOperand: ImmAsmOperand { + let Name = "Imm5u"; + let DiagnosticType = "ImmRange5u"; +} +def imm5u : Operand, ImmLeaf= 0 && Imm < (1 << 5); +}]> { + let ParserMatchClass = Imm5uAsmOperand; +} + +/// imm15u predicate - Immediate in the range [0 , (1 << 15)]. +def Imm15uAsmOperand: ImmAsmOperand { + let Name = "Imm15u"; + let DiagnosticType = "ImmRange15u"; +} +def imm15u : Operand, ImmLeaf= 0 && Imm < (1 << 15); +}]> { + let ParserMatchClass = Imm15uAsmOperand; +} + +/// imm20u predicate - Immediate in the range [0 , (1 << 20)]. +def Imm20uAsmOperand: ImmAsmOperand { + let Name = "Imm20u"; + let DiagnosticType = "ImmRange20u"; +} +def imm20u : Operand, ImmLeaf= 0 && Imm < (1 << 20); +}]> { + let ParserMatchClass = Imm20uAsmOperand; +} + +// Plus 1. +def Plus1 : SDNodeXFormgetSExtValue() + 1); }]>; + +// Node immediate fits as 15-bit sign extended on target immediate. +// e.g. addi, andi +def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>; + +// True if (N + 1) fits in 15-bit field. +def immSExt15Plus1 : PatLeaf<(imm), [{ + return isInt<16>(N->getSExtValue()) && isInt<15>(N->getSExtValue() + 1); +}]>; + + +//===----------------------------------------------------------------------===// +// Load/Store Operands Predicates +// + +class MemOperand : Operand { let OperandType = "OPERAND_MEMORY"; } + +// addr_imm15s_word := [reg + imm15s << 2] +def AddrImm15sWordAsmOperand : AsmOperandClass { let Name = "AddrImm15sWord"; } +def addr_imm15s_word : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s << 2). + + let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrWordEncoding"; + let DecoderMethod = "DecodeAddrWord"; + let ParserMatchClass = AddrImm15sWordAsmOperand; + let PrintMethod = "printAddrImmOperand"; +} + +// addr_imm15s_half := [reg + imm15s << 1] +def AddrImm15sHalfAsmOperand : AsmOperandClass { let Name = "AddrImm15sHalf"; } +def addr_imm15s_half : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s << 1). + + let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrHalfEncoding"; + let DecoderMethod = "DecodeAddrHalf"; + let ParserMatchClass = AddrImm15sHalfAsmOperand; + let PrintMethod = "printAddrImmOperand"; +} + +// addr_imm15s_byte := [reg + imm15s] +def AddrImm15sByteAsmOperand : AsmOperandClass { let Name = "AddrImm15sByte"; } +def addr_imm15s_byte : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s). + + let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrByteEncoding"; + let DecoderMethod = "DecodeAddrByte"; + let ParserMatchClass = AddrImm15sByteAsmOperand; + let PrintMethod = "printAddrImmOperand"; +} + +// addr_reg := [reg] +// use single reg as memory access address +def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } +def addr_reg : MemOperand, + ComplexPattern { + let EncoderMethod = "getAddrRegEncoding"; + let DecoderMethod = "DecodeGPRRegisterClass"; + let PrintMethod = "printAddrRegOperand"; + let ParserMatchClass = MemNoOffsetAsmOperand; + let MIOperandInfo = (ops GPR:$base); +} + +// offset operand as Reg for ([Reg], [Reg]) POST_INC addressing mode +def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } +def offset_reg : MemOperand, + ComplexPattern { + let EncoderMethod = "getAddrRegOffsetEncoding"; + let DecoderMethod = "DecodeGPRRegisterClass"; + let PrintMethod = "printAddrRegOffsetOperand"; + let ParserMatchClass = MemRegOffsetAsmOperand; + let MIOperandInfo = (ops GPR, GPR); +} + +// addressing mode operand for [Reg], (imm15s << 2) POST_INC addressing mode +def OffsetImm15sWordAsmOperand : AsmOperandClass { let Name = "OffsetImm15sWord"; } +def offset_imm15s_word : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s << 2). + let EncoderMethod = "getAddrOffsetWordEncoding"; + let DecoderMethod = "DecodeAddrOffsetWord"; + let PrintMethod = "printAddrOffsetOperand"; + let ParserMatchClass = OffsetImm15sWordAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + +// addressing mode operand for [Reg], (imm15s << 1) POST_INC addressing mode +def OffsetImm15sHalfAsmOperand : AsmOperandClass { let Name = "OffsetImm15sHalf"; } +def offset_imm15s_half : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s << 1). + let EncoderMethod = "getAddrOffsetHalfEncoding"; + let DecoderMethod = "DecodeAddrOffsetHalf"; + let PrintMethod = "printAddrOffsetOperand"; + let ParserMatchClass = OffsetImm15sHalfAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + +// addressing mode operand for [Reg], (imm15s) POST_INC addressing mode +def OffsetImm15sByteAsmOperand : AsmOperandClass { let Name = "OffsetImm15sByte"; } +def offset_imm15s_byte : MemOperand, + ComplexPattern { + // 15-bit signed immediate operand. Note that for word size load/store + // immediate access range would be +/- (imm15s). + let EncoderMethod = "getAddrOffsetByteEncoding"; + let DecoderMethod = "DecodeAddrOffsetByte"; + let PrintMethod = "printAddrOffsetOperand"; + let ParserMatchClass = OffsetImm15sByteAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + +// ldst_reg_shift := [reg + reg << sv] +// sv: shift value could be 0, 1, 2, 3 +def MemAddrRegShiftAsmOperand : AsmOperandClass { let Name = "AddrRegShift"; } +def ldst_reg_shift : MemOperand, + ComplexPattern { + let EncoderMethod = "getAddrRegShiftEncoding"; + let DecoderMethod = "DecodeAddrRegShift"; + let PrintMethod = "printRegShiftOp"; + let ParserMatchClass = MemAddrRegShiftAsmOperand; + let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$shift); +} + +// A list of registers. Used by load/store multiple. +def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } +def reglist : Operand { + let EncoderMethod = "getRegisterListEncoding"; + let DecoderMethod = "DecodeRegisterList"; + let ParserMatchClass = RegListAsmOperand; + let PrintMethod = "printRegisterList"; + let MIOperandInfo = (ops GPR:$base, variable_ops); +} + + +//===----------------------------------------------------------------------===// +// Branch/Jump target Operands Predicates +// + +def NDS32JumpTarget : AsmOperandClass { + let Name = "NDS32JumpTarget"; + let ParserMethod = "parseJumpTarget"; + let PredicateMethod = "isImm"; + let RenderMethod = "addImmOperands"; +} + +def nds32_jump_target : Operand { + let ParserMatchClass = NDS32JumpTarget; + let OperandType = "OPERAND_PCREL"; +} + +def nds32_jal_target : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getJumpTargetOpValue"; + let DecoderMethod = "DecodeJumpTarget"; + let OperandType = "OPERAND_PCREL"; +} + +def nds32_j_target : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getJumpTargetOpValue"; + let DecoderMethod = "DecodeJumpTarget"; + let OperandType = "OPERAND_PCREL"; +} + +def brtarget : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getBranchTargetEncoding"; + let DecoderMethod = "DecodeBranchTarget"; + let OperandType = "OPERAND_PCREL"; +} + +def brzerotarget : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getBranchZeroTargetEncoding"; + let DecoderMethod = "DecodeBranchZeroTarget"; + let OperandType = "OPERAND_PCREL"; +} + +def brtargetImm8s : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getBranchTargetImm8sEncoding"; + let DecoderMethod = "DecodeBranchTargetImm8s"; + let OperandType = "OPERAND_PCREL"; +} + +def brtargetImm8s_32bit : Operand { + let ParserMatchClass = NDS32JumpTarget; + let EncoderMethod = "getBranchTargetImm8s32BitEncoding"; + let DecoderMethod = "DecodeBranchTargetImm8s"; + let OperandType = "OPERAND_PCREL"; +} + + +//===----------------------------------------------------------------------===// +// 16 Bit Load/Store Instruction Operands Predicates +// + +def AddrImm3uWordAsmOperand : AsmOperandClass { let Name = "AddrImm3uWord"; } +def addr_imm3u_word : MemOperand, + ComplexPattern { + // 3-bit unsigned immediate operand. Note that for byte size load/store + // immediate access range would be + (imm3u << 2). + + let ParserMatchClass = AddrImm3uWordAsmOperand; + let MIOperandInfo = (ops lGPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrImm3uWordEncoding"; + let DecoderMethod = "DecodeAddrImm3uWord"; + let PrintMethod = "printAddrImmOperand"; +} + +def AddrImm3uHalfAsmOperand : AsmOperandClass { let Name = "AddrImm3uHalf"; } +def addr_imm3u_half : MemOperand, + ComplexPattern { + // 3-bit unsigned immediate operand. Note that for byte size load/store + // immediate access range would be + (imm3u << 1). + + let ParserMatchClass = AddrImm3uHalfAsmOperand; + let MIOperandInfo = (ops lGPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrImm3uHalfEncoding"; + let DecoderMethod = "DecodeAddrImm3uHalf"; + let PrintMethod = "printAddrImmOperand"; +} + +def AddrImm3uByteAsmOperand : AsmOperandClass { let Name = "AddrImm3uByte"; } +def addr_imm3u_byte : MemOperand, + ComplexPattern { + // 3-bit unsigned immediate operand. Note that for byte size load/store + // immediate access range would be + (imm3u). + + let ParserMatchClass = AddrImm3uByteAsmOperand; + let MIOperandInfo = (ops lGPR:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrImm3uByteEncoding"; + let DecoderMethod = "DecodeAddrImm3uByte"; + let PrintMethod = "printAddrImmOperand"; +} + +// addr_sp_base_offset_imm7u_word := [+ imm7u << 2] +def AddrSPImm7uWordAsmOperand : AsmOperandClass { let Name = "AddrSPImm7uWord"; } +def addr_sp_base_offset_imm7u_word : MemOperand { + let ParserMatchClass = AddrSPImm7uWordAsmOperand; + let MIOperandInfo = (ops SPReg:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrSPImm7uWordEncoding"; + let DecoderMethod = "DecodeAddrSPImm7uWord"; + let PrintMethod = "printSPImplyAddrImmOperand"; +} + +// addr_fp_base_offset_imm7u_word := [$fp + imm7u << 2] +def AddrFPImm7uWordAsmOperand : AsmOperandClass { let Name = "AddrFPImm7uWord"; } +def addr_fp_base_offset_imm7u_word : MemOperand { + let ParserMatchClass = AddrFPImm7uWordAsmOperand; + let MIOperandInfo = (ops FPReg:$base, i32imm:$offsimm); + let EncoderMethod = "getAddrFPImm7uWordEncoding"; + let DecoderMethod = "DecodeAddrFPImm7uWord"; + let PrintMethod = "printAddrImmOperand"; +}