Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -162,6 +162,7 @@ OperandMatchResultTy parseJALOffset(OperandVector &Operands); OperandMatchResultTy parseVTypeI(OperandVector &Operands); OperandMatchResultTy parseMaskReg(OperandVector &Operands); + OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); @@ -264,6 +265,8 @@ bool IsRV64; + bool IsGPRAsFPR; + struct RegOp { MCRegister RegNum; }; @@ -335,6 +338,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)) { @@ -777,12 +788,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; } @@ -834,6 +847,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()); @@ -937,6 +965,7 @@ Op.Reg.RegNum = convertFPR64ToFPR16(Reg); return Match_Success; } + return Match_InvalidOperand; } @@ -1616,6 +1645,29 @@ 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) && + !getSTI().hasFeature(RISCV::FeatureStdExtD) && + !getSTI().hasFeature(RISCV::FeatureExtZfh))); + } + return MatchOperand_Success; +} + OperandMatchResultTy RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { if (getLexer().isNot(AsmToken::LParen)) { Index: llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp =================================================================== --- llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -161,6 +161,36 @@ 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) { @@ -367,6 +397,30 @@ return MCDisassembler::Fail; } Insn = support::endian::read32le(Bytes.data()); + + if (STI.getFeatureBits()[RISCV::FeatureExtZfdinx] && + !STI.getFeatureBits()[RISCV::Feature64Bit]) { + LLVM_DEBUG(dbgs() << "Trying RV32DZfinx table (Double in Integer and" + "rv32)\n"); + Result = decodeInstruction(DecoderTableRV32DZfinx32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + + if (STI.getFeatureBits()[RISCV::FeatureExtZfinx]) { + 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; Index: llvm/lib/Target/RISCV/RISCV.td =================================================================== --- llvm/lib/Target/RISCV/RISCV.td +++ llvm/lib/Target/RISCV/RISCV.td @@ -49,6 +49,29 @@ AssemblerPredicate<(all_of FeatureExtZfh), "'Zfh' (Half-Precision Floating-Point)">; +def FeatureExtZfinx + : SubtargetFeature<"experimental-zfinx", "HasStdExtZfinx", "true", + "'Zfinx' (Float in Integer)">; +def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">, + AssemblerPredicate<(all_of FeatureExtZfinx), + "'Zfinx' (Float in Integer)">; + +def FeatureExtZfdinx + : SubtargetFeature<"experimental-zfdinx", "HasStdExtZfdinx", "true", + "'Zfdinx' (Double in Integer)", + [FeatureExtZfinx]>; +def HasStdExtZfdinx : Predicate<"Subtarget->hasStdExtZfdinx()">, + AssemblerPredicate<(all_of FeatureExtZfdinx), + "'Zfdinx' (Double in Integer)">; + +def FeatureExtZfhinx + : SubtargetFeature<"experimental-zfhinx", "HasStdExtZfhinx", "true", + "'Zfhinx' (Half Float in Integer)", + [FeatureExtZfinx]>; +def HasStdExtZfhinx : Predicate<"Subtarget->hasStdExtZfhinx()">, + AssemblerPredicate<(all_of FeatureExtZfhinx), + "'Zfhinx' (Half Float in Integer)">; + def FeatureStdExtC : SubtargetFeature<"c", "HasStdExtC", "true", "'C' (Compressed Instructions)">; Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1224,3 +1224,6 @@ include "RISCVInstrInfoB.td" include "RISCVInstrInfoV.td" include "RISCVInstrInfoZfh.td" +include "RISCVInstrInfoZfinx.td" +include "RISCVInstrInfoZfdinx.td" +include "RISCVInstrInfoZfhinx.td" Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfdinx.td =================================================================== --- /dev/null +++ llvm/lib/Target/RISCV/RISCVInstrInfoZfdinx.td @@ -0,0 +1,280 @@ +//===- RISCVInstrInfoZfinx.td - RISC-V 'Zfdinx' instructions -*- tblgen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard 'Zfdinx' +// double in integer. +// This version is still experimental as the 'Zfdinx' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction class templates +//===----------------------------------------------------------------------===// + +def GPRPF64AsFPR : AsmOperandClass { + let Name = "GPRPF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF64AsFPR : AsmOperandClass { + let Name = "GPRF64AsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF64Op : RegisterOperand { + let ParserMatchClass = GPRF64AsFPR; +} + +def GPRPF64Op : RegisterOperand { + let ParserMatchClass = GPRPF64AsFPR; +} + +let DecoderNamespace = "RVZfinx" in { + +// RV64 and Zfdinx extension +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPFMADINX_rrr_frm + : RVInstR4<0b01, opcode, (outs freg:$rd), + (ins freg:$rs1, freg:$rs2, freg:$rs3, frmarg:$funct3), + opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUDINX_rr funct7, bits<3> funct3, string opcodestr, RegisterOperand freg> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUDINX_rr_frm funct7, string opcodestr, RegisterOperand freg> + : RVInstRFrm; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPCmpDINX_rr funct3, string opcodestr, RegisterOperand freg> + : RVInstR<0b1010001, funct3, OPC_OP_FP, (outs GPROp:$rd), + (ins freg:$rs1, freg:$rs2), opcodestr, "$rd, $rs1, $rs2">, + Sched<[WriteFCmp64, ReadFCmp64, ReadFCmp64]>; +} + +class FPFMADINXDynFrmAlias + : InstAlias; + +class FPALUDINXDynFrmAlias + : InstAlias; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + + +// Instructions in Zfdinx extension on RV64 +let Predicates = [HasStdExtZfdinx, IsRV64] in { +def FMADD_D_INX : FPFMADINX_rrr_frm, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; +def : FPFMADINXDynFrmAlias; +def FMSUB_D_INX : FPFMADINX_rrr_frm, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +def : FPFMADINXDynFrmAlias; +def FNMSUB_D_INX : FPFMADINX_rrr_frm, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +def : FPFMADINXDynFrmAlias; +def FNMADD_D_INX : FPFMADINX_rrr_frm, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; +def : FPFMADINXDynFrmAlias; + +def FADD_D_INX : FPALUDINX_rr_frm<0b0000001, "fadd.d", GPRF64Op>, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +def : FPALUDINXDynFrmAlias; +def FSUB_D_INX : FPALUDINX_rr_frm<0b0000101, "fsub.d", GPRF64Op>, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +def : FPALUDINXDynFrmAlias; +def FMUL_D_INX : FPALUDINX_rr_frm<0b0001001, "fmul.d", GPRF64Op>, + Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>; +def : FPALUDINXDynFrmAlias; +def FDIV_D_INX : FPALUDINX_rr_frm<0b0001101, "fdiv.d", GPRF64Op>, + Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>; +def : FPALUDINXDynFrmAlias; + +def FSQRT_D_INX : FPUnaryOpINX_r_frm<0b0101101, GPRF64Op, GPRF64Op, "fsqrt.d">, + Sched<[WriteFSqrt64, ReadFSqrt64]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FSGNJ_D_INX : FPALUDINX_rr<0b0010001, 0b000, "fsgnj.d", GPRF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def FSGNJN_D_INX : FPALUDINX_rr<0b0010001, 0b001, "fsgnjn.d", GPRF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def FSGNJX_D_INX : FPALUDINX_rr<0b0010001, 0b010, "fsgnjx.d", GPRF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def FMIN_D_INX : FPALUDINX_rr<0b0010101, 0b000, "fmin.d", GPRF64Op>, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; +def FMAX_D_INX : FPALUDINX_rr<0b0010101, 0b001, "fmax.d", GPRF64Op>, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; + +def FCVT_S_D_INX : FPUnaryOpINX_r_frm<0b0100000, GPRF32Op, GPRF64Op, "fcvt.s.d">, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_D_S_INX : FPUnaryOpINX_r<0b0100001, 0b000, GPRF64Op, GPRF32Op, "fcvt.d.s">, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]> { + let rs2 = 0b00000; +} + +def FEQ_D_INX : FPCmpDINX_rr<0b010, "feq.d", GPRF64Op>; +def FLT_D_INX : FPCmpDINX_rr<0b001, "flt.d", GPRF64Op>; +def FLE_D_INX : FPCmpDINX_rr<0b000, "fle.d", GPRF64Op>; + +def FCLASS_D_INX : FPUnaryOpINX_r<0b1110001, 0b001, GPROp, GPRF64Op, "fclass.d">, + Sched<[WriteFClass64, ReadFClass64]> { + let rs2 = 0b00000; +} + +def FCVT_W_D_INX : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRF64Op, "fcvt.w.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_WU_D_INX : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRF64Op, "fcvt.wu.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_D_W_INX : FPUnaryOpINX_r<0b1101001, 0b000, GPRF64Op, GPROp, "fcvt.d.w">, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { + let rs2 = 0b00000; +} + +def ZFCVT_D_WU_INX : FPUnaryOpINX_r<0b1101001, 0b000, GPRF64Op, GPROp, "fcvt.d.wu">, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { + let rs2 = 0b00001; +} + +def FCVT_L_D_INX : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRF64Op, "fcvt.l.d">, + Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_LU_D_INX : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRF64Op, "fcvt.lu.d">, + Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_D_L_INX : FPUnaryOpINX_r_frm<0b1101001, GPRF64Op, GPROp, "fcvt.d.l">, + Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_D_L_INXU : FPUnaryOpINX_r_frm<0b1101001, GPRF64Op, GPROp, "fcvt.d.lu">, + Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; + +} // Predicates = [HasStdExtZfdinx, IsRV64] + +// Instruction in Zfdinx extension on RV32 +let Predicates = [HasStdExtZfdinx, IsRV32] in { +let DecoderNamespace = "RV32DZfinx" in { +def ZFMADD_IN32X : FPFMADINX_rrr_frm, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; +def ZFMSUB_IN32X : FPFMADINX_rrr_frm, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +def ZFNMSUB_IN32X : FPFMADINX_rrr_frm, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +def ZFNMADD_IN32X : FPFMADINX_rrr_frm, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; + +def ZFADD_IN32X : FPALUDINX_rr_frm<0b0000001, "fadd.d", GPRPF64Op>, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +def ZFSUB_IN32X : FPALUDINX_rr_frm<0b0000101, "fsub.d", GPRPF64Op>, + Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; +def ZFMUL_IN32X : FPALUDINX_rr_frm<0b0001001, "fmul.d", GPRPF64Op>, + Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>; +def ZFDIV_IN32X : FPALUDINX_rr_frm<0b0001101, "fdiv.d", GPRPF64Op>, + Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>; + +def ZFSQRT_IN32X : FPUnaryOpINX_r_frm<0b0101101, GPRPF64Op, GPRPF64Op, "fsqrt.d">, + Sched<[WriteFSqrt64, ReadFSqrt64]> { + let rs2 = 0b00000; +} + +def ZFSGNJ_IN32X : FPALUDINX_rr<0b0010001, 0b000, "fsgnj.d", GPRPF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def ZFSGNJN_IN32X : FPALUDINX_rr<0b0010001, 0b001, "fsgnjn.d", GPRPF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def ZFSGNJX_IN32X : FPALUDINX_rr<0b0010001, 0b010, "fsgnjx.d", GPRPF64Op>, + Sched<[WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64]>; +def ZFMIN_IN32X : FPALUDINX_rr<0b0010101, 0b000, "fmin.d", GPRPF64Op>, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; +def ZFMAX_IN32X : FPALUDINX_rr<0b0010101, 0b001, "fmax.d", GPRPF64Op>, + Sched<[WriteFMinMax64, ReadFMinMax64, ReadFMinMax64]>; + +def ZFCVT_S_IN32X : FPUnaryOpINX_r_frm<0b0100000, GPRF32Op, GPRPF64Op, "fcvt.s.d">, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]> { + let rs2 = 0b00001; +} + +def ZFCVT_D_S32 : FPUnaryOpINX_r<0b0100001, 0b000, GPRPF64Op, GPRF32Op, "fcvt.d.s">, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]> { + let rs2 = 0b00000; +} + +def ZFEQ_IN32X : FPCmpDINX_rr<0b010, "feq.d", GPRPF64Op>; +def ZFLT_IN32X : FPCmpDINX_rr<0b001, "flt.d", GPRPF64Op>; +def ZFLE_IN32X : FPCmpDINX_rr<0b000, "fle.d", GPRPF64Op>; + +def ZFCLASS_IN32X : FPUnaryOpINX_r<0b1110001, 0b001, GPROp, GPRPF64Op, "fclass.d">, + Sched<[WriteFClass64, ReadFClass64]> { + let rs2 = 0b00000; +} + +def ZFCVT_W_IN32X : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRPF64Op, "fcvt.w.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { + let rs2 = 0b00000; +} + +def ZFCVT_WU_IN32X : FPUnaryOpINX_r_frm<0b1100001, GPROp, GPRPF64Op, "fcvt.wu.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]> { + let rs2 = 0b00001; +} + +def ZFCVT_D_W32 : FPUnaryOpINX_r<0b1101001, 0b000, GPRPF64Op, GPROp, "fcvt.d.w">, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { + let rs2 = 0b00000; +} + +def ZFCVT_D_WU32 : FPUnaryOpINX_r<0b1101001, 0b000, GPRPF64Op, GPROp, "fcvt.d.wu">, + Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]> { + let rs2 = 0b00001; +} +} // DecoderNamespace = "RV32DZfinx" +def : FPFMADINXDynFrmAlias; +def : FPFMADINXDynFrmAlias; +def : FPFMADINXDynFrmAlias; +def : FPALUDINXDynFrmAlias; +def : FPFMADINXDynFrmAlias; +def : FPALUDINXDynFrmAlias; +def : FPALUDINXDynFrmAlias; +def : FPALUDINXDynFrmAlias; +def : FPUnaryOpINXDynFrmAlias; +def : FPUnaryOpINXDynFrmAlias; +def : FPUnaryOpINXDynFrmAlias; +def : FPUnaryOpINXDynFrmAlias; + +} // Predicates = [HasStdExtD, HasStdExtZfinx, IsRV32] Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfhinx.td =================================================================== --- /dev/null +++ llvm/lib/Target/RISCV/RISCVInstrInfoZfhinx.td @@ -0,0 +1,187 @@ +//===- RISCVInstrInfoZfinx.td - RISC-V 'Zfhinx' instructions -*- tblgen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard 'Zfhinx' +// half float in integer. +// This version is still experimental as the 'Zfhinx' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction class templates +//===----------------------------------------------------------------------===// + +def GPRF16Op : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +let DecoderNamespace = "RVZfinx" in { + +// Zfhinx extension on RV32/64 +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPFMAHINX_rrr_frm + : RVInstR4<0b10, opcode, (outs GPRF16Op:$rd), + (ins GPRF16Op:$rs1, GPRF16Op:$rs2, GPRF16Op:$rs3, frmarg:$funct3), + opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUHINX_rr funct7, bits<3> funct3, string opcodestr> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUHINX_rr_frm funct7, string opcodestr> + : RVInstRFrm; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPCmpHINX_rr funct3, string opcodestr> + : RVInstR<0b1010010, funct3, OPC_OP_FP, (outs GPROp:$rd), + (ins GPRF16Op:$rs1, GPRF16Op:$rs2), opcodestr, "$rd, $rs1, $rs2">, + Sched<[]>; +} + +class FPFMAHINXDynFrmAlias + : InstAlias; + +class FPALUHINXDynFrmAlias + : InstAlias; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +// instructions in Zfhinx extension on RV32/64 +let Predicates = [HasStdExtZfhinx] in { +def FMADD_H_INX : FPFMAHINX_rrr_frm, Sched<[]>; +def : FPFMAHINXDynFrmAlias; +def FMSUB_H_INX : FPFMAHINX_rrr_frm, Sched<[]>; +def : FPFMAHINXDynFrmAlias; +def FNMSUB_H_INX : FPFMAHINX_rrr_frm, Sched<[]>; +def : FPFMAHINXDynFrmAlias; +def FNMADD_H_INX : FPFMAHINX_rrr_frm, Sched<[]>; +def : FPFMAHINXDynFrmAlias; + +def FADD_H_INX : FPALUHINX_rr_frm<0b0000010, "fadd.h">, Sched<[]>; +def : FPALUHINXDynFrmAlias; +def FSUB_H_INX : FPALUHINX_rr_frm<0b0000110, "fsub.h">, Sched<[]>; +def : FPALUHINXDynFrmAlias; +def FMUL_H_INX : FPALUHINX_rr_frm<0b0001010, "fmul.h">, Sched<[]>; +def : FPALUHINXDynFrmAlias; +def FDIV_H_INX : FPALUHINX_rr_frm<0b0001110, "fdiv.h">, Sched<[]>; +def : FPALUHINXDynFrmAlias; + +def FSQRT_H_INX : FPUnaryOpINX_r_frm<0b0101110, GPRF16Op, GPRF16Op, "fsqrt.h">, + Sched<[]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FSGNJ_H_INX : FPALUHINX_rr<0b0010010, 0b000, "fsgnj.h">, Sched<[]>; +def FSGNJN_H_INX : FPALUHINX_rr<0b0010010, 0b001, "fsgnjn.h">, Sched<[]>; +def FSGNJX_H_INX : FPALUHINX_rr<0b0010010, 0b010, "fsgnjx.h">, Sched<[]>; +def FMIN_H_INX : FPALUHINX_rr<0b0010110, 0b000, "fmin.h">, Sched<[]>; +def FMAX_H_INX : FPALUHINX_rr<0b0010110, 0b001, "fmax.h">, Sched<[]>; + +def FCVT_W_H_INX : FPUnaryOpINX_r_frm<0b1100010, GPROp, GPRF16Op, "fcvt.w.h">, + Sched<[]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_WU_H_INX : FPUnaryOpINX_r_frm<0b1100010, GPROp, GPRF16Op, "fcvt.wu.h">, + Sched<[]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_H_W_INX : FPUnaryOpINX_r_frm<0b1101010, GPRF16Op, GPROp, "fcvt.h.w">, + Sched<[]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_H_W_INXU : FPUnaryOpINX_r_frm<0b1101010, GPRF16Op, GPROp, "fcvt.h.wu">, + Sched<[]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_H_S_INX : FPUnaryOpINX_r_frm<0b0100010, GPRF16Op, GPRF32Op, "fcvt.h.s">, + Sched<[]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_S_H_INX : FPUnaryOpINX_r<0b0100000, 0b000, GPRF32Op, GPRF16Op, "fcvt.s.h">, + Sched<[]> { + let rs2 = 0b00010; +} + +def FEQ_H_INX : FPCmpHINX_rr<0b010, "feq.h">; +def FLT_H_INX : FPCmpHINX_rr<0b001, "flt.h">; +def FLE_H_INX : FPCmpHINX_rr<0b000, "fle.h">; + +def FCLASS_H_INX : FPUnaryOpINX_r<0b1110010, 0b001, GPRF16Op, GPRF16Op, "fclass.h">, + Sched<[]> { + let rs2 = 0b00000; +} + +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 = [HasStdExtZfhinx] + +// Instructions in Zfinx extension on RV64 +let Predicates = [HasStdExtZfhinx, IsRV64] in { +def FCVT_L_H_INX : FPUnaryOpINX_r_frm<0b1100010, GPROp, GPRF16Op, "fcvt.l.h">, + Sched<[]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_LU_H_INX : FPUnaryOpINX_r_frm<0b1100010, GPROp, GPRF16Op, "fcvt.lu.h">, + Sched<[]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_H_L_INX : FPUnaryOpINX_r_frm<0b1101010, GPRF16Op, GPROp, "fcvt.h.l">, + Sched<[]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def ZFCVT_H_LU_INX : FPUnaryOpINX_r_frm<0b1101010, GPRF16Op, GPROp, "fcvt.h.lu">, + Sched<[]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; +} // Predicates = [HasStdExtZfhinx, IsRV64] + +// instructions in Zfinx and Zfdinx extensions +let Predicates = [HasStdExtZfhinx, HasStdExtZfdinx] in { +def FCVT_H_D_INX : FPUnaryOpINX_r_frm<0b0100010, GPRF16Op, GPRF64Op, "fcvt.h.d">, + Sched<[]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_D_H_INX : FPUnaryOpINX_r<0b0100001, 0b000, GPRF64Op, GPRF16Op, "fcvt.d.h">, + Sched<[]> { + let rs2 = 0b00010; +} +} // Predicates = [HasStdExtZfhinx, HasStdExtZfdinx] Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfinx.td =================================================================== --- /dev/null +++ llvm/lib/Target/RISCV/RISCVInstrInfoZfinx.td @@ -0,0 +1,204 @@ +//=== RISCVInstrInfoZfinx.td - RISC-V 'Zfinx' instructions -*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard 'Zfinx' +// float in integer. +// This version is still experimental as the 'Zfinx' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction class templates +//===----------------------------------------------------------------------===// + +def GPRAsFPR : AsmOperandClass { + let Name = "GPRAsFPR"; + let ParserMethod = "parseGPRAsFPR"; +} + +def GPRF32Op : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +def GPROp : RegisterOperand { + let ParserMatchClass = GPRAsFPR; +} + +let DecoderNamespace = "RVZfinx" in { +// For all floating extension + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPUnaryOpINX_r funct7, bits<3> funct3, RegisterOperand rdty, + RegisterOperand rs1ty, string opcodestr> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPUnaryOpINX_r_frm funct7, RegisterOperand rdty, RegisterOperand rs1ty, + string opcodestr> + : RVInstRFrm; + +// Zfinx extension on RV32/64 +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPFMASINX_rrr_frm + : RVInstR4<0b00, opcode, (outs GPRF32Op:$rd), + (ins GPRF32Op:$rs1, GPRF32Op:$rs2, GPRF32Op:$rs3, frmarg:$funct3), + opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUSINX_rr funct7, bits<3> funct3, string opcodestr> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPALUSINX_rr_frm funct7, string opcodestr> + : RVInstRFrm; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class FPCmpSINX_rr funct3, string opcodestr> + : RVInstR<0b1010000, funct3, OPC_OP_FP, (outs GPROp:$rd), + (ins GPRF32Op:$rs1, GPRF32Op:$rs2), opcodestr, "$rd, $rs1, $rs2">, + Sched<[WriteFCmp32, ReadFCmp32, ReadFCmp32]>; + +} // DecoderNamespace = "RVZfinx" + +class FPUnaryOpINXDynFrmAlias + : InstAlias; + +class FPFMASINXDynFrmAlias + : InstAlias; + +class FPALUSINXDynFrmAlias + : InstAlias; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +// Instructions in Zfinx extension on RV32/64 +let Predicates = [HasStdExtZfinx] in { +def FMADD_S_INX : FPFMASINX_rrr_frm, + Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; +def : FPFMASINXDynFrmAlias; +def FMSUB_S_INX : FPFMASINX_rrr_frm, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +def : FPFMASINXDynFrmAlias; +def FNMSUB_S_INX : FPFMASINX_rrr_frm, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +def : FPFMASINXDynFrmAlias; +def FNMADD_S_INX : FPFMASINX_rrr_frm, + Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; +def : FPFMASINXDynFrmAlias; + +def FADD_S_INX : FPALUSINX_rr_frm<0b0000000, "fadd.s">, + Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; +def : FPALUSINXDynFrmAlias; +def FSUB_S_INX : FPALUSINX_rr_frm<0b0000100, "fsub.s">, + Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; +def : FPALUSINXDynFrmAlias; +def FMUL_S_INX : FPALUSINX_rr_frm<0b0001000, "fmul.s">, + Sched<[WriteFMul32, ReadFMul32, ReadFMul32]>; +def : FPALUSINXDynFrmAlias; +def FDIV_S_INX : FPALUSINX_rr_frm<0b0001100, "fdiv.s">, + Sched<[WriteFDiv32, ReadFDiv32, ReadFDiv32]>; +def : FPALUSINXDynFrmAlias; + +def FSQRT_S_INX : FPUnaryOpINX_r_frm<0b0101100, GPRF32Op, GPRF32Op, "fsqrt.s">, + Sched<[]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FSGNJ_S_INX : FPALUSINX_rr<0b0010000, 0b000, "fsgnj.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +def FSGNJN_S_INX : FPALUSINX_rr<0b0010000, 0b001, "fsgnjn.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +def FSGNJX_S_INX : FPALUSINX_rr<0b0010000, 0b010, "fsgnjx.s">, + Sched<[WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32]>; +def FMIN_S_INX : FPALUSINX_rr<0b0010100, 0b000, "fmin.s">, + Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; +def FMAX_S_INX : FPALUSINX_rr<0b0010100, 0b001, "fmax.s">, + Sched<[WriteFMinMax32, ReadFMinMax32, ReadFMinMax32]>; + +def FCVT_W_S_INX : FPUnaryOpINX_r_frm<0b1100000, GPROp, GPRF32Op, "fcvt.w.s">, + Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_WU_S_INX : FPUnaryOpINX_r_frm<0b1100000, GPROp, GPRF32Op, "fcvt.wu.s">, + Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +def FEQ_S_INX : FPCmpSINX_rr<0b010, "feq.s">; +def FLT_S_INX : FPCmpSINX_rr<0b001, "flt.s">; +def FLE_S_INX : FPCmpSINX_rr<0b000, "fle.s">; + +def FCLASS_S_INX : FPUnaryOpINX_r<0b1110000, 0b001, GPRF32Op, GPRF32Op, "fclass.s">, + Sched<[WriteFClass32, ReadFClass32]> { + let rs2 = 0b00000; +} + +def FCVT_S_W_INX : FPUnaryOpINX_r_frm<0b1101000, GPRF32Op, GPROp, "fcvt.s.w">, + Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]> { + let rs2 = 0b00000; +} +def : FPUnaryOpINXDynFrmAlias; + +def ZFCVT_S_WU_INX : FPUnaryOpINX_r_frm<0b1101000, GPRF32Op, GPROp, "fcvt.s.wu">, + Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]> { + let rs2 = 0b00001; +} +def : FPUnaryOpINXDynFrmAlias; + +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] + +// Instructions in Zfinx extension on RV64 +let Predicates = [HasStdExtZfinx, IsRV64] in { +def FCVT_L_S_INX : FPUnaryOpINX_r_frm<0b1100000, GPROp, GPRF32Op, "fcvt.l.s">, + Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_LU_S_INX : FPUnaryOpINX_r_frm<0b1100000, GPROp, GPRF32Op, "fcvt.lu.s">, + Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; + +def FCVT_S_L_INX : FPUnaryOpINX_r_frm<0b1101000, GPRF32Op, GPROp, "fcvt.s.l">, + Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]> { + let rs2 = 0b00010; +} +def : FPUnaryOpINXDynFrmAlias; + +def ZFCVT_S_LU_INX : FPUnaryOpINX_r_frm<0b1101000, GPRF32Op, GPROp, "fcvt.s.lu">, + Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]> { + let rs2 = 0b00011; +} +def : FPUnaryOpINXDynFrmAlias; +} // Predicates = [HasStdExtZfinx, IsRV64] Index: llvm/lib/Target/RISCV/RISCVRegisterInfo.td =================================================================== --- llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -57,6 +57,8 @@ def sub_vrm4_hi : SubRegIndex<128, -1>; def sub_vrm8 : SubRegIndex<256, -1>; def sub_vrm8_hi : SubRegIndex<256, -1>; + +def sub_32_hi : SubRegIndex<32, 32>; } // Namespace = "RISCV" // Integer registers @@ -452,3 +454,52 @@ def VMV0 : RegisterClass<"RISCV", VMaskVTs, 64, (add V0)> { 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) +)>; + +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) +)>; + +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) +)>; + +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 +)>; Index: llvm/lib/Target/RISCV/RISCVSubtarget.h =================================================================== --- llvm/lib/Target/RISCV/RISCVSubtarget.h +++ llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -54,6 +54,9 @@ bool HasStdExtZvlsseg = false; bool HasStdExtZvamo = false; bool HasStdExtZfh = false; + bool HasStdExtZfinx = false; + bool HasStdExtZfdinx = false; + bool HasStdExtZfhinx = false; bool HasRV64 = false; bool IsRV32E = false; bool EnableLinkerRelax = false; @@ -120,6 +123,9 @@ bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; } bool hasStdExtZvamo() const { return HasStdExtZvamo; } bool hasStdExtZfh() const { return HasStdExtZfh; } + bool hasStdExtZfinx() const { return HasStdExtZfinx; } + bool hasStdExtZfdinx() const { return HasStdExtZfdinx; } + bool hasStdExtZfhinx() const { return HasStdExtZfhinx; } bool is64Bit() const { return HasRV64; } bool isRV32E() const { return IsRV32E; } bool enableLinkerRelax() const { return EnableLinkerRelax; } Index: llvm/test/MC/RISCV/rv32i-invalid.s =================================================================== --- llvm/test/MC/RISCV/rv32i-invalid.s +++ llvm/test/MC/RISCV/rv32i-invalid.s @@ -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.h a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfhinx' (Half Float in Integer) +fadd.s a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfinx' (Float in Integer) +fadd.d a0, a0, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfdinx' (Double in Integer) # Using floating point registers when integer registers are expected addi a2, ft0, 24 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction Index: llvm/test/MC/RISCV/rv32zfdinx-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfdinx-invalid.s @@ -0,0 +1,11 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfdinx < %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 Index: llvm/test/MC/RISCV/rv32zfdinx-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfdinx-valid.s @@ -0,0 +1,156 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfdinx -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-zfdinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfdinx -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-zfdinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfdinx -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 Index: llvm/test/MC/RISCV/rv32zfhinx-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfhinx-invalid.s @@ -0,0 +1,11 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfhinx < %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 Index: llvm/test/MC/RISCV/rv32zfhinx-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfhinx-valid.s @@ -0,0 +1,160 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfhinx -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhinx -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-zfhinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zfhinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,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 Index: llvm/test/MC/RISCV/rv32zfinx-invalid.s =================================================================== --- /dev/null +++ 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: 'Zfdinx' (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 Index: llvm/test/MC/RISCV/rv32zfinx-valid.s =================================================================== --- /dev/null +++ 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 Index: llvm/test/MC/RISCV/rv64zfdinx-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv64zfdinx-invalid.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zfdinx < %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 Index: llvm/test/MC/RISCV/rv64zfdinx-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv64zfdinx-valid.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfdinx -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-zfdinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfdinx -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfdinx < %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 Index: llvm/test/MC/RISCV/rv64zfhinx-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv64zfhinx-invalid.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zfdinx < %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 Index: llvm/test/MC/RISCV/rv64zfhinx-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv64zfhinx-valid.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhinx -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-zfhinx < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfhinx -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfhinx < %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 Index: llvm/test/MC/RISCV/rv64zfinx-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv64zfinx-invalid.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zfdinx < %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 Index: llvm/test/MC/RISCV/rv64zfinx-valid.s =================================================================== --- /dev/null +++ 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 Index: llvm/test/MC/RISCV/rvzfdinx-aliases-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rvzfdinx-aliases-valid.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfdinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfdinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfdinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfdinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfdinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfdinx - \ +# 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{{[[:space:]]}} +fcvt.l.d a0, t0 +# CHECK-INST: fcvt.lu.d a1, t1, dyn +# CHECK-ALIAS: fcvt.lu.d a1, t1{{[[:space:]]}} +fcvt.lu.d a1, t1 +# CHECK-INST: fcvt.d.l t3, a3, dyn +# CHECK-ALIAS: fcvt.d.l t3, a3{{[[:space:]]}} +fcvt.d.l t3, a3 +# CHECK-INST: fcvt.d.lu t4, a4, dyn +# CHECK-ALIAS: fcvt.d.lu t4, a4{{[[:space:]]}} +fcvt.d.lu t4, a4 Index: llvm/test/MC/RISCV/rvzfhinx-aliases-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rvzfhinx-aliases-valid.s @@ -0,0 +1,83 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhinx -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhinx \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zfhinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zfhinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfhinx - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfhinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfhinx -M no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zfhinx < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zfhinx - \ +# 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{{[[:space:]]}} +fmadd.h x10, x11, x12, x13 +# CHECK-INST: fmsub.h a4, a5, a6, a7, dyn +# CHECK-ALIAS: fmsub.h a4, a5, a6, a7{{[[:space:]]}} +fmsub.h x14, x15, x16, x17 +# CHECK-INST: fnmsub.h s2, s3, s4, s5, dyn +# CHECK-ALIAS: fnmsub.h s2, s3, s4, s5{{[[:space:]]}} +fnmsub.h x18, x19, x20, x21 +# CHECK-INST: fnmadd.h s6, s7, s8, s9, dyn +# CHECK-ALIAS: fnmadd.h s6, s7, s8, s9{{[[:space:]]}} +fnmadd.h x22, x23, x24, x25 +# CHECK-INST: fadd.h s10, s11, t3, dyn +# CHECK-ALIAS: fadd.h s10, s11, t3{{[[:space:]]}} +fadd.h x26, x27, x28 +# CHECK-INST: fsub.h t4, t5, t6, dyn +# CHECK-ALIAS: fsub.h t4, t5, t6{{[[:space:]]}} +fsub.h x29, x30, x31 +# CHECK-INST: fmul.h s0, s1, s2, dyn +# CHECK-ALIAS: fmul.h s0, s1, s2{{[[:space:]]}} +fmul.h s0, s1, s2 +# CHECK-INST: fdiv.h s3, s4, s5, dyn +# CHECK-ALIAS: fdiv.h s3, s4, s5{{[[:space:]]}} +fdiv.h s3, s4, s5 +# CHECK-INST: fsqrt.h s6, s7, dyn +# CHECK-ALIAS: fsqrt.h s6, s7{{[[:space:]]}} +fsqrt.h s6, s7 +# CHECK-INST: fcvt.w.h a0, s5, dyn +# CHECK-ALIAS: fcvt.w.h a0, s5{{[[:space:]]}} +fcvt.w.h a0, s5 +# CHECK-INST: fcvt.wu.h a1, s6, dyn +# CHECK-ALIAS: fcvt.wu.h a1, s6{{[[:space:]]}} +fcvt.wu.h a1, s6 +# CHECK-INST: fcvt.h.w t6, a4, dyn +# CHECK-ALIAS: fcvt.h.w t6, a4{{[[:space:]]}} +fcvt.h.w t6, a4 +# CHECK-INST: fcvt.h.wu s0, a5, dyn +# CHECK-ALIAS: fcvt.h.wu s0, a5{{[[:space:]]}} +fcvt.h.wu s0, a5 Index: llvm/test/MC/RISCV/rvzfinx-aliases-valid.s =================================================================== --- /dev/null +++ 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{{[[:space:]]}} +fmadd.s x10, x11, x12, x13 +# CHECK-INST: fmsub.s a4, a5, a6, a7, dyn +# CHECK-ALIAS: fmsub.s a4, a5, a6, a7{{[[:space:]]}} +fmsub.s x14, x15, x16, x17 +# CHECK-INST: fnmsub.s s2, s3, s4, s5, dyn +# CHECK-ALIAS: fnmsub.s s2, s3, s4, s5{{[[:space:]]}} +fnmsub.s x18, x19, x20, x21 +# CHECK-INST: fnmadd.s s6, s7, s8, s9, dyn +# CHECK-ALIAS: fnmadd.s s6, s7, s8, s9{{[[:space:]]}} +fnmadd.s x22, x23, x24, x25 +# CHECK-INST: fadd.s s10, s11, t3, dyn +# CHECK-ALIAS: fadd.s s10, s11, t3{{[[:space:]]}} +fadd.s x26, x27, x28 +# CHECK-INST: fsub.s t4, t5, t6, dyn +# CHECK-ALIAS: fsub.s t4, t5, t6{{[[:space:]]}} +fsub.s x29, x30, x31 +# CHECK-INST: fmul.s s0, s1, s2, dyn +# CHECK-ALIAS: fmul.s s0, s1, s2{{[[:space:]]}} +fmul.s s0, s1, s2 +# CHECK-INST: fdiv.s s3, s4, s5, dyn +# CHECK-ALIAS: fdiv.s s3, s4, s5{{[[:space:]]}} +fdiv.s s3, s4, s5 +# CHECK-INST: sqrt.s s6, s7, dyn +# CHECK-ALIAS: sqrt.s s6, s7{{[[:space:]]}} +fsqrt.s s6, s7 +# CHECK-INST: fcvt.w.s a0, s5, dyn +# CHECK-ALIAS: fcvt.w.s a0, s5{{[[:space:]]}} +fcvt.w.s a0, s5 +# CHECK-INST: fcvt.wu.s a1, s6, dyn +# CHECK-ALIAS: fcvt.wu.s a1, s6{{[[:space:]]}} +fcvt.wu.s a1, s6 +# CHECK-INST: fcvt.s.w t6, a4, dyn +# CHECK-ALIAS: fcvt.s.w t6, a4{{[[:space:]]}} +fcvt.s.w t6, a4 +# CHECK-INST: fcvt.s.wu s0, a5, dyn +# CHECK-ALIAS: fcvt.s.wu s0, a5{{[[:space:]]}} +fcvt.s.wu s0, a5