xref: /llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZfbfmin.td (revision a5ce66423bfff6f2185e5fe48bc6ffc0ade7df4d)
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// Instructions
18//===----------------------------------------------------------------------===//
19
20let Predicates = [HasStdExtZfbfmin] in {
21def FCVT_BF16_S : FPUnaryOp_r_frm<0b0100010, 0b01000, FPR16, FPR32, "fcvt.bf16.s">,
22                  Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
23def FCVT_S_BF16 : FPUnaryOp_r_frmlegacy<0b0100000, 0b00110, FPR32, FPR16, "fcvt.s.bf16">,
24                  Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
25} // Predicates = [HasStdExtZfbfmin]
26
27//===----------------------------------------------------------------------===//
28// Pseudo-instructions and codegen patterns
29//===----------------------------------------------------------------------===//
30
31let Predicates = [HasStdExtZfbfmin] in {
32def : Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), GPR:$rhs, cond,
33                                   (bf16 FPR16:$truev), FPR16:$falsev),
34          (Select_FPR16_Using_CC_GPR GPR:$lhs, GPR:$rhs,
35           (IntCCtoRISCVCC $cc), FPR16:$truev, FPR16:$falsev)>;
36
37// Explicitly select 0 in the condition to X0. The register coalescer doesn't
38// always do it.
39def : Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 0, cond,
40                                   (bf16 FPR16:$truev),
41                                   FPR16:$falsev),
42          (Select_FPR16_Using_CC_GPR GPR:$lhs, (XLenVT X0),
43           (IntCCtoRISCVCC $cc), FPR16:$truev, FPR16:$falsev)>;
44
45/// Loads
46def : LdPat<load, FLH, bf16>;
47
48/// Stores
49def : StPat<store, FSH, FPR16, bf16>;
50
51/// Float conversion operations
52// f32 -> bf16, bf16 -> f32
53def : Pat<(bf16 (fpround FPR32:$rs1)),
54          (FCVT_BF16_S FPR32:$rs1, FRM_DYN)>;
55def : Pat<(fpextend (bf16 FPR16:$rs1)),
56          (FCVT_S_BF16 FPR16:$rs1, FRM_RNE)>;
57
58// Moves (no conversion)
59def : Pat<(bf16 (riscv_fmv_h_x GPR:$src)), (FMV_H_X GPR:$src)>;
60def : Pat<(riscv_fmv_x_anyexth (bf16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
61def : Pat<(riscv_fmv_x_signexth (bf16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
62} // Predicates = [HasStdExtZfbfmin]
63
64let Predicates = [HasStdExtZfbfmin, HasStdExtD] in {
65// f64 -> bf16
66// FIXME: This pattern double rounds.
67def : Pat<(bf16 (fpround FPR64:$rs1)),
68          (FCVT_BF16_S (FCVT_S_D FPR64:$rs1, FRM_DYN), FRM_DYN)>;
69// bf16 -> f64
70def : Pat<(fpextend (bf16 FPR16:$rs1)),
71          (FCVT_D_S (FCVT_S_BF16 FPR16:$rs1, FRM_DYN), FRM_RNE)>;
72}
73