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 @@ -66,6 +66,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) { 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 @@ -169,6 +169,7 @@ OperandMatchResultTy parseJALOffset(OperandVector &Operands); OperandMatchResultTy parseVTypeI(OperandVector &Operands); OperandMatchResultTy parseMaskReg(OperandVector &Operands); + OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); @@ -272,6 +273,8 @@ bool IsRV64; + bool IsGPRAsFPR; + struct RegOp { MCRegister RegNum; }; @@ -343,6 +346,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)) { @@ -801,12 +812,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; } @@ -858,6 +871,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()); @@ -1670,6 +1698,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 @@ -26,182 +26,432 @@ def RISCVSplitF64 : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>; //===----------------------------------------------------------------------===// -// Instruction Class Templates +// Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAD_rrr_frm - : RVInstR4Frm<0b01, opcode, (outs FPR64:$rd), - (ins FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; - -class FPFMADDynFrmAlias - : InstAlias; +def GPRPF64AsFPR : AsmOperandClass { + let Name = "GPRPF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUD_rr funct7, bits<3> funct3, string opcodestr> - : RVInstR; +def GPRF64AsFPR : AsmOperandClass { + let Name = "GPRF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUD_rr_frm funct7, string opcodestr> - : RVInstRFrm; +def GPRF64Op : RegisterOperand { + let ParserMatchClass = GPRF64AsFPR; +} -class FPALUDDynFrmAlias - : InstAlias; +def GPRPF64Op : RegisterOperand { + let ParserMatchClass = GPRPF64AsFPR; +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPCmpD_rr funct3, string opcodestr> - : RVInstR<0b1010001, funct3, OPC_OP_FP, (outs GPR:$rd), - (ins FPR64:$rs1, FPR64:$rs2), opcodestr, "$rd, $rs1, $rs2">, - Sched<[WriteFCmp64, ReadFCmp64, ReadFCmp64]>; +def FPR64Op : RegisterOperand; //===----------------------------------------------------------------------===// -// Instructions +// Instruction Class Templates //===----------------------------------------------------------------------===// -let Predicates = [HasStdExtD] in { +multiclass FPUnaryOp_r_frm_FD funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_frm_single; -let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in -def FLD : RVInstI<0b011, OPC_LOAD_FP, (outs FPR64:$rd), - (ins GPR:$rs1, simm12:$imm12), - "fld", "$rd, ${imm12}(${rs1})">, - Sched<[WriteFLD64, ReadFMemBase]>; + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_frm_single; -// Operands for stores are in the order srcreg, base, offset rather than -// reflecting the order these fields are specified in the instruction -// encoding. -let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in -def FSD : RVInstS<0b011, OPC_STORE_FP, (outs), - (ins FPR64:$rs2, GPR:$rs1, simm12:$imm12), - "fsd", "$rs2, ${imm12}(${rs1})">, - Sched<[WriteFST64, ReadStoreData, ReadFMemBase]>; + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_frm_single; + } +} -def FMADD_D : FPFMAD_rrr_frm, - Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; -def : FPFMADDynFrmAlias; -def FMSUB_D : FPFMAD_rrr_frm, - Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; -def : FPFMADDynFrmAlias; -def FNMSUB_D : FPFMAD_rrr_frm, - Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; -def : FPFMADDynFrmAlias; -def FNMADD_D : FPFMAD_rrr_frm, - Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; -def : FPFMADDynFrmAlias; - -def FADD_D : FPALUD_rr_frm<0b0000001, "fadd.d">, - Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; -def : FPALUDDynFrmAlias; -def FSUB_D : FPALUD_rr_frm<0b0000101, "fsub.d">, - Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; -def : FPALUDDynFrmAlias; -def FMUL_D : FPALUD_rr_frm<0b0001001, "fmul.d">, - Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>; -def : FPALUDDynFrmAlias; -def FDIV_D : FPALUD_rr_frm<0b0001101, "fdiv.d">, - Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>; -def : FPALUDDynFrmAlias; - -def FSQRT_D : FPUnaryOp_r_frm<0b0101101, FPR64, FPR64, "fsqrt.d">, - Sched<[WriteFSqrt64, ReadFSqrt64]> { - let rs2 = 0b00000; +multiclass FPUnaryOpDynFrmAlias_FD { + let Predicates = [HasStdExtD] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV32] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; +} + + +multiclass FPUnaryOp_r_frm_DD funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_frm_single; + } } -def : FPUnaryOpDynFrmAlias; - -def FSGNJ_D : FPALUD_rr<0b0010001, 0b000, "fsgnj.d">, - Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; -def FSGNJN_D : FPALUD_rr<0b0010001, 0b001, "fsgnjn.d">, - Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; -def FSGNJX_D : FPALUD_rr<0b0010001, 0b010, "fsgnjx.d">, - Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; -def FMIN_D : FPALUD_rr<0b0010101, 0b000, "fmin.d">, - Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; -def FMAX_D : FPALUD_rr<0b0010101, 0b001, "fmax.d">, - Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; - -def FCVT_S_D : FPUnaryOp_r_frm<0b0100000, FPR32, FPR64, "fcvt.s.d">, - Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]> { - let rs2 = 0b00001; + +multiclass FPUnaryOpDynFrmAlias_DD { + let Predicates = [HasStdExtD] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV32] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; } -def : FPUnaryOpDynFrmAlias; -def FCVT_D_S : FPUnaryOp_r<0b0100001, 0b000, FPR64, FPR32, "fcvt.d.s">, - Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]> { - let rs2 = 0b00000; + +multiclass FPUnaryOp_r_frm_DX funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD, IsRV64] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_frm_single; + } } -def FEQ_D : FPCmpD_rr<0b010, "feq.d">; -def FLT_D : FPCmpD_rr<0b001, "flt.d">; -def FLE_D : FPCmpD_rr<0b000, "fle.d">; +multiclass FPUnaryOpDynFrmAlias_DX { + let Predicates = [HasStdExtD, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; -def FCLASS_D : FPUnaryOp_r<0b1110001, 0b001, GPR, FPR64, "fclass.d">, - Sched<[WriteFClass64, ReadFClass64]> { - let rs2 = 0b00000; + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; } -def FCVT_W_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.w.d">, - Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { - let rs2 = 0b00000; + +multiclass FPUnaryOp_r_frm_XPD funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_frm_single; + } } -def : FPUnaryOpDynFrmAlias; -def FCVT_WU_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.wu.d">, - Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { - let rs2 = 0b00001; +multiclass FPUnaryOpDynFrmAlias_XPD { + let Predicates = [HasStdExtD] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV32] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; } -def : FPUnaryOpDynFrmAlias; -def FCVT_D_W : FPUnaryOp_r<0b1101001, 0b000, FPR64, GPR, "fcvt.d.w">, - Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { - let rs2 = 0b00000; + +multiclass FPUnaryOp_r_frm_XD funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD, IsRV64] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_frm_single; + } } -def FCVT_D_WU : FPUnaryOp_r<0b1101001, 0b000, FPR64, GPR, "fcvt.d.wu">, - Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { - let rs2 = 0b00001; +multiclass FPUnaryOpDynFrmAlias_XD { + let Predicates = [HasStdExtD, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPUnaryOpDynFrmAlias_single; } -} // Predicates = [HasStdExtD] -let Predicates = [HasStdExtD, IsRV64] in { -def FCVT_L_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.l.d">, - Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]> { - let rs2 = 0b00010; + +multiclass FPFMAD_rrr_frm { + defvar funct2 = 0b01; + + let Predicates = [HasStdExtD] in + def "" : FPFMA_rrr_frm_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPFMA_rrr_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPFMA_rrr_frm_single; } -def : FPUnaryOpDynFrmAlias; -def FCVT_LU_D : FPUnaryOp_r_frm<0b1100001, GPR, FPR64, "fcvt.lu.d">, - Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]> { - let rs2 = 0b00011; +class FPFMADDynFrmAlias_single + : InstAlias; + +multiclass FPFMADDynFrmAlias { + let Predicates = [HasStdExtD] in + def : FPFMADDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV32] in + def : FPFMADDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPFMADDynFrmAlias_single; } -def : FPUnaryOpDynFrmAlias; -def FMV_X_D : FPUnaryOp_r<0b1110001, 0b000, GPR, FPR64, "fmv.x.d">, - Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]> { - let rs2 = 0b00000; + +multiclass FPALUD_rr funct7, bits<3> funct3, string opcodestr> { + let Predicates = [HasStdExtD] in + def "" : FPALU_rr_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPALU_rr_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPALU_rr_single; +} + + +multiclass FPALUD_rr_frm funct7, string opcodestr> { + let Predicates = [HasStdExtD] in + def "" : FPALU_rr_frm_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPALU_rr_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPALU_rr_frm_single; +} + +class FPALUDDynFrmAlias_single + : InstAlias; + +multiclass FPALUDDynFrmAlias { + let Predicates = [HasStdExtD] in + def : FPALUDDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV32] in + def : FPALUDDynFrmAlias_single; + + let Predicates = [HasStdExtZdinx, IsRV64] in + def : FPALUDDynFrmAlias_single; +} + + +multiclass FPCmpD_rr funct3, string opcodestr> { + defvar funct7 = 0b1010001; + + let Predicates = [HasStdExtD] in + def "" : FPCmp_rr_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPCmp_rr_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPCmp_rr_single; +} + + +multiclass FPUnaryOp_r_DF funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_single; + } +} + +multiclass FPUnaryOp_r_XD funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_single; + } } -def FCVT_D_L : FPUnaryOp_r_frm<0b1101001, FPR64, GPR, "fcvt.d.l">, - Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]> { - let rs2 = 0b00010; +multiclass FPUnaryOp_r_DX funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtD] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RV32Zdinx" in + let Predicates = [HasStdExtZdinx, IsRV32] in + def _IN32X : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZdinx, IsRV64] in + def _INX : FPUnaryOp_r_single; + } } -def : FPUnaryOpDynFrmAlias; -def FCVT_D_LU : FPUnaryOp_r_frm<0b1101001, FPR64, GPR, "fcvt.d.lu">, - Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]> { - let rs2 = 0b00011; +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +let Predicates = [HasStdExtD] in { + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +def FLD : RVInstI<0b011, OPC_LOAD_FP, (outs FPR64:$rd), + (ins GPR:$rs1, simm12:$imm12), + "fld", "$rd, ${imm12}(${rs1})">, + Sched<[WriteFLD64, ReadFMemBase]>; + +// Operands for stores are in the order srcreg, base, offset rather than +// reflecting the order these fields are specified in the instruction +// encoding. +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +def FSD : RVInstS<0b011, OPC_STORE_FP, (outs), + (ins FPR64:$rs2, GPR:$rs1, simm12:$imm12), + "fsd", "$rs2, ${imm12}(${rs1})">, + Sched<[WriteFST64, ReadStoreData, ReadFMemBase]>; +} // Predicates = [HasStdExtD] + +defm FMADD_D : FPFMAD_rrr_frm, + Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; +defm : FPFMADDynFrmAlias; +defm FMSUB_D : FPFMAD_rrr_frm, + Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; +defm : FPFMADDynFrmAlias; +defm FNMSUB_D : FPFMAD_rrr_frm, + Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; +defm : FPFMADDynFrmAlias; +defm FNMADD_D : FPFMAD_rrr_frm, + Sched<[WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64]>; +defm : FPFMADDynFrmAlias; + +defm FADD_D : FPALUD_rr_frm<0b0000001, "fadd.d">, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +defm : FPALUDDynFrmAlias; +defm FSUB_D : FPALUD_rr_frm<0b0000101, "fsub.d">, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +defm : FPALUDDynFrmAlias; +defm FMUL_D : FPALUD_rr_frm<0b0001001, "fmul.d">, + Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>; +defm : FPALUDDynFrmAlias; +defm FDIV_D : FPALUD_rr_frm<0b0001101, "fdiv.d">, + Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>; +defm : FPALUDDynFrmAlias; + +defm FSQRT_D : FPUnaryOp_r_frm_DD<0b0101101, "fsqrt.d", 0b00000>, + Sched<[WriteFSqrt64, ReadFSqrt64]>; +defm : FPUnaryOpDynFrmAlias_DD; + +defm FSGNJ_D : FPALUD_rr<0b0010001, 0b000, "fsgnj.d">, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +defm FSGNJN_D : FPALUD_rr<0b0010001, 0b001, "fsgnjn.d">, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +defm FSGNJX_D : FPALUD_rr<0b0010001, 0b010, "fsgnjx.d">, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +defm FMIN_D : FPALUD_rr<0b0010101, 0b000, "fmin.d">, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; +defm FMAX_D : FPALUD_rr<0b0010101, 0b001, "fmax.d">, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; + +defm FCVT_S_D : FPUnaryOp_r_frm_FD<0b0100000, "fcvt.s.d", 0b00001>, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>; +defm : FPUnaryOpDynFrmAlias_FD; + +defm FCVT_D_S : FPUnaryOp_r_DF<0b0100001, 0b000, "fcvt.d.s", 0b00000>, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>; + +defm FEQ_D : FPCmpD_rr<0b010, "feq.d">; +defm FLT_D : FPCmpD_rr<0b001, "flt.d">; +defm FLE_D : FPCmpD_rr<0b000, "fle.d">; + +defm FCLASS_D : FPUnaryOp_r_XD<0b1110001, 0b001, "fclass.d", 0b00000>, + Sched<[WriteFClass64, ReadFClass64]>; + +defm FCVT_W_D : FPUnaryOp_r_frm_XPD<0b1100001, "fcvt.w.d", 0b00000>, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; +defm : FPUnaryOpDynFrmAlias_XPD; + +defm FCVT_WU_D : FPUnaryOp_r_frm_XPD<0b1100001, "fcvt.wu.d", 0b00001>, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; +defm : FPUnaryOpDynFrmAlias_XPD; + +defm FCVT_D_W : FPUnaryOp_r_DX<0b1101001, 0b000, "fcvt.d.w", 0b00000>, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>; + +defm FCVT_D_WU : FPUnaryOp_r_DX<0b1101001, 0b000, "fcvt.d.wu", 0b00001>, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>; + +// RV64 only +defm FCVT_L_D : FPUnaryOp_r_frm_XD<0b1100001, "fcvt.l.d", 0b00010>, + Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>; +defm : FPUnaryOpDynFrmAlias_XD; + +defm FCVT_LU_D : FPUnaryOp_r_frm_XD<0b1100001, "fcvt.lu.d", 0b00011>, + Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>; +defm : FPUnaryOpDynFrmAlias_XD; + +let Predicates = [HasStdExtD, IsRV64] in +def FMV_X_D : FPUnaryOp_r_single<0b1110001, 0b000, GPROp, FPR64Op, "fmv.x.d">, + Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]> { + let rs2 = 0b00000; } -def : FPUnaryOpDynFrmAlias; -def FMV_D_X : FPUnaryOp_r<0b1111001, 0b000, FPR64, GPR, "fmv.d.x">, +defm FCVT_D_L : FPUnaryOp_r_frm_DX<0b1101001, "fcvt.d.l", 0b00010>, + Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>; +defm : FPUnaryOpDynFrmAlias_DX; + +defm FCVT_D_LU : FPUnaryOp_r_frm_DX<0b1101001, "fcvt.d.lu", 0b00011>, + Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>; +defm : FPUnaryOpDynFrmAlias_DX; + +let Predicates = [HasStdExtD, IsRV64] in +def FMV_D_X : FPUnaryOp_r_single<0b1111001, 0b000, FPR64Op, GPROp, "fmv.d.x">, Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]> { let rs2 = 0b00000; } -} // Predicates = [HasStdExtD, IsRV64] //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -226,6 +476,26 @@ def PseudoFSD : PseudoStore<"fsd", FPR64>; } // Predicates = [HasStdExtD] +let Predicates = [HasStdExtZdinx, IsRV32] in { +def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_IN32X GPRPF64Op:$rd, GPRPF64Op:$rs, GPRPF64Op:$rs)>; +def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_IN32X GPRPF64Op:$rd, GPRPF64Op:$rs, GPRPF64Op:$rs)>; + +def : InstAlias<"fgt.d $rd, $rs, $rt", + (FLT_D_IN32X GPROp:$rd, GPRPF64Op:$rt, GPRPF64Op:$rs), 0>; +def : InstAlias<"fge.d $rd, $rs, $rt", + (FLE_D_IN32X GPROp:$rd, GPRPF64Op:$rt, GPRPF64Op:$rs), 0>; +} // Predicates = [HasStdExtZdinx, IsRV32] + +let Predicates = [HasStdExtZdinx, IsRV64] in { +def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_INX GPRF64Op:$rd, GPRF64Op:$rs, GPRF64Op:$rs)>; +def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_INX GPRF64Op:$rd, GPRF64Op:$rs, GPRF64Op:$rs)>; + +def : InstAlias<"fgt.d $rd, $rs, $rt", + (FLT_D_INX GPROp:$rd, GPRF64Op:$rt, GPRF64Op:$rs), 0>; +def : InstAlias<"fge.d $rd, $rs, $rt", + (FLE_D_INX GPROp:$rd, GPRF64Op:$rt, GPRF64Op:$rs), 0>; +} // Predicates = [HasStdExtZdinx, IsRV64] + //===----------------------------------------------------------------------===// // 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 @@ -41,6 +41,20 @@ // 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; + // Floating-point rounding mode def FRMArg : AsmOperandClass { @@ -60,54 +74,203 @@ //===----------------------------------------------------------------------===// let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAS_rrr_frm - : RVInstR4Frm<0b00, opcode, (outs FPR32:$rd), - (ins FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, frmarg:$funct3), +class FPFMA_rrr_frm_single funct2, RISCVOpcode opcode, + string opcodestr, RegisterOperand freg> + : RVInstR4Frm; -class FPFMASDynFrmAlias +multiclass FPFMAS_rrr_frm { + defvar funct2 = 0b00; + + let Predicates = [HasStdExtF] in + def "" : FPFMA_rrr_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPFMA_rrr_frm_single; +} + +class FPFMASDynFrmAlias_single : InstAlias; + (Inst freg:$rd, freg:$rs1, freg:$rs2, + freg:$rs3, 0b111)>; + +multiclass FPFMASDynFrmAlias { + let Predicates = [HasStdExtF] in + def : FPFMASDynFrmAlias_single; + + let Predicates = [HasStdExtZfinx] in + def : FPFMASDynFrmAlias_single; +} + + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALU_rr_single funct7, bits<3> funct3, string opcodestr, + RegisterOperand freg> + : RVInstR; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUS_rr funct7, bits<3> funct3, string opcodestr> - : RVInstR; +multiclass FPALUS_rr funct7, bits<3> funct3, string opcodestr> { + let Predicates = [HasStdExtF] in + def "" : FPALU_rr_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPALU_rr_single; +} + let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUS_rr_frm funct7, string opcodestr> - : RVInstRFrm funct7, string opcodestr, + RegisterOperand freg> + : RVInstRFrm; -class FPALUSDynFrmAlias +multiclass FPALUS_rr_frm funct7, string opcodestr>{ + let Predicates = [HasStdExtF] in + def "" : FPALU_rr_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPALU_rr_frm_single; +} + +class FPALUSDynFrmAlias_single : InstAlias; + (Inst freg:$rd, freg:$rs1, freg:$rs2, 0b111)>; + +multiclass FPALUSDynFrmAlias { + let Predicates = [HasStdExtF] in + def : FPALUSDynFrmAlias_single; + + let Predicates = [HasStdExtZfinx] in + def : FPALUSDynFrmAlias_single; +} + let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPUnaryOp_r funct7, bits<3> funct3, RegisterClass rdty, - RegisterClass rs1ty, string opcodestr> +class FPUnaryOp_r_single funct7, bits<3> funct3, RegisterOperand rdty, + RegisterOperand rs1ty, string opcodestr> : RVInstR; +multiclass FPUnaryOp_r_XF funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtF] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPUnaryOp_r_single; + } +} + + let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPUnaryOp_r_frm funct7, RegisterClass rdty, RegisterClass rs1ty, - string opcodestr> +class FPUnaryOp_r_frm_single funct7, RegisterOperand rdty, + RegisterOperand rs1ty, string opcodestr> : RVInstRFrm; -class FPUnaryOpDynFrmAlias +class FPUnaryOpDynFrmAlias_single : InstAlias; +multiclass FPUnaryOp_r_frm_FF funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtF] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_FF { + let Predicates = [HasStdExtF] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZfinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_frm_FX funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtF] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_FX { + let Predicates = [HasStdExtF] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZfinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_frm_XF funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtF] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_XF { + let Predicates = [HasStdExtF] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZfinx] in + def : FPUnaryOpDynFrmAlias_single; +} + + let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPCmpS_rr funct3, string opcodestr> - : RVInstR<0b1010000, funct3, OPC_OP_FP, (outs GPR:$rd), - (ins FPR32:$rs1, FPR32:$rs2), opcodestr, "$rd, $rs1, $rs2">, +class FPCmp_rr_single funct7, bits<3> funct3, string opcodestr, + RegisterOperand freg> + : RVInstR, Sched<[WriteFCmp32, ReadFCmp32, ReadFCmp32]>; +multiclass FPCmpS_rr funct3, string opcodestr> { + defvar funct7 = 0b1010000; + + let Predicates = [HasStdExtF] in + def "" : FPCmp_rr_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZfinx] in + def _INX : FPCmp_rr_single; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -127,119 +290,100 @@ (ins FPR32:$rs2, GPR:$rs1, simm12:$imm12), "fsw", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST32, ReadStoreData, ReadFMemBase]>; +} // Predicates = [HasStdExtF] -def FMADD_S : FPFMAS_rrr_frm, - Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; -def : FPFMASDynFrmAlias; -def FMSUB_S : FPFMAS_rrr_frm, - Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; -def : FPFMASDynFrmAlias; -def FNMSUB_S : FPFMAS_rrr_frm, - Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; -def : FPFMASDynFrmAlias; -def FNMADD_S : FPFMAS_rrr_frm, - Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; -def : FPFMASDynFrmAlias; - -def FADD_S : FPALUS_rr_frm<0b0000000, "fadd.s">, - Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; -def : FPALUSDynFrmAlias; -def FSUB_S : FPALUS_rr_frm<0b0000100, "fsub.s">, - Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; -def : FPALUSDynFrmAlias; -def FMUL_S : FPALUS_rr_frm<0b0001000, "fmul.s">, - Sched<[WriteFMul32, ReadFMul32, ReadFMul32]>; -def : FPALUSDynFrmAlias; -def FDIV_S : FPALUS_rr_frm<0b0001100, "fdiv.s">, - Sched<[WriteFDiv32, ReadFDiv32, ReadFDiv32]>; -def : FPALUSDynFrmAlias; - -def FSQRT_S : FPUnaryOp_r_frm<0b0101100, FPR32, FPR32, "fsqrt.s">, - Sched<[WriteFSqrt32, ReadFSqrt32]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FSGNJ_S : FPALUS_rr<0b0010000, 0b000, "fsgnj.s">, - Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; -def FSGNJN_S : FPALUS_rr<0b0010000, 0b001, "fsgnjn.s">, - Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; -def FSGNJX_S : FPALUS_rr<0b0010000, 0b010, "fsgnjx.s">, - Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; -def FMIN_S : FPALUS_rr<0b0010100, 0b000, "fmin.s">, - Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; -def FMAX_S : FPALUS_rr<0b0010100, 0b001, "fmax.s">, - Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; - -def FCVT_W_S : FPUnaryOp_r_frm<0b1100000, GPR, FPR32, "fcvt.w.s">, - Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FCVT_WU_S : FPUnaryOp_r_frm<0b1100000, GPR, FPR32, "fcvt.wu.s">, - Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]> { - let rs2 = 0b00001; -} -def : FPUnaryOpDynFrmAlias; - -def FMV_X_W : FPUnaryOp_r<0b1110000, 0b000, GPR, FPR32, "fmv.x.w">, +defm FMADD_S : FPFMAS_rrr_frm, + Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; +defm : FPFMASDynFrmAlias; +defm FMSUB_S : FPFMAS_rrr_frm, + Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; +defm : FPFMASDynFrmAlias; +defm FNMSUB_S : FPFMAS_rrr_frm, + Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; +defm : FPFMASDynFrmAlias; +defm FNMADD_S : FPFMAS_rrr_frm, + Sched<[WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32]>; +defm : FPFMASDynFrmAlias; + +defm FADD_S : FPALUS_rr_frm<0b0000000, "fadd.s">, + Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; +defm : FPALUSDynFrmAlias; +defm FSUB_S : FPALUS_rr_frm<0b0000100, "fsub.s">, + Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; +defm : FPALUSDynFrmAlias; +defm FMUL_S : FPALUS_rr_frm<0b0001000, "fmul.s">, + Sched<[WriteFMul32, ReadFMul32, ReadFMul32]>; +defm : FPALUSDynFrmAlias; +defm FDIV_S : FPALUS_rr_frm<0b0001100, "fdiv.s">, + Sched<[WriteFDiv32, ReadFDiv32, ReadFDiv32]>; +defm : FPALUSDynFrmAlias; + +defm FSQRT_S : FPUnaryOp_r_frm_FF<0b0101100, "fsqrt.s", 0b00000>, + Sched<[WriteFSqrt32, ReadFSqrt32]>; +defm : FPUnaryOpDynFrmAlias_FF; + +defm FSGNJ_S : FPALUS_rr<0b0010000, 0b000, "fsgnj.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +defm FSGNJN_S : FPALUS_rr<0b0010000, 0b001, "fsgnjn.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +defm FSGNJX_S : FPALUS_rr<0b0010000, 0b010, "fsgnjx.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +defm FMIN_S : FPALUS_rr<0b0010100, 0b000, "fmin.s">, + Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; +defm FMAX_S : FPALUS_rr<0b0010100, 0b001, "fmax.s">, + Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; + +defm FCVT_W_S : FPUnaryOp_r_frm_XF<0b1100000, "fcvt.w.s", 0b00000>, + Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; +defm : FPUnaryOpDynFrmAlias_XF; + +defm FCVT_WU_S : FPUnaryOp_r_frm_XF<0b1100000, "fcvt.wu.s", 0b00001>, + Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; +defm : FPUnaryOpDynFrmAlias_XF; + +def FMV_X_W : FPUnaryOp_r_single<0b1110000, 0b000, GPROp, FPR32Op, "fmv.x.w">, Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]> { let rs2 = 0b00000; } -def FEQ_S : FPCmpS_rr<0b010, "feq.s">; -def FLT_S : FPCmpS_rr<0b001, "flt.s">; -def FLE_S : FPCmpS_rr<0b000, "fle.s">; +defm FEQ_S : FPCmpS_rr<0b010, "feq.s">; +defm FLT_S : FPCmpS_rr<0b001, "flt.s">; +defm FLE_S : FPCmpS_rr<0b000, "fle.s">; -def FCLASS_S : FPUnaryOp_r<0b1110000, 0b001, GPR, FPR32, "fclass.s">, - Sched<[WriteFClass32, ReadFClass32]> { - let rs2 = 0b00000; -} +defm FCLASS_S : FPUnaryOp_r_XF<0b1110000, 0b001, "fclass.s", 0b00000>, + Sched<[WriteFClass32, ReadFClass32]>; -def FCVT_S_W : FPUnaryOp_r_frm<0b1101000, FPR32, GPR, "fcvt.s.w">, - Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_S_W : FPUnaryOp_r_frm_FX<0b1101000, "fcvt.s.w", 0b00000>, + Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; +defm : FPUnaryOpDynFrmAlias_FX; -def FCVT_S_WU : FPUnaryOp_r_frm<0b1101000, FPR32, GPR, "fcvt.s.wu">, - Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]> { - let rs2 = 0b00001; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_S_WU : FPUnaryOp_r_frm_FX<0b1101000, "fcvt.s.wu", 0b00001>, + Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; +defm : FPUnaryOpDynFrmAlias_FX; -def FMV_W_X : FPUnaryOp_r<0b1111000, 0b000, FPR32, GPR, "fmv.w.x">, +def FMV_W_X : FPUnaryOp_r_single<0b1111000, 0b000, FPR32Op, GPROp, "fmv.w.x">, Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]> { let rs2 = 0b00000; } -} // Predicates = [HasStdExtF] -let Predicates = [HasStdExtF, IsRV64] in { -def FCVT_L_S : FPUnaryOp_r_frm<0b1100000, GPR, FPR32, "fcvt.l.s">, - Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]> { - let rs2 = 0b00010; -} -def : FPUnaryOpDynFrmAlias; +let Predicates = [IsRV64] in { +defm FCVT_L_S : FPUnaryOp_r_frm_XF<0b1100000, "fcvt.l.s", 0b00010>, + Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; +defm : FPUnaryOpDynFrmAlias_XF; -def FCVT_LU_S : FPUnaryOp_r_frm<0b1100000, GPR, FPR32, "fcvt.lu.s">, - Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]> { - let rs2 = 0b00011; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_LU_S : FPUnaryOp_r_frm_XF<0b1100000, "fcvt.lu.s", 0b00011>, + Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; +defm : FPUnaryOpDynFrmAlias_XF; -def FCVT_S_L : FPUnaryOp_r_frm<0b1101000, FPR32, GPR, "fcvt.s.l">, - Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]> { - let rs2 = 0b00010; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_S_L : FPUnaryOp_r_frm_FX<0b1101000, "fcvt.s.l", 0b00010>, + Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; +defm : FPUnaryOpDynFrmAlias_FX; -def FCVT_S_LU : FPUnaryOp_r_frm<0b1101000, FPR32, GPR, "fcvt.s.lu">, - Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]> { - let rs2 = 0b00011; -} -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtF, IsRV64] +defm FCVT_S_LU : FPUnaryOp_r_frm_FX<0b1101000, "fcvt.s.lu", 0b00011>, + Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; +defm : FPUnaryOpDynFrmAlias_FX; +} // Predicates = [IsRV64] //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -294,6 +438,17 @@ def PseudoFSW : PseudoStore<"fsw", FPR32>; } // Predicates = [HasStdExtF] +let Predicates = [HasStdExtZfinx] in { +def : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S_INX GPRF32Op:$rd, GPRF32Op:$rs, GPRF32Op:$rs)>; +def : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S_INX GPRF32Op:$rd, GPRF32Op:$rs, GPRF32Op:$rs)>; + +def : InstAlias<"fgt.s $rd, $rs, $rt", + (FLT_S_INX GPROp:$rd, GPRF32Op:$rt, GPRF32Op:$rs), 0>; +def : InstAlias<"fge.s $rd, $rs, $rt", + (FLE_S_INX GPROp:$rd, GPRF32Op:$rt, GPRF32Op:$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,40 +27,233 @@ def riscv_fmv_x_anyexth : SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_ANYEXTH>; +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +def GPRF16Op : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +def FPR16Op : RegisterOperand; + //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAH_rrr_frm - : RVInstR4Frm<0b10, opcode, (outs FPR16:$rd), - (ins FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; +multiclass FPFMAH_rrr_frm { + defvar funct2 = 0b10; + + let Predicates = [HasStdExtZfh] in + def "" : FPFMA_rrr_frm_single; -class FPFMAHDynFrmAlias + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPFMA_rrr_frm_single; +} + +class FPFMAHDynFrmAlias_single : InstAlias; + (Inst freg:$rd, freg:$rs1, freg:$rs2, freg:$rs3, 0b111)>; + +multiclass FPFMAHDynFrmAlias { + let Predicates = [HasStdExtZfh] in + def : FPFMAHDynFrmAlias_single; + + let Predicates = [HasStdExtZhinx] in + def : FPFMAHDynFrmAlias_single; +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUH_rr funct7, bits<3> funct3, string opcodestr> - : RVInstR; -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPALUH_rr_frm funct7, string opcodestr> - : RVInstRFrm; +multiclass FPALUH_rr funct7, bits<3> funct3, string opcodestr> { + let Predicates = [HasStdExtZfh] in + def "" : FPALU_rr_single; -class FPALUHDynFrmAlias + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPALU_rr_single; +} + + +multiclass FPALUH_rr_frm funct7, string opcodestr> { + let Predicates = [HasStdExtZfh] in + def "" : FPALU_rr_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPALU_rr_frm_single; +} + +class FPALUHDynFrmAlias_single : InstAlias; + (Inst freg:$rd, freg:$rs1, freg:$rs2, 0b111)>; + +multiclass FPALUHDynFrmAlias { + let Predicates = [HasStdExtZfh] in + def : FPALUHDynFrmAlias_single; + + let Predicates = [HasStdExtZhinx] in + def : FPALUHDynFrmAlias_single; +} + + +multiclass FPCmpH_rr funct3, string opcodestr> { + defvar funct7 = 0b1010010; + + let Predicates = [HasStdExtZfh] in + def "" : FPCmp_rr_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPCmp_rr_single; +} + + +multiclass FPUnaryOp_r_frm_HH funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfh] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_HH { + let Predicates = [HasStdExtZfh] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZhinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOpDynFrmAlias_XH { + let Predicates = [HasStdExtZfh] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZhinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_frm_XH funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfh] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOp_r_XH funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfh] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPUnaryOp_r_single; + } +} + +multiclass FPUnaryOp_r_frm_HX funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfh] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_HX { + let Predicates = [HasStdExtZfh] in + def : FPUnaryOpDynFrmAlias_single; + let Predicates = [HasStdExtZhinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_frm_HF funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfhmin] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinxmin] in + def _INX : FPUnaryOp_r_frm_single; + } +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPCmpH_rr funct3, string opcodestr> - : RVInstR<0b1010010, funct3, OPC_OP_FP, (outs GPR:$rd), - (ins FPR16:$rs1, FPR16:$rs2), opcodestr, "$rd, $rs1, $rs2">, - Sched<[WriteFCmp16, ReadFCmp16, ReadFCmp16]>; +multiclass FPUnaryOpDynFrmAlias_HF { + let Predicates = [HasStdExtZfhmin] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZhinxmin] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_frm_HD funct7, string opcodestr, bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfhmin, HasStdExtD] in + def "" : FPUnaryOp_r_frm_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinxmin, HasStdExtZdinx] in + def _INX : FPUnaryOp_r_frm_single; + } +} + +multiclass FPUnaryOpDynFrmAlias_HD { + let Predicates = [HasStdExtZfhmin, HasStdExtD] in + def : FPUnaryOpDynFrmAlias_single; + + let Predicates = [HasStdExtZhinxmin, HasStdExtZdinx] in + def : FPUnaryOpDynFrmAlias_single; +} + +multiclass FPUnaryOp_r_FH funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfhmin] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinxmin] in + def _INX : FPUnaryOp_r_single; + } +} + +multiclass FPUnaryOp_r_DH funct7, bits<3> funct3, string opcodestr, + bits<5> rs2> { + let rs2 = rs2 in { + let Predicates = [HasStdExtZfhmin] in + def "" : FPUnaryOp_r_single; + + let DecoderNamespace = "RVZfinx" in + let Predicates = [HasStdExtZhinx] in + def _INX : FPUnaryOp_r_single; + } +} //===----------------------------------------------------------------------===// // Instructions @@ -83,147 +276,116 @@ Sched<[WriteFST16, ReadStoreData, ReadFMemBase]>; } // Predicates = [HasStdExtZfhmin] -let Predicates = [HasStdExtZfh] in { -def FMADD_H : FPFMAH_rrr_frm, - Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; -def : FPFMAHDynFrmAlias; -def FMSUB_H : FPFMAH_rrr_frm, - Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; -def : FPFMAHDynFrmAlias; -def FNMSUB_H : FPFMAH_rrr_frm, - Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; -def : FPFMAHDynFrmAlias; -def FNMADD_H : FPFMAH_rrr_frm, - Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; -def : FPFMAHDynFrmAlias; - -def FADD_H : FPALUH_rr_frm<0b0000010, "fadd.h">, - Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; -def : FPALUHDynFrmAlias; -def FSUB_H : FPALUH_rr_frm<0b0000110, "fsub.h">, - Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; -def : FPALUHDynFrmAlias; -def FMUL_H : FPALUH_rr_frm<0b0001010, "fmul.h">, - Sched<[WriteFMul16, ReadFMul16, ReadFMul16]>; -def : FPALUHDynFrmAlias; -def FDIV_H : FPALUH_rr_frm<0b0001110, "fdiv.h">, - Sched<[WriteFDiv16, ReadFDiv16, ReadFDiv16]>; -def : FPALUHDynFrmAlias; - -def FSQRT_H : FPUnaryOp_r_frm<0b0101110, FPR16, FPR16, "fsqrt.h">, - Sched<[WriteFSqrt16, ReadFSqrt16]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FSGNJ_H : FPALUH_rr<0b0010010, 0b000, "fsgnj.h">, - Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; -def FSGNJN_H : FPALUH_rr<0b0010010, 0b001, "fsgnjn.h">, - Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; -def FSGNJX_H : FPALUH_rr<0b0010010, 0b010, "fsgnjx.h">, - Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; -def FMIN_H : FPALUH_rr<0b0010110, 0b000, "fmin.h">, - Sched<[WriteFMinMax16, ReadFMinMax16, ReadFMinMax16]>; -def FMAX_H : FPALUH_rr<0b0010110, 0b001, "fmax.h">, - Sched<[WriteFMinMax16, ReadFMinMax16, ReadFMinMax16]>; - -def FCVT_W_H : FPUnaryOp_r_frm<0b1100010, GPR, FPR16, "fcvt.w.h">, - Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FCVT_WU_H : FPUnaryOp_r_frm<0b1100010, GPR, FPR16, "fcvt.wu.h">, - Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]> { - let rs2 = 0b00001; -} -def : FPUnaryOpDynFrmAlias; - -def FCVT_H_W : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.w">, - Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.wu">, - Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]> { - let rs2 = 0b00001; -} -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtZfh] +defm FMADD_H : FPFMAH_rrr_frm, + Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; +defm : FPFMAHDynFrmAlias; +defm FMSUB_H : FPFMAH_rrr_frm, + Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; +defm : FPFMAHDynFrmAlias; +defm FNMSUB_H : FPFMAH_rrr_frm, + Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; +defm : FPFMAHDynFrmAlias; +defm FNMADD_H : FPFMAH_rrr_frm, + Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>; +defm : FPFMAHDynFrmAlias; + +defm FADD_H : FPALUH_rr_frm<0b0000010, "fadd.h">, + Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; +defm : FPALUHDynFrmAlias; +defm FSUB_H : FPALUH_rr_frm<0b0000110, "fsub.h">, + Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; +defm : FPALUHDynFrmAlias; +defm FMUL_H : FPALUH_rr_frm<0b0001010, "fmul.h">, + Sched<[WriteFMul16, ReadFMul16, ReadFMul16]>; +defm : FPALUHDynFrmAlias; +defm FDIV_H : FPALUH_rr_frm<0b0001110, "fdiv.h">, + Sched<[WriteFDiv16, ReadFDiv16, ReadFDiv16]>; +defm : FPALUHDynFrmAlias; + +defm FSQRT_H : FPUnaryOp_r_frm_HH<0b0101110, "fsqrt.h", 0b00000>, + Sched<[WriteFSqrt16, ReadFSqrt16]>; +defm : FPUnaryOpDynFrmAlias_HH; + +defm FSGNJ_H : FPALUH_rr<0b0010010, 0b000, "fsgnj.h">, + Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; +defm FSGNJN_H : FPALUH_rr<0b0010010, 0b001, "fsgnjn.h">, + Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; +defm FSGNJX_H : FPALUH_rr<0b0010010, 0b010, "fsgnjx.h">, + Sched<[WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16]>; +defm FMIN_H : FPALUH_rr<0b0010110, 0b000, "fmin.h">, + Sched<[WriteFMinMax16, ReadFMinMax16, ReadFMinMax16]>; +defm FMAX_H : FPALUH_rr<0b0010110, 0b001, "fmax.h">, + Sched<[WriteFMinMax16, ReadFMinMax16, ReadFMinMax16]>; + +defm FCVT_W_H : FPUnaryOp_r_frm_XH<0b1100010, "fcvt.w.h", 0b00000>, + Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>; +defm : FPUnaryOpDynFrmAlias_XH; + +defm FCVT_WU_H : FPUnaryOp_r_frm_XH<0b1100010, "fcvt.wu.h", 0b00001>, + Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>; +defm : FPUnaryOpDynFrmAlias_XH; + +defm FCVT_H_W : FPUnaryOp_r_frm_HX<0b1101010, "fcvt.h.w", 0b00000>, + Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>; +defm : FPUnaryOpDynFrmAlias_HX; + +defm FCVT_H_WU : FPUnaryOp_r_frm_HX<0b1101010, "fcvt.h.wu", 0b00001>, + Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>; +defm : FPUnaryOpDynFrmAlias_HX; + +defm FCVT_H_S : FPUnaryOp_r_frm_HF<0b0100010, "fcvt.h.s", 0b00000>, + Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>; +defm : FPUnaryOpDynFrmAlias_HF; + +defm FCVT_S_H : FPUnaryOp_r_FH<0b0100000, 0b000, "fcvt.s.h", 0b00010>, + Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>; let Predicates = [HasStdExtZfhmin] in { -def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, FPR16, FPR32, "fcvt.h.s">, - Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]> { - let rs2 = 0b00000; -} -def : FPUnaryOpDynFrmAlias; - -def FCVT_S_H : FPUnaryOp_r<0b0100000, 0b000, FPR32, FPR16, "fcvt.s.h">, - Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]> { - let rs2 = 0b00010; -} - -def FMV_X_H : FPUnaryOp_r<0b1110010, 0b000, GPR, FPR16, "fmv.x.h">, +def FMV_X_H : FPUnaryOp_r_single<0b1110010, 0b000, GPROp, FPR16Op, "fmv.x.h">, Sched<[WriteFMovF16ToI16, ReadFMovF16ToI16]> { let rs2 = 0b00000; } -def FMV_H_X : FPUnaryOp_r<0b1111010, 0b000, FPR16, GPR, "fmv.h.x">, +def FMV_H_X : FPUnaryOp_r_single<0b1111010, 0b000, FPR16Op, GPROp, "fmv.h.x">, Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]> { let rs2 = 0b00000; } } // Predicates = [HasStdExtZfhmin] -let Predicates = [HasStdExtZfh] in { -def FEQ_H : FPCmpH_rr<0b010, "feq.h">; -def FLT_H : FPCmpH_rr<0b001, "flt.h">; -def FLE_H : FPCmpH_rr<0b000, "fle.h">; +defm FEQ_H : FPCmpH_rr<0b010, "feq.h">; +defm FLT_H : FPCmpH_rr<0b001, "flt.h">; +defm FLE_H : FPCmpH_rr<0b000, "fle.h">; -def FCLASS_H : FPUnaryOp_r<0b1110010, 0b001, GPR, FPR16, "fclass.h">, - Sched<[WriteFClass16, ReadFClass16]> { - let rs2 = 0b00000; -} -} // Predicates = [HasStdExtZfh] +defm FCLASS_H : FPUnaryOp_r_XH<0b1110010, 0b001, "fclass.h", 0b00000>, + Sched<[WriteFClass16, ReadFClass16]>; -let Predicates = [HasStdExtZfh, IsRV64] in { -def FCVT_L_H : FPUnaryOp_r_frm<0b1100010, GPR, FPR16, "fcvt.l.h">, - Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]> { - let rs2 = 0b00010; -} -def : FPUnaryOpDynFrmAlias; +let Predicates = [IsRV64] in { +defm FCVT_L_H : FPUnaryOp_r_frm_XH<0b1100010, "fcvt.l.h", 0b00010>, + Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>; +defm : FPUnaryOpDynFrmAlias_XH; -def FCVT_LU_H : FPUnaryOp_r_frm<0b1100010, GPR, FPR16, "fcvt.lu.h">, - Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]> { - let rs2 = 0b00011; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_LU_H : FPUnaryOp_r_frm_XH<0b1100010, "fcvt.lu.h", 0b00011>, + Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>; +defm : FPUnaryOpDynFrmAlias_XH; -def FCVT_H_L : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.l">, - Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]> { - let rs2 = 0b00010; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_H_L : FPUnaryOp_r_frm_HX<0b1101010, "fcvt.h.l", 0b00010>, + Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>; +defm : FPUnaryOpDynFrmAlias_HX; -def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.lu">, - Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]> { - let rs2 = 0b00011; -} -def : FPUnaryOpDynFrmAlias; -} // Predicates = [HasStdExtZfh, IsRV64] +defm FCVT_H_LU : FPUnaryOp_r_frm_HX<0b1101010, "fcvt.h.lu", 0b00011>, + Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>; +defm : FPUnaryOpDynFrmAlias_HX; +} // Predicates = [IsRV64] -let Predicates = [HasStdExtZfhmin, HasStdExtD] in { -def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, FPR16, FPR64, "fcvt.h.d">, - Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]> { - let rs2 = 0b00001; -} -def : FPUnaryOpDynFrmAlias; +defm FCVT_H_D : FPUnaryOp_r_frm_HD<0b0100010, "fcvt.h.d", 0b00001>, + Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>; +defm : FPUnaryOpDynFrmAlias_HD; -def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b000, FPR64, FPR16, "fcvt.d.h">, - Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]> { - let rs2 = 0b00010; -} -} // Predicates = [HasStdExtZfhmin, HasStdExtD] +defm FCVT_D_H : FPUnaryOp_r_DH<0b0100001, 0b000, "fcvt.d.h", 0b00010>, + Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) @@ -252,6 +414,16 @@ def PseudoFSH : PseudoStore<"fsh", FPR16>; } // Predicates = [HasStdExtZfhmin] +let Predicates = [HasStdExtZhinx] in { +def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H_INX GPRF16Op:$rd, GPRF16Op:$rs, GPRF16Op:$rs)>; +def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H_INX GPRF16Op:$rd, GPRF16Op:$rs, GPRF16Op:$rs)>; + +def : InstAlias<"fgt.h $rd, $rs, $rt", + (FLT_H_INX GPROp:$rd, GPRF16Op:$rt, GPRF16Op:$rs), 0>; +def : InstAlias<"fge.h $rd, $rs, $rt", + (FLE_H_INX GPROp:$rd, GPRF16Op:$rt, GPRF16Op:$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 @@ -555,6 +556,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<[vbool1_t, vbool2_t, vbool4_t, vbool8_t, vbool16_t, vbool32_t, vbool64_t], diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -54,6 +54,10 @@ bool HasStdExtZvamo = false; bool HasStdExtZfhmin = false; bool HasStdExtZfh = false; + bool HasStdExtZfinx = false; + bool HasStdExtZdinx = false; + bool HasStdExtZhinx = false; + bool HasStdExtZhinxmin = false; bool HasRV64 = false; bool IsRV32E = false; bool EnableLinkerRelax = false; @@ -121,6 +125,10 @@ bool hasStdExtZvamo() const { return HasStdExtZvamo; } bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } bool hasStdExtZfh() const { return HasStdExtZfh; } + bool hasStdExtZfinx() const { return HasStdExtZfinx; } + bool hasStdExtZdinx() const { return HasStdExtZdinx; } + bool hasStdExtZhinx() const { return HasStdExtZhinx; } + bool hasStdExtZhinxmin() const { return HasStdExtZhinxmin; } bool is64Bit() const { return HasRV64; } bool isRV32E() const { return IsRV32E; } bool enableLinkerRelax() const { return EnableLinkerRelax; } diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -72,6 +72,18 @@ .attribute arch, "rv32ifzfh" # CHECK: attribute 5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1" +.attribute arch, "rv32izfinx" +# CHECK: attribute 5, "rv32i2p0_zfinx1p0" + +.attribute arch, "rv32izdinx" +# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zdinx1p0" + +.attribute arch, "rv32izhinxmin" +# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zhinxmin1p0" + +.attribute arch, "rv32izhinx" +# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zhinx1p0_zhinxmin1p0" + .attribute arch, "rv32ivzvamo_zvlsseg" # CHECK: attribute 5, "rv32i2p0_v0p10_zvamo0p10_zvlsseg0p10" diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s --- a/llvm/test/MC/RISCV/rv32i-invalid.s +++ b/llvm/test/MC/RISCV/rv32i-invalid.s @@ -1,4 +1,4 @@ -# RUN: not llvm-mc -triple riscv32 < %s 2>&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,156 @@ +# 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 +# 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,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,160 @@ +# 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 +# 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,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,160 @@ +# 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 +# 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,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/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,50 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zhinxmin -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-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=+experimental-zhinxmin %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinxmin -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zhinxmin %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinxmin -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: 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,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-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 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=+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 +# +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-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,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-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 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=+experimental-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=+experimental-zfinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-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,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-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 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=+experimental-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=+experimental-zhinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-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,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-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 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=+experimental-zhinx,+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-zhinx,+experimental-zdinx %s \ +# RUN: | llvm-objdump --mattr=+experimental-zhinx,+experimental-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,27 @@ +# 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 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: fcvt.l.d a0, t0, dyn +# CHECK-ALIAS: fcvt.l.d a0, t0 +fcvt.l.d a0, t0 +# CHECK-INST: fcvt.lu.d a1, t1, dyn +# CHECK-ALIAS: fcvt.lu.d a1, t1 +fcvt.lu.d a1, t1 +# CHECK-INST: fcvt.d.l t3, a3, dyn +# CHECK-ALIAS: fcvt.d.l t3, a3 +fcvt.d.l t3, a3 +# CHECK-INST: fcvt.d.lu t4, a4, dyn +# CHECK-ALIAS: fcvt.d.lu t4, a4 +fcvt.d.lu t4, a4 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=+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 + +##===----------------------------------------------------------------------===## +## 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,83 @@ +# 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 + +##===----------------------------------------------------------------------===## +## 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