Commit 18c9b56060e6d69e38d0d91ffb02d510d8ce1971

Authored by balrog
1 parent a171fe39

Implement iwMMXt instruction set for the PXA270 cpu.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2752 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/cpu.h
... ... @@ -129,6 +129,14 @@ typedef struct CPUARMState {
129 129 float_status fp_status;
130 130 } vfp;
131 131  
  132 + /* iwMMXt coprocessor state. */
  133 + struct {
  134 + uint64_t regs[16];
  135 + uint64_t val;
  136 +
  137 + uint32_t cregs[16];
  138 + } iwmmxt;
  139 +
132 140 #if defined(CONFIG_USER_ONLY)
133 141 /* For usermode syscall translation. */
134 142 int eabi;
... ... @@ -218,10 +226,21 @@ enum arm_cpu_mode {
218 226 #define ARM_VFP_FPINST 9
219 227 #define ARM_VFP_FPINST2 10
220 228  
  229 +/* iwMMXt coprocessor control registers. */
  230 +#define ARM_IWMMXT_wCID 0
  231 +#define ARM_IWMMXT_wCon 1
  232 +#define ARM_IWMMXT_wCSSF 2
  233 +#define ARM_IWMMXT_wCASF 3
  234 +#define ARM_IWMMXT_wCGR0 8
  235 +#define ARM_IWMMXT_wCGR1 9
  236 +#define ARM_IWMMXT_wCGR2 10
  237 +#define ARM_IWMMXT_wCGR3 11
  238 +
221 239 enum arm_features {
222 240 ARM_FEATURE_VFP,
223 241 ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
224 242 ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
  243 + ARM_FEATURE_IWMMXT /* Intel iwMMXt extension. */
225 244 };
226 245  
227 246 static inline int arm_feature(CPUARMState *env, int feature)
... ...
target-arm/exec.h
... ... @@ -32,6 +32,8 @@ register uint32_t T2 asm(AREG3);
32 32 #define FT0d env->vfp.tmp0d
33 33 #define FT1d env->vfp.tmp1d
34 34  
  35 +#define M0 env->iwmmxt.val
  36 +
35 37 #include "cpu.h"
36 38 #include "exec-all.h"
37 39  
... ...
target-arm/helper.c
... ... @@ -42,6 +42,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
42 42 case ARM_CPUID_PXA270_C5:
43 43 set_feature(env, ARM_FEATURE_XSCALE);
44 44 /* JTAG_ID is ((id << 28) | 0x09265013) */
  45 + set_feature(env, ARM_FEATURE_IWMMXT);
  46 + env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
45 47 env->cp15.c0_cachetype = 0xd172172;
46 48 break;
47 49 default:
... ...
target-arm/op.c
... ... @@ -1213,3 +1213,6 @@ void OPPROTO op_movl_T0_T2(void)
1213 1213 {
1214 1214 T0 = T2;
1215 1215 }
  1216 +
  1217 +/* iwMMXt support */
  1218 +#include "op_iwmmxt.c"
... ...
target-arm/op_iwmmxt.c 0 → 100644
  1 +/*
  2 + * iwMMXt micro operations for XScale.
  3 + *
  4 + * Copyright (c) 2007 OpenedHand, Ltd.
  5 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6 + *
  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.
  11 + *
  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.
  16 + *
  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
  20 + */
  21 +
  22 +#define M1 env->iwmmxt.regs[PARAM1]
  23 +
  24 +/* iwMMXt macros extracted from GNU gdb. */
  25 +
  26 +/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
  27 +#define SIMD8_SET( v, n, b) ((v != 0) << ((((b) + 1) * 4) + (n)))
  28 +#define SIMD16_SET(v, n, h) ((v != 0) << ((((h) + 1) * 8) + (n)))
  29 +#define SIMD32_SET(v, n, w) ((v != 0) << ((((w) + 1) * 16) + (n)))
  30 +#define SIMD64_SET(v, n) ((v != 0) << (32 + (n)))
  31 +/* Flags to pass as "n" above. */
  32 +#define SIMD_NBIT -1
  33 +#define SIMD_ZBIT -2
  34 +#define SIMD_CBIT -3
  35 +#define SIMD_VBIT -4
  36 +/* Various status bit macros. */
  37 +#define NBIT8(x) ((x) & 0x80)
  38 +#define NBIT16(x) ((x) & 0x8000)
  39 +#define NBIT32(x) ((x) & 0x80000000)
  40 +#define NBIT64(x) ((x) & 0x8000000000000000ULL)
  41 +#define ZBIT8(x) (((x) & 0xff) == 0)
  42 +#define ZBIT16(x) (((x) & 0xffff) == 0)
  43 +#define ZBIT32(x) (((x) & 0xffffffff) == 0)
  44 +#define ZBIT64(x) (x == 0)
  45 +/* Sign extension macros. */
  46 +#define EXTEND8H(a) ((uint16_t) (int8_t) (a))
  47 +#define EXTEND8(a) ((uint32_t) (int8_t) (a))
  48 +#define EXTEND16(a) ((uint32_t) (int16_t) (a))
  49 +#define EXTEND16S(a) ((int32_t) (int16_t) (a))
  50 +#define EXTEND32(a) ((uint64_t) (int32_t) (a))
  51 +
  52 +void OPPROTO op_iwmmxt_movl_T0_T1_wRn(void)
  53 +{
  54 + T0 = M1 & ~(uint32_t) 0;
  55 + T1 = M1 >> 32;
  56 +}
  57 +
  58 +void OPPROTO op_iwmmxt_movl_wRn_T0_T1(void)
  59 +{
  60 + M1 = ((uint64_t) T1 << 32) | T0;
  61 +}
  62 +
  63 +void OPPROTO op_iwmmxt_movq_M0_wRn(void)
  64 +{
  65 + M0 = M1;
  66 +}
  67 +
  68 +void OPPROTO op_iwmmxt_orq_M0_wRn(void)
  69 +{
  70 + M0 |= M1;
  71 +}
  72 +
  73 +void OPPROTO op_iwmmxt_andq_M0_wRn(void)
  74 +{
  75 + M0 &= M1;
  76 +}
  77 +
  78 +void OPPROTO op_iwmmxt_xorq_M0_wRn(void)
  79 +{
  80 + M0 ^= M1;
  81 +}
  82 +
  83 +void OPPROTO op_iwmmxt_maddsq_M0_wRn(void)
  84 +{
  85 + M0 = ((
  86 + EXTEND16S((M0 >> 0) & 0xffff) * EXTEND16S((M1 >> 0) & 0xffff) +
  87 + EXTEND16S((M0 >> 16) & 0xffff) * EXTEND16S((M1 >> 16) & 0xffff)
  88 + ) & 0xffffffff) | ((uint64_t) (
  89 + EXTEND16S((M0 >> 32) & 0xffff) * EXTEND16S((M1 >> 32) & 0xffff) +
  90 + EXTEND16S((M0 >> 48) & 0xffff) * EXTEND16S((M1 >> 48) & 0xffff)
  91 + ) << 32);
  92 +}
  93 +
  94 +void OPPROTO op_iwmmxt_madduq_M0_wRn(void)
  95 +{
  96 + M0 = ((
  97 + ((M0 >> 0) & 0xffff) * ((M1 >> 0) & 0xffff) +
  98 + ((M0 >> 16) & 0xffff) * ((M1 >> 16) & 0xffff)
  99 + ) & 0xffffffff) | ((
  100 + ((M0 >> 32) & 0xffff) * ((M1 >> 32) & 0xffff) +
  101 + ((M0 >> 48) & 0xffff) * ((M1 >> 48) & 0xffff)
  102 + ) << 32);
  103 +}
  104 +
  105 +void OPPROTO op_iwmmxt_sadb_M0_wRn(void)
  106 +{
  107 +#define abs(x) (((x) >= 0) ? x : -x)
  108 +#define SADB(SHR) abs((int) ((M0 >> SHR) & 0xff) - (int) ((M1 >> SHR) & 0xff))
  109 + M0 =
  110 + SADB(0) + SADB(8) + SADB(16) + SADB(24) +
  111 + SADB(32) + SADB(40) + SADB(48) + SADB(56);
  112 +#undef SADB
  113 +}
  114 +
  115 +void OPPROTO op_iwmmxt_sadw_M0_wRn(void)
  116 +{
  117 +#define SADW(SHR) \
  118 + abs((int) ((M0 >> SHR) & 0xffff) - (int) ((M1 >> SHR) & 0xffff))
  119 + M0 = SADW(0) + SADW(16) + SADW(32) + SADW(48);
  120 +#undef SADW
  121 +}
  122 +
  123 +void OPPROTO op_iwmmxt_addl_M0_wRn(void)
  124 +{
  125 + M0 += env->iwmmxt.regs[PARAM1] & 0xffffffff;
  126 +}
  127 +
  128 +void OPPROTO op_iwmmxt_mulsw_M0_wRn(void)
  129 +{
  130 +#define MULS(SHR) ((uint64_t) ((( \
  131 + EXTEND16S((M0 >> SHR) & 0xffff) * EXTEND16S((M1 >> SHR) & 0xffff) \
  132 + ) >> PARAM2) & 0xffff) << SHR)
  133 + M0 = MULS(0) | MULS(16) | MULS(32) | MULS(48);
  134 +#undef MULS
  135 +}
  136 +
  137 +void OPPROTO op_iwmmxt_muluw_M0_wRn(void)
  138 +{
  139 +#define MULU(SHR) ((uint64_t) ((( \
  140 + ((M0 >> SHR) & 0xffff) * ((M1 >> SHR) & 0xffff) \
  141 + ) >> PARAM2) & 0xffff) << SHR)
  142 + M0 = MULU(0) | MULU(16) | MULU(32) | MULU(48);
  143 +#undef MULU
  144 +}
  145 +
  146 +void OPPROTO op_iwmmxt_macsw_M0_wRn(void)
  147 +{
  148 +#define MACS(SHR) ( \
  149 + EXTEND16((M0 >> SHR) & 0xffff) * EXTEND16S((M1 >> SHR) & 0xffff))
  150 + M0 = (int64_t) (MACS(0) + MACS(16) + MACS(32) + MACS(48));
  151 +#undef MACS
  152 +}
  153 +
  154 +void OPPROTO op_iwmmxt_macuw_M0_wRn(void)
  155 +{
  156 +#define MACU(SHR) ( \
  157 + (uint32_t) ((M0 >> SHR) & 0xffff) * \
  158 + (uint32_t) ((M1 >> SHR) & 0xffff))
  159 + M0 = MACU(0) + MACU(16) + MACU(32) + MACU(48);
  160 +#undef MACU
  161 +}
  162 +
  163 +void OPPROTO op_iwmmxt_addsq_M0_wRn(void)
  164 +{
  165 + M0 = (int64_t) M0 + (int64_t) M1;
  166 +}
  167 +
  168 +void OPPROTO op_iwmmxt_adduq_M0_wRn(void)
  169 +{
  170 + M0 += M1;
  171 +}
  172 +
  173 +void OPPROTO op_iwmmxt_movq_wRn_M0(void)
  174 +{
  175 + M1 = M0;
  176 +}
  177 +
  178 +void OPPROTO op_iwmmxt_movl_wCx_T0(void)
  179 +{
  180 + env->iwmmxt.cregs[PARAM1] = T0;
  181 +}
  182 +
  183 +void OPPROTO op_iwmmxt_movl_T0_wCx(void)
  184 +{
  185 + T0 = env->iwmmxt.cregs[PARAM1];
  186 +}
  187 +
  188 +void OPPROTO op_iwmmxt_movl_T1_wCx(void)
  189 +{
  190 + T1 = env->iwmmxt.cregs[PARAM1];
  191 +}
  192 +
  193 +void OPPROTO op_iwmmxt_set_mup(void)
  194 +{
  195 + env->iwmmxt.cregs[ARM_IWMMXT_wCon] |= 2;
  196 +}
  197 +
  198 +void OPPROTO op_iwmmxt_set_cup(void)
  199 +{
  200 + env->iwmmxt.cregs[ARM_IWMMXT_wCon] |= 1;
  201 +}
  202 +
  203 +void OPPROTO op_iwmmxt_setpsr_nz(void)
  204 +{
  205 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  206 + SIMD64_SET((M0 == 0), SIMD_ZBIT) |
  207 + SIMD64_SET((M0 & (1ULL << 63)), SIMD_NBIT);
  208 +}
  209 +
  210 +void OPPROTO op_iwmmxt_negq_M0(void)
  211 +{
  212 + M0 = ~M0;
  213 +}
  214 +
  215 +#define NZBIT8(x, i) \
  216 + SIMD8_SET(NBIT8((x) & 0xff), SIMD_NBIT, i) | \
  217 + SIMD8_SET(ZBIT8((x) & 0xff), SIMD_ZBIT, i)
  218 +#define NZBIT16(x, i) \
  219 + SIMD16_SET(NBIT16((x) & 0xffff), SIMD_NBIT, i) | \
  220 + SIMD16_SET(ZBIT16((x) & 0xffff), SIMD_ZBIT, i)
  221 +#define NZBIT32(x, i) \
  222 + SIMD32_SET(NBIT32((x) & 0xffffffff), SIMD_NBIT, i) | \
  223 + SIMD32_SET(ZBIT32((x) & 0xffffffff), SIMD_ZBIT, i)
  224 +#define NZBIT64(x) \
  225 + SIMD64_SET(NBIT64(x), SIMD_NBIT) | \
  226 + SIMD64_SET(ZBIT64(x), SIMD_ZBIT)
  227 +#define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3) \
  228 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, b_M0_wRn))(void) \
  229 +{ \
  230 + M0 = \
  231 + (((M0 >> SH0) & 0xff) << 0) | (((M1 >> SH0) & 0xff) << 8) | \
  232 + (((M0 >> SH1) & 0xff) << 16) | (((M1 >> SH1) & 0xff) << 24) | \
  233 + (((M0 >> SH2) & 0xff) << 32) | (((M1 >> SH2) & 0xff) << 40) | \
  234 + (((M0 >> SH3) & 0xff) << 48) | (((M1 >> SH3) & 0xff) << 56); \
  235 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  236 + NZBIT8(M0 >> 0, 0) | NZBIT8(M0 >> 8, 1) | \
  237 + NZBIT8(M0 >> 16, 2) | NZBIT8(M0 >> 24, 3) | \
  238 + NZBIT8(M0 >> 32, 4) | NZBIT8(M0 >> 40, 5) | \
  239 + NZBIT8(M0 >> 48, 6) | NZBIT8(M0 >> 56, 7); \
  240 +} \
  241 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, w_M0_wRn))(void) \
  242 +{ \
  243 + M0 = \
  244 + (((M0 >> SH0) & 0xffff) << 0) | \
  245 + (((M1 >> SH0) & 0xffff) << 16) | \
  246 + (((M0 >> SH2) & 0xffff) << 32) | \
  247 + (((M1 >> SH2) & 0xffff) << 48); \
  248 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  249 + NZBIT8(M0 >> 0, 0) | NZBIT8(M0 >> 16, 1) | \
  250 + NZBIT8(M0 >> 32, 2) | NZBIT8(M0 >> 48, 3); \
  251 +} \
  252 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, l_M0_wRn))(void) \
  253 +{ \
  254 + M0 = \
  255 + (((M0 >> SH0) & 0xffffffff) << 0) | \
  256 + (((M1 >> SH0) & 0xffffffff) << 32); \
  257 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  258 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1); \
  259 +} \
  260 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, ub_M0))(void) \
  261 +{ \
  262 + M0 = \
  263 + (((M0 >> SH0) & 0xff) << 0) | \
  264 + (((M0 >> SH1) & 0xff) << 16) | \
  265 + (((M0 >> SH2) & 0xff) << 32) | \
  266 + (((M0 >> SH3) & 0xff) << 48); \
  267 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  268 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) | \
  269 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3); \
  270 +} \
  271 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, uw_M0))(void) \
  272 +{ \
  273 + M0 = \
  274 + (((M0 >> SH0) & 0xffff) << 0) | \
  275 + (((M0 >> SH2) & 0xffff) << 32); \
  276 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  277 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1); \
  278 +} \
  279 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, ul_M0))(void) \
  280 +{ \
  281 + M0 = (((M0 >> SH0) & 0xffffffff) << 0); \
  282 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0 >> 0); \
  283 +} \
  284 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, sb_M0))(void) \
  285 +{ \
  286 + M0 = \
  287 + ((uint64_t) EXTEND8H((M0 >> SH0) & 0xff) << 0) | \
  288 + ((uint64_t) EXTEND8H((M0 >> SH1) & 0xff) << 16) | \
  289 + ((uint64_t) EXTEND8H((M0 >> SH2) & 0xff) << 32) | \
  290 + ((uint64_t) EXTEND8H((M0 >> SH3) & 0xff) << 48); \
  291 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  292 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) | \
  293 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3); \
  294 +} \
  295 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, sw_M0))(void) \
  296 +{ \
  297 + M0 = \
  298 + ((uint64_t) EXTEND16((M0 >> SH0) & 0xffff) << 0) | \
  299 + ((uint64_t) EXTEND16((M0 >> SH2) & 0xffff) << 32); \
  300 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  301 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1); \
  302 +} \
  303 +void OPPROTO glue(op_iwmmxt_unpack, glue(S, sl_M0))(void) \
  304 +{ \
  305 + M0 = EXTEND32((M0 >> SH0) & 0xffffffff); \
  306 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0 >> 0); \
  307 +}
  308 +IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
  309 +IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
  310 +
  311 +#define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O) \
  312 +void OPPROTO glue(op_iwmmxt_, glue(SUFF, b_M0_wRn))(void) \
  313 +{ \
  314 + M0 = \
  315 + CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) | \
  316 + CMP(16, Tb, O, 0xff) | CMP(24, Tb, O, 0xff) | \
  317 + CMP(32, Tb, O, 0xff) | CMP(40, Tb, O, 0xff) | \
  318 + CMP(48, Tb, O, 0xff) | CMP(56, Tb, O, 0xff); \
  319 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  320 + NZBIT8(M0 >> 0, 0) | NZBIT8(M0 >> 8, 1) | \
  321 + NZBIT8(M0 >> 16, 2) | NZBIT8(M0 >> 24, 3) | \
  322 + NZBIT8(M0 >> 32, 4) | NZBIT8(M0 >> 40, 5) | \
  323 + NZBIT8(M0 >> 48, 6) | NZBIT8(M0 >> 56, 7); \
  324 +} \
  325 +void OPPROTO glue(op_iwmmxt_, glue(SUFF, w_M0_wRn))(void) \
  326 +{ \
  327 + M0 = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) | \
  328 + CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff); \
  329 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  330 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) | \
  331 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3); \
  332 +} \
  333 +void OPPROTO glue(op_iwmmxt_, glue(SUFF, l_M0_wRn))(void) \
  334 +{ \
  335 + M0 = CMP(0, Tl, O, 0xffffffff) | \
  336 + CMP(32, Tl, O, 0xffffffff); \
  337 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
  338 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1); \
  339 +}
  340 +#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((M0 >> SHR) & MASK) OPER \
  341 + (TYPE) ((M1 >> SHR) & MASK)) ? (uint64_t) MASK : 0) << SHR)
  342 +IWMMXT_OP_CMP(cmpeq, uint8_t, uint16_t, uint32_t, ==)
  343 +IWMMXT_OP_CMP(cmpgts, int8_t, int16_t, int32_t, >)
  344 +IWMMXT_OP_CMP(cmpgtu, uint8_t, uint16_t, uint32_t, >)
  345 +#undef CMP
  346 +#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((M0 >> SHR) & MASK) OPER \
  347 + (TYPE) ((M1 >> SHR) & MASK)) ? M0 : M1) & ((uint64_t) MASK << SHR))
  348 +IWMMXT_OP_CMP(mins, int8_t, int16_t, int32_t, <)
  349 +IWMMXT_OP_CMP(minu, uint8_t, uint16_t, uint32_t, <)
  350 +IWMMXT_OP_CMP(maxs, int8_t, int16_t, int32_t, >)
  351 +IWMMXT_OP_CMP(maxu, uint8_t, uint16_t, uint32_t, >)
  352 +#undef CMP
  353 +#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((M0 >> SHR) & MASK) \
  354 + OPER (TYPE) ((M1 >> SHR) & MASK)) & MASK) << SHR)
  355 +IWMMXT_OP_CMP(subn, uint8_t, uint16_t, uint32_t, -)
  356 +IWMMXT_OP_CMP(addn, uint8_t, uint16_t, uint32_t, +)
  357 +#undef CMP
  358 +/* TODO Signed- and Unsigned-Saturation */
  359 +#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((M0 >> SHR) & MASK) \
  360 + OPER (TYPE) ((M1 >> SHR) & MASK)) & MASK) << SHR)
  361 +IWMMXT_OP_CMP(subu, uint8_t, uint16_t, uint32_t, -)
  362 +IWMMXT_OP_CMP(addu, uint8_t, uint16_t, uint32_t, +)
  363 +IWMMXT_OP_CMP(subs, int8_t, int16_t, int32_t, -)
  364 +IWMMXT_OP_CMP(adds, int8_t, int16_t, int32_t, +)
  365 +#undef CMP
  366 +#undef IWMMXT_OP_CMP
  367 +
  368 +void OPPROTO op_iwmmxt_avgb_M0_wRn(void)
  369 +{
  370 +#define AVGB(SHR) ((( \
  371 + ((M0 >> SHR) & 0xff) + ((M1 >> SHR) & 0xff) + PARAM2) >> 1) << SHR)
  372 + M0 =
  373 + AVGB(0) | AVGB(8) | AVGB(16) | AVGB(24) |
  374 + AVGB(32) | AVGB(40) | AVGB(48) | AVGB(56);
  375 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  376 + SIMD8_SET(ZBIT8((M0 >> 0) & 0xff), SIMD_ZBIT, 0) |
  377 + SIMD8_SET(ZBIT8((M0 >> 8) & 0xff), SIMD_ZBIT, 1) |
  378 + SIMD8_SET(ZBIT8((M0 >> 16) & 0xff), SIMD_ZBIT, 2) |
  379 + SIMD8_SET(ZBIT8((M0 >> 24) & 0xff), SIMD_ZBIT, 3) |
  380 + SIMD8_SET(ZBIT8((M0 >> 32) & 0xff), SIMD_ZBIT, 4) |
  381 + SIMD8_SET(ZBIT8((M0 >> 40) & 0xff), SIMD_ZBIT, 5) |
  382 + SIMD8_SET(ZBIT8((M0 >> 48) & 0xff), SIMD_ZBIT, 6) |
  383 + SIMD8_SET(ZBIT8((M0 >> 56) & 0xff), SIMD_ZBIT, 7);
  384 +#undef AVGB
  385 +}
  386 +
  387 +void OPPROTO op_iwmmxt_avgw_M0_wRn(void)
  388 +{
  389 +#define AVGW(SHR) ((( \
  390 + ((M0 >> SHR) & 0xffff) + ((M1 >> SHR) & 0xffff) + PARAM2) >> 1) << SHR)
  391 + M0 = AVGW(0) | AVGW(16) | AVGW(32) | AVGW(48);
  392 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  393 + SIMD16_SET(ZBIT16((M0 >> 0) & 0xffff), SIMD_ZBIT, 0) |
  394 + SIMD16_SET(ZBIT16((M0 >> 16) & 0xffff), SIMD_ZBIT, 1) |
  395 + SIMD16_SET(ZBIT16((M0 >> 32) & 0xffff), SIMD_ZBIT, 2) |
  396 + SIMD16_SET(ZBIT16((M0 >> 48) & 0xffff), SIMD_ZBIT, 3);
  397 +#undef AVGW
  398 +}
  399 +
  400 +void OPPROTO op_iwmmxt_msadb_M0_wRn(void)
  401 +{
  402 + M0 = ((((M0 >> 0) & 0xffff) * ((M1 >> 0) & 0xffff) +
  403 + ((M0 >> 16) & 0xffff) * ((M1 >> 16) & 0xffff)) & 0xffffffff) |
  404 + ((((M0 >> 32) & 0xffff) * ((M1 >> 32) & 0xffff) +
  405 + ((M0 >> 48) & 0xffff) * ((M1 >> 48) & 0xffff)) << 32);
  406 +}
  407 +
  408 +void OPPROTO op_iwmmxt_align_M0_T0_wRn(void)
  409 +{
  410 + M0 >>= T0 << 3;
  411 + M0 |= M1 << (64 - (T0 << 3));
  412 +}
  413 +
  414 +void OPPROTO op_iwmmxt_insr_M0_T0_T1(void)
  415 +{
  416 + M0 &= ~((uint64_t) T1 << PARAM1);
  417 + M0 |= (uint64_t) (T0 & T1) << PARAM1;
  418 +}
  419 +
  420 +void OPPROTO op_iwmmxt_extrsb_T0_M0(void)
  421 +{
  422 + T0 = EXTEND8((M0 >> PARAM1) & 0xff);
  423 +}
  424 +
  425 +void OPPROTO op_iwmmxt_extrsw_T0_M0(void)
  426 +{
  427 + T0 = EXTEND16((M0 >> PARAM1) & 0xffff);
  428 +}
  429 +
  430 +void OPPROTO op_iwmmxt_extru_T0_M0_T1(void)
  431 +{
  432 + T0 = (M0 >> PARAM1) & T1;
  433 +}
  434 +
  435 +void OPPROTO op_iwmmxt_bcstb_M0_T0(void)
  436 +{
  437 + T0 &= 0xff;
  438 + M0 =
  439 + ((uint64_t) T0 << 0) | ((uint64_t) T0 << 8) |
  440 + ((uint64_t) T0 << 16) | ((uint64_t) T0 << 24) |
  441 + ((uint64_t) T0 << 32) | ((uint64_t) T0 << 40) |
  442 + ((uint64_t) T0 << 48) | ((uint64_t) T0 << 56);
  443 +}
  444 +
  445 +void OPPROTO op_iwmmxt_bcstw_M0_T0(void)
  446 +{
  447 + T0 &= 0xffff;
  448 + M0 =
  449 + ((uint64_t) T0 << 0) | ((uint64_t) T0 << 16) |
  450 + ((uint64_t) T0 << 32) | ((uint64_t) T0 << 48);
  451 +}
  452 +
  453 +void OPPROTO op_iwmmxt_bcstl_M0_T0(void)
  454 +{
  455 + M0 = ((uint64_t) T0 << 0) | ((uint64_t) T0 << 32);
  456 +}
  457 +
  458 +void OPPROTO op_iwmmxt_addcb_M0(void)
  459 +{
  460 + M0 =
  461 + ((M0 >> 0) & 0xff) + ((M0 >> 8) & 0xff) +
  462 + ((M0 >> 16) & 0xff) + ((M0 >> 24) & 0xff) +
  463 + ((M0 >> 32) & 0xff) + ((M0 >> 40) & 0xff) +
  464 + ((M0 >> 48) & 0xff) + ((M0 >> 56) & 0xff);
  465 +}
  466 +
  467 +void OPPROTO op_iwmmxt_addcw_M0(void)
  468 +{
  469 + M0 =
  470 + ((M0 >> 0) & 0xffff) + ((M0 >> 16) & 0xffff) +
  471 + ((M0 >> 32) & 0xffff) + ((M0 >> 48) & 0xffff);
  472 +}
  473 +
  474 +void OPPROTO op_iwmmxt_addcl_M0(void)
  475 +{
  476 + M0 = (M0 & 0xffffffff) + (M0 >> 32);
  477 +}
  478 +
  479 +void OPPROTO op_iwmmxt_msbb_T0_M0(void)
  480 +{
  481 + T0 =
  482 + ((M0 >> 7) & 0x01) | ((M0 >> 14) & 0x02) |
  483 + ((M0 >> 21) & 0x04) | ((M0 >> 28) & 0x08) |
  484 + ((M0 >> 35) & 0x10) | ((M0 >> 42) & 0x20) |
  485 + ((M0 >> 49) & 0x40) | ((M0 >> 56) & 0x80);
  486 +}
  487 +
  488 +void OPPROTO op_iwmmxt_msbw_T0_M0(void)
  489 +{
  490 + T0 =
  491 + ((M0 >> 15) & 0x01) | ((M0 >> 30) & 0x02) |
  492 + ((M0 >> 45) & 0x04) | ((M0 >> 52) & 0x08);
  493 +}
  494 +
  495 +void OPPROTO op_iwmmxt_msbl_T0_M0(void)
  496 +{
  497 + T0 = ((M0 >> 31) & 0x01) | ((M0 >> 62) & 0x02);
  498 +}
  499 +
  500 +void OPPROTO op_iwmmxt_srlw_M0_T0(void)
  501 +{
  502 + M0 =
  503 + (((M0 & (0xffffll << 0)) >> T0) & (0xffffll << 0)) |
  504 + (((M0 & (0xffffll << 16)) >> T0) & (0xffffll << 16)) |
  505 + (((M0 & (0xffffll << 32)) >> T0) & (0xffffll << 32)) |
  506 + (((M0 & (0xffffll << 48)) >> T0) & (0xffffll << 48));
  507 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  508 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  509 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  510 +}
  511 +
  512 +void OPPROTO op_iwmmxt_srll_M0_T0(void)
  513 +{
  514 + M0 =
  515 + ((M0 & (0xffffffffll << 0)) >> T0) |
  516 + ((M0 >> T0) & (0xffffffffll << 32));
  517 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  518 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  519 +}
  520 +
  521 +void OPPROTO op_iwmmxt_srlq_M0_T0(void)
  522 +{
  523 + M0 >>= T0;
  524 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0);
  525 +}
  526 +
  527 +void OPPROTO op_iwmmxt_sllw_M0_T0(void)
  528 +{
  529 + M0 =
  530 + (((M0 & (0xffffll << 0)) << T0) & (0xffffll << 0)) |
  531 + (((M0 & (0xffffll << 16)) << T0) & (0xffffll << 16)) |
  532 + (((M0 & (0xffffll << 32)) << T0) & (0xffffll << 32)) |
  533 + (((M0 & (0xffffll << 48)) << T0) & (0xffffll << 48));
  534 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  535 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  536 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  537 +}
  538 +
  539 +void OPPROTO op_iwmmxt_slll_M0_T0(void)
  540 +{
  541 + M0 =
  542 + ((M0 << T0) & (0xffffffffll << 0)) |
  543 + ((M0 & (0xffffffffll << 32)) << T0);
  544 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  545 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  546 +}
  547 +
  548 +void OPPROTO op_iwmmxt_sllq_M0_T0(void)
  549 +{
  550 + M0 <<= T0;
  551 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0);
  552 +}
  553 +
  554 +void OPPROTO op_iwmmxt_sraw_M0_T0(void)
  555 +{
  556 + M0 =
  557 + ((uint64_t) ((EXTEND16(M0 >> 0) >> T0) & 0xffff) << 0) |
  558 + ((uint64_t) ((EXTEND16(M0 >> 16) >> T0) & 0xffff) << 16) |
  559 + ((uint64_t) ((EXTEND16(M0 >> 32) >> T0) & 0xffff) << 32) |
  560 + ((uint64_t) ((EXTEND16(M0 >> 48) >> T0) & 0xffff) << 48);
  561 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  562 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  563 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  564 +}
  565 +
  566 +void OPPROTO op_iwmmxt_sral_M0_T0(void)
  567 +{
  568 + M0 =
  569 + (((EXTEND32(M0 >> 0) >> T0) & 0xffffffff) << 0) |
  570 + (((EXTEND32(M0 >> 32) >> T0) & 0xffffffff) << 32);
  571 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  572 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  573 +}
  574 +
  575 +void OPPROTO op_iwmmxt_sraq_M0_T0(void)
  576 +{
  577 + M0 = (int64_t) M0 >> T0;
  578 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0);
  579 +}
  580 +
  581 +void OPPROTO op_iwmmxt_rorw_M0_T0(void)
  582 +{
  583 + M0 =
  584 + ((((M0 & (0xffffll << 0)) >> T0) |
  585 + ((M0 & (0xffffll << 0)) << (16 - T0))) & (0xffffll << 0)) |
  586 + ((((M0 & (0xffffll << 16)) >> T0) |
  587 + ((M0 & (0xffffll << 16)) << (16 - T0))) & (0xffffll << 16)) |
  588 + ((((M0 & (0xffffll << 32)) >> T0) |
  589 + ((M0 & (0xffffll << 32)) << (16 - T0))) & (0xffffll << 32)) |
  590 + ((((M0 & (0xffffll << 48)) >> T0) |
  591 + ((M0 & (0xffffll << 48)) << (16 - T0))) & (0xffffll << 48));
  592 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  593 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  594 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  595 +}
  596 +
  597 +void OPPROTO op_iwmmxt_rorl_M0_T0(void)
  598 +{
  599 + M0 =
  600 + ((M0 & (0xffffffffll << 0)) >> T0) |
  601 + ((M0 >> T0) & (0xffffffffll << 32)) |
  602 + ((M0 << (32 - T0)) & (0xffffffffll << 0)) |
  603 + ((M0 & (0xffffffffll << 32)) << (32 - T0));
  604 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  605 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  606 +}
  607 +
  608 +void OPPROTO op_iwmmxt_rorq_M0_T0(void)
  609 +{
  610 + M0 = (M0 >> T0) | (M0 << (64 - T0));
  611 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(M0);
  612 +}
  613 +
  614 +void OPPROTO op_iwmmxt_shufh_M0_T0(void)
  615 +{
  616 + M0 =
  617 + (((M0 >> ((T0 << 4) & 0x30)) & 0xffff) << 0) |
  618 + (((M0 >> ((T0 << 2) & 0x30)) & 0xffff) << 16) |
  619 + (((M0 >> ((T0 << 0) & 0x30)) & 0xffff) << 32) |
  620 + (((M0 >> ((T0 >> 2) & 0x30)) & 0xffff) << 48);
  621 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  622 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  623 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  624 +}
  625 +
  626 +/* TODO: Unsigned-Saturation */
  627 +void OPPROTO op_iwmmxt_packuw_M0_wRn(void)
  628 +{
  629 + M0 =
  630 + (((M0 >> 0) & 0xff) << 0) | (((M0 >> 16) & 0xff) << 8) |
  631 + (((M0 >> 32) & 0xff) << 16) | (((M0 >> 48) & 0xff) << 24) |
  632 + (((M1 >> 0) & 0xff) << 32) | (((M1 >> 16) & 0xff) << 40) |
  633 + (((M1 >> 32) & 0xff) << 48) | (((M1 >> 48) & 0xff) << 56);
  634 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  635 + NZBIT8(M0 >> 0, 0) | NZBIT8(M0 >> 8, 1) |
  636 + NZBIT8(M0 >> 16, 2) | NZBIT8(M0 >> 24, 3) |
  637 + NZBIT8(M0 >> 32, 4) | NZBIT8(M0 >> 40, 5) |
  638 + NZBIT8(M0 >> 48, 6) | NZBIT8(M0 >> 56, 7);
  639 +}
  640 +
  641 +void OPPROTO op_iwmmxt_packul_M0_wRn(void)
  642 +{
  643 + M0 =
  644 + (((M0 >> 0) & 0xffff) << 0) | (((M0 >> 32) & 0xffff) << 16) |
  645 + (((M1 >> 0) & 0xffff) << 32) | (((M1 >> 32) & 0xffff) << 48);
  646 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  647 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  648 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  649 +}
  650 +
  651 +void OPPROTO op_iwmmxt_packuq_M0_wRn(void)
  652 +{
  653 + M0 = (M0 & 0xffffffff) | ((M1 & 0xffffffff) << 32);
  654 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  655 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  656 +}
  657 +
  658 +/* TODO: Signed-Saturation */
  659 +void OPPROTO op_iwmmxt_packsw_M0_wRn(void)
  660 +{
  661 + M0 =
  662 + (((M0 >> 0) & 0xff) << 0) | (((M0 >> 16) & 0xff) << 8) |
  663 + (((M0 >> 32) & 0xff) << 16) | (((M0 >> 48) & 0xff) << 24) |
  664 + (((M1 >> 0) & 0xff) << 32) | (((M1 >> 16) & 0xff) << 40) |
  665 + (((M1 >> 32) & 0xff) << 48) | (((M1 >> 48) & 0xff) << 56);
  666 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  667 + NZBIT8(M0 >> 0, 0) | NZBIT8(M0 >> 8, 1) |
  668 + NZBIT8(M0 >> 16, 2) | NZBIT8(M0 >> 24, 3) |
  669 + NZBIT8(M0 >> 32, 4) | NZBIT8(M0 >> 40, 5) |
  670 + NZBIT8(M0 >> 48, 6) | NZBIT8(M0 >> 56, 7);
  671 +}
  672 +
  673 +void OPPROTO op_iwmmxt_packsl_M0_wRn(void)
  674 +{
  675 + M0 =
  676 + (((M0 >> 0) & 0xffff) << 0) | (((M0 >> 32) & 0xffff) << 16) |
  677 + (((M1 >> 0) & 0xffff) << 32) | (((M1 >> 32) & 0xffff) << 48);
  678 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  679 + NZBIT16(M0 >> 0, 0) | NZBIT16(M0 >> 16, 1) |
  680 + NZBIT16(M0 >> 32, 2) | NZBIT16(M0 >> 48, 3);
  681 +}
  682 +
  683 +void OPPROTO op_iwmmxt_packsq_M0_wRn(void)
  684 +{
  685 + M0 = (M0 & 0xffffffff) | ((M1 & 0xffffffff) << 32);
  686 + env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
  687 + NZBIT32(M0 >> 0, 0) | NZBIT32(M0 >> 32, 1);
  688 +}
  689 +
  690 +void OPPROTO op_iwmmxt_muladdsl_M0_T0_T1(void)
  691 +{
  692 + M0 += (int32_t) EXTEND32(T0) * (int32_t) EXTEND32(T1);
  693 +}
  694 +
  695 +void OPPROTO op_iwmmxt_muladdsw_M0_T0_T1(void)
  696 +{
  697 + M0 += EXTEND32(EXTEND16S((T0 >> 0) & 0xffff) *
  698 + EXTEND16S((T1 >> 0) & 0xffff));
  699 + M0 += EXTEND32(EXTEND16S((T0 >> 16) & 0xffff) *
  700 + EXTEND16S((T1 >> 16) & 0xffff));
  701 +}
  702 +
  703 +void OPPROTO op_iwmmxt_muladdswl_M0_T0_T1(void)
  704 +{
  705 + M0 += EXTEND32(EXTEND16S(T0 & 0xffff) *
  706 + EXTEND16S(T1 & 0xffff));
  707 +}
... ...
target-arm/op_mem.h
... ... @@ -67,4 +67,24 @@ VFP_MEM_OP(d,q)
67 67  
68 68 #undef VFP_MEM_OP
69 69  
  70 +/* iwMMXt load/store. Address is in T1 */
  71 +#define MMX_MEM_OP(name, ldname) \
  72 +void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
  73 +{ \
  74 + M0 = glue(ld##ldname,MEMSUFFIX)(T1); \
  75 + FORCE_RET(); \
  76 +} \
  77 +void OPPROTO glue(op_iwmmxt_st##name,MEMSUFFIX)(void) \
  78 +{ \
  79 + glue(st##name,MEMSUFFIX)(T1, M0); \
  80 + FORCE_RET(); \
  81 +}
  82 +
  83 +MMX_MEM_OP(b, ub)
  84 +MMX_MEM_OP(w, uw)
  85 +MMX_MEM_OP(l, l)
  86 +MMX_MEM_OP(q, q)
  87 +
  88 +#undef MMX_MEM_OP
  89 +
70 90 #undef MEMSUFFIX
... ...
target-arm/translate.c
... ... @@ -3,6 +3,7 @@
3 3 *
4 4 * Copyright (c) 2003 Fabrice Bellard
5 5 * Copyright (c) 2005 CodeSourcery, LLC
  6 + * Copyright (c) 2007 OpenedHand, Ltd.
6 7 *
7 8 * This library is free software; you can redistribute it and/or
8 9 * modify it under the terms of the GNU Lesser General Public
... ... @@ -492,6 +493,1067 @@ static inline void gen_mov_vreg_F0(int dp, int reg)
492 493 gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg));
493 494 }
494 495  
  496 +#define ARM_CP_RW_BIT (1 << 20)
  497 +
  498 +static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
  499 +{
  500 + int rd;
  501 + uint32_t offset;
  502 +
  503 + rd = (insn >> 16) & 0xf;
  504 + gen_movl_T1_reg(s, rd);
  505 +
  506 + offset = (insn & 0xff) << ((insn >> 7) & 2);
  507 + if (insn & (1 << 24)) {
  508 + /* Pre indexed */
  509 + if (insn & (1 << 23))
  510 + gen_op_addl_T1_im(offset);
  511 + else
  512 + gen_op_addl_T1_im(-offset);
  513 +
  514 + if (insn & (1 << 21))
  515 + gen_movl_reg_T1(s, rd);
  516 + } else if (insn & (1 << 21)) {
  517 + /* Post indexed */
  518 + if (insn & (1 << 23))
  519 + gen_op_movl_T0_im(offset);
  520 + else
  521 + gen_op_movl_T0_im(- offset);
  522 + gen_op_addl_T0_T1();
  523 + gen_movl_reg_T0(s, rd);
  524 + } else if (!(insn & (1 << 23)))
  525 + return 1;
  526 + return 0;
  527 +}
  528 +
  529 +static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
  530 +{
  531 + int rd = (insn >> 0) & 0xf;
  532 +
  533 + if (insn & (1 << 8))
  534 + if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
  535 + return 1;
  536 + else
  537 + gen_op_iwmmxt_movl_T0_wCx(rd);
  538 + else
  539 + gen_op_iwmmxt_movl_T0_T1_wRn(rd);
  540 +
  541 + gen_op_movl_T1_im(mask);
  542 + gen_op_andl_T0_T1();
  543 + return 0;
  544 +}
  545 +
  546 +/* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
  547 + (ie. an undefined instruction). */
  548 +static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
  549 +{
  550 + int rd, wrd;
  551 + int rdhi, rdlo, rd0, rd1, i;
  552 +
  553 + if ((insn & 0x0e000e00) == 0x0c000000) {
  554 + if ((insn & 0x0fe00ff0) == 0x0c400000) {
  555 + wrd = insn & 0xf;
  556 + rdlo = (insn >> 12) & 0xf;
  557 + rdhi = (insn >> 16) & 0xf;
  558 + if (insn & ARM_CP_RW_BIT) { /* TMRRC */
  559 + gen_op_iwmmxt_movl_T0_T1_wRn(wrd);
  560 + gen_movl_reg_T0(s, rdlo);
  561 + gen_movl_reg_T1(s, rdhi);
  562 + } else { /* TMCRR */
  563 + gen_movl_T0_reg(s, rdlo);
  564 + gen_movl_T1_reg(s, rdhi);
  565 + gen_op_iwmmxt_movl_wRn_T0_T1(wrd);
  566 + gen_op_iwmmxt_set_mup();
  567 + }
  568 + return 0;
  569 + }
  570 +
  571 + wrd = (insn >> 12) & 0xf;
  572 + if (gen_iwmmxt_address(s, insn))
  573 + return 1;
  574 + if (insn & ARM_CP_RW_BIT) {
  575 + if ((insn >> 28) == 0xf) { /* WLDRW wCx */
  576 + gen_ldst(ldl, s);
  577 + gen_op_iwmmxt_movl_wCx_T0(wrd);
  578 + } else {
  579 + if (insn & (1 << 8))
  580 + if (insn & (1 << 22)) /* WLDRD */
  581 + gen_ldst(iwmmxt_ldq, s);
  582 + else /* WLDRW wRd */
  583 + gen_ldst(iwmmxt_ldl, s);
  584 + else
  585 + if (insn & (1 << 22)) /* WLDRH */
  586 + gen_ldst(iwmmxt_ldw, s);
  587 + else /* WLDRB */
  588 + gen_ldst(iwmmxt_ldb, s);
  589 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  590 + }
  591 + } else {
  592 + if ((insn >> 28) == 0xf) { /* WSTRW wCx */
  593 + gen_op_iwmmxt_movl_T0_wCx(wrd);
  594 + gen_ldst(stl, s);
  595 + } else {
  596 + gen_op_iwmmxt_movq_M0_wRn(wrd);
  597 + if (insn & (1 << 8))
  598 + if (insn & (1 << 22)) /* WSTRD */
  599 + gen_ldst(iwmmxt_stq, s);
  600 + else /* WSTRW wRd */
  601 + gen_ldst(iwmmxt_stl, s);
  602 + else
  603 + if (insn & (1 << 22)) /* WSTRH */
  604 + gen_ldst(iwmmxt_ldw, s);
  605 + else /* WSTRB */
  606 + gen_ldst(iwmmxt_stb, s);
  607 + }
  608 + }
  609 + return 0;
  610 + }
  611 +
  612 + if ((insn & 0x0f000000) != 0x0e000000)
  613 + return 1;
  614 +
  615 + switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
  616 + case 0x000: /* WOR */
  617 + wrd = (insn >> 12) & 0xf;
  618 + rd0 = (insn >> 0) & 0xf;
  619 + rd1 = (insn >> 16) & 0xf;
  620 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  621 + gen_op_iwmmxt_orq_M0_wRn(rd1);
  622 + gen_op_iwmmxt_setpsr_nz();
  623 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  624 + gen_op_iwmmxt_set_mup();
  625 + gen_op_iwmmxt_set_cup();
  626 + break;
  627 + case 0x011: /* TMCR */
  628 + if (insn & 0xf)
  629 + return 1;
  630 + rd = (insn >> 12) & 0xf;
  631 + wrd = (insn >> 16) & 0xf;
  632 + switch (wrd) {
  633 + case ARM_IWMMXT_wCID:
  634 + case ARM_IWMMXT_wCASF:
  635 + break;
  636 + case ARM_IWMMXT_wCon:
  637 + gen_op_iwmmxt_set_cup();
  638 + /* Fall through. */
  639 + case ARM_IWMMXT_wCSSF:
  640 + gen_op_iwmmxt_movl_T0_wCx(wrd);
  641 + gen_movl_T1_reg(s, rd);
  642 + gen_op_bicl_T0_T1();
  643 + gen_op_iwmmxt_movl_wCx_T0(wrd);
  644 + break;
  645 + case ARM_IWMMXT_wCGR0:
  646 + case ARM_IWMMXT_wCGR1:
  647 + case ARM_IWMMXT_wCGR2:
  648 + case ARM_IWMMXT_wCGR3:
  649 + gen_op_iwmmxt_set_cup();
  650 + gen_movl_reg_T0(s, rd);
  651 + gen_op_iwmmxt_movl_wCx_T0(wrd);
  652 + break;
  653 + default:
  654 + return 1;
  655 + }
  656 + break;
  657 + case 0x100: /* WXOR */
  658 + wrd = (insn >> 12) & 0xf;
  659 + rd0 = (insn >> 0) & 0xf;
  660 + rd1 = (insn >> 16) & 0xf;
  661 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  662 + gen_op_iwmmxt_xorq_M0_wRn(rd1);
  663 + gen_op_iwmmxt_setpsr_nz();
  664 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  665 + gen_op_iwmmxt_set_mup();
  666 + gen_op_iwmmxt_set_cup();
  667 + break;
  668 + case 0x111: /* TMRC */
  669 + if (insn & 0xf)
  670 + return 1;
  671 + rd = (insn >> 12) & 0xf;
  672 + wrd = (insn >> 16) & 0xf;
  673 + gen_op_iwmmxt_movl_T0_wCx(wrd);
  674 + gen_movl_reg_T0(s, rd);
  675 + break;
  676 + case 0x300: /* WANDN */
  677 + wrd = (insn >> 12) & 0xf;
  678 + rd0 = (insn >> 0) & 0xf;
  679 + rd1 = (insn >> 16) & 0xf;
  680 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  681 + gen_op_iwmmxt_negq_M0();
  682 + gen_op_iwmmxt_andq_M0_wRn(rd1);
  683 + gen_op_iwmmxt_setpsr_nz();
  684 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  685 + gen_op_iwmmxt_set_mup();
  686 + gen_op_iwmmxt_set_cup();
  687 + break;
  688 + case 0x200: /* WAND */
  689 + wrd = (insn >> 12) & 0xf;
  690 + rd0 = (insn >> 0) & 0xf;
  691 + rd1 = (insn >> 16) & 0xf;
  692 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  693 + gen_op_iwmmxt_andq_M0_wRn(rd1);
  694 + gen_op_iwmmxt_setpsr_nz();
  695 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  696 + gen_op_iwmmxt_set_mup();
  697 + gen_op_iwmmxt_set_cup();
  698 + break;
  699 + case 0x810: case 0xa10: /* WMADD */
  700 + wrd = (insn >> 12) & 0xf;
  701 + rd0 = (insn >> 0) & 0xf;
  702 + rd1 = (insn >> 16) & 0xf;
  703 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  704 + if (insn & (1 << 21))
  705 + gen_op_iwmmxt_maddsq_M0_wRn(rd1);
  706 + else
  707 + gen_op_iwmmxt_madduq_M0_wRn(rd1);
  708 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  709 + gen_op_iwmmxt_set_mup();
  710 + break;
  711 + case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
  712 + wrd = (insn >> 12) & 0xf;
  713 + rd0 = (insn >> 16) & 0xf;
  714 + rd1 = (insn >> 0) & 0xf;
  715 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  716 + switch ((insn >> 22) & 3) {
  717 + case 0:
  718 + gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
  719 + break;
  720 + case 1:
  721 + gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
  722 + break;
  723 + case 2:
  724 + gen_op_iwmmxt_unpackll_M0_wRn(rd1);
  725 + break;
  726 + case 3:
  727 + return 1;
  728 + }
  729 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  730 + gen_op_iwmmxt_set_mup();
  731 + gen_op_iwmmxt_set_cup();
  732 + break;
  733 + case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
  734 + wrd = (insn >> 12) & 0xf;
  735 + rd0 = (insn >> 16) & 0xf;
  736 + rd1 = (insn >> 0) & 0xf;
  737 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  738 + switch ((insn >> 22) & 3) {
  739 + case 0:
  740 + gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
  741 + break;
  742 + case 1:
  743 + gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
  744 + break;
  745 + case 2:
  746 + gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
  747 + break;
  748 + case 3:
  749 + return 1;
  750 + }
  751 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  752 + gen_op_iwmmxt_set_mup();
  753 + gen_op_iwmmxt_set_cup();
  754 + break;
  755 + case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
  756 + wrd = (insn >> 12) & 0xf;
  757 + rd0 = (insn >> 16) & 0xf;
  758 + rd1 = (insn >> 0) & 0xf;
  759 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  760 + if (insn & (1 << 22))
  761 + gen_op_iwmmxt_sadw_M0_wRn(rd1);
  762 + else
  763 + gen_op_iwmmxt_sadb_M0_wRn(rd1);
  764 + if (!(insn & (1 << 20)))
  765 + gen_op_iwmmxt_addl_M0_wRn(wrd);
  766 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  767 + gen_op_iwmmxt_set_mup();
  768 + break;
  769 + case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
  770 + wrd = (insn >> 12) & 0xf;
  771 + rd0 = (insn >> 16) & 0xf;
  772 + rd1 = (insn >> 0) & 0xf;
  773 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  774 + if (insn & (1 << 21))
  775 + gen_op_iwmmxt_mulsw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
  776 + else
  777 + gen_op_iwmmxt_muluw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
  778 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  779 + gen_op_iwmmxt_set_mup();
  780 + break;
  781 + case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
  782 + wrd = (insn >> 12) & 0xf;
  783 + rd0 = (insn >> 16) & 0xf;
  784 + rd1 = (insn >> 0) & 0xf;
  785 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  786 + if (insn & (1 << 21))
  787 + gen_op_iwmmxt_macsw_M0_wRn(rd1);
  788 + else
  789 + gen_op_iwmmxt_macuw_M0_wRn(rd1);
  790 + if (!(insn & (1 << 20))) {
  791 + if (insn & (1 << 21))
  792 + gen_op_iwmmxt_addsq_M0_wRn(wrd);
  793 + else
  794 + gen_op_iwmmxt_adduq_M0_wRn(wrd);
  795 + }
  796 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  797 + gen_op_iwmmxt_set_mup();
  798 + break;
  799 + case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
  800 + wrd = (insn >> 12) & 0xf;
  801 + rd0 = (insn >> 16) & 0xf;
  802 + rd1 = (insn >> 0) & 0xf;
  803 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  804 + switch ((insn >> 22) & 3) {
  805 + case 0:
  806 + gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
  807 + break;
  808 + case 1:
  809 + gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
  810 + break;
  811 + case 2:
  812 + gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
  813 + break;
  814 + case 3:
  815 + return 1;
  816 + }
  817 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  818 + gen_op_iwmmxt_set_mup();
  819 + gen_op_iwmmxt_set_cup();
  820 + break;
  821 + case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
  822 + wrd = (insn >> 12) & 0xf;
  823 + rd0 = (insn >> 16) & 0xf;
  824 + rd1 = (insn >> 0) & 0xf;
  825 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  826 + if (insn & (1 << 22))
  827 + gen_op_iwmmxt_avgw_M0_wRn(rd1, (insn >> 20) & 1);
  828 + else
  829 + gen_op_iwmmxt_avgb_M0_wRn(rd1, (insn >> 20) & 1);
  830 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  831 + gen_op_iwmmxt_set_mup();
  832 + gen_op_iwmmxt_set_cup();
  833 + break;
  834 + case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
  835 + wrd = (insn >> 12) & 0xf;
  836 + rd0 = (insn >> 16) & 0xf;
  837 + rd1 = (insn >> 0) & 0xf;
  838 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  839 + gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
  840 + gen_op_movl_T1_im(7);
  841 + gen_op_andl_T0_T1();
  842 + gen_op_iwmmxt_align_M0_T0_wRn(rd1);
  843 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  844 + gen_op_iwmmxt_set_mup();
  845 + break;
  846 + case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
  847 + rd = (insn >> 12) & 0xf;
  848 + wrd = (insn >> 16) & 0xf;
  849 + gen_movl_T0_reg(s, rd);
  850 + gen_op_iwmmxt_movq_M0_wRn(wrd);
  851 + switch ((insn >> 6) & 3) {
  852 + case 0:
  853 + gen_op_movl_T1_im(0xff);
  854 + gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
  855 + break;
  856 + case 1:
  857 + gen_op_movl_T1_im(0xffff);
  858 + gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
  859 + break;
  860 + case 2:
  861 + gen_op_movl_T1_im(0xffffffff);
  862 + gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
  863 + break;
  864 + case 3:
  865 + return 1;
  866 + }
  867 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  868 + gen_op_iwmmxt_set_mup();
  869 + break;
  870 + case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
  871 + rd = (insn >> 12) & 0xf;
  872 + wrd = (insn >> 16) & 0xf;
  873 + if (rd == 15)
  874 + return 1;
  875 + gen_op_iwmmxt_movq_M0_wRn(wrd);
  876 + switch ((insn >> 22) & 3) {
  877 + case 0:
  878 + if (insn & 8)
  879 + gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
  880 + else {
  881 + gen_op_movl_T1_im(0xff);
  882 + gen_op_iwmmxt_extru_T0_M0_T1((insn & 7) << 3);
  883 + }
  884 + break;
  885 + case 1:
  886 + if (insn & 8)
  887 + gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
  888 + else {
  889 + gen_op_movl_T1_im(0xffff);
  890 + gen_op_iwmmxt_extru_T0_M0_T1((insn & 3) << 4);
  891 + }
  892 + break;
  893 + case 2:
  894 + gen_op_movl_T1_im(0xffffffff);
  895 + gen_op_iwmmxt_extru_T0_M0_T1((insn & 1) << 5);
  896 + break;
  897 + case 3:
  898 + return 1;
  899 + }
  900 + gen_op_movl_reg_TN[0][rd]();
  901 + break;
  902 + case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
  903 + if ((insn & 0x000ff008) != 0x0003f000)
  904 + return 1;
  905 + gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
  906 + switch ((insn >> 22) & 3) {
  907 + case 0:
  908 + gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
  909 + break;
  910 + case 1:
  911 + gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
  912 + break;
  913 + case 2:
  914 + gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
  915 + break;
  916 + case 3:
  917 + return 1;
  918 + }
  919 + gen_op_shll_T1_im(28);
  920 + gen_op_movl_T0_T1();
  921 + gen_op_movl_cpsr_T0(0xf0000000);
  922 + break;
  923 + case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
  924 + rd = (insn >> 12) & 0xf;
  925 + wrd = (insn >> 16) & 0xf;
  926 + gen_movl_T0_reg(s, rd);
  927 + switch ((insn >> 6) & 3) {
  928 + case 0:
  929 + gen_op_iwmmxt_bcstb_M0_T0();
  930 + break;
  931 + case 1:
  932 + gen_op_iwmmxt_bcstw_M0_T0();
  933 + break;
  934 + case 2:
  935 + gen_op_iwmmxt_bcstl_M0_T0();
  936 + break;
  937 + case 3:
  938 + return 1;
  939 + }
  940 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  941 + gen_op_iwmmxt_set_mup();
  942 + break;
  943 + case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
  944 + if ((insn & 0x000ff00f) != 0x0003f000)
  945 + return 1;
  946 + gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
  947 + switch ((insn >> 22) & 3) {
  948 + case 0:
  949 + for (i = 0; i < 7; i ++) {
  950 + gen_op_shll_T1_im(4);
  951 + gen_op_andl_T0_T1();
  952 + }
  953 + break;
  954 + case 1:
  955 + for (i = 0; i < 3; i ++) {
  956 + gen_op_shll_T1_im(8);
  957 + gen_op_andl_T0_T1();
  958 + }
  959 + break;
  960 + case 2:
  961 + gen_op_shll_T1_im(16);
  962 + gen_op_andl_T0_T1();
  963 + break;
  964 + case 3:
  965 + return 1;
  966 + }
  967 + gen_op_movl_cpsr_T0(0xf0000000);
  968 + break;
  969 + case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
  970 + wrd = (insn >> 12) & 0xf;
  971 + rd0 = (insn >> 16) & 0xf;
  972 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  973 + switch ((insn >> 22) & 3) {
  974 + case 0:
  975 + gen_op_iwmmxt_addcb_M0();
  976 + break;
  977 + case 1:
  978 + gen_op_iwmmxt_addcw_M0();
  979 + break;
  980 + case 2:
  981 + gen_op_iwmmxt_addcl_M0();
  982 + break;
  983 + case 3:
  984 + return 1;
  985 + }
  986 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  987 + gen_op_iwmmxt_set_mup();
  988 + break;
  989 + case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
  990 + if ((insn & 0x000ff00f) != 0x0003f000)
  991 + return 1;
  992 + gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
  993 + switch ((insn >> 22) & 3) {
  994 + case 0:
  995 + for (i = 0; i < 7; i ++) {
  996 + gen_op_shll_T1_im(4);
  997 + gen_op_orl_T0_T1();
  998 + }
  999 + break;
  1000 + case 1:
  1001 + for (i = 0; i < 3; i ++) {
  1002 + gen_op_shll_T1_im(8);
  1003 + gen_op_orl_T0_T1();
  1004 + }
  1005 + break;
  1006 + case 2:
  1007 + gen_op_shll_T1_im(16);
  1008 + gen_op_orl_T0_T1();
  1009 + break;
  1010 + case 3:
  1011 + return 1;
  1012 + }
  1013 + gen_op_movl_T1_im(0xf0000000);
  1014 + gen_op_andl_T0_T1();
  1015 + gen_op_movl_cpsr_T0(0xf0000000);
  1016 + break;
  1017 + case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
  1018 + rd = (insn >> 12) & 0xf;
  1019 + rd0 = (insn >> 16) & 0xf;
  1020 + if ((insn & 0xf) != 0)
  1021 + return 1;
  1022 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1023 + switch ((insn >> 22) & 3) {
  1024 + case 0:
  1025 + gen_op_iwmmxt_msbb_T0_M0();
  1026 + break;
  1027 + case 1:
  1028 + gen_op_iwmmxt_msbw_T0_M0();
  1029 + break;
  1030 + case 2:
  1031 + gen_op_iwmmxt_msbl_T0_M0();
  1032 + break;
  1033 + case 3:
  1034 + return 1;
  1035 + }
  1036 + gen_movl_reg_T0(s, rd);
  1037 + break;
  1038 + case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
  1039 + case 0x906: case 0xb06: case 0xd06: case 0xf06:
  1040 + wrd = (insn >> 12) & 0xf;
  1041 + rd0 = (insn >> 16) & 0xf;
  1042 + rd1 = (insn >> 0) & 0xf;
  1043 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1044 + switch ((insn >> 22) & 3) {
  1045 + case 0:
  1046 + if (insn & (1 << 21))
  1047 + gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
  1048 + else
  1049 + gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
  1050 + break;
  1051 + case 1:
  1052 + if (insn & (1 << 21))
  1053 + gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
  1054 + else
  1055 + gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
  1056 + break;
  1057 + case 2:
  1058 + if (insn & (1 << 21))
  1059 + gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
  1060 + else
  1061 + gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
  1062 + break;
  1063 + case 3:
  1064 + return 1;
  1065 + }
  1066 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1067 + gen_op_iwmmxt_set_mup();
  1068 + gen_op_iwmmxt_set_cup();
  1069 + break;
  1070 + case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
  1071 + case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
  1072 + wrd = (insn >> 12) & 0xf;
  1073 + rd0 = (insn >> 16) & 0xf;
  1074 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1075 + switch ((insn >> 22) & 3) {
  1076 + case 0:
  1077 + if (insn & (1 << 21))
  1078 + gen_op_iwmmxt_unpacklsb_M0();
  1079 + else
  1080 + gen_op_iwmmxt_unpacklub_M0();
  1081 + break;
  1082 + case 1:
  1083 + if (insn & (1 << 21))
  1084 + gen_op_iwmmxt_unpacklsw_M0();
  1085 + else
  1086 + gen_op_iwmmxt_unpackluw_M0();
  1087 + break;
  1088 + case 2:
  1089 + if (insn & (1 << 21))
  1090 + gen_op_iwmmxt_unpacklsl_M0();
  1091 + else
  1092 + gen_op_iwmmxt_unpacklul_M0();
  1093 + break;
  1094 + case 3:
  1095 + return 1;
  1096 + }
  1097 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1098 + gen_op_iwmmxt_set_mup();
  1099 + gen_op_iwmmxt_set_cup();
  1100 + break;
  1101 + case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
  1102 + case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
  1103 + wrd = (insn >> 12) & 0xf;
  1104 + rd0 = (insn >> 16) & 0xf;
  1105 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1106 + switch ((insn >> 22) & 3) {
  1107 + case 0:
  1108 + if (insn & (1 << 21))
  1109 + gen_op_iwmmxt_unpackhsb_M0();
  1110 + else
  1111 + gen_op_iwmmxt_unpackhub_M0();
  1112 + break;
  1113 + case 1:
  1114 + if (insn & (1 << 21))
  1115 + gen_op_iwmmxt_unpackhsw_M0();
  1116 + else
  1117 + gen_op_iwmmxt_unpackhuw_M0();
  1118 + break;
  1119 + case 2:
  1120 + if (insn & (1 << 21))
  1121 + gen_op_iwmmxt_unpackhsl_M0();
  1122 + else
  1123 + gen_op_iwmmxt_unpackhul_M0();
  1124 + break;
  1125 + case 3:
  1126 + return 1;
  1127 + }
  1128 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1129 + gen_op_iwmmxt_set_mup();
  1130 + gen_op_iwmmxt_set_cup();
  1131 + break;
  1132 + case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
  1133 + case 0x214: case 0x614: case 0xa14: case 0xe14:
  1134 + wrd = (insn >> 12) & 0xf;
  1135 + rd0 = (insn >> 16) & 0xf;
  1136 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1137 + if (gen_iwmmxt_shift(insn, 0xff))
  1138 + return 1;
  1139 + switch ((insn >> 22) & 3) {
  1140 + case 0:
  1141 + return 1;
  1142 + case 1:
  1143 + gen_op_iwmmxt_srlw_M0_T0();
  1144 + break;
  1145 + case 2:
  1146 + gen_op_iwmmxt_srll_M0_T0();
  1147 + break;
  1148 + case 3:
  1149 + gen_op_iwmmxt_srlq_M0_T0();
  1150 + break;
  1151 + }
  1152 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1153 + gen_op_iwmmxt_set_mup();
  1154 + gen_op_iwmmxt_set_cup();
  1155 + break;
  1156 + case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
  1157 + case 0x014: case 0x414: case 0x814: case 0xc14:
  1158 + wrd = (insn >> 12) & 0xf;
  1159 + rd0 = (insn >> 16) & 0xf;
  1160 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1161 + if (gen_iwmmxt_shift(insn, 0xff))
  1162 + return 1;
  1163 + switch ((insn >> 22) & 3) {
  1164 + case 0:
  1165 + return 1;
  1166 + case 1:
  1167 + gen_op_iwmmxt_sraw_M0_T0();
  1168 + break;
  1169 + case 2:
  1170 + gen_op_iwmmxt_sral_M0_T0();
  1171 + break;
  1172 + case 3:
  1173 + gen_op_iwmmxt_sraq_M0_T0();
  1174 + break;
  1175 + }
  1176 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1177 + gen_op_iwmmxt_set_mup();
  1178 + gen_op_iwmmxt_set_cup();
  1179 + break;
  1180 + case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
  1181 + case 0x114: case 0x514: case 0x914: case 0xd14:
  1182 + wrd = (insn >> 12) & 0xf;
  1183 + rd0 = (insn >> 16) & 0xf;
  1184 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1185 + if (gen_iwmmxt_shift(insn, 0xff))
  1186 + return 1;
  1187 + switch ((insn >> 22) & 3) {
  1188 + case 0:
  1189 + return 1;
  1190 + case 1:
  1191 + gen_op_iwmmxt_sllw_M0_T0();
  1192 + break;
  1193 + case 2:
  1194 + gen_op_iwmmxt_slll_M0_T0();
  1195 + break;
  1196 + case 3:
  1197 + gen_op_iwmmxt_sllq_M0_T0();
  1198 + break;
  1199 + }
  1200 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1201 + gen_op_iwmmxt_set_mup();
  1202 + gen_op_iwmmxt_set_cup();
  1203 + break;
  1204 + case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
  1205 + case 0x314: case 0x714: case 0xb14: case 0xf14:
  1206 + wrd = (insn >> 12) & 0xf;
  1207 + rd0 = (insn >> 16) & 0xf;
  1208 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1209 + switch ((insn >> 22) & 3) {
  1210 + case 0:
  1211 + return 1;
  1212 + case 1:
  1213 + if (gen_iwmmxt_shift(insn, 0xf))
  1214 + return 1;
  1215 + gen_op_iwmmxt_rorw_M0_T0();
  1216 + break;
  1217 + case 2:
  1218 + if (gen_iwmmxt_shift(insn, 0x1f))
  1219 + return 1;
  1220 + gen_op_iwmmxt_rorl_M0_T0();
  1221 + break;
  1222 + case 3:
  1223 + if (gen_iwmmxt_shift(insn, 0x3f))
  1224 + return 1;
  1225 + gen_op_iwmmxt_rorq_M0_T0();
  1226 + break;
  1227 + }
  1228 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1229 + gen_op_iwmmxt_set_mup();
  1230 + gen_op_iwmmxt_set_cup();
  1231 + break;
  1232 + case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
  1233 + case 0x916: case 0xb16: case 0xd16: case 0xf16:
  1234 + wrd = (insn >> 12) & 0xf;
  1235 + rd0 = (insn >> 16) & 0xf;
  1236 + rd1 = (insn >> 0) & 0xf;
  1237 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1238 + switch ((insn >> 22) & 3) {
  1239 + case 0:
  1240 + if (insn & (1 << 21))
  1241 + gen_op_iwmmxt_minsb_M0_wRn(rd1);
  1242 + else
  1243 + gen_op_iwmmxt_minub_M0_wRn(rd1);
  1244 + break;
  1245 + case 1:
  1246 + if (insn & (1 << 21))
  1247 + gen_op_iwmmxt_minsw_M0_wRn(rd1);
  1248 + else
  1249 + gen_op_iwmmxt_minuw_M0_wRn(rd1);
  1250 + break;
  1251 + case 2:
  1252 + if (insn & (1 << 21))
  1253 + gen_op_iwmmxt_minsl_M0_wRn(rd1);
  1254 + else
  1255 + gen_op_iwmmxt_minul_M0_wRn(rd1);
  1256 + break;
  1257 + case 3:
  1258 + return 1;
  1259 + }
  1260 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1261 + gen_op_iwmmxt_set_mup();
  1262 + break;
  1263 + case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
  1264 + case 0x816: case 0xa16: case 0xc16: case 0xe16:
  1265 + wrd = (insn >> 12) & 0xf;
  1266 + rd0 = (insn >> 16) & 0xf;
  1267 + rd1 = (insn >> 0) & 0xf;
  1268 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1269 + switch ((insn >> 22) & 3) {
  1270 + case 0:
  1271 + if (insn & (1 << 21))
  1272 + gen_op_iwmmxt_maxsb_M0_wRn(rd1);
  1273 + else
  1274 + gen_op_iwmmxt_maxub_M0_wRn(rd1);
  1275 + break;
  1276 + case 1:
  1277 + if (insn & (1 << 21))
  1278 + gen_op_iwmmxt_maxsw_M0_wRn(rd1);
  1279 + else
  1280 + gen_op_iwmmxt_maxuw_M0_wRn(rd1);
  1281 + break;
  1282 + case 2:
  1283 + if (insn & (1 << 21))
  1284 + gen_op_iwmmxt_maxsl_M0_wRn(rd1);
  1285 + else
  1286 + gen_op_iwmmxt_maxul_M0_wRn(rd1);
  1287 + break;
  1288 + case 3:
  1289 + return 1;
  1290 + }
  1291 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1292 + gen_op_iwmmxt_set_mup();
  1293 + break;
  1294 + case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
  1295 + case 0x402: case 0x502: case 0x602: case 0x702:
  1296 + wrd = (insn >> 12) & 0xf;
  1297 + rd0 = (insn >> 16) & 0xf;
  1298 + rd1 = (insn >> 0) & 0xf;
  1299 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1300 + gen_op_movl_T0_im((insn >> 20) & 3);
  1301 + gen_op_iwmmxt_align_M0_T0_wRn(rd1);
  1302 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1303 + gen_op_iwmmxt_set_mup();
  1304 + break;
  1305 + case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
  1306 + case 0x41a: case 0x51a: case 0x61a: case 0x71a:
  1307 + case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
  1308 + case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
  1309 + wrd = (insn >> 12) & 0xf;
  1310 + rd0 = (insn >> 16) & 0xf;
  1311 + rd1 = (insn >> 0) & 0xf;
  1312 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1313 + switch ((insn >> 20) & 0xf) {
  1314 + case 0x0:
  1315 + gen_op_iwmmxt_subnb_M0_wRn(rd1);
  1316 + break;
  1317 + case 0x1:
  1318 + gen_op_iwmmxt_subub_M0_wRn(rd1);
  1319 + break;
  1320 + case 0x3:
  1321 + gen_op_iwmmxt_subsb_M0_wRn(rd1);
  1322 + break;
  1323 + case 0x4:
  1324 + gen_op_iwmmxt_subnw_M0_wRn(rd1);
  1325 + break;
  1326 + case 0x5:
  1327 + gen_op_iwmmxt_subuw_M0_wRn(rd1);
  1328 + break;
  1329 + case 0x7:
  1330 + gen_op_iwmmxt_subsw_M0_wRn(rd1);
  1331 + break;
  1332 + case 0x8:
  1333 + gen_op_iwmmxt_subnl_M0_wRn(rd1);
  1334 + break;
  1335 + case 0x9:
  1336 + gen_op_iwmmxt_subul_M0_wRn(rd1);
  1337 + break;
  1338 + case 0xb:
  1339 + gen_op_iwmmxt_subsl_M0_wRn(rd1);
  1340 + break;
  1341 + default:
  1342 + return 1;
  1343 + }
  1344 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1345 + gen_op_iwmmxt_set_mup();
  1346 + gen_op_iwmmxt_set_cup();
  1347 + break;
  1348 + case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
  1349 + case 0x41e: case 0x51e: case 0x61e: case 0x71e:
  1350 + case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
  1351 + case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
  1352 + wrd = (insn >> 12) & 0xf;
  1353 + rd0 = (insn >> 16) & 0xf;
  1354 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1355 + gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
  1356 + gen_op_iwmmxt_shufh_M0_T0();
  1357 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1358 + gen_op_iwmmxt_set_mup();
  1359 + gen_op_iwmmxt_set_cup();
  1360 + break;
  1361 + case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
  1362 + case 0x418: case 0x518: case 0x618: case 0x718:
  1363 + case 0x818: case 0x918: case 0xa18: case 0xb18:
  1364 + case 0xc18: case 0xd18: case 0xe18: case 0xf18:
  1365 + wrd = (insn >> 12) & 0xf;
  1366 + rd0 = (insn >> 16) & 0xf;
  1367 + rd1 = (insn >> 0) & 0xf;
  1368 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1369 + switch ((insn >> 20) & 0xf) {
  1370 + case 0x0:
  1371 + gen_op_iwmmxt_addnb_M0_wRn(rd1);
  1372 + break;
  1373 + case 0x1:
  1374 + gen_op_iwmmxt_addub_M0_wRn(rd1);
  1375 + break;
  1376 + case 0x3:
  1377 + gen_op_iwmmxt_addsb_M0_wRn(rd1);
  1378 + break;
  1379 + case 0x4:
  1380 + gen_op_iwmmxt_addnw_M0_wRn(rd1);
  1381 + break;
  1382 + case 0x5:
  1383 + gen_op_iwmmxt_adduw_M0_wRn(rd1);
  1384 + break;
  1385 + case 0x7:
  1386 + gen_op_iwmmxt_addsw_M0_wRn(rd1);
  1387 + break;
  1388 + case 0x8:
  1389 + gen_op_iwmmxt_addnl_M0_wRn(rd1);
  1390 + break;
  1391 + case 0x9:
  1392 + gen_op_iwmmxt_addul_M0_wRn(rd1);
  1393 + break;
  1394 + case 0xb:
  1395 + gen_op_iwmmxt_addsl_M0_wRn(rd1);
  1396 + break;
  1397 + default:
  1398 + return 1;
  1399 + }
  1400 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1401 + gen_op_iwmmxt_set_mup();
  1402 + gen_op_iwmmxt_set_cup();
  1403 + break;
  1404 + case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
  1405 + case 0x408: case 0x508: case 0x608: case 0x708:
  1406 + case 0x808: case 0x908: case 0xa08: case 0xb08:
  1407 + case 0xc08: case 0xd08: case 0xe08: case 0xf08:
  1408 + wrd = (insn >> 12) & 0xf;
  1409 + rd0 = (insn >> 16) & 0xf;
  1410 + rd1 = (insn >> 0) & 0xf;
  1411 + gen_op_iwmmxt_movq_M0_wRn(rd0);
  1412 + if (!(insn & (1 << 20)))
  1413 + return 1;
  1414 + switch ((insn >> 22) & 3) {
  1415 + case 0:
  1416 + return 1;
  1417 + case 1:
  1418 + if (insn & (1 << 21))
  1419 + gen_op_iwmmxt_packsw_M0_wRn(rd1);
  1420 + else
  1421 + gen_op_iwmmxt_packuw_M0_wRn(rd1);
  1422 + break;
  1423 + case 2:
  1424 + if (insn & (1 << 21))
  1425 + gen_op_iwmmxt_packsl_M0_wRn(rd1);
  1426 + else
  1427 + gen_op_iwmmxt_packul_M0_wRn(rd1);
  1428 + break;
  1429 + case 3:
  1430 + if (insn & (1 << 21))
  1431 + gen_op_iwmmxt_packsq_M0_wRn(rd1);
  1432 + else
  1433 + gen_op_iwmmxt_packuq_M0_wRn(rd1);
  1434 + break;
  1435 + }
  1436 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1437 + gen_op_iwmmxt_set_mup();
  1438 + gen_op_iwmmxt_set_cup();
  1439 + break;
  1440 + case 0x201: case 0x203: case 0x205: case 0x207:
  1441 + case 0x209: case 0x20b: case 0x20d: case 0x20f:
  1442 + case 0x211: case 0x213: case 0x215: case 0x217:
  1443 + case 0x219: case 0x21b: case 0x21d: case 0x21f:
  1444 + wrd = (insn >> 5) & 0xf;
  1445 + rd0 = (insn >> 12) & 0xf;
  1446 + rd1 = (insn >> 0) & 0xf;
  1447 + if (rd0 == 0xf || rd1 == 0xf)
  1448 + return 1;
  1449 + gen_op_iwmmxt_movq_M0_wRn(wrd);
  1450 + switch ((insn >> 16) & 0xf) {
  1451 + case 0x0: /* TMIA */
  1452 + gen_op_movl_TN_reg[0][rd0]();
  1453 + gen_op_movl_TN_reg[1][rd1]();
  1454 + gen_op_iwmmxt_muladdsl_M0_T0_T1();
  1455 + break;
  1456 + case 0x8: /* TMIAPH */
  1457 + gen_op_movl_TN_reg[0][rd0]();
  1458 + gen_op_movl_TN_reg[1][rd1]();
  1459 + gen_op_iwmmxt_muladdsw_M0_T0_T1();
  1460 + break;
  1461 + case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
  1462 + gen_op_movl_TN_reg[1][rd0]();
  1463 + if (insn & (1 << 16))
  1464 + gen_op_shrl_T1_im(16);
  1465 + gen_op_movl_T0_T1();
  1466 + gen_op_movl_TN_reg[1][rd1]();
  1467 + if (insn & (1 << 17))
  1468 + gen_op_shrl_T1_im(16);
  1469 + gen_op_iwmmxt_muladdswl_M0_T0_T1();
  1470 + break;
  1471 + default:
  1472 + return 1;
  1473 + }
  1474 + gen_op_iwmmxt_movq_wRn_M0(wrd);
  1475 + gen_op_iwmmxt_set_mup();
  1476 + break;
  1477 + default:
  1478 + return 1;
  1479 + }
  1480 +
  1481 + return 0;
  1482 +}
  1483 +
  1484 +/* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
  1485 + (ie. an undefined instruction). */
  1486 +static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
  1487 +{
  1488 + int acc, rd0, rd1, rdhi, rdlo;
  1489 +
  1490 + if ((insn & 0x0ff00f10) == 0x0e200010) {
  1491 + /* Multiply with Internal Accumulate Format */
  1492 + rd0 = (insn >> 12) & 0xf;
  1493 + rd1 = insn & 0xf;
  1494 + acc = (insn >> 5) & 7;
  1495 +
  1496 + if (acc != 0)
  1497 + return 1;
  1498 +
  1499 + switch ((insn >> 16) & 0xf) {
  1500 + case 0x0: /* MIA */
  1501 + gen_op_movl_TN_reg[0][rd0]();
  1502 + gen_op_movl_TN_reg[1][rd1]();
  1503 + gen_op_iwmmxt_muladdsl_M0_T0_T1();
  1504 + break;
  1505 + case 0x8: /* MIAPH */
  1506 + gen_op_movl_TN_reg[0][rd0]();
  1507 + gen_op_movl_TN_reg[1][rd1]();
  1508 + gen_op_iwmmxt_muladdsw_M0_T0_T1();
  1509 + break;
  1510 + case 0xc: /* MIABB */
  1511 + case 0xd: /* MIABT */
  1512 + case 0xe: /* MIATB */
  1513 + case 0xf: /* MIATT */
  1514 + gen_op_movl_TN_reg[1][rd0]();
  1515 + if (insn & (1 << 16))
  1516 + gen_op_shrl_T1_im(16);
  1517 + gen_op_movl_T0_T1();
  1518 + gen_op_movl_TN_reg[1][rd1]();
  1519 + if (insn & (1 << 17))
  1520 + gen_op_shrl_T1_im(16);
  1521 + gen_op_iwmmxt_muladdswl_M0_T0_T1();
  1522 + break;
  1523 + default:
  1524 + return 1;
  1525 + }
  1526 +
  1527 + gen_op_iwmmxt_movq_wRn_M0(acc);
  1528 + return 0;
  1529 + }
  1530 +
  1531 + if ((insn & 0x0fe00ff8) == 0x0c400000) {
  1532 + /* Internal Accumulator Access Format */
  1533 + rdhi = (insn >> 16) & 0xf;
  1534 + rdlo = (insn >> 12) & 0xf;
  1535 + acc = insn & 7;
  1536 +
  1537 + if (acc != 0)
  1538 + return 1;
  1539 +
  1540 + if (insn & ARM_CP_RW_BIT) { /* MRA */
  1541 + gen_op_iwmmxt_movl_T0_T1_wRn(acc);
  1542 + gen_op_movl_reg_TN[0][rdlo]();
  1543 + gen_op_movl_T0_im((1 << (40 - 32)) - 1);
  1544 + gen_op_andl_T0_T1();
  1545 + gen_op_movl_reg_TN[0][rdhi]();
  1546 + } else { /* MAR */
  1547 + gen_op_movl_TN_reg[0][rdlo]();
  1548 + gen_op_movl_TN_reg[1][rdhi]();
  1549 + gen_op_iwmmxt_movl_wRn_T0_T1(acc);
  1550 + }
  1551 + return 0;
  1552 + }
  1553 +
  1554 + return 1;
  1555 +}
  1556 +
495 1557 /* Disassemble system coprocessor instruction. Return nonzero if
496 1558 instruction is not defined. */
497 1559 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
... ... @@ -502,7 +1564,7 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
502 1564 return 1;
503 1565 }
504 1566  
505   - if (insn & (1 << 20)) {
  1567 + if (insn & ARM_CP_RW_BIT) {
506 1568 if (!env->cp[cp].cp_read)
507 1569 return 1;
508 1570 gen_op_movl_T0_im((uint32_t) s->pc);
... ... @@ -540,7 +1602,7 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn)
540 1602 return 0;
541 1603 }
542 1604 rd = (insn >> 12) & 0xf;
543   - if (insn & (1 << 20)) {
  1605 + if (insn & ARM_CP_RW_BIT) {
544 1606 gen_op_movl_T0_cp15(insn);
545 1607 /* If the destination register is r15 then sets condition codes. */
546 1608 if (rd != 15)
... ... @@ -587,7 +1649,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
587 1649 we only set half the register. */
588 1650 gen_mov_F0_vreg(1, rn);
589 1651 gen_op_vfp_mrrd();
590   - if (insn & (1 << 20)) {
  1652 + if (insn & ARM_CP_RW_BIT) {
591 1653 /* vfp->arm */
592 1654 if (insn & (1 << 21))
593 1655 gen_movl_reg_T1(s, rd);
... ... @@ -604,7 +1666,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
604 1666 }
605 1667 } else {
606 1668 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
607   - if (insn & (1 << 20)) {
  1669 + if (insn & ARM_CP_RW_BIT) {
608 1670 /* vfp->arm */
609 1671 if (insn & (1 << 21)) {
610 1672 /* system register */
... ... @@ -938,7 +2000,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
938 2000 } else
939 2001 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
940 2002  
941   - if (insn & (1 << 20)) {
  2003 + if (insn & ARM_CP_RW_BIT) {
942 2004 /* vfp->arm */
943 2005 if (dp) {
944 2006 gen_mov_F0_vreg(1, rm);
... ... @@ -1005,7 +2067,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
1005 2067 else
1006 2068 offset = 4;
1007 2069 for (i = 0; i < n; i++) {
1008   - if (insn & (1 << 20)) {
  2070 + if (insn & ARM_CP_RW_BIT) {
1009 2071 /* load */
1010 2072 gen_vfp_ld(s, dp);
1011 2073 gen_mov_vreg_F0(dp, rd + i);
... ... @@ -1845,6 +2907,15 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
1845 2907 goto illegal_op;
1846 2908 switch (op1) {
1847 2909 case 0 ... 1:
  2910 + if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
  2911 + if (disas_iwmmxt_insn(env, s, insn))
  2912 + goto illegal_op;
  2913 + } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
  2914 + if (disas_dsp_insn(env, s, insn))
  2915 + goto illegal_op;
  2916 + } else
  2917 + goto illegal_op;
  2918 + break;
1848 2919 case 2 ... 9:
1849 2920 case 12 ... 14:
1850 2921 if (disas_cp_insn (env, s, insn))
... ...
tests/Makefile
... ... @@ -82,6 +82,9 @@ hello-arm: hello-arm.o
82 82 hello-arm.o: hello-arm.c
83 83 arm-linux-gcc -Wall -g -O2 -c -o $@ $<
84 84  
  85 +test-arm-iwmmxt: test-arm-iwmmxt.s
  86 + cpp < $< | arm-linux-gnu-gcc -Wall -static -march=iwmmxt -mabi=aapcs -x assembler - -o $@
  87 +
85 88 # MIPS test
86 89 hello-mips: hello-mips.c
87 90 mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
... ...
tests/test-arm-iwmmxt.s 0 → 100644
  1 +@ Checks whether iwMMXt is functional.
  2 +.code 32
  3 +.globl main
  4 +
  5 +main:
  6 +ldr r0, =data0
  7 +ldr r1, =data1
  8 +ldr r2, =data2
  9 +#ifndef FPA
  10 +wldrd wr0, [r0, #0]
  11 +wldrd wr1, [r0, #8]
  12 +wldrd wr2, [r1, #0]
  13 +wldrd wr3, [r1, #8]
  14 +wsubb wr2, wr2, wr0
  15 +wsubb wr3, wr3, wr1
  16 +wldrd wr0, [r2, #0]
  17 +wldrd wr1, [r2, #8]
  18 +waddb wr0, wr0, wr2
  19 +waddb wr1, wr1, wr3
  20 +wstrd wr0, [r2, #0]
  21 +wstrd wr1, [r2, #8]
  22 +#else
  23 +ldfe f0, [r0, #0]
  24 +ldfe f1, [r0, #8]
  25 +ldfe f2, [r1, #0]
  26 +ldfe f3, [r1, #8]
  27 +adfdp f2, f2, f0
  28 +adfdp f3, f3, f1
  29 +ldfe f0, [r2, #0]
  30 +ldfe f1, [r2, #8]
  31 +adfd f0, f0, f2
  32 +adfd f1, f1, f3
  33 +stfe f0, [r2, #0]
  34 +stfe f1, [r2, #8]
  35 +#endif
  36 +mov r0, #1
  37 +mov r1, r2
  38 +mov r2, #0x11
  39 +swi #0x900004
  40 +mov r0, #0
  41 +swi #0x900001
  42 +
  43 +.data
  44 +data0:
  45 +.string "aaaabbbbccccdddd"
  46 +data1:
  47 +.string "bbbbccccddddeeee"
  48 +data2:
  49 +.string "hvLLWs\x1fsdrs9\x1fNJ-\n"
... ...