215 changes: 148 additions & 67 deletions llvm/lib/Target/RISCV/RISCVInstrInfoD.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,69 @@ def SDT_RISCVSplitF64 : SDTypeProfile<2, 1, [SDTCisVT<0, i32>,
def RISCVBuildPairF64 : SDNode<"RISCVISD::BuildPairF64", SDT_RISCVBuildPairF64>;
def RISCVSplitF64 : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>;

//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//

// Zdinx

def GPRPF64AsFPR : AsmOperandClass {
let Name = "GPRPF64AsFPR";
let ParserMethod = "parseGPRAsFPR";
let RenderMethod = "addRegOperands";
}

def GPRF64AsFPR : AsmOperandClass {
let Name = "GPRF64AsFPR";
let ParserMethod = "parseGPRAsFPR";
let RenderMethod = "addRegOperands";
}

def FPR64INX : RegisterOperand<GPRF64> {
let ParserMatchClass = GPRF64AsFPR;
let DecoderMethod = "DecodeGPRRegisterClass";
}

def FPR64IN32X : RegisterOperand<GPRPF64> {
let ParserMatchClass = GPRPF64AsFPR;
}

def DExt : ExtInfo<0, [HasStdExtD]>;
def D64Ext : ExtInfo<0, [HasStdExtD, IsRV64]>;
def ZdinxExt : ExtInfo<1, [HasStdExtZdinx, IsRV64]>;
def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>;

def D : ExtInfo_r<DExt, FPR64>;
def D_INX : ExtInfo_r<ZdinxExt, FPR64INX>;
def D_IN32X : ExtInfo_r<Zdinx32Ext, FPR64IN32X>;

def DD : ExtInfo_rr<DExt, FPR64, FPR64>;
def DD_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR64INX>;
def DD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR64IN32X>;
def DF : ExtInfo_rr<DExt, FPR64, FPR32>;
def DF_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR32INX>;
def DF_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR32INX>;
def DX : ExtInfo_rr<DExt, FPR64, GPR>;
def DX_INX : ExtInfo_rr<ZdinxExt, FPR64INX, GPR>;
def DX_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, GPR>;
def DX_64 : ExtInfo_rr<D64Ext, FPR64, GPR>;
def FD : ExtInfo_rr<DExt, FPR32, FPR64>;
def FD_INX : ExtInfo_rr<ZdinxExt, FPR32INX, FPR64INX>;
def FD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR32INX, FPR64IN32X>;
def XD : ExtInfo_rr<DExt, GPR, FPR64>;
def XD_INX : ExtInfo_rr<ZdinxExt, GPR, FPR64INX>;
def XD_IN32X : ExtInfo_rr<Zdinx32Ext, GPR, FPR64IN32X>;
def XD_64 : ExtInfo_rr<D64Ext, GPR, FPR64>;

defvar DINX = [D, D_INX, D_IN32X];
defvar DDINX = [DD, DD_INX, DD_IN32X];
defvar DXINX = [DX, DX_INX, DX_IN32X];
defvar DFINX = [DF, DF_INX, DF_IN32X];
defvar FDINX = [FD, FD_INX, FD_IN32X];
defvar XDINX = [XD, XD_INX, XD_IN32X];
defvar DXIN64X = [DX_64, DX_INX];
defvar XDIN64X = [XD_64, XD_INX];

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
Expand All @@ -36,106 +99,104 @@ def FLD : FPLoad_r<0b011, "fld", FPR64, WriteFLD64>;
// reflecting the order these fields are specified in the instruction
// encoding.
def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>;
} // Predicates = [HasStdExtD]

let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
def FMADD_D : FPFMA_rrr_frm<OPC_MADD, 0b01, "fmadd.d", FPR64>;
def FMSUB_D : FPFMA_rrr_frm<OPC_MSUB, 0b01, "fmsub.d", FPR64>;
def FNMSUB_D : FPFMA_rrr_frm<OPC_NMSUB, 0b01, "fnmsub.d", FPR64>;
def FNMADD_D : FPFMA_rrr_frm<OPC_NMADD, 0b01, "fnmadd.d", FPR64>;
defm FMADD_D : FPFMA_rrr_frm_m<OPC_MADD, 0b01, "fmadd.d", DINX>;
defm FMSUB_D : FPFMA_rrr_frm_m<OPC_MSUB, 0b01, "fmsub.d", DINX>;
defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", DINX>;
defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", DINX>;
}

defm : FPFMADynFrmAlias_m<FMADD_D, "fmadd.d", DINX>;
defm : FPFMADynFrmAlias_m<FMSUB_D, "fmsub.d", DINX>;
defm : FPFMADynFrmAlias_m<FNMSUB_D, "fnmsub.d", DINX>;
defm : FPFMADynFrmAlias_m<FNMADD_D, "fnmadd.d", DINX>;

let SchedRW = [WriteFALU64, ReadFALU64, ReadFALU64] in {
defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX>;
defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>;
}
let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX>;

def : FPFMADynFrmAlias<FMADD_D, "fmadd.d", FPR64>;
def : FPFMADynFrmAlias<FMSUB_D, "fmsub.d", FPR64>;
def : FPFMADynFrmAlias<FNMSUB_D, "fnmsub.d", FPR64>;
def : FPFMADynFrmAlias<FNMADD_D, "fnmadd.d", FPR64>;

def FADD_D : FPALU_rr_frm<0b0000001, "fadd.d", FPR64>,
Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>;
def FSUB_D : FPALU_rr_frm<0b0000101, "fsub.d", FPR64>,
Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>;
def FMUL_D : FPALU_rr_frm<0b0001001, "fmul.d", FPR64>,
Sched<[WriteFMul64, ReadFMul64, ReadFMul64]>;
def FDIV_D : FPALU_rr_frm<0b0001101, "fdiv.d", FPR64>,
Sched<[WriteFDiv64, ReadFDiv64, ReadFDiv64]>;

def : FPALUDynFrmAlias<FADD_D, "fadd.d", FPR64>;
def : FPALUDynFrmAlias<FSUB_D, "fsub.d", FPR64>;
def : FPALUDynFrmAlias<FMUL_D, "fmul.d", FPR64>;
def : FPALUDynFrmAlias<FDIV_D, "fdiv.d", FPR64>;

def FSQRT_D : FPUnaryOp_r_frm<0b0101101, 0b00000, FPR64, FPR64, "fsqrt.d">,
Sched<[WriteFSqrt64, ReadFSqrt64]>;
def : FPUnaryOpDynFrmAlias<FSQRT_D, "fsqrt.d", FPR64, FPR64>;
let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>;

defm : FPALUDynFrmAlias_m<FADD_D, "fadd.d", DINX>;
defm : FPALUDynFrmAlias_m<FSUB_D, "fsub.d", DINX>;
defm : FPALUDynFrmAlias_m<FMUL_D, "fmul.d", DINX>;
defm : FPALUDynFrmAlias_m<FDIV_D, "fdiv.d", DINX>;

defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, DDINX, "fsqrt.d">,
Sched<[WriteFSqrt64, ReadFSqrt64]>;
defm : FPUnaryOpDynFrmAlias_m<FSQRT_D, "fsqrt.d", DDINX>;

let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
mayRaiseFPException = 0 in {
def FSGNJ_D : FPALU_rr<0b0010001, 0b000, "fsgnj.d", FPR64>;
def FSGNJN_D : FPALU_rr<0b0010001, 0b001, "fsgnjn.d", FPR64>;
def FSGNJX_D : FPALU_rr<0b0010001, 0b010, "fsgnjx.d", FPR64>;
defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", DINX>;
defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", DINX>;
defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>;
}

let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
def FMIN_D : FPALU_rr<0b0010101, 0b000, "fmin.d", FPR64>;
def FMAX_D : FPALU_rr<0b0010101, 0b001, "fmax.d", FPR64>;
defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX>;
defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX>;
}

def FCVT_S_D : FPUnaryOp_r_frm<0b0100000, 0b00001, FPR32, FPR64, "fcvt.s.d">,
Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
def : FPUnaryOpDynFrmAlias<FCVT_S_D, "fcvt.s.d", FPR32, FPR64>;
defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">,
Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_S_D, "fcvt.s.d", FDINX>;

def FCVT_D_S : FPUnaryOp_r<0b0100001, 0b00000, 0b000, FPR64, FPR32, "fcvt.d.s">,
Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">,
Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;

let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
def FEQ_D : FPCmp_rr<0b1010001, 0b010, "feq.d", FPR64>;
def FLT_D : FPCmp_rr<0b1010001, 0b001, "flt.d", FPR64>;
def FLE_D : FPCmp_rr<0b1010001, 0b000, "fle.d", FPR64>;
defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX>;
defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>;
defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>;
}

let mayRaiseFPException = 0 in
def FCLASS_D : FPUnaryOp_r<0b1110001, 0b00000, 0b001, GPR, FPR64, "fclass.d">,
Sched<[WriteFClass64, ReadFClass64]>;
defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, XDINX, "fclass.d">,
Sched<[WriteFClass64, ReadFClass64]>;

def FCVT_W_D : FPUnaryOp_r_frm<0b1100001, 0b00000, GPR, FPR64, "fcvt.w.d">,
defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, XDINX, "fcvt.w.d">,
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
def : FPUnaryOpDynFrmAlias<FCVT_W_D, "fcvt.w.d", GPR, FPR64>;

def FCVT_WU_D : FPUnaryOp_r_frm<0b1100001, 0b00001, GPR, FPR64, "fcvt.wu.d">,
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
def : FPUnaryOpDynFrmAlias<FCVT_WU_D, "fcvt.wu.d", GPR, FPR64>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_W_D, "fcvt.w.d", XDINX>;

def FCVT_D_W : FPUnaryOp_r<0b1101001, 0b00000, 0b000, FPR64, GPR, "fcvt.d.w">,
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, XDINX, "fcvt.wu.d">,
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_WU_D, "fcvt.wu.d", XDINX>;

def FCVT_D_WU : FPUnaryOp_r<0b1101001, 0b00001, 0b000, FPR64, GPR, "fcvt.d.wu">,
defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, DXINX, "fcvt.d.w">,
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
} // Predicates = [HasStdExtD]

let Predicates = [HasStdExtD, IsRV64] in {
def FCVT_L_D : FPUnaryOp_r_frm<0b1100001, 0b00010, GPR, FPR64, "fcvt.l.d">,
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
def : FPUnaryOpDynFrmAlias<FCVT_L_D, "fcvt.l.d", GPR, FPR64>;
defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, DXINX, "fcvt.d.wu">,
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;

def FCVT_LU_D : FPUnaryOp_r_frm<0b1100001, 0b00011, GPR, FPR64, "fcvt.lu.d">,
defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, XDIN64X, "fcvt.l.d">,
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
def : FPUnaryOpDynFrmAlias<FCVT_LU_D, "fcvt.lu.d", GPR, FPR64>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_L_D, "fcvt.l.d", XDIN64X>;

let mayRaiseFPException = 0 in
defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, XDIN64X, "fcvt.lu.d">,
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_LU_D, "fcvt.lu.d", XDIN64X>;

let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
def FMV_X_D : FPUnaryOp_r<0b1110001, 0b00000, 0b000, GPR, FPR64, "fmv.x.d">,
Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;

def FCVT_D_L : FPUnaryOp_r_frm<0b1101001, 0b00010, FPR64, GPR, "fcvt.d.l">,
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
def : FPUnaryOpDynFrmAlias<FCVT_D_L, "fcvt.d.l", FPR64, GPR>;

def FCVT_D_LU : FPUnaryOp_r_frm<0b1101001, 0b00011, FPR64, GPR, "fcvt.d.lu">,
defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, DXIN64X, "fcvt.d.l">,
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
def : FPUnaryOpDynFrmAlias<FCVT_D_LU, "fcvt.d.lu", FPR64, GPR>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_D_L, "fcvt.d.l", DXIN64X>;

let mayRaiseFPException = 0 in
defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, DXIN64X, "fcvt.d.lu">,
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_D_LU, "fcvt.d.lu", DXIN64X>;

let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
def FMV_D_X : FPUnaryOp_r<0b1111001, 0b00000, 0b000, FPR64, GPR, "fmv.d.x">,
Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>;
} // Predicates = [HasStdExtD, IsRV64]

//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
Expand Down Expand Up @@ -164,6 +225,26 @@ def PseudoQuietFLT_D : PseudoQuietFCMP<FPR64>;
}
} // Predicates = [HasStdExtD]

let Predicates = [HasStdExtZdinx, IsRV64] in {
def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>;
def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_INX FPR64INX:$rd, FPR64INX:$rs, FPR64INX:$rs)>;

def : InstAlias<"fgt.d $rd, $rs, $rt",
(FLT_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>;
def : InstAlias<"fge.d $rd, $rs, $rt",
(FLE_D_INX GPR:$rd, FPR64INX:$rt, FPR64INX:$rs), 0>;
} // Predicates = [HasStdExtZdinx, IsRV64]

let Predicates = [HasStdExtZdinx, IsRV32] in {
def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>;
def : InstAlias<"fneg.d $rd, $rs", (FSGNJN_D_IN32X FPR64IN32X:$rd, FPR64IN32X:$rs, FPR64IN32X:$rs)>;

def : InstAlias<"fgt.d $rd, $rs, $rt",
(FLT_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>;
def : InstAlias<"fge.d $rd, $rs, $rt",
(FLE_D_IN32X GPR:$rd, FPR64IN32X:$rt, FPR64IN32X:$rs), 0>;
} // Predicates = [HasStdExtZdinx, IsRV32]

//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//
Expand Down
281 changes: 209 additions & 72 deletions llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Large diffs are not rendered by default.

213 changes: 136 additions & 77 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,62 @@ def riscv_fmv_x_anyexth
def riscv_fmv_x_signexth
: SDNode<"RISCVISD::FMV_X_SIGNEXTH", SDT_RISCVFMV_X_EXTH>;

//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//

// Zhinxmin and Zhinx

def FPR16INX : RegisterOperand<GPRF16> {
let ParserMatchClass = GPRAsFPR;
let DecoderMethod = "DecodeGPRRegisterClass";
}

def ZfhExt : ExtInfo<0, [HasStdExtZfh]>;
def Zfh64Ext : ExtInfo<0, [HasStdExtZfh, IsRV64]>;
def ZfhminExt : ExtInfo<0, [HasStdExtZfhOrZfhmin]>;
def ZhinxExt : ExtInfo<1, [HasStdExtZhinx]>;
def ZhinxminExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin]>;
def Zhinx64Ext : ExtInfo<1, [HasStdExtZhinx, IsRV64]>;

def ZfhminDExt : ExtInfo<0, [HasStdExtZfhOrZfhmin, HasStdExtD]>;
def ZhinxminZdinxExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx]>;

def H : ExtInfo_r<ZfhExt, FPR16>;
def H_INX : ExtInfo_r<ZhinxExt, FPR16INX>;

def HH : ExtInfo_rr<ZfhExt, FPR16, FPR16>;
def HH_INX : ExtInfo_rr<ZhinxExt, FPR16INX, FPR16INX>;
def XH : ExtInfo_rr<ZfhExt, GPR, FPR16>;
def XH_INX : ExtInfo_rr<ZhinxExt, GPR, FPR16INX>;
def HX : ExtInfo_rr<ZfhExt, FPR16, GPR>;
def HX_INX : ExtInfo_rr<ZhinxExt, FPR16INX, GPR>;
def XH_64 : ExtInfo_rr<Zfh64Ext, GPR, FPR16>;
def HX_64 : ExtInfo_rr<Zfh64Ext, FPR16, GPR>;
def XH_INX_64 : ExtInfo_rr<Zhinx64Ext, GPR, FPR16INX>;
def HX_INX_64 : ExtInfo_rr<Zhinx64Ext, FPR16INX, GPR>;
def HFmin : ExtInfo_rr<ZfhminExt, FPR16, FPR32>;
def HF_INXmin : ExtInfo_rr<ZhinxminExt, FPR16INX, FPR32INX>;
def HF_INX : ExtInfo_rr<ZhinxExt, FPR16INX, FPR32INX>;
def FHmin : ExtInfo_rr<ZfhminExt, FPR32, FPR16>;
def FH_INXmin : ExtInfo_rr<ZhinxminExt, FPR32INX, FPR16INX>;
def FH_INX : ExtInfo_rr<ZhinxExt, FPR32INX, FPR16INX>;
def DHmin : ExtInfo_rr<ZfhminDExt, FPR64, FPR16>;
def DH_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR64INX, FPR16INX>;
def HDmin : ExtInfo_rr<ZfhminDExt, FPR16, FPR64>;
def HD_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR16INX, FPR64INX>;

defvar HINX = [H, H_INX];
defvar HHINX = [HH, HH_INX];
defvar XHINX = [XH, XH_INX];
defvar HXINX = [HX, HX_INX];
defvar XHIN64X = [XH_64, XH_INX_64];
defvar HXIN64X = [HX_64, HX_INX_64];
defvar HFINXmin = [HFmin, HF_INXmin];
defvar FHINXmin = [FHmin, FH_INXmin];
defvar DHINXmin = [DHmin, DH_INXmin];
defvar HDINXmin = [HDmin, HD_INXmin];

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
Expand All @@ -40,74 +96,73 @@ def FLH : FPLoad_r<0b001, "flh", FPR16, WriteFLD16>;
def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>;
} // Predicates = [HasStdExtZfhOrZfhmin]

let Predicates = [HasStdExtZfh] in {
let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in {
def FMADD_H : FPFMA_rrr_frm<OPC_MADD, 0b10, "fmadd.h", FPR16>;
def FMSUB_H : FPFMA_rrr_frm<OPC_MSUB, 0b10, "fmsub.h", FPR16>;
def FNMSUB_H : FPFMA_rrr_frm<OPC_NMSUB, 0b10, "fnmsub.h", FPR16>;
def FNMADD_H : FPFMA_rrr_frm<OPC_NMADD, 0b10, "fnmadd.h", FPR16>;
defm FMADD_H : FPFMA_rrr_frm_m<OPC_MADD, 0b10, "fmadd.h", HINX>;
defm FMSUB_H : FPFMA_rrr_frm_m<OPC_MSUB, 0b10, "fmsub.h", HINX>;
defm FNMSUB_H : FPFMA_rrr_frm_m<OPC_NMSUB, 0b10, "fnmsub.h", HINX>;
defm FNMADD_H : FPFMA_rrr_frm_m<OPC_NMADD, 0b10, "fnmadd.h", HINX>;
}

def : FPFMADynFrmAlias<FMADD_H, "fmadd.h", FPR16>;
def : FPFMADynFrmAlias<FMSUB_H, "fmsub.h", FPR16>;
def : FPFMADynFrmAlias<FNMSUB_H, "fnmsub.h", FPR16>;
def : FPFMADynFrmAlias<FNMADD_H, "fnmadd.h", FPR16>;

def FADD_H : FPALU_rr_frm<0b0000010, "fadd.h", FPR16>,
Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>;
def FSUB_H : FPALU_rr_frm<0b0000110, "fsub.h", FPR16>,
Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>;
def FMUL_H : FPALU_rr_frm<0b0001010, "fmul.h", FPR16>,
Sched<[WriteFMul16, ReadFMul16, ReadFMul16]>;
def FDIV_H : FPALU_rr_frm<0b0001110, "fdiv.h", FPR16>,
Sched<[WriteFDiv16, ReadFDiv16, ReadFDiv16]>;

def : FPALUDynFrmAlias<FADD_H, "fadd.h", FPR16>;
def : FPALUDynFrmAlias<FSUB_H, "fsub.h", FPR16>;
def : FPALUDynFrmAlias<FMUL_H, "fmul.h", FPR16>;
def : FPALUDynFrmAlias<FDIV_H, "fdiv.h", FPR16>;

def FSQRT_H : FPUnaryOp_r_frm<0b0101110, 0b00000, FPR16, FPR16, "fsqrt.h">,
Sched<[WriteFSqrt16, ReadFSqrt16]>;
def : FPUnaryOpDynFrmAlias<FSQRT_H, "fsqrt.h", FPR16, FPR16>;
defm : FPFMADynFrmAlias_m<FMADD_H, "fmadd.h", HINX>;
defm : FPFMADynFrmAlias_m<FMSUB_H, "fmsub.h", HINX>;
defm : FPFMADynFrmAlias_m<FNMSUB_H, "fnmsub.h", HINX>;
defm : FPFMADynFrmAlias_m<FNMADD_H, "fnmadd.h", HINX>;

let SchedRW = [WriteFALU16, ReadFALU16, ReadFALU16] in {
defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX>;
defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", HINX>;
}
let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX>;

let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>;

defm : FPALUDynFrmAlias_m<FADD_H, "fadd.h", HINX>;
defm : FPALUDynFrmAlias_m<FSUB_H, "fsub.h", HINX>;
defm : FPALUDynFrmAlias_m<FMUL_H, "fmul.h", HINX>;
defm : FPALUDynFrmAlias_m<FDIV_H, "fdiv.h", HINX>;

defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, HHINX, "fsqrt.h">,
Sched<[WriteFSqrt16, ReadFSqrt16]>;
defm : FPUnaryOpDynFrmAlias_m<FSQRT_H, "fsqrt.h", HHINX>;

let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16],
mayRaiseFPException = 0 in {
def FSGNJ_H : FPALU_rr<0b0010010, 0b000, "fsgnj.h", FPR16>;
def FSGNJN_H : FPALU_rr<0b0010010, 0b001, "fsgnjn.h", FPR16>;
def FSGNJX_H : FPALU_rr<0b0010010, 0b010, "fsgnjx.h", FPR16>;
defm FSGNJ_H : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h", HINX>;
defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", HINX>;
defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", HINX>;
}

let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
def FMIN_H : FPALU_rr<0b0010110, 0b000, "fmin.h", FPR16>;
def FMAX_H : FPALU_rr<0b0010110, 0b001, "fmax.h", FPR16>;
defm FMIN_H : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX>;
defm FMAX_H : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX>;
}

def FCVT_W_H : FPUnaryOp_r_frm<0b1100010, 0b00000, GPR, FPR16, "fcvt.w.h">,
Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
def : FPUnaryOpDynFrmAlias<FCVT_W_H, "fcvt.w.h", GPR, FPR16>;

def FCVT_WU_H : FPUnaryOp_r_frm<0b1100010, 0b00001, GPR, FPR16, "fcvt.wu.h">,
defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, XHINX, "fcvt.w.h">,
Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
def : FPUnaryOpDynFrmAlias<FCVT_WU_H, "fcvt.wu.h", GPR, FPR16>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_W_H, "fcvt.w.h", XHINX>;

def FCVT_H_W : FPUnaryOp_r_frm<0b1101010, 0b00000, FPR16, GPR, "fcvt.h.w">,
Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_W, "fcvt.h.w", FPR16, GPR>;
defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, XHINX, "fcvt.wu.h">,
Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_WU_H, "fcvt.wu.h", XHINX>;

def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, 0b00001, FPR16, GPR, "fcvt.h.wu">,
defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, HXINX, "fcvt.h.w">,
Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_WU, "fcvt.h.wu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh]
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_W, "fcvt.h.w", HXINX>;

let Predicates = [HasStdExtZfhOrZfhmin] in {
def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, 0b00000, FPR16, FPR32, "fcvt.h.s">,
Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_S, "fcvt.h.s", FPR16, FPR32>;
defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, HXINX, "fcvt.h.wu">,
Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_WU, "fcvt.h.wu", HXINX>;

def FCVT_S_H : FPUnaryOp_r<0b0100000, 0b00010, 0b000, FPR32, FPR16, "fcvt.s.h">,
defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, HFINXmin, "fcvt.h.s">,
Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_S, "fcvt.h.s", HFINXmin>;

defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, FHINXmin, "fcvt.s.h">,
Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;

let Predicates = [HasStdExtZfhOrZfhmin] in {
let mayRaiseFPException = 0 in
def FMV_X_H : FPUnaryOp_r<0b1110010, 0b00000, 0b000, GPR, FPR16, "fmv.x.h">,
Sched<[WriteFMovF16ToI16, ReadFMovF16ToI16]>;
Expand All @@ -117,45 +172,38 @@ def FMV_H_X : FPUnaryOp_r<0b1111010, 0b00000, 0b000, FPR16, GPR, "fmv.h.x">,
Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>;
} // Predicates = [HasStdExtZfhOrZfhmin]

let Predicates = [HasStdExtZfh] in {

let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
def FEQ_H : FPCmp_rr<0b1010010, 0b010, "feq.h", FPR16>;
def FLT_H : FPCmp_rr<0b1010010, 0b001, "flt.h", FPR16>;
def FLE_H : FPCmp_rr<0b1010010, 0b000, "fle.h", FPR16>;
defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX>;
defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", HINX>;
defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", HINX>;
}

let mayRaiseFPException = 0 in
def FCLASS_H : FPUnaryOp_r<0b1110010, 0b00000, 0b001, GPR, FPR16, "fclass.h">,
Sched<[WriteFClass16, ReadFClass16]>;
} // Predicates = [HasStdExtZfh]

let Predicates = [HasStdExtZfh, IsRV64] in {
def FCVT_L_H : FPUnaryOp_r_frm<0b1100010, 0b00010, GPR, FPR16, "fcvt.l.h">,
Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
def : FPUnaryOpDynFrmAlias<FCVT_L_H, "fcvt.l.h", GPR, FPR16>;
defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, XHINX, "fclass.h">,
Sched<[WriteFClass16, ReadFClass16]>;

def FCVT_LU_H : FPUnaryOp_r_frm<0b1100010, 0b00011, GPR, FPR16, "fcvt.lu.h">,
defm FCVT_L_H : FPUnaryOp_r_frm_m<0b1100010, 0b00010, XHIN64X, "fcvt.l.h">,
Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
def : FPUnaryOpDynFrmAlias<FCVT_LU_H, "fcvt.lu.h", GPR, FPR16>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_L_H, "fcvt.l.h", XHIN64X>;

def FCVT_H_L : FPUnaryOp_r_frm<0b1101010, 0b00010, FPR16, GPR, "fcvt.h.l">,
Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_L, "fcvt.h.l", FPR16, GPR>;
defm FCVT_LU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00011, XHIN64X, "fcvt.lu.h">,
Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_LU_H, "fcvt.lu.h", XHIN64X>;

def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, 0b00011, FPR16, GPR, "fcvt.h.lu">,
defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, HXIN64X, "fcvt.h.l">,
Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_LU, "fcvt.h.lu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh, IsRV64]
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_L, "fcvt.h.l", HXIN64X>;

let Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] in {
def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, 0b00001, FPR16, FPR64, "fcvt.h.d">,
Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
def : FPUnaryOpDynFrmAlias<FCVT_H_D, "fcvt.h.d", FPR16, FPR64>;
defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, HXIN64X, "fcvt.h.lu">,
Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_LU, "fcvt.h.lu", HXIN64X>;

def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b00010, 0b000, FPR64, FPR16, "fcvt.d.h">,
Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
} // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD]
defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, HDINXmin, "fcvt.h.d">,
Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
defm : FPUnaryOpDynFrmAlias_m<FCVT_H_D, "fcvt.h.d", HDINXmin>;

defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, DHINXmin, "fcvt.d.h">,
Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;

//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
Expand Down Expand Up @@ -188,6 +236,17 @@ def PseudoQuietFLT_H : PseudoQuietFCMP<FPR16>;
}
} // Predicates = [HasStdExtZfhOrZfhmin]

let Predicates = [HasStdExtZhinx] in {
def : InstAlias<"fmv.h $rd, $rs", (FSGNJ_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;

def : InstAlias<"fgt.h $rd, $rs, $rt",
(FLT_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
def : InstAlias<"fge.h $rd, $rs, $rt",
(FLE_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
} // Predicates = [HasStdExtZhinx]

//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//
Expand Down
30 changes: 30 additions & 0 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def sub_vrm1_5 : ComposedSubRegIndex<sub_vrm2_2, sub_vrm1_1>;
def sub_vrm1_6 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_0>;
def sub_vrm1_7 : ComposedSubRegIndex<sub_vrm2_3, sub_vrm1_1>;

def sub_32_hi : SubRegIndex<32, 32>;
} // Namespace = "RISCV"

// Integer registers
Expand Down Expand Up @@ -534,6 +535,35 @@ def VMV0 : RegisterClass<"RISCV", VMaskVTs, 64, (add V0)> {
let Size = 64;
}

let RegInfos = XLenRI in {
def GPRF16 : RegisterClass<"RISCV", [f16], 16, (add GPR)>;
def GPRF32 : RegisterClass<"RISCV", [f32], 32, (add GPR)>;
def GPRF64 : RegisterClass<"RISCV", [f64], 64, (add GPR)>;
} // RegInfos = XLenRI

let RegAltNameIndices = [ABIRegAltName] in {
foreach Index = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
24, 26, 28, 30] in {
defvar Reg = !cast<Register>("X"#Index);
def X#Index#_PD : RISCVRegWithSubRegs<Index, Reg.AsmName,
[!cast<Register>("X"#Index),
!cast<Register>("X"#!add(Index, 1))],
Reg.AltNames> {
let SubRegIndices = [sub_32, sub_32_hi];
}
}
}

let RegInfos = RegInfoByHwMode<[RV64], [RegInfo<64, 64, 64>]> in
def GPRPF64 : RegisterClass<"RISCV", [f64], 64, (add
X10_PD, X12_PD, X14_PD, X16_PD,
X6_PD,
X28_PD, X30_PD,
X8_PD,
X18_PD, X20_PD, X22_PD, X24_PD, X26_PD,
X0_PD, X2_PD, X4_PD
)>;

// The register class is added for inline assembly for vector mask types.
def VM : VReg<VMaskVTs,
(add (sequence "V%u", 8, 31),
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool HasStdExtZve64d = false;
bool HasStdExtZfhmin = false;
bool HasStdExtZfh = false;
bool HasStdExtZfinx = false;
bool HasStdExtZdinx = false;
bool HasStdExtZhinxmin = false;
bool HasStdExtZhinx = false;
bool HasStdExtZbkb = false;
bool HasStdExtZbkc = false;
bool HasStdExtZbkx = false;
Expand Down Expand Up @@ -172,6 +176,10 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool hasStdExtZvl() const { return ZvlLen != ExtZvl::NotSet; }
bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
bool hasStdExtZfh() const { return HasStdExtZfh; }
bool hasStdExtZfinx() const { return HasStdExtZfinx; }
bool hasStdExtZdinx() const { return HasStdExtZdinx; }
bool hasStdExtZhinxmin() const { return HasStdExtZhinxmin; }
bool hasStdExtZhinx() const { return HasStdExtZhinx; }
bool hasStdExtZbkb() const { return HasStdExtZbkb; }
bool hasStdExtZbkc() const { return HasStdExtZbkc; }
bool hasStdExtZbkx() const { return HasStdExtZbkx; }
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/CodeGen/RISCV/zfinx-types.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \
; RUN: -target-abi=ilp32f | FileCheck -check-prefix=RVZFINX %s
; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \
; RUN: -target-abi=lp64f | FileCheck -check-prefix=RVZFINX %s

define float @test_float(float %x) {
; RVZFINX-LABEL: test_float:
; RVZFINX: # %bb.0:
; RVZFINX-NEXT: .cfi_def_cfa_offset 0
; RVZFINX-NEXT: li a0, 0
; RVZFINX-NEXT: #APP
; RVZFINX-NEXT: mv a0, a0
; RVZFINX-NEXT: #NO_APP
; RVZFINX-NEXT: li a0, 0
; RVZFINX-NEXT: ret
%1 = tail call float asm sideeffect alignstack "mv a0, a0", "={x10},{x10}"(float 0.000000e+00)
ret float 0.000000e+00
}
12 changes: 12 additions & 0 deletions llvm/test/MC/RISCV/attribute-arch.s
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@
.attribute arch, "rv32ifzfh1p0"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfh1p0"

.attribute arch, "rv32izfinx"
# CHECK: attribute 5, "rv32i2p0_zfinx1p0"

.attribute arch, "rv32izfinx_zdinx"
# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zdinx1p0"

.attribute arch, "rv32izfinx_zhinxmin"
# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zhinxmin1p0"

.attribute arch, "rv32izfinx_zhinx1p0"
# CHECK: attribute 5, "rv32i2p0_zfinx1p0_zhinx1p0"

.attribute arch, "rv32i_zbkb1p0"
# CHECK: attribute 5, "rv32i2p0_zbkb1p0"

Expand Down
6 changes: 5 additions & 1 deletion llvm/test/MC/RISCV/rv32i-invalid.s
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -172,6 +172,10 @@ xor s2, s2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
mul a4, ra, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
amomaxu.w s5, s4, (s3) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'A' (Atomic Instructions)
fadd.s ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}}
fadd.h ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)
fadd.s a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfinx' (Float in Integer)
fadd.d a0, a2, a4 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer)
fadd.h a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer)
flh ft0, (a0) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) or 'Zfhmin' (Half-Precision Floating-Point Minimal){{$}}
sh1add a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zba' (Address Generation Instructions)
clz a0, a1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbb' (Basic Bit-Manipulation)
Expand Down
27 changes: 27 additions & 0 deletions llvm/test/MC/RISCV/rv32zdinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 | FileCheck %s

# Unsupport Odd Registers in RV32
fadd.d a0, a1, a2 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction

# Not support float registers
flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
fadd.d fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point)

# Invalid instructions
fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
fmv.x.w s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction

# Invalid register names
fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
fsgnjn.d a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction

# Rounding mode when a register is expected
fmadd.d x10, x12, x14, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction

# Invalid rounding modes
fmadd.d x10, x12, x14, x16, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fmsub.d x10, x12, x14, x16, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fnmsub.d x10, x12, x14, x16, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic

# FP registers where integer regs are expected
fcvt.wu.d ft2, a1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
124 changes: 124 additions & 0 deletions llvm/test/MC/RISCV/rv32zdinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zdinx %s \
# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zdinx %s \
# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, dyn
# CHECK-ASM: encoding: [0x43,0x75,0xe6,0x82]
fmadd.d x10, x12, x14, x16, dyn
# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, dyn
# CHECK-ASM: encoding: [0x47,0x75,0xe6,0x82]
fmsub.d x10, x12, x14, x16, dyn
# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, dyn
# CHECK-ASM: encoding: [0x4b,0x75,0xe6,0x82]
fnmsub.d x10, x12, x14, x16, dyn
# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, dyn
# CHECK-ASM: encoding: [0x4f,0x75,0xe6,0x82]
fnmadd.d x10, x12, x14, x16, dyn

# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x03]
fadd.d x26, x28, x30, dyn
# CHECK-ASM-AND-OBJ: fsub.d s10, t3, t5, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x0b]
fsub.d x26, x28, x30, dyn
# CHECK-ASM-AND-OBJ: fmul.d s10, t3, t5, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x13]
fmul.d x26, x28, x30, dyn
# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x1b]
fdiv.d x26, x28, x30, dyn
# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, dyn
# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0x5a]
fsqrt.d x20, x22, dyn
# CHECK-ASM-AND-OBJ: fsgnj.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x23]
fsgnj.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fsgnjn.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x23]
fsgnjn.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fsgnjx.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x2d,0xee,0x23]
fsgnjx.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fmin.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x2b]
fmin.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fmax.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x2b]
fmax.d x26, x28, x30

# CHECK-ASM-AND-OBJ: fcvt.s.d s10, t3, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0x1e,0x40]
fcvt.s.d x26, x28, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.s s10, t3
# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0x42]
fcvt.d.s x26, x28
# CHECK-ASM-AND-OBJ: feq.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x2d,0xee,0xa3]
feq.d x26, x28, x30
# CHECK-ASM-AND-OBJ: flt.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x1d,0xee,0xa3]
flt.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fle.d s10, t3, t5
# CHECK-ASM: encoding: [0x53,0x0d,0xee,0xa3]
fle.d x26, x28, x30
# CHECK-ASM-AND-OBJ: fclass.d s10, t3
# CHECK-ASM: encoding: [0x53,0x1d,0x0e,0xe2]
fclass.d x26, x28

# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, dyn
# CHECK-ASM: encoding: [0x53,0x7a,0x0b,0xc2]
fcvt.w.d x20, x22, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.w s10, t3
# CHECK-ASM: encoding: [0x53,0x0d,0x0e,0xd2]
fcvt.d.w x26, x28
# CHECK-ASM-AND-OBJ: fcvt.d.wu s10, t3
# CHECK-ASM: encoding: [0x53,0x0d,0x1e,0xd2]
fcvt.d.wu x26, x28

# Rounding modes

# CHECK-ASM-AND-OBJ: fmadd.d a0, a2, a4, a6, rne
# CHECK-ASM: encoding: [0x43,0x05,0xe6,0x82]
fmadd.d x10, x12, x14, x16, rne
# CHECK-ASM-AND-OBJ: fmsub.d a0, a2, a4, a6, rtz
# CHECK-ASM: encoding: [0x47,0x15,0xe6,0x82]
fmsub.d x10, x12, x14, x16, rtz
# CHECK-ASM-AND-OBJ: fnmsub.d a0, a2, a4, a6, rdn
# CHECK-ASM: encoding: [0x4b,0x25,0xe6,0x82]
fnmsub.d x10, x12, x14, x16, rdn
# CHECK-ASM-AND-OBJ: fnmadd.d a0, a2, a4, a6, rup
# CHECK-ASM: encoding: [0x4f,0x35,0xe6,0x82]
fnmadd.d x10, x12, x14, x16, rup

# CHECK-ASM-AND-OBJ: fadd.d s10, t3, t5, rmm
# CHECK-ASM: encoding: [0x53,0x4d,0xee,0x03]
fadd.d x26, x28, x30, rmm
# CHECK-ASM-AND-OBJ: fsub.d s10, t3, t5, dyn
# CHECK-ASM: encoding: [0x53,0x7d,0xee,0x0b]
fsub.d x26, x28, x30, dyn
# CHECK-ASM-AND-OBJ: fmul.d s10, t3, t5, rne
# CHECK-ASM: encoding: [0x53,0x0d,0xee,0x13]
fmul.d x26, x28, x30, rne
# CHECK-ASM-AND-OBJ: fdiv.d s10, t3, t5, rtz
# CHECK-ASM: encoding: [0x53,0x1d,0xee,0x1b]
fdiv.d x26, x28, x30, rtz

# CHECK-ASM-AND-OBJ: fsqrt.d s4, s6, rdn
# CHECK-ASM: encoding: [0x53,0x2a,0x0b,0x5a]
fsqrt.d x20, x22, rdn
# CHECK-ASM-AND-OBJ: fcvt.s.d s4, s6, rup
# CHECK-ASM: encoding: [0x53,0x3a,0x1b,0x40]
fcvt.s.d x20, x22, rup
# CHECK-ASM-AND-OBJ: fcvt.w.d s4, s6, rmm
# CHECK-ASM: encoding: [0x53,0x4a,0x0b,0xc2]
fcvt.w.d x20, x22, rmm
# CHECK-ASM-AND-OBJ: fcvt.wu.d s4, s6, dyn
# CHECK-ASM: encoding: [0x53,0x7a,0x1b,0xc2]
fcvt.wu.d x20, x22, dyn
25 changes: 25 additions & 0 deletions llvm/test/MC/RISCV/rv32zfinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 | FileCheck %s

# Not support float registers
flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
fadd.s fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)

# Invalid instructions
fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
fmv.x.w s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
fadd.d t1, t3, t5 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer)

# Invalid register names
fadd.d a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
fsgnjn.s a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction

# Rounding mode when a register is expected
fmadd.s x10, x11, x12, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction

# Invalid rounding modes
fmadd.s x10, x11, x12, x13, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fmsub.s x14, x15, x16, x17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fnmsub.s x18, x19, x20, x21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic

# Using 'Zdinx' instructions for an 'Zfinx'-only target
fadd.d t0, t1, t2 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
128 changes: 128 additions & 0 deletions llvm/test/MC/RISCV/rv32zfinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zfinx %s \
# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \
# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, dyn
# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x68]
fmadd.s x10, x11, x12, x13, dyn
# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, dyn
# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89]
fmsub.s x14, x15, x16, x17, dyn
# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, dyn
# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xa9]
fnmsub.s x18, x19, x20, x21, dyn
# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, dyn
# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xc9]
fnmadd.s x22, x23, x24, x25, dyn

# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, dyn
# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x01]
fadd.s x26, x27, x28, dyn
# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, dyn
# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x09]
fsub.s x29, x30, x31, dyn
# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, dyn
# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x11]
fmul.s s0, s1, s2, dyn
# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, dyn
# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x19]
fdiv.s s3, s4, s5, dyn
# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, dyn
# CHECK-ASM: encoding: [0x53,0xf3,0x03,0x58]
fsqrt.s t1, t2, dyn
# CHECK-ASM-AND-OBJ: fsgnj.s s1, a0, a1
# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x20]
fsgnj.s s1, a0, a1
# CHECK-ASM-AND-OBJ: fsgnjn.s a1, a3, a4
# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x20]
fsgnjn.s a1, a3, a4
# CHECK-ASM-AND-OBJ: fsgnjx.s a4, a3, a2
# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x20]
fsgnjx.s a4, a3, a2
# CHECK-ASM-AND-OBJ: fmin.s a5, a6, a7
# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x29]
fmin.s a5, a6, a7
# CHECK-ASM-AND-OBJ: fmax.s s2, s3, s4
# CHECK-ASM: encoding: [0x53,0x99,0x49,0x29]
fmax.s s2, s3, s4
# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc0]
fcvt.w.s a0, s5, dyn
# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc0]
fcvt.wu.s a1, s6, dyn
# CHECK-ASM-AND-OBJ: feq.s a1, s8, s9
# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa1]
feq.s a1, s8, s9
# CHECK-ASM-AND-OBJ: flt.s a2, s10, s11
# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa1]
flt.s a2, s10, s11
# CHECK-ASM-AND-OBJ: fle.s a3, t3, t4
# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa1]
fle.s a3, t3, t4
# CHECK-ASM-AND-OBJ: fclass.s a3, t5
# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe0]
fclass.s a3, t5
# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, dyn
# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd0]
fcvt.s.w t6, a4, dyn
# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, dyn
# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd0]
fcvt.s.wu s0, a5, dyn

# Rounding modes

# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rne
# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x68]
fmadd.s x10, x11, x12, x13, rne
# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7, rtz
# CHECK-ASM: encoding: [0x47,0x97,0x07,0x89]
fmsub.s x14, x15, x16, x17, rtz
# CHECK-ASM-AND-OBJ: fnmsub.s s2, s3, s4, s5, rdn
# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xa9]
fnmsub.s x18, x19, x20, x21, rdn
# CHECK-ASM-AND-OBJ: fnmadd.s s6, s7, s8, s9, rup
# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xc9]
fnmadd.s x22, x23, x24, x25, rup
# CHECK-ASM-AND-OBJ: fmadd.s a0, a1, a2, a3, rmm
# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x68]
fmadd.s x10, x11, x12, x13, rmm
# CHECK-ASM-AND-OBJ: fmsub.s a4, a5, a6, a7
# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x89]
fmsub.s x14, x15, x16, x17, dyn

# CHECK-ASM-AND-OBJ: fadd.s s10, s11, t3, rne
# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x01]
fadd.s x26, x27, x28, rne
# CHECK-ASM-AND-OBJ: fsub.s t4, t5, t6, rtz
# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x09]
fsub.s x29, x30, x31, rtz
# CHECK-ASM-AND-OBJ: fmul.s s0, s1, s2, rdn
# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x11]
fmul.s s0, s1, s2, rdn
# CHECK-ASM-AND-OBJ: fdiv.s s3, s4, s5, rup
# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x19]
fdiv.s s3, s4, s5, rup

# CHECK-ASM-AND-OBJ: fsqrt.s t1, t2, rmm
# CHECK-ASM: encoding: [0x53,0xc3,0x03,0x58]
fsqrt.s t1, t2, rmm
# CHECK-ASM-AND-OBJ: fcvt.w.s a0, s5, rup
# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc0]
fcvt.w.s a0, s5, rup
# CHECK-ASM-AND-OBJ: fcvt.wu.s a1, s6, rdn
# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc0]
fcvt.wu.s a1, s6, rdn
# CHECK-ASM-AND-OBJ: fcvt.s.w t6, a4, rtz
# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd0]
fcvt.s.w t6, a4, rtz
# CHECK-ASM-AND-OBJ: fcvt.s.wu s0, a5, rne
# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd0]
fcvt.s.wu s0, a5, rne
24 changes: 24 additions & 0 deletions llvm/test/MC/RISCV/rv32zhinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 | FileCheck %s

# Not support float registers
flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
fadd.h fa0, fa1, fa2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)

# Invalid instructions
fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction

# Invalid register names
fadd.h a100, a2, a3 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
fsgnjn.h a100, a2, a3 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction

# Rounding mode when a register is expected
fmadd.h x10, x11, x12, ree # CHECK: :[[@LINE]]:24: error: invalid operand for instruction

# Invalid rounding modes
fmadd.h x10, x11, x12, x13, ree # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fmsub.h x14, x15, x16, x17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a valid floating point rounding mode mnemonic
fnmsub.h x18, x19, x20, x21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic

# FP registers where integer regs are expected
fcvt.wu.h ft2, a1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
128 changes: 128 additions & 0 deletions llvm/test/MC/RISCV/rv32zhinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zhinx %s \
# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \
# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, dyn
# CHECK-ASM: encoding: [0x43,0xf5,0xc5,0x6c]
fmadd.h x10, x11, x12, x13, dyn
# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, dyn
# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d]
fmsub.h x14, x15, x16, x17, dyn
# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, dyn
# CHECK-ASM: encoding: [0x4b,0xf9,0x49,0xad]
fnmsub.h x18, x19, x20, x21, dyn
# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, dyn
# CHECK-ASM: encoding: [0x4f,0xfb,0x8b,0xcd]
fnmadd.h x22, x23, x24, x25, dyn

# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, dyn
# CHECK-ASM: encoding: [0x53,0xfd,0xcd,0x05]
fadd.h x26, x27, x28, dyn
# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, dyn
# CHECK-ASM: encoding: [0xd3,0x7e,0xff,0x0d]
fsub.h x29, x30, x31, dyn
# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, dyn
# CHECK-ASM: encoding: [0x53,0xf4,0x24,0x15]
fmul.h s0, s1, s2, dyn
# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, dyn
# CHECK-ASM: encoding: [0xd3,0x79,0x5a,0x1d]
fdiv.h s3, s4, s5, dyn
# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, dyn
# CHECK-ASM: encoding: [0x53,0xfb,0x0b,0x5c]
fsqrt.h s6, s7, dyn
# CHECK-ASM-AND-OBJ: fsgnj.h s1, a0, a1
# CHECK-ASM: encoding: [0xd3,0x04,0xb5,0x24]
fsgnj.h x9, x10, x11
# CHECK-ASM-AND-OBJ: fsgnjn.h a1, a3, a4
# CHECK-ASM: encoding: [0xd3,0x95,0xe6,0x24]
fsgnjn.h x11, x13, x14
# CHECK-ASM-AND-OBJ: fsgnjx.h a4, a3, a2
# CHECK-ASM: encoding: [0x53,0xa7,0xc6,0x24]
fsgnjx.h x14, x13, x12
# CHECK-ASM-AND-OBJ: fmin.h a5, a6, a7
# CHECK-ASM: encoding: [0xd3,0x07,0x18,0x2d]
fmin.h x15, x16, x17
# CHECK-ASM-AND-OBJ: fmax.h s2, s3, s4
# CHECK-ASM: encoding: [0x53,0x99,0x49,0x2d]
fmax.h x18, x19, x20
# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x0a,0xc4]
fcvt.w.h x10, x21, dyn
# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x1b,0xc4]
fcvt.wu.h x11, x22, dyn
# CHECK-ASM-AND-OBJ: feq.h a1, s8, s9
# CHECK-ASM: encoding: [0xd3,0x25,0x9c,0xa5]
feq.h x11, x24, x25
# CHECK-ASM-AND-OBJ: flt.h a2, s10, s11
# CHECK-ASM: encoding: [0x53,0x16,0xbd,0xa5]
flt.h x12, x26, x27
# CHECK-ASM-AND-OBJ: fle.h a3, t3, t4
# CHECK-ASM: encoding: [0xd3,0x06,0xde,0xa5]
fle.h x13, x28, x29
# CHECK-ASM-AND-OBJ: fclass.h a3, t5
# CHECK-ASM: encoding: [0xd3,0x16,0x0f,0xe4]
fclass.h x13, x30
# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, dyn
# CHECK-ASM: encoding: [0xd3,0x7f,0x07,0xd4]
fcvt.h.w x31, x14, dyn
# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, dyn
# CHECK-ASM: encoding: [0x53,0xf4,0x17,0xd4]
fcvt.h.wu s0, x15, dyn

# Rounding modes

# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rne
# CHECK-ASM: encoding: [0x43,0x85,0xc5,0x6c]
fmadd.h x10, x11, x12, x13, rne
# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7, rtz
# CHECK-ASM: encoding: [0x47,0x97,0x07,0x8d]
fmsub.h x14, x15, x16, x17, rtz
# CHECK-ASM-AND-OBJ: fnmsub.h s2, s3, s4, s5, rdn
# CHECK-ASM: encoding: [0x4b,0xa9,0x49,0xad]
fnmsub.h x18, x19, x20, x21, rdn
# CHECK-ASM-AND-OBJ: fnmadd.h s6, s7, s8, s9, rup
# CHECK-ASM: encoding: [0x4f,0xbb,0x8b,0xcd]
fnmadd.h x22, x23, x24, x25, rup
# CHECK-ASM-AND-OBJ: fmadd.h a0, a1, a2, a3, rmm
# CHECK-ASM: encoding: [0x43,0xc5,0xc5,0x6c]
fmadd.h x10, x11, x12, x13, rmm
# CHECK-ASM-AND-OBJ: fmsub.h a4, a5, a6, a7
# CHECK-ASM: encoding: [0x47,0xf7,0x07,0x8d]
fmsub.h x14, x15, x16, x17, dyn

# CHECK-ASM-AND-OBJ: fadd.h s10, s11, t3, rne
# CHECK-ASM: encoding: [0x53,0x8d,0xcd,0x05]
fadd.h x26, x27, x28, rne
# CHECK-ASM-AND-OBJ: fsub.h t4, t5, t6, rtz
# CHECK-ASM: encoding: [0xd3,0x1e,0xff,0x0d]
fsub.h x29, x30, x31, rtz
# CHECK-ASM-AND-OBJ: fmul.h s0, s1, s2, rdn
# CHECK-ASM: encoding: [0x53,0xa4,0x24,0x15]
fmul.h s0, s1, s2, rdn
# CHECK-ASM-AND-OBJ: fdiv.h s3, s4, s5, rup
# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x1d]
fdiv.h s3, s4, s5, rup

# CHECK-ASM-AND-OBJ: fsqrt.h s6, s7, rmm
# CHECK-ASM: encoding: [0x53,0xcb,0x0b,0x5c]
fsqrt.h s6, s7, rmm
# CHECK-ASM-AND-OBJ: fcvt.w.h a0, s5, rup
# CHECK-ASM: encoding: [0x53,0xb5,0x0a,0xc4]
fcvt.w.h x10, x21, rup
# CHECK-ASM-AND-OBJ: fcvt.wu.h a1, s6, rdn
# CHECK-ASM: encoding: [0xd3,0x25,0x1b,0xc4]
fcvt.wu.h x11, x22, rdn
# CHECK-ASM-AND-OBJ: fcvt.h.w t6, a4, rtz
# CHECK-ASM: encoding: [0xd3,0x1f,0x07,0xd4]
fcvt.h.w x31, x14, rtz
# CHECK-ASM-AND-OBJ: fcvt.h.wu s0, a5, rne
# CHECK-ASM: encoding: [0x53,0x84,0x17,0xd4]
fcvt.h.wu s0, a5, rne
15 changes: 15 additions & 0 deletions llvm/test/MC/RISCV/rv32zhinxmin-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+zhinxmin %s 2>&1 | FileCheck %s

# Not support float registers
flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
fcvt.h.s fa0, fa1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point) or 'Zfhmin' (Half-Precision Floating-Point Minimal)

# Invalid instructions
fsw a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
fmv.x.h s0, s1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction

# Invalid register names
fcvt.h.s a100, a1 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction

# Valid in Zhinx
fmadd.h x10, x11, x12, x13, dyn # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zhinx' (Half Float in Integer)
18 changes: 18 additions & 0 deletions llvm/test/MC/RISCV/rv32zhinxmin-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinxmin -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zhinxmin %s \
# RUN: | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinxmin %s \
# RUN: | llvm-objdump --mattr=+zhinxmin -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: fcvt.s.h a0, a1
# CHECK-ASM: encoding: [0x53,0x85,0x25,0x40]
fcvt.s.h a0, a1

# CHECK-ASM-AND-OBJ: fcvt.h.s a0, a1, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x05,0x44]
fcvt.h.s a0, a1
9 changes: 9 additions & 0 deletions llvm/test/MC/RISCV/rv64zdinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+zdinx %s 2>&1 | FileCheck %s

# Invalid Instructions
fmv.x.d t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
fmv.d.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# FP registers where integer regs are expected
fcvt.d.l a3, ft3 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
fcvt.d.lu a4, ft4 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
43 changes: 43 additions & 0 deletions llvm/test/MC/RISCV/rv64zdinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zdinx %s \
# RUN: | llvm-objdump --mattr=+zdinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 \
# RUN: | FileCheck -check-prefix=CHECK-RV32 %s

# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc2]
# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
fcvt.l.d a0, t0, dyn
# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc2]
# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
fcvt.lu.d a1, t1, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, dyn
# CHECK-ASM: encoding: [0x53,0xfe,0x26,0xd2]
# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
fcvt.d.l t3, a3, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, dyn
# CHECK-ASM: encoding: [0xd3,0x7e,0x37,0xd2]
# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
fcvt.d.lu t4, a4, dyn

# Rounding modes
# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, rne
# CHECK-ASM: encoding: [0x53,0x8e,0x26,0xd2]
# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
fcvt.d.l t3, a3, rne
# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, rtz
# CHECK-ASM: encoding: [0xd3,0x1e,0x37,0xd2]
# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
fcvt.d.lu t4, a4, rtz
# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, rdn
# CHECK-ASM: encoding: [0x53,0xa5,0x22,0xc2]
# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
fcvt.l.d a0, t0, rdn
# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, rup
# CHECK-ASM: encoding: [0xd3,0x35,0x33,0xc2]
# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
fcvt.lu.d a1, t1, rup
9 changes: 9 additions & 0 deletions llvm/test/MC/RISCV/rv64zfinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+zfinx %s 2>&1 | FileCheck %s

# Invalid instructions
fmv.x.w t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
fmv.w.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# FP registers where integer regs are expected
fcvt.s.l a2, ft2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
fcvt.s.lu a3, ft3 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
43 changes: 43 additions & 0 deletions llvm/test/MC/RISCV/rv64zfinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zfinx %s \
# RUN: | llvm-objdump --mattr=+zfinx -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 -mattr=+zfinx %s 2>&1 \
# RUN: | FileCheck -check-prefix=CHECK-RV32 %s

# CHECK-ASM-AND-OBJ: fcvt.l.s a0, t0, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.s a0, t0, dyn
# CHECK-ASM-AND-OBJ: fcvt.lu.s a1, t1, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.s a1, t1, dyn
# CHECK-ASM-AND-OBJ: fcvt.s.l t2, a2, dyn
# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.s.l t2, a2, dyn
# CHECK-ASM-AND-OBJ: fcvt.s.lu t3, a3, dyn
# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.s.lu t3, a3, dyn

# Rounding modes
# CHECK-ASM-AND-OBJ: fcvt.l.s a4, t4, rne
# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.s a4, t4, rne
# CHECK-ASM-AND-OBJ: fcvt.lu.s a5, t5, rtz
# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.s a5, t5, rtz
# CHECK-ASM-AND-OBJ: fcvt.s.l t6, a6, rdn
# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.s.l t6, a6, rdn
# CHECK-ASM-AND-OBJ: fcvt.s.lu s7, a7, rup
# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd0]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.s.lu s7, a7, rup
9 changes: 9 additions & 0 deletions llvm/test/MC/RISCV/rv64zhinx-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s

# Invalid instructions
fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# FP registers where integer regs are expected
fcvt.h.l a2, ft2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
fcvt.h.lu a3, ft3 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
43 changes: 43 additions & 0 deletions llvm/test/MC/RISCV/rv64zhinx-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx %s \
# RUN: | llvm-objdump --mattr=+zhinx -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 -mattr=+zhinx %s 2>&1 \
# RUN: | FileCheck -check-prefix=CHECK-RV32 %s

# CHECK-ASM-AND-OBJ: fcvt.l.h a0, t0, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.h a0, t0, dyn
# CHECK-ASM-AND-OBJ: fcvt.lu.h a1, t1, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.h a1, t1, dyn
# CHECK-ASM-AND-OBJ: fcvt.h.l t2, a2, dyn
# CHECK-ASM: encoding: [0xd3,0x73,0x26,0xd4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.h.l t2, a2, dyn
# CHECK-ASM-AND-OBJ: fcvt.h.lu t3, a3, dyn
# CHECK-ASM: encoding: [0x53,0xfe,0x36,0xd4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.h.lu t3, a3, dyn

# Rounding modes
# CHECK-ASM-AND-OBJ: fcvt.l.h a4, t4, rne
# CHECK-ASM: encoding: [0x53,0x87,0x2e,0xc4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.h a4, t4, rne
# CHECK-ASM-AND-OBJ: fcvt.lu.h a5, t5, rtz
# CHECK-ASM: encoding: [0xd3,0x17,0x3f,0xc4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.h a5, t5, rtz
# CHECK-ASM-AND-OBJ: fcvt.h.l t6, a6, rdn
# CHECK-ASM: encoding: [0xd3,0x2f,0x28,0xd4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.h.l t6, a6, rdn
# CHECK-ASM-AND-OBJ: fcvt.h.lu s7, a7, rup
# CHECK-ASM: encoding: [0xd3,0xbb,0x38,0xd4]
# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.h.lu s7, a7, rup
9 changes: 9 additions & 0 deletions llvm/test/MC/RISCV/rv64zhinxmin-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+zhinx %s 2>&1 | FileCheck %s

# Invalid instructions
fmv.x.h t2, a2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
fmv.h.x a5, t5 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# FP registers where integer regs are expected
fcvt.d.h a0, fa2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
fcvt.h.d a0, fa2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
13 changes: 13 additions & 0 deletions llvm/test/MC/RISCV/rv64zhinxmin-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx,+zdinx -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zhinx,+zdinx %s \
# RUN: | llvm-objdump --mattr=+zhinx,+zdinx -M no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: fcvt.d.h a0, a2
# CHECK-ASM: encoding: [0x53,0x05,0x26,0x42]
fcvt.d.h a0, a2

# CHECK-ASM-AND-OBJ: fcvt.h.d a0, a2, dyn
# CHECK-ASM: encoding: [0x53,0x75,0x16,0x44]
fcvt.h.d a0, a2, dyn
49 changes: 49 additions & 0 deletions llvm/test/MC/RISCV/rvzdinx-aliases-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zdinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zdinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \
# RUN: | llvm-objdump -d --mattr=+zdinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zdinx %s \
# RUN: | llvm-objdump -d --mattr=+zdinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \
# RUN: | llvm-objdump -d --mattr=+zdinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zdinx %s \
# RUN: | llvm-objdump -d --mattr=+zdinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s

##===----------------------------------------------------------------------===##
## Aliases which omit the rounding mode.
##===----------------------------------------------------------------------===##

# CHECK-INST: fmadd.d a0, a2, a4, a6, dyn
# CHECK-ALIAS: fmadd.d a0, a2, a4, a6
fmadd.d x10, x12, x14, x16
# CHECK-INST: fmsub.d a0, a2, a4, a6, dyn
# CHECK-ALIAS: fmsub.d a0, a2, a4, a6
fmsub.d x10, x12, x14, x16
# CHECK-INST: fnmsub.d a0, a2, a4, a6, dyn
# CHECK-ALIAS: fnmsub.d a0, a2, a4, a6
fnmsub.d x10, x12, x14, x16
# CHECK-INST: fnmadd.d a0, a2, a4, a6, dyn
# CHECK-ALIAS: fnmadd.d a0, a2, a4, a6
fnmadd.d x10, x12, x14, x16
# CHECK-INST: fadd.d a0, a2, a4, dyn
# CHECK-ALIAS: fadd.d a0, a2, a4
fadd.d x10, x12, x14
# CHECK-INST: fsub.d a0, a2, a4, dyn
# CHECK-ALIAS: fsub.d a0, a2, a4
fsub.d x10, x12, x14
# CHECK-INST: fmul.d a0, a2, a4, dyn
# CHECK-ALIAS: fmul.d a0, a2, a4
fmul.d x10, x12, x14
# CHECK-INST: fdiv.d a0, a2, a4, dyn
# CHECK-ALIAS: fdiv.d a0, a2, a4
fdiv.d x10, x12, x14
82 changes: 82 additions & 0 deletions llvm/test/MC/RISCV/rvzfinx-aliases-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zfinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zfinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \
# RUN: | llvm-objdump -d --mattr=+zfinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zfinx %s \
# RUN: | llvm-objdump -d --mattr=+zfinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \
# RUN: | llvm-objdump -d --mattr=+zfinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zfinx %s \
# RUN: | llvm-objdump -d --mattr=+zfinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s

##===----------------------------------------------------------------------===##
## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
##===----------------------------------------------------------------------===##

# CHECK-INST: fsgnjx.s s1, s2, s2
# CHECK-ALIAS: fabs.s s1, s2
fabs.s s1, s2
# CHECK-INST: fsgnjn.s s2, s3, s3
# CHECK-ALIAS: fneg.s s2, s3
fneg.s s2, s3

# CHECK-INST: flt.s tp, s6, s5
# CHECK-ALIAS: flt.s tp, s6, s5
fgt.s x4, s5, s6
# CHECK-INST: fle.s t2, s1, s0
# CHECK-ALIAS: fle.s t2, s1, s0
fge.s x7, x8, x9

##===----------------------------------------------------------------------===##
## Aliases which omit the rounding mode.
##===----------------------------------------------------------------------===##

# CHECK-INST: fmadd.s a0, a1, a2, a3, dyn
# CHECK-ALIAS: fmadd.s a0, a1, a2, a3
fmadd.s x10, x11, x12, x13
# CHECK-INST: fmsub.s a4, a5, a6, a7, dyn
# CHECK-ALIAS: fmsub.s a4, a5, a6, a7
fmsub.s x14, x15, x16, x17
# CHECK-INST: fnmsub.s s2, s3, s4, s5, dyn
# CHECK-ALIAS: fnmsub.s s2, s3, s4, s5
fnmsub.s x18, x19, x20, x21
# CHECK-INST: fnmadd.s s6, s7, s8, s9, dyn
# CHECK-ALIAS: fnmadd.s s6, s7, s8, s9
fnmadd.s x22, x23, x24, x25
# CHECK-INST: fadd.s s10, s11, t3, dyn
# CHECK-ALIAS: fadd.s s10, s11, t3
fadd.s x26, x27, x28
# CHECK-INST: fsub.s t4, t5, t6, dyn
# CHECK-ALIAS: fsub.s t4, t5, t6
fsub.s x29, x30, x31
# CHECK-INST: fmul.s s0, s1, s2, dyn
# CHECK-ALIAS: fmul.s s0, s1, s2
fmul.s s0, s1, s2
# CHECK-INST: fdiv.s s3, s4, s5, dyn
# CHECK-ALIAS: fdiv.s s3, s4, s5
fdiv.s s3, s4, s5
# CHECK-INST: sqrt.s s6, s7, dyn
# CHECK-ALIAS: sqrt.s s6, s7
fsqrt.s s6, s7
# CHECK-INST: fcvt.w.s a0, s5, dyn
# CHECK-ALIAS: fcvt.w.s a0, s5
fcvt.w.s a0, s5
# CHECK-INST: fcvt.wu.s a1, s6, dyn
# CHECK-ALIAS: fcvt.wu.s a1, s6
fcvt.wu.s a1, s6
# CHECK-INST: fcvt.s.w t6, a4, dyn
# CHECK-ALIAS: fcvt.s.w t6, a4
fcvt.s.w t6, a4
# CHECK-INST: fcvt.s.wu s0, a5, dyn
# CHECK-ALIAS: fcvt.s.wu s0, a5
fcvt.s.wu s0, a5
82 changes: 82 additions & 0 deletions llvm/test/MC/RISCV/rvzhinx-aliases-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zhinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx -riscv-no-aliases \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zhinx \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \
# RUN: | llvm-objdump -d --mattr=+zhinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zhinx %s \
# RUN: | llvm-objdump -d --mattr=+zhinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \
# RUN: | llvm-objdump -d --mattr=+zhinx -M no-aliases - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zhinx %s \
# RUN: | llvm-objdump -d --mattr=+zhinx - \
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s

##===----------------------------------------------------------------------===##
## Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
##===----------------------------------------------------------------------===##

# CHECK-INST: fsgnjx.h s1, s2, s2
# CHECK-ALIAS: fabs.h s1, s2
fabs.h s1, s2
# CHECK-INST: fsgnjn.h s2, s3, s3
# CHECK-ALIAS: fneg.h s2, s3
fneg.h s2, s3

# CHECK-INST: flt.h tp, s6, s5
# CHECK-ALIAS: flt.h tp, s6, s5
fgt.h x4, s5, s6
# CHECK-INST: fle.h t2, s1, s0
# CHECK-ALIAS: fle.h t2, s1, s0
fge.h x7, x8, x9

##===----------------------------------------------------------------------===##
## Aliases which omit the rounding mode.
##===----------------------------------------------------------------------===##

# CHECK-INST: fmadd.h a0, a1, a2, a3, dyn
# CHECK-ALIAS: fmadd.h a0, a1, a2, a3
fmadd.h x10, x11, x12, x13
# CHECK-INST: fmsub.h a4, a5, a6, a7, dyn
# CHECK-ALIAS: fmsub.h a4, a5, a6, a7
fmsub.h x14, x15, x16, x17
# CHECK-INST: fnmsub.h s2, s3, s4, s5, dyn
# CHECK-ALIAS: fnmsub.h s2, s3, s4, s5
fnmsub.h x18, x19, x20, x21
# CHECK-INST: fnmadd.h s6, s7, s8, s9, dyn
# CHECK-ALIAS: fnmadd.h s6, s7, s8, s9
fnmadd.h x22, x23, x24, x25
# CHECK-INST: fadd.h s10, s11, t3, dyn
# CHECK-ALIAS: fadd.h s10, s11, t3
fadd.h x26, x27, x28
# CHECK-INST: fsub.h t4, t5, t6, dyn
# CHECK-ALIAS: fsub.h t4, t5, t6
fsub.h x29, x30, x31
# CHECK-INST: fmul.h s0, s1, s2, dyn
# CHECK-ALIAS: fmul.h s0, s1, s2
fmul.h s0, s1, s2
# CHECK-INST: fdiv.h s3, s4, s5, dyn
# CHECK-ALIAS: fdiv.h s3, s4, s5
fdiv.h s3, s4, s5
# CHECK-INST: fsqrt.h s6, s7, dyn
# CHECK-ALIAS: fsqrt.h s6, s7
fsqrt.h s6, s7
# CHECK-INST: fcvt.w.h a0, s5, dyn
# CHECK-ALIAS: fcvt.w.h a0, s5
fcvt.w.h a0, s5
# CHECK-INST: fcvt.wu.h a1, s6, dyn
# CHECK-ALIAS: fcvt.wu.h a1, s6
fcvt.wu.h a1, s6
# CHECK-INST: fcvt.h.w t6, a4, dyn
# CHECK-ALIAS: fcvt.h.w t6, a4
fcvt.h.w t6, a4
# CHECK-INST: fcvt.h.wu s0, a5, dyn
# CHECK-ALIAS: fcvt.h.wu s0, a5
fcvt.h.wu s0, a5