Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}

static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't reuse decodeVMaskReg here because it accepts arbitrary vm field value, while we only accept vm = 0 for carry-in vmask. Put it differently, if the input is an invalid encoding with vm=1 on instruction with carry-in mask, decodeVMaskReg puts a NoRegister as the MCOperand and crashes the program, rather than printing out a nice error message.

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) {
Expand Down
35 changes: 20 additions & 15 deletions llvm/lib/Target/RISCV/RISCVInstrInfoV.td
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,25 @@ def VMaskAsmOperand : AsmOperandClass {
let DiagnosticType = "InvalidVMaskRegister";
}

def VMaskCarryInAsmOperand : AsmOperandClass {
let Name = "RVVMaskCarryInRegOpOperand";
let RenderMethod = "addRegOperands";
let PredicateMethod = "isV0Reg";
let DiagnosticType = "InvalidVMaskCarryInRegister";
}

def VMaskOp : RegisterOperand<VMV0> {
let ParserMatchClass = VMaskAsmOperand;
let PrintMethod = "printVMaskReg";
let EncoderMethod = "getVMaskReg";
let DecoderMethod = "decodeVMaskReg";
}

def VMaskCarryInOp : RegisterOperand<VMV0> {
let ParserMatchClass = VMaskCarryInAsmOperand;
let EncoderMethod = "getVMaskReg";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we want to create another encoder method here. On one hand, it's impossible for codegen to create a MCOperand with register other than V0. But on the other hand, if the MCInst is created "manually", I'm not sure if it will validate the register class.

}

def simm5 : RISCVSImmLeafOp<5> {
let MCOperandPredicate = [{
int64_t Imm;
Expand Down Expand Up @@ -442,10 +454,8 @@ class VALUVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>
// op vd, vs2, vs1, v0 (without mask, use v0 as carry input)
class VALUmVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>
: RVInstVV<funct6, opv, (outs VR:$vd),
(ins VR:$vs2, VR:$vs1, VMV0:$v0),
opcodestr, "$vd, $vs2, $vs1, v0"> {
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<bits<6> funct6, RISCVVFormat opv, string opcodestr,
Expand Down Expand Up @@ -474,10 +484,8 @@ class VALUVX<bits<6> funct6, RISCVVFormat opv, string opcodestr>
// op vd, vs2, rs1, v0 (without mask, use v0 as carry input)
class VALUmVX<bits<6> funct6, RISCVVFormat opv, string opcodestr>
: RVInstVX<funct6, opv, (outs VR:$vd),
(ins VR:$vs2, GPR:$rs1, VMV0:$v0),
opcodestr, "$vd, $vs2, $rs1, v0"> {
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<bits<6> funct6, RISCVVFormat opv, string opcodestr,
Expand Down Expand Up @@ -506,10 +514,8 @@ class VALUVI<bits<6> funct6, string opcodestr, Operand optype = simm5>
// op vd, vs2, imm, v0 (without mask, use v0 as carry input)
class VALUmVI<bits<6> funct6, string opcodestr, Operand optype = simm5>
: RVInstIVI<funct6, (outs VR:$vd),
(ins VR:$vs2, optype:$imm, VMV0:$v0),
opcodestr, "$vd, $vs2, $imm, v0"> {
let vm = 0;
}
(ins VR:$vs2, optype:$imm, VMaskCarryInOp:$vm),
opcodestr, "$vd, $vs2, $imm, $vm">;

// op vd, vs2, imm, vm
class VALUVINoVm<bits<6> funct6, string opcodestr, Operand optype = simm5>
Expand Down Expand Up @@ -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
Expand Down
69 changes: 69 additions & 0 deletions llvm/test/MC/Disassembler/RISCV/vmask-carry-in.txt
Original file line number Diff line number Diff line change
@@ -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: <MCInst #{{[0-9]+}} VMERGE_VVM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x44,0x45,0x5c]
# CHECK: <MCInst #{{[0-9]+}} VMERGE_VXM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0xb4,0x47,0x5c]
# CHECK: <MCInst #{{[0-9]+}} VMERGE_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

[0x57,0x04,0x4a,0x40]
# CHECK: <MCInst #{{[0-9]+}} VADC_VVM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x44,0x45,0x40]
# CHECK: <MCInst #{{[0-9]+}} VADC_VXM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0xb4,0x47,0x40]
# CHECK: <MCInst #{{[0-9]+}} VADC_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

[0x57,0x04,0x4a,0x44]
# CHECK: <MCInst #{{[0-9]+}} VMADC_VVM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x44,0x45,0x44]
# CHECK: <MCInst #{{[0-9]+}} VMADC_VXM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0xb4,0x47,0x44]
# CHECK: <MCInst #{{[0-9]+}} VMADC_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

[0x57,0x04,0x4a,0x48]
# CHECK: <MCInst #{{[0-9]+}} VSBC_VVM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x44,0x45,0x48]
# CHECK: <MCInst #{{[0-9]+}} VSBC_VXM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x04,0x4a,0x4c]
# CHECK: <MCInst #{{[0-9]+}} VMSBC_VVM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x44,0x45,0x4c]
# CHECK: <MCInst #{{[0-9]+}} VMSBC_VXM
# CHECK-COUNT-4: MCOperand Reg

[0x57,0x54,0x45,0x5c]
# CHECK: <MCInst #{{[0-9]+}} VFMERGE_VFM
# CHECK-COUNT-4: MCOperand Reg
69 changes: 69 additions & 0 deletions llvm/test/MC/RISCV/rvv/vmask-carry-in.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# RUN: llvm-mc -triple=riscv64 -show-inst --mattr=+v %s \
# RUN: --M no-aliases | FileCheck %s

# Check if there is a MCOperand for the carry-in mask.

vmerge.vvm v8, v4, v20, v0
# CHECK: <MCInst #{{[0-9]+}} VMERGE_VVM
# CHECK-COUNT-4: MCOperand Reg

vmerge.vxm v8, v4, a0, v0
# CHECK: <MCInst #{{[0-9]+}} VMERGE_VXM
# CHECK-COUNT-4: MCOperand Reg

vmerge.vim v8, v4, 15, v0
# CHECK: <MCInst #{{[0-9]+}} VMERGE_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

vadc.vvm v8, v4, v20, v0
# CHECK: <MCInst #{{[0-9]+}} VADC_VVM
# CHECK-COUNT-4: MCOperand Reg

vadc.vxm v8, v4, a0, v0
# CHECK: <MCInst #{{[0-9]+}} VADC_VXM
# CHECK-COUNT-4: MCOperand Reg

vadc.vim v8, v4, 15, v0
# CHECK: <MCInst #{{[0-9]+}} VADC_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

vmadc.vvm v8, v4, v20, v0
# CHECK: <MCInst #{{[0-9]+}} VMADC_VVM
# CHECK-COUNT-4: MCOperand Reg

vmadc.vxm v8, v4, a0, v0
# CHECK: <MCInst #{{[0-9]+}} VMADC_VXM
# CHECK-COUNT-4: MCOperand Reg

vmadc.vim v8, v4, 15, v0
# CHECK: <MCInst #{{[0-9]+}} VMADC_VIM
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Reg
# CHECK-NEXT: MCOperand Imm
# CHECK-NEXT: MCOperand Reg

vsbc.vvm v8, v4, v20, v0
# CHECK: <MCInst #{{[0-9]+}} VSBC_VVM
# CHECK-COUNT-4: MCOperand Reg

vsbc.vxm v8, v4, a0, v0
# CHECK: <MCInst #{{[0-9]+}} VSBC_VXM
# CHECK-COUNT-4: MCOperand Reg

vmsbc.vvm v8, v4, v20, v0
# CHECK: <MCInst #{{[0-9]+}} VMSBC_VVM
# CHECK-COUNT-4: MCOperand Reg

vmsbc.vxm v8, v4, a0, v0
# CHECK: <MCInst #{{[0-9]+}} VMSBC_VXM
# CHECK-COUNT-4: MCOperand Reg

vfmerge.vfm v8, v4, fa0, v0
# CHECK: <MCInst #{{[0-9]+}} VFMERGE_VFM
# CHECK-COUNT-4: MCOperand Reg
Loading