diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 8177280044bf4..cc797f3b209e2 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1671,6 +1671,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be v0.t"); } + case Match_InvalidVMaskCarryInRegister: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "operand must be v0"); + } case Match_InvalidSImm5Plus1: { return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1, (1 << 4), diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 971ef90c63327..afd1035be2f8e 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -293,6 +293,16 @@ static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + if (RegNo) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::createReg(RISCV::V0)); + return MCDisassembler::Success; +} + static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td index 24a881dc6810f..671e493fb3763 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -50,6 +50,13 @@ def VMaskAsmOperand : AsmOperandClass { let DiagnosticType = "InvalidVMaskRegister"; } +def VMaskCarryInAsmOperand : AsmOperandClass { + let Name = "RVVMaskCarryInRegOpOperand"; + let RenderMethod = "addRegOperands"; + let PredicateMethod = "isV0Reg"; + let DiagnosticType = "InvalidVMaskCarryInRegister"; +} + def VMaskOp : RegisterOperand { let ParserMatchClass = VMaskAsmOperand; let PrintMethod = "printVMaskReg"; @@ -57,6 +64,11 @@ def VMaskOp : RegisterOperand { let DecoderMethod = "decodeVMaskReg"; } +def VMaskCarryInOp : RegisterOperand { + let ParserMatchClass = VMaskCarryInAsmOperand; + let EncoderMethod = "getVMaskReg"; +} + def simm5 : RISCVSImmLeafOp<5> { let MCOperandPredicate = [{ int64_t Imm; @@ -442,10 +454,8 @@ class VALUVV funct6, RISCVVFormat opv, string opcodestr> // op vd, vs2, vs1, v0 (without mask, use v0 as carry input) class VALUmVV funct6, RISCVVFormat opv, string opcodestr> : RVInstVV { - let vm = 0; -} + (ins VR:$vs2, VR:$vs1, VMaskCarryInOp:$vm), + opcodestr, "$vd, $vs2, $vs1, $vm">; // op vd, vs1, vs2, vm (reverse the order of vs1 and vs2) class VALUrVV funct6, RISCVVFormat opv, string opcodestr, @@ -474,10 +484,8 @@ class VALUVX funct6, RISCVVFormat opv, string opcodestr> // op vd, vs2, rs1, v0 (without mask, use v0 as carry input) class VALUmVX funct6, RISCVVFormat opv, string opcodestr> : RVInstVX { - let vm = 0; -} + (ins VR:$vs2, GPR:$rs1, VMaskCarryInOp:$vm), + opcodestr, "$vd, $vs2, $rs1, $vm">; // op vd, rs1, vs2, vm (reverse the order of rs1 and vs2) class VALUrVX funct6, RISCVVFormat opv, string opcodestr, @@ -506,10 +514,8 @@ class VALUVI funct6, string opcodestr, Operand optype = simm5> // op vd, vs2, imm, v0 (without mask, use v0 as carry input) class VALUmVI funct6, string opcodestr, Operand optype = simm5> : RVInstIVI { - let vm = 0; -} + (ins VR:$vs2, optype:$imm, VMaskCarryInOp:$vm), + opcodestr, "$vd, $vs2, $imm, $vm">; // op vd, vs2, imm, vm class VALUVINoVm funct6, string opcodestr, Operand optype = simm5> @@ -1458,10 +1464,9 @@ defm VFCLASS_V : VCLS_FV_VS2<"vfclass.v", 0b010011, 0b10000>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { // Vector Floating-Point Merge Instruction -let vm = 0 in def VFMERGE_VFM : RVInstVX<0b010111, OPFVF, (outs VR:$vd), - (ins VR:$vs2, FPR32:$rs1, VMV0:$v0), - "vfmerge.vfm", "$vd, $vs2, $rs1, v0">, + (ins VR:$vs2, FPR32:$rs1, VMaskCarryInOp:$vm), + "vfmerge.vfm", "$vd, $vs2, $rs1, $vm">, SchedBinaryMC<"WriteVFMergeV", "ReadVFMergeV", "ReadVFMergeF">; // Vector Floating-Point Move Instruction diff --git a/llvm/test/MC/Disassembler/RISCV/vmask-carry-in.txt b/llvm/test/MC/Disassembler/RISCV/vmask-carry-in.txt new file mode 100644 index 0000000000000..e9af01ac60b43 --- /dev/null +++ b/llvm/test/MC/Disassembler/RISCV/vmask-carry-in.txt @@ -0,0 +1,69 @@ +# RUN: llvm-mc -triple=riscv64 -disassemble -show-inst --mattr=+v %s \ +# RUN: --M no-aliases | FileCheck %s + +# Check if there is a MCOperand for the carry-in mask. + +[0x57,0x04,0x4a,0x5c] +# CHECK: