| //===- XtensaOperands.td - Xtensa instruction operands -------*- tblgen-*--===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // 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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // Immediate operands with a shared generic render method. | |
| class ImmAsmOperand<string name> : AsmOperandClass { | |
| let Name = name; | |
| let RenderMethod = "addImmOperands"; | |
| let DiagnosticType = !strconcat("Invalid", name); | |
| } | |
| class Immediate<ValueType vt, code pred, string asmop> | |
| : Operand<vt>, ImmLeaf<vt, pred> { | |
| let PrintMethod = "print"#asmop; | |
| let ParserMatchClass = !cast<AsmOperandClass>(asmop); | |
| } | |
| // imm8 predicate - Immediate in the range [-128,127] | |
| def Imm8_AsmOperand : ImmAsmOperand<"Imm8">; | |
| def imm8 : Immediate<i32, [{ return Imm >= -128 && Imm <= 127; }], "Imm8_AsmOperand"> { | |
| let EncoderMethod = "getImm8OpValue"; | |
| let DecoderMethod = "decodeImm8Operand"; | |
| } | |
| // imm8_sh8 predicate - Immediate in the range [-32768,32512] with (bits[7-0] == 0) | |
| // imm8 value left shifted by 8 bits | |
| def Imm8_sh8_AsmOperand : ImmAsmOperand<"Imm8_sh8">; | |
| def imm8_sh8 : Immediate<i32, [{ return Imm >= -32768 && Imm <= 32512 && ((Imm & 0xFF) == 0); }], | |
| "Imm8_sh8_AsmOperand"> { | |
| let EncoderMethod = "getImm8_sh8OpValue"; | |
| let DecoderMethod = "decodeImm8_sh8Operand"; | |
| } | |
| // imm12 predicate - Immediate in the range [-2048,2047] | |
| def Imm12_AsmOperand : ImmAsmOperand<"Imm12">; | |
| def imm12 : Immediate<i32, [{ return Imm >= -2048 && Imm <= 2047; }], "Imm12_AsmOperand"> { | |
| let EncoderMethod = "getImm12OpValue"; | |
| let DecoderMethod = "decodeImm12Operand"; | |
| } | |
| // imm12m predicate - Immediate for MOV operation | |
| def Imm12m_AsmOperand : ImmAsmOperand<"Imm12m">; | |
| def imm12m : Immediate<i32, [{ return Imm >= -2048 && Imm <= 2047; }], "Imm12m_AsmOperand"> { | |
| let EncoderMethod = "getImm12OpValue"; | |
| let DecoderMethod = "decodeImm12Operand"; | |
| } | |
| // uimm4 predicate - Immediate in the range [0,15] | |
| def Uimm4_AsmOperand : ImmAsmOperand<"Uimm4">; | |
| def uimm4 : Immediate<i32, [{ return Imm >= 0 && Imm <= 15; }], "Uimm4_AsmOperand"> { | |
| let EncoderMethod = "getUimm4OpValue"; | |
| let DecoderMethod = "decodeUimm4Operand"; | |
| } | |
| // uimm5 predicate - Immediate in the range [0,31] | |
| def Uimm5_AsmOperand : ImmAsmOperand<"Uimm5">; | |
| def uimm5 : Immediate<i32, [{ return Imm >= 0 && Imm <= 31; }], "Uimm5_AsmOperand"> { | |
| let EncoderMethod = "getUimm5OpValue"; | |
| let DecoderMethod = "decodeUimm5Operand"; | |
| } | |
| // imm1_16 predicate - Immediate in the range [1,16] | |
| def Imm1_16_AsmOperand : ImmAsmOperand<"Imm1_16">; | |
| def imm1_16 : Immediate<i32, [{ return Imm >= 1 && Imm <= 16; }], "Imm1_16_AsmOperand"> { | |
| let EncoderMethod = "getImm1_16OpValue"; | |
| let DecoderMethod = "decodeImm1_16Operand"; | |
| } | |
| // shimm1_31 predicate - Immediate in the range [1,31] | |
| def Shimm1_31_AsmOperand : ImmAsmOperand<"Shimm1_31">; | |
| def shimm1_31 : Immediate<i32, [{ return Imm >= 1 && Imm <= 31; }], "Shimm1_31_AsmOperand"> { | |
| let EncoderMethod = "getShimm1_31OpValue"; | |
| let DecoderMethod = "decodeShimm1_31Operand"; | |
| } | |
| // Memory offset 0..255 for 8-bit memory accesses | |
| def Offset8m8_AsmOperand : ImmAsmOperand<"Offset8m8">; | |
| def offset8m8 : Immediate<i32, | |
| [{ return Imm >= 0 && Imm <= 255; }], | |
| "Offset8m8_AsmOperand">; | |
| // Memory offset 0..510 for 16-bit memory accesses | |
| def Offset8m16_AsmOperand : ImmAsmOperand<"Offset8m16">; | |
| def offset8m16 : Immediate<i32, | |
| [{ return Imm >= 0 && Imm <= 510 && (Imm & 0x1 == 0); }], | |
| "Offset8m16_AsmOperand">; | |
| // Memory offset 0..1020 for 32-bit memory accesses | |
| def Offset8m32_AsmOperand : ImmAsmOperand<"Offset8m32">; | |
| def offset8m32 : Immediate<i32, | |
| [{ return Imm >= 0 && Imm <= 1020 && (Imm & 0x3 == 0); }], | |
| "Offset8m32_AsmOperand">; | |
| // Memory offset 0..60 for 32-bit memory accesses | |
| def Offset4m32_AsmOperand : ImmAsmOperand<"Offset4m32">; | |
| def offset4m32 : Immediate<i32, | |
| [{ return Imm >= 0 && Imm <= 60 && (Imm & 0x3 == 0); }], | |
| "Offset4m32_AsmOperand">; | |
| // b4const predicate - Branch Immediate 4-bit signed operand | |
| def B4const_AsmOperand: ImmAsmOperand<"B4const">; | |
| def b4const: Immediate<i32, | |
| [{ switch (Imm) { | |
| case -1: case 1: case 2: case 3: case 4: | |
| case 5: case 6: case 7: case 8: case 10: case 12: | |
| case 16: case 32: case 64: case 128: case 256: return 1; | |
| default: return 0; | |
| } | |
| }], | |
| "B4const_AsmOperand"> { | |
| let EncoderMethod = "getB4constOpValue"; | |
| let DecoderMethod = "decodeB4constOperand"; | |
| } | |
| // b4constu predicate - Branch Immediate 4-bit unsigned operand | |
| def B4constu_AsmOperand: ImmAsmOperand<"B4constu">; | |
| def b4constu: Immediate<i32, | |
| [{ switch (Imm) { | |
| case 32768: case 65536: case 2: case 3: case 4: | |
| case 5: case 6: case 7: case 8: case 10: case 12: | |
| case 16: case 32: case 64: case 128: case 256: return 1; | |
| default: return 0; | |
| } | |
| }], | |
| "B4constu_AsmOperand"> { | |
| let EncoderMethod = "getB4constuOpValue"; | |
| let DecoderMethod = "decodeB4constuOperand"; | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Memory address operands | |
| //===----------------------------------------------------------------------===// | |
| class mem<Operand offset> : Operand<i32> { | |
| let MIOperandInfo = (ops AR, offset); | |
| let EncoderMethod = "getMemRegEncoding"; | |
| let OperandType = "OPERAND_MEMORY"; | |
| let PrintMethod = "printMemOperand"; | |
| } | |
| def mem8 : mem<offset8m8> { | |
| let DecoderMethod = "decodeMem8Operand"; | |
| } | |
| def mem16 : mem<offset8m16> { | |
| let DecoderMethod = "decodeMem16Operand"; | |
| } | |
| def mem32 : mem<offset8m32> { | |
| let DecoderMethod = "decodeMem32Operand"; | |
| } | |
| def mem32n : mem<offset4m32> { | |
| let DecoderMethod = "decodeMem32nOperand"; | |
| } | |
| //Add patterns for future use in stack addressing mode | |
| def addr_ish1 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH1", [frameindex]>; | |
| def addr_ish2 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH2", [frameindex]>; | |
| def addr_ish4 : ComplexPattern<iPTR, 2, "selectMemRegAddrISH4", [frameindex]>; | |
| //===----------------------------------------------------------------------===// | |
| // Symbolic address operands | |
| //===----------------------------------------------------------------------===// | |
| def XtensaPCRelTargetAsmOperand : AsmOperandClass { | |
| let Name = "PCRelTarget"; | |
| let ParserMethod = "parsePCRelTarget"; | |
| let PredicateMethod = "isImm"; | |
| let RenderMethod = "addImmOperands"; | |
| } | |
| def pcrel32call : Operand<iPTR> { | |
| let PrintMethod = "printCallOperand"; | |
| let EncoderMethod = "getCallEncoding"; | |
| let DecoderMethod = "decodeCallOperand"; | |
| let ParserMatchClass = XtensaPCRelTargetAsmOperand; | |
| } | |
| def brtarget : Operand<OtherVT> { | |
| let PrintMethod = "printBranchTarget"; | |
| let EncoderMethod = "getBranchTargetEncoding"; | |
| let DecoderMethod = "decodeBranchOperand"; | |
| let ParserMatchClass = XtensaPCRelTargetAsmOperand; | |
| } | |
| def jumptarget : Operand<OtherVT> { | |
| let PrintMethod = "printJumpTarget"; | |
| let EncoderMethod = "getJumpTargetEncoding"; | |
| let DecoderMethod = "decodeJumpOperand"; | |
| let ParserMatchClass = XtensaPCRelTargetAsmOperand; | |
| } | |
| def L32Rtarget : Operand<i32> { | |
| let PrintMethod = "printL32RTarget"; | |
| let EncoderMethod = "getL32RTargetEncoding"; | |
| let DecoderMethod = "decodeL32ROperand"; | |
| let ParserMatchClass = XtensaPCRelTargetAsmOperand; | |
| } |