]>
git.proxmox.com Git - qemu.git/blob - target-arm/op.c
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery, LLC
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 void OPPROTO
op_addl_T0_T1_cc(void)
30 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
33 void OPPROTO
op_adcl_T0_T1_cc(void)
44 env
->VF
= (src1
^ T1
^ -1) & (src1
^ T0
);
49 #define OPSUB(sub, sbc, res, T0, T1) \
51 void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \
57 env->CF = src1 >= T1; \
58 env->VF = (src1 ^ T1) & (src1 ^ T0); \
62 void OPPROTO op_ ## sbc ## l_T0_T1(void) \
64 res = T0 - T1 + env->CF - 1; \
67 void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \
73 env->CF = src1 > T1; \
76 env->CF = src1 >= T1; \
78 env->VF = (src1 ^ T1) & (src1 ^ T0); \
84 OPSUB(sub
, sbc
, T0
, T0
, T1
)
86 OPSUB(rsb
, rsc
, T0
, T1
, T0
)
88 #define EIP (env->regs[15])
90 void OPPROTO
op_test_eq(void)
97 void OPPROTO
op_test_ne(void)
100 GOTO_LABEL_PARAM(1);;
104 void OPPROTO
op_test_cs(void)
111 void OPPROTO
op_test_cc(void)
118 void OPPROTO
op_test_mi(void)
120 if ((env
->NZF
& 0x80000000) != 0)
125 void OPPROTO
op_test_pl(void)
127 if ((env
->NZF
& 0x80000000) == 0)
132 void OPPROTO
op_test_vs(void)
134 if ((env
->VF
& 0x80000000) != 0)
139 void OPPROTO
op_test_vc(void)
141 if ((env
->VF
& 0x80000000) == 0)
146 void OPPROTO
op_test_hi(void)
148 if (env
->CF
!= 0 && env
->NZF
!= 0)
153 void OPPROTO
op_test_ls(void)
155 if (env
->CF
== 0 || env
->NZF
== 0)
160 void OPPROTO
op_test_ge(void)
162 if (((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
167 void OPPROTO
op_test_lt(void)
169 if (((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
174 void OPPROTO
op_test_gt(void)
176 if (env
->NZF
!= 0 && ((env
->VF
^ env
->NZF
) & 0x80000000) == 0)
181 void OPPROTO
op_test_le(void)
183 if (env
->NZF
== 0 || ((env
->VF
^ env
->NZF
) & 0x80000000) != 0)
188 void OPPROTO
op_test_T0(void)
194 void OPPROTO
op_testn_T0(void)
201 void OPPROTO
op_movl_T0_cpsr(void)
203 /* Execution state bits always read as zero. */
204 T0
= cpsr_read(env
) & ~CPSR_EXEC
;
208 void OPPROTO
op_movl_T0_spsr(void)
213 void OPPROTO
op_movl_spsr_T0(void)
215 uint32_t mask
= PARAM1
;
216 env
->spsr
= (env
->spsr
& ~mask
) | (T0
& mask
);
219 void OPPROTO
op_movl_cpsr_T0(void)
221 cpsr_write(env
, T0
, PARAM1
);
225 /* 48 bit signed mul, top 32 bits */
226 void OPPROTO
op_imulw_T0_T1(void)
229 res
= (int64_t)((int32_t)T0
) * (int64_t)((int32_t)T1
);
233 void OPPROTO
op_addq_T0_T1(void)
236 res
= ((uint64_t)T1
<< 32) | T0
;
237 res
+= ((uint64_t)(env
->regs
[PARAM2
]) << 32) | (env
->regs
[PARAM1
]);
242 void OPPROTO
op_addq_lo_T0_T1(void)
245 res
= ((uint64_t)T1
<< 32) | T0
;
246 res
+= (uint64_t)(env
->regs
[PARAM1
]);
251 /* Dual 16-bit accumulate. */
252 void OPPROTO
op_addq_T0_T1_dual(void)
255 res
= ((uint64_t)(env
->regs
[PARAM2
]) << 32) | (env
->regs
[PARAM1
]);
258 env
->regs
[PARAM1
] = (uint32_t)res
;
259 env
->regs
[PARAM2
] = res
>> 32;
262 /* Dual 16-bit subtract accumulate. */
263 void OPPROTO
op_subq_T0_T1_dual(void)
266 res
= ((uint64_t)(env
->regs
[PARAM2
]) << 32) | (env
->regs
[PARAM1
]);
269 env
->regs
[PARAM1
] = (uint32_t)res
;
270 env
->regs
[PARAM2
] = res
>> 32;
273 void OPPROTO
op_logicq_cc(void)
275 env
->NZF
= (T1
& 0x80000000) | ((T0
| T1
) != 0);
280 #define MEMSUFFIX _raw
283 #if !defined(CONFIG_USER_ONLY)
284 #define MEMSUFFIX _user
286 #define MEMSUFFIX _kernel
290 void OPPROTO
op_clrex(void)
297 /* T1 based, use T0 as shift count */
299 void OPPROTO
op_shll_T1_T0(void)
310 void OPPROTO
op_shrl_T1_T0(void)
317 T1
= (uint32_t)T1
>> shift
;
321 void OPPROTO
op_sarl_T1_T0(void)
327 T1
= (int32_t)T1
>> shift
;
330 void OPPROTO
op_rorl_T1_T0(void)
335 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
340 /* T1 based, use T0 as shift count and compute CF */
342 void OPPROTO
op_shll_T1_T0_cc(void)
352 } else if (shift
!= 0) {
353 env
->CF
= (T1
>> (32 - shift
)) & 1;
359 void OPPROTO
op_shrl_T1_T0_cc(void)
365 env
->CF
= (T1
>> 31) & 1;
369 } else if (shift
!= 0) {
370 env
->CF
= (T1
>> (shift
- 1)) & 1;
371 T1
= (uint32_t)T1
>> shift
;
376 void OPPROTO
op_sarl_T1_T0_cc(void)
381 env
->CF
= (T1
>> 31) & 1;
382 T1
= (int32_t)T1
>> 31;
383 } else if (shift
!= 0) {
384 env
->CF
= (T1
>> (shift
- 1)) & 1;
385 T1
= (int32_t)T1
>> shift
;
390 void OPPROTO
op_rorl_T1_T0_cc(void)
394 shift
= shift1
& 0x1f;
397 env
->CF
= (T1
>> 31) & 1;
399 env
->CF
= (T1
>> (shift
- 1)) & 1;
400 T1
= ((uint32_t)T1
>> shift
) | (T1
<< (32 - shift
));
407 void OPPROTO
op_swi(void)
409 env
->exception_index
= EXCP_SWI
;
413 void OPPROTO
op_undef_insn(void)
415 env
->exception_index
= EXCP_UDEF
;
419 void OPPROTO
op_debug(void)
421 env
->exception_index
= EXCP_DEBUG
;
425 void OPPROTO
op_wfi(void)
427 env
->exception_index
= EXCP_HLT
;
432 void OPPROTO
op_bkpt(void)
434 env
->exception_index
= EXCP_BKPT
;
438 void OPPROTO
op_exception_exit(void)
440 env
->exception_index
= EXCP_EXCEPTION_EXIT
;
444 /* VFP support. We follow the convention used for VFP instrunctions:
445 Single precition routines have a "s" suffix, double precision a
448 #define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
450 #define VFP_BINOP(name) \
453 FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status); \
457 FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status); \
465 #define VFP_HELPER(name) \
468 do_vfp_##name##s(); \
472 do_vfp_##name##d(); \
480 /* XXX: Will this do the right thing for NANs. Should invert the signbit
481 without looking at the rest of the value. */
484 FT0s
= float32_chs(FT0s
);
489 FT0d
= float64_chs(FT0d
);
512 /* Helper routines to perform bitwise copies between float and int. */
513 static inline float32
vfp_itos(uint32_t i
)
524 static inline uint32_t vfp_stoi(float32 s
)
535 static inline float64
vfp_itod(uint64_t i
)
546 static inline uint64_t vfp_dtoi(float64 d
)
557 /* Integer to float conversion. */
560 FT0s
= uint32_to_float32(vfp_stoi(FT0s
), &env
->vfp
.fp_status
);
565 FT0d
= uint32_to_float64(vfp_stoi(FT0s
), &env
->vfp
.fp_status
);
570 FT0s
= int32_to_float32(vfp_stoi(FT0s
), &env
->vfp
.fp_status
);
575 FT0d
= int32_to_float64(vfp_stoi(FT0s
), &env
->vfp
.fp_status
);
578 /* Float to integer conversion. */
581 FT0s
= vfp_itos(float32_to_uint32(FT0s
, &env
->vfp
.fp_status
));
586 FT0s
= vfp_itos(float64_to_uint32(FT0d
, &env
->vfp
.fp_status
));
591 FT0s
= vfp_itos(float32_to_int32(FT0s
, &env
->vfp
.fp_status
));
596 FT0s
= vfp_itos(float64_to_int32(FT0d
, &env
->vfp
.fp_status
));
599 /* TODO: Set rounding mode properly. */
602 FT0s
= vfp_itos(float32_to_uint32_round_to_zero(FT0s
, &env
->vfp
.fp_status
));
607 FT0s
= vfp_itos(float64_to_uint32_round_to_zero(FT0d
, &env
->vfp
.fp_status
));
612 FT0s
= vfp_itos(float32_to_int32_round_to_zero(FT0s
, &env
->vfp
.fp_status
));
617 FT0s
= vfp_itos(float64_to_int32_round_to_zero(FT0d
, &env
->vfp
.fp_status
));
620 /* floating point conversion */
623 FT0d
= float32_to_float64(FT0s
, &env
->vfp
.fp_status
);
628 FT0s
= float64_to_float32(FT0d
, &env
->vfp
.fp_status
);
631 /* VFP3 fixed point conversion. */
632 #define VFP_CONV_FIX(name, p, ftype, itype, sign) \
633 VFP_OP(name##to, p) \
636 tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \
637 &env->vfp.fp_status); \
638 FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \
640 VFP_OP(to##name, p) \
643 tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \
644 FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
645 &env->vfp.fp_status)); \
648 VFP_CONV_FIX(sh
, d
, float64
, int16
, )
649 VFP_CONV_FIX(sl
, d
, float64
, int32
, )
650 VFP_CONV_FIX(uh
, d
, float64
, uint16
, u
)
651 VFP_CONV_FIX(ul
, d
, float64
, uint32
, u
)
652 VFP_CONV_FIX(sh
, s
, float32
, int16
, )
653 VFP_CONV_FIX(sl
, s
, float32
, int32
, )
654 VFP_CONV_FIX(uh
, s
, float32
, uint16
, u
)
655 VFP_CONV_FIX(ul
, s
, float32
, uint32
, u
)
657 /* Get and Put values from registers. */
660 FT0d
= *(float64
*)((char *) env
+ PARAM1
);
665 FT0s
= *(float32
*)((char *) env
+ PARAM1
);
670 FT1d
= *(float64
*)((char *) env
+ PARAM1
);
675 FT1s
= *(float32
*)((char *) env
+ PARAM1
);
680 *(float64
*)((char *) env
+ PARAM1
) = FT0d
;
685 *(float32
*)((char *) env
+ PARAM1
) = FT0s
;
688 void OPPROTO
op_vfp_movl_T0_fpscr(void)
693 void OPPROTO
op_vfp_movl_T0_fpscr_flags(void)
695 T0
= env
->vfp
.xregs
[ARM_VFP_FPSCR
] & (0xf << 28);
698 void OPPROTO
op_vfp_movl_fpscr_T0(void)
703 void OPPROTO
op_vfp_movl_T0_xreg(void)
705 T0
= env
->vfp
.xregs
[PARAM1
];
708 void OPPROTO
op_vfp_movl_xreg_T0(void)
710 env
->vfp
.xregs
[PARAM1
] = T0
;
713 /* Move between FT0s to T0 */
714 void OPPROTO
op_vfp_mrs(void)
719 void OPPROTO
op_vfp_msr(void)
724 /* Move between FT0d and {T0,T1} */
725 void OPPROTO
op_vfp_mrrd(void)
734 void OPPROTO
op_vfp_mdrr(void)
743 /* Load immediate. PARAM1 is the 32 most significant bits of the value. */
744 void OPPROTO
op_vfp_fconstd(void)
752 void OPPROTO
op_vfp_fconsts(void)
754 FT0s
= vfp_itos(PARAM1
);
757 /* Copy the most significant bit of T0 to all bits of T1. */
758 void OPPROTO
op_signbit_T1_T0(void)
760 T1
= (int32_t)T0
>> 31;
763 void OPPROTO
op_movl_cp_T0(void)
765 helper_set_cp(env
, PARAM1
, T0
);
769 void OPPROTO
op_movl_T0_cp(void)
771 T0
= helper_get_cp(env
, PARAM1
);
775 void OPPROTO
op_movl_cp15_T0(void)
777 helper_set_cp15(env
, PARAM1
, T0
);
781 void OPPROTO
op_movl_T0_cp15(void)
783 T0
= helper_get_cp15(env
, PARAM1
);
787 /* Access to user mode registers from privileged modes. */
788 void OPPROTO
op_movl_T0_user(void)
792 T0
= env
->banked_r13
[0];
793 } else if (regno
== 14) {
794 T0
= env
->banked_r14
[0];
795 } else if ((env
->uncached_cpsr
& 0x1f) == ARM_CPU_MODE_FIQ
) {
796 T0
= env
->usr_regs
[regno
- 8];
798 T0
= env
->regs
[regno
];
804 void OPPROTO
op_movl_user_T0(void)
808 env
->banked_r13
[0] = T0
;
809 } else if (regno
== 14) {
810 env
->banked_r14
[0] = T0
;
811 } else if ((env
->uncached_cpsr
& 0x1f) == ARM_CPU_MODE_FIQ
) {
812 env
->usr_regs
[regno
- 8] = T0
;
814 env
->regs
[regno
] = T0
;
819 /* ARMv6 Media instructions. */
821 /* Note that signed overflow is undefined in C. The following routines are
822 careful to use unsigned types where modulo arithmetic is required.
823 Failure to do so _will_ break on newer gcc. */
825 /* Signed saturating arithmetic. */
827 /* Perform 16-bit signed satruating addition. */
828 static inline uint16_t add16_sat(uint16_t a
, uint16_t b
)
833 if (((res
^ a
) & 0x8000) && !((a
^ b
) & 0x8000)) {
842 /* Perform 8-bit signed satruating addition. */
843 static inline uint8_t add8_sat(uint8_t a
, uint8_t b
)
848 if (((res
^ a
) & 0x80) && !((a
^ b
) & 0x80)) {
857 /* Perform 16-bit signed satruating subtraction. */
858 static inline uint16_t sub16_sat(uint16_t a
, uint16_t b
)
863 if (((res
^ a
) & 0x8000) && ((a
^ b
) & 0x8000)) {
872 /* Perform 8-bit signed satruating subtraction. */
873 static inline uint8_t sub8_sat(uint8_t a
, uint8_t b
)
878 if (((res
^ a
) & 0x80) && ((a
^ b
) & 0x80)) {
887 #define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
888 #define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
889 #define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
890 #define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
893 #include "op_addsub.h"
895 /* Unsigned saturating arithmetic. */
896 static inline uint16_t add16_usat(uint16_t a
, uint8_t b
)
905 static inline uint16_t sub16_usat(uint16_t a
, uint8_t b
)
913 static inline uint8_t add8_usat(uint8_t a
, uint8_t b
)
922 static inline uint8_t sub8_usat(uint8_t a
, uint8_t b
)
930 #define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
931 #define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
932 #define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
933 #define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
936 #include "op_addsub.h"
938 /* Signed modulo arithmetic. */
939 #define SARITH16(a, b, n, op) do { \
941 sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
942 RESULT(sum, n, 16); \
944 ge |= 3 << (n * 2); \
947 #define SARITH8(a, b, n, op) do { \
949 sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
956 #define ADD16(a, b, n) SARITH16(a, b, n, +)
957 #define SUB16(a, b, n) SARITH16(a, b, n, -)
958 #define ADD8(a, b, n) SARITH8(a, b, n, +)
959 #define SUB8(a, b, n) SARITH8(a, b, n, -)
963 #include "op_addsub.h"
965 /* Unsigned modulo arithmetic. */
966 #define ADD16(a, b, n) do { \
968 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
969 RESULT(sum, n, 16); \
970 if ((sum >> 16) == 0) \
971 ge |= 3 << (n * 2); \
974 #define ADD8(a, b, n) do { \
976 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
978 if ((sum >> 8) == 0) \
979 ge |= 3 << (n * 2); \
982 #define SUB16(a, b, n) do { \
984 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
985 RESULT(sum, n, 16); \
986 if ((sum >> 16) == 0) \
987 ge |= 3 << (n * 2); \
990 #define SUB8(a, b, n) do { \
992 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
994 if ((sum >> 8) == 0) \
995 ge |= 3 << (n * 2); \
1001 #include "op_addsub.h"
1003 /* Halved signed arithmetic. */
1004 #define ADD16(a, b, n) \
1005 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
1006 #define SUB16(a, b, n) \
1007 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
1008 #define ADD8(a, b, n) \
1009 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
1010 #define SUB8(a, b, n) \
1011 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
1014 #include "op_addsub.h"
1016 /* Halved unsigned arithmetic. */
1017 #define ADD16(a, b, n) \
1018 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1019 #define SUB16(a, b, n) \
1020 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1021 #define ADD8(a, b, n) \
1022 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1023 #define SUB8(a, b, n) \
1024 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1027 #include "op_addsub.h"
1029 void OPPROTO
op_pkhtb_T0_T1(void)
1031 T0
= (T0
& 0xffff0000) | (T1
& 0xffff);
1034 void OPPROTO
op_pkhbt_T0_T1(void)
1036 T0
= (T0
& 0xffff) | (T1
& 0xffff0000);
1039 void OPPROTO
op_rev16_T0(void)
1041 T0
= ((T0
& 0xff000000) >> 8)
1042 | ((T0
& 0x00ff0000) << 8)
1043 | ((T0
& 0x0000ff00) >> 8)
1044 | ((T0
& 0x000000ff) << 8);
1047 void OPPROTO
op_revsh_T0(void)
1049 T0
= (int16_t)( ((T0
& 0x0000ff00) >> 8)
1050 | ((T0
& 0x000000ff) << 8));
1053 void OPPROTO
op_rbit_T0(void)
1055 T0
= ((T0
& 0xff000000) >> 24)
1056 | ((T0
& 0x00ff0000) >> 8)
1057 | ((T0
& 0x0000ff00) << 8)
1058 | ((T0
& 0x000000ff) << 24);
1059 T0
= ((T0
& 0xf0f0f0f0) >> 4)
1060 | ((T0
& 0x0f0f0f0f) << 4);
1061 T0
= ((T0
& 0x88888888) >> 3)
1062 | ((T0
& 0x44444444) >> 1)
1063 | ((T0
& 0x22222222) << 1)
1064 | ((T0
& 0x11111111) << 3);
1067 /* Dual 16-bit signed multiply. */
1068 void OPPROTO
op_mul_dual_T0_T1(void)
1072 low
= (int32_t)(int16_t)T0
* (int32_t)(int16_t)T1
;
1073 high
= (((int32_t)T0
) >> 16) * (((int32_t)T1
) >> 16);
1078 void OPPROTO
op_sel_T0_T1(void)
1093 T0
= (T0
& mask
) | (T1
& ~mask
);
1097 void OPPROTO
op_roundqd_T0_T1(void)
1099 T0
= T1
+ ((uint32_t)T0
>> 31);
1102 /* Signed saturation. */
1103 static inline uint32_t do_ssat(int32_t val
, int shift
)
1110 mask
= (1u << shift
) - 1;
1114 } else if (top
< -1) {
1121 /* Unsigned saturation. */
1122 static inline uint32_t do_usat(int32_t val
, int shift
)
1127 max
= (1u << shift
) - 1;
1131 } else if (val
> max
) {
1138 /* Signed saturate. */
1139 void OPPROTO
op_ssat_T1(void)
1141 T0
= do_ssat(T0
, PARAM1
);
1145 /* Dual halfword signed saturate. */
1146 void OPPROTO
op_ssat16_T1(void)
1150 res
= (uint16_t)do_ssat((int16_t)T0
, PARAM1
);
1151 res
|= do_ssat(((int32_t)T0
) >> 16, PARAM1
) << 16;
1156 /* Unsigned saturate. */
1157 void OPPROTO
op_usat_T1(void)
1159 T0
= do_usat(T0
, PARAM1
);
1163 /* Dual halfword unsigned saturate. */
1164 void OPPROTO
op_usat16_T1(void)
1168 res
= (uint16_t)do_usat((int16_t)T0
, PARAM1
);
1169 res
|= do_usat(((int32_t)T0
) >> 16, PARAM1
) << 16;
1174 /* Dual 16-bit add. */
1175 static inline uint8_t do_usad(uint8_t a
, uint8_t b
)
1183 /* Unsigned sum of absolute byte differences. */
1184 void OPPROTO
op_usad8_T0_T1(void)
1187 sum
= do_usad(T0
, T1
);
1188 sum
+= do_usad(T0
>> 8, T1
>> 8);
1189 sum
+= do_usad(T0
>> 16, T1
>>16);
1190 sum
+= do_usad(T0
>> 24, T1
>> 24);
1194 /* Thumb-2 instructions. */
1196 /* Insert T1 into T0. Result goes in T1. */
1197 void OPPROTO
op_bfi_T1_T0(void)
1200 uint32_t mask
= PARAM2
;
1203 bits
= (T1
<< shift
) & mask
;
1204 T1
= (T0
& ~mask
) | bits
;
1207 /* Unsigned bitfield extract. */
1208 void OPPROTO
op_ubfx_T1(void)
1210 uint32_t shift
= PARAM1
;
1211 uint32_t mask
= PARAM2
;
1217 /* Signed bitfield extract. */
1218 void OPPROTO
op_sbfx_T1(void)
1220 uint32_t shift
= PARAM1
;
1221 uint32_t width
= PARAM2
;
1224 val
= T1
<< (32 - (shift
+ width
));
1225 T1
= val
>> (32 - width
);
1228 void OPPROTO
op_sdivl_T0_T1(void)
1241 void OPPROTO
op_udivl_T0_T1(void)
1254 void OPPROTO
op_movl_T1_r13_banked(void)
1256 T1
= helper_get_r13_banked(env
, PARAM1
);
1259 void OPPROTO
op_movl_r13_T1_banked(void)
1261 helper_set_r13_banked(env
, PARAM1
, T1
);
1264 void OPPROTO
op_v7m_mrs_T0(void)
1266 T0
= helper_v7m_mrs(env
, PARAM1
);
1269 void OPPROTO
op_v7m_msr_T0(void)
1271 helper_v7m_msr(env
, PARAM1
, T0
);
1274 void OPPROTO
op_movl_T0_sp(void)
1276 if (PARAM1
== env
->v7m
.current_sp
)
1279 T0
= env
->v7m
.other_sp
;
1283 #include "op_neon.h"
1285 /* iwMMXt support */
1286 #include "op_iwmmxt.c"