diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 8f9a5ae75fca7..f897dea519a40 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -793,6 +793,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isSImm5() const { return isSImm<5>(); } bool isSImm6() const { return isSImm<6>(); } bool isSImm11() const { return isSImm<11>(); } + bool isSImm16() const { return isSImm<16>(); } bool isSImm20() const { return isSImm<20>(); } bool isSImm26() const { return isSImm<26>(); } bool isSImm32() const { return isSImm<32>(); } @@ -1511,6 +1512,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, "immediate must be a multiple of 2 bytes in the range"); + case Match_InvalidSImm16: + return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15), + (1 << 15) - 1); case Match_InvalidSImm16NonZero: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1, @@ -3150,10 +3154,13 @@ bool RISCVAsmParser::parseDirectiveAttribute() { return false; } -bool isValidInsnFormat(StringRef Format, bool AllowC) { +bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI) { return StringSwitch(Format) .Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true) - .Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC) + .Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", + STI.hasFeature(RISCV::FeatureStdExtZca)) + .Cases("qc.eai", "qc.ei", "qc.eb", "qc.ej", "qc.es", + !STI.hasFeature(RISCV::Feature64Bit)) .Default(false); } @@ -3243,7 +3250,7 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { return false; } - if (!isValidInsnFormat(Format, AllowC)) + if (!isValidInsnFormat(Format, getSTI())) return Error(ErrorLoc, "invalid instruction format"); std::string FormatName = (".insn_" + Format).str(); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index d6672de02862d..adccd1e6c5002 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -51,7 +51,12 @@ enum { InstFormatCLH = 19, InstFormatCSB = 20, InstFormatCSH = 21, - InstFormatOther = 22, + InstFormatQC_EAI = 22, + InstFormatQC_EI = 23, + InstFormatQC_EB = 24, + InstFormatQC_EJ = 25, + InstFormatQC_ES = 26, + InstFormatOther = 31, InstFormatMask = 31, InstFormatShift = 0, @@ -333,6 +338,7 @@ enum OperandType : unsigned { OPERAND_SIMM11, OPERAND_SIMM12, OPERAND_SIMM12_LSB00000, + OPERAND_SIMM16, OPERAND_SIMM16_NONZERO, OPERAND_SIMM20, OPERAND_SIMM26, diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index d95e806b79f25..0bb0ba57ff50d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -52,7 +52,13 @@ def InstFormatCLB : InstFormat<18>; def InstFormatCLH : InstFormat<19>; def InstFormatCSB : InstFormat<20>; def InstFormatCSH : InstFormat<21>; -def InstFormatOther : InstFormat<22>; +def InstFormatQC_EAI : InstFormat<22>; +def InstFormatQC_EI : InstFormat<23>; +def InstFormatQC_EB : InstFormat<24>; +def InstFormatQC_EJ : InstFormat<25>; +def InstFormatQC_ES : InstFormat<26>; +def InstFormatOther : InstFormat<31>; + class RISCVVConstraint val> { bits<3> Value = val; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 89e5ad8067c1b..c87452171f090 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1144,6 +1144,33 @@ def AnyReg : Operand { let ParserMatchClass = AnyRegOperand; } +// isCodeGenOnly = 1 to hide them from the tablegened assembly parser. +let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1, + hasNoSchedulingInfo = 1 in { +def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> { + bits<16> value; + + let Inst{15-0} = value; + let AsmString = ".insn 0x2, $value"; +} +def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> { + bits<32> value; + + let Inst{31-0} = value; + let AsmString = ".insn 0x4, $value"; +} +def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> { + bits<48> value; + let Inst{47-0} = value; + let AsmString = ".insn 0x6, $value"; +} +def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> { + bits<64> value; + let Inst{63-0} = value; + let AsmString = ".insn 0x8, $value"; +} +} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo + // isCodeGenOnly = 1 to hide them from the tablegened assembly parser. let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1, hasNoSchedulingInfo = 1 in { @@ -1179,23 +1206,7 @@ def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2, AnyReg:$rs1, simm12:$imm12), "$opcode, $funct3, $rs2, ${imm12}(${rs1})">; -def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> { - bits<32> value; - - let Inst{31-0} = value; - let AsmString = ".insn 0x4, $value"; -} -def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> { - bits<48> value; - let Inst{47-0} = value; - let AsmString = ".insn 0x6, $value"; -} -def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> { - bits<64> value; - let Inst{63-0} = value; - let AsmString = ".insn 0x8, $value"; -} -} +} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo // Use InstAliases to match these so that we can combine the insn and format // into a mnemonic to use as the key for the tablegened asm matcher table. The diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index 718d95aa1a4bc..1c94af58880f2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -799,12 +799,6 @@ def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode, uimm3:$funct3, bare_simm12_lsb0:$imm11), "$opcode, $funct3, $imm11">; -def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> { - bits<16> value; - - let Inst{15-0} = value; - let AsmString = ".insn 0x2, $value"; -} } // Use InstAliases to match these so that we can combine the insn and format diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 2479bbd1258a4..93eb82b012eb4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -94,6 +94,8 @@ def simm5nonzero : RISCVOp, def simm11 : RISCVSImmLeafOp<11>; +def simm16 : RISCVSImmOp<16>; + def simm16nonzero : RISCVOp, ImmLeaf(Imm);}]> { let ParserMatchClass = SImmAsmOperand<16, "NonZero">; @@ -139,6 +141,219 @@ def simm32_lsb0 : Operand { // Instruction Formats //===----------------------------------------------------------------------===// + +class DirectiveInsnQC_EAI + : RVInst48 { + bits<7> opcode; + bits<3> func3; + bits<1> func1; + + bits<5> rd; + bits<32> imm32; + + let Inst{47-16} = imm32; + let Inst{15} = func1; + let Inst{14-12} = func3; + let Inst{11-7} = rd; + let Inst{6-0} = opcode; + + let AsmString = ".insn qc.eai " # argstr; +} + +class DirectiveInsnQC_EI + : RVInst48 { + bits<7> opcode; + bits<3> func3; + bits<2> func2; + + bits<5> rd; + bits<5> rs1; + bits<26> imm26; + + let Inst{47-32} = imm26{25-10}; + let Inst{31-30} = func2; + let Inst{29-20} = imm26{9-0}; + let Inst{19-15} = rs1; + let Inst{14-12} = func3; + let Inst{11-7} = rd; + let Inst{6-0} = opcode; + + let AsmString = ".insn qc.ei " # argstr; +} + +class DirectiveInsnQC_EB + : RVInst48 { + bits<7> opcode; + bits<3> func3; + bits<5> func5; + + bits<5> rs1; + bits<12> imm12; // This one is the PC-relative offset + bits<16> imm16; + + let Inst{47-32} = imm16; + let Inst{31} = imm12{11}; + let Inst{30-25} = imm12{9-4}; + let Inst{24-20} = func5; + let Inst{19-15} = rs1; + let Inst{14-12} = func3; + let Inst{11-8} = imm12{3-0}; + let Inst{7} = imm12{10}; + let Inst{6-0} = opcode; + + let AsmString = ".insn qc.eb " # argstr; +} + +class DirectiveInsnQC_EJ + : RVInst48 { + bits<7> opcode; + bits<3> func3; + bits<2> func2; + bits<5> func5; + + bits<31> imm31; + + let Inst{47-32} = imm31{30-15}; + let Inst{31} = imm31{11}; + let Inst{30-25} = imm31{9-4}; + let Inst{24-20} = func5; + let Inst{19-17} = imm31{14-12}; + let Inst{16-15} = func2; + let Inst{14-12} = func3; + let Inst{11-8} = imm31{3-0}; + let Inst{7} = imm31{10}; + let Inst{6-0} = opcode; + + let AsmString = ".insn qc.ej " # argstr; +} + +class DirectiveInsnQC_ES + : RVInst48 { + bits<7> opcode; + bits<3> func3; + bits<2> func2; + + bits<5> rs1; + bits<5> rs2; + bits<26> imm26; + + let Inst{47-32} = imm26{25-10}; + let Inst{31-30} = func2; + let Inst{29-25} = imm26{9-5}; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = func3; + let Inst{11-7} = imm26{4-0}; + let Inst{6-0} = opcode; + + let AsmString = ".insn qc.es " # argstr; +} + + +let isCodeGenOnly = true, hasSideEffects = true, mayLoad = true, + mayStore = true, hasNoSchedulingInfo = true, Predicates=[IsRV32] in { +def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm1:$func1, + simm32:$imm32), + "$opcode, $func3, $func1, $rd, $imm32">; +def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs1, + simm26:$imm26), + "$opcode, $func3, $func2, $rd, $rs1, $imm26">; +def InsnQC_EI_Mem : DirectiveInsnQC_EI<(outs AnyReg:$rd), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs1, + simm26:$imm26), + "$opcode, $func3, $func2, $rd, ${imm26}(${rs1})">; +def InsnQC_EB : DirectiveInsnQC_EB<(outs), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm5:$func5, + AnyReg:$rs1, + simm16:$imm16, + bare_simm13_lsb0:$imm12), + "$opcode, $func3, $func5, $rs1, $imm16, $imm12">; +def InsnQC_EJ : DirectiveInsnQC_EJ<(outs), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + uimm5:$func5, + simm32_lsb0:$imm31), + "$opcode, $func3, $func2, $func5, $imm31">; +def InsnQC_ES : DirectiveInsnQC_ES<(outs), + (ins uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs2, + AnyReg:$rs1, + simm26:$imm26), + "$opcode, $func3, $func2, $rs2, ${imm26}(${rs1})">; +} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo, Predicates + +let EmitPriority = 0, Predicates = [IsRV32] in { +def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32", + (InsnQC_EAI AnyReg:$rd, + uimm7_opcode:$opcode, + uimm3:$func3, + uimm1:$func1, + simm32:$imm32)>; +def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26", + (InsnQC_EI AnyReg:$rd, + uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs1, + simm26:$imm26)>; +def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, ${imm26}(${rs1})", + (InsnQC_EI_Mem AnyReg:$rd, + uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs1, + simm26:$imm26)>; +def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, (${rs1})", + (InsnQC_EI_Mem AnyReg:$rd, + uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs1, + 0)>; +def : InstAlias<".insn_qc.eb $opcode, $func3, $func5, $rs1, $imm16, $imm12", + (InsnQC_EB uimm7_opcode:$opcode, + uimm3:$func3, + uimm5:$func5, + AnyReg:$rs1, + simm16:$imm16, + bare_simm13_lsb0:$imm12)>; +def : InstAlias<".insn_qc.ej $opcode, $func3, $func2, $func5, $imm31", + (InsnQC_EJ uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + uimm5:$func5, + simm32_lsb0:$imm31)>; +def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, ${imm26}(${rs1})", + (InsnQC_ES uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs2, + AnyReg:$rs1, + simm26:$imm26)>; +def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, (${rs1})", + (InsnQC_ES uimm7_opcode:$opcode, + uimm3:$func3, + uimm2:$func2, + AnyReg:$rs2, + AnyReg:$rs1, + 0)>; +} // EmitPriority = 0, Predicates = [IsRV32] + //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/RISCV/insn_xqci-invalid.s b/llvm/test/MC/RISCV/insn_xqci-invalid.s new file mode 100644 index 0000000000000..8177adaf8ac50 --- /dev/null +++ b/llvm/test/MC/RISCV/insn_xqci-invalid.s @@ -0,0 +1,111 @@ +# RUN: not llvm-mc %s -triple=riscv32 -M no-aliases -show-encoding \ +# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s + +.insn qc.eai 128, 0, 0, x0, 0 +# CHECK-ERR: [[@LINE-1]]:14: error: opcode must be a valid opcode name or an immediate in the range [0, 127] + +.insn qc.eai 127, 8, 0, x0, 0 +# CHECK-ERR: [[@LINE-1]]:19: error: immediate must be an integer in the range [0, 7] + +.insn qc.eai 127, 7, 2, x0, 0 +# CHECK-ERR: [[@LINE-1]]:22: error: immediate must be an integer in the range [0, 1] + +.insn qc.eai 127, 7, 1, not_a_reg, 0 +# CHECK-ERR: [[@LINE-1]]:25: error: invalid operand for instruction + +.insn qc.eai 127, 7, 1, x31, 0x100000000 +# CHECK-ERR: [[@LINE-1]]:30: error: immediate must be an integer in the range [-2147483648, 4294967295] + +.insn qc.eai 126, 7, 1, x31, 0xFFFFFFFF, extra +# CHECK-ERR: [[@LINE-1]]:42: error: invalid operand for instruction + +.insn qc.ei 128, 0, 0, x31, x0, 0 +# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127] + +.insn qc.ei 127, 8, 0, x0, x0, 0 +# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7] + +.insn qc.ei 127, 7, 4, x0, x0, 0 +# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 3] + +.insn qc.ei 127, 7, 3, not_a_reg, x0, 0 +# CHECK-ERR: [[@LINE-1]]:24: error: invalid operand for instruction + +.insn qc.ei 127, 7, 3, x31, not_a_reg, 0 +# CHECK-ERR: [[@LINE-1]]:29: error: immediate must be an integer in the range [-33554432, 33554431] + +.insn qc.ei 127, 7, 3, x31, x31, 0x2000000 +# CHECK-ERR: [[@LINE-1]]:34: error: immediate must be an integer in the range [-33554432, 33554431] + +.insn qc.ei 127, 7, 3, x31, x31, 0x1000000, extra +# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction + +.insn qc.ei 126, 7, 3, x31, 0x2000000(x0) +# CHECK-ERR: [[@LINE-1]]:29: error: immediate must be an integer in the range [-33554432, 33554431] + +.insn qc.ei 126, 7, 3, x31, 0x1000000(not_a_reg) +# CHECK-ERR: [[@LINE-1]]:39: error: expected register + +.insn qc.ei 126, 7, 3, x31, 0x1000000(x31), extra +# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction + +.insn qc.eb 128, 0, 0, x0, 0, 0 +# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127] + +.insn qc.eb 127, 8, 0, x0, 0, 0 +# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7] + +.insn qc.eb 127, 7, 32, x0, 0, 0 +# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] + +.insn qc.eb 127, 7, 31, not_a_reg, 0, 0 +# CHECK-ERR: [[@LINE-1]]:25: error: invalid operand for instruction + +.insn qc.eb 127, 7, 31, x31, 0x8000, 0 +# CHECK-ERR: [[@LINE-1]]:30: error: immediate must be an integer in the range [-32768, 32767] + +.insn qc.eb 127, 7, 31, x31, 0x4000, 0x1000 +# CHECK-ERR: [[@LINE-1]]:38: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094] + +.insn qc.eb 127, 7, 31, x31, 0x4000, 0x800, extra +# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction + + +.insn qc.ej 128, 0, 0, 0, 0 +# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127] + +.insn qc.ej 127, 8, 0, 0, 0 +# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7] + +.insn qc.ej 127, 7, 4, 0, 0 +# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 3] + +.insn qc.ej 127, 7, 3, 32, 0 +# CHECK-ERR: [[@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] + +.insn qc.ej 127, 7, 3, 31, 0x100000000 +# CHECK-ERR: [[@LINE-1]]:28: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646] + +.insn qc.ej 127, 7, 3, 31, 0x80000000, extra +# CHECK-ERR: [[@LINE-1]]:40: error: invalid operand for instruction + +.insn qc.es 128, 0, 0, x0, 0(x0) +# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127] + +.insn qc.es 127, 8, 0, x0, 0(x0) +# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7] + +.insn qc.es 127, 7, 4, x0, 0(x0) +# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 3] + +.insn qc.es 127, 7, 3, not_a_reg, 0(x0) +# CHECK-ERR: [[@LINE-1]]:24: error: invalid operand for instruction + +.insn qc.es 127, 7, 3, x31, 0x2000000(x0) +# CHECK-ERR: [[@LINE-1]]:29: error: immediate must be an integer in the range [-33554432, 33554431] + +.insn qc.es 127, 7, 3, x31, 0x1000000(not_a_reg) +# CHECK-ERR: [[@LINE-1]]:39: error: expected register + +.insn qc.es 127, 7, 3, x31, 0x1000000(x31), extra +# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/insn_xqci.s b/llvm/test/MC/RISCV/insn_xqci.s new file mode 100644 index 0000000000000..098745ec22294 --- /dev/null +++ b/llvm/test/MC/RISCV/insn_xqci.s @@ -0,0 +1,41 @@ +# RUN: llvm-mc %s -triple=riscv32 -M no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcilia,+experimental-xqcilo,+experimental-xqcibi,+experimental-xqcilb \ +# RUN: -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ %s + +# CHECK-ASM: .insn qc.eai 31, 2, 0, a0, 16711935 +# CHECK-ASM: encoding: [0x1f,0x25,0xff,0x00,0xff,0x00] +# CHECK-OBJ: qc.e.addai a0, 0xff00ff +.insn qc.eai 0x1f, 2, 0, a0, 0x00FF00FF + +# CHECK-ASM: .insn qc.ei 31, 3, 2, a0, a1, 16711935 +# CHECK-ASM: encoding: [0x1f,0xb5,0xf5,0x8f,0xc0,0x3f] +# CHECK-OBJ: qc.e.addi a0, a1, 0xff00ff +.insn qc.ei 0x1f, 3, 2, a0, a1, 0x00FF00FF + +# CHECK-ASM: .insn qc.ei 31, 5, 0, a1, 16711935(a0) +# CHECK-ASM: encoding: [0x9f,0x55,0xf5,0x0f,0xc0,0x3f] +# CHECK-OBJ: qc.e.lb a1, 0xff00ff(a0) +.insn qc.ei 0x1f, 5, 0, a1, 0x00FF00FF(a0) + +# CHECK-ASM: .insn qc.ei 31, 5, 0, a1, 0(a0) +# CHECK-ASM: encoding: [0x9f,0x55,0x05,0x00,0x00,0x00] +# CHECK-OBJ: qc.e.lb a1, 0x0(a0) +.insn qc.ei 0x1f, 5, 0, a1, (a0) + +# CHECK-ASM: .insn qc.eb 31, 4, 24, a0, 17476, 22 +# CHECK-ASM: encoding: [0x1f,0x4b,0x85,0x01,0x44,0x44] +# CHECK-OBJ: qc.e.beqi a0, 0x4444, 0x2e +.insn qc.eb 0x1f, 4, 24, a0, 0x4444, 22 + +# CHECK-ASM: .insn qc.ej 31, 4, 0, 0, 22 +# CHECK-ASM: encoding: [0x1f,0x4b,0x00,0x00,0x00,0x00] +# CHECK-OBJ: qc.e.j 0x34 +.insn qc.ej 0x1f, 4, 0, 0, 22 + +# CHECK-ASM: .insn qc.es 31, 6, 1, a1, 0(a0) +# CHECK-ASM: encoding: [0x1f,0x60,0xb5,0x40,0x00,0x00] +# CHECK-OBJ: qc.e.sb a1, 0x0(a0) +.insn qc.es 0x1f, 6, 1, a1, (a0) diff --git a/llvm/test/MC/RISCV/rv64xtheadmemidx-invalid.s b/llvm/test/MC/RISCV/rv64xtheadmemidx-invalid.s index fe6d0de0a4b00..e45c43a50048a 100644 --- a/llvm/test/MC/RISCV/rv64xtheadmemidx-invalid.s +++ b/llvm/test/MC/RISCV/rv64xtheadmemidx-invalid.s @@ -1,7 +1,7 @@ # RUN: not llvm-mc -triple riscv32 -mattr=+xtheadmemidx < %s 2>&1 | FileCheck %s # RUN: not llvm-mc -triple riscv64 -mattr=+xtheadmemidx < %s 2>&1 | FileCheck %s -th.ldia 0(a0), (a1), 0, 0 # CHECK: :[[@LINE]]:23: error: invalid operand for instruction +th.ldia 0(a0), (a1), 0, 0 # CHECK: :[[@LINE]]:26: error: invalid operand for instruction th.ldib a0, 2(a1), 15, 1 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction th.lwia a0, (a1), 30, 2 # CHECK: :[[@LINE]]:20: error: immediate must be an integer in the range [-16, 15] th.lwib a0, (a1), -16, 43 # CHECK: :[[@LINE]]:25: error: immediate must be an integer in the range [0, 3]