diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -337,7 +337,6 @@ bool isImm() const override { return Kind == KindTy::Immediate; } bool isMem() const override { return false; } bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } - bool isVType() const { return Kind == KindTy::VType; } bool isGPR() const { return Kind == KindTy::Register && @@ -421,7 +420,27 @@ bool isCSRSystemRegister() const { return isSystemRegister(); } - bool isVTypeI() const { return isVType(); } + bool isVTypeImm(unsigned N) const { + int64_t Imm; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + if (!isImm()) + return false; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isUIntN(N, Imm) && VK == RISCVMCExpr::VK_RISCV_None; + } + + // If the last operand of the vsetvli/vsetvli instruction is a constant + // expression, KindTy is Immediate. + bool isVTypeI10() const { + if (Kind == KindTy::Immediate) + return isVTypeImm(10); + return Kind == KindTy::VType; + } + bool isVTypeI11() const { + if (Kind == KindTy::Immediate) + return isVTypeImm(11); + return Kind == KindTy::VType; + } /// Return true if the operand is a valid for the fence instruction e.g. /// ('iorw'). @@ -898,9 +917,21 @@ Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); } + // Support non-canonical syntax: + // "vsetivli rd, uimm, 0xabc" or "vsetvli rd, rs1, 0xabc" + // "vsetivli rd, uimm, (0xc << N)" or "vsetvli rd, rs1, (0xc << N)" void addVTypeIOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createImm(getVType())); + int64_t Imm = 0; + if (Kind == KindTy::Immediate) { + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + (void)IsConstantImm; + assert(IsConstantImm && "Invalid VTypeI Operand!"); + } else { + Imm = getVType(); + } + Inst.addOperand(MCOperand::createImm(Imm)); } // Returns the rounding mode represented by this RISCVOperand. Should only diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -19,18 +19,22 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// -def VTypeIAsmOperand : AsmOperandClass { - let Name = "VTypeI"; +class VTypeIAsmOperand : AsmOperandClass { + let Name = "VTypeI" # VTypeINum; let ParserMethod = "parseVTypeI"; let DiagnosticType = "InvalidVTypeI"; + let RenderMethod = "addVTypeIOperands"; } -def VTypeIOp : Operand { - let ParserMatchClass = VTypeIAsmOperand; +class VTypeIOp : Operand { + let ParserMatchClass = VTypeIAsmOperand; let PrintMethod = "printVTypeI"; - let DecoderMethod = "decodeUImmOperand<11>"; + let DecoderMethod = "decodeUImmOperand<"#VTypeINum#">"; } +def VTypeIOp10 : VTypeIOp<10>; +def VTypeIOp11 : VTypeIOp<11>; + def VMaskAsmOperand : AsmOperandClass { let Name = "RVVMaskRegOpOperand"; let RenderMethod = "addRegOperands"; @@ -775,10 +779,10 @@ let Predicates = [HasStdExtV] in { let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { -def VSETVLI : RVInstSetVLi<(outs GPR:$rd), (ins GPR:$rs1, VTypeIOp:$vtypei), +def VSETVLI : RVInstSetVLi<(outs GPR:$rd), (ins GPR:$rs1, VTypeIOp11:$vtypei), "vsetvli", "$rd, $rs1, $vtypei">; -def VSETIVLI : RVInstSetiVLi<(outs GPR:$rd), (ins uimm5:$uimm, VTypeIOp:$vtypei), +def VSETIVLI : RVInstSetiVLi<(outs GPR:$rd), (ins uimm5:$uimm, VTypeIOp10:$vtypei), "vsetivli", "$rd, $uimm, $vtypei">; def VSETVL : RVInstSetVL<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -3805,9 +3805,9 @@ // the when we aren't using one of the special X0 encodings. Otherwise it could // be accidentally be made X0 by MachineIR optimizations. To satisfy the // verifier, we also need a GPRX0 instruction for the special encodings. -def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp:$vtypei), []>; -def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp:$vtypei), []>; -def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp:$vtypei), []>; +def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp11:$vtypei), []>; +def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp11:$vtypei), []>; +def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp10:$vtypei), []>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/RISCV/rvv/invalid.s b/llvm/test/MC/RISCV/rvv/invalid.s --- a/llvm/test/MC/RISCV/rvv/invalid.s +++ b/llvm/test/MC/RISCV/rvv/invalid.s @@ -7,9 +7,22 @@ vsetivli a2, zero, e8,m1 # CHECK-ERROR: immediate must be an integer in the range [0, 31] +vsetivli a2, 5, (1 << 10) +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] + +vsetivli a2, 5, 0x400 +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] + vsetivli a2, 5, e31 # CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +vsetvli a2, a0, (1 << 11) +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] + +vsetvli a2, a0, 0x800 +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] + + vsetvli a2, a0, e31 # CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] diff --git a/llvm/test/MC/RISCV/rvv/vsetvl.s b/llvm/test/MC/RISCV/rvv/vsetvl.s --- a/llvm/test/MC/RISCV/rvv/vsetvl.s +++ b/llvm/test/MC/RISCV/rvv/vsetvl.s @@ -8,6 +8,43 @@ # RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-v %s \ # RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +# reserved filed: vlmul[2:0]=4, vsew[2:0]=0b1xx, non-zero bits 8/9/10. +vsetvli a2, a0, 0x224 +# CHECK-INST: vsetvli a2, a0, 548 +# CHECK-ENCODING: [0x57,0x76,0x45,0x22] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 45 22 + +vsetvli a2, a0, 0xd0 +# CHECK-INST: vsetvli a2, a0, e32, m1, ta, ma +# CHECK-ENCODING: [0x57,0x76,0x05,0x0d] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 05 0d + +vsetvli a2, a0, 0xd1 +# CHECK-INST: vsetvli a2, a0, e32, m2, ta, ma +# CHECK-ENCODING: [0x57,0x76,0x15,0x0d] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 15 0d + +vsetvli a2, a0, 0x50 +# CHECK-INST: vsetvli a2, a0, e32, m1, ta, mu +# CHECK-ENCODING: [0x57,0x76,0x05,0x05] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 05 05 + +vsetvli a2, a0, 0x90 +# CHECK-INST: vsetvli a2, a0, e32, m1, tu, ma +# CHECK-ENCODING: [0x57,0x76,0x05,0x09] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 05 09 + +vsetvli a2, a0, 144 +# CHECK-INST: vsetvli a2, a0, e32, m1, tu, ma +# CHECK-ENCODING: [0x57,0x76,0x05,0x09] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 05 09 + vsetvli a2, a0, e32, m1, ta, ma # CHECK-INST: vsetvli a2, a0, e32, m1, ta, ma # CHECK-ENCODING: [0x57,0x76,0x05,0x0d] @@ -80,6 +117,31 @@ # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) # CHECK-UNKNOWN: 57 76 b5 80 +# reserved filed: vlmul[2:0]=4, vsew[2:0]=0b1xx, non-zero bits 8/9/10. +vsetivli a2, 0, 0x224 +# CHECK-INST: vsetivli a2, 0, 548 +# CHECK-ENCODING: [0x57,0x76,0x40,0xe2] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 40 e2 + +vsetivli a2, 0, 0xd0 +# CHECK-INST: vsetivli a2, 0, e32, m1, ta, ma +# CHECK-ENCODING: [0x57,0x76,0x00,0xcd] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 76 00 cd + +vsetivli a2, 15, 0xd0 +# CHECK-INST: vsetivli a2, 15, e32, m1, ta, ma +# CHECK-ENCODING: [0x57,0xf6,0x07,0xcd] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 f6 07 cd + +vsetivli a2, 15, 208 +# CHECK-INST: vsetivli a2, 15, e32, m1, ta, ma +# CHECK-ENCODING: [0x57,0xf6,0x07,0xcd] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 f6 07 cd + vsetivli a2, 0, e32, m1, ta, ma # CHECK-INST: vsetivli a2, 0, e32, m1, ta, ma # CHECK-ENCODING: [0x57,0x76,0x00,0xcd]