//===-- 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, ImmLeaf { let EncoderMethod = "getYBNDSWImmOpValue"; let ParserMatchClass = YBNDSWImmOperand; let DecoderMethod = "DecodeYBNDSWImm"; let OperandType = "OPERAND_UIMM9_YBNDSWI"; } def uimm7_eq_xlen : RISCVUImmOp<7>, ImmLeafgetXLen(); }]> { 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 funct7, string opcodestr, DAGOperand rdOp, DAGOperand rs1Op, DAGOperand rs2Op> : RVInstR; // Like RVY_rr, except rs2 is now an additional function code. class RVYInst2Op 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 funct5, string opcodestr> : RVYInst2Op<0b1111000, funct5, GPR, GPR, opcodestr, "$rd, $rs1">; class RVY_r_xy funct5, string opcodestr> : RVYInst2Op<0b1111010, funct5, GPR, YGPR, opcodestr, "$rd, $rs1">; class RVY_ri funct3, string opcodestr, DAGOperand rdOp = YGPR, DAGOperand rs1Op = YGPR> : RVInstI; class RVY_bndswi : 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 : 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]