Statistics
| Branch: | Revision:

root / op-arm.c @ b67d5959

History | View | Annotate | Download (12.7 kB)

1 5898e816 bellard
/*
2 5898e816 bellard
 *  ARM micro operations
3 5898e816 bellard
 * 
4 5898e816 bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 5898e816 bellard
 *
6 5898e816 bellard
 * This library is free software; you can redistribute it and/or
7 5898e816 bellard
 * modify it under the terms of the GNU Lesser General Public
8 5898e816 bellard
 * License as published by the Free Software Foundation; either
9 5898e816 bellard
 * version 2 of the License, or (at your option) any later version.
10 5898e816 bellard
 *
11 5898e816 bellard
 * This library is distributed in the hope that it will be useful,
12 5898e816 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 5898e816 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 5898e816 bellard
 * Lesser General Public License for more details.
15 5898e816 bellard
 *
16 5898e816 bellard
 * You should have received a copy of the GNU Lesser General Public
17 5898e816 bellard
 * License along with this library; if not, write to the Free Software
18 5898e816 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 5898e816 bellard
 */
20 5898e816 bellard
#include "exec-arm.h"
21 5898e816 bellard
22 5898e816 bellard
#define REGNAME r0
23 5898e816 bellard
#define REG (env->regs[0])
24 5898e816 bellard
#include "op-arm-template.h"
25 5898e816 bellard
26 5898e816 bellard
#define REGNAME r1
27 5898e816 bellard
#define REG (env->regs[1])
28 5898e816 bellard
#include "op-arm-template.h"
29 5898e816 bellard
30 5898e816 bellard
#define REGNAME r2
31 5898e816 bellard
#define REG (env->regs[2])
32 5898e816 bellard
#include "op-arm-template.h"
33 5898e816 bellard
34 5898e816 bellard
#define REGNAME r3
35 5898e816 bellard
#define REG (env->regs[3])
36 5898e816 bellard
#include "op-arm-template.h"
37 5898e816 bellard
38 5898e816 bellard
#define REGNAME r4
39 5898e816 bellard
#define REG (env->regs[4])
40 5898e816 bellard
#include "op-arm-template.h"
41 5898e816 bellard
42 5898e816 bellard
#define REGNAME r5
43 5898e816 bellard
#define REG (env->regs[5])
44 5898e816 bellard
#include "op-arm-template.h"
45 5898e816 bellard
46 5898e816 bellard
#define REGNAME r6
47 5898e816 bellard
#define REG (env->regs[6])
48 5898e816 bellard
#include "op-arm-template.h"
49 5898e816 bellard
50 5898e816 bellard
#define REGNAME r7
51 5898e816 bellard
#define REG (env->regs[7])
52 5898e816 bellard
#include "op-arm-template.h"
53 5898e816 bellard
54 5898e816 bellard
#define REGNAME r8
55 5898e816 bellard
#define REG (env->regs[8])
56 5898e816 bellard
#include "op-arm-template.h"
57 5898e816 bellard
58 5898e816 bellard
#define REGNAME r9
59 5898e816 bellard
#define REG (env->regs[9])
60 5898e816 bellard
#include "op-arm-template.h"
61 5898e816 bellard
62 5898e816 bellard
#define REGNAME r10
63 5898e816 bellard
#define REG (env->regs[10])
64 5898e816 bellard
#include "op-arm-template.h"
65 5898e816 bellard
66 5898e816 bellard
#define REGNAME r11
67 5898e816 bellard
#define REG (env->regs[11])
68 5898e816 bellard
#include "op-arm-template.h"
69 5898e816 bellard
70 5898e816 bellard
#define REGNAME r12
71 5898e816 bellard
#define REG (env->regs[12])
72 5898e816 bellard
#include "op-arm-template.h"
73 5898e816 bellard
74 5898e816 bellard
#define REGNAME r13
75 5898e816 bellard
#define REG (env->regs[13])
76 5898e816 bellard
#include "op-arm-template.h"
77 5898e816 bellard
78 5898e816 bellard
#define REGNAME r14
79 5898e816 bellard
#define REG (env->regs[14])
80 5898e816 bellard
#include "op-arm-template.h"
81 5898e816 bellard
82 5898e816 bellard
#define REGNAME r15
83 5898e816 bellard
#define REG (env->regs[15])
84 5898e816 bellard
#include "op-arm-template.h"
85 5898e816 bellard
86 5898e816 bellard
void OPPROTO op_movl_T0_0(void)
87 5898e816 bellard
{
88 5898e816 bellard
    T0 = 0;
89 5898e816 bellard
}
90 5898e816 bellard
91 5898e816 bellard
void OPPROTO op_movl_T0_im(void)
92 5898e816 bellard
{
93 5898e816 bellard
    T0 = PARAM1;
94 5898e816 bellard
}
95 5898e816 bellard
96 5898e816 bellard
void OPPROTO op_movl_T1_im(void)
97 5898e816 bellard
{
98 5898e816 bellard
    T1 = PARAM1;
99 5898e816 bellard
}
100 5898e816 bellard
101 5898e816 bellard
void OPPROTO op_movl_T2_im(void)
102 5898e816 bellard
{
103 5898e816 bellard
    T2 = PARAM1;
104 5898e816 bellard
}
105 5898e816 bellard
106 5898e816 bellard
void OPPROTO op_addl_T1_im(void)
107 5898e816 bellard
{
108 5898e816 bellard
    T1 += PARAM1;
109 5898e816 bellard
}
110 5898e816 bellard
111 5898e816 bellard
void OPPROTO op_addl_T1_T2(void)
112 5898e816 bellard
{
113 5898e816 bellard
    T1 += T2;
114 5898e816 bellard
}
115 5898e816 bellard
116 5898e816 bellard
void OPPROTO op_subl_T1_T2(void)
117 5898e816 bellard
{
118 5898e816 bellard
    T1 -= T2;
119 5898e816 bellard
}
120 5898e816 bellard
121 5898e816 bellard
void OPPROTO op_addl_T0_T1(void)
122 5898e816 bellard
{
123 5898e816 bellard
    T0 += T1;
124 5898e816 bellard
}
125 5898e816 bellard
126 5898e816 bellard
void OPPROTO op_addl_T0_T1_cc(void)
127 5898e816 bellard
{
128 5898e816 bellard
    unsigned int src1;
129 5898e816 bellard
    src1 = T0;
130 5898e816 bellard
    T0 += T1;
131 5898e816 bellard
    env->NZF = T0;
132 5898e816 bellard
    env->CF = T0 < src1;
133 5898e816 bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
134 5898e816 bellard
}
135 5898e816 bellard
136 5898e816 bellard
void OPPROTO op_adcl_T0_T1(void)
137 5898e816 bellard
{
138 5898e816 bellard
    T0 += T1 + env->CF;
139 5898e816 bellard
}
140 5898e816 bellard
141 5898e816 bellard
void OPPROTO op_adcl_T0_T1_cc(void)
142 5898e816 bellard
{
143 5898e816 bellard
    unsigned int src1;
144 5898e816 bellard
    src1 = T0;
145 5898e816 bellard
    if (!env->CF) {
146 5898e816 bellard
        T0 += T1;
147 5898e816 bellard
        env->CF = T0 < src1;
148 5898e816 bellard
    } else {
149 5898e816 bellard
        T0 += T1 + 1;
150 5898e816 bellard
        env->CF = T0 <= src1;
151 5898e816 bellard
    }
152 5898e816 bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
153 5898e816 bellard
    env->NZF = T0;
154 5898e816 bellard
    FORCE_RET();
155 5898e816 bellard
}
156 5898e816 bellard
157 6e295807 bellard
#define OPSUB(sub, sbc, res, T0, T1)            \
158 5898e816 bellard
                                                \
159 5898e816 bellard
void OPPROTO op_ ## sub ## l_T0_T1(void)        \
160 5898e816 bellard
{                                               \
161 6e295807 bellard
    res = T0 - T1;                              \
162 5898e816 bellard
}                                               \
163 5898e816 bellard
                                                \
164 5898e816 bellard
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
165 5898e816 bellard
{                                               \
166 5898e816 bellard
    unsigned int src1;                          \
167 5898e816 bellard
    src1 = T0;                                  \
168 5898e816 bellard
    T0 -= T1;                                   \
169 5898e816 bellard
    env->NZF = T0;                              \
170 6e295807 bellard
    env->CF = src1 >= T1;                       \
171 5898e816 bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
172 6e295807 bellard
    res = T0;                                   \
173 5898e816 bellard
}                                               \
174 5898e816 bellard
                                                \
175 5898e816 bellard
void OPPROTO op_ ## sbc ## l_T0_T1(void)        \
176 5898e816 bellard
{                                               \
177 6e295807 bellard
    res = T0 - T1 + env->CF - 1;                \
178 5898e816 bellard
}                                               \
179 5898e816 bellard
                                                \
180 5898e816 bellard
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
181 5898e816 bellard
{                                               \
182 5898e816 bellard
    unsigned int src1;                          \
183 5898e816 bellard
    src1 = T0;                                  \
184 5898e816 bellard
    if (!env->CF) {                             \
185 5898e816 bellard
        T0 = T0 - T1 - 1;                       \
186 6e295807 bellard
        env->CF = src1 >= T1;                   \
187 5898e816 bellard
    } else {                                    \
188 5898e816 bellard
        T0 = T0 - T1;                           \
189 6e295807 bellard
        env->CF = src1 > T1;                    \
190 5898e816 bellard
    }                                           \
191 5898e816 bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
192 5898e816 bellard
    env->NZF = T0;                              \
193 6e295807 bellard
    res = T0;                                   \
194 5898e816 bellard
    FORCE_RET();                                \
195 5898e816 bellard
}
196 5898e816 bellard
197 6e295807 bellard
OPSUB(sub, sbc, T0, T0, T1)
198 5898e816 bellard
199 6e295807 bellard
OPSUB(rsb, rsc, T0, T1, T0)
200 5898e816 bellard
201 5898e816 bellard
void OPPROTO op_andl_T0_T1(void)
202 5898e816 bellard
{
203 5898e816 bellard
    T0 &= T1;
204 5898e816 bellard
}
205 5898e816 bellard
206 5898e816 bellard
void OPPROTO op_xorl_T0_T1(void)
207 5898e816 bellard
{
208 5898e816 bellard
    T0 ^= T1;
209 5898e816 bellard
}
210 5898e816 bellard
211 5898e816 bellard
void OPPROTO op_orl_T0_T1(void)
212 5898e816 bellard
{
213 5898e816 bellard
    T0 |= T1;
214 5898e816 bellard
}
215 5898e816 bellard
216 5898e816 bellard
void OPPROTO op_bicl_T0_T1(void)
217 5898e816 bellard
{
218 5898e816 bellard
    T0 &= ~T1;
219 5898e816 bellard
}
220 5898e816 bellard
221 5898e816 bellard
void OPPROTO op_notl_T1(void)
222 5898e816 bellard
{
223 5898e816 bellard
    T1 = ~T1;
224 5898e816 bellard
}
225 5898e816 bellard
226 6e295807 bellard
void OPPROTO op_logic_T0_cc(void)
227 5898e816 bellard
{
228 5898e816 bellard
    env->NZF = T0;
229 5898e816 bellard
}
230 5898e816 bellard
231 6e295807 bellard
void OPPROTO op_logic_T1_cc(void)
232 6e295807 bellard
{
233 6e295807 bellard
    env->NZF = T1;
234 6e295807 bellard
}
235 6e295807 bellard
236 5898e816 bellard
#define EIP (env->regs[15])
237 5898e816 bellard
238 5898e816 bellard
void OPPROTO op_test_eq(void)
239 5898e816 bellard
{
240 5898e816 bellard
    if (env->NZF == 0)
241 25731098 bellard
        JUMP_TB(op_test_eq, PARAM1, 0, PARAM2);
242 5898e816 bellard
    FORCE_RET();
243 5898e816 bellard
}
244 5898e816 bellard
245 5898e816 bellard
void OPPROTO op_test_ne(void)
246 5898e816 bellard
{
247 5898e816 bellard
    if (env->NZF != 0)
248 25731098 bellard
        JUMP_TB(op_test_ne, PARAM1, 0, PARAM2);
249 5898e816 bellard
    FORCE_RET();
250 5898e816 bellard
}
251 5898e816 bellard
252 5898e816 bellard
void OPPROTO op_test_cs(void)
253 5898e816 bellard
{
254 5898e816 bellard
    if (env->CF != 0)
255 25731098 bellard
        JUMP_TB(op_test_cs, PARAM1, 0, PARAM2);
256 5898e816 bellard
    FORCE_RET();
257 5898e816 bellard
}
258 5898e816 bellard
259 5898e816 bellard
void OPPROTO op_test_cc(void)
260 5898e816 bellard
{
261 5898e816 bellard
    if (env->CF == 0)
262 25731098 bellard
        JUMP_TB(op_test_cc, PARAM1, 0, PARAM2);
263 5898e816 bellard
    FORCE_RET();
264 5898e816 bellard
}
265 5898e816 bellard
266 5898e816 bellard
void OPPROTO op_test_mi(void)
267 5898e816 bellard
{
268 5898e816 bellard
    if ((env->NZF & 0x80000000) != 0)
269 25731098 bellard
        JUMP_TB(op_test_mi, PARAM1, 0, PARAM2);
270 5898e816 bellard
    FORCE_RET();
271 5898e816 bellard
}
272 5898e816 bellard
273 5898e816 bellard
void OPPROTO op_test_pl(void)
274 5898e816 bellard
{
275 5898e816 bellard
    if ((env->NZF & 0x80000000) == 0)
276 25731098 bellard
        JUMP_TB(op_test_pl, PARAM1, 0, PARAM2);
277 5898e816 bellard
    FORCE_RET();
278 5898e816 bellard
}
279 5898e816 bellard
280 5898e816 bellard
void OPPROTO op_test_vs(void)
281 5898e816 bellard
{
282 5898e816 bellard
    if ((env->VF & 0x80000000) != 0)
283 25731098 bellard
        JUMP_TB(op_test_vs, PARAM1, 0, PARAM2);
284 5898e816 bellard
    FORCE_RET();
285 5898e816 bellard
}
286 5898e816 bellard
287 5898e816 bellard
void OPPROTO op_test_vc(void)
288 5898e816 bellard
{
289 5898e816 bellard
    if ((env->VF & 0x80000000) == 0)
290 25731098 bellard
        JUMP_TB(op_test_vc, PARAM1, 0, PARAM2);
291 5898e816 bellard
    FORCE_RET();
292 5898e816 bellard
}
293 5898e816 bellard
294 5898e816 bellard
void OPPROTO op_test_hi(void)
295 5898e816 bellard
{
296 5898e816 bellard
    if (env->CF != 0 && env->NZF != 0)
297 25731098 bellard
        JUMP_TB(op_test_hi, PARAM1, 0, PARAM2);
298 5898e816 bellard
    FORCE_RET();
299 5898e816 bellard
}
300 5898e816 bellard
301 5898e816 bellard
void OPPROTO op_test_ls(void)
302 5898e816 bellard
{
303 5898e816 bellard
    if (env->CF == 0 || env->NZF == 0)
304 25731098 bellard
        JUMP_TB(op_test_ls, PARAM1, 0, PARAM2);
305 5898e816 bellard
    FORCE_RET();
306 5898e816 bellard
}
307 5898e816 bellard
308 5898e816 bellard
void OPPROTO op_test_ge(void)
309 5898e816 bellard
{
310 5898e816 bellard
    if (((env->VF ^ env->NZF) & 0x80000000) == 0)
311 25731098 bellard
        JUMP_TB(op_test_ge, PARAM1, 0, PARAM2);
312 5898e816 bellard
    FORCE_RET();
313 5898e816 bellard
}
314 5898e816 bellard
315 5898e816 bellard
void OPPROTO op_test_lt(void)
316 5898e816 bellard
{
317 5898e816 bellard
    if (((env->VF ^ env->NZF) & 0x80000000) != 0)
318 25731098 bellard
        JUMP_TB(op_test_lt, PARAM1, 0, PARAM2);
319 5898e816 bellard
    FORCE_RET();
320 5898e816 bellard
}
321 5898e816 bellard
322 5898e816 bellard
void OPPROTO op_test_gt(void)
323 5898e816 bellard
{
324 5898e816 bellard
    if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
325 25731098 bellard
        JUMP_TB(op_test_gt, PARAM1, 0, PARAM2);
326 5898e816 bellard
    FORCE_RET();
327 5898e816 bellard
}
328 5898e816 bellard
329 5898e816 bellard
void OPPROTO op_test_le(void)
330 5898e816 bellard
{
331 5898e816 bellard
    if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
332 25731098 bellard
        JUMP_TB(op_test_le, PARAM1, 0, PARAM2);
333 5898e816 bellard
    FORCE_RET();
334 5898e816 bellard
}
335 5898e816 bellard
336 5898e816 bellard
void OPPROTO op_jmp(void)
337 5898e816 bellard
{
338 25731098 bellard
    JUMP_TB(op_jmp, PARAM1, 1, PARAM2);
339 5898e816 bellard
}
340 5898e816 bellard
341 9621339d bellard
void OPPROTO op_exit_tb(void)
342 9621339d bellard
{
343 9621339d bellard
    EXIT_TB();
344 9621339d bellard
}
345 9621339d bellard
346 5898e816 bellard
void OPPROTO op_movl_T0_psr(void)
347 5898e816 bellard
{
348 6e295807 bellard
    T0 = compute_cpsr();
349 5898e816 bellard
}
350 5898e816 bellard
351 5898e816 bellard
/* NOTE: N = 1 and Z = 1 cannot be stored currently */
352 5898e816 bellard
void OPPROTO op_movl_psr_T0(void)
353 5898e816 bellard
{
354 5898e816 bellard
    unsigned int psr;
355 5898e816 bellard
    psr = T0;
356 5898e816 bellard
    env->CF = (psr >> 29) & 1;
357 5898e816 bellard
    env->NZF = (psr & 0xc0000000) ^ 0x40000000;
358 5898e816 bellard
    env->VF = (psr << 3) & 0x80000000;
359 5898e816 bellard
    /* for user mode we do not update other state info */
360 5898e816 bellard
}
361 5898e816 bellard
362 5898e816 bellard
void OPPROTO op_mul_T0_T1(void)
363 5898e816 bellard
{
364 5898e816 bellard
    T0 = T0 * T1;
365 5898e816 bellard
}
366 5898e816 bellard
367 5898e816 bellard
/* 64 bit unsigned mul */
368 5898e816 bellard
void OPPROTO op_mull_T0_T1(void)
369 5898e816 bellard
{
370 5898e816 bellard
    uint64_t res;
371 5898e816 bellard
    res = T0 * T1;
372 5898e816 bellard
    T1 = res >> 32;
373 5898e816 bellard
    T0 = res;
374 5898e816 bellard
}
375 5898e816 bellard
376 5898e816 bellard
/* 64 bit signed mul */
377 5898e816 bellard
void OPPROTO op_imull_T0_T1(void)
378 5898e816 bellard
{
379 5898e816 bellard
    uint64_t res;
380 5898e816 bellard
    res = (int32_t)T0 * (int32_t)T1;
381 5898e816 bellard
    T1 = res >> 32;
382 5898e816 bellard
    T0 = res;
383 5898e816 bellard
}
384 5898e816 bellard
385 5898e816 bellard
void OPPROTO op_addq_T0_T1(void)
386 5898e816 bellard
{
387 5898e816 bellard
    uint64_t res;
388 5898e816 bellard
    res = ((uint64_t)T1 << 32) | T0;
389 5898e816 bellard
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
390 5898e816 bellard
    T1 = res >> 32;
391 5898e816 bellard
    T0 = res;
392 5898e816 bellard
}
393 5898e816 bellard
394 5898e816 bellard
void OPPROTO op_logicq_cc(void)
395 5898e816 bellard
{
396 5898e816 bellard
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
397 5898e816 bellard
}
398 5898e816 bellard
399 5898e816 bellard
/* memory access */
400 5898e816 bellard
401 5898e816 bellard
void OPPROTO op_ldub_T0_T1(void)
402 5898e816 bellard
{
403 5898e816 bellard
    T0 = ldub((void *)T1);
404 5898e816 bellard
}
405 5898e816 bellard
406 5898e816 bellard
void OPPROTO op_ldsb_T0_T1(void)
407 5898e816 bellard
{
408 5898e816 bellard
    T0 = ldsb((void *)T1);
409 5898e816 bellard
}
410 5898e816 bellard
411 5898e816 bellard
void OPPROTO op_lduw_T0_T1(void)
412 5898e816 bellard
{
413 5898e816 bellard
    T0 = lduw((void *)T1);
414 5898e816 bellard
}
415 5898e816 bellard
416 5898e816 bellard
void OPPROTO op_ldsw_T0_T1(void)
417 5898e816 bellard
{
418 5898e816 bellard
    T0 = ldsw((void *)T1);
419 5898e816 bellard
}
420 5898e816 bellard
421 5898e816 bellard
void OPPROTO op_ldl_T0_T1(void)
422 5898e816 bellard
{
423 5898e816 bellard
    T0 = ldl((void *)T1);
424 5898e816 bellard
}
425 5898e816 bellard
426 5898e816 bellard
void OPPROTO op_stb_T0_T1(void)
427 5898e816 bellard
{
428 5898e816 bellard
    stb((void *)T1, T0);
429 5898e816 bellard
}
430 5898e816 bellard
431 5898e816 bellard
void OPPROTO op_stw_T0_T1(void)
432 5898e816 bellard
{
433 5898e816 bellard
    stw((void *)T1, T0);
434 5898e816 bellard
}
435 5898e816 bellard
436 5898e816 bellard
void OPPROTO op_stl_T0_T1(void)
437 5898e816 bellard
{
438 5898e816 bellard
    stl((void *)T1, T0);
439 5898e816 bellard
}
440 5898e816 bellard
441 5898e816 bellard
void OPPROTO op_swpb_T0_T1(void)
442 5898e816 bellard
{
443 5898e816 bellard
    int tmp;
444 5898e816 bellard
445 5898e816 bellard
    cpu_lock();
446 5898e816 bellard
    tmp = ldub((void *)T1);
447 5898e816 bellard
    stb((void *)T1, T0);
448 5898e816 bellard
    T0 = tmp;
449 5898e816 bellard
    cpu_unlock();
450 5898e816 bellard
}
451 5898e816 bellard
452 5898e816 bellard
void OPPROTO op_swpl_T0_T1(void)
453 5898e816 bellard
{
454 5898e816 bellard
    int tmp;
455 5898e816 bellard
456 5898e816 bellard
    cpu_lock();
457 5898e816 bellard
    tmp = ldl((void *)T1);
458 5898e816 bellard
    stl((void *)T1, T0);
459 5898e816 bellard
    T0 = tmp;
460 5898e816 bellard
    cpu_unlock();
461 5898e816 bellard
}
462 5898e816 bellard
463 5898e816 bellard
/* shifts */
464 5898e816 bellard
465 5898e816 bellard
/* T1 based */
466 5898e816 bellard
void OPPROTO op_shll_T1_im(void)
467 5898e816 bellard
{
468 5898e816 bellard
    T1 = T1 << PARAM1;
469 5898e816 bellard
}
470 5898e816 bellard
471 5898e816 bellard
void OPPROTO op_shrl_T1_im(void)
472 5898e816 bellard
{
473 5898e816 bellard
    T1 = (uint32_t)T1 >> PARAM1;
474 5898e816 bellard
}
475 5898e816 bellard
476 5898e816 bellard
void OPPROTO op_sarl_T1_im(void)
477 5898e816 bellard
{
478 5898e816 bellard
    T1 = (int32_t)T1 >> PARAM1;
479 5898e816 bellard
}
480 5898e816 bellard
481 5898e816 bellard
void OPPROTO op_rorl_T1_im(void)
482 5898e816 bellard
{
483 5898e816 bellard
    int shift;
484 5898e816 bellard
    shift = PARAM1;
485 5898e816 bellard
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
486 5898e816 bellard
}
487 5898e816 bellard
488 5898e816 bellard
/* T1 based, set C flag */
489 5898e816 bellard
void OPPROTO op_shll_T1_im_cc(void)
490 5898e816 bellard
{
491 5898e816 bellard
    env->CF = (T1 >> (32 - PARAM1)) & 1;
492 5898e816 bellard
    T1 = T1 << PARAM1;
493 5898e816 bellard
}
494 5898e816 bellard
495 5898e816 bellard
void OPPROTO op_shrl_T1_im_cc(void)
496 5898e816 bellard
{
497 5898e816 bellard
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
498 5898e816 bellard
    T1 = (uint32_t)T1 >> PARAM1;
499 5898e816 bellard
}
500 5898e816 bellard
501 5898e816 bellard
void OPPROTO op_sarl_T1_im_cc(void)
502 5898e816 bellard
{
503 5898e816 bellard
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
504 5898e816 bellard
    T1 = (int32_t)T1 >> PARAM1;
505 5898e816 bellard
}
506 5898e816 bellard
507 5898e816 bellard
void OPPROTO op_rorl_T1_im_cc(void)
508 5898e816 bellard
{
509 5898e816 bellard
    int shift;
510 5898e816 bellard
    shift = PARAM1;
511 5898e816 bellard
    env->CF = (T1 >> (shift - 1)) & 1;
512 5898e816 bellard
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
513 5898e816 bellard
}
514 5898e816 bellard
515 5898e816 bellard
/* T2 based */
516 5898e816 bellard
void OPPROTO op_shll_T2_im(void)
517 5898e816 bellard
{
518 5898e816 bellard
    T2 = T2 << PARAM1;
519 5898e816 bellard
}
520 5898e816 bellard
521 5898e816 bellard
void OPPROTO op_shrl_T2_im(void)
522 5898e816 bellard
{
523 5898e816 bellard
    T2 = (uint32_t)T2 >> PARAM1;
524 5898e816 bellard
}
525 5898e816 bellard
526 5898e816 bellard
void OPPROTO op_sarl_T2_im(void)
527 5898e816 bellard
{
528 5898e816 bellard
    T2 = (int32_t)T2 >> PARAM1;
529 5898e816 bellard
}
530 5898e816 bellard
531 5898e816 bellard
void OPPROTO op_rorl_T2_im(void)
532 5898e816 bellard
{
533 5898e816 bellard
    int shift;
534 5898e816 bellard
    shift = PARAM1;
535 5898e816 bellard
    T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
536 5898e816 bellard
}
537 5898e816 bellard
538 5898e816 bellard
/* T1 based, use T0 as shift count */
539 5898e816 bellard
540 5898e816 bellard
void OPPROTO op_shll_T1_T0(void)
541 5898e816 bellard
{
542 5898e816 bellard
    int shift;
543 5898e816 bellard
    shift = T0 & 0xff;
544 5898e816 bellard
    if (shift >= 32)
545 5898e816 bellard
        T1 = 0;
546 5898e816 bellard
    else
547 5898e816 bellard
        T1 = T1 << shift;
548 5898e816 bellard
    FORCE_RET();
549 5898e816 bellard
}
550 5898e816 bellard
551 5898e816 bellard
void OPPROTO op_shrl_T1_T0(void)
552 5898e816 bellard
{
553 5898e816 bellard
    int shift;
554 5898e816 bellard
    shift = T0 & 0xff;
555 5898e816 bellard
    if (shift >= 32)
556 5898e816 bellard
        T1 = 0;
557 5898e816 bellard
    else
558 5898e816 bellard
        T1 = (uint32_t)T1 >> shift;
559 5898e816 bellard
    FORCE_RET();
560 5898e816 bellard
}
561 5898e816 bellard
562 5898e816 bellard
void OPPROTO op_sarl_T1_T0(void)
563 5898e816 bellard
{
564 5898e816 bellard
    int shift;
565 5898e816 bellard
    shift = T0 & 0xff;
566 5898e816 bellard
    if (shift >= 32)
567 5898e816 bellard
        shift = 31;
568 5898e816 bellard
    T1 = (int32_t)T1 >> shift;
569 5898e816 bellard
}
570 5898e816 bellard
571 5898e816 bellard
void OPPROTO op_rorl_T1_T0(void)
572 5898e816 bellard
{
573 5898e816 bellard
    int shift;
574 5898e816 bellard
    shift = T0 & 0x1f;
575 5898e816 bellard
    if (shift) {
576 5898e816 bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
577 5898e816 bellard
    }
578 5898e816 bellard
    FORCE_RET();
579 5898e816 bellard
}
580 5898e816 bellard
581 5898e816 bellard
/* T1 based, use T0 as shift count and compute CF */
582 5898e816 bellard
583 5898e816 bellard
void OPPROTO op_shll_T1_T0_cc(void)
584 5898e816 bellard
{
585 5898e816 bellard
    int shift;
586 5898e816 bellard
    shift = T0 & 0xff;
587 5898e816 bellard
    if (shift >= 32) {
588 5898e816 bellard
        if (shift == 32)
589 5898e816 bellard
            env->CF = T1 & 1;
590 5898e816 bellard
        else
591 5898e816 bellard
            env->CF = 0;
592 5898e816 bellard
        T1 = 0;
593 5898e816 bellard
    } else if (shift != 0) {
594 5898e816 bellard
        env->CF = (T1 >> (32 - shift)) & 1;
595 5898e816 bellard
        T1 = T1 << shift;
596 5898e816 bellard
    }
597 5898e816 bellard
    FORCE_RET();
598 5898e816 bellard
}
599 5898e816 bellard
600 5898e816 bellard
void OPPROTO op_shrl_T1_T0_cc(void)
601 5898e816 bellard
{
602 5898e816 bellard
    int shift;
603 5898e816 bellard
    shift = T0 & 0xff;
604 5898e816 bellard
    if (shift >= 32) {
605 5898e816 bellard
        if (shift == 32)
606 5898e816 bellard
            env->CF = (T1 >> 31) & 1;
607 5898e816 bellard
        else
608 5898e816 bellard
            env->CF = 0;
609 5898e816 bellard
        T1 = 0;
610 5898e816 bellard
    } else if (shift != 0) {
611 5898e816 bellard
        env->CF = (T1 >> (shift - 1)) & 1;
612 5898e816 bellard
        T1 = (uint32_t)T1 >> shift;
613 5898e816 bellard
    }
614 5898e816 bellard
    FORCE_RET();
615 5898e816 bellard
}
616 5898e816 bellard
617 5898e816 bellard
void OPPROTO op_sarl_T1_T0_cc(void)
618 5898e816 bellard
{
619 5898e816 bellard
    int shift;
620 5898e816 bellard
    shift = T0 & 0xff;
621 5898e816 bellard
    if (shift >= 32) {
622 5898e816 bellard
        env->CF = (T1 >> 31) & 1;
623 5898e816 bellard
        T1 = (int32_t)T1 >> 31;
624 5898e816 bellard
    } else {
625 5898e816 bellard
        env->CF = (T1 >> (shift - 1)) & 1;
626 5898e816 bellard
        T1 = (int32_t)T1 >> shift;
627 5898e816 bellard
    }
628 5898e816 bellard
    FORCE_RET();
629 5898e816 bellard
}
630 5898e816 bellard
631 5898e816 bellard
void OPPROTO op_rorl_T1_T0_cc(void)
632 5898e816 bellard
{
633 5898e816 bellard
    int shift1, shift;
634 5898e816 bellard
    shift1 = T0 & 0xff;
635 5898e816 bellard
    shift = shift1 & 0x1f;
636 5898e816 bellard
    if (shift == 0) {
637 5898e816 bellard
        if (shift1 != 0)
638 5898e816 bellard
            env->CF = (T1 >> 31) & 1;
639 5898e816 bellard
    } else {
640 5898e816 bellard
        env->CF = (T1 >> (shift - 1)) & 1;
641 5898e816 bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
642 5898e816 bellard
    }
643 5898e816 bellard
    FORCE_RET();
644 5898e816 bellard
}
645 5898e816 bellard
646 5898e816 bellard
/* exceptions */
647 5898e816 bellard
648 5898e816 bellard
void OPPROTO op_swi(void)
649 5898e816 bellard
{
650 5898e816 bellard
    env->exception_index = EXCP_SWI;
651 5898e816 bellard
    cpu_loop_exit();
652 5898e816 bellard
}
653 5898e816 bellard
654 5898e816 bellard
void OPPROTO op_undef_insn(void)
655 5898e816 bellard
{
656 5898e816 bellard
    env->exception_index = EXCP_UDEF;
657 5898e816 bellard
    cpu_loop_exit();
658 5898e816 bellard
}
659 5898e816 bellard
660 5898e816 bellard
/* thread support */
661 5898e816 bellard
662 5898e816 bellard
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
663 5898e816 bellard
664 5898e816 bellard
void cpu_lock(void)
665 5898e816 bellard
{
666 5898e816 bellard
    spin_lock(&global_cpu_lock);
667 5898e816 bellard
}
668 5898e816 bellard
669 5898e816 bellard
void cpu_unlock(void)
670 5898e816 bellard
{
671 5898e816 bellard
    spin_unlock(&global_cpu_lock);
672 5898e816 bellard
}