Statistics
| Branch: | Revision:

root / target-arm / op.c @ d9ba4830

History | View | Annotate | Download (13.4 kB)

1 2c0262af bellard
/*
2 2c0262af bellard
 *  ARM micro operations
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 9ee6e8bb pbrook
 *  Copyright (c) 2005-2007 CodeSourcery, LLC
6 2c0262af bellard
 *
7 2c0262af bellard
 * This library is free software; you can redistribute it and/or
8 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
9 2c0262af bellard
 * License as published by the Free Software Foundation; either
10 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
11 2c0262af bellard
 *
12 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
13 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 2c0262af bellard
 * Lesser General Public License for more details.
16 2c0262af bellard
 *
17 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
18 2c0262af bellard
 * License along with this library; if not, write to the Free Software
19 2c0262af bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 2c0262af bellard
 */
21 2c0262af bellard
#include "exec.h"
22 2c0262af bellard
23 2c0262af bellard
void OPPROTO op_addl_T0_T1_cc(void)
24 2c0262af bellard
{
25 2c0262af bellard
    unsigned int src1;
26 2c0262af bellard
    src1 = T0;
27 2c0262af bellard
    T0 += T1;
28 2c0262af bellard
    env->NZF = T0;
29 2c0262af bellard
    env->CF = T0 < src1;
30 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
31 2c0262af bellard
}
32 2c0262af bellard
33 2c0262af bellard
void OPPROTO op_adcl_T0_T1_cc(void)
34 2c0262af bellard
{
35 2c0262af bellard
    unsigned int src1;
36 2c0262af bellard
    src1 = T0;
37 2c0262af bellard
    if (!env->CF) {
38 2c0262af bellard
        T0 += T1;
39 2c0262af bellard
        env->CF = T0 < src1;
40 2c0262af bellard
    } else {
41 2c0262af bellard
        T0 += T1 + 1;
42 2c0262af bellard
        env->CF = T0 <= src1;
43 2c0262af bellard
    }
44 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
45 2c0262af bellard
    env->NZF = T0;
46 2c0262af bellard
    FORCE_RET();
47 2c0262af bellard
}
48 2c0262af bellard
49 2c0262af bellard
#define OPSUB(sub, sbc, res, T0, T1)            \
50 2c0262af bellard
                                                \
51 2c0262af bellard
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
52 2c0262af bellard
{                                               \
53 2c0262af bellard
    unsigned int src1;                          \
54 2c0262af bellard
    src1 = T0;                                  \
55 2c0262af bellard
    T0 -= T1;                                   \
56 2c0262af bellard
    env->NZF = T0;                              \
57 2c0262af bellard
    env->CF = src1 >= T1;                       \
58 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
59 2c0262af bellard
    res = T0;                                   \
60 2c0262af bellard
}                                               \
61 2c0262af bellard
                                                \
62 2c0262af bellard
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
63 2c0262af bellard
{                                               \
64 2c0262af bellard
    unsigned int src1;                          \
65 2c0262af bellard
    src1 = T0;                                  \
66 2c0262af bellard
    if (!env->CF) {                             \
67 2c0262af bellard
        T0 = T0 - T1 - 1;                       \
68 78573df6 bellard
        env->CF = src1 > T1;                    \
69 2c0262af bellard
    } else {                                    \
70 2c0262af bellard
        T0 = T0 - T1;                           \
71 78573df6 bellard
        env->CF = src1 >= T1;                   \
72 2c0262af bellard
    }                                           \
73 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
74 2c0262af bellard
    env->NZF = T0;                              \
75 2c0262af bellard
    res = T0;                                   \
76 2c0262af bellard
    FORCE_RET();                                \
77 2c0262af bellard
}
78 2c0262af bellard
79 2c0262af bellard
OPSUB(sub, sbc, T0, T0, T1)
80 2c0262af bellard
81 2c0262af bellard
OPSUB(rsb, rsc, T0, T1, T0)
82 2c0262af bellard
83 2c0262af bellard
void OPPROTO op_addq_T0_T1(void)
84 2c0262af bellard
{
85 2c0262af bellard
    uint64_t res;
86 2c0262af bellard
    res = ((uint64_t)T1 << 32) | T0;
87 2c0262af bellard
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
88 2c0262af bellard
    T1 = res >> 32;
89 2c0262af bellard
    T0 = res;
90 2c0262af bellard
}
91 2c0262af bellard
92 99c475ab bellard
void OPPROTO op_addq_lo_T0_T1(void)
93 99c475ab bellard
{
94 99c475ab bellard
    uint64_t res;
95 99c475ab bellard
    res = ((uint64_t)T1 << 32) | T0;
96 99c475ab bellard
    res += (uint64_t)(env->regs[PARAM1]);
97 99c475ab bellard
    T1 = res >> 32;
98 99c475ab bellard
    T0 = res;
99 99c475ab bellard
}
100 99c475ab bellard
101 9ee6e8bb pbrook
/* Dual 16-bit accumulate.  */
102 9ee6e8bb pbrook
void OPPROTO op_addq_T0_T1_dual(void)
103 9ee6e8bb pbrook
{
104 9ee6e8bb pbrook
  uint64_t res;
105 9ee6e8bb pbrook
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
106 9ee6e8bb pbrook
  res += (int32_t)T0;
107 9ee6e8bb pbrook
  res += (int32_t)T1;
108 9ee6e8bb pbrook
  env->regs[PARAM1] = (uint32_t)res;
109 9ee6e8bb pbrook
  env->regs[PARAM2] = res >> 32;
110 9ee6e8bb pbrook
}
111 9ee6e8bb pbrook
112 9ee6e8bb pbrook
/* Dual 16-bit subtract accumulate.  */
113 9ee6e8bb pbrook
void OPPROTO op_subq_T0_T1_dual(void)
114 9ee6e8bb pbrook
{
115 9ee6e8bb pbrook
  uint64_t res;
116 9ee6e8bb pbrook
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
117 9ee6e8bb pbrook
  res += (int32_t)T0;
118 9ee6e8bb pbrook
  res -= (int32_t)T1;
119 9ee6e8bb pbrook
  env->regs[PARAM1] = (uint32_t)res;
120 9ee6e8bb pbrook
  env->regs[PARAM2] = res >> 32;
121 9ee6e8bb pbrook
}
122 9ee6e8bb pbrook
123 2c0262af bellard
void OPPROTO op_logicq_cc(void)
124 2c0262af bellard
{
125 2c0262af bellard
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
126 2c0262af bellard
}
127 2c0262af bellard
128 2c0262af bellard
/* memory access */
129 2c0262af bellard
130 b5ff1b31 bellard
#define MEMSUFFIX _raw
131 b5ff1b31 bellard
#include "op_mem.h"
132 2c0262af bellard
133 b5ff1b31 bellard
#if !defined(CONFIG_USER_ONLY)
134 b5ff1b31 bellard
#define MEMSUFFIX _user
135 b5ff1b31 bellard
#include "op_mem.h"
136 b5ff1b31 bellard
#define MEMSUFFIX _kernel
137 b5ff1b31 bellard
#include "op_mem.h"
138 b5ff1b31 bellard
#endif
139 2c0262af bellard
140 9ee6e8bb pbrook
void OPPROTO op_clrex(void)
141 9ee6e8bb pbrook
{
142 9ee6e8bb pbrook
    cpu_lock();
143 9ee6e8bb pbrook
    helper_clrex(env);
144 9ee6e8bb pbrook
    cpu_unlock();
145 9ee6e8bb pbrook
}
146 9ee6e8bb pbrook
147 2c0262af bellard
/* T1 based, use T0 as shift count */
148 2c0262af bellard
149 2c0262af bellard
void OPPROTO op_shll_T1_T0(void)
150 2c0262af bellard
{
151 2c0262af bellard
    int shift;
152 2c0262af bellard
    shift = T0 & 0xff;
153 2c0262af bellard
    if (shift >= 32)
154 2c0262af bellard
        T1 = 0;
155 2c0262af bellard
    else
156 2c0262af bellard
        T1 = T1 << shift;
157 2c0262af bellard
    FORCE_RET();
158 2c0262af bellard
}
159 2c0262af bellard
160 2c0262af bellard
void OPPROTO op_shrl_T1_T0(void)
161 2c0262af bellard
{
162 2c0262af bellard
    int shift;
163 2c0262af bellard
    shift = T0 & 0xff;
164 2c0262af bellard
    if (shift >= 32)
165 2c0262af bellard
        T1 = 0;
166 2c0262af bellard
    else
167 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
168 2c0262af bellard
    FORCE_RET();
169 2c0262af bellard
}
170 2c0262af bellard
171 2c0262af bellard
void OPPROTO op_sarl_T1_T0(void)
172 2c0262af bellard
{
173 2c0262af bellard
    int shift;
174 2c0262af bellard
    shift = T0 & 0xff;
175 2c0262af bellard
    if (shift >= 32)
176 2c0262af bellard
        shift = 31;
177 2c0262af bellard
    T1 = (int32_t)T1 >> shift;
178 2c0262af bellard
}
179 2c0262af bellard
180 2c0262af bellard
void OPPROTO op_rorl_T1_T0(void)
181 2c0262af bellard
{
182 2c0262af bellard
    int shift;
183 2c0262af bellard
    shift = T0 & 0x1f;
184 2c0262af bellard
    if (shift) {
185 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
186 2c0262af bellard
    }
187 2c0262af bellard
    FORCE_RET();
188 2c0262af bellard
}
189 2c0262af bellard
190 2c0262af bellard
/* T1 based, use T0 as shift count and compute CF */
191 2c0262af bellard
192 2c0262af bellard
void OPPROTO op_shll_T1_T0_cc(void)
193 2c0262af bellard
{
194 2c0262af bellard
    int shift;
195 2c0262af bellard
    shift = T0 & 0xff;
196 2c0262af bellard
    if (shift >= 32) {
197 2c0262af bellard
        if (shift == 32)
198 2c0262af bellard
            env->CF = T1 & 1;
199 2c0262af bellard
        else
200 2c0262af bellard
            env->CF = 0;
201 2c0262af bellard
        T1 = 0;
202 2c0262af bellard
    } else if (shift != 0) {
203 2c0262af bellard
        env->CF = (T1 >> (32 - shift)) & 1;
204 2c0262af bellard
        T1 = T1 << shift;
205 2c0262af bellard
    }
206 2c0262af bellard
    FORCE_RET();
207 2c0262af bellard
}
208 2c0262af bellard
209 2c0262af bellard
void OPPROTO op_shrl_T1_T0_cc(void)
210 2c0262af bellard
{
211 2c0262af bellard
    int shift;
212 2c0262af bellard
    shift = T0 & 0xff;
213 2c0262af bellard
    if (shift >= 32) {
214 2c0262af bellard
        if (shift == 32)
215 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
216 2c0262af bellard
        else
217 2c0262af bellard
            env->CF = 0;
218 2c0262af bellard
        T1 = 0;
219 2c0262af bellard
    } else if (shift != 0) {
220 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
221 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
222 2c0262af bellard
    }
223 2c0262af bellard
    FORCE_RET();
224 2c0262af bellard
}
225 2c0262af bellard
226 2c0262af bellard
void OPPROTO op_sarl_T1_T0_cc(void)
227 2c0262af bellard
{
228 2c0262af bellard
    int shift;
229 2c0262af bellard
    shift = T0 & 0xff;
230 2c0262af bellard
    if (shift >= 32) {
231 2c0262af bellard
        env->CF = (T1 >> 31) & 1;
232 2c0262af bellard
        T1 = (int32_t)T1 >> 31;
233 1b1afeb9 balrog
    } else if (shift != 0) {
234 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
235 2c0262af bellard
        T1 = (int32_t)T1 >> shift;
236 2c0262af bellard
    }
237 2c0262af bellard
    FORCE_RET();
238 2c0262af bellard
}
239 2c0262af bellard
240 2c0262af bellard
void OPPROTO op_rorl_T1_T0_cc(void)
241 2c0262af bellard
{
242 2c0262af bellard
    int shift1, shift;
243 2c0262af bellard
    shift1 = T0 & 0xff;
244 2c0262af bellard
    shift = shift1 & 0x1f;
245 2c0262af bellard
    if (shift == 0) {
246 2c0262af bellard
        if (shift1 != 0)
247 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
248 2c0262af bellard
    } else {
249 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
250 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
251 2c0262af bellard
    }
252 2c0262af bellard
    FORCE_RET();
253 2c0262af bellard
}
254 2c0262af bellard
255 b7bcbe95 bellard
/* VFP support.  We follow the convention used for VFP instrunctions:
256 b7bcbe95 bellard
   Single precition routines have a "s" suffix, double precision a
257 b7bcbe95 bellard
   "d" suffix.  */
258 2c0262af bellard
259 b7bcbe95 bellard
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
260 2c0262af bellard
261 53cd6637 bellard
#define VFP_BINOP(name) \
262 b7bcbe95 bellard
VFP_OP(name, s)             \
263 b7bcbe95 bellard
{                           \
264 53cd6637 bellard
    FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status);    \
265 b7bcbe95 bellard
}                           \
266 b7bcbe95 bellard
VFP_OP(name, d)             \
267 b7bcbe95 bellard
{                           \
268 53cd6637 bellard
    FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status);    \
269 b7bcbe95 bellard
}
270 53cd6637 bellard
VFP_BINOP(add)
271 53cd6637 bellard
VFP_BINOP(sub)
272 53cd6637 bellard
VFP_BINOP(mul)
273 53cd6637 bellard
VFP_BINOP(div)
274 b7bcbe95 bellard
#undef VFP_BINOP
275 b7bcbe95 bellard
276 b7bcbe95 bellard
#define VFP_HELPER(name)  \
277 b7bcbe95 bellard
VFP_OP(name, s)           \
278 b7bcbe95 bellard
{                         \
279 b7bcbe95 bellard
    do_vfp_##name##s();    \
280 b7bcbe95 bellard
}                         \
281 b7bcbe95 bellard
VFP_OP(name, d)           \
282 b7bcbe95 bellard
{                         \
283 b7bcbe95 bellard
    do_vfp_##name##d();    \
284 b7bcbe95 bellard
}
285 b7bcbe95 bellard
VFP_HELPER(abs)
286 b7bcbe95 bellard
VFP_HELPER(sqrt)
287 b7bcbe95 bellard
VFP_HELPER(cmp)
288 b7bcbe95 bellard
VFP_HELPER(cmpe)
289 b7bcbe95 bellard
#undef VFP_HELPER
290 b7bcbe95 bellard
291 b7bcbe95 bellard
/* XXX: Will this do the right thing for NANs.  Should invert the signbit
292 b7bcbe95 bellard
   without looking at the rest of the value.  */
293 b7bcbe95 bellard
VFP_OP(neg, s)
294 b7bcbe95 bellard
{
295 53cd6637 bellard
    FT0s = float32_chs(FT0s);
296 b7bcbe95 bellard
}
297 b7bcbe95 bellard
298 b7bcbe95 bellard
VFP_OP(neg, d)
299 b7bcbe95 bellard
{
300 53cd6637 bellard
    FT0d = float64_chs(FT0d);
301 b7bcbe95 bellard
}
302 b7bcbe95 bellard
303 b7bcbe95 bellard
VFP_OP(F1_ld0, s)
304 b7bcbe95 bellard
{
305 53cd6637 bellard
    union {
306 53cd6637 bellard
        uint32_t i;
307 53cd6637 bellard
        float32 s;
308 53cd6637 bellard
    } v;
309 53cd6637 bellard
    v.i = 0;
310 53cd6637 bellard
    FT1s = v.s;
311 b7bcbe95 bellard
}
312 b7bcbe95 bellard
313 b7bcbe95 bellard
VFP_OP(F1_ld0, d)
314 b7bcbe95 bellard
{
315 53cd6637 bellard
    union {
316 53cd6637 bellard
        uint64_t i;
317 53cd6637 bellard
        float64 d;
318 53cd6637 bellard
    } v;
319 53cd6637 bellard
    v.i = 0;
320 53cd6637 bellard
    FT1d = v.d;
321 b7bcbe95 bellard
}
322 b7bcbe95 bellard
323 b7bcbe95 bellard
/* Helper routines to perform bitwise copies between float and int.  */
324 53cd6637 bellard
static inline float32 vfp_itos(uint32_t i)
325 b7bcbe95 bellard
{
326 b7bcbe95 bellard
    union {
327 b7bcbe95 bellard
        uint32_t i;
328 53cd6637 bellard
        float32 s;
329 b7bcbe95 bellard
    } v;
330 b7bcbe95 bellard
331 b7bcbe95 bellard
    v.i = i;
332 b7bcbe95 bellard
    return v.s;
333 b7bcbe95 bellard
}
334 b7bcbe95 bellard
335 53cd6637 bellard
static inline uint32_t vfp_stoi(float32 s)
336 b7bcbe95 bellard
{
337 b7bcbe95 bellard
    union {
338 b7bcbe95 bellard
        uint32_t i;
339 53cd6637 bellard
        float32 s;
340 b7bcbe95 bellard
    } v;
341 b7bcbe95 bellard
342 b7bcbe95 bellard
    v.s = s;
343 b7bcbe95 bellard
    return v.i;
344 b7bcbe95 bellard
}
345 b7bcbe95 bellard
346 9ee6e8bb pbrook
static inline float64 vfp_itod(uint64_t i)
347 9ee6e8bb pbrook
{
348 9ee6e8bb pbrook
    union {
349 9ee6e8bb pbrook
        uint64_t i;
350 9ee6e8bb pbrook
        float64 d;
351 9ee6e8bb pbrook
    } v;
352 9ee6e8bb pbrook
353 9ee6e8bb pbrook
    v.i = i;
354 9ee6e8bb pbrook
    return v.d;
355 9ee6e8bb pbrook
}
356 9ee6e8bb pbrook
357 9ee6e8bb pbrook
static inline uint64_t vfp_dtoi(float64 d)
358 9ee6e8bb pbrook
{
359 9ee6e8bb pbrook
    union {
360 9ee6e8bb pbrook
        uint64_t i;
361 9ee6e8bb pbrook
        float64 d;
362 9ee6e8bb pbrook
    } v;
363 9ee6e8bb pbrook
364 9ee6e8bb pbrook
    v.d = d;
365 9ee6e8bb pbrook
    return v.i;
366 9ee6e8bb pbrook
}
367 9ee6e8bb pbrook
368 b7bcbe95 bellard
/* Integer to float conversion.  */
369 b7bcbe95 bellard
VFP_OP(uito, s)
370 b7bcbe95 bellard
{
371 53cd6637 bellard
    FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
372 b7bcbe95 bellard
}
373 b7bcbe95 bellard
374 b7bcbe95 bellard
VFP_OP(uito, d)
375 b7bcbe95 bellard
{
376 53cd6637 bellard
    FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
377 b7bcbe95 bellard
}
378 b7bcbe95 bellard
379 b7bcbe95 bellard
VFP_OP(sito, s)
380 b7bcbe95 bellard
{
381 53cd6637 bellard
    FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
382 b7bcbe95 bellard
}
383 b7bcbe95 bellard
384 b7bcbe95 bellard
VFP_OP(sito, d)
385 b7bcbe95 bellard
{
386 53cd6637 bellard
    FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
387 b7bcbe95 bellard
}
388 b7bcbe95 bellard
389 b7bcbe95 bellard
/* Float to integer conversion.  */
390 b7bcbe95 bellard
VFP_OP(toui, s)
391 b7bcbe95 bellard
{
392 53cd6637 bellard
    FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
393 b7bcbe95 bellard
}
394 b7bcbe95 bellard
395 b7bcbe95 bellard
VFP_OP(toui, d)
396 b7bcbe95 bellard
{
397 53cd6637 bellard
    FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
398 b7bcbe95 bellard
}
399 b7bcbe95 bellard
400 b7bcbe95 bellard
VFP_OP(tosi, s)
401 b7bcbe95 bellard
{
402 53cd6637 bellard
    FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
403 b7bcbe95 bellard
}
404 b7bcbe95 bellard
405 b7bcbe95 bellard
VFP_OP(tosi, d)
406 b7bcbe95 bellard
{
407 53cd6637 bellard
    FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
408 b7bcbe95 bellard
}
409 b7bcbe95 bellard
410 b7bcbe95 bellard
/* TODO: Set rounding mode properly.  */
411 b7bcbe95 bellard
VFP_OP(touiz, s)
412 b7bcbe95 bellard
{
413 53cd6637 bellard
    FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
414 b7bcbe95 bellard
}
415 b7bcbe95 bellard
416 b7bcbe95 bellard
VFP_OP(touiz, d)
417 b7bcbe95 bellard
{
418 53cd6637 bellard
    FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
419 b7bcbe95 bellard
}
420 b7bcbe95 bellard
421 b7bcbe95 bellard
VFP_OP(tosiz, s)
422 b7bcbe95 bellard
{
423 53cd6637 bellard
    FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
424 b7bcbe95 bellard
}
425 b7bcbe95 bellard
426 b7bcbe95 bellard
VFP_OP(tosiz, d)
427 2c0262af bellard
{
428 53cd6637 bellard
    FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
429 2c0262af bellard
}
430 2c0262af bellard
431 b7bcbe95 bellard
/* floating point conversion */
432 b7bcbe95 bellard
VFP_OP(fcvtd, s)
433 2c0262af bellard
{
434 53cd6637 bellard
    FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
435 2c0262af bellard
}
436 2c0262af bellard
437 b7bcbe95 bellard
VFP_OP(fcvts, d)
438 b7bcbe95 bellard
{
439 53cd6637 bellard
    FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
440 b7bcbe95 bellard
}
441 b7bcbe95 bellard
442 9ee6e8bb pbrook
/* VFP3 fixed point conversion.  */
443 9ee6e8bb pbrook
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
444 9ee6e8bb pbrook
VFP_OP(name##to, p) \
445 9ee6e8bb pbrook
{ \
446 9ee6e8bb pbrook
    ftype tmp; \
447 9ee6e8bb pbrook
    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \
448 9ee6e8bb pbrook
                                  &env->vfp.fp_status); \
449 9ee6e8bb pbrook
    FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \
450 9ee6e8bb pbrook
} \
451 9ee6e8bb pbrook
VFP_OP(to##name, p) \
452 9ee6e8bb pbrook
{ \
453 9ee6e8bb pbrook
    ftype tmp; \
454 9ee6e8bb pbrook
    tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \
455 9ee6e8bb pbrook
    FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
456 9ee6e8bb pbrook
            &env->vfp.fp_status)); \
457 9ee6e8bb pbrook
}
458 9ee6e8bb pbrook
459 9ee6e8bb pbrook
VFP_CONV_FIX(sh, d, float64, int16, )
460 9ee6e8bb pbrook
VFP_CONV_FIX(sl, d, float64, int32, )
461 9ee6e8bb pbrook
VFP_CONV_FIX(uh, d, float64, uint16, u)
462 9ee6e8bb pbrook
VFP_CONV_FIX(ul, d, float64, uint32, u)
463 9ee6e8bb pbrook
VFP_CONV_FIX(sh, s, float32, int16, )
464 9ee6e8bb pbrook
VFP_CONV_FIX(sl, s, float32, int32, )
465 9ee6e8bb pbrook
VFP_CONV_FIX(uh, s, float32, uint16, u)
466 9ee6e8bb pbrook
VFP_CONV_FIX(ul, s, float32, uint32, u)
467 9ee6e8bb pbrook
468 b7bcbe95 bellard
/* Get and Put values from registers.  */
469 b7bcbe95 bellard
VFP_OP(getreg_F0, d)
470 b7bcbe95 bellard
{
471 53cd6637 bellard
  FT0d = *(float64 *)((char *) env + PARAM1);
472 b7bcbe95 bellard
}
473 b7bcbe95 bellard
474 b7bcbe95 bellard
VFP_OP(getreg_F0, s)
475 b7bcbe95 bellard
{
476 53cd6637 bellard
  FT0s = *(float32 *)((char *) env + PARAM1);
477 b7bcbe95 bellard
}
478 b7bcbe95 bellard
479 b7bcbe95 bellard
VFP_OP(getreg_F1, d)
480 b7bcbe95 bellard
{
481 53cd6637 bellard
  FT1d = *(float64 *)((char *) env + PARAM1);
482 b7bcbe95 bellard
}
483 b7bcbe95 bellard
484 b7bcbe95 bellard
VFP_OP(getreg_F1, s)
485 b7bcbe95 bellard
{
486 53cd6637 bellard
  FT1s = *(float32 *)((char *) env + PARAM1);
487 b7bcbe95 bellard
}
488 b7bcbe95 bellard
489 b7bcbe95 bellard
VFP_OP(setreg_F0, d)
490 b7bcbe95 bellard
{
491 53cd6637 bellard
  *(float64 *)((char *) env + PARAM1) = FT0d;
492 b7bcbe95 bellard
}
493 b7bcbe95 bellard
494 b7bcbe95 bellard
VFP_OP(setreg_F0, s)
495 b7bcbe95 bellard
{
496 53cd6637 bellard
  *(float32 *)((char *) env + PARAM1) = FT0s;
497 b7bcbe95 bellard
}
498 b7bcbe95 bellard
499 b7bcbe95 bellard
void OPPROTO op_vfp_movl_T0_fpscr(void)
500 b7bcbe95 bellard
{
501 b7bcbe95 bellard
    do_vfp_get_fpscr ();
502 b7bcbe95 bellard
}
503 b7bcbe95 bellard
504 b7bcbe95 bellard
void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
505 b7bcbe95 bellard
{
506 40f137e1 pbrook
    T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
507 b7bcbe95 bellard
}
508 b7bcbe95 bellard
509 b7bcbe95 bellard
void OPPROTO op_vfp_movl_fpscr_T0(void)
510 b7bcbe95 bellard
{
511 b7bcbe95 bellard
    do_vfp_set_fpscr();
512 b7bcbe95 bellard
}
513 b7bcbe95 bellard
514 40f137e1 pbrook
void OPPROTO op_vfp_movl_T0_xreg(void)
515 40f137e1 pbrook
{
516 40f137e1 pbrook
    T0 = env->vfp.xregs[PARAM1];
517 40f137e1 pbrook
}
518 40f137e1 pbrook
519 40f137e1 pbrook
void OPPROTO op_vfp_movl_xreg_T0(void)
520 40f137e1 pbrook
{
521 40f137e1 pbrook
    env->vfp.xregs[PARAM1] = T0;
522 40f137e1 pbrook
}
523 40f137e1 pbrook
524 b7bcbe95 bellard
/* Move between FT0s to T0  */
525 b7bcbe95 bellard
void OPPROTO op_vfp_mrs(void)
526 b7bcbe95 bellard
{
527 b7bcbe95 bellard
    T0 = vfp_stoi(FT0s);
528 b7bcbe95 bellard
}
529 b7bcbe95 bellard
530 b7bcbe95 bellard
void OPPROTO op_vfp_msr(void)
531 b7bcbe95 bellard
{
532 b7bcbe95 bellard
    FT0s = vfp_itos(T0);
533 b7bcbe95 bellard
}
534 b7bcbe95 bellard
535 b7bcbe95 bellard
/* Move between FT0d and {T0,T1} */
536 b7bcbe95 bellard
void OPPROTO op_vfp_mrrd(void)
537 b7bcbe95 bellard
{
538 b7bcbe95 bellard
    CPU_DoubleU u;
539 3b46e624 ths
540 b7bcbe95 bellard
    u.d = FT0d;
541 b7bcbe95 bellard
    T0 = u.l.lower;
542 b7bcbe95 bellard
    T1 = u.l.upper;
543 b7bcbe95 bellard
}
544 b7bcbe95 bellard
545 b7bcbe95 bellard
void OPPROTO op_vfp_mdrr(void)
546 b7bcbe95 bellard
{
547 b7bcbe95 bellard
    CPU_DoubleU u;
548 3b46e624 ths
549 b7bcbe95 bellard
    u.l.lower = T0;
550 b7bcbe95 bellard
    u.l.upper = T1;
551 b7bcbe95 bellard
    FT0d = u.d;
552 b7bcbe95 bellard
}
553 b7bcbe95 bellard
554 9ee6e8bb pbrook
/* Load immediate.  PARAM1 is the 32 most significant bits of the value.  */
555 9ee6e8bb pbrook
void OPPROTO op_vfp_fconstd(void)
556 9ee6e8bb pbrook
{
557 9ee6e8bb pbrook
    CPU_DoubleU u;
558 9ee6e8bb pbrook
    u.l.upper = PARAM1;
559 9ee6e8bb pbrook
    u.l.lower = 0;
560 9ee6e8bb pbrook
    FT0d = u.d;
561 9ee6e8bb pbrook
}
562 9ee6e8bb pbrook
563 9ee6e8bb pbrook
void OPPROTO op_vfp_fconsts(void)
564 9ee6e8bb pbrook
{
565 9ee6e8bb pbrook
    FT0s = vfp_itos(PARAM1);
566 9ee6e8bb pbrook
}
567 9ee6e8bb pbrook
568 c1713132 balrog
void OPPROTO op_movl_cp_T0(void)
569 c1713132 balrog
{
570 c1713132 balrog
    helper_set_cp(env, PARAM1, T0);
571 c1713132 balrog
    FORCE_RET();
572 c1713132 balrog
}
573 c1713132 balrog
574 c1713132 balrog
void OPPROTO op_movl_T0_cp(void)
575 c1713132 balrog
{
576 c1713132 balrog
    T0 = helper_get_cp(env, PARAM1);
577 c1713132 balrog
    FORCE_RET();
578 c1713132 balrog
}
579 c1713132 balrog
580 b5ff1b31 bellard
void OPPROTO op_movl_cp15_T0(void)
581 b7bcbe95 bellard
{
582 b5ff1b31 bellard
    helper_set_cp15(env, PARAM1, T0);
583 b5ff1b31 bellard
    FORCE_RET();
584 b7bcbe95 bellard
}
585 b7bcbe95 bellard
586 b5ff1b31 bellard
void OPPROTO op_movl_T0_cp15(void)
587 b7bcbe95 bellard
{
588 b5ff1b31 bellard
    T0 = helper_get_cp15(env, PARAM1);
589 b5ff1b31 bellard
    FORCE_RET();
590 b7bcbe95 bellard
}
591 b7bcbe95 bellard
592 b5ff1b31 bellard
/* Access to user mode registers from privileged modes.  */
593 b5ff1b31 bellard
void OPPROTO op_movl_T0_user(void)
594 b7bcbe95 bellard
{
595 b5ff1b31 bellard
    int regno = PARAM1;
596 b5ff1b31 bellard
    if (regno == 13) {
597 b5ff1b31 bellard
        T0 = env->banked_r13[0];
598 b5ff1b31 bellard
    } else if (regno == 14) {
599 b5ff1b31 bellard
        T0 = env->banked_r14[0];
600 b5ff1b31 bellard
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
601 b5ff1b31 bellard
        T0 = env->usr_regs[regno - 8];
602 b5ff1b31 bellard
    } else {
603 b5ff1b31 bellard
        T0 = env->regs[regno];
604 b5ff1b31 bellard
    }
605 b5ff1b31 bellard
    FORCE_RET();
606 b5ff1b31 bellard
}
607 b5ff1b31 bellard
608 b5ff1b31 bellard
609 b5ff1b31 bellard
void OPPROTO op_movl_user_T0(void)
610 b5ff1b31 bellard
{
611 b5ff1b31 bellard
    int regno = PARAM1;
612 b5ff1b31 bellard
    if (regno == 13) {
613 b5ff1b31 bellard
        env->banked_r13[0] = T0;
614 b5ff1b31 bellard
    } else if (regno == 14) {
615 b5ff1b31 bellard
        env->banked_r14[0] = T0;
616 b5ff1b31 bellard
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
617 b5ff1b31 bellard
        env->usr_regs[regno - 8] = T0;
618 b5ff1b31 bellard
    } else {
619 b5ff1b31 bellard
        env->regs[regno] = T0;
620 b5ff1b31 bellard
    }
621 b5ff1b31 bellard
    FORCE_RET();
622 b7bcbe95 bellard
}
623 191abaa2 pbrook
624 9ee6e8bb pbrook
void OPPROTO op_movl_T1_r13_banked(void)
625 9ee6e8bb pbrook
{
626 9ee6e8bb pbrook
    T1 = helper_get_r13_banked(env, PARAM1);
627 9ee6e8bb pbrook
}
628 9ee6e8bb pbrook
629 9ee6e8bb pbrook
void OPPROTO op_movl_r13_T1_banked(void)
630 9ee6e8bb pbrook
{
631 9ee6e8bb pbrook
    helper_set_r13_banked(env, PARAM1, T1);
632 9ee6e8bb pbrook
}
633 9ee6e8bb pbrook
634 9ee6e8bb pbrook
void OPPROTO op_v7m_mrs_T0(void)
635 9ee6e8bb pbrook
{
636 9ee6e8bb pbrook
    T0 = helper_v7m_mrs(env, PARAM1);
637 9ee6e8bb pbrook
}
638 9ee6e8bb pbrook
639 9ee6e8bb pbrook
void OPPROTO op_v7m_msr_T0(void)
640 9ee6e8bb pbrook
{
641 9ee6e8bb pbrook
    helper_v7m_msr(env, PARAM1, T0);
642 9ee6e8bb pbrook
}
643 9ee6e8bb pbrook
644 9ee6e8bb pbrook
void OPPROTO op_movl_T0_sp(void)
645 9ee6e8bb pbrook
{
646 9ee6e8bb pbrook
    if (PARAM1 == env->v7m.current_sp)
647 9ee6e8bb pbrook
        T0 = env->regs[13];
648 9ee6e8bb pbrook
    else
649 9ee6e8bb pbrook
        T0 = env->v7m.other_sp;
650 9ee6e8bb pbrook
    FORCE_RET();
651 9ee6e8bb pbrook
}
652 9ee6e8bb pbrook
653 9ee6e8bb pbrook
#include "op_neon.h"
654 9ee6e8bb pbrook
655 18c9b560 balrog
/* iwMMXt support */
656 18c9b560 balrog
#include "op_iwmmxt.c"