[RISCV] Separate the Zfhmin and Zfh extensions.

The spec doesn't seem to be written as if Zfh implies Zfhmin. They
seem to be separate extensions.

This patch moves the instructions from Zfhmin to be enabled with
either the Zfh or Zfhmin extensions.

Reviewed By: achieveartificialintelligence

Differential Revision: https://reviews.llvm.org/D118581
This commit is contained in:
Craig Topper 2022-01-31 08:56:32 -08:00
parent 20875fe8a5
commit aae947e860
6 changed files with 29 additions and 23 deletions

View File

@ -738,7 +738,7 @@ Error RISCVISAInfo::checkDependency() {
static const char *ImpliedExtsV[] = {"zvl128b", "f", "d"};
static const char *ImpliedExtsZfhmin[] = {"f"};
static const char *ImpliedExtsZfh[] = {"zfhmin"};
static const char *ImpliedExtsZfh[] = {"f"};
static const char *ImpliedExtsZve64d[] = {"zve64f"};
static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"};
static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"};

View File

@ -52,11 +52,17 @@ def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
def FeatureStdExtZfh
: SubtargetFeature<"zfh", "HasStdExtZfh", "true",
"'Zfh' (Half-Precision Floating-Point)",
[FeatureStdExtZfhmin, FeatureStdExtF]>;
[FeatureStdExtF]>;
def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
AssemblerPredicate<(all_of FeatureStdExtZfh),
"'Zfh' (Half-Precision Floating-Point)">;
def HasStdExtZfhOrZfhmin
: Predicate<"Subtarget->hasStdExtZfh() || Subtarget->hasStdExtZfhmin()">,
AssemblerPredicate<(any_of FeatureStdExtZfh, FeatureStdExtZfhmin),
"'Zfh' (Half-Precision Floating-Point) or "
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;
def FeatureStdExtC
: SubtargetFeature<"c", "HasStdExtC", "true",
"'C' (Compressed Instructions)">;

View File

@ -29,14 +29,14 @@ def riscv_fmv_x_anyexth
// Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasStdExtZfhmin] in {
let Predicates = [HasStdExtZfhOrZfhmin] in {
def FLH : FPLoad_r<0b001, "flh", FPR16, WriteFLD16>;
// Operands for stores are in the order srcreg, base, offset rather than
// reflecting the order these fields are specified in the instruction
// encoding.
def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>;
} // Predicates = [HasStdExtZfhmin]
} // Predicates = [HasStdExtZfhOrZfhmin]
let Predicates = [HasStdExtZfh] in {
let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in {
@ -98,7 +98,7 @@ def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, 0b00001, FPR16, GPR, "fcvt.h.wu">,
def : FPUnaryOpDynFrmAlias<FCVT_H_WU, "fcvt.h.wu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh]
let Predicates = [HasStdExtZfhmin] in {
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>;
@ -113,7 +113,7 @@ def FMV_X_H : FPUnaryOp_r<0b1110010, 0b00000, 0b000, GPR, FPR16, "fmv.x.h">,
let mayRaiseFPException = 0 in
def FMV_H_X : FPUnaryOp_r<0b1111010, 0b00000, 0b000, FPR16, GPR, "fmv.h.x">,
Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>;
} // Predicates = [HasStdExtZfhmin]
} // Predicates = [HasStdExtZfhOrZfhmin]
let Predicates = [HasStdExtZfh] in {
@ -146,23 +146,23 @@ def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, 0b00011, FPR16, GPR, "fcvt.h.lu">,
def : FPUnaryOpDynFrmAlias<FCVT_H_LU, "fcvt.h.lu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh, IsRV64]
let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
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>;
def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b00010, 0b000, FPR64, FPR16, "fcvt.d.h">,
Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
} // Predicates = [HasStdExtZfhmin, HasStdExtD]
} // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD]
//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
//===----------------------------------------------------------------------===//
let Predicates = [HasStdExtZfhmin] in {
let Predicates = [HasStdExtZfhOrZfhmin] in {
def : InstAlias<"flh $rd, (${rs1})", (FLH FPR16:$rd, GPR:$rs1, 0), 0>;
def : InstAlias<"fsh $rs2, (${rs1})", (FSH FPR16:$rs2, GPR:$rs1, 0), 0>;
} // Predicates = [HasStdExtZfhmin]
} // Predicates = [HasStdExtZfhOrZfhmin]
let Predicates = [HasStdExtZfh] in {
def : InstAlias<"fmv.h $rd, $rs", (FSGNJ_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
@ -177,14 +177,14 @@ def : InstAlias<"fge.h $rd, $rs, $rt",
(FLE_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
} // Predicates = [HasStdExtZfh]
let Predicates = [HasStdExtZfhmin] in {
let Predicates = [HasStdExtZfhOrZfhmin] in {
def PseudoFLH : PseudoFloatLoad<"flh", FPR16>;
def PseudoFSH : PseudoStore<"fsh", FPR16>;
let usesCustomInserter = 1 in {
def PseudoQuietFLE_H : PseudoQuietFCMP<FPR16>;
def PseudoQuietFLT_H : PseudoQuietFCMP<FPR16>;
}
} // Predicates = [HasStdExtZfhmin]
} // Predicates = [HasStdExtZfhOrZfhmin]
//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
@ -281,7 +281,7 @@ def : PatSetCC<FPR16, any_fsetccs, SETOLE, FLE_H>;
def Select_FPR16_Using_CC_GPR : SelectCC_rrirr<FPR16, GPR>;
} // Predicates = [HasStdExtZfh]
let Predicates = [HasStdExtZfhmin] in {
let Predicates = [HasStdExtZfhOrZfhmin] in {
/// Loads
defm : LdPat<load, FLH, f16>;
@ -299,7 +299,7 @@ def : Pat<(any_fpextend FPR16:$rs1), (FCVT_S_H FPR16:$rs1)>;
// Moves (no conversion)
def : Pat<(riscv_fmv_h_x GPR:$src), (FMV_H_X GPR:$src)>;
def : Pat<(riscv_fmv_x_anyexth FPR16:$src), (FMV_X_H FPR16:$src)>;
} // Predicates = [HasStdExtZfhmin]
} // Predicates = [HasStdExtZfhOrZfhmin]
let Predicates = [HasStdExtZfh, IsRV32] in {
// half->[u]int. Round-to-zero must be used.
@ -351,7 +351,7 @@ def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_L $rs1, 0b111)>;
def : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_H_LU $rs1, 0b111)>;
} // Predicates = [HasStdExtZfh, IsRV64]
let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
let Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] in {
/// Float conversion operations
// f64 -> f16, f16 -> f64
def : Pat<(any_fpround FPR64:$rs1), (FCVT_H_D FPR64:$rs1, 0b111)>;
@ -361,4 +361,4 @@ def : Pat<(any_fpextend FPR16:$rs1), (FCVT_D_H FPR16:$rs1)>;
def : Pat<(fcopysign FPR16:$rs1, FPR64:$rs2),
(FSGNJ_H $rs1, (FCVT_H_D $rs2, 0b111))>;
def : Pat<(fcopysign FPR64:$rs1, FPR16:$rs2), (FSGNJ_D $rs1, (FCVT_D_H $rs2))>;
} // Predicates = [HasStdExtZfhmin, HasStdExtD]
} // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD]

View File

@ -71,7 +71,7 @@
; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0"
; RV32C: .attribute 5, "rv32i2p0_c2p0"
; RV32ZFHMIN: .attribute 5, "rv32i2p0_f2p0_zfhmin1p0"
; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh1p0_zfhmin1p0"
; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh1p0"
; RV32ZBA: .attribute 5, "rv32i2p0_zba1p0"
; RV32ZBB: .attribute 5, "rv32i2p0_zbb1p0"
; RV32ZBC: .attribute 5, "rv32i2p0_zbc1p0"
@ -83,7 +83,7 @@
; RV32ZBS: .attribute 5, "rv32i2p0_zbs1p0"
; RV32ZBT: .attribute 5, "rv32i2p0_zbt0p93"
; RV32V: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zfh1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV32ZBKB: .attribute 5, "rv32i2p0_zbkb1p0"
; RV32ZBKC: .attribute 5, "rv32i2p0_zbkc1p0"
; RV32ZBKX: .attribute 5, "rv32i2p0_zbkx1p0"
@ -104,7 +104,7 @@
; RV64D: .attribute 5, "rv64i2p0_f2p0_d2p0"
; RV64C: .attribute 5, "rv64i2p0_c2p0"
; RV64ZFHMIN: .attribute 5, "rv64i2p0_f2p0_zfhmin1p0"
; RV64ZFH: .attribute 5, "rv64i2p0_f2p0_zfh1p0_zfhmin1p0"
; RV64ZFH: .attribute 5, "rv64i2p0_f2p0_zfh1p0"
; RV64ZBA: .attribute 5, "rv64i2p0_zba1p0"
; RV64ZBB: .attribute 5, "rv64i2p0_zbb1p0"
; RV64ZBC: .attribute 5, "rv64i2p0_zbc1p0"
@ -116,7 +116,7 @@
; RV64ZBS: .attribute 5, "rv64i2p0_zbs1p0"
; RV64ZBT: .attribute 5, "rv64i2p0_zbt0p93"
; RV64V: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zfh1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
; RV64ZBKB: .attribute 5, "rv64i2p0_zbkb1p0"
; RV64ZBKC: .attribute 5, "rv64i2p0_zbkc1p0"
; RV64ZBKX: .attribute 5, "rv64i2p0_zbkx1p0"

View File

@ -123,7 +123,7 @@
# CHECK: attribute 5, "rv32i2p0_f2p0_zfhmin1p0"
.attribute arch, "rv32ifzfh1p0"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfh1p0_zfhmin1p0"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfh1p0"
.attribute arch, "rv32i_zbkb1p0"
# CHECK: attribute 5, "rv32i2p0_zbkb1p0"

View File

@ -171,8 +171,8 @@ xor s2, s2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Instruction not in the base ISA
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 ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}}
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)
clmul a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbc' (Carry-Less Multiplication)