diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -65,6 +65,11 @@ {"zfhmin", RISCVExtensionVersion{0, 1}}, {"zfh", RISCVExtensionVersion{0, 1}}, + + {"zfinx", RISCVExtensionVersion{1, 0}}, + {"zdinx", RISCVExtensionVersion{1, 0}}, + {"zhinxmin", RISCVExtensionVersion{1, 0}}, + {"zhinx", RISCVExtensionVersion{1, 0}}, }; static bool stripExperimentalPrefix(StringRef &Ext) { @@ -282,6 +287,15 @@ if (ExtName == "i") continue; + if (ExtName == "zdinx") + Features.push_back("+zfinx"); + if (ExtName == "zhinxmin") + Features.push_back("+zfinx"); + if (ExtName == "zhinx") { + Features.push_back("+zfinx"); + Features.push_back("+zhinxmin"); + } + if (ExtName == "zvlsseg") { Features.push_back("+experimental-v"); Features.push_back("+experimental-zvlsseg"); 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 @@ -170,6 +170,7 @@ OperandMatchResultTy parseVTypeI(OperandVector &Operands); OperandMatchResultTy parseMaskReg(OperandVector &Operands); OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands); + OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); @@ -273,6 +274,8 @@ bool IsRV64; + bool IsGPRAsFPR; + struct RegOp { MCRegister RegNum; }; @@ -344,6 +347,14 @@ RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); } + bool isGPRAsFPR() const { return isGPR() && IsGPRAsFPR; } + + bool isGPRPF64AsFPR() const { + return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1); + } + + bool isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; } + static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, RISCVMCExpr::VariantKind &VK) { if (auto *RE = dyn_cast(Expr)) { @@ -802,12 +813,14 @@ } static std::unique_ptr createReg(unsigned RegNo, SMLoc S, - SMLoc E, bool IsRV64) { + SMLoc E, bool IsRV64, + bool IsGPRAsFPR = false) { auto Op = std::make_unique(KindTy::Register); Op->Reg.RegNum = RegNo; Op->StartLoc = S; Op->EndLoc = E; Op->IsRV64 = IsRV64; + Op->IsGPRAsFPR = IsGPRAsFPR; return Op; } @@ -861,6 +874,21 @@ Inst.addOperand(MCOperand::createReg(getReg())); } + void addGPRAsFPROperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getReg())); + } + + void addGPRPF64AsFPROperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands"); + Inst.addOperand(MCOperand::createReg(getReg())); + } + + void addGPRF64AsFPROperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands"); + Inst.addOperand(MCOperand::createReg(getReg())); + } + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); @@ -1736,6 +1764,26 @@ return MatchOperand_Success; } +OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) { + switch (getLexer().getKind()) { + default: + return MatchOperand_NoMatch; + case AsmToken::Identifier: + StringRef Name = getLexer().getTok().getIdentifier(); + MCRegister RegNo; + matchRegisterNameHelper(isRV32E(), RegNo, Name); + + if (RegNo == RISCV::NoRegister) + return MatchOperand_NoMatch; + SMLoc S = getLoc(); + SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + getLexer().Lex(); + Operands.push_back(RISCVOperand::createReg( + RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF))); + } + return MatchOperand_Success; +} + OperandMatchResultTy RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { if (getLexer().isNot(AsmToken::LParen)) { diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -161,6 +161,35 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeGPRF16RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeGPRF32RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeGPRF64RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo >= 32 || RegNo & 1) + return MCDisassembler::Fail; + + MCRegister Reg = RISCV::X0 + RegNo; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder) { @@ -427,6 +456,28 @@ return MCDisassembler::Fail; } Insn = support::endian::read32le(Bytes.data()); + if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] && + !STI.getFeatureBits()[RISCV::Feature64Bit]) { + LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and" + "rv32)\n"); + Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + + if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) { + LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n"); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this, + STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); Size = 4; diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -57,6 +57,37 @@ AssemblerPredicate<(all_of FeatureStdExtZfh), "'Zfh' (Half-Precision Floating-Point)">; +def FeatureStdExtZfinx + : SubtargetFeature<"experimental-zfinx", "HasStdExtZfinx", "true", + "'Zfinx' (Float in Integer)">; +def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">, + AssemblerPredicate<(all_of FeatureStdExtZfinx), + "'Zfinx' (Float in Integer)">; + +def FeatureStdExtZdinx + : SubtargetFeature<"experimental-zdinx", "HasStdExtZdinx", "true", + "'Zdinx' (Double in Integer)", + [FeatureStdExtZfinx]>; +def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">, + AssemblerPredicate<(all_of FeatureStdExtZdinx), + "'Zdinx' (Double in Integer)">; + +def FeatureStdExtZhinxmin + : SubtargetFeature<"experimental-zhinxmin", "HasStdExtZhinxmin", "true", + "'Zhinxmin' (Half Float in Integer Minimal)", + [FeatureStdExtZfinx]>; +def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">, + AssemblerPredicate<(all_of FeatureStdExtZhinxmin), + "'Zhinxmin' (Half Float in Integer Minimal)">; + +def FeatureStdExtZhinx + : SubtargetFeature<"experimental-zhinx", "HasStdExtZhinx", "true", + "'Zhinx' (Half Float in Integer)", + [FeatureStdExtZhinxmin]>; +def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">, + AssemblerPredicate<(all_of FeatureStdExtZhinx), + "'Zhinx' (Half Float in Integer)">; + def FeatureStdExtC : SubtargetFeature<"c", "HasStdExtC", "true", "'C' (Compressed Instructions)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -25,6 +25,38 @@ def RISCVBuildPairF64 : SDNode<"RISCVISD::BuildPairF64", SDT_RISCVBuildPairF64>; def RISCVSplitF64 : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>; +//===----------------------------------------------------------------------===// +// Zdinx +//===----------------------------------------------------------------------===// + +def GPRPF64AsFPR : AsmOperandClass { + let Name = "GPRPF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF64AsFPR : AsmOperandClass { + let Name = "GPRF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF64Op : RegisterOperand { + let ParserMatchClass = GPRF64AsFPR; +} + +def GPRPF64Op : RegisterOperand { + let ParserMatchClass = GPRPF64AsFPR; +} + +def FPR64Op : RegisterOperand; + +def D : ExtInfo<"", [HasStdExtD], FPR64Op>; +def ZDINX : ExtInfo<"_INX", [HasStdExtZdinx, IsRV64], GPRF64Op, + "RVZfinx">; +def ZDIN32X : ExtInfo<"_IN32X", [HasStdExtZdinx, IsRV32], GPRPF64Op, + "RV32Zdinx">; + +defvar DINX = [D, ZDINX, ZDIN32X]; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -36,33 +68,68 @@ // reflecting the order these fields are specified in the instruction // encoding. def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>; +} // Predicates = [HasStdExtD] let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in { -def FMADD_D : FPFMA_rrr_frm; -def FMSUB_D : FPFMA_rrr_frm; -def FNMSUB_D : FPFMA_rrr_frm; -def FNMADD_D : FPFMA_rrr_frm; +defm FMADD_D : FPFMA_rrr_frm_m; +defm FMSUB_D : FPFMA_rrr_frm_m; +defm FNMSUB_D : FPFMA_rrr_frm_m; +defm FNMADD_D : FPFMA_rrr_frm_m; +} + +let Predicates = [HasStdExtD] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtD] + +let Predicates = [HasStdExtZdinx, IsRV64] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtZdinx] + +let Predicates = [HasStdExtZdinx, IsRV32] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtZdinx] + +let SchedRW = [WriteFALU64, ReadFALU64, ReadFALU64] in { +defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX>; +defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>; } +let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in +defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX>; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; - -def FADD_D : FPALU_rr_frm<0b0000001, "fadd.d", FPR64>, - Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; -def FSUB_D : FPALU_rr_frm<0b0000101, "fsub.d", FPR64>, - Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; -def FMUL_D : FPALU_rr_frm<0b0001001, "fmul.d", FPR64>, - Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>; -def FDIV_D : FPALU_rr_frm<0b0001101, "fdiv.d", FPR64>, - Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>; - -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; +let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in +defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>; +let Predicates = [HasStdExtD] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtD] + +let Predicates = [HasStdExtZdinx, IsRV64] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtZdinx, IsRV64] + +let Predicates = [HasStdExtZdinx, IsRV32] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtZdinx, IsRV32] + +let Predicates = [HasStdExtD] in { def FSQRT_D : FPUnaryOp_r_frm<0b0101101, 0b00000, FPR64, FPR64, "fsqrt.d">, Sched<[WriteFSqrt64, ReadFSqrt64]>; def : FPUnaryOpDynFrmAlias; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -55,6 +55,33 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +// Zfinx + +def GPRAsFPR : AsmOperandClass { + let Name = "GPRAsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF32Op : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +def GPROp : RegisterOperand; +def FPR32Op : RegisterOperand; + +class ExtInfo pres, RegisterOperand reg, + string space = ""> { + string Name = suffix; + list Predicates = pres; + RegisterOperand Reg = reg; + string Space = space; +} + +def F : ExtInfo<"", [HasStdExtF], FPR32Op>; +def ZFINX : ExtInfo<"_INX", [HasStdExtZfinx], GPRF32Op, "RVZfinx">; + +defvar FINX = [F, ZFINX]; + // Floating-point rounding mode def FRMArg : AsmOperandClass { @@ -92,13 +119,21 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, UseNamedOperandTable = 1, hasPostISelHook = 1 in class FPFMA_rrr_frm funct2, string opcodestr, - RegisterClass rty> + RegisterOperand rty> : RVInstR4Frm; +multiclass FPFMA_rrr_frm_m funct2, + string opcodestr, list Exts> { + foreach Ext = Exts in { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Name : FPFMA_rrr_frm; + } +} + class FPFMADynFrmAlias + RegisterOperand rty> : InstAlias; @@ -110,13 +145,20 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, UseNamedOperandTable = 1, hasPostISelHook = 1 in -class FPALU_rr_frm funct7, string opcodestr, RegisterClass rty> +class FPALU_rr_frm funct7, string opcodestr, RegisterOperand rty> : RVInstRFrm; +multiclass FPALU_rr_frm_m funct7, string opcodestr, list Exts> { + foreach Ext = Exts in { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Name : FPALU_rr_frm; + } +} + class FPALUDynFrmAlias + RegisterOperand rty> : InstAlias; @@ -160,33 +202,54 @@ // reflecting the order these fields are specified in the instruction // encoding. def FSW : FPStore_r<0b010, "fsw", FPR32, WriteFST32>; +} // Predicates = [HasStdExtF] let SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in { -def FMADD_S : FPFMA_rrr_frm; -def FMSUB_S : FPFMA_rrr_frm; -def FNMSUB_S : FPFMA_rrr_frm; -def FNMADD_S : FPFMA_rrr_frm; +defm FMADD_S : FPFMA_rrr_frm_m; +defm FMSUB_S : FPFMA_rrr_frm_m; +defm FNMSUB_S : FPFMA_rrr_frm_m; +defm FNMADD_S : FPFMA_rrr_frm_m; } -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; - -def FADD_S : FPALU_rr_frm<0b0000000, "fadd.s", FPR32>, - Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; -def FSUB_S : FPALU_rr_frm<0b0000100, "fsub.s", FPR32>, - Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; -def FMUL_S : FPALU_rr_frm<0b0001000, "fmul.s", FPR32>, - Sched<[WriteFMul32, ReadFMul32, ReadFMul32]>; -def FDIV_S : FPALU_rr_frm<0b0001100, "fdiv.s", FPR32>, - Sched<[WriteFDiv32, ReadFDiv32, ReadFDiv32]>; - -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; +let Predicates = [HasStdExtF] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtF] + +let Predicates = [HasStdExtZfinx] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtZfinx] + +let SchedRW = [WriteFALU32, ReadFALU32, ReadFALU32] in { +defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX>; +defm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", FINX>; +} +let SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in +defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX>; +let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in +defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>; + +let Predicates = [HasStdExtF] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtF] + +let Predicates = [HasStdExtZfinx] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtZfinx] + +let Predicates = [HasStdExtF] in { def FSQRT_S : FPUnaryOp_r_frm<0b0101100, 0b00000, FPR32, FPR32, "fsqrt.s">, Sched<[WriteFSqrt32, ReadFSqrt32]>; def : FPUnaryOpDynFrmAlias; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td @@ -27,6 +27,21 @@ def riscv_fmv_x_anyexth : SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_ANYEXTH>; +//===----------------------------------------------------------------------===// +// Zhinx and Zhinxmin +//===----------------------------------------------------------------------===// + +def GPRF16Op : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +def FPR16Op : RegisterOperand; + +def ZFH : ExtInfo<"", [HasStdExtZfh], FPR16Op>; +def ZHINX : ExtInfo<"_INX", [HasStdExtZhinx], GPRF16Op, "RVZfinx">; + +defvar HINX = [ZFH, ZHINX]; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -40,33 +55,52 @@ def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>; } // Predicates = [HasStdExtZfhmin] -let Predicates = [HasStdExtZfh] in { let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in { -def FMADD_H : FPFMA_rrr_frm; -def FMSUB_H : FPFMA_rrr_frm; -def FNMSUB_H : FPFMA_rrr_frm; -def FNMADD_H : FPFMA_rrr_frm; +defm FMADD_H : FPFMA_rrr_frm_m; +defm FMSUB_H : FPFMA_rrr_frm_m; +defm FNMSUB_H : FPFMA_rrr_frm_m; +defm FNMADD_H : FPFMA_rrr_frm_m; +} + +let Predicates = [HasStdExtZfh] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtZfh] + +let Predicates = [HasStdExtZhinx] in { +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +def : FPFMADynFrmAlias; +} // Predicates = [HasStdExtZhinx] + +let SchedRW = [WriteFALU16, ReadFALU16, ReadFALU16] in { +defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX>; +defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", HINX>; } +let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in +defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX>; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; -def : FPFMADynFrmAlias; - -def FADD_H : FPALU_rr_frm<0b0000010, "fadd.h", FPR16>, - Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; -def FSUB_H : FPALU_rr_frm<0b0000110, "fsub.h", FPR16>, - Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; -def FMUL_H : FPALU_rr_frm<0b0001010, "fmul.h", FPR16>, - Sched<[WriteFMul16, ReadFMul16, ReadFMul16]>; -def FDIV_H : FPALU_rr_frm<0b0001110, "fdiv.h", FPR16>, - Sched<[WriteFDiv16, ReadFDiv16, ReadFDiv16]>; - -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; -def : FPALUDynFrmAlias; +let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in +defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>; +let Predicates = [HasStdExtZfh] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtZfh] + +let Predicates = [HasStdExtZhinx] in { +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +def : FPALUDynFrmAlias; +} // Predicates = [HasStdExtZhinx] + +let Predicates = [HasStdExtZfh] in { def FSQRT_H : FPUnaryOp_r_frm<0b0101110, 0b00000, FPR16, FPR16, "fsqrt.h">, Sched<[WriteFSqrt16, ReadFSqrt16]>; def : FPUnaryOpDynFrmAlias; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -66,6 +66,7 @@ def sub_vrm1_6 : ComposedSubRegIndex; def sub_vrm1_7 : ComposedSubRegIndex; +def sub_32_hi : SubRegIndex<32, 32>; } // Namespace = "RISCV" // Integer registers @@ -557,6 +558,63 @@ let Size = 64; } +let RegAltNameIndices = [ABIRegAltName] in { + foreach Index = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, + 24, 26, 28, 30] in { + defvar Reg = !cast("X"#Index); + def X#Index#_PD : RISCVRegWithSubRegs("X"#Index), + !cast("X"#!add(Index, 1))], + Reg.AltNames> { + let SubRegIndices = [sub_32, sub_32_hi]; + } + } +} + +def GPRF16 : RegisterClass<"RISCV", [f16], 16, (add + (sequence "X%u", 10, 17), + (sequence "X%u", 5, 7), + (sequence "X%u", 28, 31), + (sequence "X%u", 8, 9), + (sequence "X%u", 18, 27), + (sequence "X%u", 0, 4) +)> { + let RegInfos = XLenRI; +} + +def GPRF32 : RegisterClass<"RISCV", [f32], 32, (add + (sequence "X%u", 10, 17), + (sequence "X%u", 5, 7), + (sequence "X%u", 28, 31), + (sequence "X%u", 8, 9), + (sequence "X%u", 18, 27), + (sequence "X%u", 0, 4) +)> { + let RegInfos = XLenRI; +} + +def GPRF64 : RegisterClass<"RISCV", [f64], 64, (add + (sequence "X%u", 10, 17), + (sequence "X%u", 5, 7), + (sequence "X%u", 28, 31), + (sequence "X%u", 8, 9), + (sequence "X%u", 18, 27), + (sequence "X%u", 0, 4) +)> { + let RegInfos = XLenRI; +} + +def GPRPF64 : RegisterClass<"RISCV", [f64], 64, (add + X10_PD, X12_PD, X14_PD, X16_PD, + X6_PD, + X28_PD, X30_PD, + X8_PD, + X18_PD, X20_PD, X22_PD, X24_PD, X26_PD, + X0_PD, X2_PD, X4_PD +)> { + let RegInfos = XLenRI; +} + // The register class is added for inline assembly for vector mask types. def VM : VReg&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv32 %s 2>&1 | FileCheck %s # Out of range immediates ## fencearg @@ -173,6 +173,9 @@ amomaxu.w s5, s4, (s3) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'A' (Atomic Instructions) fadd.s ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) fadd.h ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) +fadd.s a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfinx' (Float in Integer) +fadd.d a0, a2, a4 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer) +fadd.h a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer) # Using floating point registers when integer registers are expected addi a2, ft0, 24 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zdinx-invalid.s b/llvm/test/MC/RISCV/rv32zdinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zdinx-invalid.s @@ -0,0 +1,11 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zdinx %s 2>&1 | FileCheck %s + +# Invalid instructions +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction +fmv.x.w s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction + +# Invalid register names +lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction +lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register +fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zdinx-valid.s b/llvm/test/MC/RISCV/rv32zdinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zdinx-valid.s @@ -0,0 +1,68 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zdinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zdinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: lw s0, 12(a0) +# CHECK-ASM: encoding: [0x03,0x24,0xc5,0x00] +lw s0, 12(a0) +# CHECK-ASM-AND-OBJ: lw s1, 4(ra) +# CHECK-ASM: encoding: [0x83,0xa4,0x40,0x00] +lw s1, +4(ra) +# CHECK-ASM-AND-OBJ: lw s2, -2048(a3) +# CHECK-ASM: encoding: [0x03,0xa9,0x06,0x80] +lw s2, -2048(x13) +# CHECK-ASM-AND-OBJ: lw s3, -2048(s1) +# CHECK-ASM: encoding: [0x83,0xa9,0x04,0x80] +lw s3, %lo(2048)(s1) +# CHECK-ASM-AND-OBJ: lw s4, 2047(s2) +# CHECK-ASM: encoding: [0x03,0x2a,0xf9,0x7f] +lw s4, 2047(s2) +# CHECK-ASM-AND-OBJ: lw s5, 0(s3) +# CHECK-ASM: encoding: [0x83,0xaa,0x09,0x00] +lw s5, 0(s3) + +# CHECK-ASM-AND-OBJ: sw s6, 2047(s4) +# CHECK-ASM: encoding: [0xa3,0x2f,0x6a,0x7f] +sw s6, 2047(s4) +# CHECK-ASM-AND-OBJ: sw s7, -2048(s5) +# CHECK-ASM: encoding: [0x23,0xa0,0x7a,0x81] +sw s7, -2048(s5) +# CHECK-ASM-AND-OBJ: sw s8, -2048(s6) +# CHECK-ASM: encoding: [0x23,0x20,0x8b,0x81] +sw s8, %lo(2048)(s6) +# CHECK-ASM-AND-OBJ: sw s9, 999(s7) +# CHECK-ASM: encoding: [0xa3,0xa3,0x9b,0x3f] +sw s9, 999(s7) + +# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, dyn +# CHECK-ASM: encoding: [0x43,0x75,0xe6,0x82] +fmadd.d x10, x12, x14, x16, dyn +# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, dyn +# CHECK-ASM: encoding: [0x47,0x75,0xe6,0x82] +fmsub.d x10, x12, x14, x16, dyn +# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, dyn +# CHECK-ASM: encoding: [0x4b,0x75,0xe6,0x82] +fnmsub.d x10, x12, x14, x16, dyn +# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, dyn +# CHECK-ASM: encoding: [0x4f,0x75,0xe6,0x82] +fnmadd.d x10, x12, x14, x16, dyn + +# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, dyn +# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x03] +fadd.d x26, x28, x30, dyn +# CHECK-ASM-AND-OBJ: fsub.d s10, t3, t5, dyn +# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x0b] +fsub.d x26, x28, x30, dyn +# CHECK-ASM-AND-OBJ: fmul.d s10, t3, t5, dyn +# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x13] +fmul.d x26, x28, x30, dyn +# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, dyn +# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x1b] +fdiv.d x26, x28, x30, dyn diff --git a/llvm/test/MC/RISCV/rv32zfinx-invalid.s b/llvm/test/MC/RISCV/rv32zfinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zfinx-invalid.s @@ -0,0 +1,12 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfinx %s 2>&1 | FileCheck %s + +# Invalid instructions +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction +fmv.x.d s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +fadd.d t1, t3, t5 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer) + +# Invalid register names +lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction +lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register +fadd.s a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zfinx-valid.s b/llvm/test/MC/RISCV/rv32zfinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zfinx-valid.s @@ -0,0 +1,68 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: lw s0, 12(a0) +# CHECK-ASM: encoding: [0x03,0x24,0xc5,0x00] +lw s0, 12(a0) +# CHECK-ASM-AND-OBJ: lw s1, 4(ra) +# CHECK-ASM: encoding: [0x83,0xa4,0x40,0x00] +lw s1, +4(ra) +# CHECK-ASM-AND-OBJ: lw s2, -2048(a3) +# CHECK-ASM: encoding: [0x03,0xa9,0x06,0x80] +lw s2, -2048(x13) +# CHECK-ASM-AND-OBJ: lw s3, -2048(s1) +# CHECK-ASM: encoding: [0x83,0xa9,0x04,0x80] +lw s3, %lo(2048)(s1) +# CHECK-ASM-AND-OBJ: lw s4, 2047(s2) +# CHECK-ASM: encoding: [0x03,0x2a,0xf9,0x7f] +lw s4, 2047(s2) +# CHECK-ASM-AND-OBJ: lw s5, 0(s3) +# CHECK-ASM: encoding: [0x83,0xaa,0x09,0x00] +lw s5, 0(s3) + +# CHECK-ASM-AND-OBJ: sw s6, 2047(s4) +# CHECK-ASM: encoding: [0xa3,0x2f,0x6a,0x7f] +sw s6, 2047(s4) +# CHECK-ASM-AND-OBJ: sw s7, -2048(s5) +# CHECK-ASM: encoding: [0x23,0xa0,0x7a,0x81] +sw s7, -2048(s5) +# CHECK-ASM-AND-OBJ: sw s8, -2048(s6) +# CHECK-ASM: encoding: [0x23,0x20,0x8b,0x81] +sw s8, %lo(2048)(s6) +# CHECK-ASM-AND-OBJ: sw s9, 999(s7) +# CHECK-ASM: encoding: [0xa3,0xa3,0x9b,0x3f] +sw s9, 999(s7) + +# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, dyn +# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x68] +fmadd.s x10, x11, x12, x13, dyn +# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, dyn +# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89] +fmsub.s x14, x15, x16, x17, dyn +# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, dyn +# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xa9] +fnmsub.s x18, x19, x20, x21, dyn +# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, dyn +# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xc9] +fnmadd.s x22, x23, x24, x25, dyn + +# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, dyn +# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x01] +fadd.s x26, x27, x28, dyn +# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, dyn +# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x09] +fsub.s x29, x30, x31, dyn +# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, dyn +# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x11] +fmul.s s0, s1, s2, dyn +# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, dyn +# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x19] +fdiv.s s3, s4, s5, dyn diff --git a/llvm/test/MC/RISCV/rv32zhinx-invalid.s b/llvm/test/MC/RISCV/rv32zhinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zhinx-invalid.s @@ -0,0 +1,11 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zhinx %s 2>&1 | FileCheck %s + +# Invalid instructions +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction +fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction + +# Invalid register names +lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction +lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register +fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zhinx-valid.s b/llvm/test/MC/RISCV/rv32zhinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zhinx-valid.s @@ -0,0 +1,68 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zhinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zhinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: lh s0, 12(a0) +# CHECK-ASM: encoding: [0x03,0x14,0xc5,0x00] +lh s0, 12(a0) +# CHECK-ASM-AND-OBJ: lh s1, 4(ra) +# CHECK-ASM: encoding: [0x83,0x94,0x40,0x00] +lh s1, +4(ra) +# CHECK-ASM-AND-OBJ: lh s2, -2048(a3) +# CHECK-ASM: encoding: [0x03,0x99,0x06,0x80] +lh s2, -2048(x13) +# CHECK-ASM-AND-OBJ: lh s3, -2048(s1) +# CHECK-ASM: encoding: [0x83,0x99,0x04,0x80] +lh s3, %lo(2048)(s1) +# CHECK-ASM-AND-OBJ: lh s4, 2047(s2) +# CHECK-ASM: encoding: [0x03,0x1a,0xf9,0x7f] +lh s4, 2047(s2) +# CHECK-ASM-AND-OBJ: lh s5, 0(s3) +# CHECK-ASM: encoding: [0x83,0x9a,0x09,0x00] +lh s5, 0(s3) + +# CHECK-ASM-AND-OBJ: sh s6, 2047(s4) +# CHECK-ASM: encoding: [0xa3,0x1f,0x6a,0x7f] +sh s6, 2047(s4) +# CHECK-ASM-AND-OBJ: sh s7, -2048(s5) +# CHECK-ASM: encoding: [0x23,0x90,0x7a,0x81] +sh s7, -2048(s5) +# CHECK-ASM-AND-OBJ: sh s0, -2048(s6) +# CHECK-ASM: encoding: [0x23,0x10,0x8b,0x80] +sh x8, %lo(2048)(s6) +# CHECK-ASM-AND-OBJ: sh s1, 999(s7) +# CHECK-ASM: encoding: [0xa3,0x93,0x9b,0x3e] +sh x9, 999(s7) + +# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, dyn +# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x6c] +fmadd.h x10, x11, x12, x13, dyn +# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, dyn +# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d] +fmsub.h x14, x15, x16, x17, dyn +# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, dyn +# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xad] +fnmsub.h x18, x19, x20, x21, dyn +# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, dyn +# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xcd] +fnmadd.h x22, x23, x24, x25, dyn + +# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, dyn +# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x05] +fadd.h x26, x27, x28, dyn +# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, dyn +# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x0d] +fsub.h x29, x30, x31, dyn +# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, dyn +# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x15] +fmul.h s0, s1, s2, dyn +# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, dyn +# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x1d] +fdiv.h s3, s4, s5, dyn diff --git a/llvm/test/MC/RISCV/rv32zhinxmin-invalid.s b/llvm/test/MC/RISCV/rv32zhinxmin-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zhinxmin-invalid.s @@ -0,0 +1,14 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zhinxmin %s 2>&1 | FileCheck %s + +# Invalid instructions +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction +fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction + +# Invalid register names +lw f15, 100(a0) # CHECK: :[[@LINE]]:4: error: invalid operand for instruction +lw t1, 100(a10) # CHECK: :[[@LINE]]:12: error: expected register +fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction + +# Valid in Zhinx +fmadd.h x10, x11, x12, x13, dyn # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer) diff --git a/llvm/test/MC/RISCV/rvzdinx-aliases-valid.s b/llvm/test/MC/RISCV/rvzdinx-aliases-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rvzdinx-aliases-valid.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zdinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zdinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zdinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zdinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zdinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zdinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zdinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zdinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +##===----------------------------------------------------------------------===## +## Aliases which omit the rounding mode. +##===----------------------------------------------------------------------===## + +# CHECK-INST: fmadd.d a0, a2, a4, a6, dyn +# CHECK-ALIAS: fmadd.d a0, a2, a4, a6 +fmadd.d x10, x12, x14, x16 +# CHECK-INST: fmsub.d a0, a2, a4, a6, dyn +# CHECK-ALIAS: fmsub.d a0, a2, a4, a6 +fmsub.d x10, x12, x14, x16 +# CHECK-INST: fnmsub.d a0, a2, a4, a6, dyn +# CHECK-ALIAS: fnmsub.d a0, a2, a4, a6 +fnmsub.d x10, x12, x14, x16 +# CHECK-INST: fnmadd.d a0, a2, a4, a6, dyn +# CHECK-ALIAS: fnmadd.d a0, a2, a4, a6 +fnmadd.d x10, x12, x14, x16 +# CHECK-INST: fadd.d a0, a2, a4, dyn +# CHECK-ALIAS: fadd.d a0, a2, a4 +fadd.d x10, x12, x14 +# CHECK-INST: fsub.d a0, a2, a4, dyn +# CHECK-ALIAS: fsub.d a0, a2, a4 +fsub.d x10, x12, x14 +# CHECK-INST: fmul.d a0, a2, a4, dyn +# CHECK-ALIAS: fmul.d a0, a2, a4 +fmul.d x10, x12, x14 +# CHECK-INST: fdiv.d a0, a2, a4, dyn +# CHECK-ALIAS: fdiv.d a0, a2, a4 +fdiv.d x10, x12, x14 diff --git a/llvm/test/MC/RISCV/rvzfinx-aliases-valid.s b/llvm/test/MC/RISCV/rvzfinx-aliases-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rvzfinx-aliases-valid.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +##===----------------------------------------------------------------------===## +## Aliases which omit the rounding mode. +##===----------------------------------------------------------------------===## + +# CHECK-INST: fmadd.s a0, a1, a2, a3, dyn +# CHECK-ALIAS: fmadd.s a0, a1, a2, a3 +fmadd.s x10, x11, x12, x13 +# CHECK-INST: fmsub.s a4, a5, a6, a7, dyn +# CHECK-ALIAS: fmsub.s a4, a5, a6, a7 +fmsub.s x14, x15, x16, x17 +# CHECK-INST: fnmsub.s s2, s3, s4, s5, dyn +# CHECK-ALIAS: fnmsub.s s2, s3, s4, s5 +fnmsub.s x18, x19, x20, x21 +# CHECK-INST: fnmadd.s s6, s7, s8, s9, dyn +# CHECK-ALIAS: fnmadd.s s6, s7, s8, s9 +fnmadd.s x22, x23, x24, x25 +# CHECK-INST: fadd.s s10, s11, t3, dyn +# CHECK-ALIAS: fadd.s s10, s11, t3 +fadd.s x26, x27, x28 +# CHECK-INST: fsub.s t4, t5, t6, dyn +# CHECK-ALIAS: fsub.s t4, t5, t6 +fsub.s x29, x30, x31 +# CHECK-INST: fmul.s s0, s1, s2, dyn +# CHECK-ALIAS: fmul.s s0, s1, s2 +fmul.s s0, s1, s2 +# CHECK-INST: fdiv.s s3, s4, s5, dyn +# CHECK-ALIAS: fdiv.s s3, s4, s5 +fdiv.s s3, s4, s5 diff --git a/llvm/test/MC/RISCV/rvzhinx-aliases-valid.s b/llvm/test/MC/RISCV/rvzhinx-aliases-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rvzhinx-aliases-valid.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zhinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zhinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +##===----------------------------------------------------------------------===## +## Aliases which omit the rounding mode. +##===----------------------------------------------------------------------===## + +# CHECK-INST: fmadd.h a0, a1, a2, a3, dyn +# CHECK-ALIAS: fmadd.h a0, a1, a2, a3 +fmadd.h x10, x11, x12, x13 +# CHECK-INST: fmsub.h a4, a5, a6, a7, dyn +# CHECK-ALIAS: fmsub.h a4, a5, a6, a7 +fmsub.h x14, x15, x16, x17 +# CHECK-INST: fnmsub.h s2, s3, s4, s5, dyn +# CHECK-ALIAS: fnmsub.h s2, s3, s4, s5 +fnmsub.h x18, x19, x20, x21 +# CHECK-INST: fnmadd.h s6, s7, s8, s9, dyn +# CHECK-ALIAS: fnmadd.h s6, s7, s8, s9 +fnmadd.h x22, x23, x24, x25 +# CHECK-INST: fadd.h s10, s11, t3, dyn +# CHECK-ALIAS: fadd.h s10, s11, t3 +fadd.h x26, x27, x28 +# CHECK-INST: fsub.h t4, t5, t6, dyn +# CHECK-ALIAS: fsub.h t4, t5, t6 +fsub.h x29, x30, x31 +# CHECK-INST: fmul.h s0, s1, s2, dyn +# CHECK-ALIAS: fmul.h s0, s1, s2 +fmul.h s0, s1, s2 +# CHECK-INST: fdiv.h s3, s4, s5, dyn +# CHECK-ALIAS: fdiv.h s3, s4, s5 +fdiv.h s3, s4, s5