]> Git Repo - qemu.git/blame - target/arm/translate-neon.inc.c
target/arm: Convert V[US]DOT (scalar) to decodetree
[qemu.git] / target / arm / translate-neon.inc.c
CommitLineData
625e3dd4
PM
1/*
2 * ARM translation: AArch32 Neon instructions
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
7 * Copyright (c) 2020 Linaro, Ltd.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * This file is intended to be included from translate.c; it uses
25 * some macros and definitions provided by that file.
26 * It might be possible to convert it to a standalone .c file eventually.
27 */
28
29/* Include the generated Neon decoder */
30#include "decode-neon-dp.inc.c"
31#include "decode-neon-ls.inc.c"
32#include "decode-neon-shared.inc.c"
afff8de0
PM
33
34static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
35{
36 int opr_sz;
37 TCGv_ptr fpst;
38 gen_helper_gvec_3_ptr *fn_gvec_ptr;
39
40 if (!dc_isar_feature(aa32_vcma, s)
41 || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
42 return false;
43 }
44
45 /* UNDEF accesses to D16-D31 if they don't exist. */
46 if (!dc_isar_feature(aa32_simd_r32, s) &&
47 ((a->vd | a->vn | a->vm) & 0x10)) {
48 return false;
49 }
50
51 if ((a->vn | a->vm | a->vd) & a->q) {
52 return false;
53 }
54
55 if (!vfp_access_check(s)) {
56 return true;
57 }
58
59 opr_sz = (1 + a->q) * 8;
60 fpst = get_fpstatus_ptr(1);
61 fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
62 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
63 vfp_reg_offset(1, a->vn),
64 vfp_reg_offset(1, a->vm),
65 fpst, opr_sz, opr_sz, a->rot,
66 fn_gvec_ptr);
67 tcg_temp_free_ptr(fpst);
68 return true;
69}
94d5eb7b
PM
70
71static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
72{
73 int opr_sz;
74 TCGv_ptr fpst;
75 gen_helper_gvec_3_ptr *fn_gvec_ptr;
76
77 if (!dc_isar_feature(aa32_vcma, s)
78 || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
79 return false;
80 }
81
82 /* UNDEF accesses to D16-D31 if they don't exist. */
83 if (!dc_isar_feature(aa32_simd_r32, s) &&
84 ((a->vd | a->vn | a->vm) & 0x10)) {
85 return false;
86 }
87
88 if ((a->vn | a->vm | a->vd) & a->q) {
89 return false;
90 }
91
92 if (!vfp_access_check(s)) {
93 return true;
94 }
95
96 opr_sz = (1 + a->q) * 8;
97 fpst = get_fpstatus_ptr(1);
98 fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
99 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
100 vfp_reg_offset(1, a->vn),
101 vfp_reg_offset(1, a->vm),
102 fpst, opr_sz, opr_sz, a->rot,
103 fn_gvec_ptr);
104 tcg_temp_free_ptr(fpst);
105 return true;
106}
32da0e33
PM
107
108static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
109{
110 int opr_sz;
111 gen_helper_gvec_3 *fn_gvec;
112
113 if (!dc_isar_feature(aa32_dp, s)) {
114 return false;
115 }
116
117 /* UNDEF accesses to D16-D31 if they don't exist. */
118 if (!dc_isar_feature(aa32_simd_r32, s) &&
119 ((a->vd | a->vn | a->vm) & 0x10)) {
120 return false;
121 }
122
123 if ((a->vn | a->vm | a->vd) & a->q) {
124 return false;
125 }
126
127 if (!vfp_access_check(s)) {
128 return true;
129 }
130
131 opr_sz = (1 + a->q) * 8;
132 fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
133 tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
134 vfp_reg_offset(1, a->vn),
135 vfp_reg_offset(1, a->vm),
136 opr_sz, opr_sz, 0, fn_gvec);
137 return true;
138}
9a107e7b
PM
139
140static bool trans_VFML(DisasContext *s, arg_VFML *a)
141{
142 int opr_sz;
143
144 if (!dc_isar_feature(aa32_fhm, s)) {
145 return false;
146 }
147
148 /* UNDEF accesses to D16-D31 if they don't exist. */
149 if (!dc_isar_feature(aa32_simd_r32, s) &&
150 (a->vd & 0x10)) {
151 return false;
152 }
153
154 if (a->vd & a->q) {
155 return false;
156 }
157
158 if (!vfp_access_check(s)) {
159 return true;
160 }
161
162 opr_sz = (1 + a->q) * 8;
163 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
164 vfp_reg_offset(a->q, a->vn),
165 vfp_reg_offset(a->q, a->vm),
166 cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
167 gen_helper_gvec_fmlal_a32);
168 return true;
169}
7e1b5d61
PM
170
171static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
172{
173 gen_helper_gvec_3_ptr *fn_gvec_ptr;
174 int opr_sz;
175 TCGv_ptr fpst;
176
177 if (!dc_isar_feature(aa32_vcma, s)) {
178 return false;
179 }
180 if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
181 return false;
182 }
183
184 /* UNDEF accesses to D16-D31 if they don't exist. */
185 if (!dc_isar_feature(aa32_simd_r32, s) &&
186 ((a->vd | a->vn | a->vm) & 0x10)) {
187 return false;
188 }
189
190 if ((a->vd | a->vn) & a->q) {
191 return false;
192 }
193
194 if (!vfp_access_check(s)) {
195 return true;
196 }
197
198 fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
199 : gen_helper_gvec_fcmlah_idx);
200 opr_sz = (1 + a->q) * 8;
201 fpst = get_fpstatus_ptr(1);
202 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
203 vfp_reg_offset(1, a->vn),
204 vfp_reg_offset(1, a->vm),
205 fpst, opr_sz, opr_sz,
206 (a->index << 2) | a->rot, fn_gvec_ptr);
207 tcg_temp_free_ptr(fpst);
208 return true;
209}
35f5d4d1
PM
210
211static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
212{
213 gen_helper_gvec_3 *fn_gvec;
214 int opr_sz;
215 TCGv_ptr fpst;
216
217 if (!dc_isar_feature(aa32_dp, s)) {
218 return false;
219 }
220
221 /* UNDEF accesses to D16-D31 if they don't exist. */
222 if (!dc_isar_feature(aa32_simd_r32, s) &&
223 ((a->vd | a->vn) & 0x10)) {
224 return false;
225 }
226
227 if ((a->vd | a->vn) & a->q) {
228 return false;
229 }
230
231 if (!vfp_access_check(s)) {
232 return true;
233 }
234
235 fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
236 opr_sz = (1 + a->q) * 8;
237 fpst = get_fpstatus_ptr(1);
238 tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
239 vfp_reg_offset(1, a->vn),
240 vfp_reg_offset(1, a->rm),
241 opr_sz, opr_sz, a->index, fn_gvec);
242 tcg_temp_free_ptr(fpst);
243 return true;
244}
This page took 0.0489579999999999 seconds and 4 git commands to generate.