blob: c626a2102eb27652673220956e3763ba71261bc2 [file] [edit]
//===-- RISCVInstrInfoY.td - RISCV instructions -------------*- tblgen-*---===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file describes the RISC-V instructions from the standard 'Base Y'
// instruction set.
//
// This version is still experimental as the 'Y' extension hasn't been
// ratified yet.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Operand definitions.
//===----------------------------------------------------------------------===//
def YBNDSWImmOperand : AsmOperandClass {
let Name = "YBNDSWImm";
let RenderMethod = "addImmOperands";
let DiagnosticType = "InvalidYBNDSWImm";
}
def ybndsw_imm : RISCVOp<XLenVT>, ImmLeaf<XLenVT, [{
return llvm::RISCV::isValidYBNDSWImm(Imm);
}]> {
let EncoderMethod = "getYBNDSWImmOpValue";
let ParserMatchClass = YBNDSWImmOperand;
let DecoderMethod = "DecodeYBNDSWImm";
let OperandType = "OPERAND_UIMM9_YBNDSWI";
}
def uimm7_eq_xlen : RISCVUImmOp<7>, ImmLeaf<XLenVT, [{
return Imm == Subtarget->getXLen();
}]> {
let ParserMatchClass = UImmAsmOperand<7, "EqXLen">;
let DecoderMethod = "decodeUImm7EqXLenOperand";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
return false;
return Imm == Subtarget->getXLen()
}];
let OperandType = "OPERAND_UIMM7_EQ_XLEN";
}
//===----------------------------------------------------------------------===//
// Instruction Formats and class templates
//===----------------------------------------------------------------------===//
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// All regular 3-operand RVY instructions use opc=CUSTOM-3/RVY-A with funct3=0
defvar OPC_RVY_A = OPC_CUSTOM_3;
class RVY_rr<bits<7> funct7, string opcodestr, DAGOperand rdOp,
DAGOperand rs1Op, DAGOperand rs2Op>
: RVInstR<funct7, 0b000, OPC_RVY_A, (outs rdOp:$rd),
(ins rs1Op:$rs1, rs2Op:$rs2), opcodestr, "$rd, $rs1, $rs2">;
// Like RVY_rr, except rs2 is now an additional function code.
class RVYInst2Op<bits<7> funct7, bits<5> funct5, DAGOperand rdOp,
DAGOperand rs1Op, string opcodestr, string argstr>
: RVInst<(outs rdOp:$rd), (ins rs1Op:$rs1), opcodestr, argstr, [],
InstFormatR> {
bits<5> rs1;
bits<5> rd;
let Inst{31-25} = funct7;
let Inst{24-20} = funct5;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b000; // funct3
let Inst{11-7} = rd;
let Inst{6-0} = OPC_RVY_A.Value;
}
class RVY_r_xx<bits<5> funct5, string opcodestr>
: RVYInst2Op<0b1111000, funct5, GPR, GPR, opcodestr, "$rd, $rs1">;
class RVY_r_xy<bits<5> funct5, string opcodestr>
: RVYInst2Op<0b1111010, funct5, GPR, YGPR, opcodestr, "$rd, $rs1">;
class RVY_ri<bits<3> funct3, string opcodestr, DAGOperand rdOp = YGPR,
DAGOperand rs1Op = YGPR>
: RVInstI<funct3, OPC_RVY_A, (outs rdOp:$rd),
(ins rs1Op:$rs1, simm12_lo:$imm12), opcodestr,
"$rd, $rs1, $imm12">;
class RVY_bndswi<string opcodestr>
: RVInstIBase<0b101, OPC_RVY_A, (outs YGPR:$rd),
(ins YGPR:$rs1, ybndsw_imm:$imm), opcodestr,
"$rd, $rs1, $imm"> {
bits<5> rd;
bits<5> rs1;
bits<9> imm;
let Inst{31-29} = 0b111;
let Inst{28-20} = imm;
}
class RVY_srli<string opcodestr>
: RVInstIBase<0b101, OPC_RVY_A, (outs GPR:$rd),
(ins YGPR:$rs1, uimm7_eq_xlen:$shamt), opcodestr,
"$rd, $rs1, $shamt"> {
bits<7> shamt;
let Inst{31-27} = 0b00000;
let Inst{26-20} = shamt;
}
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
let Predicates = [HasStdExtY] in {
//
// Instructions to Update The Capability Pointer
//
let isReMaterializable = true, isAsCheapAsAMove = true in {
def YADD : RVY_rr<0b0000011, "yadd", YGPR, YGPR, GPRNoX0>;
def YADDI : RVY_ri<0b100, "yaddi">;
}
def : InstAlias<"yadd $rd, $rs1, $imm12",
(YADDI YGPR:$rd, YGPR:$rs1, simm12_lo:$imm12), 0>;
def YADDRW : RVY_rr<0b0001011, "yaddrw", YGPR, YGPR, GPR>;
//
// Instructions to Manipulate Capabilities
//
def YPERMC : RVY_rr<0b0010011, "ypermc", YGPR, YGPR, GPR>;
// YMV is encoded as YADD with rs2=x0
let isReMaterializable = true, isAsCheapAsAMove = true, isMoveReg = true in
def YMV : RVYInst2Op<0b0000011, 0b00000, YGPR, YGPR, "ymv", "$rd, $rs1">;
def PACKY : RVY_rr<0b0000001, "packy", YGPR, YGPR, GPR>;
def : MnemonicAlias<"yhiw", "packy">;
def YBNDSW : RVY_rr<0b0011011, "ybndsw", YGPR, YGPR, GPR>;
def YBNDSWI : RVY_bndswi<"ybndswi">;
def : InstAlias<"ybndsw $rd, $rs1, $imm",
(YBNDSWI YGPR:$rd, YGPR:$rs1, ybndsw_imm:$imm), 0>;
def YBNDSRW : RVY_rr<0b0100011, "ybndsrw", YGPR, YGPR, GPR>;
def YSUNSEAL : RVY_rr<0b0000111, "ysunseal", YGPR, YGPR, YGPR>;
def YBLD : RVY_rr<0b0001111, "ybld", YGPR, YGPR, YGPR>;
//
// Instructions to Decode Capability Bounds
//
def YBASER : RVY_r_xy<0b00000, "ybaser">;
def YLENR : RVY_r_xy<0b00011, "ylenr">;
def YTOPR : RVY_r_xy<0b00010, "ytopr">;
//
// Instructions to Extract Capability Fields
//
def YTAGR : RVY_r_xy<0b00100, "ytagr">;
def YPERMR : RVY_r_xy<0b00001, "ypermr">;
def YTYPER : RVY_r_xy<0b00101, "ytyper">;
// Extracting the high bits of capabilities is effectively a XLEN-bit right
// shift. It is encoded this way so that a future "YLEN arithmetic" extension
// can define shifts with arbitrary shift amounts. YHIR is a pseudo that expands
// to the XLEN-wide shift value depending on RV32/RV64.
def SRLIY : RVY_srli<"srliy">;
let Predicates = [HasStdExtY, IsRV64] in {
def : InstAlias<"yhir $rd, $rs1", (SRLIY GPR:$rd, YGPR:$rs1, 64)>;
}
let Predicates = [HasStdExtY, IsRV32] in {
def : InstAlias<"yhir $rd, $rs1", (SRLIY GPR:$rd, YGPR:$rs1, 32)>;
}
//
// Miscellaneous Instructions to Handle Capability Data
//
def YEQ : RVY_rr<0b0000110, "yeq", GPR, YGPR, YGPR>;
def YSS : RVY_rr<0b0001110, "yss", GPR, YGPR, YGPR>;
def YAMASK : RVY_r_xx<0b00000, "yamask">;
} // Predicates = [HasStdExtY]