204 lines
7.2 KiB
TableGen
204 lines
7.2 KiB
TableGen
|
//===- 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<OtherVT> {
|
||
|
let PrintMethod = "printL32RTarget";
|
||
|
let EncoderMethod = "getL32RTargetEncoding";
|
||
|
let DecoderMethod = "decodeL32ROperand";
|
||
|
let ParserMatchClass = XtensaPCRelTargetAsmOperand;
|
||
|
}
|