4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define REG (env->regs[0])
24 #include "op-arm-template.h"
27 #define REG (env->regs[1])
28 #include "op-arm-template.h"
31 #define REG (env->regs[2])
32 #include "op-arm-template.h"
35 #define REG (env->regs[3])
36 #include "op-arm-template.h"
39 #define REG (env->regs[4])
40 #include "op-arm-template.h"
43 #define REG (env->regs[5])
44 #include "op-arm-template.h"
47 #define REG (env->regs[6])
48 #include "op-arm-template.h"
51 #define REG (env->regs[7])
52 #include "op-arm-template.h"
55 #define REG (env->regs[8])
56 #include "op-arm-template.h"
59 #define REG (env->regs[9])
60 #include "op-arm-template.h"
63 #define REG (env->regs[10])
64 #include "op-arm-template.h"
67 #define REG (env->regs[11])
68 #include "op-arm-template.h"
71 #define REG (env->regs[12])
72 #include "op-arm-template.h"
75 #define REG (env->regs[13])
76 #include "op-arm-template.h"
79 #define REG (env->regs[14])
80 #include "op-arm-template.h"
83 #define REG (env->regs[15])
84 #include "op-arm-template.h"
86 void OPPROTO
op_movl_T0_0(void)
91 void OPPROTO
op_movl_T0_im(void)
96 void OPPROTO
op_movl_T1_im(void)
101 void OPPROTO
op_movl_T2_im(void)
106 void OPPROTO
op_addl_T1_im(void)
111 void OPPROTO
op_addl_T1_T2(void)
116 void OPPROTO
op_subl_T1_T2(void)
121 void OPPROTO
op_addl_T0_T1(void)
126 void OPPROTO
op_addl_T0_T1_cc(void)
133 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
136 void OPPROTO
op_adcl_T0_T1(void)
141 void OPPROTO
op_adcl_T0_T1_cc(void)
150 env
->CF
= T0
<= src1
;
152 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
157 #define OPSUB(sub, sbc, T0, T1) \
159 void OPPROTO op_ ## sub ## l_T0_T1(void) \
164 void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \
170 env->CF = src1 < T1; \
171 env->VF = (src1 ^ T1) & (src1 ^ T0); \
174 void OPPROTO op_ ## sbc ## l_T0_T1(void) \
176 T0 = T0 - T1 + env->CF - 1; \
179 void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \
186 env->CF = src1 < T1; \
189 env->CF = src1 <= T1; \
191 env->VF = (src1 ^ T1) & (src1 ^ T0); \
196 OPSUB(sub
, sbc
, T0
, T1
)
198 OPSUB(rsb
, rsc
, T1
, T0
)
200 void OPPROTO
op_andl_T0_T1(void)
205 void OPPROTO
op_xorl_T0_T1(void)
210 void OPPROTO
op_orl_T0_T1(void)
215 void OPPROTO
op_bicl_T0_T1(void)
220 void OPPROTO
op_notl_T1(void)
225 void OPPROTO
op_logic_cc(void)
230 #define EIP (env->regs[15])
232 void OPPROTO
op_test_eq(void)
235 JUMP_TB(PARAM1
, 0, PARAM2
);
239 void OPPROTO
op_test_ne(void)
242 JUMP_TB(PARAM1
, 0, PARAM2
);
246 void OPPROTO
op_test_cs(void)
249 JUMP_TB(PARAM1
, 0, PARAM2
);
253 void OPPROTO
op_test_cc(void)
256 JUMP_TB(PARAM1
, 0, PARAM2
);
260 void OPPROTO
op_test_mi(void)
262 if ((env
->NZF
& 0x80000000) != 0)
263 JUMP_TB(PARAM1
, 0, PARAM2
);
267 void OPPROTO
op_test_pl(void)
269 if ((env
->NZF
& 0x80000000) == 0)
270 JUMP_TB(PARAM1
, 0, PARAM2
);
274 void OPPROTO
op_test_vs(void)
276 if ((env
->VF
& 0x80000000) != 0)
277 JUMP_TB(PARAM1
, 0, PARAM2
);
281 void OPPROTO
op_test_vc(void)
283 if ((env
->VF
& 0x80000000) == 0)
284 JUMP_TB(PARAM1
, 0, PARAM2
);
288 void OPPROTO
op_test_hi(void)
290 if (env
->CF
!= 0 && env
->NZF
!= 0)
291 JUMP_TB(PARAM1
, 0, PARAM2
);
295 void OPPROTO
op_test_ls(void)
297 if (env
->CF
== 0 || env
->NZF
== 0)
298 JUMP_TB(PARAM1
, 0, PARAM2
);
302 void OPPROTO
op_test_ge(void)
304 if (((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
305 JUMP_TB(PARAM1
, 0, PARAM2
);
309 void OPPROTO
op_test_lt(void)
311 if (((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
312 JUMP_TB(PARAM1
, 0, PARAM2
);
316 void OPPROTO
op_test_gt(void)
318 if (env
->NZF
!= 0 && ((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
319 JUMP_TB(PARAM1
, 0, PARAM2
);
323 void OPPROTO
op_test_le(void)
325 if (env
->NZF
== 0 || ((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
326 JUMP_TB(PARAM1
, 0, PARAM2
);
330 void OPPROTO
op_jmp(void)
332 JUMP_TB(PARAM1
, 1, PARAM2
);
335 void OPPROTO
op_movl_T0_psr(void)
338 ZF
= (env
->NZF
== 0);
339 T0
= env
->cpsr
| (env
->NZF
& 0x80000000) | (ZF
<< 30) |
340 (env
->CF
<< 29) | ((env
->VF
& 0x80000000) >> 3);
343 /* NOTE: N = 1 and Z = 1 cannot be stored currently */
344 void OPPROTO
op_movl_psr_T0(void)
348 env
->CF
= (psr
>> 29) & 1;
349 env
->NZF
= (psr
& 0xc0000000) ^ 0x40000000;
350 env
->VF
= (psr
<< 3) & 0x80000000;
351 /* for user mode we do not update other state info */
354 void OPPROTO
op_mul_T0_T1(void)
359 /* 64 bit unsigned mul */
360 void OPPROTO
op_mull_T0_T1(void)
368 /* 64 bit signed mul */
369 void OPPROTO
op_imull_T0_T1(void)
372 res
= (int32_t)T0
* (int32_t)T1
;
377 void OPPROTO
op_addq_T0_T1(void)
380 res
= ((uint64_t)T1
<< 32) | T0
;
381 res
+= ((uint64_t)(env
->regs
[PARAM2
]) << 32) | (env
->regs
[PARAM1
]);
386 void OPPROTO
op_logicq_cc(void)
388 env
->NZF
= (T1
& 0x80000000) | ((T0
| T1
) != 0);
393 void OPPROTO
op_ldub_T0_T1(void)
395 T0
= ldub((void *)T1
);
398 void OPPROTO
op_ldsb_T0_T1(void)
400 T0
= ldsb((void *)T1
);
403 void OPPROTO
op_lduw_T0_T1(void)
405 T0
= lduw((void *)T1
);
408 void OPPROTO
op_ldsw_T0_T1(void)
410 T0
= ldsw((void *)T1
);
413 void OPPROTO
op_ldl_T0_T1(void)
415 T0
= ldl((void *)T1
);
418 void OPPROTO
op_stb_T0_T1(void)
423 void OPPROTO
op_stw_T0_T1(void)
428 void OPPROTO
op_stl_T0_T1(void)
433 void OPPROTO
op_swpb_T0_T1(void)
438 tmp
= ldub((void *)T1
);
444 void OPPROTO
op_swpl_T0_T1(void)
449 tmp
= ldl((void *)T1
);
458 void OPPROTO
op_shll_T1_im(void)
463 void OPPROTO
op_shrl_T1_im(void)
465 T1
= (uint32_t)T1
>> PARAM1
;
468 void OPPROTO
op_sarl_T1_im(void)
470 T1
= (int32_t)T1
>> PARAM1
;
473 void OPPROTO
op_rorl_T1_im(void)
477 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
480 /* T1 based, set C flag */
481 void OPPROTO
op_shll_T1_im_cc(void)
483 env
->CF
= (T1
>> (32 - PARAM1
)) & 1;
487 void OPPROTO
op_shrl_T1_im_cc(void)
489 env
->CF
= (T1
>> (PARAM1
- 1)) & 1;
490 T1
= (uint32_t)T1
>> PARAM1
;
493 void OPPROTO
op_sarl_T1_im_cc(void)
495 env
->CF
= (T1
>> (PARAM1
- 1)) & 1;
496 T1
= (int32_t)T1
>> PARAM1
;
499 void OPPROTO
op_rorl_T1_im_cc(void)
503 env
->CF
= (T1
>> (shift
- 1)) & 1;
504 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
508 void OPPROTO
op_shll_T2_im(void)
513 void OPPROTO
op_shrl_T2_im(void)
515 T2
= (uint32_t)T2
>> PARAM1
;
518 void OPPROTO
op_sarl_T2_im(void)
520 T2
= (int32_t)T2
>> PARAM1
;
523 void OPPROTO
op_rorl_T2_im(void)
527 T2
= ((uint32_t)T2
>> shift
) | (T2
<< (32 - shift
));
530 /* T1 based, use T0 as shift count */
532 void OPPROTO
op_shll_T1_T0(void)
543 void OPPROTO
op_shrl_T1_T0(void)
550 T1
= (uint32_t)T1
>> shift
;
554 void OPPROTO
op_sarl_T1_T0(void)
560 T1
= (int32_t)T1
>> shift
;
563 void OPPROTO
op_rorl_T1_T0(void)
568 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
573 /* T1 based, use T0 as shift count and compute CF */
575 void OPPROTO
op_shll_T1_T0_cc(void)
585 } else if (shift
!= 0) {
586 env
->CF
= (T1
>> (32 - shift
)) & 1;
592 void OPPROTO
op_shrl_T1_T0_cc(void)
598 env
->CF
= (T1
>> 31) & 1;
602 } else if (shift
!= 0) {
603 env
->CF
= (T1
>> (shift
- 1)) & 1;
604 T1
= (uint32_t)T1
>> shift
;
609 void OPPROTO
op_sarl_T1_T0_cc(void)
614 env
->CF
= (T1
>> 31) & 1;
615 T1
= (int32_t)T1
>> 31;
617 env
->CF
= (T1
>> (shift
- 1)) & 1;
618 T1
= (int32_t)T1
>> shift
;
623 void OPPROTO
op_rorl_T1_T0_cc(void)
627 shift
= shift1
& 0x1f;
630 env
->CF
= (T1
>> 31) & 1;
632 env
->CF
= (T1
>> (shift
- 1)) & 1;
633 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
640 void OPPROTO
op_swi(void)
642 env
->exception_index
= EXCP_SWI
;
646 void OPPROTO
op_undef_insn(void)
648 env
->exception_index
= EXCP_UDEF
;
654 spinlock_t global_cpu_lock
= SPIN_LOCK_UNLOCKED
;
658 spin_lock(&global_cpu_lock
);
661 void cpu_unlock(void)
663 spin_unlock(&global_cpu_lock
);