xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZfbfmin.td (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1//===-- RISCVInstrInfoZfbfmin.td - 'Zfbfmin' instructions --*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the RISC-V instructions from the standard 'Zfbfmin'
10// extension, providing scalar conversion instructions for BFloat16.
11// This version is still experimental as the 'Zfbfmin' extension hasn't been
12// ratified yet.
13//
14//===----------------------------------------------------------------------===//
15
16//===----------------------------------------------------------------------===//
17// RISC-V specific DAG Nodes.
18//===----------------------------------------------------------------------===//
19
20def SDT_RISCVFP_ROUND_BF16
21    : SDTypeProfile<1, 1, [SDTCisVT<0, bf16>, SDTCisVT<1, f32>]>;
22def SDT_RISCVFP_EXTEND_BF16
23    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, bf16>]>;
24
25def riscv_fpround_bf16
26    : SDNode<"RISCVISD::FP_ROUND_BF16", SDT_RISCVFP_ROUND_BF16>;
27def riscv_fpextend_bf16
28    : SDNode<"RISCVISD::FP_EXTEND_BF16", SDT_RISCVFP_EXTEND_BF16>;
29
30//===----------------------------------------------------------------------===//
31// Instructions
32//===----------------------------------------------------------------------===//
33
34let Predicates = [HasStdExtZfbfmin] in {
35def FCVT_BF16_S : FPUnaryOp_r_frm<0b0100010, 0b01000, FPR16, FPR32, "fcvt.bf16.s">,
36                  Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
37def FCVT_S_BF16 : FPUnaryOp_r_frm<0b0100000, 0b00110, FPR32, FPR16, "fcvt.s.bf16">,
38                  Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
39} // Predicates = [HasStdExtZfbfmin]
40
41//===----------------------------------------------------------------------===//
42// Pseudo-instructions and codegen patterns
43//===----------------------------------------------------------------------===//
44
45let Predicates = [HasStdExtZfbfmin] in {
46/// Loads
47def : LdPat<load, FLH, bf16>;
48
49/// Stores
50def : StPat<store, FSH, FPR16, bf16>;
51
52/// Float conversion operations
53// f32 -> bf16, bf16 -> f32
54def : Pat<(bf16 (riscv_fpround_bf16 FPR32:$rs1)),
55          (FCVT_BF16_S FPR32:$rs1, FRM_DYN)>;
56def : Pat<(riscv_fpextend_bf16 (bf16 FPR16:$rs1)),
57          (FCVT_S_BF16 FPR16:$rs1, FRM_DYN)>;
58
59// Moves (no conversion)
60def : Pat<(bf16 (riscv_fmv_h_x GPR:$src)), (FMV_H_X GPR:$src)>;
61def : Pat<(riscv_fmv_x_anyexth (bf16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
62def : Pat<(riscv_fmv_x_signexth (bf16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
63} // Predicates = [HasStdExtZfbfmin]
64
65let Predicates = [HasStdExtZfbfmin] in {
66// bf16->[u]int. Round-to-zero must be used for the f32->int step, the
67// rounding mode has no effect for bf16->f32.
68def : Pat<(i32 (any_fp_to_sint (bf16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_BF16 $rs1, FRM_RNE), FRM_RTZ)>;
69def : Pat<(i32 (any_fp_to_uint (bf16 FPR16:$rs1))), (FCVT_WU_S (FCVT_S_BF16 $rs1, FRM_RNE), FRM_RTZ)>;
70
71// [u]int->bf16. Match GCC and default to using dynamic rounding mode.
72def : Pat<(bf16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_BF16_S (FCVT_S_W $rs1, FRM_DYN), FRM_DYN)>;
73def : Pat<(bf16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_BF16_S (FCVT_S_WU $rs1, FRM_DYN), FRM_DYN)>;
74}
75
76let Predicates = [HasStdExtZfbfmin, IsRV64] in {
77// bf16->[u]int64. Round-to-zero must be used for the f32->int step, the
78// rounding mode has no effect for bf16->f32.
79def : Pat<(i64 (any_fp_to_sint (bf16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_BF16 $rs1, FRM_RNE), FRM_RTZ)>;
80def : Pat<(i64 (any_fp_to_uint (bf16 FPR16:$rs1))), (FCVT_LU_S (FCVT_S_BF16 $rs1, FRM_RNE), FRM_RTZ)>;
81
82// [u]int->bf16. Match GCC and default to using dynamic rounding mode.
83def : Pat<(bf16 (any_sint_to_fp (i64 GPR:$rs1))), (FCVT_BF16_S (FCVT_S_L $rs1, FRM_DYN), FRM_DYN)>;
84def : Pat<(bf16 (any_uint_to_fp (i64 GPR:$rs1))), (FCVT_BF16_S (FCVT_S_LU $rs1, FRM_DYN), FRM_DYN)>;
85}
86