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
24
#define REG (env->regs[0])
25
#include "op_template.h"
28
#define REG (env->regs[1])
29
#include "op_template.h"
32
#define REG (env->regs[2])
33
#include "op_template.h"
36
#define REG (env->regs[3])
37
#include "op_template.h"
40
#define REG (env->regs[4])
41
#include "op_template.h"
44
#define REG (env->regs[5])
45
#include "op_template.h"
48
#define REG (env->regs[6])
49
#include "op_template.h"
52
#define REG (env->regs[7])
53
#include "op_template.h"
56
#define REG (env->regs[8])
57
#include "op_template.h"
60
#define REG (env->regs[9])
61
#include "op_template.h"
64
#define REG (env->regs[10])
65
#include "op_template.h"
68
#define REG (env->regs[11])
69
#include "op_template.h"
72
#define REG (env->regs[12])
73
#include "op_template.h"
76
#define REG (env->regs[13])
77
#include "op_template.h"
80
#define REG (env->regs[14])
81
#include "op_template.h"
84
#define REG (env->regs[15])
85
#define SET_REG(x) REG = x & ~(uint32_t)1
86
#include "op_template.h"
88
void OPPROTO op_bx_T0(void)
90
env->regs[15] = T0 & ~(uint32_t)1;
91
env->thumb = (T0 & 1) != 0;
94
void OPPROTO op_movl_T0_0(void)
99
void OPPROTO op_movl_T0_im(void)
104
void OPPROTO op_movl_T1_im(void)
109
void OPPROTO op_mov_CF_T1(void)
111
env->CF = ((uint32_t)T1) >> 31;
114
void OPPROTO op_movl_T2_im(void)
119
void OPPROTO op_addl_T1_im(void)
124
void OPPROTO op_addl_T1_T2(void)
129
void OPPROTO op_subl_T1_T2(void)
134
void OPPROTO op_addl_T0_T1(void)
139
void OPPROTO op_addl_T0_T1_cc(void)
146
env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
149
void OPPROTO op_adcl_T0_T1(void)
154
void OPPROTO op_adcl_T0_T1_cc(void)
163
env->CF = T0 <= src1;
165
env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
170
#define OPSUB(sub, sbc, res, T0, T1) \
172
void OPPROTO op_ ## sub ## l_T0_T1(void) \
177
void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \
183
env->CF = src1 >= T1; \
184
env->VF = (src1 ^ T1) & (src1 ^ T0); \
188
void OPPROTO op_ ## sbc ## l_T0_T1(void) \
190
res = T0 - T1 + env->CF - 1; \
193
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \
199
env->CF = src1 > T1; \
202
env->CF = src1 >= T1; \
204
env->VF = (src1 ^ T1) & (src1 ^ T0); \
210
OPSUB(sub, sbc, T0, T0, T1)
212
OPSUB(rsb, rsc, T0, T1, T0)
214
void OPPROTO op_andl_T0_T1(void)
219
void OPPROTO op_xorl_T0_T1(void)
224
void OPPROTO op_orl_T0_T1(void)
229
void OPPROTO op_bicl_T0_T1(void)
234
void OPPROTO op_notl_T0(void)
239
void OPPROTO op_notl_T1(void)
244
void OPPROTO op_logic_T0_cc(void)
249
void OPPROTO op_logic_T1_cc(void)
254
#define EIP (env->regs[15])
256
void OPPROTO op_test_eq(void)
259
GOTO_LABEL_PARAM(1);;
263
void OPPROTO op_test_ne(void)
266
GOTO_LABEL_PARAM(1);;
270
void OPPROTO op_test_cs(void)
277
void OPPROTO op_test_cc(void)
284
void OPPROTO op_test_mi(void)
286
if ((env->NZF & 0x80000000) != 0)
291
void OPPROTO op_test_pl(void)
293
if ((env->NZF & 0x80000000) == 0)
298
void OPPROTO op_test_vs(void)
300
if ((env->VF & 0x80000000) != 0)
305
void OPPROTO op_test_vc(void)
307
if ((env->VF & 0x80000000) == 0)
312
void OPPROTO op_test_hi(void)
314
if (env->CF != 0 && env->NZF != 0)
319
void OPPROTO op_test_ls(void)
321
if (env->CF == 0 || env->NZF == 0)
326
void OPPROTO op_test_ge(void)
328
if (((env->VF ^ env->NZF) & 0x80000000) == 0)
333
void OPPROTO op_test_lt(void)
335
if (((env->VF ^ env->NZF) & 0x80000000) != 0)
340
void OPPROTO op_test_gt(void)
342
if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
347
void OPPROTO op_test_le(void)
349
if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
354
void OPPROTO op_test_T0(void)
360
void OPPROTO op_testn_T0(void)
367
void OPPROTO op_goto_tb0(void)
369
GOTO_TB(op_goto_tb0, PARAM1, 0);
372
void OPPROTO op_goto_tb1(void)
374
GOTO_TB(op_goto_tb1, PARAM1, 1);
377
void OPPROTO op_exit_tb(void)
382
void OPPROTO op_movl_T0_cpsr(void)
384
/* Execution state bits always read as zero. */
385
T0 = cpsr_read(env) & ~CPSR_EXEC;
389
void OPPROTO op_movl_T0_spsr(void)
394
void OPPROTO op_movl_spsr_T0(void)
396
uint32_t mask = PARAM1;
397
env->spsr = (env->spsr & ~mask) | (T0 & mask);
400
void OPPROTO op_movl_cpsr_T0(void)
402
cpsr_write(env, T0, PARAM1);
406
void OPPROTO op_mul_T0_T1(void)
411
/* 64 bit unsigned mul */
412
void OPPROTO op_mull_T0_T1(void)
415
res = (uint64_t)T0 * (uint64_t)T1;
420
/* 64 bit signed mul */
421
void OPPROTO op_imull_T0_T1(void)
424
res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
429
/* 48 bit signed mul, top 32 bits */
430
void OPPROTO op_imulw_T0_T1(void)
433
res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
437
void OPPROTO op_addq_T0_T1(void)
440
res = ((uint64_t)T1 << 32) | T0;
441
res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
446
void OPPROTO op_addq_lo_T0_T1(void)
449
res = ((uint64_t)T1 << 32) | T0;
450
res += (uint64_t)(env->regs[PARAM1]);
455
/* Dual 16-bit accumulate. */
456
void OPPROTO op_addq_T0_T1_dual(void)
459
res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
462
env->regs[PARAM1] = (uint32_t)res;
463
env->regs[PARAM2] = res >> 32;
466
/* Dual 16-bit subtract accumulate. */
467
void OPPROTO op_subq_T0_T1_dual(void)
470
res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
473
env->regs[PARAM1] = (uint32_t)res;
474
env->regs[PARAM2] = res >> 32;
477
void OPPROTO op_logicq_cc(void)
479
env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
484
#define MEMSUFFIX _raw
487
#if !defined(CONFIG_USER_ONLY)
488
#define MEMSUFFIX _user
490
#define MEMSUFFIX _kernel
494
void OPPROTO op_clrex(void)
504
void OPPROTO op_shll_T0_im(void)
511
void OPPROTO op_shll_T1_im(void)
516
void OPPROTO op_shrl_T1_im(void)
518
T1 = (uint32_t)T1 >> PARAM1;
521
void OPPROTO op_shrl_T1_0(void)
526
void OPPROTO op_sarl_T1_im(void)
528
T1 = (int32_t)T1 >> PARAM1;
531
void OPPROTO op_sarl_T1_0(void)
533
T1 = (int32_t)T1 >> 31;
536
void OPPROTO op_rorl_T1_im(void)
540
T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
543
void OPPROTO op_rrxl_T1(void)
545
T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
548
/* T1 based, set C flag */
549
void OPPROTO op_shll_T1_im_cc(void)
551
env->CF = (T1 >> (32 - PARAM1)) & 1;
555
void OPPROTO op_shrl_T1_im_cc(void)
557
env->CF = (T1 >> (PARAM1 - 1)) & 1;
558
T1 = (uint32_t)T1 >> PARAM1;
561
void OPPROTO op_shrl_T1_0_cc(void)
563
env->CF = (T1 >> 31) & 1;
567
void OPPROTO op_sarl_T1_im_cc(void)
569
env->CF = (T1 >> (PARAM1 - 1)) & 1;
570
T1 = (int32_t)T1 >> PARAM1;
573
void OPPROTO op_sarl_T1_0_cc(void)
575
env->CF = (T1 >> 31) & 1;
576
T1 = (int32_t)T1 >> 31;
579
void OPPROTO op_rorl_T1_im_cc(void)
583
env->CF = (T1 >> (shift - 1)) & 1;
584
T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
587
void OPPROTO op_rrxl_T1_cc(void)
591
T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
596
void OPPROTO op_shll_T2_im(void)
601
void OPPROTO op_shrl_T2_im(void)
603
T2 = (uint32_t)T2 >> PARAM1;
606
void OPPROTO op_shrl_T2_0(void)
611
void OPPROTO op_sarl_T2_im(void)
613
T2 = (int32_t)T2 >> PARAM1;
616
void OPPROTO op_sarl_T2_0(void)
618
T2 = (int32_t)T2 >> 31;
621
void OPPROTO op_rorl_T2_im(void)
625
T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
628
void OPPROTO op_rrxl_T2(void)
630
T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
633
/* T1 based, use T0 as shift count */
635
void OPPROTO op_shll_T1_T0(void)
646
void OPPROTO op_shrl_T1_T0(void)
653
T1 = (uint32_t)T1 >> shift;
657
void OPPROTO op_sarl_T1_T0(void)
663
T1 = (int32_t)T1 >> shift;
666
void OPPROTO op_rorl_T1_T0(void)
671
T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
676
/* T1 based, use T0 as shift count and compute CF */
678
void OPPROTO op_shll_T1_T0_cc(void)
688
} else if (shift != 0) {
689
env->CF = (T1 >> (32 - shift)) & 1;
695
void OPPROTO op_shrl_T1_T0_cc(void)
701
env->CF = (T1 >> 31) & 1;
705
} else if (shift != 0) {
706
env->CF = (T1 >> (shift - 1)) & 1;
707
T1 = (uint32_t)T1 >> shift;
712
void OPPROTO op_sarl_T1_T0_cc(void)
717
env->CF = (T1 >> 31) & 1;
718
T1 = (int32_t)T1 >> 31;
719
} else if (shift != 0) {
720
env->CF = (T1 >> (shift - 1)) & 1;
721
T1 = (int32_t)T1 >> shift;
726
void OPPROTO op_rorl_T1_T0_cc(void)
730
shift = shift1 & 0x1f;
733
env->CF = (T1 >> 31) & 1;
735
env->CF = (T1 >> (shift - 1)) & 1;
736
T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
742
void OPPROTO op_clz_T0(void)
745
for (count = 32; T0 > 0; count--)
751
void OPPROTO op_sarl_T0_im(void)
753
T0 = (int32_t)T0 >> PARAM1;
756
/* Sign/zero extend */
757
void OPPROTO op_sxth_T0(void)
762
void OPPROTO op_sxth_T1(void)
767
void OPPROTO op_sxtb_T1(void)
772
void OPPROTO op_uxtb_T1(void)
777
void OPPROTO op_uxth_T1(void)
782
void OPPROTO op_sxtb16_T1(void)
785
res = (uint16_t)(int8_t)T1;
786
res |= (uint32_t)(int8_t)(T1 >> 16) << 16;
790
void OPPROTO op_uxtb16_T1(void)
793
res = (uint16_t)(uint8_t)T1;
794
res |= (uint32_t)(uint8_t)(T1 >> 16) << 16;
798
#define SIGNBIT (uint32_t)0x80000000
799
/* saturating arithmetic */
800
void OPPROTO op_addl_T0_T1_setq(void)
805
if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
812
void OPPROTO op_addl_T0_T1_saturate(void)
817
if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
830
void OPPROTO op_subl_T0_T1_saturate(void)
835
if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
848
void OPPROTO op_double_T1_saturate(void)
853
if (val >= 0x40000000) {
856
} else if (val <= (int32_t)0xc0000000) {
865
/* Unsigned saturating arithmetic for NEON. */
866
void OPPROTO op_addl_T0_T1_usaturate(void)
881
void OPPROTO op_subl_T0_T1_usaturate(void)
896
/* Thumb shift by immediate */
897
void OPPROTO op_shll_T0_im_thumb_cc(void)
902
env->CF = (T0 >> (32 - shift)) & 1;
909
void OPPROTO op_shll_T0_im_thumb(void)
915
void OPPROTO op_shrl_T0_im_thumb_cc(void)
921
env->CF = ((uint32_t)T0) >> 31;
924
env->CF = (T0 >> (shift - 1)) & 1;
931
void OPPROTO op_shrl_T0_im_thumb(void)
944
void OPPROTO op_sarl_T0_im_thumb_cc(void)
950
T0 = ((int32_t)T0) >> 31;
953
env->CF = (T0 >> (shift - 1)) & 1;
954
T0 = ((int32_t)T0) >> shift;
960
void OPPROTO op_sarl_T0_im_thumb(void)
968
T0 = ((int32_t)T0) >> shift;
975
void OPPROTO op_swi(void)
977
env->exception_index = EXCP_SWI;
981
void OPPROTO op_undef_insn(void)
983
env->exception_index = EXCP_UDEF;
987
void OPPROTO op_debug(void)
989
env->exception_index = EXCP_DEBUG;
993
void OPPROTO op_wfi(void)
995
env->exception_index = EXCP_HLT;
1000
void OPPROTO op_bkpt(void)
1002
env->exception_index = EXCP_BKPT;
1006
void OPPROTO op_exception_exit(void)
1008
env->exception_index = EXCP_EXCEPTION_EXIT;
1012
/* VFP support. We follow the convention used for VFP instrunctions:
1013
Single precition routines have a "s" suffix, double precision a
1016
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
1018
#define VFP_BINOP(name) \
1021
FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status); \
1025
FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status); \
1033
#define VFP_HELPER(name) \
1036
do_vfp_##name##s(); \
1040
do_vfp_##name##d(); \
1048
/* XXX: Will this do the right thing for NANs. Should invert the signbit
1049
without looking at the rest of the value. */
1052
FT0s = float32_chs(FT0s);
1057
FT0d = float64_chs(FT0d);
1080
/* Helper routines to perform bitwise copies between float and int. */
1081
static inline float32 vfp_itos(uint32_t i)
1092
static inline uint32_t vfp_stoi(float32 s)
1103
static inline float64 vfp_itod(uint64_t i)
1114
static inline uint64_t vfp_dtoi(float64 d)
1125
/* Integer to float conversion. */
1128
FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
1133
FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
1138
FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
1143
FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
1146
/* Float to integer conversion. */
1149
FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
1154
FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
1159
FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
1164
FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
1167
/* TODO: Set rounding mode properly. */
1170
FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
1175
FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
1180
FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
1185
FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
1188
/* floating point conversion */
1191
FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
1196
FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
1199
/* VFP3 fixed point conversion. */
1200
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
1201
VFP_OP(name##to, p) \
1204
tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \
1205
&env->vfp.fp_status); \
1206
FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \
1208
VFP_OP(to##name, p) \
1211
tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \
1212
FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
1213
&env->vfp.fp_status)); \
1216
VFP_CONV_FIX(sh, d, float64, int16, )
1217
VFP_CONV_FIX(sl, d, float64, int32, )
1218
VFP_CONV_FIX(uh, d, float64, uint16, u)
1219
VFP_CONV_FIX(ul, d, float64, uint32, u)
1220
VFP_CONV_FIX(sh, s, float32, int16, )
1221
VFP_CONV_FIX(sl, s, float32, int32, )
1222
VFP_CONV_FIX(uh, s, float32, uint16, u)
1223
VFP_CONV_FIX(ul, s, float32, uint32, u)
1225
/* Get and Put values from registers. */
1226
VFP_OP(getreg_F0, d)
1228
FT0d = *(float64 *)((char *) env + PARAM1);
1231
VFP_OP(getreg_F0, s)
1233
FT0s = *(float32 *)((char *) env + PARAM1);
1236
VFP_OP(getreg_F1, d)
1238
FT1d = *(float64 *)((char *) env + PARAM1);
1241
VFP_OP(getreg_F1, s)
1243
FT1s = *(float32 *)((char *) env + PARAM1);
1246
VFP_OP(setreg_F0, d)
1248
*(float64 *)((char *) env + PARAM1) = FT0d;
1251
VFP_OP(setreg_F0, s)
1253
*(float32 *)((char *) env + PARAM1) = FT0s;
1256
void OPPROTO op_vfp_movl_T0_fpscr(void)
1258
do_vfp_get_fpscr ();
1261
void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
1263
T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
1266
void OPPROTO op_vfp_movl_fpscr_T0(void)
1271
void OPPROTO op_vfp_movl_T0_xreg(void)
1273
T0 = env->vfp.xregs[PARAM1];
1276
void OPPROTO op_vfp_movl_xreg_T0(void)
1278
env->vfp.xregs[PARAM1] = T0;
1281
/* Move between FT0s to T0 */
1282
void OPPROTO op_vfp_mrs(void)
1284
T0 = vfp_stoi(FT0s);
1287
void OPPROTO op_vfp_msr(void)
1289
FT0s = vfp_itos(T0);
1292
/* Move between FT0d and {T0,T1} */
1293
void OPPROTO op_vfp_mrrd(void)
1302
void OPPROTO op_vfp_mdrr(void)
1311
/* Load immediate. PARAM1 is the 32 most significant bits of the value. */
1312
void OPPROTO op_vfp_fconstd(void)
1320
void OPPROTO op_vfp_fconsts(void)
1322
FT0s = vfp_itos(PARAM1);
1325
/* Copy the most significant bit of T0 to all bits of T1. */
1326
void OPPROTO op_signbit_T1_T0(void)
1328
T1 = (int32_t)T0 >> 31;
1331
void OPPROTO op_movl_cp_T0(void)
1333
helper_set_cp(env, PARAM1, T0);
1337
void OPPROTO op_movl_T0_cp(void)
1339
T0 = helper_get_cp(env, PARAM1);
1343
void OPPROTO op_movl_cp15_T0(void)
1345
helper_set_cp15(env, PARAM1, T0);
1349
void OPPROTO op_movl_T0_cp15(void)
1351
T0 = helper_get_cp15(env, PARAM1);
1355
/* Access to user mode registers from privileged modes. */
1356
void OPPROTO op_movl_T0_user(void)
1360
T0 = env->banked_r13[0];
1361
} else if (regno == 14) {
1362
T0 = env->banked_r14[0];
1363
} else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1364
T0 = env->usr_regs[regno - 8];
1366
T0 = env->regs[regno];
1372
void OPPROTO op_movl_user_T0(void)
1376
env->banked_r13[0] = T0;
1377
} else if (regno == 14) {
1378
env->banked_r14[0] = T0;
1379
} else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1380
env->usr_regs[regno - 8] = T0;
1382
env->regs[regno] = T0;
1387
void OPPROTO op_movl_T0_T1(void)
1392
void OPPROTO op_movl_T0_T2(void)
1397
void OPPROTO op_movl_T1_T0(void)
1402
void OPPROTO op_movl_T1_T2(void)
1407
void OPPROTO op_movl_T2_T0(void)
1412
/* ARMv6 Media instructions. */
1414
/* Note that signed overflow is undefined in C. The following routines are
1415
careful to use unsigned types where modulo arithmetic is required.
1416
Failure to do so _will_ break on newer gcc. */
1418
/* Signed saturating arithmetic. */
1420
/* Perform 16-bit signed satruating addition. */
1421
static inline uint16_t add16_sat(uint16_t a, uint16_t b)
1426
if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
1435
/* Perform 8-bit signed satruating addition. */
1436
static inline uint8_t add8_sat(uint8_t a, uint8_t b)
1441
if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
1450
/* Perform 16-bit signed satruating subtraction. */
1451
static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
1456
if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
1465
/* Perform 8-bit signed satruating subtraction. */
1466
static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
1471
if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
1480
#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
1481
#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
1482
#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
1483
#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
1486
#include "op_addsub.h"
1488
/* Unsigned saturating arithmetic. */
1489
static inline uint16_t add16_usat(uint16_t a, uint8_t b)
1498
static inline uint16_t sub16_usat(uint16_t a, uint8_t b)
1506
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
1515
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
1523
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
1524
#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
1525
#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
1526
#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
1529
#include "op_addsub.h"
1531
/* Signed modulo arithmetic. */
1532
#define SARITH16(a, b, n, op) do { \
1534
sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
1535
RESULT(sum, n, 16); \
1537
ge |= 3 << (n * 2); \
1540
#define SARITH8(a, b, n, op) do { \
1542
sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
1543
RESULT(sum, n, 8); \
1549
#define ADD16(a, b, n) SARITH16(a, b, n, +)
1550
#define SUB16(a, b, n) SARITH16(a, b, n, -)
1551
#define ADD8(a, b, n) SARITH8(a, b, n, +)
1552
#define SUB8(a, b, n) SARITH8(a, b, n, -)
1556
#include "op_addsub.h"
1558
/* Unsigned modulo arithmetic. */
1559
#define ADD16(a, b, n) do { \
1561
sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
1562
RESULT(sum, n, 16); \
1563
if ((sum >> 16) == 0) \
1564
ge |= 3 << (n * 2); \
1567
#define ADD8(a, b, n) do { \
1569
sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
1570
RESULT(sum, n, 8); \
1571
if ((sum >> 8) == 0) \
1572
ge |= 3 << (n * 2); \
1575
#define SUB16(a, b, n) do { \
1577
sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
1578
RESULT(sum, n, 16); \
1579
if ((sum >> 16) == 0) \
1580
ge |= 3 << (n * 2); \
1583
#define SUB8(a, b, n) do { \
1585
sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
1586
RESULT(sum, n, 8); \
1587
if ((sum >> 8) == 0) \
1588
ge |= 3 << (n * 2); \
1594
#include "op_addsub.h"
1596
/* Halved signed arithmetic. */
1597
#define ADD16(a, b, n) \
1598
RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
1599
#define SUB16(a, b, n) \
1600
RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
1601
#define ADD8(a, b, n) \
1602
RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
1603
#define SUB8(a, b, n) \
1604
RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
1607
#include "op_addsub.h"
1609
/* Halved unsigned arithmetic. */
1610
#define ADD16(a, b, n) \
1611
RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1612
#define SUB16(a, b, n) \
1613
RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1614
#define ADD8(a, b, n) \
1615
RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1616
#define SUB8(a, b, n) \
1617
RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1620
#include "op_addsub.h"
1622
void OPPROTO op_pkhtb_T0_T1(void)
1624
T0 = (T0 & 0xffff0000) | (T1 & 0xffff);
1627
void OPPROTO op_pkhbt_T0_T1(void)
1629
T0 = (T0 & 0xffff) | (T1 & 0xffff0000);
1631
void OPPROTO op_rev_T0(void)
1633
T0 = ((T0 & 0xff000000) >> 24)
1634
| ((T0 & 0x00ff0000) >> 8)
1635
| ((T0 & 0x0000ff00) << 8)
1636
| ((T0 & 0x000000ff) << 24);
1639
void OPPROTO op_revh_T0(void)
1641
T0 = (T0 >> 16) | (T0 << 16);
1644
void OPPROTO op_rev16_T0(void)
1646
T0 = ((T0 & 0xff000000) >> 8)
1647
| ((T0 & 0x00ff0000) << 8)
1648
| ((T0 & 0x0000ff00) >> 8)
1649
| ((T0 & 0x000000ff) << 8);
1652
void OPPROTO op_revsh_T0(void)
1654
T0 = (int16_t)( ((T0 & 0x0000ff00) >> 8)
1655
| ((T0 & 0x000000ff) << 8));
1658
void OPPROTO op_rbit_T0(void)
1660
T0 = ((T0 & 0xff000000) >> 24)
1661
| ((T0 & 0x00ff0000) >> 8)
1662
| ((T0 & 0x0000ff00) << 8)
1663
| ((T0 & 0x000000ff) << 24);
1664
T0 = ((T0 & 0xf0f0f0f0) >> 4)
1665
| ((T0 & 0x0f0f0f0f) << 4);
1666
T0 = ((T0 & 0x88888888) >> 3)
1667
| ((T0 & 0x44444444) >> 1)
1668
| ((T0 & 0x22222222) << 1)
1669
| ((T0 & 0x11111111) << 3);
1672
/* Swap low and high halfwords. */
1673
void OPPROTO op_swap_half_T1(void)
1675
T1 = (T1 >> 16) | (T1 << 16);
1679
/* Dual 16-bit signed multiply. */
1680
void OPPROTO op_mul_dual_T0_T1(void)
1684
low = (int32_t)(int16_t)T0 * (int32_t)(int16_t)T1;
1685
high = (((int32_t)T0) >> 16) * (((int32_t)T1) >> 16);
1690
void OPPROTO op_sel_T0_T1(void)
1705
T0 = (T0 & mask) | (T1 & ~mask);
1709
void OPPROTO op_roundqd_T0_T1(void)
1711
T0 = T1 + ((uint32_t)T0 >> 31);
1714
/* Signed saturation. */
1715
static inline uint32_t do_ssat(int32_t val, int shift)
1722
mask = (1u << shift) - 1;
1726
} else if (top < -1) {
1733
/* Unsigned saturation. */
1734
static inline uint32_t do_usat(int32_t val, int shift)
1739
max = (1u << shift) - 1;
1743
} else if (val > max) {
1750
/* Signed saturate. */
1751
void OPPROTO op_ssat_T1(void)
1753
T0 = do_ssat(T0, PARAM1);
1757
/* Dual halfword signed saturate. */
1758
void OPPROTO op_ssat16_T1(void)
1762
res = (uint16_t)do_ssat((int16_t)T0, PARAM1);
1763
res |= do_ssat(((int32_t)T0) >> 16, PARAM1) << 16;
1768
/* Unsigned saturate. */
1769
void OPPROTO op_usat_T1(void)
1771
T0 = do_usat(T0, PARAM1);
1775
/* Dual halfword unsigned saturate. */
1776
void OPPROTO op_usat16_T1(void)
1780
res = (uint16_t)do_usat((int16_t)T0, PARAM1);
1781
res |= do_usat(((int32_t)T0) >> 16, PARAM1) << 16;
1786
/* Dual 16-bit add. */
1787
void OPPROTO op_add16_T1_T2(void)
1790
mask = (T0 & T1) & 0x8000;
1793
T0 = (T0 + T1) ^ mask;
1796
static inline uint8_t do_usad(uint8_t a, uint8_t b)
1804
/* Unsigned sum of absolute byte differences. */
1805
void OPPROTO op_usad8_T0_T1(void)
1808
sum = do_usad(T0, T1);
1809
sum += do_usad(T0 >> 8, T1 >> 8);
1810
sum += do_usad(T0 >> 16, T1 >>16);
1811
sum += do_usad(T0 >> 24, T1 >> 24);
1815
/* Thumb-2 instructions. */
1817
/* Insert T1 into T0. Result goes in T1. */
1818
void OPPROTO op_bfi_T1_T0(void)
1821
uint32_t mask = PARAM2;
1824
bits = (T1 << shift) & mask;
1825
T1 = (T0 & ~mask) | bits;
1828
/* Unsigned bitfield extract. */
1829
void OPPROTO op_ubfx_T1(void)
1831
uint32_t shift = PARAM1;
1832
uint32_t mask = PARAM2;
1838
/* Signed bitfield extract. */
1839
void OPPROTO op_sbfx_T1(void)
1841
uint32_t shift = PARAM1;
1842
uint32_t width = PARAM2;
1845
val = T1 << (32 - (shift + width));
1846
T1 = val >> (32 - width);
1849
void OPPROTO op_movtop_T0_im(void)
1851
T0 = (T0 & 0xffff) | PARAM1;
1854
/* Used by table branch instructions. */
1855
void OPPROTO op_jmp_T0_im(void)
1857
env->regs[15] = PARAM1 + (T0 << 1);
1860
void OPPROTO op_set_condexec(void)
1862
env->condexec_bits = PARAM1;
1865
void OPPROTO op_sdivl_T0_T1(void)
1878
void OPPROTO op_udivl_T0_T1(void)
1891
void OPPROTO op_movl_T1_r13_banked(void)
1893
T1 = helper_get_r13_banked(env, PARAM1);
1896
void OPPROTO op_movl_r13_T1_banked(void)
1898
helper_set_r13_banked(env, PARAM1, T1);
1901
void OPPROTO op_v7m_mrs_T0(void)
1903
T0 = helper_v7m_mrs(env, PARAM1);
1906
void OPPROTO op_v7m_msr_T0(void)
1908
helper_v7m_msr(env, PARAM1, T0);
1911
void OPPROTO op_movl_T0_sp(void)
1913
if (PARAM1 == env->v7m.current_sp)
1916
T0 = env->v7m.other_sp;
1920
#include "op_neon.h"
1922
/* iwMMXt support */
1923
#include "op_iwmmxt.c"