llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-risc-v Author: Alexander Richardson (arichardson) <details> <summary>Changes</summary> This adds MC-level support for most of the base Y extension instructions, restricted to the execution-mode-independent subset. The Y extension (CHERI for RISC-V) also introduces an execution mode that determines whether certain register operands use the full extended register or only the address subset (the current XLEN registers). The instructions that depend on execution mode (loads/stores/jumps + AUIPC) will be added in the following commits in this stack of changes. Co-authored-by: Jessica Clarke <jrtc27@<!-- -->jrtc27.com> Co-authored-by: Alexander Richardson <alexrichardson@<!-- -->google.com> Co-authored-by: Petr Vesely <petr.vesely@<!-- -->codasip.com> --- Patch is 33.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/176871.diff 9 Files Affected: - (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+55) - (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+39) - (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) - (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+29) - (added) llvm/lib/Target/RISCV/RISCVInstrFormatsY.td (+77) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+3) - (added) llvm/lib/Target/RISCV/RISCVInstrInfoY.td (+108) - (added) llvm/test/MC/RISCV/rvy/rvy-invalid-mode-independent.s (+42) - (added) llvm/test/MC/RISCV/rvy/rvy-valid-mode-independent.s (+242) ``````````diff diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index e9d72aceb0e88..6edc942cdb280 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -488,6 +488,11 @@ struct RISCVOperand final : public MCParsedAsmOperand { RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.Reg); } + bool isYGPR() const { + return Kind == KindTy::Register && + RISCVMCRegisterClasses[RISCV::YGPRRegClassID].contains(Reg.Reg); + } + bool isGPRPair() const { return Kind == KindTy::Register && RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(Reg.Reg); @@ -762,6 +767,11 @@ struct RISCVOperand final : public MCParsedAsmOperand { }); } + bool isUImm7Srliy() const { + return isUImmPred( + [this](int64_t Imm) { return isRV64Expr() ? Imm == 64 : Imm == 32; }); + } + bool isUImm8GE32() const { return isUImmPred([](int64_t Imm) { return isUInt<8>(Imm) && Imm >= 32; }); } @@ -794,6 +804,29 @@ struct RISCVOperand final : public MCParsedAsmOperand { return IsConstantImm && isInt<N>(fixImmediateForRV32(Imm, isRV64Expr())); } + bool isYBNDSWImm() const { + if (!isExpr()) + return false; + + int64_t Imm; + bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm); + if (!IsConstantImm) + return false; + // The immediate is encoded using `((imm[7:0] + 257) << imm[9:8]) - 256` + // which gives the following valid ranges: + if (Imm < 1) + return false; + if (Imm <= 256) + return true; + if (Imm <= 768) + return (Imm % 2) == 0; + if (Imm <= 1792) + return (Imm % 4) == 0; + if (Imm <= 3840) + return (Imm % 8) == 0; + return false; + } + template <class Pred> bool isSImmPred(Pred p) const { int64_t Imm; if (!isExpr()) @@ -1301,6 +1334,11 @@ static MCRegister convertFPR64ToFPR128(MCRegister Reg) { return Reg - RISCV::F0_D + RISCV::F0_Q; } +static MCRegister convertGPRToYGPR(MCRegister Reg) { + assert(Reg >= RISCV::X0 && Reg <= RISCV::X31 && "Invalid register"); + return Reg - RISCV::X0 + RISCV::X0_Y; +} + static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind) { unsigned RegClassID; @@ -1334,6 +1372,11 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg); + if (Op.isGPR() && Kind == MCK_YGPR) { + // GPR and capability GPR use the same register names, convert if required. + Op.Reg.Reg = convertGPRToYGPR(Reg); + return Match_Success; + } if (IsRegFPR64 && Kind == MCK_FPR256) { Op.Reg.Reg = convertFPR64ToFPR256(Reg); return Match_Success; @@ -1712,6 +1755,18 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ErrorLoc, "stack adjustment is invalid for this instruction and register list"); } + case Match_InvalidYBNDSWImm: { + const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "immediate must be an integer in the range " + "[1, 256], a multiple of 2 in the range [258, 768], " + "a multiple of 4 in the range [772, 1792], or " + "a multiple of 8 in the range [1800, 3840]"); + } + case Match_InvalidUImm7Srliy: { + const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "immediate must be an integer equal to XLEN (" + + Twine(isRV64() ? "64" : "32") + ")"); + } } if (const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) { diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index cacb07fb65501..d894714b03773 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -91,6 +91,19 @@ static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodeYGPRRegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE); + + if (RegNo >= 32 || (IsRVE && RegNo >= 16)) + return MCDisassembler::Fail; + + MCRegister Reg = RISCV::X0_Y + RegNo; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPRF16RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder) { @@ -438,6 +451,15 @@ static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodeYBNDSWImm(MCInst &Inst, uint64_t Imm, int64_t Address, + const MCDisassembler *Decoder) { + assert(isUInt<10>(Imm) && "Invalid immediate"); + const uint32_t Shift = Imm >> 8; + uint64_t Result = (((Imm & maxUIntN(8)) + 257) << Shift) - 256; + Inst.addOperand(MCOperand::createImm(Result)); + return MCDisassembler::Success; +} + static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder) { @@ -519,6 +541,20 @@ static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm, return MCDisassembler::Success; } +static DecodeStatus decodeUImm7SrliyOperand(MCInst &Inst, uint32_t Imm, + int64_t Address, + const MCDisassembler *Decoder) { + assert(isUInt<7>(Imm) && "Invalid immediate"); + + uint32_t ExpectedValue = + Decoder->getSubtargetInfo().hasFeature(RISCV::Feature64Bit) ? 64 : 32; + if (Imm != ExpectedValue) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::createImm(Imm)); + return MCDisassembler::Success; +} + template <unsigned N> static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address, @@ -727,6 +763,9 @@ static constexpr DecoderListEntry DecoderList32[]{ {DecoderTableXSMT32, XSMTGroup, "SpacemiT extensions"}, {DecoderTableXAIF32, XAIFGroup, "AI Foundry extensions"}, // Standard Extensions + {DecoderTableRVYOnly32, + {RISCV::FeatureStdExtY}, + "RVY-only standard 32-bit instructions"}, {DecoderTable32, {}, "standard 32-bit instructions"}, {DecoderTableRV32Only32, {}, "RV32-only standard 32-bit instructions"}, {DecoderTableZfinx32, {}, "Zfinx (Float in Integer)"}, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index cda2f95bbef78..e2b6df1e8c1d5 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -380,6 +380,7 @@ enum OperandType : unsigned { OPERAND_UIMM7, OPERAND_UIMM7_LSB00, OPERAND_UIMM7_LSB000, + OPERAND_UIMM7_SRLIY, OPERAND_UIMM8_LSB00, OPERAND_UIMM8, OPERAND_UIMM8_LSB000, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 5cf1f296d4f72..ef40b8b203ca2 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -105,6 +105,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + unsigned getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getVMaskReg(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; @@ -730,6 +734,31 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, return 0; } +unsigned +RISCVMCCodeEmitter::getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + unsigned Imm = getImmOpValue(MI, OpNo, Fixups, STI); + // The 10-bit immediate is encoded as `((imm[7:0] + 257) << imm[9:8]) - 256`. + if (Imm <= 256) { + assert(Imm > 0); // 1, 2, ..., 255, 256 + return Imm - 1; + } + if (Imm <= 768) { + assert(Imm % 2 == 0); // 258, 260, ..., 766, 768 + return ((Imm - 258) >> 1) | (1 << 8); + } + if (Imm <= 1792) { + assert(Imm % 4 == 0); // 772, 776, ..., 1788, 1792 + return ((Imm - 772) >> 2) | (2 << 8); + } + if (Imm <= 3840) { + assert(Imm % 8 == 0); // 1800, 1808, ..., 3832, 3840 + return ((Imm - 1800) >> 3) | (3 << 8); + } + llvm_unreachable("Invalid immediate for YBNDSWI"); +} + unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsY.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsY.td new file mode 100644 index 0000000000000..cc32d124f515d --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsY.td @@ -0,0 +1,77 @@ +//===-- RISCVInstrFormatsY.td --------------------------------*- tablegen -*-=// +// +// 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 Y extension instruction formats. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Operand definitions. +//===----------------------------------------------------------------------===// + +def YBNDSWImmOperand : AsmOperandClass { + let Name = "YBNDSWImm"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidYBNDSWImm"; +} + +def ybndsw_imm : Operand<XLenVT>, ImmLeaf<XLenVT, [{ + return (Imm >= 1 && Imm <= 256) || + (Imm >= 258 && Imm <= 768 && (Imm % 2) == 0) || + (Imm >= 772 && Imm <= 1792 && (Imm % 4) == 0) || + (Imm >= 1800 && Imm <= 3840 && (Imm % 8) == 0); +}]> { + let EncoderMethod = "getYBNDSWImmOpValue"; + let ParserMatchClass = YBNDSWImmOperand; + let DecoderMethod = "DecodeYBNDSWImm"; + let MIOperandInfo = (ops i32imm); +} + +def uimm7_srliy : RISCVUImmOp<7>, ImmLeaf<XLenVT, [{ + return Subtarget->is64Bit() ? Imm == 64 : Imm == 32; +}]> { + let ParserMatchClass = UImmAsmOperand<7, "Srliy">; + let DecoderMethod = "decodeUImm7SrliyOperand"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return Subtarget->is64Bit() ? Imm == 64 : Imm == 32; + }]; + let OperandType = "OPERAND_UIMM7_SRLIY"; +} + +//===----------------------------------------------------------------------===// +// Instruction Formats +//===----------------------------------------------------------------------===// + +// Like an RVInstR, except rs2 is now an additional function code. +class RVYInstSrcDst<bits<7> funct7, bits<5> funct5, bits<3> funct3, + RISCVOpcode opcode, dag outs, dag ins, string opcodestr, + string argstr> + : RVInst<outs, ins, 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} = funct3; + let Inst{11 -7} = rd; + let Inst{6 -0} = opcode.Value; +} + +class RVYInstSetBoundsImmFmt<dag outs, dag ins, string opcodestr, string argstr> + : RVInstIBase<0b011, OPC_OP_IMM_32, outs, ins, opcodestr, argstr> { + bits<5> rd; + bits<5> rs1; + bits<10> imm; + + let Inst{31 -30} = 0b00; + let Inst{29 -20} = imm; +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index c7be5b07c33cc..e8e3691564744 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -2369,6 +2369,9 @@ include "RISCVInstrInfoZicfiss.td" // Short Forward Branch include "RISCVInstrInfoSFB.td" +// CHERI +include "RISCVInstrInfoY.td" + //===----------------------------------------------------------------------===// // Vendor extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoY.td b/llvm/lib/Target/RISCV/RISCVInstrInfoY.td new file mode 100644 index 0000000000000..08565a6f906e8 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoY.td @@ -0,0 +1,108 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction Formats +//===----------------------------------------------------------------------===// + +include "RISCVInstrFormatsY.td" + +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { + class RVY_r<bits<5> funct5, string opcodestr, DAGOperand rdOp = GPR, + DAGOperand rs1Op = YGPR> + : RVYInstSrcDst<0x8, funct5, 0x0, OPC_OP, (outs rdOp:$rd), + (ins rs1Op:$rs1), opcodestr, "$rd, $rs1">; + class RVY_rr<bits<7> funct7, bits<3> funct3, string opcodestr, + DAGOperand rdOp = YGPR, DAGOperand rs1Op = YGPR, + DAGOperand rs2Op = GPR> + : RVInstR<funct7, funct3, OPC_OP, (outs rdOp:$rd), + (ins rs1Op:$rs1, rs2Op:$rs2), opcodestr, "$rd, $rs1, $rs2">; + class RVY_ri<bits<3> funct3, RISCVOpcode opcode, string opcodestr, + DAGOperand rdOp = YGPR, DAGOperand rs1Op = YGPR> + : RVInstI<funct3, opcode, (outs rdOp:$rd), + (ins rs1Op:$rs1, simm12_lo:$imm12), opcodestr, + "$rd, $rs1, $imm12">; + class RVY_setboundsimm<string opcodestr> + : RVYInstSetBoundsImmFmt<(outs YGPR:$rd), + (ins YGPR:$rs1, ybndsw_imm:$imm), opcodestr, + "$rd, $rs1, $imm">; +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 + +let Predicates = [HasStdExtY] in { + // + // Instructions to Update The Capability Pointer + // + let isReMaterializable = true, isAsCheapAsAMove = true in { + def ADDY : RVY_rr<0x6, 0x0, "addy", YGPR, YGPR, GPRNoX0>; + def ADDIY : RVY_ri<0x2, OPC_OP_IMM_32, "addiy">; + } + def : InstAlias<"addy $rd, $rs1, $imm12", + (ADDIY YGPR:$rd, YGPR:$rs1, simm12_lo:$imm12), 0>; + def YADDRW : RVY_rr<0x6, 0x1, "yaddrw", YGPR, YGPR, GPR>; + + // + // Instructions to Manipulate Capabilities + // + // TODO: should we support acperm/candperm aliases with inverted mask? + def YPERMC : RVY_rr<0x6, 0x2, "ypermc", YGPR, YGPR, GPR>; + let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isReMaterializable = true, + isAsCheapAsAMove = true, isMoveReg = true in { + def YMV : RVYInstSrcDst<0x6, 0x0, 0x0, OPC_OP, (outs YGPR:$rd), + (ins YGPR:$rs1), "ymv", "$rd, $rs1">; + } + def PACKY : RVY_rr<0x6, 0x3, "packy", YGPR, YGPR, GPR>; + def : InstAlias<"yhiw $rd, $rs1, $rs2", (PACKY YGPR:$rd, YGPR:$rs1, GPR:$rs2), + 0>; + def YBNDSW : RVY_rr<0x7, 0x0, "ybndsw", YGPR, YGPR, GPR>; + def YBNDSWI : RVY_setboundsimm<"ybndswi">; + def : InstAlias<"ybndsw $rd, $rs1, $imm", + (YBNDSWI YGPR:$rd, YGPR:$rs1, ybndsw_imm:$imm), 0>; + def YBNDSRW : RVY_rr<0x7, 0x1, "ybndsrw", YGPR, YGPR, GPR>; + def YSUNSEAL : RVY_rr<0x7, 0x2, "ysunseal", YGPR, YGPR, YGPR>; + // + // Instructions to Decode Capability Bounds + // + def YBASER : RVY_r<0x5, "ybaser", GPR, YGPR>; + def YLENR : RVY_r<0x6, "ylenr", GPR, YGPR>; + + // + // Instructions to Extract Capability Fields + // + def YTAGR : RVY_r<0x0, "ytagr", GPR, YGPR>; + def YPERMR : RVY_r<0x1, "ypermr", GPR, YGPR>; + def YTYPER : RVY_r<0x2, "ytyper", GPR, YGPR>; + // The SRLIY instruction uses the encoding of SRLI with shamt==XLEN, other + // values are not supported. YHIR is a pseudo that expands to the correct + // shift value depending on RV32/RV64. + let DecoderNamespace = "RVYOnly", hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + def SRLIY : RVInstIBase<0b101, OPC_OP_IMM, (outs GPR:$rd), + (ins YGPR:$rs1, uimm7_srliy:$shamt), "srliy", + "$rd, $rs1, $shamt"> { + bits<7> shamt; + let Inst{31 -27} = 0b00000; + let Inst{26 -20} = shamt; + } + } + 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 SYEQ : RVY_rr<0x6, 0x4, "syeq", GPR, YGPR, YGPR>; + def YLT : RVY_rr<0x6, 0x6, "ylt", GPR, YGPR, YGPR>; + def YAMASK : RVY_r<0x7, "yamask", GPR, GPR>; +} // Predicates = [HasStdExtY] diff --git a/llvm/test/MC/RISCV/rvy/rvy-invalid-mode-independent.s b/llvm/test/MC/RISCV/rvy/rvy-invalid-mode-independent.s new file mode 100644 index 0000000000000..608becf94983e --- /dev/null +++ b/llvm/test/MC/RISCV/rvy/rvy-invalid-mode-independent.s @@ -0,0 +1,42 @@ +# RUN: not llvm-mc --triple riscv32 --mattr=+experimental-y <%s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-32 '--implicit-check-not=error:' +# RUN: not llvm-mc --triple riscv64 --mattr=+experimental-y <%s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-64 '--implicit-check-not=error:' + +addy a0, a1, zero +# CHECK: <stdin>:[[#@LINE-1]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an integer in the range [-2048, 2047] +addy a0, a1, x0 +# CHECK: <stdin>:[[#@LINE-1]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an integer in the range [-2048, 2047] +srliy a0, a1, 65 +# CHECK-32: <stdin>:[[#@LINE-1]]:15: error: immediate must be an integer equal to XLEN (32) +# CHECK-64: <stdin>:[[#@LINE-2]]:15: error: immediate must be an integer equal to XLEN (64) +srliy a0, a1, 64 +# CHECK-32: <stdin>:[[#@LINE-1]]:15: error: immediate must be an integer equal to XLEN (32) +srliy a0, a1, 32 +# CHECK-64: <stdin>:[[#@LINE-1]]:15: error: immediate must be an integer equal to XLEN (64) +ybndswi a0, a0, 0 +# CHECK: <stdin>:[[#@LINE-1]]:17: error: immediate must be an integer in the range [1, 256], a multiple of 2 in the range [258, 768], a multiple of 4 in the range [772, 1792], or a multiple of 8 in the range [1800, 3840] +ybndswi a0, a0, 257 +# CHECK: <stdin>:[[#@LINE-1]]:17: error: immediate must be an integer in the range [1, 256], a multiple of 2 in the range [258, 768], a multiple of 4 in the range [772, 1792], or a multiple of 8 in the range [1800, 3840] +ybndswi a0, a0, 259 +# CHECK: <stdin>:[[#@LINE-1]]:17: error: immediate must be an integer in the range [1, 256], a multiple of 2 in the range [258, 768], a multiple of 4 in the range [772, 1792], or a multiple of 8 i... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/176871 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
