Statistics
| Branch: | Revision:

root / target-arm / op.c @ 5fafdf24

History | View | Annotate | Download (21.6 kB)

1 2c0262af bellard
/*
2 2c0262af bellard
 *  ARM micro operations
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 b7bcbe95 bellard
 *  Copyright (c) 2005 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
#define REGNAME r0
24 2c0262af bellard
#define REG (env->regs[0])
25 2c0262af bellard
#include "op_template.h"
26 2c0262af bellard
27 2c0262af bellard
#define REGNAME r1
28 2c0262af bellard
#define REG (env->regs[1])
29 2c0262af bellard
#include "op_template.h"
30 2c0262af bellard
31 2c0262af bellard
#define REGNAME r2
32 2c0262af bellard
#define REG (env->regs[2])
33 2c0262af bellard
#include "op_template.h"
34 2c0262af bellard
35 2c0262af bellard
#define REGNAME r3
36 2c0262af bellard
#define REG (env->regs[3])
37 2c0262af bellard
#include "op_template.h"
38 2c0262af bellard
39 2c0262af bellard
#define REGNAME r4
40 2c0262af bellard
#define REG (env->regs[4])
41 2c0262af bellard
#include "op_template.h"
42 2c0262af bellard
43 2c0262af bellard
#define REGNAME r5
44 2c0262af bellard
#define REG (env->regs[5])
45 2c0262af bellard
#include "op_template.h"
46 2c0262af bellard
47 2c0262af bellard
#define REGNAME r6
48 2c0262af bellard
#define REG (env->regs[6])
49 2c0262af bellard
#include "op_template.h"
50 2c0262af bellard
51 2c0262af bellard
#define REGNAME r7
52 2c0262af bellard
#define REG (env->regs[7])
53 2c0262af bellard
#include "op_template.h"
54 2c0262af bellard
55 2c0262af bellard
#define REGNAME r8
56 2c0262af bellard
#define REG (env->regs[8])
57 2c0262af bellard
#include "op_template.h"
58 2c0262af bellard
59 2c0262af bellard
#define REGNAME r9
60 2c0262af bellard
#define REG (env->regs[9])
61 2c0262af bellard
#include "op_template.h"
62 2c0262af bellard
63 2c0262af bellard
#define REGNAME r10
64 2c0262af bellard
#define REG (env->regs[10])
65 2c0262af bellard
#include "op_template.h"
66 2c0262af bellard
67 2c0262af bellard
#define REGNAME r11
68 2c0262af bellard
#define REG (env->regs[11])
69 2c0262af bellard
#include "op_template.h"
70 2c0262af bellard
71 2c0262af bellard
#define REGNAME r12
72 2c0262af bellard
#define REG (env->regs[12])
73 2c0262af bellard
#include "op_template.h"
74 2c0262af bellard
75 2c0262af bellard
#define REGNAME r13
76 2c0262af bellard
#define REG (env->regs[13])
77 2c0262af bellard
#include "op_template.h"
78 2c0262af bellard
79 2c0262af bellard
#define REGNAME r14
80 2c0262af bellard
#define REG (env->regs[14])
81 2c0262af bellard
#include "op_template.h"
82 2c0262af bellard
83 2c0262af bellard
#define REGNAME r15
84 2c0262af bellard
#define REG (env->regs[15])
85 99c475ab bellard
#define SET_REG(x) REG = x & ~(uint32_t)1
86 2c0262af bellard
#include "op_template.h"
87 2c0262af bellard
88 99c475ab bellard
void OPPROTO op_bx_T0(void)
89 99c475ab bellard
{
90 99c475ab bellard
  env->regs[15] = T0 & ~(uint32_t)1;
91 99c475ab bellard
  env->thumb = (T0 & 1) != 0;
92 99c475ab bellard
}
93 99c475ab bellard
94 2c0262af bellard
void OPPROTO op_movl_T0_0(void)
95 2c0262af bellard
{
96 2c0262af bellard
    T0 = 0;
97 2c0262af bellard
}
98 2c0262af bellard
99 2c0262af bellard
void OPPROTO op_movl_T0_im(void)
100 2c0262af bellard
{
101 2c0262af bellard
    T0 = PARAM1;
102 2c0262af bellard
}
103 2c0262af bellard
104 b5ff1b31 bellard
void OPPROTO op_movl_T0_T1(void)
105 b5ff1b31 bellard
{
106 b5ff1b31 bellard
    T0 = T1;
107 b5ff1b31 bellard
}
108 b5ff1b31 bellard
109 2c0262af bellard
void OPPROTO op_movl_T1_im(void)
110 2c0262af bellard
{
111 2c0262af bellard
    T1 = PARAM1;
112 2c0262af bellard
}
113 2c0262af bellard
114 7ff4d218 bellard
void OPPROTO op_mov_CF_T1(void)
115 7ff4d218 bellard
{
116 7ff4d218 bellard
    env->CF = ((uint32_t)T1) >> 31;
117 7ff4d218 bellard
}
118 7ff4d218 bellard
119 2c0262af bellard
void OPPROTO op_movl_T2_im(void)
120 2c0262af bellard
{
121 2c0262af bellard
    T2 = PARAM1;
122 2c0262af bellard
}
123 2c0262af bellard
124 2c0262af bellard
void OPPROTO op_addl_T1_im(void)
125 2c0262af bellard
{
126 2c0262af bellard
    T1 += PARAM1;
127 2c0262af bellard
}
128 2c0262af bellard
129 2c0262af bellard
void OPPROTO op_addl_T1_T2(void)
130 2c0262af bellard
{
131 2c0262af bellard
    T1 += T2;
132 2c0262af bellard
}
133 2c0262af bellard
134 2c0262af bellard
void OPPROTO op_subl_T1_T2(void)
135 2c0262af bellard
{
136 2c0262af bellard
    T1 -= T2;
137 2c0262af bellard
}
138 2c0262af bellard
139 2c0262af bellard
void OPPROTO op_addl_T0_T1(void)
140 2c0262af bellard
{
141 2c0262af bellard
    T0 += T1;
142 2c0262af bellard
}
143 2c0262af bellard
144 2c0262af bellard
void OPPROTO op_addl_T0_T1_cc(void)
145 2c0262af bellard
{
146 2c0262af bellard
    unsigned int src1;
147 2c0262af bellard
    src1 = T0;
148 2c0262af bellard
    T0 += T1;
149 2c0262af bellard
    env->NZF = T0;
150 2c0262af bellard
    env->CF = T0 < src1;
151 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
152 2c0262af bellard
}
153 2c0262af bellard
154 2c0262af bellard
void OPPROTO op_adcl_T0_T1(void)
155 2c0262af bellard
{
156 2c0262af bellard
    T0 += T1 + env->CF;
157 2c0262af bellard
}
158 2c0262af bellard
159 2c0262af bellard
void OPPROTO op_adcl_T0_T1_cc(void)
160 2c0262af bellard
{
161 2c0262af bellard
    unsigned int src1;
162 2c0262af bellard
    src1 = T0;
163 2c0262af bellard
    if (!env->CF) {
164 2c0262af bellard
        T0 += T1;
165 2c0262af bellard
        env->CF = T0 < src1;
166 2c0262af bellard
    } else {
167 2c0262af bellard
        T0 += T1 + 1;
168 2c0262af bellard
        env->CF = T0 <= src1;
169 2c0262af bellard
    }
170 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
171 2c0262af bellard
    env->NZF = T0;
172 2c0262af bellard
    FORCE_RET();
173 2c0262af bellard
}
174 2c0262af bellard
175 2c0262af bellard
#define OPSUB(sub, sbc, res, T0, T1)            \
176 2c0262af bellard
                                                \
177 2c0262af bellard
void OPPROTO op_ ## sub ## l_T0_T1(void)        \
178 2c0262af bellard
{                                               \
179 2c0262af bellard
    res = T0 - T1;                              \
180 2c0262af bellard
}                                               \
181 2c0262af bellard
                                                \
182 2c0262af bellard
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
183 2c0262af bellard
{                                               \
184 2c0262af bellard
    unsigned int src1;                          \
185 2c0262af bellard
    src1 = T0;                                  \
186 2c0262af bellard
    T0 -= T1;                                   \
187 2c0262af bellard
    env->NZF = T0;                              \
188 2c0262af bellard
    env->CF = src1 >= T1;                       \
189 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
190 2c0262af bellard
    res = T0;                                   \
191 2c0262af bellard
}                                               \
192 2c0262af bellard
                                                \
193 2c0262af bellard
void OPPROTO op_ ## sbc ## l_T0_T1(void)        \
194 2c0262af bellard
{                                               \
195 2c0262af bellard
    res = T0 - T1 + env->CF - 1;                \
196 2c0262af bellard
}                                               \
197 2c0262af bellard
                                                \
198 2c0262af bellard
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
199 2c0262af bellard
{                                               \
200 2c0262af bellard
    unsigned int src1;                          \
201 2c0262af bellard
    src1 = T0;                                  \
202 2c0262af bellard
    if (!env->CF) {                             \
203 2c0262af bellard
        T0 = T0 - T1 - 1;                       \
204 78573df6 bellard
        env->CF = src1 > T1;                    \
205 2c0262af bellard
    } else {                                    \
206 2c0262af bellard
        T0 = T0 - T1;                           \
207 78573df6 bellard
        env->CF = src1 >= T1;                   \
208 2c0262af bellard
    }                                           \
209 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
210 2c0262af bellard
    env->NZF = T0;                              \
211 2c0262af bellard
    res = T0;                                   \
212 2c0262af bellard
    FORCE_RET();                                \
213 2c0262af bellard
}
214 2c0262af bellard
215 2c0262af bellard
OPSUB(sub, sbc, T0, T0, T1)
216 2c0262af bellard
217 2c0262af bellard
OPSUB(rsb, rsc, T0, T1, T0)
218 2c0262af bellard
219 2c0262af bellard
void OPPROTO op_andl_T0_T1(void)
220 2c0262af bellard
{
221 2c0262af bellard
    T0 &= T1;
222 2c0262af bellard
}
223 2c0262af bellard
224 2c0262af bellard
void OPPROTO op_xorl_T0_T1(void)
225 2c0262af bellard
{
226 2c0262af bellard
    T0 ^= T1;
227 2c0262af bellard
}
228 2c0262af bellard
229 2c0262af bellard
void OPPROTO op_orl_T0_T1(void)
230 2c0262af bellard
{
231 2c0262af bellard
    T0 |= T1;
232 2c0262af bellard
}
233 2c0262af bellard
234 2c0262af bellard
void OPPROTO op_bicl_T0_T1(void)
235 2c0262af bellard
{
236 2c0262af bellard
    T0 &= ~T1;
237 2c0262af bellard
}
238 2c0262af bellard
239 2c0262af bellard
void OPPROTO op_notl_T1(void)
240 2c0262af bellard
{
241 2c0262af bellard
    T1 = ~T1;
242 2c0262af bellard
}
243 2c0262af bellard
244 2c0262af bellard
void OPPROTO op_logic_T0_cc(void)
245 2c0262af bellard
{
246 2c0262af bellard
    env->NZF = T0;
247 2c0262af bellard
}
248 2c0262af bellard
249 2c0262af bellard
void OPPROTO op_logic_T1_cc(void)
250 2c0262af bellard
{
251 2c0262af bellard
    env->NZF = T1;
252 2c0262af bellard
}
253 2c0262af bellard
254 2c0262af bellard
#define EIP (env->regs[15])
255 2c0262af bellard
256 2c0262af bellard
void OPPROTO op_test_eq(void)
257 2c0262af bellard
{
258 2c0262af bellard
    if (env->NZF == 0)
259 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);;
260 2c0262af bellard
    FORCE_RET();
261 2c0262af bellard
}
262 2c0262af bellard
263 2c0262af bellard
void OPPROTO op_test_ne(void)
264 2c0262af bellard
{
265 2c0262af bellard
    if (env->NZF != 0)
266 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);;
267 2c0262af bellard
    FORCE_RET();
268 2c0262af bellard
}
269 2c0262af bellard
270 2c0262af bellard
void OPPROTO op_test_cs(void)
271 2c0262af bellard
{
272 2c0262af bellard
    if (env->CF != 0)
273 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
274 2c0262af bellard
    FORCE_RET();
275 2c0262af bellard
}
276 2c0262af bellard
277 2c0262af bellard
void OPPROTO op_test_cc(void)
278 2c0262af bellard
{
279 2c0262af bellard
    if (env->CF == 0)
280 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
281 2c0262af bellard
    FORCE_RET();
282 2c0262af bellard
}
283 2c0262af bellard
284 2c0262af bellard
void OPPROTO op_test_mi(void)
285 2c0262af bellard
{
286 2c0262af bellard
    if ((env->NZF & 0x80000000) != 0)
287 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
288 2c0262af bellard
    FORCE_RET();
289 2c0262af bellard
}
290 2c0262af bellard
291 2c0262af bellard
void OPPROTO op_test_pl(void)
292 2c0262af bellard
{
293 2c0262af bellard
    if ((env->NZF & 0x80000000) == 0)
294 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
295 2c0262af bellard
    FORCE_RET();
296 2c0262af bellard
}
297 2c0262af bellard
298 2c0262af bellard
void OPPROTO op_test_vs(void)
299 2c0262af bellard
{
300 2c0262af bellard
    if ((env->VF & 0x80000000) != 0)
301 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
302 2c0262af bellard
    FORCE_RET();
303 2c0262af bellard
}
304 2c0262af bellard
305 2c0262af bellard
void OPPROTO op_test_vc(void)
306 2c0262af bellard
{
307 2c0262af bellard
    if ((env->VF & 0x80000000) == 0)
308 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
309 2c0262af bellard
    FORCE_RET();
310 2c0262af bellard
}
311 2c0262af bellard
312 2c0262af bellard
void OPPROTO op_test_hi(void)
313 2c0262af bellard
{
314 2c0262af bellard
    if (env->CF != 0 && env->NZF != 0)
315 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
316 2c0262af bellard
    FORCE_RET();
317 2c0262af bellard
}
318 2c0262af bellard
319 2c0262af bellard
void OPPROTO op_test_ls(void)
320 2c0262af bellard
{
321 2c0262af bellard
    if (env->CF == 0 || env->NZF == 0)
322 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
323 2c0262af bellard
    FORCE_RET();
324 2c0262af bellard
}
325 2c0262af bellard
326 2c0262af bellard
void OPPROTO op_test_ge(void)
327 2c0262af bellard
{
328 2c0262af bellard
    if (((env->VF ^ env->NZF) & 0x80000000) == 0)
329 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
330 2c0262af bellard
    FORCE_RET();
331 2c0262af bellard
}
332 2c0262af bellard
333 2c0262af bellard
void OPPROTO op_test_lt(void)
334 2c0262af bellard
{
335 2c0262af bellard
    if (((env->VF ^ env->NZF) & 0x80000000) != 0)
336 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
337 2c0262af bellard
    FORCE_RET();
338 2c0262af bellard
}
339 2c0262af bellard
340 2c0262af bellard
void OPPROTO op_test_gt(void)
341 2c0262af bellard
{
342 2c0262af bellard
    if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
343 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
344 2c0262af bellard
    FORCE_RET();
345 2c0262af bellard
}
346 2c0262af bellard
347 2c0262af bellard
void OPPROTO op_test_le(void)
348 2c0262af bellard
{
349 2c0262af bellard
    if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
350 e50e6a20 bellard
        GOTO_LABEL_PARAM(1);
351 2c0262af bellard
    FORCE_RET();
352 2c0262af bellard
}
353 2c0262af bellard
354 c53be334 bellard
void OPPROTO op_goto_tb0(void)
355 2c0262af bellard
{
356 c53be334 bellard
    GOTO_TB(op_goto_tb0, PARAM1, 0);
357 e50e6a20 bellard
}
358 e50e6a20 bellard
359 c53be334 bellard
void OPPROTO op_goto_tb1(void)
360 e50e6a20 bellard
{
361 c53be334 bellard
    GOTO_TB(op_goto_tb1, PARAM1, 1);
362 2c0262af bellard
}
363 2c0262af bellard
364 2c0262af bellard
void OPPROTO op_exit_tb(void)
365 2c0262af bellard
{
366 2c0262af bellard
    EXIT_TB();
367 2c0262af bellard
}
368 2c0262af bellard
369 b5ff1b31 bellard
void OPPROTO op_movl_T0_cpsr(void)
370 2c0262af bellard
{
371 b5ff1b31 bellard
    T0 = cpsr_read(env);
372 b5ff1b31 bellard
    FORCE_RET();
373 2c0262af bellard
}
374 2c0262af bellard
375 b5ff1b31 bellard
void OPPROTO op_movl_T0_spsr(void)
376 2c0262af bellard
{
377 b5ff1b31 bellard
    T0 = env->spsr;
378 b5ff1b31 bellard
}
379 b5ff1b31 bellard
380 b5ff1b31 bellard
void OPPROTO op_movl_spsr_T0(void)
381 b5ff1b31 bellard
{
382 b5ff1b31 bellard
    uint32_t mask = PARAM1;
383 b5ff1b31 bellard
    env->spsr = (env->spsr & ~mask) | (T0 & mask);
384 b5ff1b31 bellard
}
385 b5ff1b31 bellard
386 b5ff1b31 bellard
void OPPROTO op_movl_cpsr_T0(void)
387 b5ff1b31 bellard
{
388 b5ff1b31 bellard
    cpsr_write(env, T0, PARAM1);
389 b5ff1b31 bellard
    FORCE_RET();
390 2c0262af bellard
}
391 2c0262af bellard
392 2c0262af bellard
void OPPROTO op_mul_T0_T1(void)
393 2c0262af bellard
{
394 2c0262af bellard
    T0 = T0 * T1;
395 2c0262af bellard
}
396 2c0262af bellard
397 2c0262af bellard
/* 64 bit unsigned mul */
398 2c0262af bellard
void OPPROTO op_mull_T0_T1(void)
399 2c0262af bellard
{
400 2c0262af bellard
    uint64_t res;
401 2e134c9c bellard
    res = (uint64_t)T0 * (uint64_t)T1;
402 2c0262af bellard
    T1 = res >> 32;
403 2c0262af bellard
    T0 = res;
404 2c0262af bellard
}
405 2c0262af bellard
406 2c0262af bellard
/* 64 bit signed mul */
407 2c0262af bellard
void OPPROTO op_imull_T0_T1(void)
408 2c0262af bellard
{
409 2c0262af bellard
    uint64_t res;
410 163a7cb6 bellard
    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
411 2c0262af bellard
    T1 = res >> 32;
412 2c0262af bellard
    T0 = res;
413 2c0262af bellard
}
414 2c0262af bellard
415 99c475ab bellard
/* 48 bit signed mul, top 32 bits */
416 99c475ab bellard
void OPPROTO op_imulw_T0_T1(void)
417 99c475ab bellard
{
418 99c475ab bellard
  uint64_t res;
419 99c475ab bellard
  res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
420 99c475ab bellard
  T0 = res >> 16;
421 99c475ab bellard
}
422 99c475ab bellard
423 2c0262af bellard
void OPPROTO op_addq_T0_T1(void)
424 2c0262af bellard
{
425 2c0262af bellard
    uint64_t res;
426 2c0262af bellard
    res = ((uint64_t)T1 << 32) | T0;
427 2c0262af bellard
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
428 2c0262af bellard
    T1 = res >> 32;
429 2c0262af bellard
    T0 = res;
430 2c0262af bellard
}
431 2c0262af bellard
432 99c475ab bellard
void OPPROTO op_addq_lo_T0_T1(void)
433 99c475ab bellard
{
434 99c475ab bellard
    uint64_t res;
435 99c475ab bellard
    res = ((uint64_t)T1 << 32) | T0;
436 99c475ab bellard
    res += (uint64_t)(env->regs[PARAM1]);
437 99c475ab bellard
    T1 = res >> 32;
438 99c475ab bellard
    T0 = res;
439 99c475ab bellard
}
440 99c475ab bellard
441 2c0262af bellard
void OPPROTO op_logicq_cc(void)
442 2c0262af bellard
{
443 2c0262af bellard
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
444 2c0262af bellard
}
445 2c0262af bellard
446 2c0262af bellard
/* memory access */
447 2c0262af bellard
448 b5ff1b31 bellard
#define MEMSUFFIX _raw
449 b5ff1b31 bellard
#include "op_mem.h"
450 2c0262af bellard
451 b5ff1b31 bellard
#if !defined(CONFIG_USER_ONLY)
452 b5ff1b31 bellard
#define MEMSUFFIX _user
453 b5ff1b31 bellard
#include "op_mem.h"
454 b5ff1b31 bellard
#define MEMSUFFIX _kernel
455 b5ff1b31 bellard
#include "op_mem.h"
456 b5ff1b31 bellard
#endif
457 2c0262af bellard
458 2c0262af bellard
/* shifts */
459 2c0262af bellard
460 2c0262af bellard
/* T1 based */
461 1e8d4eec bellard
462 2c0262af bellard
void OPPROTO op_shll_T1_im(void)
463 2c0262af bellard
{
464 2c0262af bellard
    T1 = T1 << PARAM1;
465 2c0262af bellard
}
466 2c0262af bellard
467 2c0262af bellard
void OPPROTO op_shrl_T1_im(void)
468 2c0262af bellard
{
469 2c0262af bellard
    T1 = (uint32_t)T1 >> PARAM1;
470 2c0262af bellard
}
471 2c0262af bellard
472 1e8d4eec bellard
void OPPROTO op_shrl_T1_0(void)
473 1e8d4eec bellard
{
474 1e8d4eec bellard
    T1 = 0;
475 1e8d4eec bellard
}
476 1e8d4eec bellard
477 2c0262af bellard
void OPPROTO op_sarl_T1_im(void)
478 2c0262af bellard
{
479 2c0262af bellard
    T1 = (int32_t)T1 >> PARAM1;
480 2c0262af bellard
}
481 2c0262af bellard
482 1e8d4eec bellard
void OPPROTO op_sarl_T1_0(void)
483 1e8d4eec bellard
{
484 1e8d4eec bellard
    T1 = (int32_t)T1 >> 31;
485 1e8d4eec bellard
}
486 1e8d4eec bellard
487 2c0262af bellard
void OPPROTO op_rorl_T1_im(void)
488 2c0262af bellard
{
489 2c0262af bellard
    int shift;
490 2c0262af bellard
    shift = PARAM1;
491 2c0262af bellard
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
492 2c0262af bellard
}
493 2c0262af bellard
494 88920f34 bellard
void OPPROTO op_rrxl_T1(void)
495 88920f34 bellard
{
496 88920f34 bellard
    T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
497 88920f34 bellard
}
498 88920f34 bellard
499 2c0262af bellard
/* T1 based, set C flag */
500 2c0262af bellard
void OPPROTO op_shll_T1_im_cc(void)
501 2c0262af bellard
{
502 2c0262af bellard
    env->CF = (T1 >> (32 - PARAM1)) & 1;
503 2c0262af bellard
    T1 = T1 << PARAM1;
504 2c0262af bellard
}
505 2c0262af bellard
506 2c0262af bellard
void OPPROTO op_shrl_T1_im_cc(void)
507 2c0262af bellard
{
508 2c0262af bellard
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
509 2c0262af bellard
    T1 = (uint32_t)T1 >> PARAM1;
510 2c0262af bellard
}
511 2c0262af bellard
512 1e8d4eec bellard
void OPPROTO op_shrl_T1_0_cc(void)
513 1e8d4eec bellard
{
514 1e8d4eec bellard
    env->CF = (T1 >> 31) & 1;
515 1e8d4eec bellard
    T1 = 0;
516 1e8d4eec bellard
}
517 1e8d4eec bellard
518 2c0262af bellard
void OPPROTO op_sarl_T1_im_cc(void)
519 2c0262af bellard
{
520 2c0262af bellard
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
521 2c0262af bellard
    T1 = (int32_t)T1 >> PARAM1;
522 2c0262af bellard
}
523 2c0262af bellard
524 1e8d4eec bellard
void OPPROTO op_sarl_T1_0_cc(void)
525 1e8d4eec bellard
{
526 1e8d4eec bellard
    env->CF = (T1 >> 31) & 1;
527 1e8d4eec bellard
    T1 = (int32_t)T1 >> 31;
528 1e8d4eec bellard
}
529 1e8d4eec bellard
530 2c0262af bellard
void OPPROTO op_rorl_T1_im_cc(void)
531 2c0262af bellard
{
532 2c0262af bellard
    int shift;
533 2c0262af bellard
    shift = PARAM1;
534 2c0262af bellard
    env->CF = (T1 >> (shift - 1)) & 1;
535 2c0262af bellard
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
536 2c0262af bellard
}
537 2c0262af bellard
538 88920f34 bellard
void OPPROTO op_rrxl_T1_cc(void)
539 88920f34 bellard
{
540 88920f34 bellard
    uint32_t c;
541 88920f34 bellard
    c = T1 & 1;
542 88920f34 bellard
    T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
543 88920f34 bellard
    env->CF = c;
544 88920f34 bellard
}
545 88920f34 bellard
546 2c0262af bellard
/* T2 based */
547 2c0262af bellard
void OPPROTO op_shll_T2_im(void)
548 2c0262af bellard
{
549 2c0262af bellard
    T2 = T2 << PARAM1;
550 2c0262af bellard
}
551 2c0262af bellard
552 2c0262af bellard
void OPPROTO op_shrl_T2_im(void)
553 2c0262af bellard
{
554 2c0262af bellard
    T2 = (uint32_t)T2 >> PARAM1;
555 2c0262af bellard
}
556 2c0262af bellard
557 1e8d4eec bellard
void OPPROTO op_shrl_T2_0(void)
558 1e8d4eec bellard
{
559 1e8d4eec bellard
    T2 = 0;
560 1e8d4eec bellard
}
561 1e8d4eec bellard
562 2c0262af bellard
void OPPROTO op_sarl_T2_im(void)
563 2c0262af bellard
{
564 2c0262af bellard
    T2 = (int32_t)T2 >> PARAM1;
565 2c0262af bellard
}
566 2c0262af bellard
567 1e8d4eec bellard
void OPPROTO op_sarl_T2_0(void)
568 1e8d4eec bellard
{
569 1e8d4eec bellard
    T2 = (int32_t)T2 >> 31;
570 1e8d4eec bellard
}
571 1e8d4eec bellard
572 2c0262af bellard
void OPPROTO op_rorl_T2_im(void)
573 2c0262af bellard
{
574 2c0262af bellard
    int shift;
575 2c0262af bellard
    shift = PARAM1;
576 2c0262af bellard
    T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
577 2c0262af bellard
}
578 2c0262af bellard
579 1e8d4eec bellard
void OPPROTO op_rrxl_T2(void)
580 1e8d4eec bellard
{
581 1e8d4eec bellard
    T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
582 1e8d4eec bellard
}
583 1e8d4eec bellard
584 2c0262af bellard
/* T1 based, use T0 as shift count */
585 2c0262af bellard
586 2c0262af bellard
void OPPROTO op_shll_T1_T0(void)
587 2c0262af bellard
{
588 2c0262af bellard
    int shift;
589 2c0262af bellard
    shift = T0 & 0xff;
590 2c0262af bellard
    if (shift >= 32)
591 2c0262af bellard
        T1 = 0;
592 2c0262af bellard
    else
593 2c0262af bellard
        T1 = T1 << shift;
594 2c0262af bellard
    FORCE_RET();
595 2c0262af bellard
}
596 2c0262af bellard
597 2c0262af bellard
void OPPROTO op_shrl_T1_T0(void)
598 2c0262af bellard
{
599 2c0262af bellard
    int shift;
600 2c0262af bellard
    shift = T0 & 0xff;
601 2c0262af bellard
    if (shift >= 32)
602 2c0262af bellard
        T1 = 0;
603 2c0262af bellard
    else
604 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
605 2c0262af bellard
    FORCE_RET();
606 2c0262af bellard
}
607 2c0262af bellard
608 2c0262af bellard
void OPPROTO op_sarl_T1_T0(void)
609 2c0262af bellard
{
610 2c0262af bellard
    int shift;
611 2c0262af bellard
    shift = T0 & 0xff;
612 2c0262af bellard
    if (shift >= 32)
613 2c0262af bellard
        shift = 31;
614 2c0262af bellard
    T1 = (int32_t)T1 >> shift;
615 2c0262af bellard
}
616 2c0262af bellard
617 2c0262af bellard
void OPPROTO op_rorl_T1_T0(void)
618 2c0262af bellard
{
619 2c0262af bellard
    int shift;
620 2c0262af bellard
    shift = T0 & 0x1f;
621 2c0262af bellard
    if (shift) {
622 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
623 2c0262af bellard
    }
624 2c0262af bellard
    FORCE_RET();
625 2c0262af bellard
}
626 2c0262af bellard
627 2c0262af bellard
/* T1 based, use T0 as shift count and compute CF */
628 2c0262af bellard
629 2c0262af bellard
void OPPROTO op_shll_T1_T0_cc(void)
630 2c0262af bellard
{
631 2c0262af bellard
    int shift;
632 2c0262af bellard
    shift = T0 & 0xff;
633 2c0262af bellard
    if (shift >= 32) {
634 2c0262af bellard
        if (shift == 32)
635 2c0262af bellard
            env->CF = T1 & 1;
636 2c0262af bellard
        else
637 2c0262af bellard
            env->CF = 0;
638 2c0262af bellard
        T1 = 0;
639 2c0262af bellard
    } else if (shift != 0) {
640 2c0262af bellard
        env->CF = (T1 >> (32 - shift)) & 1;
641 2c0262af bellard
        T1 = T1 << shift;
642 2c0262af bellard
    }
643 2c0262af bellard
    FORCE_RET();
644 2c0262af bellard
}
645 2c0262af bellard
646 2c0262af bellard
void OPPROTO op_shrl_T1_T0_cc(void)
647 2c0262af bellard
{
648 2c0262af bellard
    int shift;
649 2c0262af bellard
    shift = T0 & 0xff;
650 2c0262af bellard
    if (shift >= 32) {
651 2c0262af bellard
        if (shift == 32)
652 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
653 2c0262af bellard
        else
654 2c0262af bellard
            env->CF = 0;
655 2c0262af bellard
        T1 = 0;
656 2c0262af bellard
    } else if (shift != 0) {
657 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
658 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
659 2c0262af bellard
    }
660 2c0262af bellard
    FORCE_RET();
661 2c0262af bellard
}
662 2c0262af bellard
663 2c0262af bellard
void OPPROTO op_sarl_T1_T0_cc(void)
664 2c0262af bellard
{
665 2c0262af bellard
    int shift;
666 2c0262af bellard
    shift = T0 & 0xff;
667 2c0262af bellard
    if (shift >= 32) {
668 2c0262af bellard
        env->CF = (T1 >> 31) & 1;
669 2c0262af bellard
        T1 = (int32_t)T1 >> 31;
670 1b1afeb9 balrog
    } else if (shift != 0) {
671 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
672 2c0262af bellard
        T1 = (int32_t)T1 >> shift;
673 2c0262af bellard
    }
674 2c0262af bellard
    FORCE_RET();
675 2c0262af bellard
}
676 2c0262af bellard
677 2c0262af bellard
void OPPROTO op_rorl_T1_T0_cc(void)
678 2c0262af bellard
{
679 2c0262af bellard
    int shift1, shift;
680 2c0262af bellard
    shift1 = T0 & 0xff;
681 2c0262af bellard
    shift = shift1 & 0x1f;
682 2c0262af bellard
    if (shift == 0) {
683 2c0262af bellard
        if (shift1 != 0)
684 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
685 2c0262af bellard
    } else {
686 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
687 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
688 2c0262af bellard
    }
689 2c0262af bellard
    FORCE_RET();
690 2c0262af bellard
}
691 2c0262af bellard
692 99c475ab bellard
/* misc */
693 99c475ab bellard
void OPPROTO op_clz_T0(void)
694 99c475ab bellard
{
695 99c475ab bellard
    int count;
696 99c475ab bellard
    for (count = 32; T0 > 0; count--)
697 99c475ab bellard
        T0 = T0 >> 1;
698 99c475ab bellard
    T0 = count;
699 99c475ab bellard
    FORCE_RET();
700 99c475ab bellard
}
701 99c475ab bellard
702 99c475ab bellard
void OPPROTO op_sarl_T0_im(void)
703 99c475ab bellard
{
704 99c475ab bellard
    T0 = (int32_t)T0 >> PARAM1;
705 99c475ab bellard
}
706 99c475ab bellard
707 b5ff1b31 bellard
/* Sign/zero extend */
708 b5ff1b31 bellard
void OPPROTO op_sxth_T0(void)
709 99c475ab bellard
{
710 99c475ab bellard
  T0 = (int16_t)T0;
711 99c475ab bellard
}
712 99c475ab bellard
713 b5ff1b31 bellard
void OPPROTO op_sxth_T1(void)
714 99c475ab bellard
{
715 99c475ab bellard
  T1 = (int16_t)T1;
716 99c475ab bellard
}
717 99c475ab bellard
718 b5ff1b31 bellard
void OPPROTO op_sxtb_T1(void)
719 b5ff1b31 bellard
{
720 b5ff1b31 bellard
    T1 = (int8_t)T1;
721 b5ff1b31 bellard
}
722 b5ff1b31 bellard
723 b5ff1b31 bellard
void OPPROTO op_uxtb_T1(void)
724 b5ff1b31 bellard
{
725 b5ff1b31 bellard
    T1 = (uint8_t)T1;
726 b5ff1b31 bellard
}
727 b5ff1b31 bellard
728 b5ff1b31 bellard
void OPPROTO op_uxth_T1(void)
729 b5ff1b31 bellard
{
730 b5ff1b31 bellard
    T1 = (uint16_t)T1;
731 b5ff1b31 bellard
}
732 b5ff1b31 bellard
733 b5ff1b31 bellard
void OPPROTO op_sxtb16_T1(void)
734 b5ff1b31 bellard
{
735 b5ff1b31 bellard
    uint32_t res;
736 b5ff1b31 bellard
    res = (uint16_t)(int8_t)T1;
737 b5ff1b31 bellard
    res |= (uint32_t)(int8_t)(T1 >> 16) << 16;
738 b5ff1b31 bellard
    T1 = res;
739 b5ff1b31 bellard
}
740 b5ff1b31 bellard
741 b5ff1b31 bellard
void OPPROTO op_uxtb16_T1(void)
742 b5ff1b31 bellard
{
743 b5ff1b31 bellard
    uint32_t res;
744 b5ff1b31 bellard
    res = (uint16_t)(uint8_t)T1;
745 b5ff1b31 bellard
    res |= (uint32_t)(uint8_t)(T1 >> 16) << 16;
746 b5ff1b31 bellard
    T1 = res;
747 b5ff1b31 bellard
}
748 b5ff1b31 bellard
749 99c475ab bellard
#define SIGNBIT (uint32_t)0x80000000
750 99c475ab bellard
/* saturating arithmetic  */
751 99c475ab bellard
void OPPROTO op_addl_T0_T1_setq(void)
752 99c475ab bellard
{
753 99c475ab bellard
  uint32_t res;
754 99c475ab bellard
755 99c475ab bellard
  res = T0 + T1;
756 99c475ab bellard
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
757 99c475ab bellard
      env->QF = 1;
758 99c475ab bellard
759 99c475ab bellard
  T0 = res;
760 99c475ab bellard
  FORCE_RET();
761 99c475ab bellard
}
762 99c475ab bellard
763 99c475ab bellard
void OPPROTO op_addl_T0_T1_saturate(void)
764 99c475ab bellard
{
765 99c475ab bellard
  uint32_t res;
766 99c475ab bellard
767 99c475ab bellard
  res = T0 + T1;
768 99c475ab bellard
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
769 99c475ab bellard
      env->QF = 1;
770 99c475ab bellard
      if (T0 & SIGNBIT)
771 99c475ab bellard
          T0 = 0x80000000;
772 99c475ab bellard
      else
773 99c475ab bellard
          T0 = 0x7fffffff;
774 99c475ab bellard
  }
775 99c475ab bellard
  else
776 99c475ab bellard
    T0 = res;
777 5fafdf24 ths
 
778 99c475ab bellard
  FORCE_RET();
779 99c475ab bellard
}
780 99c475ab bellard
781 99c475ab bellard
void OPPROTO op_subl_T0_T1_saturate(void)
782 99c475ab bellard
{
783 99c475ab bellard
  uint32_t res;
784 99c475ab bellard
785 99c475ab bellard
  res = T0 - T1;
786 99c475ab bellard
  if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
787 99c475ab bellard
      env->QF = 1;
788 99c475ab bellard
      if (T0 & SIGNBIT)
789 567d4107 bellard
          T0 = 0x80000000;
790 99c475ab bellard
      else
791 99c475ab bellard
          T0 = 0x7fffffff;
792 99c475ab bellard
  }
793 99c475ab bellard
  else
794 99c475ab bellard
    T0 = res;
795 5fafdf24 ths
 
796 99c475ab bellard
  FORCE_RET();
797 99c475ab bellard
}
798 99c475ab bellard
799 ff8263a9 bellard
void OPPROTO op_double_T1_saturate(void)
800 ff8263a9 bellard
{
801 ff8263a9 bellard
  int32_t val;
802 ff8263a9 bellard
803 ff8263a9 bellard
  val = T1;
804 ff8263a9 bellard
  if (val >= 0x40000000) {
805 ff8263a9 bellard
      T1 = 0x7fffffff;
806 ff8263a9 bellard
      env->QF = 1;
807 ff8263a9 bellard
  } else if (val <= (int32_t)0xc0000000) {
808 ff8263a9 bellard
      T1 = 0x80000000;
809 ff8263a9 bellard
      env->QF = 1;
810 ff8263a9 bellard
  } else {
811 ff8263a9 bellard
      T1 = val << 1;
812 ff8263a9 bellard
  }
813 ff8263a9 bellard
  FORCE_RET();
814 ff8263a9 bellard
}
815 ff8263a9 bellard
816 99c475ab bellard
/* thumb shift by immediate */
817 99c475ab bellard
void OPPROTO op_shll_T0_im_thumb(void)
818 99c475ab bellard
{
819 99c475ab bellard
    int shift;
820 99c475ab bellard
    shift = PARAM1;
821 99c475ab bellard
    if (shift != 0) {
822 aa268ea6 pbrook
        env->CF = (T0 >> (32 - shift)) & 1;
823 99c475ab bellard
        T0 = T0 << shift;
824 99c475ab bellard
    }
825 99c475ab bellard
    env->NZF = T0;
826 99c475ab bellard
    FORCE_RET();
827 99c475ab bellard
}
828 99c475ab bellard
829 99c475ab bellard
void OPPROTO op_shrl_T0_im_thumb(void)
830 99c475ab bellard
{
831 99c475ab bellard
    int shift;
832 99c475ab bellard
833 99c475ab bellard
    shift = PARAM1;
834 99c475ab bellard
    if (shift == 0) {
835 aa268ea6 pbrook
        env->CF = ((uint32_t)T0) >> 31;
836 99c475ab bellard
        T0 = 0;
837 99c475ab bellard
    } else {
838 99c475ab bellard
        env->CF = (T0 >> (shift - 1)) & 1;
839 99c475ab bellard
        T0 = T0 >> shift;
840 99c475ab bellard
    }
841 5899f386 bellard
    env->NZF = T0;
842 99c475ab bellard
    FORCE_RET();
843 99c475ab bellard
}
844 99c475ab bellard
845 99c475ab bellard
void OPPROTO op_sarl_T0_im_thumb(void)
846 99c475ab bellard
{
847 99c475ab bellard
    int shift;
848 99c475ab bellard
849 99c475ab bellard
    shift = PARAM1;
850 99c475ab bellard
    if (shift == 0) {
851 99c475ab bellard
        T0 = ((int32_t)T0) >> 31;
852 99c475ab bellard
        env->CF = T0 & 1;
853 99c475ab bellard
    } else {
854 99c475ab bellard
        env->CF = (T0 >> (shift - 1)) & 1;
855 99c475ab bellard
        T0 = ((int32_t)T0) >> shift;
856 99c475ab bellard
    }
857 99c475ab bellard
    env->NZF = T0;
858 99c475ab bellard
    FORCE_RET();
859 99c475ab bellard
}
860 99c475ab bellard
861 2c0262af bellard
/* exceptions */
862 2c0262af bellard
863 2c0262af bellard
void OPPROTO op_swi(void)
864 2c0262af bellard
{
865 2c0262af bellard
    env->exception_index = EXCP_SWI;
866 2c0262af bellard
    cpu_loop_exit();
867 2c0262af bellard
}
868 2c0262af bellard
869 2c0262af bellard
void OPPROTO op_undef_insn(void)
870 2c0262af bellard
{
871 2c0262af bellard
    env->exception_index = EXCP_UDEF;
872 2c0262af bellard
    cpu_loop_exit();
873 2c0262af bellard
}
874 2c0262af bellard
875 1fddef4b bellard
void OPPROTO op_debug(void)
876 1fddef4b bellard
{
877 1fddef4b bellard
    env->exception_index = EXCP_DEBUG;
878 1fddef4b bellard
    cpu_loop_exit();
879 1fddef4b bellard
}
880 1fddef4b bellard
881 9332f9da bellard
void OPPROTO op_wfi(void)
882 9332f9da bellard
{
883 9332f9da bellard
    env->exception_index = EXCP_HLT;
884 9332f9da bellard
    env->halted = 1;
885 9332f9da bellard
    cpu_loop_exit();
886 9332f9da bellard
}
887 9332f9da bellard
888 06c949e6 pbrook
void OPPROTO op_bkpt(void)
889 06c949e6 pbrook
{
890 06c949e6 pbrook
    env->exception_index = EXCP_BKPT;
891 06c949e6 pbrook
    cpu_loop_exit();
892 06c949e6 pbrook
}
893 06c949e6 pbrook
894 b7bcbe95 bellard
/* VFP support.  We follow the convention used for VFP instrunctions:
895 b7bcbe95 bellard
   Single precition routines have a "s" suffix, double precision a
896 b7bcbe95 bellard
   "d" suffix.  */
897 2c0262af bellard
898 b7bcbe95 bellard
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
899 2c0262af bellard
900 53cd6637 bellard
#define VFP_BINOP(name) \
901 b7bcbe95 bellard
VFP_OP(name, s)             \
902 b7bcbe95 bellard
{                           \
903 53cd6637 bellard
    FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status);    \
904 b7bcbe95 bellard
}                           \
905 b7bcbe95 bellard
VFP_OP(name, d)             \
906 b7bcbe95 bellard
{                           \
907 53cd6637 bellard
    FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status);    \
908 b7bcbe95 bellard
}
909 53cd6637 bellard
VFP_BINOP(add)
910 53cd6637 bellard
VFP_BINOP(sub)
911 53cd6637 bellard
VFP_BINOP(mul)
912 53cd6637 bellard
VFP_BINOP(div)
913 b7bcbe95 bellard
#undef VFP_BINOP
914 b7bcbe95 bellard
915 b7bcbe95 bellard
#define VFP_HELPER(name)  \
916 b7bcbe95 bellard
VFP_OP(name, s)           \
917 b7bcbe95 bellard
{                         \
918 b7bcbe95 bellard
    do_vfp_##name##s();    \
919 b7bcbe95 bellard
}                         \
920 b7bcbe95 bellard
VFP_OP(name, d)           \
921 b7bcbe95 bellard
{                         \
922 b7bcbe95 bellard
    do_vfp_##name##d();    \
923 b7bcbe95 bellard
}
924 b7bcbe95 bellard
VFP_HELPER(abs)
925 b7bcbe95 bellard
VFP_HELPER(sqrt)
926 b7bcbe95 bellard
VFP_HELPER(cmp)
927 b7bcbe95 bellard
VFP_HELPER(cmpe)
928 b7bcbe95 bellard
#undef VFP_HELPER
929 b7bcbe95 bellard
930 b7bcbe95 bellard
/* XXX: Will this do the right thing for NANs.  Should invert the signbit
931 b7bcbe95 bellard
   without looking at the rest of the value.  */
932 b7bcbe95 bellard
VFP_OP(neg, s)
933 b7bcbe95 bellard
{
934 53cd6637 bellard
    FT0s = float32_chs(FT0s);
935 b7bcbe95 bellard
}
936 b7bcbe95 bellard
937 b7bcbe95 bellard
VFP_OP(neg, d)
938 b7bcbe95 bellard
{
939 53cd6637 bellard
    FT0d = float64_chs(FT0d);
940 b7bcbe95 bellard
}
941 b7bcbe95 bellard
942 b7bcbe95 bellard
VFP_OP(F1_ld0, s)
943 b7bcbe95 bellard
{
944 53cd6637 bellard
    union {
945 53cd6637 bellard
        uint32_t i;
946 53cd6637 bellard
        float32 s;
947 53cd6637 bellard
    } v;
948 53cd6637 bellard
    v.i = 0;
949 53cd6637 bellard
    FT1s = v.s;
950 b7bcbe95 bellard
}
951 b7bcbe95 bellard
952 b7bcbe95 bellard
VFP_OP(F1_ld0, d)
953 b7bcbe95 bellard
{
954 53cd6637 bellard
    union {
955 53cd6637 bellard
        uint64_t i;
956 53cd6637 bellard
        float64 d;
957 53cd6637 bellard
    } v;
958 53cd6637 bellard
    v.i = 0;
959 53cd6637 bellard
    FT1d = v.d;
960 b7bcbe95 bellard
}
961 b7bcbe95 bellard
962 b7bcbe95 bellard
/* Helper routines to perform bitwise copies between float and int.  */
963 53cd6637 bellard
static inline float32 vfp_itos(uint32_t i)
964 b7bcbe95 bellard
{
965 b7bcbe95 bellard
    union {
966 b7bcbe95 bellard
        uint32_t i;
967 53cd6637 bellard
        float32 s;
968 b7bcbe95 bellard
    } v;
969 b7bcbe95 bellard
970 b7bcbe95 bellard
    v.i = i;
971 b7bcbe95 bellard
    return v.s;
972 b7bcbe95 bellard
}
973 b7bcbe95 bellard
974 53cd6637 bellard
static inline uint32_t vfp_stoi(float32 s)
975 b7bcbe95 bellard
{
976 b7bcbe95 bellard
    union {
977 b7bcbe95 bellard
        uint32_t i;
978 53cd6637 bellard
        float32 s;
979 b7bcbe95 bellard
    } v;
980 b7bcbe95 bellard
981 b7bcbe95 bellard
    v.s = s;
982 b7bcbe95 bellard
    return v.i;
983 b7bcbe95 bellard
}
984 b7bcbe95 bellard
985 b7bcbe95 bellard
/* Integer to float conversion.  */
986 b7bcbe95 bellard
VFP_OP(uito, s)
987 b7bcbe95 bellard
{
988 53cd6637 bellard
    FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
989 b7bcbe95 bellard
}
990 b7bcbe95 bellard
991 b7bcbe95 bellard
VFP_OP(uito, d)
992 b7bcbe95 bellard
{
993 53cd6637 bellard
    FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
994 b7bcbe95 bellard
}
995 b7bcbe95 bellard
996 b7bcbe95 bellard
VFP_OP(sito, s)
997 b7bcbe95 bellard
{
998 53cd6637 bellard
    FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
999 b7bcbe95 bellard
}
1000 b7bcbe95 bellard
1001 b7bcbe95 bellard
VFP_OP(sito, d)
1002 b7bcbe95 bellard
{
1003 53cd6637 bellard
    FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
1004 b7bcbe95 bellard
}
1005 b7bcbe95 bellard
1006 b7bcbe95 bellard
/* Float to integer conversion.  */
1007 b7bcbe95 bellard
VFP_OP(toui, s)
1008 b7bcbe95 bellard
{
1009 53cd6637 bellard
    FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
1010 b7bcbe95 bellard
}
1011 b7bcbe95 bellard
1012 b7bcbe95 bellard
VFP_OP(toui, d)
1013 b7bcbe95 bellard
{
1014 53cd6637 bellard
    FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
1015 b7bcbe95 bellard
}
1016 b7bcbe95 bellard
1017 b7bcbe95 bellard
VFP_OP(tosi, s)
1018 b7bcbe95 bellard
{
1019 53cd6637 bellard
    FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
1020 b7bcbe95 bellard
}
1021 b7bcbe95 bellard
1022 b7bcbe95 bellard
VFP_OP(tosi, d)
1023 b7bcbe95 bellard
{
1024 53cd6637 bellard
    FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
1025 b7bcbe95 bellard
}
1026 b7bcbe95 bellard
1027 b7bcbe95 bellard
/* TODO: Set rounding mode properly.  */
1028 b7bcbe95 bellard
VFP_OP(touiz, s)
1029 b7bcbe95 bellard
{
1030 53cd6637 bellard
    FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
1031 b7bcbe95 bellard
}
1032 b7bcbe95 bellard
1033 b7bcbe95 bellard
VFP_OP(touiz, d)
1034 b7bcbe95 bellard
{
1035 53cd6637 bellard
    FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
1036 b7bcbe95 bellard
}
1037 b7bcbe95 bellard
1038 b7bcbe95 bellard
VFP_OP(tosiz, s)
1039 b7bcbe95 bellard
{
1040 53cd6637 bellard
    FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
1041 b7bcbe95 bellard
}
1042 b7bcbe95 bellard
1043 b7bcbe95 bellard
VFP_OP(tosiz, d)
1044 2c0262af bellard
{
1045 53cd6637 bellard
    FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
1046 2c0262af bellard
}
1047 2c0262af bellard
1048 b7bcbe95 bellard
/* floating point conversion */
1049 b7bcbe95 bellard
VFP_OP(fcvtd, s)
1050 2c0262af bellard
{
1051 53cd6637 bellard
    FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
1052 2c0262af bellard
}
1053 2c0262af bellard
1054 b7bcbe95 bellard
VFP_OP(fcvts, d)
1055 b7bcbe95 bellard
{
1056 53cd6637 bellard
    FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
1057 b7bcbe95 bellard
}
1058 b7bcbe95 bellard
1059 b7bcbe95 bellard
/* Get and Put values from registers.  */
1060 b7bcbe95 bellard
VFP_OP(getreg_F0, d)
1061 b7bcbe95 bellard
{
1062 53cd6637 bellard
  FT0d = *(float64 *)((char *) env + PARAM1);
1063 b7bcbe95 bellard
}
1064 b7bcbe95 bellard
1065 b7bcbe95 bellard
VFP_OP(getreg_F0, s)
1066 b7bcbe95 bellard
{
1067 53cd6637 bellard
  FT0s = *(float32 *)((char *) env + PARAM1);
1068 b7bcbe95 bellard
}
1069 b7bcbe95 bellard
1070 b7bcbe95 bellard
VFP_OP(getreg_F1, d)
1071 b7bcbe95 bellard
{
1072 53cd6637 bellard
  FT1d = *(float64 *)((char *) env + PARAM1);
1073 b7bcbe95 bellard
}
1074 b7bcbe95 bellard
1075 b7bcbe95 bellard
VFP_OP(getreg_F1, s)
1076 b7bcbe95 bellard
{
1077 53cd6637 bellard
  FT1s = *(float32 *)((char *) env + PARAM1);
1078 b7bcbe95 bellard
}
1079 b7bcbe95 bellard
1080 b7bcbe95 bellard
VFP_OP(setreg_F0, d)
1081 b7bcbe95 bellard
{
1082 53cd6637 bellard
  *(float64 *)((char *) env + PARAM1) = FT0d;
1083 b7bcbe95 bellard
}
1084 b7bcbe95 bellard
1085 b7bcbe95 bellard
VFP_OP(setreg_F0, s)
1086 b7bcbe95 bellard
{
1087 53cd6637 bellard
  *(float32 *)((char *) env + PARAM1) = FT0s;
1088 b7bcbe95 bellard
}
1089 b7bcbe95 bellard
1090 b7bcbe95 bellard
void OPPROTO op_vfp_movl_T0_fpscr(void)
1091 b7bcbe95 bellard
{
1092 b7bcbe95 bellard
    do_vfp_get_fpscr ();
1093 b7bcbe95 bellard
}
1094 b7bcbe95 bellard
1095 b7bcbe95 bellard
void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
1096 b7bcbe95 bellard
{
1097 40f137e1 pbrook
    T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
1098 b7bcbe95 bellard
}
1099 b7bcbe95 bellard
1100 b7bcbe95 bellard
void OPPROTO op_vfp_movl_fpscr_T0(void)
1101 b7bcbe95 bellard
{
1102 b7bcbe95 bellard
    do_vfp_set_fpscr();
1103 b7bcbe95 bellard
}
1104 b7bcbe95 bellard
1105 40f137e1 pbrook
void OPPROTO op_vfp_movl_T0_xreg(void)
1106 40f137e1 pbrook
{
1107 40f137e1 pbrook
    T0 = env->vfp.xregs[PARAM1];
1108 40f137e1 pbrook
}
1109 40f137e1 pbrook
1110 40f137e1 pbrook
void OPPROTO op_vfp_movl_xreg_T0(void)
1111 40f137e1 pbrook
{
1112 40f137e1 pbrook
    env->vfp.xregs[PARAM1] = T0;
1113 40f137e1 pbrook
}
1114 40f137e1 pbrook
1115 b7bcbe95 bellard
/* Move between FT0s to T0  */
1116 b7bcbe95 bellard
void OPPROTO op_vfp_mrs(void)
1117 b7bcbe95 bellard
{
1118 b7bcbe95 bellard
    T0 = vfp_stoi(FT0s);
1119 b7bcbe95 bellard
}
1120 b7bcbe95 bellard
1121 b7bcbe95 bellard
void OPPROTO op_vfp_msr(void)
1122 b7bcbe95 bellard
{
1123 b7bcbe95 bellard
    FT0s = vfp_itos(T0);
1124 b7bcbe95 bellard
}
1125 b7bcbe95 bellard
1126 b7bcbe95 bellard
/* Move between FT0d and {T0,T1} */
1127 b7bcbe95 bellard
void OPPROTO op_vfp_mrrd(void)
1128 b7bcbe95 bellard
{
1129 b7bcbe95 bellard
    CPU_DoubleU u;
1130 5fafdf24 ths
   
1131 b7bcbe95 bellard
    u.d = FT0d;
1132 b7bcbe95 bellard
    T0 = u.l.lower;
1133 b7bcbe95 bellard
    T1 = u.l.upper;
1134 b7bcbe95 bellard
}
1135 b7bcbe95 bellard
1136 b7bcbe95 bellard
void OPPROTO op_vfp_mdrr(void)
1137 b7bcbe95 bellard
{
1138 b7bcbe95 bellard
    CPU_DoubleU u;
1139 5fafdf24 ths
   
1140 b7bcbe95 bellard
    u.l.lower = T0;
1141 b7bcbe95 bellard
    u.l.upper = T1;
1142 b7bcbe95 bellard
    FT0d = u.d;
1143 b7bcbe95 bellard
}
1144 b7bcbe95 bellard
1145 c1713132 balrog
/* Copy the most significant bit of T0 to all bits of T1.  */
1146 b5ff1b31 bellard
void OPPROTO op_signbit_T1_T0(void)
1147 b7bcbe95 bellard
{
1148 b5ff1b31 bellard
    T1 = (int32_t)T0 >> 31;
1149 b7bcbe95 bellard
}
1150 b7bcbe95 bellard
1151 c1713132 balrog
void OPPROTO op_movl_cp_T0(void)
1152 c1713132 balrog
{
1153 c1713132 balrog
    helper_set_cp(env, PARAM1, T0);
1154 c1713132 balrog
    FORCE_RET();
1155 c1713132 balrog
}
1156 c1713132 balrog
1157 c1713132 balrog
void OPPROTO op_movl_T0_cp(void)
1158 c1713132 balrog
{
1159 c1713132 balrog
    T0 = helper_get_cp(env, PARAM1);
1160 c1713132 balrog
    FORCE_RET();
1161 c1713132 balrog
}
1162 c1713132 balrog
1163 b5ff1b31 bellard
void OPPROTO op_movl_cp15_T0(void)
1164 b7bcbe95 bellard
{
1165 b5ff1b31 bellard
    helper_set_cp15(env, PARAM1, T0);
1166 b5ff1b31 bellard
    FORCE_RET();
1167 b7bcbe95 bellard
}
1168 b7bcbe95 bellard
1169 b5ff1b31 bellard
void OPPROTO op_movl_T0_cp15(void)
1170 b7bcbe95 bellard
{
1171 b5ff1b31 bellard
    T0 = helper_get_cp15(env, PARAM1);
1172 b5ff1b31 bellard
    FORCE_RET();
1173 b7bcbe95 bellard
}
1174 b7bcbe95 bellard
1175 b5ff1b31 bellard
/* Access to user mode registers from privileged modes.  */
1176 b5ff1b31 bellard
void OPPROTO op_movl_T0_user(void)
1177 b7bcbe95 bellard
{
1178 b5ff1b31 bellard
    int regno = PARAM1;
1179 b5ff1b31 bellard
    if (regno == 13) {
1180 b5ff1b31 bellard
        T0 = env->banked_r13[0];
1181 b5ff1b31 bellard
    } else if (regno == 14) {
1182 b5ff1b31 bellard
        T0 = env->banked_r14[0];
1183 b5ff1b31 bellard
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1184 b5ff1b31 bellard
        T0 = env->usr_regs[regno - 8];
1185 b5ff1b31 bellard
    } else {
1186 b5ff1b31 bellard
        T0 = env->regs[regno];
1187 b5ff1b31 bellard
    }
1188 b5ff1b31 bellard
    FORCE_RET();
1189 b5ff1b31 bellard
}
1190 b5ff1b31 bellard
1191 b5ff1b31 bellard
1192 b5ff1b31 bellard
void OPPROTO op_movl_user_T0(void)
1193 b5ff1b31 bellard
{
1194 b5ff1b31 bellard
    int regno = PARAM1;
1195 b5ff1b31 bellard
    if (regno == 13) {
1196 b5ff1b31 bellard
        env->banked_r13[0] = T0;
1197 b5ff1b31 bellard
    } else if (regno == 14) {
1198 b5ff1b31 bellard
        env->banked_r14[0] = T0;
1199 b5ff1b31 bellard
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1200 b5ff1b31 bellard
        env->usr_regs[regno - 8] = T0;
1201 b5ff1b31 bellard
    } else {
1202 b5ff1b31 bellard
        env->regs[regno] = T0;
1203 b5ff1b31 bellard
    }
1204 b5ff1b31 bellard
    FORCE_RET();
1205 b7bcbe95 bellard
}
1206 191abaa2 pbrook
1207 191abaa2 pbrook
void OPPROTO op_movl_T2_T0(void)
1208 191abaa2 pbrook
{
1209 191abaa2 pbrook
    T2 = T0;
1210 191abaa2 pbrook
}
1211 191abaa2 pbrook
1212 191abaa2 pbrook
void OPPROTO op_movl_T0_T2(void)
1213 191abaa2 pbrook
{
1214 191abaa2 pbrook
    T0 = T2;
1215 191abaa2 pbrook
}
1216 18c9b560 balrog
1217 18c9b560 balrog
/* iwMMXt support */
1218 18c9b560 balrog
#include "op_iwmmxt.c"