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_template.h"
27 #define REG (env->regs[1])
28 #include "op_template.h"
31 #define REG (env->regs[2])
32 #include "op_template.h"
35 #define REG (env->regs[3])
36 #include "op_template.h"
39 #define REG (env->regs[4])
40 #include "op_template.h"
43 #define REG (env->regs[5])
44 #include "op_template.h"
47 #define REG (env->regs[6])
48 #include "op_template.h"
51 #define REG (env->regs[7])
52 #include "op_template.h"
55 #define REG (env->regs[8])
56 #include "op_template.h"
59 #define REG (env->regs[9])
60 #include "op_template.h"
63 #define REG (env->regs[10])
64 #include "op_template.h"
67 #define REG (env->regs[11])
68 #include "op_template.h"
71 #define REG (env->regs[12])
72 #include "op_template.h"
75 #define REG (env->regs[13])
76 #include "op_template.h"
79 #define REG (env->regs[14])
80 #include "op_template.h"
83 #define REG (env->regs[15])
84 #define SET_REG(x) REG = x & ~(uint32_t)1
85 #include "op_template.h"
87 void OPPROTO
op_bx_T0(void)
89 env
->regs
[15] = T0
& ~(uint32_t)1;
90 env
->thumb
= (T0
& 1) != 0;
93 void OPPROTO
op_movl_T0_0(void)
98 void OPPROTO
op_movl_T0_im(void)
103 void OPPROTO
op_movl_T1_im(void)
108 void OPPROTO
op_movl_T2_im(void)
113 void OPPROTO
op_addl_T1_im(void)
118 void OPPROTO
op_addl_T1_T2(void)
123 void OPPROTO
op_subl_T1_T2(void)
128 void OPPROTO
op_addl_T0_T1(void)
133 void OPPROTO
op_addl_T0_T1_cc(void)
140 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
143 void OPPROTO
op_adcl_T0_T1(void)
148 void OPPROTO
op_adcl_T0_T1_cc(void)
157 env
->CF
= T0
<= src1
;
159 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
164 #define OPSUB(sub, sbc, res, T0, T1) \
166 void OPPROTO op_ ## sub ## l_T0_T1(void) \
171 void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \
177 env->CF = src1 >= T1; \
178 env->VF = (src1 ^ T1) & (src1 ^ T0); \
182 void OPPROTO op_ ## sbc ## l_T0_T1(void) \
184 res = T0 - T1 + env->CF - 1; \
187 void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \
193 env->CF = src1 > T1; \
196 env->CF = src1 >= T1; \
198 env->VF = (src1 ^ T1) & (src1 ^ T0); \
204 OPSUB(sub
, sbc
, T0
, T0
, T1
)
206 OPSUB(rsb
, rsc
, T0
, T1
, T0
)
208 void OPPROTO
op_andl_T0_T1(void)
213 void OPPROTO
op_xorl_T0_T1(void)
218 void OPPROTO
op_orl_T0_T1(void)
223 void OPPROTO
op_bicl_T0_T1(void)
228 void OPPROTO
op_notl_T1(void)
233 void OPPROTO
op_logic_T0_cc(void)
238 void OPPROTO
op_logic_T1_cc(void)
243 #define EIP (env->regs[15])
245 void OPPROTO
op_test_eq(void)
248 JUMP_TB(op_test_eq
, PARAM1
, 0, PARAM2
);
252 void OPPROTO
op_test_ne(void)
255 JUMP_TB(op_test_ne
, PARAM1
, 0, PARAM2
);
259 void OPPROTO
op_test_cs(void)
262 JUMP_TB(op_test_cs
, PARAM1
, 0, PARAM2
);
266 void OPPROTO
op_test_cc(void)
269 JUMP_TB(op_test_cc
, PARAM1
, 0, PARAM2
);
273 void OPPROTO
op_test_mi(void)
275 if ((env
->NZF
& 0x80000000) != 0)
276 JUMP_TB(op_test_mi
, PARAM1
, 0, PARAM2
);
280 void OPPROTO
op_test_pl(void)
282 if ((env
->NZF
& 0x80000000) == 0)
283 JUMP_TB(op_test_pl
, PARAM1
, 0, PARAM2
);
287 void OPPROTO
op_test_vs(void)
289 if ((env
->VF
& 0x80000000) != 0)
290 JUMP_TB(op_test_vs
, PARAM1
, 0, PARAM2
);
294 void OPPROTO
op_test_vc(void)
296 if ((env
->VF
& 0x80000000) == 0)
297 JUMP_TB(op_test_vc
, PARAM1
, 0, PARAM2
);
301 void OPPROTO
op_test_hi(void)
303 if (env
->CF
!= 0 && env
->NZF
!= 0)
304 JUMP_TB(op_test_hi
, PARAM1
, 0, PARAM2
);
308 void OPPROTO
op_test_ls(void)
310 if (env
->CF
== 0 || env
->NZF
== 0)
311 JUMP_TB(op_test_ls
, PARAM1
, 0, PARAM2
);
315 void OPPROTO
op_test_ge(void)
317 if (((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
318 JUMP_TB(op_test_ge
, PARAM1
, 0, PARAM2
);
322 void OPPROTO
op_test_lt(void)
324 if (((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
325 JUMP_TB(op_test_lt
, PARAM1
, 0, PARAM2
);
329 void OPPROTO
op_test_gt(void)
331 if (env
->NZF
!= 0 && ((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
332 JUMP_TB(op_test_gt
, PARAM1
, 0, PARAM2
);
336 void OPPROTO
op_test_le(void)
338 if (env
->NZF
== 0 || ((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
339 JUMP_TB(op_test_le
, PARAM1
, 0, PARAM2
);
343 void OPPROTO
op_jmp(void)
345 JUMP_TB(op_jmp
, PARAM1
, 1, PARAM2
);
348 void OPPROTO
op_exit_tb(void)
353 void OPPROTO
op_movl_T0_psr(void)
358 /* NOTE: N = 1 and Z = 1 cannot be stored currently */
359 void OPPROTO
op_movl_psr_T0(void)
363 env
->CF
= (psr
>> 29) & 1;
364 env
->NZF
= (psr
& 0xc0000000) ^ 0x40000000;
365 env
->VF
= (psr
<< 3) & 0x80000000;
366 /* for user mode we do not update other state info */
369 void OPPROTO
op_mul_T0_T1(void)
374 /* 64 bit unsigned mul */
375 void OPPROTO
op_mull_T0_T1(void)
378 res
= (uint64_t)T0
* (uint64_t)T1
;
383 /* 64 bit signed mul */
384 void OPPROTO
op_imull_T0_T1(void)
387 res
= (int64_t)((int32_t)T0
) * (int64_t)((int32_t)T1
);
392 /* 48 bit signed mul, top 32 bits */
393 void OPPROTO
op_imulw_T0_T1(void)
396 res
= (int64_t)((int32_t)T0
) * (int64_t)((int32_t)T1
);
400 void OPPROTO
op_addq_T0_T1(void)
403 res
= ((uint64_t)T1
<< 32) | T0
;
404 res
+= ((uint64_t)(env
->regs
[PARAM2
]) << 32) | (env
->regs
[PARAM1
]);
409 void OPPROTO
op_addq_lo_T0_T1(void)
412 res
= ((uint64_t)T1
<< 32) | T0
;
413 res
+= (uint64_t)(env
->regs
[PARAM1
]);
418 void OPPROTO
op_logicq_cc(void)
420 env
->NZF
= (T1
& 0x80000000) | ((T0
| T1
) != 0);
425 void OPPROTO
op_ldub_T0_T1(void)
427 T0
= ldub((void *)T1
);
430 void OPPROTO
op_ldsb_T0_T1(void)
432 T0
= ldsb((void *)T1
);
435 void OPPROTO
op_lduw_T0_T1(void)
437 T0
= lduw((void *)T1
);
440 void OPPROTO
op_ldsw_T0_T1(void)
442 T0
= ldsw((void *)T1
);
445 void OPPROTO
op_ldl_T0_T1(void)
447 T0
= ldl((void *)T1
);
450 void OPPROTO
op_stb_T0_T1(void)
455 void OPPROTO
op_stw_T0_T1(void)
460 void OPPROTO
op_stl_T0_T1(void)
465 void OPPROTO
op_swpb_T0_T1(void)
470 tmp
= ldub((void *)T1
);
476 void OPPROTO
op_swpl_T0_T1(void)
481 tmp
= ldl((void *)T1
);
491 void OPPROTO
op_shll_T1_im(void)
496 void OPPROTO
op_shrl_T1_im(void)
498 T1
= (uint32_t)T1
>> PARAM1
;
501 void OPPROTO
op_shrl_T1_0(void)
506 void OPPROTO
op_sarl_T1_im(void)
508 T1
= (int32_t)T1
>> PARAM1
;
511 void OPPROTO
op_sarl_T1_0(void)
513 T1
= (int32_t)T1
>> 31;
516 void OPPROTO
op_rorl_T1_im(void)
520 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
523 void OPPROTO
op_rrxl_T1(void)
525 T1
= ((uint32_t)T1
>> 1) | ((uint32_t)env
->CF
<< 31);
528 /* T1 based, set C flag */
529 void OPPROTO
op_shll_T1_im_cc(void)
531 env
->CF
= (T1
>> (32 - PARAM1
)) & 1;
535 void OPPROTO
op_shrl_T1_im_cc(void)
537 env
->CF
= (T1
>> (PARAM1
- 1)) & 1;
538 T1
= (uint32_t)T1
>> PARAM1
;
541 void OPPROTO
op_shrl_T1_0_cc(void)
543 env
->CF
= (T1
>> 31) & 1;
547 void OPPROTO
op_sarl_T1_im_cc(void)
549 env
->CF
= (T1
>> (PARAM1
- 1)) & 1;
550 T1
= (int32_t)T1
>> PARAM1
;
553 void OPPROTO
op_sarl_T1_0_cc(void)
555 env
->CF
= (T1
>> 31) & 1;
556 T1
= (int32_t)T1
>> 31;
559 void OPPROTO
op_rorl_T1_im_cc(void)
563 env
->CF
= (T1
>> (shift
- 1)) & 1;
564 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
567 void OPPROTO
op_rrxl_T1_cc(void)
571 T1
= ((uint32_t)T1
>> 1) | ((uint32_t)env
->CF
<< 31);
576 void OPPROTO
op_shll_T2_im(void)
581 void OPPROTO
op_shrl_T2_im(void)
583 T2
= (uint32_t)T2
>> PARAM1
;
586 void OPPROTO
op_shrl_T2_0(void)
591 void OPPROTO
op_sarl_T2_im(void)
593 T2
= (int32_t)T2
>> PARAM1
;
596 void OPPROTO
op_sarl_T2_0(void)
598 T2
= (int32_t)T2
>> 31;
601 void OPPROTO
op_rorl_T2_im(void)
605 T2
= ((uint32_t)T2
>> shift
) | (T2
<< (32 - shift
));
608 void OPPROTO
op_rrxl_T2(void)
610 T2
= ((uint32_t)T2
>> 1) | ((uint32_t)env
->CF
<< 31);
613 /* T1 based, use T0 as shift count */
615 void OPPROTO
op_shll_T1_T0(void)
626 void OPPROTO
op_shrl_T1_T0(void)
633 T1
= (uint32_t)T1
>> shift
;
637 void OPPROTO
op_sarl_T1_T0(void)
643 T1
= (int32_t)T1
>> shift
;
646 void OPPROTO
op_rorl_T1_T0(void)
651 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
656 /* T1 based, use T0 as shift count and compute CF */
658 void OPPROTO
op_shll_T1_T0_cc(void)
668 } else if (shift
!= 0) {
669 env
->CF
= (T1
>> (32 - shift
)) & 1;
675 void OPPROTO
op_shrl_T1_T0_cc(void)
681 env
->CF
= (T1
>> 31) & 1;
685 } else if (shift
!= 0) {
686 env
->CF
= (T1
>> (shift
- 1)) & 1;
687 T1
= (uint32_t)T1
>> shift
;
692 void OPPROTO
op_sarl_T1_T0_cc(void)
697 env
->CF
= (T1
>> 31) & 1;
698 T1
= (int32_t)T1
>> 31;
700 env
->CF
= (T1
>> (shift
- 1)) & 1;
701 T1
= (int32_t)T1
>> shift
;
706 void OPPROTO
op_rorl_T1_T0_cc(void)
710 shift
= shift1
& 0x1f;
713 env
->CF
= (T1
>> 31) & 1;
715 env
->CF
= (T1
>> (shift
- 1)) & 1;
716 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
722 void OPPROTO
op_clz_T0(void)
725 for (count
= 32; T0
> 0; count
--)
731 void OPPROTO
op_sarl_T0_im(void)
733 T0
= (int32_t)T0
>> PARAM1
;
736 /* 16->32 Sign extend */
737 void OPPROTO
op_sxl_T0(void)
742 void OPPROTO
op_sxl_T1(void)
747 #define SIGNBIT (uint32_t)0x80000000
748 /* saturating arithmetic */
749 void OPPROTO
op_addl_T0_T1_setq(void)
754 if (((res
^ T0
) & SIGNBIT
) && !((T0
^ T1
) & SIGNBIT
))
761 void OPPROTO
op_addl_T0_T1_saturate(void)
766 if (((res
^ T0
) & SIGNBIT
) && !((T0
^ T1
) & SIGNBIT
)) {
779 void OPPROTO
op_subl_T0_T1_saturate(void)
784 if (((res
^ T0
) & SIGNBIT
) && ((T0
^ T1
) & SIGNBIT
)) {
797 /* thumb shift by immediate */
798 void OPPROTO
op_shll_T0_im_thumb(void)
803 env
->CF
= (T1
>> (32 - shift
)) & 1;
810 void OPPROTO
op_shrl_T0_im_thumb(void)
819 env
->CF
= (T0
>> (shift
- 1)) & 1;
825 void OPPROTO
op_sarl_T0_im_thumb(void)
831 T0
= ((int32_t)T0
) >> 31;
834 env
->CF
= (T0
>> (shift
- 1)) & 1;
835 T0
= ((int32_t)T0
) >> shift
;
843 void OPPROTO
op_swi(void)
845 env
->exception_index
= EXCP_SWI
;
849 void OPPROTO
op_undef_insn(void)
851 env
->exception_index
= EXCP_UDEF
;
857 spinlock_t global_cpu_lock
= SPIN_LOCK_UNLOCKED
;
861 spin_lock(&global_cpu_lock
);
864 void cpu_unlock(void)
866 spin_unlock(&global_cpu_lock
);