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 @@ -53,6 +53,11 @@ {"zfhmin", RISCVExtensionVersion{1, 0}}, {"zfh", RISCVExtensionVersion{1, 0}}, + {"zfinx", RISCVExtensionVersion{1, 0}}, + {"zdinx", RISCVExtensionVersion{1, 0}}, + {"zhinxmin", RISCVExtensionVersion{1, 0}}, + {"zhinx", RISCVExtensionVersion{1, 0}}, + {"zba", RISCVExtensionVersion{1, 0}}, {"zbb", RISCVExtensionVersion{1, 0}}, {"zbc", RISCVExtensionVersion{1, 0}}, @@ -688,6 +693,8 @@ bool HasE = Exts.count("e") != 0; bool HasD = Exts.count("d") != 0; bool HasF = Exts.count("f") != 0; + bool HasZfinx = Exts.count("zfinx") != 0; + bool HasZdinx = Exts.count("zdinx") != 0; bool HasVector = Exts.count("zve32x") != 0; bool HasZve32f = Exts.count("zve32f") != 0; bool HasZve64d = Exts.count("zve64d") != 0; @@ -706,17 +713,15 @@ return createStringError(errc::invalid_argument, "d requires f extension to also be specified"); - // FIXME: Consider Zfinx in the future - if (HasZve32f && !HasF) + if (HasZve32f && !HasF && !HasZfinx) return createStringError( errc::invalid_argument, - "zve32f requires f extension to also be specified"); + "zve32f requires f or zfinx extension to also be specified"); - // FIXME: Consider Zdinx in the future - if (HasZve64d && !HasD) + if (HasZve64d && !HasD && !HasZdinx) return createStringError( errc::invalid_argument, - "zve64d requires d extension to also be specified"); + "zve64d requires d or zdinx extension to also be specified"); if (HasZvl && !HasVector) return createStringError( @@ -733,6 +738,9 @@ static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"}; static const char *ImpliedExtsZfhmin[] = {"f"}; static const char *ImpliedExtsZfh[] = {"f"}; +static const char *ImpliedExtsZdinx[] = {"zfinx"}; +static const char *ImpliedExtsZhinxmin[] = {"zfinx"}; +static const char *ImpliedExtsZhinx[] = {"zfinx"}; static const char *ImpliedExtsZve64d[] = {"zve64f"}; static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"}; static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"}; @@ -767,8 +775,11 @@ // Note: The table needs to be sorted by name. static constexpr ImpliedExtsEntry ImpliedExts[] = { {{"v"}, {ImpliedExtsV}}, + {{"zdinx"}, {ImpliedExtsZdinx}}, {{"zfh"}, {ImpliedExtsZfh}}, {{"zfhmin"}, {ImpliedExtsZfhmin}}, + {{"zhinx"}, {ImpliedExtsZhinx}}, + {{"zhinxmin"}, {ImpliedExtsZhinxmin}}, {{"zk"}, {ImpliedExtsZk}}, {{"zkn"}, {ImpliedExtsZkn}}, {{"zks"}, {ImpliedExtsZks}}, 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 @@ -171,6 +171,7 @@ OperandMatchResultTy parseVTypeI(OperandVector &Operands); OperandMatchResultTy parseMaskReg(OperandVector &Operands); OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands); + OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); @@ -274,6 +275,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 isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; } + + bool isGPRPF64AsFPR() const { + return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1); + } + static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, RISCVMCExpr::VariantKind &VK) { if (auto *RE = dyn_cast(Expr)) { @@ -840,12 +851,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; } @@ -1801,6 +1814,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,17 @@ return MCDisassembler::Success; } +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 +438,27 @@ 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"); + 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 @@ -70,6 +70,43 @@ "'Zfh' (Half-Precision Floating-Point) or " "'Zfhmin' (Half-Precision Floating-Point Minimal)">; +def FeatureStdExtZfinx + : SubtargetFeature<"zfinx", "HasStdExtZfinx", "true", + "'Zfinx' (Float in Integer)">; +def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">, + AssemblerPredicate<(all_of FeatureStdExtZfinx), + "'Zfinx' (Float in Integer)">; + +def FeatureStdExtZdinx + : SubtargetFeature<"zdinx", "HasStdExtZdinx", "true", + "'Zdinx' (Double in Integer)", + [FeatureStdExtZfinx]>; +def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">, + AssemblerPredicate<(all_of FeatureStdExtZdinx), + "'Zdinx' (Double in Integer)">; + +def FeatureStdExtZhinxmin + : SubtargetFeature<"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<"zhinx", "HasStdExtZhinx", "true", + "'Zhinx' (Half Float in Integer)", + [FeatureStdExtZfinx]>; +def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">, + AssemblerPredicate<(all_of FeatureStdExtZhinx), + "'Zhinx' (Half Float in Integer)">; + +def HasStdExtZhinxOrZhinxmin + : Predicate<"Subtarget->hasStdExtZhinx() || Subtarget->hasStdExtZhinxmin()">, + AssemblerPredicate<(any_of FeatureStdExtZhinx, FeatureStdExtZhinxmin), + "'Zhinx' (Half Float in Integer) or " + "'Zhinxmin' (Half Float in Integer Minimal)">; + def FeatureStdExtC : SubtargetFeature<"c", "HasStdExtC", "true", "'C' (Compressed Instructions)">; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -10920,7 +10920,29 @@ } } - return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); + std::pair Res = + TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); + + if (Res.second == &RISCV::GPRF32RegClass) { + if (!Subtarget.is64Bit() || VT == MVT::Other) + return std::make_pair(Res.first, &RISCV::GPRRegClass); + return std::make_pair(0, nullptr); + } + + if (Res.second == &RISCV::GPRF64RegClass || + Res.second == &RISCV::GPRPF64RegClass) { + if (Subtarget.is64Bit() || VT == MVT::Other) + return std::make_pair(Res.first, &RISCV::GPRRegClass); + return std::make_pair(0, nullptr); + } + + if (Res.second == &RISCV::GPRF16RegClass) { + if (VT == MVT::Other) + return std::make_pair(Res.first, &RISCV::GPRRegClass); + return std::make_pair(0, nullptr); + } + + return Res; } unsigned 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,69 @@ def RISCVBuildPairF64 : SDNode<"RISCVISD::BuildPairF64", SDT_RISCVBuildPairF64>; def RISCVSplitF64 : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>; +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +// Zdinx + +def GPRPF64AsFPR : AsmOperandClass { + let Name = "GPRPF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; + let RenderMethod = "addRegOperands"; +} + +def GPRF64AsFPR : AsmOperandClass { + let Name = "GPRF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; + let RenderMethod = "addRegOperands"; +} + +def FPR64INX : RegisterOperand { + let ParserMatchClass = GPRF64AsFPR; + let DecoderMethod = "DecodeGPRRegisterClass"; +} + +def FPR64IN32X : RegisterOperand { + let ParserMatchClass = GPRPF64AsFPR; +} + +def DExt : ExtInfo<0, [HasStdExtD]>; +def D64Ext : ExtInfo<0, [HasStdExtD, IsRV64]>; +def ZdinxExt : ExtInfo<1, [HasStdExtZdinx, IsRV64]>; +def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>; + +def D : ExtInfo_r; +def D_INX : ExtInfo_r; +def D_IN32X : ExtInfo_r; + +def DD : ExtInfo_rr; +def DD_INX : ExtInfo_rr; +def DD_IN32X : ExtInfo_rr; +def DF : ExtInfo_rr; +def DF_INX : ExtInfo_rr; +def DF_IN32X : ExtInfo_rr; +def DX : ExtInfo_rr; +def DX_INX : ExtInfo_rr; +def DX_IN32X : ExtInfo_rr; +def DX_64 : ExtInfo_rr; +def FD : ExtInfo_rr; +def FD_INX : ExtInfo_rr; +def FD_IN32X : ExtInfo_rr; +def XD : ExtInfo_rr; +def XD_INX : ExtInfo_rr; +def XD_IN32X : ExtInfo_rr; +def XD_64 : ExtInfo_rr; + +defvar DINX = [D, D_INX, D_IN32X]; +defvar DDINX = [DD, DD_INX, DD_IN32X]; +defvar DXINX = [DX, DX_INX, DX_IN32X]; +defvar DFINX = [DF, DF_INX, DF_IN32X]; +defvar FDINX = [FD, FD_INX, FD_IN32X]; +defvar XDINX = [XD, XD_INX, XD_IN32X]; +defvar DXIN64X = [DX_64, DX_INX]; +defvar XDIN64X = [XD_64, XD_INX]; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -36,106 +99,104 @@ // 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; +} + +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; + +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; - -def FSQRT_D : FPUnaryOp_r_frm<0b0101101, 0b00000, FPR64, FPR64, "fsqrt.d">, - Sched<[WriteFSqrt64, ReadFSqrt64]>; -def : FPUnaryOpDynFrmAlias; +let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in +defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>; + +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; + +defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, DDINX, "fsqrt.d">, + Sched<[WriteFSqrt64, ReadFSqrt64]>; +defm : FPUnaryOpDynFrmAlias_m; let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64], mayRaiseFPException = 0 in { -def FSGNJ_D : FPALU_rr<0b0010001, 0b000, "fsgnj.d", FPR64>; -def FSGNJN_D : FPALU_rr<0b0010001, 0b001, "fsgnjn.d", FPR64>; -def FSGNJX_D : FPALU_rr<0b0010001, 0b010, "fsgnjx.d", FPR64>; +defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", DINX>; +defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", DINX>; +defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>; } let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in { -def FMIN_D : FPALU_rr<0b0010101, 0b000, "fmin.d", FPR64>; -def FMAX_D : FPALU_rr<0b0010101, 0b001, "fmax.d", FPR64>; +defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX>; +defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX>; } -def FCVT_S_D : FPUnaryOp_r_frm<0b0100000, 0b00001, FPR32, FPR64, "fcvt.s.d">, - Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_D_S : FPUnaryOp_r<0b0100001, 0b00000, 0b000, FPR64, FPR32, "fcvt.d.s">, - Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>; +defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>; let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in { -def FEQ_D : FPCmp_rr<0b1010001, 0b010, "feq.d", FPR64>; -def FLT_D : FPCmp_rr<0b1010001, 0b001, "flt.d", FPR64>; -def FLE_D : FPCmp_rr<0b1010001, 0b000, "fle.d", FPR64>; +defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX>; +defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>; +defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>; } -let mayRaiseFPException = 0 in -def FCLASS_D : FPUnaryOp_r<0b1110001, 0b00000, 0b001, GPR, FPR64, "fclass.d">, - Sched<[WriteFClass64, ReadFClass64]>; +defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, XDINX, "fclass.d">, + Sched<[WriteFClass64, ReadFClass64]>; -def FCVT_W_D : FPUnaryOp_r_frm<0b1100001, 0b00000, GPR, FPR64, "fcvt.w.d">, +defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, XDINX, "fcvt.w.d">, Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; -def : FPUnaryOpDynFrmAlias; - -def FCVT_WU_D : FPUnaryOp_r_frm<0b1100001, 0b00001, GPR, FPR64, "fcvt.wu.d">, - Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_D_W : FPUnaryOp_r<0b1101001, 0b00000, 0b000, FPR64, GPR, "fcvt.d.w">, - Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>; +defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, XDINX, "fcvt.wu.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_D_WU : FPUnaryOp_r<0b1101001, 0b00001, 0b000, FPR64, GPR, "fcvt.d.wu">, +defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, DXINX, "fcvt.d.w">, Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>; -} // Predicates = [HasStdExtD] -let Predicates = [HasStdExtD, IsRV64] in { -def FCVT_L_D : FPUnaryOp_r_frm<0b1100001, 0b00010, GPR, FPR64, "fcvt.l.d">, - Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, DXINX, "fcvt.d.wu">, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>; -def FCVT_LU_D : FPUnaryOp_r_frm<0b1100001, 0b00011, GPR, FPR64, "fcvt.lu.d">, +defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, XDIN64X, "fcvt.l.d">, Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -let mayRaiseFPException = 0 in +defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, XDIN64X, "fcvt.lu.d">, + Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>; +defm : FPUnaryOpDynFrmAlias_m; + +let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in def FMV_X_D : FPUnaryOp_r<0b1110001, 0b00000, 0b000, GPR, FPR64, "fmv.x.d">, Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>; -def FCVT_D_L : FPUnaryOp_r_frm<0b1101001, 0b00010, FPR64, GPR, "fcvt.d.l">, - Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>; -def : FPUnaryOpDynFrmAlias; - -def FCVT_D_LU : FPUnaryOp_r_frm<0b1101001, 0b00011, FPR64, GPR, "fcvt.d.lu">, +defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, DXIN64X, "fcvt.d.l">, Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -let mayRaiseFPException = 0 in +defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, DXIN64X, "fcvt.d.lu">, + Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>; +defm : FPUnaryOpDynFrmAlias_m; + +let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in def FMV_D_X : FPUnaryOp_r<0b1111001, 0b00000, 0b000, FPR64, GPR, "fmv.d.x">, Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>; -} // Predicates = [HasStdExtD, IsRV64] //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -164,6 +225,26 @@ } } // Predicates = [HasStdExtD] +let Predicates = [HasStdExtZdinx, IsRV64] in { +def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>; +def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>; + +def : InstAlias<"fgt.d $rd, $rs, $rt", + (FLT_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>; +def : InstAlias<"fge.d $rd, $rs, $rt", + (FLE_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>; +} // Predicates = [HasStdExtZdinx, IsRV64] + +let Predicates = [HasStdExtZdinx, IsRV32] in { +def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>; +def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>; + +def : InstAlias<"fgt.d $rd, $rs, $rt", + (FLT_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>; +def : InstAlias<"fge.d $rd, $rs, $rt", + (FLE_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>; +} // Predicates = [HasStdExtZdinx, IsRV32] + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// 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 @@ -57,6 +57,73 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +// Zfinx + +def GPRAsFPR : AsmOperandClass { + let Name = "GPRAsFPR"; + let ParserMethod = "parseGPRAsFPR"; + let RenderMethod = "addRegOperands"; +} + +def FPR32INX : RegisterOperand { + let ParserMatchClass = GPRAsFPR; + let DecoderMethod = "DecodeGPRRegisterClass"; +} + +// inx = 0 : f, d, zfh, zfhmin +// = 1 : zfinx, zdinx, zhinx, zhinxmin +// = 2 : zdinx_rv32 +class ExtInfo inx, list pres> { + string Suffix = !cond(!eq(inx, 0): "", + !eq(inx, 1): "_INX", + !eq(inx, 2): "_IN32X"); + list Predicates = pres; + string Space = !cond(!eq(inx, 0): "", + !eq(inx, 1): "RVZfinx", + !eq(inx, 2): "RV32Zdinx"); +} + +class ExtInfo_r { + string Suffix = ext.Suffix; + list Predicates = ext.Predicates; + string Space = ext.Space; + DAGOperand Reg = reg; +} + +class ExtInfo_rr { + string Suffix = ext.Suffix; + list Predicates = ext.Predicates; + string Space = ext.Space; + DAGOperand RdTy = rdty; + DAGOperand Rs1Ty = rs1ty; +} + +def FExt : ExtInfo<0, [HasStdExtF]>; +def F64Ext : ExtInfo<0, [HasStdExtF, IsRV64]>; +def ZfinxExt : ExtInfo<1, [HasStdExtZfinx]>; +def Zfinx64Ext : ExtInfo<1, [HasStdExtZfinx, IsRV64]>; + +def F : ExtInfo_r; +def F_INX : ExtInfo_r; + +def FF : ExtInfo_rr; +def FF_INX : ExtInfo_rr; +def FX : ExtInfo_rr; +def FX_INX : ExtInfo_rr; +def FX_64 : ExtInfo_rr; +def FX_INX_64 : ExtInfo_rr; +def XF : ExtInfo_rr; +def XF_64 : ExtInfo_rr; +def XF_INX : ExtInfo_rr; +def XF_INX_64 : ExtInfo_rr; + +defvar FINX = [F, F_INX]; +defvar FFINX = [FF, FF_INX]; +defvar FXINX = [FX, FX_INX]; +defvar XFINX = [XF, XF_INX]; +defvar XFIN64X = [XF_64, XF_INX_64]; +defvar FXIN64X = [FX_64, FX_INX_64]; + // Floating-point rounding mode def FRMArg : AsmOperandClass { @@ -94,62 +161,123 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, UseNamedOperandTable = 1, hasPostISelHook = 1 in class FPFMA_rrr_frm funct2, string opcodestr, - RegisterClass rty> + DAGOperand 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.Suffix : FPFMA_rrr_frm; +} + class FPFMADynFrmAlias + DAGOperand rty> : InstAlias; +multiclass FPFMADynFrmAlias_m Exts> { + foreach Ext = Exts in + let Predicates = Ext.Predicates in + def : FPFMADynFrmAlias(Inst#Ext.Suffix), OpcodeStr, + Ext.Reg>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in class FPALU_rr funct7, bits<3> funct3, string opcodestr, - RegisterClass rty> + DAGOperand rty> : RVInstR; +multiclass FPALU_rr_m funct7, bits<3> funct3, string opcodestr, + list Exts> { + foreach Ext = Exts in + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPALU_rr; +} 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, DAGOperand 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.Suffix : FPALU_rr_frm; +} + class FPALUDynFrmAlias + DAGOperand rty> : InstAlias; +multiclass FPALUDynFrmAlias_m Exts> { + foreach Ext = Exts in + let Predicates = Ext.Predicates in + def : FPALUDynFrmAlias(Inst#Ext.Suffix), OpcodeStr, + Ext.Reg>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in class FPUnaryOp_r funct7, bits<5> rs2val, bits<3> funct3, - RegisterClass rdty, RegisterClass rs1ty, string opcodestr> + DAGOperand rdty, DAGOperand rs1ty, string opcodestr> : RVInstR { let rs2 = rs2val; } +multiclass FPUnaryOp_r_m funct7, bits<5> rs2val, bits<3> funct3, + list Exts, string opcodestr> { + foreach Ext = Exts in + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPUnaryOp_r; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, UseNamedOperandTable = 1, hasPostISelHook = 1 in -class FPUnaryOp_r_frm funct7, bits<5> rs2val, RegisterClass rdty, - RegisterClass rs1ty, string opcodestr> +class FPUnaryOp_r_frm funct7, bits<5> rs2val, DAGOperand rdty, + DAGOperand rs1ty, string opcodestr> : RVInstRFrm { let rs2 = rs2val; } +multiclass FPUnaryOp_r_frm_m funct7, bits<5> rs2val, + list Exts, string opcodestr> { + foreach Ext = Exts in + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPUnaryOp_r_frm; +} class FPUnaryOpDynFrmAlias + DAGOperand rdty, DAGOperand rs1ty> : InstAlias; +multiclass FPUnaryOpDynFrmAlias_m Exts> { + foreach Ext = Exts in + let Predicates = Ext.Predicates in + def : FPUnaryOpDynFrmAlias(Inst#Ext.Suffix), + OpcodeStr, Ext.RdTy, Ext.Rs1Ty>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in class FPCmp_rr funct7, bits<3> funct3, string opcodestr, - RegisterClass rty> + DAGOperand rty> : RVInstR; +multiclass FPCmp_rr_m funct7, bits<3> funct3, string opcodestr, + list Exts> { + foreach Ext = Exts in + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPCmp_rr; +} //===----------------------------------------------------------------------===// // Instructions @@ -162,101 +290,100 @@ // 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; +} + +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; + +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>; -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; - -def FSQRT_S : FPUnaryOp_r_frm<0b0101100, 0b00000, FPR32, FPR32, "fsqrt.s">, - Sched<[WriteFSqrt32, ReadFSqrt32]>; -def : FPUnaryOpDynFrmAlias; +let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in +defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>; + +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; + +defm FSQRT_S : FPUnaryOp_r_frm_m<0b0101100, 0b00000, FFINX, "fsqrt.s">, + Sched<[WriteFSqrt32, ReadFSqrt32]>; +defm : FPUnaryOpDynFrmAlias_m; let SchedRW = [WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32], mayRaiseFPException = 0 in { -def FSGNJ_S : FPALU_rr<0b0010000, 0b000, "fsgnj.s", FPR32>; -def FSGNJN_S : FPALU_rr<0b0010000, 0b001, "fsgnjn.s", FPR32>; -def FSGNJX_S : FPALU_rr<0b0010000, 0b010, "fsgnjx.s", FPR32>; +defm FSGNJ_S : FPALU_rr_m<0b0010000, 0b000, "fsgnj.s", FINX>; +defm FSGNJN_S : FPALU_rr_m<0b0010000, 0b001, "fsgnjn.s", FINX>; +defm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", FINX>; } let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in { -def FMIN_S : FPALU_rr<0b0010100, 0b000, "fmin.s", FPR32>; -def FMAX_S : FPALU_rr<0b0010100, 0b001, "fmax.s", FPR32>; +defm FMIN_S : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX>; +defm FMAX_S : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX>; } -def FCVT_W_S : FPUnaryOp_r_frm<0b1100000, 0b00000, GPR, FPR32, "fcvt.w.s">, - Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; -def : FPUnaryOpDynFrmAlias; - -def FCVT_WU_S : FPUnaryOp_r_frm<0b1100000, 0b00001, GPR, FPR32, "fcvt.wu.s">, +defm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, XFINX, "fcvt.w.s">, Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; + +defm FCVT_WU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00001, XFINX, "fcvt.wu.s">, + Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; +defm : FPUnaryOpDynFrmAlias_m; let mayRaiseFPException = 0 in def FMV_X_W : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR32, "fmv.x.w">, Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>; let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in { -def FEQ_S : FPCmp_rr<0b1010000, 0b010, "feq.s", FPR32>; -def FLT_S : FPCmp_rr<0b1010000, 0b001, "flt.s", FPR32>; -def FLE_S : FPCmp_rr<0b1010000, 0b000, "fle.s", FPR32>; +defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX>; +defm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", FINX>; +defm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", FINX>; } let mayRaiseFPException = 0 in -def FCLASS_S : FPUnaryOp_r<0b1110000, 0b00000, 0b001, GPR, FPR32, "fclass.s">, - Sched<[WriteFClass32, ReadFClass32]>; - -def FCVT_S_W : FPUnaryOp_r_frm<0b1101000, 0b00000, FPR32, GPR, "fcvt.s.w">, - Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; -def : FPUnaryOpDynFrmAlias; +defm FCLASS_S : FPUnaryOp_r_m<0b1110000, 0b00000, 0b001, XFINX, "fclass.s">, + Sched<[WriteFClass32, ReadFClass32]>; -def FCVT_S_WU : FPUnaryOp_r_frm<0b1101000, 0b00001, FPR32, GPR, "fcvt.s.wu">, +defm FCVT_S_W : FPUnaryOp_r_frm_m<0b1101000, 0b00000, FXINX, "fcvt.s.w">, Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; + +defm FCVT_S_WU : FPUnaryOp_r_frm_m<0b1101000, 0b00001, FXINX, "fcvt.s.wu">, + Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; +defm : FPUnaryOpDynFrmAlias_m; let mayRaiseFPException = 0 in def FMV_W_X : FPUnaryOp_r<0b1111000, 0b00000, 0b000, FPR32, GPR, "fmv.w.x">, Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>; -} // Predicates = [HasStdExtF] -let Predicates = [HasStdExtF, IsRV64] in { -def FCVT_L_S : FPUnaryOp_r_frm<0b1100000, 0b00010, GPR, FPR32, "fcvt.l.s">, - Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; -def : FPUnaryOpDynFrmAlias; - -def FCVT_LU_S : FPUnaryOp_r_frm<0b1100000, 0b00011, GPR, FPR32, "fcvt.lu.s">, +defm FCVT_L_S : FPUnaryOp_r_frm_m<0b1100000, 0b00010, XFIN64X, "fcvt.l.s">, Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_S_L : FPUnaryOp_r_frm<0b1101000, 0b00010, FPR32, GPR, "fcvt.s.l">, - Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_LU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00011, XFIN64X, "fcvt.lu.s">, + Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_S_LU : FPUnaryOp_r_frm<0b1101000, 0b00011, FPR32, GPR, "fcvt.s.lu">, +defm FCVT_S_L : FPUnaryOp_r_frm_m<0b1101000, 0b00010, FXIN64X, "fcvt.s.l">, Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtF, IsRV64] +defm : FPUnaryOpDynFrmAlias_m; + +defm FCVT_S_LU : FPUnaryOp_r_frm_m<0b1101000, 0b00011, FXIN64X, "fcvt.s.lu">, + Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; +defm : FPUnaryOpDynFrmAlias_m; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -315,6 +442,16 @@ } } // Predicates = [HasStdExtF] +let Predicates = [HasStdExtZfinx] in { +def : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>; +def : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>; + +def : InstAlias<"fgt.s $rd, $rs, $rt", + (FLT_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>; +def : InstAlias<"fge.s $rd, $rs, $rt", + (FLE_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>; +} // Predicates = [HasStdExtZfinx] + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// 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,62 @@ def riscv_fmv_x_signexth : SDNode<"RISCVISD::FMV_X_SIGNEXTH", SDT_RISCVFMV_X_EXTH>; +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +// Zhinxmin and Zhinx + +def FPR16INX : RegisterOperand { + let ParserMatchClass = GPRAsFPR; + let DecoderMethod = "DecodeGPRRegisterClass"; +} + +def ZfhExt : ExtInfo<0, [HasStdExtZfh]>; +def Zfh64Ext : ExtInfo<0, [HasStdExtZfh, IsRV64]>; +def ZfhminExt : ExtInfo<0, [HasStdExtZfhOrZfhmin]>; +def ZhinxExt : ExtInfo<1, [HasStdExtZhinx]>; +def ZhinxminExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin]>; +def Zhinx64Ext : ExtInfo<1, [HasStdExtZhinx, IsRV64]>; + +def ZfhminDExt : ExtInfo<0, [HasStdExtZfhOrZfhmin, HasStdExtD]>; +def ZhinxminZdinxExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx]>; + +def H : ExtInfo_r; +def H_INX : ExtInfo_r; + +def HH : ExtInfo_rr; +def HH_INX : ExtInfo_rr; +def XH : ExtInfo_rr; +def XH_INX : ExtInfo_rr; +def HX : ExtInfo_rr; +def HX_INX : ExtInfo_rr; +def XH_64 : ExtInfo_rr; +def HX_64 : ExtInfo_rr; +def XH_INX_64 : ExtInfo_rr; +def HX_INX_64 : ExtInfo_rr; +def HFmin : ExtInfo_rr; +def HF_INXmin : ExtInfo_rr; +def HF_INX : ExtInfo_rr; +def FHmin : ExtInfo_rr; +def FH_INXmin : ExtInfo_rr; +def FH_INX : ExtInfo_rr; +def DHmin : ExtInfo_rr; +def DH_INXmin : ExtInfo_rr; +def HDmin : ExtInfo_rr; +def HD_INXmin : ExtInfo_rr; + +defvar HINX = [H, H_INX]; +defvar HHINX = [HH, HH_INX]; +defvar XHINX = [XH, XH_INX]; +defvar HXINX = [HX, HX_INX]; +defvar XHIN64X = [XH_64, XH_INX_64]; +defvar HXIN64X = [HX_64, HX_INX_64]; +defvar HFINXmin = [HFmin, HF_INXmin]; +defvar FHINXmin = [FHmin, FH_INXmin]; +defvar DHINXmin = [DHmin, DH_INXmin]; +defvar HDINXmin = [HDmin, HD_INXmin]; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -40,74 +96,73 @@ def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>; } // Predicates = [HasStdExtZfhOrZfhmin] -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; } -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; - -def FSQRT_H : FPUnaryOp_r_frm<0b0101110, 0b00000, FPR16, FPR16, "fsqrt.h">, - Sched<[WriteFSqrt16, ReadFSqrt16]>; -def : FPUnaryOpDynFrmAlias; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; +defm : FPFMADynFrmAlias_m; + +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>; + +let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in +defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>; + +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; +defm : FPALUDynFrmAlias_m; + +defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, HHINX, "fsqrt.h">, + Sched<[WriteFSqrt16, ReadFSqrt16]>; +defm : FPUnaryOpDynFrmAlias_m; let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16], mayRaiseFPException = 0 in { -def FSGNJ_H : FPALU_rr<0b0010010, 0b000, "fsgnj.h", FPR16>; -def FSGNJN_H : FPALU_rr<0b0010010, 0b001, "fsgnjn.h", FPR16>; -def FSGNJX_H : FPALU_rr<0b0010010, 0b010, "fsgnjx.h", FPR16>; +defm FSGNJ_H : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h", HINX>; +defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", HINX>; +defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", HINX>; } let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in { -def FMIN_H : FPALU_rr<0b0010110, 0b000, "fmin.h", FPR16>; -def FMAX_H : FPALU_rr<0b0010110, 0b001, "fmax.h", FPR16>; +defm FMIN_H : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX>; +defm FMAX_H : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX>; } -def FCVT_W_H : FPUnaryOp_r_frm<0b1100010, 0b00000, GPR, FPR16, "fcvt.w.h">, - Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>; -def : FPUnaryOpDynFrmAlias; - -def FCVT_WU_H : FPUnaryOp_r_frm<0b1100010, 0b00001, GPR, FPR16, "fcvt.wu.h">, +defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, XHINX, "fcvt.w.h">, Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_H_W : FPUnaryOp_r_frm<0b1101010, 0b00000, FPR16, GPR, "fcvt.h.w">, - Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, XHINX, "fcvt.wu.h">, + Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, 0b00001, FPR16, GPR, "fcvt.h.wu">, +defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, HXINX, "fcvt.h.w">, Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>; -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtZfh] +defm : FPUnaryOpDynFrmAlias_m; -let Predicates = [HasStdExtZfhOrZfhmin] in { -def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, 0b00000, FPR16, FPR32, "fcvt.h.s">, - Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, HXINX, "fcvt.h.wu">, + Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_S_H : FPUnaryOp_r<0b0100000, 0b00010, 0b000, FPR32, FPR16, "fcvt.s.h">, +defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, HFINXmin, "fcvt.h.s">, + Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>; +defm : FPUnaryOpDynFrmAlias_m; + +defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, FHINXmin, "fcvt.s.h">, Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>; +let Predicates = [HasStdExtZfhOrZfhmin] in { let mayRaiseFPException = 0 in def FMV_X_H : FPUnaryOp_r<0b1110010, 0b00000, 0b000, GPR, FPR16, "fmv.x.h">, Sched<[WriteFMovF16ToI16, ReadFMovF16ToI16]>; @@ -117,45 +172,38 @@ Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>; } // Predicates = [HasStdExtZfhOrZfhmin] -let Predicates = [HasStdExtZfh] in { - let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in { -def FEQ_H : FPCmp_rr<0b1010010, 0b010, "feq.h", FPR16>; -def FLT_H : FPCmp_rr<0b1010010, 0b001, "flt.h", FPR16>; -def FLE_H : FPCmp_rr<0b1010010, 0b000, "fle.h", FPR16>; +defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX>; +defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", HINX>; +defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", HINX>; } let mayRaiseFPException = 0 in -def FCLASS_H : FPUnaryOp_r<0b1110010, 0b00000, 0b001, GPR, FPR16, "fclass.h">, - Sched<[WriteFClass16, ReadFClass16]>; -} // Predicates = [HasStdExtZfh] - -let Predicates = [HasStdExtZfh, IsRV64] in { -def FCVT_L_H : FPUnaryOp_r_frm<0b1100010, 0b00010, GPR, FPR16, "fcvt.l.h">, - Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>; -def : FPUnaryOpDynFrmAlias; +defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, XHINX, "fclass.h">, + Sched<[WriteFClass16, ReadFClass16]>; -def FCVT_LU_H : FPUnaryOp_r_frm<0b1100010, 0b00011, GPR, FPR16, "fcvt.lu.h">, +defm FCVT_L_H : FPUnaryOp_r_frm_m<0b1100010, 0b00010, XHIN64X, "fcvt.l.h">, Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>; -def : FPUnaryOpDynFrmAlias; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_H_L : FPUnaryOp_r_frm<0b1101010, 0b00010, FPR16, GPR, "fcvt.h.l">, - Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_LU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00011, XHIN64X, "fcvt.lu.h">, + Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, 0b00011, FPR16, GPR, "fcvt.h.lu">, +defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, HXIN64X, "fcvt.h.l">, Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>; -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtZfh, IsRV64] +defm : FPUnaryOpDynFrmAlias_m; -let Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] in { -def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, 0b00001, FPR16, FPR64, "fcvt.h.d">, - Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>; -def : FPUnaryOpDynFrmAlias; +defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, HXIN64X, "fcvt.h.lu">, + Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>; +defm : FPUnaryOpDynFrmAlias_m; -def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b00010, 0b000, FPR64, FPR16, "fcvt.d.h">, - Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>; -} // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] +defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, HDINXmin, "fcvt.h.d">, + Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>; +defm : FPUnaryOpDynFrmAlias_m; + +defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, DHINXmin, "fcvt.d.h">, + Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -188,6 +236,17 @@ } } // Predicates = [HasStdExtZfhOrZfhmin] +let Predicates = [HasStdExtZhinx] in { +def : InstAlias<"fmv.h $rd, $rs", (FSGNJ_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>; +def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>; +def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>; + +def : InstAlias<"fgt.h $rd, $rs, $rt", + (FLT_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>; +def : InstAlias<"fge.h $rd, $rs, $rt", + (FLE_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>; +} // Predicates = [HasStdExtZhinx] + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// 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 @@ -534,6 +535,35 @@ let Size = 64; } +let RegInfos = XLenRI in { +def GPRF16 : RegisterClass<"RISCV", [f16], 16, (add GPR)>; +def GPRF32 : RegisterClass<"RISCV", [f32], 32, (add GPR)>; +def GPRF64 : RegisterClass<"RISCV", [f64], 64, (add GPR)>; +} // RegInfos = XLenRI + +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]; + } + } +} + +let RegInfos = RegInfoByHwMode<[RV64], [RegInfo<64, 64, 64>]> in +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 +)>; + // 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 @@ -172,6 +172,10 @@ mul a4, ra, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'M' (Integer Multiplication and Division) 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) flh ft0, (a0) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) or 'Zfhmin' (Half-Precision Floating-Point Minimal){{$}} sh1add a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zba' (Address Generation Instructions) clz a0, a1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbb' (Basic Bit-Manipulation) 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,27 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 | FileCheck %s + +# Unsupport Odd Registers in RV32 +fadd.d a0, a1, a2 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction + +# Not support float registers +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fadd.d fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point) + +# Invalid instructions +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 +fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +fsgnjn.d a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction + +# Rounding mode when a register is expected +fmadd.d x10, x12, x14, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction + +# Invalid rounding modes +fmadd.d x10, x12, x14, x16, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fmsub.d x10, x12, x14, x16, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fnmsub.d x10, x12, x14, x16, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic + +# FP registers where integer regs are expected +fcvt.wu.d ft2, a1 # CHECK: :[[@LINE]]:11: 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,124 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+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=+zdinx %s \ +# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+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=+zdinx %s \ +# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# 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 +# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, dyn +# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0x5a] +fsqrt.d x20, x22, dyn +# CHECK-ASM-AND-OBJ: fsgnj.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x23] +fsgnj.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fsgnjn.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x23] +fsgnjn.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fsgnjx.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x2d,0xee,0x23] +fsgnjx.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fmin.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x2b] +fmin.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fmax.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x2b] +fmax.d x26, x28, x30 + +# CHECK-ASM-AND-OBJ: fcvt.s.d s10, t3, dyn +# CHECK-ASM: encoding: [0x53,0x7d,0x1e,0x40] +fcvt.s.d x26, x28, dyn +# CHECK-ASM-AND-OBJ: fcvt.d.s s10, t3 +# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0x42] +fcvt.d.s x26, x28 +# CHECK-ASM-AND-OBJ: feq.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x2d,0xee,0xa3] +feq.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: flt.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x1d,0xee,0xa3] +flt.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fle.d s10, t3, t5 +# CHECK-ASM: encoding: [0x53,0x0d,0xee,0xa3] +fle.d x26, x28, x30 +# CHECK-ASM-AND-OBJ: fclass.d s10, t3 +# CHECK-ASM: encoding: [0x53,0x1d,0x0e,0xe2] +fclass.d x26, x28 + +# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, dyn +# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0xc2] +fcvt.w.d x20, x22, dyn +# CHECK-ASM-AND-OBJ: fcvt.d.w s10, t3 +# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0xd2] +fcvt.d.w x26, x28 +# CHECK-ASM-AND-OBJ: fcvt.d.wu s10, t3 +# CHECK-ASM: encoding: [0x53,0x0d,0x1e,0xd2] +fcvt.d.wu x26, x28 + +# Rounding modes + +# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, rne +# CHECK-ASM: encoding: [0x43,0x05,0xe6,0x82] +fmadd.d x10, x12, x14, x16, rne +# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, rtz +# CHECK-ASM: encoding: [0x47,0x15,0xe6,0x82] +fmsub.d x10, x12, x14, x16, rtz +# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, rdn +# CHECK-ASM: encoding: [0x4b,0x25,0xe6,0x82] +fnmsub.d x10, x12, x14, x16, rdn +# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, rup +# CHECK-ASM: encoding: [0x4f,0x35,0xe6,0x82] +fnmadd.d x10, x12, x14, x16, rup + +# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, rmm +# CHECK-ASM: encoding: [0x53,0x4d,0xee,0x03] +fadd.d x26, x28, x30, rmm +# 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, rne +# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x13] +fmul.d x26, x28, x30, rne +# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, rtz +# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x1b] +fdiv.d x26, x28, x30, rtz + +# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, rdn +# CHECK-ASM: encoding: [0x53,0x2a,0x0b,0x5a] +fsqrt.d x20, x22, rdn +# CHECK-ASM-AND-OBJ: fcvt.s.d s4, s6, rup +# CHECK-ASM: encoding: [0x53,0x3a,0x1b,0x40] +fcvt.s.d x20, x22, rup +# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, rmm +# CHECK-ASM: encoding: [0x53,0x4a,0x0b,0xc2] +fcvt.w.d x20, x22, rmm +# CHECK-ASM-AND-OBJ: fcvt.wu.d s4, s6, dyn +# CHECK-ASM: encoding: [0x53,0x7a,0x1b,0xc2] +fcvt.wu.d x20, x22, 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,25 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 | FileCheck %s + +# Not support float registers +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fadd.s fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) + +# Invalid instructions +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 +fadd.d t1, t3, t5 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer) + +# Invalid register names +fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +fsgnjn.s a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction + +# Rounding mode when a register is expected +fmadd.s x10, x11, x12, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction + +# Invalid rounding modes +fmadd.s x10, x11, x12, x13, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fmsub.s x14, x15, x16, x17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fnmsub.s x18, x19, x20, x21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic + +# Using 'Zdinx' instructions for an 'Zfinx'-only target +fadd.d t0, t1, t2 # 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,128 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+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=+zfinx %s \ +# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \ +# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# 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 +# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, dyn +# CHECK-ASM: encoding: [0x53,0xf3,0x03,0x58] +fsqrt.s t1, t2, dyn +# CHECK-ASM-AND-OBJ: fsgnj.s s1, a0, a1 +# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x20] +fsgnj.s s1, a0, a1 +# CHECK-ASM-AND-OBJ: fsgnjn.s a1, a3, a4 +# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x20] +fsgnjn.s a1, a3, a4 +# CHECK-ASM-AND-OBJ: fsgnjx.s a4, a3, a2 +# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x20] +fsgnjx.s a4, a3, a2 +# CHECK-ASM-AND-OBJ: fmin.s a5, a6, a7 +# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x29] +fmin.s a5, a6, a7 +# CHECK-ASM-AND-OBJ: fmax.s s2, s3, s4 +# CHECK-ASM: encoding: [0x53,0x99,0x49,0x29] +fmax.s s2, s3, s4 +# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc0] +fcvt.w.s a0, s5, dyn +# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, dyn +# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc0] +fcvt.wu.s a1, s6, dyn +# CHECK-ASM-AND-OBJ: feq.s a1, s8, s9 +# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa1] +feq.s a1, s8, s9 +# CHECK-ASM-AND-OBJ: flt.s a2, s10, s11 +# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa1] +flt.s a2, s10, s11 +# CHECK-ASM-AND-OBJ: fle.s a3, t3, t4 +# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa1] +fle.s a3, t3, t4 +# CHECK-ASM-AND-OBJ: fclass.s a3, t5 +# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe0] +fclass.s a3, t5 +# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, dyn +# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd0] +fcvt.s.w t6, a4, dyn +# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, dyn +# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd0] +fcvt.s.wu s0, a5, dyn + +# Rounding modes + +# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rne +# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x68] +fmadd.s x10, x11, x12, x13, rne +# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, rtz +# CHECK-ASM: encoding: [0x47,0x97,0x07,0x89] +fmsub.s x14, x15, x16, x17, rtz +# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, rdn +# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xa9] +fnmsub.s x18, x19, x20, x21, rdn +# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, rup +# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xc9] +fnmadd.s x22, x23, x24, x25, rup +# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rmm +# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x68] +fmadd.s x10, x11, x12, x13, rmm +# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7 +# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89] +fmsub.s x14, x15, x16, x17, dyn + +# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, rne +# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x01] +fadd.s x26, x27, x28, rne +# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, rtz +# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x09] +fsub.s x29, x30, x31, rtz +# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, rdn +# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x11] +fmul.s s0, s1, s2, rdn +# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, rup +# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x19] +fdiv.s s3, s4, s5, rup + +# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, rmm +# CHECK-ASM: encoding: [0x53,0xc3,0x03,0x58] +fsqrt.s t1, t2, rmm +# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, rup +# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc0] +fcvt.w.s a0, s5, rup +# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, rdn +# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc0] +fcvt.wu.s a1, s6, rdn +# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, rtz +# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd0] +fcvt.s.w t6, a4, rtz +# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, rne +# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd0] +fcvt.s.wu s0, a5, rne 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,24 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 | FileCheck %s + +# Not support float registers +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fadd.h fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) + +# Invalid instructions +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 +fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +fsgnjn.h a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction + +# Rounding mode when a register is expected +fmadd.h x10, x11, x12, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction + +# Invalid rounding modes +fmadd.h x10, x11, x12, x13, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fmsub.h x14, x15, x16, x17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic +fnmsub.h x18, x19, x20, x21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic + +# FP registers where integer regs are expected +fcvt.wu.h ft2, a1 # CHECK: :[[@LINE]]:11: 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,128 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+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=+zhinx %s \ +# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \ +# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# 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 +# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, dyn +# CHECK-ASM: encoding: [0x53,0xfb,0x0b,0x5c] +fsqrt.h s6, s7, dyn +# CHECK-ASM-AND-OBJ: fsgnj.h s1, a0, a1 +# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x24] +fsgnj.h x9, x10, x11 +# CHECK-ASM-AND-OBJ: fsgnjn.h a1, a3, a4 +# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x24] +fsgnjn.h x11, x13, x14 +# CHECK-ASM-AND-OBJ: fsgnjx.h a4, a3, a2 +# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x24] +fsgnjx.h x14, x13, x12 +# CHECK-ASM-AND-OBJ: fmin.h a5, a6, a7 +# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x2d] +fmin.h x15, x16, x17 +# CHECK-ASM-AND-OBJ: fmax.h s2, s3, s4 +# CHECK-ASM: encoding: [0x53,0x99,0x49,0x2d] +fmax.h x18, x19, x20 +# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc4] +fcvt.w.h x10, x21, dyn +# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, dyn +# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc4] +fcvt.wu.h x11, x22, dyn +# CHECK-ASM-AND-OBJ: feq.h a1, s8, s9 +# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa5] +feq.h x11, x24, x25 +# CHECK-ASM-AND-OBJ: flt.h a2, s10, s11 +# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa5] +flt.h x12, x26, x27 +# CHECK-ASM-AND-OBJ: fle.h a3, t3, t4 +# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa5] +fle.h x13, x28, x29 +# CHECK-ASM-AND-OBJ: fclass.h a3, t5 +# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe4] +fclass.h x13, x30 +# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, dyn +# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd4] +fcvt.h.w x31, x14, dyn +# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, dyn +# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd4] +fcvt.h.wu s0, x15, dyn + +# Rounding modes + +# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rne +# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x6c] +fmadd.h x10, x11, x12, x13, rne +# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, rtz +# CHECK-ASM: encoding: [0x47,0x97,0x07,0x8d] +fmsub.h x14, x15, x16, x17, rtz +# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, rdn +# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xad] +fnmsub.h x18, x19, x20, x21, rdn +# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, rup +# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xcd] +fnmadd.h x22, x23, x24, x25, rup +# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rmm +# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x6c] +fmadd.h x10, x11, x12, x13, rmm +# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7 +# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d] +fmsub.h x14, x15, x16, x17, dyn + +# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, rne +# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x05] +fadd.h x26, x27, x28, rne +# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, rtz +# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x0d] +fsub.h x29, x30, x31, rtz +# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, rdn +# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x15] +fmul.h s0, s1, s2, rdn +# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, rup +# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x1d] +fdiv.h s3, s4, s5, rup + +# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, rmm +# CHECK-ASM: encoding: [0x53,0xcb,0x0b,0x5c] +fsqrt.h s6, s7, rmm +# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, rup +# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc4] +fcvt.w.h x10, x21, rup +# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, rdn +# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc4] +fcvt.wu.h x11, x22, rdn +# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, rtz +# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd4] +fcvt.h.w x31, x14, rtz +# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, rne +# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd4] +fcvt.h.wu s0, a5, rne 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,15 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zhinxmin %s 2>&1 | FileCheck %s + +# Not support float registers +flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point) +fcvt.h.s fa0, fa1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) or 'Zfhmin' (Half-Precision Floating-Point Minimal) + +# Invalid instructions +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 +fcvt.h.s a100, a1 # CHECK: :[[@LINE]]:10: 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/rv32zhinxmin-valid.s b/llvm/test/MC/RISCV/rv32zhinxmin-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zhinxmin-valid.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zhinxmin %s \ +# RUN: | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinxmin %s \ +# RUN: | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: fcvt.s.h a0, a1 +# CHECK-ASM: encoding: [0x53,0x85,0x25,0x40] +fcvt.s.h a0, a1 + +# CHECK-ASM-AND-OBJ: fcvt.h.s a0, a1, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x05,0x44] +fcvt.h.s a0, a1 diff --git a/llvm/test/MC/RISCV/rv64zdinx-invalid.s b/llvm/test/MC/RISCV/rv64zdinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zdinx-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+zdinx %s 2>&1 | FileCheck %s + +# Invalid Instructions +fmv.x.d t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +fmv.d.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction + +# FP registers where integer regs are expected +fcvt.d.l a3, ft3 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +fcvt.d.lu a4, ft4 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64zdinx-valid.s b/llvm/test/MC/RISCV/rv64zdinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zdinx-valid.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+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=+zdinx %s \ +# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 \ +# RUN: | FileCheck -check-prefix=CHECK-RV32 %s + +# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc2] +# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction +fcvt.l.d a0, t0, dyn +# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, dyn +# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc2] +# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction +fcvt.lu.d a1, t1, dyn +# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, dyn +# CHECK-ASM: encoding: [0x53,0xfe,0x26,0xd2] +# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction +fcvt.d.l t3, a3, dyn +# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, dyn +# CHECK-ASM: encoding: [0xd3,0x7e,0x37,0xd2] +# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction +fcvt.d.lu t4, a4, dyn + +# Rounding modes +# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, rne +# CHECK-ASM: encoding: [0x53,0x8e,0x26,0xd2] +# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction +fcvt.d.l t3, a3, rne +# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, rtz +# CHECK-ASM: encoding: [0xd3,0x1e,0x37,0xd2] +# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction +fcvt.d.lu t4, a4, rtz +# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, rdn +# CHECK-ASM: encoding: [0x53,0xa5,0x22,0xc2] +# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction +fcvt.l.d a0, t0, rdn +# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, rup +# CHECK-ASM: encoding: [0xd3,0x35,0x33,0xc2] +# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction +fcvt.lu.d a1, t1, rup diff --git a/llvm/test/MC/RISCV/rv64zfinx-invalid.s b/llvm/test/MC/RISCV/rv64zfinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zfinx-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+zfinx %s 2>&1 | FileCheck %s + +# Invalid instructions +fmv.x.w t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +fmv.w.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction + +# FP registers where integer regs are expected +fcvt.s.l a2, ft2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +fcvt.s.lu a3, ft3 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64zfinx-valid.s b/llvm/test/MC/RISCV/rv64zfinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zfinx-valid.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \ +# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 \ +# RUN: | FileCheck -check-prefix=CHECK-RV32 %s + +# CHECK-ASM-AND-OBJ: fcvt.l.s a0, t0, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.l.s a0, t0, dyn +# CHECK-ASM-AND-OBJ: fcvt.lu.s a1, t1, dyn +# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.lu.s a1, t1, dyn +# CHECK-ASM-AND-OBJ: fcvt.s.l t2, a2, dyn +# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.s.l t2, a2, dyn +# CHECK-ASM-AND-OBJ: fcvt.s.lu t3, a3, dyn +# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.s.lu t3, a3, dyn + +# Rounding modes +# CHECK-ASM-AND-OBJ: fcvt.l.s a4, t4, rne +# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.l.s a4, t4, rne +# CHECK-ASM-AND-OBJ: fcvt.lu.s a5, t5, rtz +# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.lu.s a5, t5, rtz +# CHECK-ASM-AND-OBJ: fcvt.s.l t6, a6, rdn +# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.s.l t6, a6, rdn +# CHECK-ASM-AND-OBJ: fcvt.s.lu s7, a7, rup +# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd0] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.s.lu s7, a7, rup diff --git a/llvm/test/MC/RISCV/rv64zhinx-invalid.s b/llvm/test/MC/RISCV/rv64zhinx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zhinx-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s + +# Invalid instructions +fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction + +# FP registers where integer regs are expected +fcvt.h.l a2, ft2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +fcvt.h.lu a3, ft3 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64zhinx-valid.s b/llvm/test/MC/RISCV/rv64zhinx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zhinx-valid.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \ +# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 \ +# RUN: | FileCheck -check-prefix=CHECK-RV32 %s + +# CHECK-ASM-AND-OBJ: fcvt.l.h a0, t0, dyn +# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.l.h a0, t0, dyn +# CHECK-ASM-AND-OBJ: fcvt.lu.h a1, t1, dyn +# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.lu.h a1, t1, dyn +# CHECK-ASM-AND-OBJ: fcvt.h.l t2, a2, dyn +# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.h.l t2, a2, dyn +# CHECK-ASM-AND-OBJ: fcvt.h.lu t3, a3, dyn +# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.h.lu t3, a3, dyn + +# Rounding modes +# CHECK-ASM-AND-OBJ: fcvt.l.h a4, t4, rne +# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.l.h a4, t4, rne +# CHECK-ASM-AND-OBJ: fcvt.lu.h a5, t5, rtz +# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.lu.h a5, t5, rtz +# CHECK-ASM-AND-OBJ: fcvt.h.l t6, a6, rdn +# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.h.l t6, a6, rdn +# CHECK-ASM-AND-OBJ: fcvt.h.lu s7, a7, rup +# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd4] +# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set +fcvt.h.lu s7, a7, rup diff --git a/llvm/test/MC/RISCV/rv64zhinxmin-invalid.s b/llvm/test/MC/RISCV/rv64zhinxmin-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zhinxmin-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s + +# Invalid instructions +fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction + +# FP registers where integer regs are expected +fcvt.d.h a0, fa2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +fcvt.h.d a0, fa2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64zhinxmin-valid.s b/llvm/test/MC/RISCV/rv64zhinxmin-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zhinxmin-valid.s @@ -0,0 +1,13 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx,+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=+zhinx,+zdinx %s \ +# RUN: | llvm-objdump --mattr=+zhinx,+zdinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: fcvt.d.h a0, a2 +# CHECK-ASM: encoding: [0x53,0x05,0x26,0x42] +fcvt.d.h a0, a2 + +# CHECK-ASM-AND-OBJ: fcvt.h.d a0, a2, dyn +# CHECK-ASM: encoding: [0x53,0x75,0x16,0x44] +fcvt.h.d a0, a2, dyn 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=+zdinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+zdinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+zdinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+zdinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \ +# RUN: | llvm-objdump -d --mattr=+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,82 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+zfinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+zfinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+zfinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \ +# RUN: | llvm-objdump -d --mattr=+zfinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +##===----------------------------------------------------------------------===## +## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) +##===----------------------------------------------------------------------===## + +# CHECK-INST: fsgnjx.s s1, s2, s2 +# CHECK-ALIAS: fabs.s s1, s2 +fabs.s s1, s2 +# CHECK-INST: fsgnjn.s s2, s3, s3 +# CHECK-ALIAS: fneg.s s2, s3 +fneg.s s2, s3 + +# CHECK-INST: flt.s tp, s6, s5 +# CHECK-ALIAS: flt.s tp, s6, s5 +fgt.s x4, s5, s6 +# CHECK-INST: fle.s t2, s1, s0 +# CHECK-ALIAS: fle.s t2, s1, s0 +fge.s x7, x8, x9 + +##===----------------------------------------------------------------------===## +## 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 +# CHECK-INST: sqrt.s s6, s7, dyn +# CHECK-ALIAS: sqrt.s s6, s7 +fsqrt.s s6, s7 +# CHECK-INST: fcvt.w.s a0, s5, dyn +# CHECK-ALIAS: fcvt.w.s a0, s5 +fcvt.w.s a0, s5 +# CHECK-INST: fcvt.wu.s a1, s6, dyn +# CHECK-ALIAS: fcvt.wu.s a1, s6 +fcvt.wu.s a1, s6 +# CHECK-INST: fcvt.s.w t6, a4, dyn +# CHECK-ALIAS: fcvt.s.w t6, a4 +fcvt.s.w t6, a4 +# CHECK-INST: fcvt.s.wu s0, a5, dyn +# CHECK-ALIAS: fcvt.s.wu s0, a5 +fcvt.s.wu s0, a5 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,82 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+zhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+zhinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+zhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \ +# RUN: | llvm-objdump -d --mattr=+zhinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +##===----------------------------------------------------------------------===## +## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) +##===----------------------------------------------------------------------===## + +# CHECK-INST: fsgnjx.h s1, s2, s2 +# CHECK-ALIAS: fabs.h s1, s2 +fabs.h s1, s2 +# CHECK-INST: fsgnjn.h s2, s3, s3 +# CHECK-ALIAS: fneg.h s2, s3 +fneg.h s2, s3 + +# CHECK-INST: flt.h tp, s6, s5 +# CHECK-ALIAS: flt.h tp, s6, s5 +fgt.h x4, s5, s6 +# CHECK-INST: fle.h t2, s1, s0 +# CHECK-ALIAS: fle.h t2, s1, s0 +fge.h x7, x8, x9 + +##===----------------------------------------------------------------------===## +## 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 +# CHECK-INST: fsqrt.h s6, s7, dyn +# CHECK-ALIAS: fsqrt.h s6, s7 +fsqrt.h s6, s7 +# CHECK-INST: fcvt.w.h a0, s5, dyn +# CHECK-ALIAS: fcvt.w.h a0, s5 +fcvt.w.h a0, s5 +# CHECK-INST: fcvt.wu.h a1, s6, dyn +# CHECK-ALIAS: fcvt.wu.h a1, s6 +fcvt.wu.h a1, s6 +# CHECK-INST: fcvt.h.w t6, a4, dyn +# CHECK-ALIAS: fcvt.h.w t6, a4 +fcvt.h.w t6, a4 +# CHECK-INST: fcvt.h.wu s0, a5, dyn +# CHECK-ALIAS: fcvt.h.wu s0, a5 +fcvt.h.wu s0, a5