master
inc 168 lines 5.29 KB
Raw
1 /*
2 * RISC-V translation routines for the BF16 Standard Extensions.
3 *
4 * Copyright (c) 2020-2023 PLCT Lab
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #define REQUIRE_ZFBFMIN(ctx) do { \
20 if (!ctx->cfg_ptr->ext_zfbfmin) { \
21 return false; \
22 } \
23 } while (0)
24
25 #define REQUIRE_ZVFBFMIN(ctx) do { \
26 if (!ctx->cfg_ptr->ext_zvfbfmin) { \
27 return false; \
28 } \
29 } while (0)
30
31 #define REQUIRE_ZVFBFWMA(ctx) do { \
32 if (!ctx->cfg_ptr->ext_zvfbfwma) { \
33 return false; \
34 } \
35 } while (0)
36
37 static bool trans_fcvt_bf16_s(DisasContext *ctx, arg_fcvt_bf16_s *a)
38 {
39 REQUIRE_FPU;
40 REQUIRE_ZFBFMIN(ctx);
41
42 TCGv_i64 dest = dest_fpr(ctx, a->rd);
43 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
44
45 gen_set_rm(ctx, a->rm);
46 gen_helper_fcvt_bf16_s(dest, tcg_env, src1);
47 gen_set_fpr_hs(ctx, a->rd, dest);
48 mark_fs_dirty(ctx);
49 return true;
50 }
51
52 static bool trans_fcvt_s_bf16(DisasContext *ctx, arg_fcvt_s_bf16 *a)
53 {
54 REQUIRE_FPU;
55 REQUIRE_ZFBFMIN(ctx);
56
57 TCGv_i64 dest = dest_fpr(ctx, a->rd);
58 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
59
60 gen_set_rm(ctx, a->rm);
61 gen_helper_fcvt_s_bf16(dest, tcg_env, src1);
62 gen_set_fpr_hs(ctx, a->rd, dest);
63 mark_fs_dirty(ctx);
64 return true;
65 }
66
67 static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
68 {
69 REQUIRE_FPU;
70 REQUIRE_ZVFBFMIN(ctx);
71
72 if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {
73 uint32_t data = 0;
74
75 gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
76
77 data = FIELD_DP32(data, VDATA, VM, a->vm);
78 data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
79 data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
80 data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
81 tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
82 vreg_ofs(ctx, a->rs2), tcg_env,
83 ctx->cfg_ptr->vlenb,
84 ctx->cfg_ptr->vlenb, data,
85 gen_helper_vfncvtbf16_f_f_w);
86 finalize_rvv_inst(ctx);
87 return true;
88 }
89 return false;
90 }
91
92 static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
93 {
94 REQUIRE_FPU;
95 REQUIRE_ZVFBFMIN(ctx);
96
97 if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {
98 uint32_t data = 0;
99
100 gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
101
102 data = FIELD_DP32(data, VDATA, VM, a->vm);
103 data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
104 data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
105 data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
106 tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
107 vreg_ofs(ctx, a->rs2), tcg_env,
108 ctx->cfg_ptr->vlenb,
109 ctx->cfg_ptr->vlenb, data,
110 gen_helper_vfwcvtbf16_f_f_v);
111 finalize_rvv_inst(ctx);
112 return true;
113 }
114 return false;
115 }
116
117 static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
118 {
119 REQUIRE_FPU;
120 REQUIRE_ZVFBFWMA(ctx);
121
122 uint8_t sew = ctx->sew;
123 if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
124 vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm) &&
125 vext_check_input_eew(ctx, a->rd, sew + 1, a->rs1, sew, a->vm) &&
126 vext_check_input_eew(ctx, a->rd, sew + 1, a->rs2, sew, a->vm)) {
127 uint32_t data = 0;
128
129 gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
130
131 data = FIELD_DP32(data, VDATA, VM, a->vm);
132 data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
133 data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
134 data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
135 tcg_gen_gvec_4_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
136 vreg_ofs(ctx, a->rs1),
137 vreg_ofs(ctx, a->rs2), tcg_env,
138 ctx->cfg_ptr->vlenb,
139 ctx->cfg_ptr->vlenb, data,
140 gen_helper_vfwmaccbf16_vv);
141 finalize_rvv_inst(ctx);
142 return true;
143 }
144 return false;
145 }
146
147 static bool trans_vfwmaccbf16_vf(DisasContext *ctx, arg_vfwmaccbf16_vf *a)
148 {
149 REQUIRE_FPU;
150 REQUIRE_ZVFBFWMA(ctx);
151
152 uint8_t sew = ctx->sew;
153 if (require_rvv(ctx) && (ctx->sew == MO_16) && vext_check_isa_ill(ctx) &&
154 vext_check_ds(ctx, a->rd, a->rs2, a->vm) &&
155 vext_check_input_eew(ctx, a->rd, sew + 1, a->rs2, sew, a->vm)) {
156 uint32_t data = 0;
157
158 gen_set_rm(ctx, RISCV_FRM_DYN);
159 data = FIELD_DP32(data, VDATA, VM, a->vm);
160 data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
161 data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
162 data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
163 return opfvf_trans(a->rd, a->rs1, a->rs2, data,
164 gen_helper_vfwmaccbf16_vf, ctx);
165 }
166
167 return false;
168 }