OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [arm/] [iwmmxt.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/*  iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
2
    Copyright (C) 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3
    Contributed by matthew green (mrg@redhat.com).
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 3 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
 
18
#include <string.h>
19
 
20
#include "armdefs.h"
21
#include "armos.h"
22
#include "armemu.h"
23
#include "ansidecl.h"
24
#include "iwmmxt.h"
25
 
26
/* #define DEBUG 1 */
27
 
28
/* Intel(r) Wireless MMX(tm) technology co-processor.
29
   It uses co-processor numbers (0 and 1).  There are 16 vector registers wRx
30
   and 16 control registers wCx.  Co-processors 0 and 1 are used in MCR/MRC
31
   to access wRx and wCx respectively.  */
32
 
33
static ARMdword wR[16];
34
static ARMword  wC[16] = { 0x69051010 };
35
 
36
#define SUBSTR(w,t,m,n) ((t)(w <<  ((sizeof (t) * 8 - 1) - (n))) \
37
                               >> (((sizeof (t) * 8 - 1) - (n)) + (m)))
38
#define wCBITS(w,x,y)   SUBSTR (wC[w], ARMword, x, y)
39
#define wRBITS(w,x,y)   SUBSTR (wR[w], ARMdword, x, y)
40
#define wCID   0
41
#define wCon   1
42
#define wCSSF  2
43
#define wCASF  3
44
#define wCGR0  8
45
#define wCGR1  9
46
#define wCGR2 10
47
#define wCGR3 11
48
 
49
/* Bits in the wCon register.  */
50
#define WCON_CUP        (1 << 0)
51
#define WCON_MUP        (1 << 1)
52
 
53
/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations.  */
54
#define SIMD8_SET(x,  v, n, b)  (x) |= ((v != 0) << ((((b) + 1) * 4) + (n)))
55
#define SIMD16_SET(x, v, n, h)  (x) |= ((v != 0) << ((((h) + 1) * 8) + (n)))
56
#define SIMD32_SET(x, v, n, w)  (x) |= ((v != 0) << ((((w) + 1) * 16) + (n)))
57
#define SIMD64_SET(x, v, n)     (x) |= ((v != 0) << (32 + (n)))
58
 
59
/* Flags to pass as "n" above.  */
60
#define SIMD_NBIT       -1
61
#define SIMD_ZBIT       -2
62
#define SIMD_CBIT       -3
63
#define SIMD_VBIT       -4
64
 
65
/* Various status bit macros.  */
66
#define NBIT8(x)        ((x) & 0x80)
67
#define NBIT16(x)       ((x) & 0x8000)
68
#define NBIT32(x)       ((x) & 0x80000000)
69
#define NBIT64(x)       ((x) & 0x8000000000000000ULL)
70
#define ZBIT8(x)        (((x) & 0xff) == 0)
71
#define ZBIT16(x)       (((x) & 0xffff) == 0)
72
#define ZBIT32(x)       (((x) & 0xffffffff) == 0)
73
#define ZBIT64(x)       (x == 0)
74
 
75
/* Access byte/half/word "n" of register "x".  */
76
#define wRBYTE(x,n)     wRBITS ((x), (n) * 8, (n) * 8 + 7)
77
#define wRHALF(x,n)     wRBITS ((x), (n) * 16, (n) * 16 + 15)
78
#define wRWORD(x,n)     wRBITS ((x), (n) * 32, (n) * 32 + 31)
79
 
80
/* Macro to handle how the G bit selects wCGR registers.  */
81
#define DECODE_G_BIT(state, instr, shift)       \
82
{                                               \
83
  unsigned int reg;                             \
84
                                                \
85
  reg = BITS (0, 3);                             \
86
                                                \
87
  if (BIT (8))  /* G */                         \
88
    {                                           \
89
      if (reg < wCGR0 || reg > wCGR3)           \
90
        {                                       \
91
          ARMul_UndefInstr (state, instr);      \
92
          return ARMul_DONE;                    \
93
        }                                       \
94
      shift = wC [reg];                         \
95
    }                                           \
96
  else                                          \
97
    shift = wR [reg];                           \
98
                                                \
99
  shift &= 0xff;                                \
100
}
101
 
102
/* Index calculations for the satrv[] array.  */
103
#define BITIDX8(x)      (x)
104
#define BITIDX16(x)     (((x) + 1) * 2 - 1)
105
#define BITIDX32(x)     (((x) + 1) * 4 - 1)
106
 
107
/* Sign extension macros.  */
108
#define EXTEND8(a)      ((a) & 0x80 ? ((a) | 0xffffff00) : (a))
109
#define EXTEND16(a)     ((a) & 0x8000 ? ((a) | 0xffff0000) : (a))
110
#define EXTEND32(a)     ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a))
111
 
112
/* Set the wCSSF from 8 values.  */
113
#define SET_wCSSF(a,b,c,d,e,f,g,h) \
114
  wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \
115
            | (((f) != 0) << 5) | (((e) != 0) << 4) \
116
            | (((d) != 0) << 3) | (((c) != 0) << 2) \
117
            | (((b) != 0) << 1) | (((a) != 0) << 0);
118
 
119
/* Set the wCSSR from an array with 8 values.  */
120
#define SET_wCSSFvec(v) \
121
  SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7])
122
 
123
/* Size qualifiers for vector operations.  */
124
#define Bqual                   0
125
#define Hqual                   1
126
#define Wqual                   2
127
#define Dqual                   3
128
 
129
/* Saturation qualifiers for vector operations.  */
130
#define NoSaturation            0
131
#define UnsignedSaturation      1
132
#define SignedSaturation        3
133
 
134
 
135
/* Prototypes.  */
136
static ARMword         Add32  (ARMword,  ARMword,  int *, int *, ARMword);
137
static ARMdword        AddS32 (ARMdword, ARMdword, int *, int *);
138
static ARMdword        AddU32 (ARMdword, ARMdword, int *, int *);
139
static ARMword         AddS16 (ARMword,  ARMword,  int *, int *);
140
static ARMword         AddU16 (ARMword,  ARMword,  int *, int *);
141
static ARMword         AddS8  (ARMword,  ARMword,  int *, int *);
142
static ARMword         AddU8  (ARMword,  ARMword,  int *, int *);
143
static ARMword         Sub32  (ARMword,  ARMword,  int *, int *, ARMword);
144
static ARMdword        SubS32 (ARMdword, ARMdword, int *, int *);
145
static ARMdword        SubU32 (ARMdword, ARMdword, int *, int *);
146
static ARMword         SubS16 (ARMword,  ARMword,  int *, int *);
147
static ARMword         SubS8  (ARMword,  ARMword,  int *, int *);
148
static ARMword         SubU16 (ARMword,  ARMword,  int *, int *);
149
static ARMword         SubU8  (ARMword,  ARMword,  int *, int *);
150
static unsigned char   IwmmxtSaturateU8  (signed short, int *);
151
static signed char     IwmmxtSaturateS8  (signed short, int *);
152
static unsigned short  IwmmxtSaturateU16 (signed int, int *);
153
static signed short    IwmmxtSaturateS16 (signed int, int *);
154
static unsigned long   IwmmxtSaturateU32 (signed long long, int *);
155
static signed long     IwmmxtSaturateS32 (signed long long, int *);
156
static ARMword         Compute_Iwmmxt_Address   (ARMul_State *, ARMword, int *);
157
static ARMdword        Iwmmxt_Load_Double_Word  (ARMul_State *, ARMword);
158
static ARMword         Iwmmxt_Load_Word         (ARMul_State *, ARMword);
159
static ARMword         Iwmmxt_Load_Half_Word    (ARMul_State *, ARMword);
160
static ARMword         Iwmmxt_Load_Byte         (ARMul_State *, ARMword);
161
static void            Iwmmxt_Store_Double_Word (ARMul_State *, ARMword, ARMdword);
162
static void            Iwmmxt_Store_Word        (ARMul_State *, ARMword, ARMword);
163
static void            Iwmmxt_Store_Half_Word   (ARMul_State *, ARMword, ARMword);
164
static void            Iwmmxt_Store_Byte        (ARMul_State *, ARMword, ARMword);
165
static int             Process_Instruction      (ARMul_State *, ARMword);
166
 
167
static int TANDC    (ARMul_State *, ARMword);
168
static int TBCST    (ARMul_State *, ARMword);
169
static int TEXTRC   (ARMul_State *, ARMword);
170
static int TEXTRM   (ARMul_State *, ARMword);
171
static int TINSR    (ARMul_State *, ARMword);
172
static int TMCR     (ARMul_State *, ARMword);
173
static int TMCRR    (ARMul_State *, ARMword);
174
static int TMIA     (ARMul_State *, ARMword);
175
static int TMIAPH   (ARMul_State *, ARMword);
176
static int TMIAxy   (ARMul_State *, ARMword);
177
static int TMOVMSK  (ARMul_State *, ARMword);
178
static int TMRC     (ARMul_State *, ARMword);
179
static int TMRRC    (ARMul_State *, ARMword);
180
static int TORC     (ARMul_State *, ARMword);
181
static int WACC     (ARMul_State *, ARMword);
182
static int WADD     (ARMul_State *, ARMword);
183
static int WALIGNI  (ARMword);
184
static int WALIGNR  (ARMul_State *, ARMword);
185
static int WAND     (ARMword);
186
static int WANDN    (ARMword);
187
static int WAVG2    (ARMword);
188
static int WCMPEQ   (ARMul_State *, ARMword);
189
static int WCMPGT   (ARMul_State *, ARMword);
190
static int WLDR     (ARMul_State *, ARMword);
191
static int WMAC     (ARMword);
192
static int WMADD    (ARMword);
193
static int WMAX     (ARMul_State *, ARMword);
194
static int WMIN     (ARMul_State *, ARMword);
195
static int WMUL     (ARMword);
196
static int WOR      (ARMword);
197
static int WPACK    (ARMul_State *, ARMword);
198
static int WROR     (ARMul_State *, ARMword);
199
static int WSAD     (ARMword);
200
static int WSHUFH   (ARMword);
201
static int WSLL     (ARMul_State *, ARMword);
202
static int WSRA     (ARMul_State *, ARMword);
203
static int WSRL     (ARMul_State *, ARMword);
204
static int WSTR     (ARMul_State *, ARMword);
205
static int WSUB     (ARMul_State *, ARMword);
206
static int WUNPCKEH (ARMul_State *, ARMword);
207
static int WUNPCKEL (ARMul_State *, ARMword);
208
static int WUNPCKIH (ARMul_State *, ARMword);
209
static int WUNPCKIL (ARMul_State *, ARMword);
210
static int WXOR     (ARMword);
211
 
212
/* This function does the work of adding two 32bit values
213
   together, and calculating if a carry has occurred.  */
214
 
215
static ARMword
216
Add32 (ARMword a1,
217
       ARMword a2,
218
       int * carry_ptr,
219
       int * overflow_ptr,
220
       ARMword sign_mask)
221
{
222
  ARMword result = (a1 + a2);
223
  unsigned int uresult = (unsigned int) result;
224
  unsigned int ua1 = (unsigned int) a1;
225
 
226
  /* If (result == a1) and (a2 == 0),
227
     or (result > a2) then we have no carry.  */
228
  * carry_ptr = ((uresult == ua1) ? (a2 != 0) : (uresult < ua1));
229
 
230
  /* Overflow occurs when both arguments are the
231
     same sign, but the result is a different sign.  */
232
  * overflow_ptr = (   ( (result & sign_mask) && !(a1 & sign_mask) && !(a2 & sign_mask))
233
                    || (!(result & sign_mask) &&  (a1 & sign_mask) &&  (a2 & sign_mask)));
234
 
235
  return result;
236
}
237
 
238
static ARMdword
239
AddS32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr)
240
{
241
  ARMdword     result;
242
  unsigned int uresult;
243
  unsigned int ua1;
244
 
245
  a1 = EXTEND32 (a1);
246
  a2 = EXTEND32 (a2);
247
 
248
  result  = a1 + a2;
249
  uresult = (unsigned int) result;
250
  ua1     = (unsigned int) a1;
251
 
252
  * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1));
253
 
254
  * overflow_ptr = (   ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL))
255
                    || (!(result & 0x80000000ULL) &&  (a1 & 0x80000000ULL) &&  (a2 & 0x80000000ULL)));
256
 
257
  return result;
258
}
259
 
260
static ARMdword
261
AddU32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr)
262
{
263
  ARMdword     result;
264
  unsigned int uresult;
265
  unsigned int ua1;
266
 
267
  a1 &= 0xffffffff;
268
  a2 &= 0xffffffff;
269
 
270
  result  = a1 + a2;
271
  uresult = (unsigned int) result;
272
  ua1     = (unsigned int) a1;
273
 
274
  * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1));
275
 
276
  * overflow_ptr = (   ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL))
277
                    || (!(result & 0x80000000ULL) &&  (a1 & 0x80000000ULL) &&  (a2 & 0x80000000ULL)));
278
 
279
  return result;
280
}
281
 
282
static ARMword
283
AddS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
284
{
285
  a1 = EXTEND16 (a1);
286
  a2 = EXTEND16 (a2);
287
 
288
  return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
289
}
290
 
291
static ARMword
292
AddU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
293
{
294
  a1 &= 0xffff;
295
  a2 &= 0xffff;
296
 
297
  return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
298
}
299
 
300
static ARMword
301
AddS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
302
{
303
  a1 = EXTEND8 (a1);
304
  a2 = EXTEND8 (a2);
305
 
306
  return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
307
}
308
 
309
static ARMword
310
AddU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
311
{
312
  a1 &= 0xff;
313
  a2 &= 0xff;
314
 
315
  return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
316
}
317
 
318
static ARMword
319
Sub32 (ARMword a1,
320
       ARMword a2,
321
       int * borrow_ptr,
322
       int * overflow_ptr,
323
       ARMword sign_mask)
324
{
325
  ARMword result = (a1 - a2);
326
  unsigned int ua1 = (unsigned int) a1;
327
  unsigned int ua2 = (unsigned int) a2;
328
 
329
  /* A borrow occurs if a2 is (unsigned) larger than a1.
330
     However the carry flag is *cleared* if a borrow occurs.  */
331
  * borrow_ptr = ! (ua2 > ua1);
332
 
333
  /* Overflow occurs when a negative number is subtracted from a
334
     positive number and the result is negative or a positive
335
     number is subtracted from a negative number and the result is
336
     positive.  */
337
  * overflow_ptr = ( (! (a1 & sign_mask) &&   (a2 & sign_mask) &&   (result & sign_mask))
338
                    || ((a1 & sign_mask) && ! (a2 & sign_mask) && ! (result & sign_mask)));
339
 
340
  return result;
341
}
342
 
343
static ARMdword
344
SubS32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr)
345
{
346
  ARMdword     result;
347
  unsigned int ua1;
348
  unsigned int ua2;
349
 
350
  a1 = EXTEND32 (a1);
351
  a2 = EXTEND32 (a2);
352
 
353
  result = a1 - a2;
354
  ua1    = (unsigned int) a1;
355
  ua2    = (unsigned int) a2;
356
 
357
  * borrow_ptr = ! (ua2 > ua1);
358
 
359
  * overflow_ptr = ( (! (a1 & 0x80000000ULL) &&   (a2 & 0x80000000ULL) &&   (result & 0x80000000ULL))
360
                    || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL)));
361
 
362
  return result;
363
}
364
 
365
static ARMword
366
SubS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
367
{
368
  a1 = EXTEND16 (a1);
369
  a2 = EXTEND16 (a2);
370
 
371
  return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
372
}
373
 
374
static ARMword
375
SubS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
376
{
377
  a1 = EXTEND8 (a1);
378
  a2 = EXTEND8 (a2);
379
 
380
  return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
381
}
382
 
383
static ARMword
384
SubU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
385
{
386
  a1 &= 0xffff;
387
  a2 &= 0xffff;
388
 
389
  return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
390
}
391
 
392
static ARMword
393
SubU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
394
{
395
  a1 &= 0xff;
396
  a2 &= 0xff;
397
 
398
  return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
399
}
400
 
401
static ARMdword
402
SubU32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr)
403
{
404
  ARMdword     result;
405
  unsigned int ua1;
406
  unsigned int ua2;
407
 
408
  a1 &= 0xffffffff;
409
  a2 &= 0xffffffff;
410
 
411
  result = a1 - a2;
412
  ua1    = (unsigned int) a1;
413
  ua2    = (unsigned int) a2;
414
 
415
  * borrow_ptr = ! (ua2 > ua1);
416
 
417
  * overflow_ptr = ( (! (a1 & 0x80000000ULL) &&   (a2 & 0x80000000ULL) &&   (result & 0x80000000ULL))
418
                    || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL)));
419
 
420
  return result;
421
}
422
 
423
/* For the saturation.  */
424
 
425
static unsigned char
426
IwmmxtSaturateU8 (signed short val, int * sat)
427
{
428
  unsigned char rv;
429
 
430
  if (val < 0)
431
    {
432
      rv = 0;
433
      *sat = 1;
434
    }
435
  else if (val > 0xff)
436
    {
437
      rv = 0xff;
438
      *sat = 1;
439
    }
440
  else
441
    {
442
      rv = val & 0xff;
443
      *sat = 0;
444
    }
445
  return rv;
446
}
447
 
448
static signed char
449
IwmmxtSaturateS8 (signed short val, int * sat)
450
{
451
  signed char rv;
452
 
453
  if (val < -0x80)
454
    {
455
      rv = -0x80;
456
      *sat = 1;
457
    }
458
  else if (val > 0x7f)
459
    {
460
      rv = 0x7f;
461
      *sat = 1;
462
    }
463
  else
464
    {
465
      rv = val & 0xff;
466
      *sat = 0;
467
    }
468
  return rv;
469
}
470
 
471
static unsigned short
472
IwmmxtSaturateU16 (signed int val, int * sat)
473
{
474
  unsigned short rv;
475
 
476
  if (val < 0)
477
    {
478
      rv = 0;
479
      *sat = 1;
480
    }
481
  else if (val > 0xffff)
482
    {
483
      rv = 0xffff;
484
      *sat = 1;
485
    }
486
  else
487
    {
488
      rv = val & 0xffff;
489
      *sat = 0;
490
    }
491
  return rv;
492
}
493
 
494
static signed short
495
IwmmxtSaturateS16 (signed int val, int * sat)
496
{
497
  signed short rv;
498
 
499
  if (val < -0x8000)
500
    {
501
      rv = - 0x8000;
502
      *sat = 1;
503
    }
504
  else if (val > 0x7fff)
505
    {
506
      rv = 0x7fff;
507
      *sat = 1;
508
    }
509
  else
510
    {
511
      rv = val & 0xffff;
512
      *sat = 0;
513
    }
514
  return rv;
515
}
516
 
517
static unsigned long
518
IwmmxtSaturateU32 (signed long long val, int * sat)
519
{
520
  unsigned long rv;
521
 
522
  if (val < 0)
523
    {
524
      rv = 0;
525
      *sat = 1;
526
    }
527
  else if (val > 0xffffffff)
528
    {
529
      rv = 0xffffffff;
530
      *sat = 1;
531
    }
532
  else
533
    {
534
      rv = val & 0xffffffff;
535
      *sat = 0;
536
    }
537
  return rv;
538
}
539
 
540
static signed long
541
IwmmxtSaturateS32 (signed long long val, int * sat)
542
{
543
  signed long rv;
544
 
545
  if (val < -0x80000000LL)
546
    {
547
      rv = -0x80000000;
548
      *sat = 1;
549
    }
550
  else if (val > 0x7fffffff)
551
    {
552
      rv = 0x7fffffff;
553
      *sat = 1;
554
    }
555
  else
556
    {
557
      rv = val & 0xffffffff;
558
      *sat = 0;
559
    }
560
  return rv;
561
}
562
 
563
/* Intel(r) Wireless MMX(tm) technology Acessor functions.  */
564
 
565
unsigned
566
IwmmxtLDC (ARMul_State * state ATTRIBUTE_UNUSED,
567
           unsigned      type  ATTRIBUTE_UNUSED,
568
           ARMword       instr,
569
           ARMword       data)
570
{
571
  return ARMul_CANT;
572
}
573
 
574
unsigned
575
IwmmxtSTC (ARMul_State * state ATTRIBUTE_UNUSED,
576
           unsigned      type  ATTRIBUTE_UNUSED,
577
           ARMword       instr,
578
           ARMword *     data)
579
{
580
  return ARMul_CANT;
581
}
582
 
583
unsigned
584
IwmmxtMRC (ARMul_State * state ATTRIBUTE_UNUSED,
585
           unsigned      type  ATTRIBUTE_UNUSED,
586
           ARMword       instr,
587
           ARMword *     value)
588
{
589
  return ARMul_CANT;
590
}
591
 
592
unsigned
593
IwmmxtMCR (ARMul_State * state ATTRIBUTE_UNUSED,
594
           unsigned      type  ATTRIBUTE_UNUSED,
595
           ARMword       instr,
596
           ARMword       value)
597
{
598
  return ARMul_CANT;
599
}
600
 
601
unsigned
602
IwmmxtCDP (ARMul_State * state, unsigned type, ARMword instr)
603
{
604
  return ARMul_CANT;
605
}
606
 
607
/* Intel(r) Wireless MMX(tm) technology instruction implementations.  */
608
 
609
static int
610
TANDC (ARMul_State * state, ARMword instr)
611
{
612
  ARMword cpsr;
613
 
614
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
615
    return ARMul_CANT;
616
 
617
#ifdef DEBUG
618
  fprintf (stderr, "tandc\n");
619
#endif  
620
 
621
  /* The Rd field must be r15.  */
622
  if (BITS (12, 15) != 15)
623
    return ARMul_CANT;
624
 
625
  /* The CRn field must be r3.  */
626
  if (BITS (16, 19) != 3)
627
    return ARMul_CANT;
628
 
629
  /* The CRm field must be r0.  */
630
  if (BITS (0, 3) != 0)
631
    return ARMul_CANT;
632
 
633
  cpsr = ARMul_GetCPSR (state) & 0x0fffffff;
634
 
635
  switch (BITS (22, 23))
636
    {
637
    case Bqual:
638
      cpsr |= (  (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 24, 27)
639
                & wCBITS (wCASF, 20, 23) & wCBITS (wCASF, 16, 19)
640
                & wCBITS (wCASF, 12, 15) & wCBITS (wCASF,  8, 11)
641
                & wCBITS (wCASF,  4,  7) & wCBITS (wCASF,  0,  3)) << 28);
642
      break;
643
 
644
    case Hqual:
645
      cpsr |= (  (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 20, 23)
646
                & wCBITS (wCASF, 12, 15) & wCBITS (wCASF,  4, 7)) << 28);
647
      break;
648
 
649
    case Wqual:
650
      cpsr |= ((wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 12, 15)) << 28);
651
      break;
652
 
653
    default:
654
      ARMul_UndefInstr (state, instr);
655
      return ARMul_DONE;
656
    }
657
 
658
  ARMul_SetCPSR (state, cpsr);
659
 
660
  return ARMul_DONE;
661
}
662
 
663
static int
664
TBCST (ARMul_State * state, ARMword instr)
665
{
666
  ARMdword Rn;
667
  int wRd;
668
 
669
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
670
    return ARMul_CANT;
671
 
672
#ifdef DEBUG
673
  fprintf (stderr, "tbcst\n");
674
#endif  
675
 
676
  Rn  = state->Reg [BITS (12, 15)];
677
  if (BITS (12, 15) == 15)
678
    Rn &= 0xfffffffc;
679
 
680
  wRd = BITS (16, 19);
681
 
682
  switch (BITS (6, 7))
683
    {
684
    case Bqual:
685
      Rn &= 0xff;
686
      wR [wRd] = (Rn << 56) | (Rn << 48) | (Rn << 40) | (Rn << 32)
687
               | (Rn << 24) | (Rn << 16) | (Rn << 8) | Rn;
688
      break;
689
 
690
    case Hqual:
691
      Rn &= 0xffff;
692
      wR [wRd] = (Rn << 48) | (Rn << 32) | (Rn << 16) | Rn;
693
      break;
694
 
695
    case Wqual:
696
      Rn &= 0xffffffff;
697
      wR [wRd] = (Rn << 32) | Rn;
698
      break;
699
 
700
    default:
701
      ARMul_UndefInstr (state, instr);
702
      break;
703
    }
704
 
705
  wC [wCon] |= WCON_MUP;
706
  return ARMul_DONE;
707
}
708
 
709
static int
710
TEXTRC (ARMul_State * state, ARMword instr)
711
{
712
  ARMword cpsr;
713
  ARMword selector;
714
 
715
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
716
    return ARMul_CANT;
717
 
718
#ifdef DEBUG
719
  fprintf (stderr, "textrc\n");
720
#endif  
721
 
722
  /* The Rd field must be r15.  */
723
  if (BITS (12, 15) != 15)
724
    return ARMul_CANT;
725
 
726
  /* The CRn field must be r3.  */
727
  if (BITS (16, 19) != 3)
728
    return ARMul_CANT;
729
 
730
  /* The CRm field must be 0xxx.  */
731
  if (BIT (3) != 0)
732
    return ARMul_CANT;
733
 
734
  selector = BITS (0, 2);
735
  cpsr = ARMul_GetCPSR (state) & 0x0fffffff;
736
 
737
  switch (BITS (22, 23))
738
    {
739
    case Bqual: selector *= 4; break;
740
    case Hqual: selector = ((selector & 3) * 8) + 4; break;
741
    case Wqual: selector = ((selector & 1) * 16) + 12; break;
742
 
743
    default:
744
      ARMul_UndefInstr (state, instr);
745
      return ARMul_DONE;
746
    }
747
 
748
  cpsr |= wCBITS (wCASF, selector, selector + 3) << 28;
749
  ARMul_SetCPSR (state, cpsr);
750
 
751
  return ARMul_DONE;
752
}
753
 
754
static int
755
TEXTRM (ARMul_State * state, ARMword instr)
756
{
757
  ARMword Rd;
758
  int     offset;
759
  int     wRn;
760
  int     sign;
761
 
762
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
763
    return ARMul_CANT;
764
 
765
#ifdef DEBUG
766
  fprintf (stderr, "textrm\n");
767
#endif  
768
 
769
  wRn    = BITS (16, 19);
770
  sign   = BIT (3);
771
  offset = BITS (0, 2);
772
 
773
  switch (BITS (22, 23))
774
    {
775
    case Bqual:
776
      offset *= 8;
777
      Rd = wRBITS (wRn, offset, offset + 7);
778
      if (sign)
779
        Rd = EXTEND8 (Rd);
780
      break;
781
 
782
    case Hqual:
783
      offset = (offset & 3) * 16;
784
      Rd = wRBITS (wRn, offset, offset + 15);
785
      if (sign)
786
        Rd = EXTEND16 (Rd);
787
      break;
788
 
789
    case Wqual:
790
      offset = (offset & 1) * 32;
791
      Rd = wRBITS (wRn, offset, offset + 31);
792
      break;
793
 
794
    default:
795
      ARMul_UndefInstr (state, instr);
796
      return ARMul_DONE;
797
    }
798
 
799
  if (BITS (12, 15) == 15)
800
    ARMul_UndefInstr (state, instr);
801
  else
802
    state->Reg [BITS (12, 15)] = Rd;
803
 
804
  return ARMul_DONE;
805
}
806
 
807
static int
808
TINSR (ARMul_State * state, ARMword instr)
809
{
810
  ARMdword data;
811
  ARMword  offset;
812
  int      wRd;
813
 
814
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
815
    return ARMul_CANT;
816
 
817
#ifdef DEBUG
818
  fprintf (stderr, "tinsr\n");
819
#endif
820
 
821
  wRd = BITS (16, 19);
822
  data = state->Reg [BITS (12, 15)];
823
  offset = BITS (0, 2);
824
 
825
  switch (BITS (6, 7))
826
    {
827
    case Bqual:
828
      data &= 0xff;
829
      switch (offset)
830
        {
831
        case 0: wR [wRd] = data | (wRBITS (wRd, 8, 63) << 8); break;
832
        case 1: wR [wRd] = wRBITS (wRd, 0,  7) | (data <<  8) | (wRBITS (wRd, 16, 63) << 16); break;
833
        case 2: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 24, 63) << 24); break;
834
        case 3: wR [wRd] = wRBITS (wRd, 0, 23) | (data << 24) | (wRBITS (wRd, 32, 63) << 32); break;
835
        case 4: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 40, 63) << 40); break;
836
        case 5: wR [wRd] = wRBITS (wRd, 0, 39) | (data << 40) | (wRBITS (wRd, 48, 63) << 48); break;
837
        case 6: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48) | (wRBITS (wRd, 56, 63) << 56); break;
838
        case 7: wR [wRd] = wRBITS (wRd, 0, 55) | (data << 56); break;
839
        }
840
      break;
841
 
842
    case Hqual:
843
      data &= 0xffff;
844
 
845
      switch (offset & 3)
846
        {
847
        case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break;
848
        case 1: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 32, 63) << 32); break;
849
        case 2: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 48, 63) << 48); break;
850
        case 3: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48); break;
851
        }
852
      break;
853
 
854
    case Wqual:
855
      if (offset & 1)
856
        wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32);
857
      else
858
        wR [wRd] = (wRBITS (wRd, 32, 63) << 32) | data;
859
      break;
860
 
861
    default:
862
      ARMul_UndefInstr (state, instr);
863
      break;
864
    }
865
 
866
  wC [wCon] |= WCON_MUP;
867
  return ARMul_DONE;
868
}
869
 
870
static int
871
TMCR (ARMul_State * state, ARMword instr)
872
{
873
  ARMword val;
874
  int     wCreg;
875
 
876
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
877
    return ARMul_CANT;
878
 
879
#ifdef DEBUG
880
  fprintf (stderr, "tmcr\n");
881
#endif  
882
 
883
  if (BITS (0, 3) != 0)
884
    return ARMul_CANT;
885
 
886
  val = state->Reg [BITS (12, 15)];
887
  if (BITS (12, 15) == 15)
888
    val &= 0xfffffffc;
889
 
890
  wCreg = BITS (16, 19);
891
 
892
  switch (wCreg)
893
    {
894
    case wCID:
895
      /* The wCID register is read only.  */
896
      break;
897
 
898
    case wCon:
899
      /* Writing to the MUP or CUP bits clears them.  */
900
      wC [wCon] &= ~ (val & 0x3);
901
      break;
902
 
903
    case wCSSF:
904
      /* Only the bottom 8 bits can be written to.
905
          The higher bits write as zero.  */
906
      wC [wCSSF] = (val & 0xff);
907
      wC [wCon] |= WCON_CUP;
908
      break;
909
 
910
    default:
911
      wC [wCreg] = val;
912
      wC [wCon] |= WCON_CUP;
913
      break;
914
    }
915
 
916
  return ARMul_DONE;
917
}
918
 
919
static int
920
TMCRR (ARMul_State * state, ARMword instr)
921
{
922
  ARMdword RdHi = state->Reg [BITS (16, 19)];
923
  ARMword  RdLo = state->Reg [BITS (12, 15)];
924
 
925
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
926
    return ARMul_CANT;
927
 
928
#ifdef DEBUG
929
  fprintf (stderr, "tmcrr\n");
930
#endif  
931
 
932
  if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
933
    return ARMul_CANT;
934
 
935
  wR [BITS (0, 3)] = (RdHi << 32) | RdLo;
936
 
937
  wC [wCon] |= WCON_MUP;
938
 
939
  return ARMul_DONE;
940
}
941
 
942
static int
943
TMIA (ARMul_State * state, ARMword instr)
944
{
945
  signed long long a, b;
946
 
947
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
948
    return ARMul_CANT;
949
 
950
#ifdef DEBUG
951
  fprintf (stderr, "tmia\n");
952
#endif  
953
 
954
  if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
955
    {
956
      ARMul_UndefInstr (state, instr);
957
      return ARMul_DONE;
958
    }
959
 
960
  a = state->Reg [BITS (0, 3)];
961
  b = state->Reg [BITS (12, 15)];
962
 
963
  a = EXTEND32 (a);
964
  b = EXTEND32 (b);
965
 
966
  wR [BITS (5, 8)] += a * b;
967
  wC [wCon] |= WCON_MUP;
968
 
969
  return ARMul_DONE;
970
}
971
 
972
static int
973
TMIAPH (ARMul_State * state, ARMword instr)
974
{
975
  signed long a, b, result;
976
  signed long long r;
977
  ARMword Rm = state->Reg [BITS (0, 3)];
978
  ARMword Rs = state->Reg [BITS (12, 15)];
979
 
980
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
981
    return ARMul_CANT;
982
 
983
#ifdef DEBUG
984
  fprintf (stderr, "tmiaph\n");
985
#endif  
986
 
987
  if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
988
    {
989
      ARMul_UndefInstr (state, instr);
990
      return ARMul_DONE;
991
    }
992
 
993
  a = SUBSTR (Rs, ARMword, 16, 31);
994
  b = SUBSTR (Rm, ARMword, 16, 31);
995
 
996
  a = EXTEND16 (a);
997
  b = EXTEND16 (b);
998
 
999
  result = a * b;
1000
 
1001
  r = result;
1002
  r = EXTEND32 (r);
1003
 
1004
  wR [BITS (5, 8)] += r;
1005
 
1006
  a = SUBSTR (Rs, ARMword,  0, 15);
1007
  b = SUBSTR (Rm, ARMword,  0, 15);
1008
 
1009
  a = EXTEND16 (a);
1010
  b = EXTEND16 (b);
1011
 
1012
  result = a * b;
1013
 
1014
  r = result;
1015
  r = EXTEND32 (r);
1016
 
1017
  wR [BITS (5, 8)] += r;
1018
  wC [wCon] |= WCON_MUP;
1019
 
1020
  return ARMul_DONE;
1021
}
1022
 
1023
static int
1024
TMIAxy (ARMul_State * state, ARMword instr)
1025
{
1026
  ARMword Rm;
1027
  ARMword Rs;
1028
  long long temp;
1029
 
1030
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1031
    return ARMul_CANT;
1032
 
1033
#ifdef DEBUG
1034
  fprintf (stderr, "tmiaxy\n");
1035
#endif  
1036
 
1037
  if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
1038
    {
1039
      ARMul_UndefInstr (state, instr);
1040
      return ARMul_DONE;
1041
    }
1042
 
1043
  Rm = state->Reg [BITS (0, 3)];
1044
  if (BIT (17))
1045
    Rm >>= 16;
1046
  else
1047
    Rm &= 0xffff;
1048
 
1049
  Rs = state->Reg [BITS (12, 15)];
1050
  if (BIT (16))
1051
    Rs >>= 16;
1052
  else
1053
    Rs &= 0xffff;
1054
 
1055
  if (Rm & (1 << 15))
1056
    Rm -= 1 << 16;
1057
 
1058
  if (Rs & (1 << 15))
1059
    Rs -= 1 << 16;
1060
 
1061
  Rm *= Rs;
1062
  temp = Rm;
1063
 
1064
  if (temp & (1 << 31))
1065
    temp -= 1ULL << 32;
1066
 
1067
  wR [BITS (5, 8)] += temp;
1068
  wC [wCon] |= WCON_MUP;
1069
 
1070
  return ARMul_DONE;
1071
}
1072
 
1073
static int
1074
TMOVMSK (ARMul_State * state, ARMword instr)
1075
{
1076
  ARMdword result;
1077
  int      wRn;
1078
 
1079
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1080
    return ARMul_CANT;
1081
 
1082
#ifdef DEBUG
1083
  fprintf (stderr, "tmovmsk\n");
1084
#endif  
1085
 
1086
  /* The CRm field must be r0.  */
1087
  if (BITS (0, 3) != 0)
1088
    return ARMul_CANT;
1089
 
1090
  wRn = BITS (16, 19);
1091
 
1092
  switch (BITS (22, 23))
1093
    {
1094
    case Bqual:
1095
      result = (  (wRBITS (wRn, 63, 63) << 7)
1096
                | (wRBITS (wRn, 55, 55) << 6)
1097
                | (wRBITS (wRn, 47, 47) << 5)
1098
                | (wRBITS (wRn, 39, 39) << 4)
1099
                | (wRBITS (wRn, 31, 31) << 3)
1100
                | (wRBITS (wRn, 23, 23) << 2)
1101
                | (wRBITS (wRn, 15, 15) << 1)
1102
                | (wRBITS (wRn,  7,  7) << 0));
1103
      break;
1104
 
1105
    case Hqual:
1106
      result = (  (wRBITS (wRn, 63, 63) << 3)
1107
                | (wRBITS (wRn, 47, 47) << 2)
1108
                | (wRBITS (wRn, 31, 31) << 1)
1109
                | (wRBITS (wRn, 15, 15) << 0));
1110
      break;
1111
 
1112
    case Wqual:
1113
      result = (wRBITS (wRn, 63, 63) << 1) | wRBITS (wRn, 31, 31);
1114
      break;
1115
 
1116
    default:
1117
      ARMul_UndefInstr (state, instr);
1118
      return ARMul_DONE;
1119
    }
1120
 
1121
  state->Reg [BITS (12, 15)] = result;
1122
 
1123
  return ARMul_DONE;
1124
}
1125
 
1126
static int
1127
TMRC (ARMul_State * state, ARMword instr)
1128
{
1129
  int reg = BITS (12, 15);
1130
 
1131
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1132
    return ARMul_CANT;
1133
 
1134
#ifdef DEBUG
1135
  fprintf (stderr, "tmrc\n");
1136
#endif  
1137
 
1138
  if (BITS (0, 3) != 0)
1139
    return ARMul_CANT;
1140
 
1141
  if (reg == 15)
1142
    ARMul_UndefInstr (state, instr);
1143
  else
1144
    state->Reg [reg] = wC [BITS (16, 19)];
1145
 
1146
  return ARMul_DONE;
1147
}
1148
 
1149
static int
1150
TMRRC (ARMul_State * state, ARMword instr)
1151
{
1152
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1153
    return ARMul_CANT;
1154
 
1155
#ifdef DEBUG
1156
  fprintf (stderr, "tmrrc\n");
1157
#endif  
1158
 
1159
  if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
1160
    ARMul_UndefInstr (state, instr);
1161
  else
1162
    {
1163
      state->Reg [BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63);
1164
      state->Reg [BITS (12, 15)] = wRBITS (BITS (0, 3),  0, 31);
1165
    }
1166
 
1167
  return ARMul_DONE;
1168
}
1169
 
1170
static int
1171
TORC (ARMul_State * state, ARMword instr)
1172
{
1173
  ARMword cpsr = ARMul_GetCPSR (state);
1174
 
1175
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1176
    return ARMul_CANT;
1177
 
1178
#ifdef DEBUG
1179
  fprintf (stderr, "torc\n");
1180
#endif  
1181
 
1182
  /* The Rd field must be r15.  */
1183
  if (BITS (12, 15) != 15)
1184
    return ARMul_CANT;
1185
 
1186
  /* The CRn field must be r3.  */
1187
  if (BITS (16, 19) != 3)
1188
    return ARMul_CANT;
1189
 
1190
  /* The CRm field must be r0.  */
1191
  if (BITS (0, 3) != 0)
1192
    return ARMul_CANT;
1193
 
1194
  cpsr &= 0x0fffffff;
1195
 
1196
  switch (BITS (22, 23))
1197
    {
1198
    case Bqual:
1199
      cpsr |= (  (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 24, 27)
1200
                | wCBITS (wCASF, 20, 23) | wCBITS (wCASF, 16, 19)
1201
                | wCBITS (wCASF, 12, 15) | wCBITS (wCASF,  8, 11)
1202
                | wCBITS (wCASF,  4,  7) | wCBITS (wCASF,  0,  3)) << 28);
1203
      break;
1204
 
1205
    case Hqual:
1206
      cpsr |= (  (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 20, 23)
1207
                | wCBITS (wCASF, 12, 15) | wCBITS (wCASF,  4,  7)) << 28);
1208
      break;
1209
 
1210
    case Wqual:
1211
      cpsr |= ((wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 12, 15)) << 28);
1212
      break;
1213
 
1214
    default:
1215
      ARMul_UndefInstr (state, instr);
1216
      return ARMul_DONE;
1217
    }
1218
 
1219
  ARMul_SetCPSR (state, cpsr);
1220
 
1221
  return ARMul_DONE;
1222
}
1223
 
1224
static int
1225
WACC (ARMul_State * state, ARMword instr)
1226
{
1227
  int wRn;
1228
 
1229
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1230
    return ARMul_CANT;
1231
 
1232
#ifdef DEBUG
1233
  fprintf (stderr, "wacc\n");
1234
#endif  
1235
 
1236
  wRn = BITS (16, 19);
1237
 
1238
  switch (BITS (22, 23))
1239
    {
1240
    case Bqual:
1241
      wR [BITS (12, 15)] =
1242
          wRBITS (wRn, 56, 63) + wRBITS (wRn, 48, 55)
1243
        + wRBITS (wRn, 40, 47) + wRBITS (wRn, 32, 39)
1244
        + wRBITS (wRn, 24, 31) + wRBITS (wRn, 16, 23)
1245
        + wRBITS (wRn,  8, 15) + wRBITS (wRn,  0,  7);
1246
      break;
1247
 
1248
    case Hqual:
1249
      wR [BITS (12, 15)] =
1250
          wRBITS (wRn, 48, 63) + wRBITS (wRn, 32, 47)
1251
        + wRBITS (wRn, 16, 31) + wRBITS (wRn,  0, 15);
1252
      break;
1253
 
1254
    case Wqual:
1255
      wR [BITS (12, 15)] = wRBITS (wRn, 32, 63) + wRBITS (wRn, 0, 31);
1256
      break;
1257
 
1258
    default:
1259
      ARMul_UndefInstr (state, instr);
1260
      break;
1261
    }
1262
 
1263
  wC [wCon] |= WCON_MUP;
1264
  return ARMul_DONE;
1265
}
1266
 
1267
static int
1268
WADD (ARMul_State * state, ARMword instr)
1269
{
1270
  ARMdword r = 0;
1271
  ARMdword x;
1272
  ARMdword s;
1273
  ARMword  psr = 0;
1274
  int      i;
1275
  int      carry;
1276
  int      overflow;
1277
  int      satrv[8];
1278
 
1279
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1280
    return ARMul_CANT;
1281
 
1282
#ifdef DEBUG
1283
  fprintf (stderr, "wadd\n");
1284
#endif  
1285
 
1286
  /* Add two numbers using the specified function,
1287
     leaving setting the carry bit as required.  */
1288
#define ADDx(x, y, m, f) \
1289
   (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
1290
         wRBITS (BITS ( 0,  3), (x), (y)) & (m), \
1291
        & carry, & overflow)
1292
 
1293
  switch (BITS (22, 23))
1294
    {
1295
    case Bqual:
1296
      for (i = 0; i < 8; i++)
1297
        {
1298
          switch (BITS (20, 21))
1299
            {
1300
            case NoSaturation:
1301
              s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8);
1302
              satrv [BITIDX8 (i)] = 0;
1303
              r |= (s & 0xff) << (i * 8);
1304
              SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1305
              SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1306
              SIMD8_SET (psr, carry,     SIMD_CBIT, i);
1307
              SIMD8_SET (psr, overflow,  SIMD_VBIT, i);
1308
              break;
1309
 
1310
            case UnsignedSaturation:
1311
              s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddU8);
1312
              x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i));
1313
              r |= (x & 0xff) << (i * 8);
1314
              SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
1315
              SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
1316
              if (! satrv [BITIDX8 (i)])
1317
                {
1318
                  SIMD8_SET (psr, carry,    SIMD_CBIT, i);
1319
                  SIMD8_SET (psr, overflow, SIMD_VBIT, i);
1320
                }
1321
              break;
1322
 
1323
            case SignedSaturation:
1324
              s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8);
1325
              x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i));
1326
              r |= (x & 0xff) << (i * 8);
1327
              SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
1328
              SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
1329
              if (! satrv [BITIDX8 (i)])
1330
                {
1331
                  SIMD8_SET (psr, carry,    SIMD_CBIT, i);
1332
                  SIMD8_SET (psr, overflow, SIMD_VBIT, i);
1333
                }
1334
              break;
1335
 
1336
            default:
1337
              ARMul_UndefInstr (state, instr);
1338
              return ARMul_DONE;
1339
            }
1340
        }
1341
      break;
1342
 
1343
    case Hqual:
1344
      satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
1345
 
1346
      for (i = 0; i < 4; i++)
1347
        {
1348
          switch (BITS (20, 21))
1349
            {
1350
            case NoSaturation:
1351
              s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16);
1352
              satrv [BITIDX16 (i)] = 0;
1353
              r |= (s & 0xffff) << (i * 16);
1354
              SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1355
              SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1356
              SIMD16_SET (psr, carry,      SIMD_CBIT, i);
1357
              SIMD16_SET (psr, overflow,   SIMD_VBIT, i);
1358
              break;
1359
 
1360
            case UnsignedSaturation:
1361
              s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddU16);
1362
              x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i));
1363
              r |= (x & 0xffff) << (i * 16);
1364
              SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
1365
              SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
1366
              if (! satrv [BITIDX16 (i)])
1367
                {
1368
                  SIMD16_SET (psr, carry,    SIMD_CBIT, i);
1369
                  SIMD16_SET (psr, overflow, SIMD_VBIT, i);
1370
                }
1371
              break;
1372
 
1373
            case SignedSaturation:
1374
              s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16);
1375
              x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i));
1376
              r |= (x & 0xffff) << (i * 16);
1377
              SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
1378
              SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
1379
              if (! satrv [BITIDX16 (i)])
1380
                {
1381
                  SIMD16_SET (psr, carry,    SIMD_CBIT, i);
1382
                  SIMD16_SET (psr, overflow, SIMD_VBIT, i);
1383
                }
1384
              break;
1385
 
1386
            default:
1387
              ARMul_UndefInstr (state, instr);
1388
              return ARMul_DONE;
1389
            }
1390
        }
1391
      break;
1392
 
1393
    case Wqual:
1394
      satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
1395
 
1396
      for (i = 0; i < 2; i++)
1397
        {
1398
          switch (BITS (20, 21))
1399
            {
1400
            case NoSaturation:
1401
              s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32);
1402
              satrv [BITIDX32 (i)] = 0;
1403
              r |= (s & 0xffffffff) << (i * 32);
1404
              SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1405
              SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1406
              SIMD32_SET (psr, carry,      SIMD_CBIT, i);
1407
              SIMD32_SET (psr, overflow,   SIMD_VBIT, i);
1408
              break;
1409
 
1410
            case UnsignedSaturation:
1411
              s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddU32);
1412
              x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i));
1413
              r |= (x & 0xffffffff) << (i * 32);
1414
              SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
1415
              SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
1416
              if (! satrv [BITIDX32 (i)])
1417
                {
1418
                  SIMD32_SET (psr, carry,    SIMD_CBIT, i);
1419
                  SIMD32_SET (psr, overflow, SIMD_VBIT, i);
1420
                }
1421
              break;
1422
 
1423
            case SignedSaturation:
1424
              s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32);
1425
              x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i));
1426
              r |= (x & 0xffffffff) << (i * 32);
1427
              SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
1428
              SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
1429
              if (! satrv [BITIDX32 (i)])
1430
                {
1431
                  SIMD32_SET (psr, carry,    SIMD_CBIT, i);
1432
                  SIMD32_SET (psr, overflow, SIMD_VBIT, i);
1433
                }
1434
              break;
1435
 
1436
            default:
1437
              ARMul_UndefInstr (state, instr);
1438
              return ARMul_DONE;
1439
            }
1440
        }
1441
      break;
1442
 
1443
    default:
1444
      ARMul_UndefInstr (state, instr);
1445
      return ARMul_DONE;
1446
    }
1447
 
1448
  wC [wCASF] = psr;
1449
  wR [BITS (12, 15)] = r;
1450
  wC [wCon] |= (WCON_MUP | WCON_CUP);
1451
 
1452
  SET_wCSSFvec (satrv);
1453
 
1454
#undef ADDx
1455
 
1456
  return ARMul_DONE;
1457
}
1458
 
1459
static int
1460
WALIGNI (ARMword instr)
1461
{
1462
  int shift = BITS (20, 22) * 8;
1463
 
1464
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1465
    return ARMul_CANT;
1466
 
1467
#ifdef DEBUG
1468
  fprintf (stderr, "waligni\n");
1469
#endif  
1470
 
1471
  if (shift)
1472
    wR [BITS (12, 15)] =
1473
      wRBITS (BITS (16, 19), shift, 63)
1474
      | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift)));
1475
  else
1476
    wR [BITS (12, 15)] = wR [BITS (16, 19)];
1477
 
1478
  wC [wCon] |= WCON_MUP;
1479
  return ARMul_DONE;
1480
}
1481
 
1482
static int
1483
WALIGNR (ARMul_State * state, ARMword instr)
1484
{
1485
  int shift = (wC [BITS (20, 21) + 8] & 0x7) * 8;
1486
 
1487
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1488
    return ARMul_CANT;
1489
 
1490
#ifdef DEBUG
1491
  fprintf (stderr, "walignr\n");
1492
#endif  
1493
 
1494
  if (shift)
1495
    wR [BITS (12, 15)] =
1496
      wRBITS (BITS (16, 19), shift, 63)
1497
      | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift)));
1498
  else
1499
    wR [BITS (12, 15)] = wR [BITS (16, 19)];
1500
 
1501
  wC [wCon] |= WCON_MUP;
1502
  return ARMul_DONE;
1503
}
1504
 
1505
static int
1506
WAND (ARMword instr)
1507
{
1508
  ARMdword result;
1509
  ARMword  psr = 0;
1510
 
1511
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1512
    return ARMul_CANT;
1513
 
1514
#ifdef DEBUG
1515
  fprintf (stderr, "wand\n");
1516
#endif  
1517
 
1518
  result = wR [BITS (16, 19)] & wR [BITS (0, 3)];
1519
  wR [BITS (12, 15)] = result;
1520
 
1521
  SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
1522
  SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
1523
 
1524
  wC [wCASF] = psr;
1525
  wC [wCon] |= (WCON_CUP | WCON_MUP);
1526
 
1527
  return ARMul_DONE;
1528
}
1529
 
1530
static int
1531
WANDN (ARMword instr)
1532
{
1533
  ARMdword result;
1534
  ARMword  psr = 0;
1535
 
1536
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1537
    return ARMul_CANT;
1538
 
1539
#ifdef DEBUG
1540
  fprintf (stderr, "wandn\n");
1541
#endif  
1542
 
1543
  result = wR [BITS (16, 19)] & ~ wR [BITS (0, 3)];
1544
  wR [BITS (12, 15)] = result;
1545
 
1546
  SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
1547
  SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
1548
 
1549
  wC [wCASF] = psr;
1550
  wC [wCon] |= (WCON_CUP | WCON_MUP);
1551
 
1552
  return ARMul_DONE;
1553
}
1554
 
1555
static int
1556
WAVG2 (ARMword instr)
1557
{
1558
  ARMdword r = 0;
1559
  ARMword  psr = 0;
1560
  ARMdword s;
1561
  int      i;
1562
  int      round = BIT (20) ? 1 : 0;
1563
 
1564
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1565
    return ARMul_CANT;
1566
 
1567
#ifdef DEBUG
1568
  fprintf (stderr, "wavg2\n");
1569
#endif  
1570
 
1571
#define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
1572
                       + (wRBITS (BITS ( 0,  3), (x), (y)) & (m)) \
1573
                       + round) / 2)
1574
 
1575
  if (BIT (22))
1576
    {
1577
      for (i = 0; i < 4; i++)
1578
        {
1579
          s = AVG2x ((i * 16), (i * 16) + 15, 0xffff) & 0xffff;
1580
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1581
          r |= s << (i * 16);
1582
        }
1583
    }
1584
  else
1585
    {
1586
      for (i = 0; i < 8; i++)
1587
        {
1588
          s = AVG2x ((i * 8), (i * 8) + 7, 0xff) & 0xff;
1589
          SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1590
          r |= s << (i * 8);
1591
        }
1592
    }
1593
 
1594
  wR [BITS (12, 15)] = r;
1595
  wC [wCASF] = psr;
1596
  wC [wCon] |= (WCON_CUP | WCON_MUP);
1597
 
1598
  return ARMul_DONE;
1599
}
1600
 
1601
static int
1602
WCMPEQ (ARMul_State * state, ARMword instr)
1603
{
1604
  ARMdword r = 0;
1605
  ARMword  psr = 0;
1606
  ARMdword s;
1607
  int      i;
1608
 
1609
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1610
    return ARMul_CANT;
1611
 
1612
#ifdef DEBUG
1613
  fprintf (stderr, "wcmpeq\n");
1614
#endif  
1615
 
1616
  switch (BITS (22, 23))
1617
    {
1618
    case Bqual:
1619
      for (i = 0; i < 8; i++)
1620
        {
1621
          s = wRBYTE (BITS (16, 19), i) == wRBYTE (BITS (0, 3), i) ? 0xff : 0;
1622
          r |= s << (i * 8);
1623
          SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1624
          SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1625
        }
1626
      break;
1627
 
1628
    case Hqual:
1629
      for (i = 0; i < 4; i++)
1630
        {
1631
          s = wRHALF (BITS (16, 19), i) == wRHALF (BITS (0, 3), i) ? 0xffff : 0;
1632
          r |= s << (i * 16);
1633
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1634
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1635
        }
1636
      break;
1637
 
1638
    case Wqual:
1639
      for (i = 0; i < 2; i++)
1640
        {
1641
          s = wRWORD (BITS (16, 19), i) == wRWORD (BITS (0, 3), i) ? 0xffffffff : 0;
1642
          r |= s << (i * 32);
1643
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1644
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1645
        }
1646
      break;
1647
 
1648
    default:
1649
      ARMul_UndefInstr (state, instr);
1650
      return ARMul_DONE;
1651
    }
1652
 
1653
  wC [wCASF] = psr;
1654
  wR [BITS (12, 15)] = r;
1655
  wC [wCon] |= (WCON_CUP | WCON_MUP);
1656
 
1657
  return ARMul_DONE;
1658
}
1659
 
1660
static int
1661
WCMPGT (ARMul_State * state, ARMword instr)
1662
{
1663
  ARMdword r = 0;
1664
  ARMword  psr = 0;
1665
  ARMdword s;
1666
  int      i;
1667
 
1668
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1669
    return ARMul_CANT;
1670
 
1671
#ifdef DEBUG
1672
  fprintf (stderr, "wcmpgt\n");
1673
#endif  
1674
 
1675
  switch (BITS (22, 23))
1676
    {
1677
    case Bqual:
1678
      if (BIT (21))
1679
        {
1680
          /* Use a signed comparison.  */
1681
          for (i = 0; i < 8; i++)
1682
            {
1683
              signed char a, b;
1684
 
1685
              a = wRBYTE (BITS (16, 19), i);
1686
              b = wRBYTE (BITS (0, 3), i);
1687
 
1688
              s = (a > b) ? 0xff : 0;
1689
              r |= s << (i * 8);
1690
              SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1691
              SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1692
            }
1693
        }
1694
      else
1695
        {
1696
          for (i = 0; i < 8; i++)
1697
            {
1698
              s = (wRBYTE (BITS (16, 19), i) > wRBYTE (BITS (0, 3), i))
1699
                ? 0xff : 0;
1700
              r |= s << (i * 8);
1701
              SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1702
              SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1703
            }
1704
        }
1705
      break;
1706
 
1707
    case Hqual:
1708
      if (BIT (21))
1709
        {
1710
          for (i = 0; i < 4; i++)
1711
            {
1712
              signed int a, b;
1713
 
1714
              a = wRHALF (BITS (16, 19), i);
1715
              a = EXTEND16 (a);
1716
 
1717
              b = wRHALF (BITS (0, 3), i);
1718
              b = EXTEND16 (b);
1719
 
1720
              s = (a > b) ? 0xffff : 0;
1721
              r |= s << (i * 16);
1722
              SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1723
              SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1724
            }
1725
        }
1726
      else
1727
        {
1728
          for (i = 0; i < 4; i++)
1729
            {
1730
              s = (wRHALF (BITS (16, 19), i) > wRHALF (BITS (0, 3), i))
1731
                ? 0xffff : 0;
1732
              r |= s << (i * 16);
1733
              SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1734
              SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1735
            }
1736
        }
1737
      break;
1738
 
1739
    case Wqual:
1740
      if (BIT (21))
1741
        {
1742
          for (i = 0; i < 2; i++)
1743
            {
1744
              signed long a, b;
1745
 
1746
              a = wRWORD (BITS (16, 19), i);
1747
              b = wRWORD (BITS (0, 3), i);
1748
 
1749
              s = (a > b) ? 0xffffffff : 0;
1750
              r |= s << (i * 32);
1751
              SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1752
              SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1753
            }
1754
        }
1755
      else
1756
        {
1757
          for (i = 0; i < 2; i++)
1758
            {
1759
              s = (wRWORD (BITS (16, 19), i) > wRWORD (BITS (0, 3), i))
1760
                ? 0xffffffff : 0;
1761
              r |= s << (i * 32);
1762
              SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1763
              SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1764
            }
1765
        }
1766
      break;
1767
 
1768
    default:
1769
      ARMul_UndefInstr (state, instr);
1770
      return ARMul_DONE;
1771
    }
1772
 
1773
  wC [wCASF] = psr;
1774
  wR [BITS (12, 15)] = r;
1775
  wC [wCon] |= (WCON_CUP | WCON_MUP);
1776
 
1777
  return ARMul_DONE;
1778
}
1779
 
1780
static ARMword
1781
Compute_Iwmmxt_Address (ARMul_State * state, ARMword instr, int * pFailed)
1782
{
1783
  ARMword  Rn;
1784
  ARMword  addr;
1785
  ARMword  offset;
1786
  ARMword  multiplier;
1787
 
1788
  * pFailed  = 0;
1789
  Rn         = BITS (16, 19);
1790
  addr       = state->Reg [Rn];
1791
  offset     = BITS (0, 7);
1792
  multiplier = BIT (8) ? 4 : 1;
1793
 
1794
  if (BIT (24)) /* P */
1795
    {
1796
      /* Pre Indexed Addressing.  */
1797
      if (BIT (23))
1798
        addr += offset * multiplier;
1799
      else
1800
        addr -= offset * multiplier;
1801
 
1802
      /* Immediate Pre-Indexed.  */
1803
      if (BIT (21)) /* W */
1804
        {
1805
          if (Rn == 15)
1806
            {
1807
              /* Writeback into R15 is UNPREDICTABLE.  */
1808
#ifdef DEBUG
1809
              fprintf (stderr, "iWMMXt: writeback into r15\n");
1810
#endif
1811
              * pFailed = 1;
1812
            }
1813
          else
1814
            state->Reg [Rn] = addr;
1815
        }
1816
    }
1817
  else
1818
    {
1819
      /* Post Indexed Addressing.  */
1820
      if (BIT (21)) /* W */
1821
        {
1822
          /* Handle the write back of the final address.  */
1823
          if (Rn == 15)
1824
            {
1825
              /* Writeback into R15 is UNPREDICTABLE.  */
1826
#ifdef DEBUG
1827
              fprintf (stderr, "iWMMXt: writeback into r15\n");
1828
#endif  
1829
              * pFailed = 1;
1830
            }
1831
          else
1832
            {
1833
              ARMword  increment;
1834
 
1835
              if (BIT (23))
1836
                increment = offset * multiplier;
1837
              else
1838
                increment = - (offset * multiplier);
1839
 
1840
              state->Reg [Rn] = addr + increment;
1841
            }
1842
        }
1843
      else
1844
        {
1845
          /* P == 0, W == 0, U == 0 is UNPREDICTABLE.  */
1846
          if (BIT (23) == 0)
1847
            {
1848
#ifdef DEBUG
1849
              fprintf (stderr, "iWMMXt: undefined addressing mode\n");
1850
#endif  
1851
              * pFailed = 1;
1852
            }
1853
        }
1854
    }
1855
 
1856
  return addr;
1857
}
1858
 
1859
static ARMdword
1860
Iwmmxt_Load_Double_Word (ARMul_State * state, ARMword address)
1861
{
1862
  ARMdword value;
1863
 
1864
  /* The address must be aligned on a 8 byte boundary.  */
1865
  if (address & 0x7)
1866
    {
1867
      fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1868
               (state->Reg[15] - 8) & ~0x3, address);
1869
#ifdef DEBUG
1870
#endif
1871
      /* No need to check for alignment traps.  An unaligned
1872
         double word load with alignment trapping disabled is
1873
         UNPREDICTABLE.  */
1874
      ARMul_Abort (state, ARMul_DataAbortV);
1875
    }
1876
 
1877
  /* Load the words.  */
1878
  if (! state->bigendSig)
1879
    {
1880
      value = ARMul_LoadWordN (state, address + 4);
1881
      value <<= 32;
1882
      value |= ARMul_LoadWordN (state, address);
1883
    }
1884
  else
1885
    {
1886
      value = ARMul_LoadWordN (state, address);
1887
      value <<= 32;
1888
      value |= ARMul_LoadWordN (state, address + 4);
1889
    }
1890
 
1891
  /* Check for data aborts.  */
1892
  if (state->Aborted)
1893
    ARMul_Abort (state, ARMul_DataAbortV);
1894
  else
1895
    ARMul_Icycles (state, 2, 0L);
1896
 
1897
  return value;
1898
}
1899
 
1900
static ARMword
1901
Iwmmxt_Load_Word (ARMul_State * state, ARMword address)
1902
{
1903
  ARMword value;
1904
 
1905
  /* Check for a misaligned address.  */
1906
  if (address & 3)
1907
    {
1908
      if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1909
        ARMul_Abort (state, ARMul_DataAbortV);
1910
      else
1911
        address &= ~ 3;
1912
    }
1913
 
1914
  value = ARMul_LoadWordN (state, address);
1915
 
1916
  if (state->Aborted)
1917
    ARMul_Abort (state, ARMul_DataAbortV);
1918
  else
1919
    ARMul_Icycles (state, 1, 0L);
1920
 
1921
  return value;
1922
}
1923
 
1924
static ARMword
1925
Iwmmxt_Load_Half_Word (ARMul_State * state, ARMword address)
1926
{
1927
  ARMword value;
1928
 
1929
  /* Check for a misaligned address.  */
1930
  if (address & 1)
1931
    {
1932
      if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1933
        ARMul_Abort (state, ARMul_DataAbortV);
1934
      else
1935
        address &= ~ 1;
1936
    }
1937
 
1938
  value = ARMul_LoadHalfWord (state, address);
1939
 
1940
  if (state->Aborted)
1941
    ARMul_Abort (state, ARMul_DataAbortV);
1942
  else
1943
    ARMul_Icycles (state, 1, 0L);
1944
 
1945
  return value;
1946
}
1947
 
1948
static ARMword
1949
Iwmmxt_Load_Byte (ARMul_State * state, ARMword address)
1950
{
1951
  ARMword value;
1952
 
1953
  value = ARMul_LoadByte (state, address);
1954
 
1955
  if (state->Aborted)
1956
    ARMul_Abort (state, ARMul_DataAbortV);
1957
  else
1958
    ARMul_Icycles (state, 1, 0L);
1959
 
1960
  return value;
1961
}
1962
 
1963
static void
1964
Iwmmxt_Store_Double_Word (ARMul_State * state, ARMword address, ARMdword value)
1965
{
1966
  /* The address must be aligned on a 8 byte boundary.  */
1967
  if (address & 0x7)
1968
    {
1969
      fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1970
               (state->Reg[15] - 8) & ~0x3, address);
1971
#ifdef DEBUG
1972
#endif
1973
      /* No need to check for alignment traps.  An unaligned
1974
         double word store with alignment trapping disabled is
1975
         UNPREDICTABLE.  */
1976
      ARMul_Abort (state, ARMul_DataAbortV);
1977
    }
1978
 
1979
  /* Store the words.  */
1980
  if (! state->bigendSig)
1981
    {
1982
      ARMul_StoreWordN (state, address, value);
1983
      ARMul_StoreWordN (state, address + 4, value >> 32);
1984
    }
1985
  else
1986
    {
1987
      ARMul_StoreWordN (state, address + 4, value);
1988
      ARMul_StoreWordN (state, address, value >> 32);
1989
    }
1990
 
1991
  /* Check for data aborts.  */
1992
  if (state->Aborted)
1993
    ARMul_Abort (state, ARMul_DataAbortV);
1994
  else
1995
    ARMul_Icycles (state, 2, 0L);
1996
}
1997
 
1998
static void
1999
Iwmmxt_Store_Word (ARMul_State * state, ARMword address, ARMword value)
2000
{
2001
  /* Check for a misaligned address.  */
2002
  if (address & 3)
2003
    {
2004
      if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2005
        ARMul_Abort (state, ARMul_DataAbortV);
2006
      else
2007
        address &= ~ 3;
2008
    }
2009
 
2010
  ARMul_StoreWordN (state, address, value);
2011
 
2012
  if (state->Aborted)
2013
    ARMul_Abort (state, ARMul_DataAbortV);
2014
}
2015
 
2016
static void
2017
Iwmmxt_Store_Half_Word (ARMul_State * state, ARMword address, ARMword value)
2018
{
2019
  /* Check for a misaligned address.  */
2020
  if (address & 1)
2021
    {
2022
      if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2023
        ARMul_Abort (state, ARMul_DataAbortV);
2024
      else
2025
        address &= ~ 1;
2026
    }
2027
 
2028
  ARMul_StoreHalfWord (state, address, value);
2029
 
2030
  if (state->Aborted)
2031
    ARMul_Abort (state, ARMul_DataAbortV);
2032
}
2033
 
2034
static void
2035
Iwmmxt_Store_Byte (ARMul_State * state, ARMword address, ARMword value)
2036
{
2037
  ARMul_StoreByte (state, address, value);
2038
 
2039
  if (state->Aborted)
2040
    ARMul_Abort (state, ARMul_DataAbortV);
2041
}
2042
 
2043
static int
2044
WLDR (ARMul_State * state, ARMword instr)
2045
{
2046
  ARMword address;
2047
  int failed;
2048
 
2049
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2050
    return ARMul_CANT;
2051
 
2052
#ifdef DEBUG
2053
  fprintf (stderr, "wldr\n");
2054
#endif  
2055
 
2056
  address = Compute_Iwmmxt_Address (state, instr, & failed);
2057
  if (failed)
2058
    return ARMul_CANT;
2059
 
2060
  if (BITS (28, 31) == 0xf)
2061
    {
2062
      /* WLDRW wCx */
2063
      wC [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2064
    }
2065
  else if (BIT (8) == 0)
2066
    {
2067
      if (BIT (22) == 0)
2068
        /* WLDRB */
2069
        wR [BITS (12, 15)] = Iwmmxt_Load_Byte (state, address);
2070
      else
2071
        /* WLDRH */
2072
        wR [BITS (12, 15)] = Iwmmxt_Load_Half_Word (state, address);
2073
    }
2074
  else
2075
    {
2076
      if (BIT (22) == 0)
2077
        /* WLDRW wRd */
2078
        wR [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2079
      else
2080
        /* WLDRD */
2081
        wR [BITS (12, 15)] = Iwmmxt_Load_Double_Word (state, address);
2082
    }
2083
 
2084
  wC [wCon] |= WCON_MUP;
2085
 
2086
  return ARMul_DONE;
2087
}
2088
 
2089
static int
2090
WMAC (ARMword instr)
2091
{
2092
  int      i;
2093
  ARMdword t = 0;
2094
  ARMword  a, b;
2095
 
2096
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2097
    return ARMul_CANT;
2098
 
2099
#ifdef DEBUG
2100
  fprintf (stderr, "wmac\n");
2101
#endif  
2102
 
2103
  for (i = 0; i < 4; i++)
2104
    {
2105
      if (BIT (21))
2106
        {
2107
          /* Signed.  */
2108
          signed long s;
2109
 
2110
          a = wRHALF (BITS (16, 19), i);
2111
          a = EXTEND16 (a);
2112
 
2113
          b = wRHALF (BITS (0, 3), i);
2114
          b = EXTEND16 (b);
2115
 
2116
          s = (signed long) a * (signed long) b;
2117
 
2118
          t = t + (ARMdword) s;
2119
        }
2120
      else
2121
        {
2122
          /* Unsigned.  */
2123
          a = wRHALF (BITS (16, 19), i);
2124
          b = wRHALF (BITS ( 0,  3), i);
2125
 
2126
          t += a * b;
2127
        }
2128
    }
2129
 
2130
  if (BIT (20))
2131
    wR [BITS (12, 15)] = 0;
2132
 
2133
  if (BIT (21)) /* Signed.  */
2134
    wR[BITS (12, 15)] += t;
2135
  else
2136
    wR [BITS (12, 15)] += t;
2137
 
2138
  wC [wCon] |= WCON_MUP;
2139
 
2140
  return ARMul_DONE;
2141
}
2142
 
2143
static int
2144
WMADD (ARMword instr)
2145
{
2146
  ARMdword r = 0;
2147
  int i;
2148
 
2149
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2150
    return ARMul_CANT;
2151
 
2152
#ifdef DEBUG
2153
  fprintf (stderr, "wmadd\n");
2154
#endif  
2155
 
2156
  for (i = 0; i < 2; i++)
2157
    {
2158
      ARMdword s1, s2;
2159
 
2160
      if (BIT (21))     /* Signed.  */
2161
        {
2162
          signed long a, b;
2163
 
2164
          a = wRHALF (BITS (16, 19), i * 2);
2165
          a = EXTEND16 (a);
2166
 
2167
          b = wRHALF (BITS (0, 3), i * 2);
2168
          b = EXTEND16 (b);
2169
 
2170
          s1 = (ARMdword) (a * b);
2171
 
2172
          a = wRHALF (BITS (16, 19), i * 2 + 1);
2173
          a = EXTEND16 (a);
2174
 
2175
          b = wRHALF (BITS (0, 3), i * 2 + 1);
2176
          b = EXTEND16 (b);
2177
 
2178
          s2 = (ARMdword) (a * b);
2179
        }
2180
      else                      /* Unsigned.  */
2181
        {
2182
          unsigned long a, b;
2183
 
2184
          a = wRHALF (BITS (16, 19), i * 2);
2185
          b = wRHALF (BITS ( 0,  3), i * 2);
2186
 
2187
          s1 = (ARMdword) (a * b);
2188
 
2189
          a = wRHALF (BITS (16, 19), i * 2 + 1);
2190
          b = wRHALF (BITS ( 0,  3), i * 2 + 1);
2191
 
2192
          s2 = (ARMdword) a * b;
2193
        }
2194
 
2195
      r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0);
2196
    }
2197
 
2198
  wR [BITS (12, 15)] = r;
2199
  wC [wCon] |= WCON_MUP;
2200
 
2201
  return ARMul_DONE;
2202
}
2203
 
2204
static int
2205
WMAX (ARMul_State * state, ARMword instr)
2206
{
2207
  ARMdword r = 0;
2208
  ARMdword s;
2209
  int      i;
2210
 
2211
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2212
    return ARMul_CANT;
2213
 
2214
#ifdef DEBUG
2215
  fprintf (stderr, "wmax\n");
2216
#endif  
2217
 
2218
  switch (BITS (22, 23))
2219
    {
2220
    case Bqual:
2221
      for (i = 0; i < 8; i++)
2222
        if (BIT (21))   /* Signed.  */
2223
          {
2224
            int a, b;
2225
 
2226
            a = wRBYTE (BITS (16, 19), i);
2227
            a = EXTEND8 (a);
2228
 
2229
            b = wRBYTE (BITS (0, 3), i);
2230
            b = EXTEND8 (b);
2231
 
2232
            if (a > b)
2233
              s = a;
2234
            else
2235
              s = b;
2236
 
2237
            r |= (s & 0xff) << (i * 8);
2238
          }
2239
        else            /* Unsigned.  */
2240
          {
2241
            unsigned int a, b;
2242
 
2243
            a = wRBYTE (BITS (16, 19), i);
2244
            b = wRBYTE (BITS (0, 3), i);
2245
 
2246
            if (a > b)
2247
              s = a;
2248
            else
2249
              s = b;
2250
 
2251
            r |= (s & 0xff) << (i * 8);
2252
          }
2253
      break;
2254
 
2255
    case Hqual:
2256
      for (i = 0; i < 4; i++)
2257
        if (BIT (21))   /* Signed.  */
2258
          {
2259
            int a, b;
2260
 
2261
            a = wRHALF (BITS (16, 19), i);
2262
            a = EXTEND16 (a);
2263
 
2264
            b = wRHALF (BITS (0, 3), i);
2265
            b = EXTEND16 (b);
2266
 
2267
            if (a > b)
2268
              s = a;
2269
            else
2270
              s = b;
2271
 
2272
            r |= (s & 0xffff) << (i * 16);
2273
          }
2274
        else            /* Unsigned.  */
2275
          {
2276
            unsigned int a, b;
2277
 
2278
            a = wRHALF (BITS (16, 19), i);
2279
            b = wRHALF (BITS (0, 3), i);
2280
 
2281
            if (a > b)
2282
              s = a;
2283
            else
2284
              s = b;
2285
 
2286
            r |= (s & 0xffff) << (i * 16);
2287
          }
2288
      break;
2289
 
2290
    case Wqual:
2291
      for (i = 0; i < 2; i++)
2292
        if (BIT (21))   /* Signed.  */
2293
          {
2294
            int a, b;
2295
 
2296
            a = wRWORD (BITS (16, 19), i);
2297
            b = wRWORD (BITS (0, 3), i);
2298
 
2299
            if (a > b)
2300
              s = a;
2301
            else
2302
              s = b;
2303
 
2304
            r |= (s & 0xffffffff) << (i * 32);
2305
          }
2306
        else
2307
          {
2308
            unsigned int a, b;
2309
 
2310
            a = wRWORD (BITS (16, 19), i);
2311
            b = wRWORD (BITS (0, 3), i);
2312
 
2313
            if (a > b)
2314
              s = a;
2315
            else
2316
              s = b;
2317
 
2318
            r |= (s & 0xffffffff) << (i * 32);
2319
          }
2320
      break;
2321
 
2322
    default:
2323
      ARMul_UndefInstr (state, instr);
2324
      return ARMul_DONE;
2325
    }
2326
 
2327
  wR [BITS (12, 15)] = r;
2328
  wC [wCon] |= WCON_MUP;
2329
 
2330
  return ARMul_DONE;
2331
}
2332
 
2333
static int
2334
WMIN (ARMul_State * state, ARMword instr)
2335
{
2336
  ARMdword r = 0;
2337
  ARMdword s;
2338
  int      i;
2339
 
2340
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2341
    return ARMul_CANT;
2342
 
2343
#ifdef DEBUG
2344
  fprintf (stderr, "wmin\n");
2345
#endif  
2346
 
2347
  switch (BITS (22, 23))
2348
    {
2349
    case Bqual:
2350
      for (i = 0; i < 8; i++)
2351
        if (BIT (21))   /* Signed.  */
2352
          {
2353
            int a, b;
2354
 
2355
            a = wRBYTE (BITS (16, 19), i);
2356
            a = EXTEND8 (a);
2357
 
2358
            b = wRBYTE (BITS (0, 3), i);
2359
            b = EXTEND8 (b);
2360
 
2361
            if (a < b)
2362
              s = a;
2363
            else
2364
              s = b;
2365
 
2366
            r |= (s & 0xff) << (i * 8);
2367
          }
2368
        else            /* Unsigned.  */
2369
          {
2370
            unsigned int a, b;
2371
 
2372
            a = wRBYTE (BITS (16, 19), i);
2373
            b = wRBYTE (BITS (0, 3), i);
2374
 
2375
            if (a < b)
2376
              s = a;
2377
            else
2378
              s = b;
2379
 
2380
            r |= (s & 0xff) << (i * 8);
2381
          }
2382
      break;
2383
 
2384
    case Hqual:
2385
      for (i = 0; i < 4; i++)
2386
        if (BIT (21))   /* Signed.  */
2387
          {
2388
            int a, b;
2389
 
2390
            a = wRHALF (BITS (16, 19), i);
2391
            a = EXTEND16 (a);
2392
 
2393
            b = wRHALF (BITS (0, 3), i);
2394
            b = EXTEND16 (b);
2395
 
2396
            if (a < b)
2397
              s = a;
2398
            else
2399
              s = b;
2400
 
2401
            r |= (s & 0xffff) << (i * 16);
2402
          }
2403
        else
2404
          {
2405
            /* Unsigned.  */
2406
            unsigned int a, b;
2407
 
2408
            a = wRHALF (BITS (16, 19), i);
2409
            b = wRHALF (BITS ( 0,  3), i);
2410
 
2411
            if (a < b)
2412
              s = a;
2413
            else
2414
              s = b;
2415
 
2416
            r |= (s & 0xffff) << (i * 16);
2417
          }
2418
      break;
2419
 
2420
    case Wqual:
2421
      for (i = 0; i < 2; i++)
2422
        if (BIT (21))   /* Signed.  */
2423
          {
2424
            int a, b;
2425
 
2426
            a = wRWORD (BITS (16, 19), i);
2427
            b = wRWORD (BITS ( 0,  3), i);
2428
 
2429
            if (a < b)
2430
              s = a;
2431
            else
2432
              s = b;
2433
 
2434
            r |= (s & 0xffffffff) << (i * 32);
2435
          }
2436
        else
2437
          {
2438
            unsigned int a, b;
2439
 
2440
            a = wRWORD (BITS (16, 19), i);
2441
            b = wRWORD (BITS (0, 3), i);
2442
 
2443
            if (a < b)
2444
              s = a;
2445
            else
2446
              s = b;
2447
 
2448
            r |= (s & 0xffffffff) << (i * 32);
2449
          }
2450
      break;
2451
 
2452
    default:
2453
      ARMul_UndefInstr (state, instr);
2454
      return ARMul_DONE;
2455
    }
2456
 
2457
  wR [BITS (12, 15)] = r;
2458
  wC [wCon] |= WCON_MUP;
2459
 
2460
  return ARMul_DONE;
2461
}
2462
 
2463
static int
2464
WMUL (ARMword instr)
2465
{
2466
  ARMdword r = 0;
2467
  ARMdword s;
2468
  int      i;
2469
 
2470
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2471
    return ARMul_CANT;
2472
 
2473
#ifdef DEBUG
2474
  fprintf (stderr, "wmul\n");
2475
#endif  
2476
 
2477
  for (i = 0; i < 4; i++)
2478
    if (BIT (21))       /* Signed.  */
2479
      {
2480
        long a, b;
2481
 
2482
        a = wRHALF (BITS (16, 19), i);
2483
        a = EXTEND16 (a);
2484
 
2485
        b = wRHALF (BITS (0, 3), i);
2486
        b = EXTEND16 (b);
2487
 
2488
        s = a * b;
2489
 
2490
        if (BIT (20))
2491
          r |= ((s >> 16) & 0xffff) << (i * 16);
2492
        else
2493
          r |= (s & 0xffff) << (i * 16);
2494
      }
2495
    else                /* Unsigned.  */
2496
      {
2497
        unsigned long a, b;
2498
 
2499
        a = wRHALF (BITS (16, 19), i);
2500
        b = wRHALF (BITS (0, 3), i);
2501
 
2502
        s = a * b;
2503
 
2504
        if (BIT (20))
2505
          r |= ((s >> 16) & 0xffff) << (i * 16);
2506
        else
2507
          r |= (s & 0xffff) << (i * 16);
2508
      }
2509
 
2510
  wR [BITS (12, 15)] = r;
2511
  wC [wCon] |= WCON_MUP;
2512
 
2513
  return ARMul_DONE;
2514
}
2515
 
2516
static int
2517
WOR (ARMword instr)
2518
{
2519
  ARMword psr = 0;
2520
  ARMdword result;
2521
 
2522
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2523
    return ARMul_CANT;
2524
 
2525
#ifdef DEBUG
2526
  fprintf (stderr, "wor\n");
2527
#endif  
2528
 
2529
  result = wR [BITS (16, 19)] | wR [BITS (0, 3)];
2530
  wR [BITS (12, 15)] = result;
2531
 
2532
  SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
2533
  SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
2534
 
2535
  wC [wCASF] = psr;
2536
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2537
 
2538
  return ARMul_DONE;
2539
}
2540
 
2541
static int
2542
WPACK (ARMul_State * state, ARMword instr)
2543
{
2544
  ARMdword r = 0;
2545
  ARMword  psr = 0;
2546
  ARMdword x;
2547
  ARMdword s;
2548
  int      i;
2549
  int      satrv[8];
2550
 
2551
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2552
    return ARMul_CANT;
2553
 
2554
#ifdef DEBUG
2555
  fprintf (stderr, "wpack\n");
2556
#endif  
2557
 
2558
  switch (BITS (22, 23))
2559
    {
2560
    case Hqual:
2561
      for (i = 0; i < 8; i++)
2562
        {
2563
          x = wRHALF (i < 4 ? BITS (16, 19) : BITS (0, 3), i & 3);
2564
 
2565
          switch (BITS (20, 21))
2566
            {
2567
            case UnsignedSaturation:
2568
              s = IwmmxtSaturateU8 (x, satrv + BITIDX8 (i));
2569
              break;
2570
 
2571
            case SignedSaturation:
2572
              s = IwmmxtSaturateS8 (x, satrv + BITIDX8 (i));
2573
              break;
2574
 
2575
            default:
2576
              ARMul_UndefInstr (state, instr);
2577
              return ARMul_DONE;
2578
            }
2579
 
2580
          r |= (s & 0xff) << (i * 8);
2581
          SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
2582
          SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
2583
        }
2584
      break;
2585
 
2586
    case Wqual:
2587
      satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
2588
 
2589
      for (i = 0; i < 4; i++)
2590
        {
2591
          x = wRWORD (i < 2 ? BITS (16, 19) : BITS (0, 3), i & 1);
2592
 
2593
          switch (BITS (20, 21))
2594
            {
2595
            case UnsignedSaturation:
2596
              s = IwmmxtSaturateU16 (x, satrv + BITIDX16 (i));
2597
              break;
2598
 
2599
            case SignedSaturation:
2600
              s = IwmmxtSaturateS16 (x, satrv + BITIDX16 (i));
2601
              break;
2602
 
2603
            default:
2604
              ARMul_UndefInstr (state, instr);
2605
              return ARMul_DONE;
2606
            }
2607
 
2608
          r |= (s & 0xffff) << (i * 16);
2609
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2610
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2611
        }
2612
      break;
2613
 
2614
    case Dqual:
2615
      satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
2616
 
2617
      for (i = 0; i < 2; i++)
2618
        {
2619
          x = wR [i ? BITS (0, 3) : BITS (16, 19)];
2620
 
2621
          switch (BITS (20, 21))
2622
            {
2623
            case UnsignedSaturation:
2624
              s = IwmmxtSaturateU32 (x, satrv + BITIDX32 (i));
2625
              break;
2626
 
2627
            case SignedSaturation:
2628
              s = IwmmxtSaturateS32 (x, satrv + BITIDX32 (i));
2629
              break;
2630
 
2631
            default:
2632
              ARMul_UndefInstr (state, instr);
2633
              return ARMul_DONE;
2634
            }
2635
 
2636
          r |= (s & 0xffffffff) << (i * 32);
2637
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2638
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2639
        }
2640
      break;
2641
 
2642
    default:
2643
      ARMul_UndefInstr (state, instr);
2644
      return ARMul_DONE;
2645
    }
2646
 
2647
  wC [wCASF] = psr;
2648
  wR [BITS (12, 15)] = r;
2649
  SET_wCSSFvec (satrv);
2650
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2651
 
2652
  return ARMul_DONE;
2653
}
2654
 
2655
static int
2656
WROR (ARMul_State * state, ARMword instr)
2657
{
2658
  ARMdword r = 0;
2659
  ARMdword s;
2660
  ARMword  psr = 0;
2661
  int      i;
2662
  int      shift;
2663
 
2664
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2665
    return ARMul_CANT;
2666
 
2667
#ifdef DEBUG
2668
  fprintf (stderr, "wror\n");
2669
#endif  
2670
 
2671
  DECODE_G_BIT (state, instr, shift);
2672
 
2673
  switch (BITS (22, 23))
2674
    {
2675
    case Hqual:
2676
      shift &= 0xf;
2677
      for (i = 0; i < 4; i++)
2678
        {
2679
          s = ((wRHALF (BITS (16, 19), i) & 0xffff) << (16 - shift))
2680
            | ((wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2681
          r |= (s & 0xffff) << (i * 16);
2682
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2683
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2684
        }
2685
      break;
2686
 
2687
    case Wqual:
2688
      shift &= 0x1f;
2689
      for (i = 0; i < 2; i++)
2690
        {
2691
          s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << (32 - shift))
2692
            | ((wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2693
          r |= (s & 0xffffffff) << (i * 32);
2694
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2695
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2696
        }
2697
      break;
2698
 
2699
    case Dqual:
2700
      shift &= 0x3f;
2701
      r = (wR [BITS (16, 19)] >> shift)
2702
        | (wR [BITS (16, 19)] << (64 - shift));
2703
 
2704
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2705
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2706
      break;
2707
 
2708
    default:
2709
      ARMul_UndefInstr (state, instr);
2710
      return ARMul_DONE;
2711
    }
2712
 
2713
  wC [wCASF] = psr;
2714
  wR [BITS (12, 15)] = r;
2715
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2716
 
2717
  return ARMul_DONE;
2718
}
2719
 
2720
static int
2721
WSAD (ARMword instr)
2722
{
2723
  ARMdword r;
2724
  int      s;
2725
  int      i;
2726
 
2727
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2728
    return ARMul_CANT;
2729
 
2730
#ifdef DEBUG
2731
  fprintf (stderr, "wsad\n");
2732
#endif  
2733
 
2734
  /* Z bit.  */
2735
  r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff);
2736
 
2737
  if (BIT (22))
2738
    /* Half.  */
2739
    for (i = 0; i < 4; i++)
2740
      {
2741
        s = (wRHALF (BITS (16, 19), i) - wRHALF (BITS (0, 3), i));
2742
        r += abs (s);
2743
      }
2744
  else
2745
    /* Byte.  */
2746
    for (i = 0; i < 8; i++)
2747
      {
2748
        s = (wRBYTE (BITS (16, 19), i) - wRBYTE (BITS (0, 3), i));
2749
        r += abs (s);
2750
      }
2751
 
2752
  wR [BITS (12, 15)] = r;
2753
  wC [wCon] |= WCON_MUP;
2754
 
2755
  return ARMul_DONE;
2756
}
2757
 
2758
static int
2759
WSHUFH (ARMword instr)
2760
{
2761
  ARMdword r = 0;
2762
  ARMword  psr = 0;
2763
  ARMdword s;
2764
  int      i;
2765
  int      imm8;
2766
 
2767
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2768
    return ARMul_CANT;
2769
 
2770
#ifdef DEBUG
2771
  fprintf (stderr, "wshufh\n");
2772
#endif  
2773
 
2774
  imm8 = (BITS (20, 23) << 4) | BITS (0, 3);
2775
 
2776
  for (i = 0; i < 4; i++)
2777
    {
2778
      s = wRHALF (BITS (16, 19), ((imm8 >> (i * 2) & 3)) & 0xff);
2779
      r |= (s & 0xffff) << (i * 16);
2780
      SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2781
      SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2782
    }
2783
 
2784
  wC [wCASF] = psr;
2785
  wR [BITS (12, 15)] = r;
2786
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2787
 
2788
  return ARMul_DONE;
2789
}
2790
 
2791
static int
2792
WSLL (ARMul_State * state, ARMword instr)
2793
{
2794
  ARMdword r = 0;
2795
  ARMdword s;
2796
  ARMword  psr = 0;
2797
  int      i;
2798
  unsigned shift;
2799
 
2800
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2801
    return ARMul_CANT;
2802
 
2803
#ifdef DEBUG
2804
  fprintf (stderr, "wsll\n");
2805
#endif  
2806
 
2807
  DECODE_G_BIT (state, instr, shift);
2808
 
2809
  switch (BITS (22, 23))
2810
    {
2811
    case Hqual:
2812
      for (i = 0; i < 4; i++)
2813
        {
2814
          if (shift > 15)
2815
            s = 0;
2816
          else
2817
            s = ((wRHALF (BITS (16, 19), i) & 0xffff) << shift);
2818
          r |= (s & 0xffff) << (i * 16);
2819
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2820
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2821
        }
2822
      break;
2823
 
2824
    case Wqual:
2825
      for (i = 0; i < 2; i++)
2826
        {
2827
          if (shift > 31)
2828
            s = 0;
2829
          else
2830
            s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << shift);
2831
          r |= (s & 0xffffffff) << (i * 32);
2832
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2833
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2834
        }
2835
      break;
2836
 
2837
    case Dqual:
2838
      if (shift > 63)
2839
        r = 0;
2840
      else
2841
        r = ((wR[BITS (16, 19)] & 0xffffffffffffffffULL) << shift);
2842
 
2843
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2844
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2845
      break;
2846
 
2847
    default:
2848
      ARMul_UndefInstr (state, instr);
2849
      return ARMul_DONE;
2850
    }
2851
 
2852
  wC [wCASF] = psr;
2853
  wR [BITS (12, 15)] = r;
2854
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2855
 
2856
  return ARMul_DONE;
2857
}
2858
 
2859
static int
2860
WSRA (ARMul_State * state, ARMword instr)
2861
{
2862
  ARMdword     r = 0;
2863
  ARMdword     s;
2864
  ARMword      psr = 0;
2865
  int          i;
2866
  unsigned     shift;
2867
  signed long  t;
2868
 
2869
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2870
    return ARMul_CANT;
2871
 
2872
#ifdef DEBUG
2873
  fprintf (stderr, "wsra\n");
2874
#endif  
2875
 
2876
  DECODE_G_BIT (state, instr, shift);
2877
 
2878
  switch (BITS (22, 23))
2879
    {
2880
    case Hqual:
2881
      for (i = 0; i < 4; i++)
2882
        {
2883
          if (shift > 15)
2884
            t = (wRHALF (BITS (16, 19), i) & 0x8000) ? 0xffff : 0;
2885
          else
2886
            {
2887
              t = wRHALF (BITS (16, 19), i);
2888
              t = EXTEND16 (t);
2889
              t >>= shift;
2890
            }
2891
 
2892
          s = t;
2893
          r |= (s & 0xffff) << (i * 16);
2894
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2895
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2896
        }
2897
      break;
2898
 
2899
    case Wqual:
2900
      for (i = 0; i < 2; i++)
2901
        {
2902
          if (shift > 31)
2903
            t = (wRWORD (BITS (16, 19), i) & 0x80000000) ? 0xffffffff : 0;
2904
          else
2905
            {
2906
              t = wRWORD (BITS (16, 19), i);
2907
              t >>= shift;
2908
            }
2909
          s = t;
2910
          r |= (s & 0xffffffff) << (i * 32);
2911
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2912
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2913
        }
2914
      break;
2915
 
2916
    case Dqual:
2917
      if (shift > 63)
2918
        r = (wR [BITS (16, 19)] & 0x8000000000000000ULL) ? 0xffffffffffffffffULL : 0;
2919
      else
2920
        r = ((signed long long) (wR[BITS (16, 19)] & 0xffffffffffffffffULL) >> shift);
2921
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2922
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2923
      break;
2924
 
2925
    default:
2926
      ARMul_UndefInstr (state, instr);
2927
      return ARMul_DONE;
2928
    }
2929
 
2930
  wC [wCASF] = psr;
2931
  wR [BITS (12, 15)] = r;
2932
  wC [wCon] |= (WCON_CUP | WCON_MUP);
2933
 
2934
  return ARMul_DONE;
2935
}
2936
 
2937
static int
2938
WSRL (ARMul_State * state, ARMword instr)
2939
{
2940
  ARMdword     r = 0;
2941
  ARMdword     s;
2942
  ARMword      psr = 0;
2943
  int          i;
2944
  unsigned int shift;
2945
 
2946
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2947
    return ARMul_CANT;
2948
 
2949
#ifdef DEBUG
2950
  fprintf (stderr, "wsrl\n");
2951
#endif
2952
 
2953
  DECODE_G_BIT (state, instr, shift);
2954
 
2955
  switch (BITS (22, 23))
2956
    {
2957
    case Hqual:
2958
      for (i = 0; i < 4; i++)
2959
        {
2960
          if (shift > 15)
2961
            s = 0;
2962
          else
2963
            s = ((unsigned) (wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2964
 
2965
          r |= (s & 0xffff) << (i * 16);
2966
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2967
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2968
        }
2969
      break;
2970
 
2971
    case Wqual:
2972
      for (i = 0; i < 2; i++)
2973
        {
2974
          if (shift > 31)
2975
            s = 0;
2976
          else
2977
            s = ((unsigned long) (wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2978
 
2979
          r |= (s & 0xffffffff) << (i * 32);
2980
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2981
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2982
        }
2983
      break;
2984
 
2985
    case Dqual:
2986
      if (shift > 63)
2987
        r = 0;
2988
      else
2989
        r = (wR [BITS (16, 19)] & 0xffffffffffffffffULL) >> shift;
2990
 
2991
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2992
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2993
      break;
2994
 
2995
    default:
2996
      ARMul_UndefInstr (state, instr);
2997
      return ARMul_DONE;
2998
    }
2999
 
3000
  wC [wCASF] = psr;
3001
  wR [BITS (12, 15)] = r;
3002
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3003
 
3004
  return ARMul_DONE;
3005
}
3006
 
3007
static int
3008
WSTR (ARMul_State * state, ARMword instr)
3009
{
3010
  ARMword address;
3011
  int failed;
3012
 
3013
 
3014
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3015
    return ARMul_CANT;
3016
 
3017
#ifdef DEBUG
3018
  fprintf (stderr, "wstr\n");
3019
#endif
3020
 
3021
  address = Compute_Iwmmxt_Address (state, instr, & failed);
3022
  if (failed)
3023
    return ARMul_CANT;
3024
 
3025
  if (BITS (28, 31) == 0xf)
3026
    {
3027
      /* WSTRW wCx */
3028
      Iwmmxt_Store_Word (state, address, wC [BITS (12, 15)]);
3029
    }
3030
  else if (BIT (8) == 0)
3031
    {
3032
      if (BIT (22) == 0)
3033
        /* WSTRB */
3034
        Iwmmxt_Store_Byte (state, address, wR [BITS (12, 15)]);
3035
      else
3036
        /* WSTRH */
3037
        Iwmmxt_Store_Half_Word (state, address, wR [BITS (12, 15)]);
3038
    }
3039
  else
3040
    {
3041
      if (BIT (22) == 0)
3042
        /* WSTRW wRd */
3043
        Iwmmxt_Store_Word (state, address, wR [BITS (12, 15)]);
3044
      else
3045
        /* WSTRD */
3046
        Iwmmxt_Store_Double_Word (state, address, wR [BITS (12, 15)]);
3047
    }
3048
 
3049
  return ARMul_DONE;
3050
}
3051
 
3052
static int
3053
WSUB (ARMul_State * state, ARMword instr)
3054
{
3055
  ARMdword r = 0;
3056
  ARMword  psr = 0;
3057
  ARMdword x;
3058
  ARMdword s;
3059
  int      i;
3060
  int      carry;
3061
  int      overflow;
3062
  int      satrv[8];
3063
 
3064
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3065
    return ARMul_CANT;
3066
 
3067
#ifdef DEBUG
3068
  fprintf (stderr, "wsub\n");
3069
#endif  
3070
 
3071
/* Subtract two numbers using the specified function,
3072
   leaving setting the carry bit as required.  */
3073
#define SUBx(x, y, m, f) \
3074
   (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3075
         wRBITS (BITS ( 0,  3), (x), (y)) & (m), & carry, & overflow)
3076
 
3077
  switch (BITS (22, 23))
3078
    {
3079
    case Bqual:
3080
      for (i = 0; i < 8; i++)
3081
        {
3082
          switch (BITS (20, 21))
3083
            {
3084
            case NoSaturation:
3085
              s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3086
              satrv [BITIDX8 (i)] = 0;
3087
              r |= (s & 0xff) << (i * 8);
3088
              SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
3089
              SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
3090
              SIMD8_SET (psr, carry, SIMD_CBIT, i);
3091
              SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3092
              break;
3093
 
3094
            case UnsignedSaturation:
3095
              s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubU8);
3096
              x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i));
3097
              r |= (x & 0xff) << (i * 8);
3098
              SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3099
              SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3100
              if (! satrv [BITIDX8 (i)])
3101
                {
3102
                  SIMD8_SET (psr, carry,     SIMD_CBIT, i);
3103
                  SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3104
                }
3105
              break;
3106
 
3107
            case SignedSaturation:
3108
              s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3109
              x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i));
3110
              r |= (x & 0xff) << (i * 8);
3111
              SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3112
              SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3113
              if (! satrv [BITIDX8 (i)])
3114
                {
3115
                  SIMD8_SET (psr, carry,     SIMD_CBIT, i);
3116
                  SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3117
                }
3118
              break;
3119
 
3120
            default:
3121
              ARMul_UndefInstr (state, instr);
3122
              return ARMul_DONE;
3123
            }
3124
        }
3125
      break;
3126
 
3127
    case Hqual:
3128
      satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
3129
 
3130
      for (i = 0; i < 4; i++)
3131
        {
3132
          switch (BITS (20, 21))
3133
            {
3134
            case NoSaturation:
3135
              s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3136
              satrv [BITIDX16 (i)] = 0;
3137
              r |= (s & 0xffff) << (i * 16);
3138
              SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3139
              SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3140
              SIMD16_SET (psr, carry,      SIMD_CBIT, i);
3141
              SIMD16_SET (psr, overflow,   SIMD_VBIT, i);
3142
              break;
3143
 
3144
            case UnsignedSaturation:
3145
              s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3146
              x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i));
3147
              r |= (x & 0xffff) << (i * 16);
3148
              SIMD16_SET (psr, NBIT16 (x & 0xffff), SIMD_NBIT, i);
3149
              SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3150
              if (! satrv [BITIDX16 (i)])
3151
                {
3152
                  SIMD16_SET (psr, carry,    SIMD_CBIT, i);
3153
                  SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3154
                }
3155
              break;
3156
 
3157
            case SignedSaturation:
3158
              s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubS16);
3159
              x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i));
3160
              r |= (x & 0xffff) << (i * 16);
3161
              SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
3162
              SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3163
              if (! satrv [BITIDX16 (i)])
3164
                {
3165
                  SIMD16_SET (psr, carry,    SIMD_CBIT, i);
3166
                  SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3167
                }
3168
              break;
3169
 
3170
            default:
3171
              ARMul_UndefInstr (state, instr);
3172
              return ARMul_DONE;
3173
            }
3174
        }
3175
      break;
3176
 
3177
    case Wqual:
3178
      satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
3179
 
3180
      for (i = 0; i < 2; i++)
3181
        {
3182
          switch (BITS (20, 21))
3183
            {
3184
            case NoSaturation:
3185
              s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3186
              satrv[BITIDX32 (i)] = 0;
3187
              r |= (s & 0xffffffff) << (i * 32);
3188
              SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3189
              SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3190
              SIMD32_SET (psr, carry,      SIMD_CBIT, i);
3191
              SIMD32_SET (psr, overflow,   SIMD_VBIT, i);
3192
              break;
3193
 
3194
            case UnsignedSaturation:
3195
              s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3196
              x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i));
3197
              r |= (x & 0xffffffff) << (i * 32);
3198
              SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3199
              SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3200
              if (! satrv [BITIDX32 (i)])
3201
                {
3202
                  SIMD32_SET (psr, carry,    SIMD_CBIT, i);
3203
                  SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3204
                }
3205
              break;
3206
 
3207
            case SignedSaturation:
3208
              s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubS32);
3209
              x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i));
3210
              r |= (x & 0xffffffff) << (i * 32);
3211
              SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3212
              SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3213
              if (! satrv [BITIDX32 (i)])
3214
                {
3215
                  SIMD32_SET (psr, carry,    SIMD_CBIT, i);
3216
                  SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3217
                }
3218
              break;
3219
 
3220
            default:
3221
              ARMul_UndefInstr (state, instr);
3222
              return ARMul_DONE;
3223
            }
3224
        }
3225
      break;
3226
 
3227
    default:
3228
      ARMul_UndefInstr (state, instr);
3229
      return ARMul_DONE;
3230
    }
3231
 
3232
  wR [BITS (12, 15)] = r;
3233
  wC [wCASF] = psr;
3234
  SET_wCSSFvec (satrv);
3235
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3236
 
3237
#undef SUBx
3238
 
3239
  return ARMul_DONE;
3240
}
3241
 
3242
static int
3243
WUNPCKEH (ARMul_State * state, ARMword instr)
3244
{
3245
  ARMdword r = 0;
3246
  ARMword  psr = 0;
3247
  ARMdword s;
3248
  int      i;
3249
 
3250
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3251
    return ARMul_CANT;
3252
 
3253
#ifdef DEBUG
3254
  fprintf (stderr, "wunpckeh\n");
3255
#endif  
3256
 
3257
  switch (BITS (22, 23))
3258
    {
3259
    case Bqual:
3260
      for (i = 0; i < 4; i++)
3261
        {
3262
          s = wRBYTE (BITS (16, 19), i + 4);
3263
 
3264
          if (BIT (21) && NBIT8 (s))
3265
            s |= 0xff00;
3266
 
3267
          r |= (s & 0xffff) << (i * 16);
3268
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3269
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3270
        }
3271
      break;
3272
 
3273
    case Hqual:
3274
      for (i = 0; i < 2; i++)
3275
        {
3276
          s = wRHALF (BITS (16, 19), i + 2);
3277
 
3278
          if (BIT (21) && NBIT16 (s))
3279
            s |= 0xffff0000;
3280
 
3281
          r |= (s & 0xffffffff) << (i * 32);
3282
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3283
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3284
        }
3285
      break;
3286
 
3287
    case Wqual:
3288
      r = wRWORD (BITS (16, 19), 1);
3289
 
3290
      if (BIT (21) && NBIT32 (r))
3291
        r |= 0xffffffff00000000ULL;
3292
 
3293
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3294
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3295
      break;
3296
 
3297
    default:
3298
      ARMul_UndefInstr (state, instr);
3299
      return ARMul_DONE;
3300
    }
3301
 
3302
  wC [wCASF] = psr;
3303
  wR [BITS (12, 15)] = r;
3304
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3305
 
3306
  return ARMul_DONE;
3307
}
3308
 
3309
static int
3310
WUNPCKEL (ARMul_State * state, ARMword instr)
3311
{
3312
  ARMdword r = 0;
3313
  ARMword  psr = 0;
3314
  ARMdword s;
3315
  int      i;
3316
 
3317
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3318
    return ARMul_CANT;
3319
 
3320
#ifdef DEBUG
3321
  fprintf (stderr, "wunpckel\n");
3322
#endif  
3323
 
3324
  switch (BITS (22, 23))
3325
    {
3326
    case Bqual:
3327
      for (i = 0; i < 4; i++)
3328
        {
3329
          s = wRBYTE (BITS (16, 19), i);
3330
 
3331
          if (BIT (21) && NBIT8 (s))
3332
            s |= 0xff00;
3333
 
3334
          r |= (s & 0xffff) << (i * 16);
3335
          SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3336
          SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3337
        }
3338
      break;
3339
 
3340
    case Hqual:
3341
      for (i = 0; i < 2; i++)
3342
        {
3343
          s = wRHALF (BITS (16, 19), i);
3344
 
3345
          if (BIT (21) && NBIT16 (s))
3346
            s |= 0xffff0000;
3347
 
3348
          r |= (s & 0xffffffff) << (i * 32);
3349
          SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3350
          SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3351
        }
3352
      break;
3353
 
3354
    case Wqual:
3355
      r = wRWORD (BITS (16, 19), 0);
3356
 
3357
      if (BIT (21) && NBIT32 (r))
3358
        r |= 0xffffffff00000000ULL;
3359
 
3360
      SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3361
      SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3362
      break;
3363
 
3364
    default:
3365
      ARMul_UndefInstr (state, instr);
3366
      return ARMul_DONE;
3367
    }
3368
 
3369
  wC [wCASF] = psr;
3370
  wR [BITS (12, 15)] = r;
3371
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3372
 
3373
  return ARMul_DONE;
3374
}
3375
 
3376
static int
3377
WUNPCKIH (ARMul_State * state, ARMword instr)
3378
{
3379
  ARMword  a, b;
3380
  ARMdword r = 0;
3381
  ARMword  psr = 0;
3382
  ARMdword s;
3383
  int      i;
3384
 
3385
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3386
    return ARMul_CANT;
3387
 
3388
#ifdef DEBUG
3389
  fprintf (stderr, "wunpckih\n");
3390
#endif  
3391
 
3392
  switch (BITS (22, 23))
3393
    {
3394
    case Bqual:
3395
      for (i = 0; i < 4; i++)
3396
        {
3397
          a = wRBYTE (BITS (16, 19), i + 4);
3398
          b = wRBYTE (BITS ( 0,  3), i + 4);
3399
          s = a | (b << 8);
3400
          r |= (s & 0xffff) << (i * 16);
3401
          SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3402
          SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3403
          SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3404
          SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3405
        }
3406
      break;
3407
 
3408
    case Hqual:
3409
      for (i = 0; i < 2; i++)
3410
        {
3411
          a = wRHALF (BITS (16, 19), i + 2);
3412
          b = wRHALF (BITS ( 0,  3), i + 2);
3413
          s = a | (b << 16);
3414
          r |= (s & 0xffffffff) << (i * 32);
3415
          SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3416
          SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3417
          SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3418
          SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3419
        }
3420
      break;
3421
 
3422
    case Wqual:
3423
      a = wRWORD (BITS (16, 19), 1);
3424
      s = wRWORD (BITS ( 0,  3), 1);
3425
      r = a | (s << 32);
3426
 
3427
      SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3428
      SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3429
      SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3430
      SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3431
      break;
3432
 
3433
    default:
3434
      ARMul_UndefInstr (state, instr);
3435
      return ARMul_DONE;
3436
    }
3437
 
3438
  wC [wCASF] = psr;
3439
  wR [BITS (12, 15)] = r;
3440
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3441
 
3442
  return ARMul_DONE;
3443
}
3444
 
3445
static int
3446
WUNPCKIL (ARMul_State * state, ARMword instr)
3447
{
3448
  ARMword  a, b;
3449
  ARMdword r = 0;
3450
  ARMword  psr = 0;
3451
  ARMdword s;
3452
  int      i;
3453
 
3454
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3455
    return ARMul_CANT;
3456
 
3457
#ifdef DEBUG
3458
  fprintf (stderr, "wunpckil\n");
3459
#endif  
3460
 
3461
  switch (BITS (22, 23))
3462
    {
3463
    case Bqual:
3464
      for (i = 0; i < 4; i++)
3465
        {
3466
          a = wRBYTE (BITS (16, 19), i);
3467
          b = wRBYTE (BITS ( 0,  3), i);
3468
          s = a | (b << 8);
3469
          r |= (s & 0xffff) << (i * 16);
3470
          SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3471
          SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3472
          SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3473
          SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3474
        }
3475
      break;
3476
 
3477
    case Hqual:
3478
      for (i = 0; i < 2; i++)
3479
        {
3480
          a = wRHALF (BITS (16, 19), i);
3481
          b = wRHALF (BITS ( 0,  3), i);
3482
          s = a | (b << 16);
3483
          r |= (s & 0xffffffff) << (i * 32);
3484
          SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3485
          SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3486
          SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3487
          SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3488
        }
3489
      break;
3490
 
3491
    case Wqual:
3492
      a = wRWORD (BITS (16, 19), 0);
3493
      s = wRWORD (BITS ( 0,  3), 0);
3494
      r = a | (s << 32);
3495
 
3496
      SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3497
      SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3498
      SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3499
      SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3500
      break;
3501
 
3502
    default:
3503
      ARMul_UndefInstr (state, instr);
3504
      return ARMul_DONE;
3505
    }
3506
 
3507
  wC [wCASF] = psr;
3508
  wR [BITS (12, 15)] = r;
3509
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3510
 
3511
  return ARMul_DONE;
3512
}
3513
 
3514
static int
3515
WXOR (ARMword instr)
3516
{
3517
  ARMword psr = 0;
3518
  ARMdword result;
3519
 
3520
  if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3521
    return ARMul_CANT;
3522
 
3523
#ifdef DEBUG
3524
  fprintf (stderr, "wxor\n");
3525
#endif  
3526
 
3527
  result = wR [BITS (16, 19)] ^ wR [BITS (0, 3)];
3528
  wR [BITS (12, 15)] = result;
3529
 
3530
  SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
3531
  SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
3532
 
3533
  wC [wCASF] = psr;
3534
  wC [wCon] |= (WCON_CUP | WCON_MUP);
3535
 
3536
  return ARMul_DONE;
3537
}
3538
 
3539
/* This switch table is moved to a seperate function in order
3540
   to work around a compiler bug in the host compiler...  */
3541
 
3542
static int
3543
Process_Instruction (ARMul_State * state, ARMword instr)
3544
{
3545
  int status = ARMul_BUSY;
3546
 
3547
  switch ((BITS (20, 23) << 8) | BITS (4, 11))
3548
    {
3549
    case 0x000: status = WOR (instr); break;
3550
    case 0x011: status = TMCR (state, instr); break;
3551
    case 0x100: status = WXOR (instr); break;
3552
    case 0x111: status = TMRC (state, instr); break;
3553
    case 0x300: status = WANDN (instr); break;
3554
    case 0x200: status = WAND (instr); break;
3555
 
3556
    case 0x810: case 0xa10:
3557
      status = WMADD (instr); break;
3558
 
3559
    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3560
      status = WUNPCKIL (state, instr); break;
3561
    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3562
      status = WUNPCKIH (state, instr); break;
3563
    case 0x012: case 0x112: case 0x412: case 0x512:
3564
      status = WSAD (instr); break;
3565
    case 0x010: case 0x110: case 0x210: case 0x310:
3566
      status = WMUL (instr); break;
3567
    case 0x410: case 0x510: case 0x610: case 0x710:
3568
      status = WMAC (instr); break;
3569
    case 0x006: case 0x406: case 0x806: case 0xc06:
3570
      status = WCMPEQ (state, instr); break;
3571
    case 0x800: case 0x900: case 0xc00: case 0xd00:
3572
      status = WAVG2 (instr); break;
3573
    case 0x802: case 0x902: case 0xa02: case 0xb02:
3574
      status = WALIGNR (state, instr); break;
3575
    case 0x601: case 0x605: case 0x609: case 0x60d:
3576
      status = TINSR (state, instr); break;
3577
    case 0x107: case 0x507: case 0x907: case 0xd07:
3578
      status = TEXTRM (state, instr); break;
3579
    case 0x117: case 0x517: case 0x917: case 0xd17:
3580
      status = TEXTRC (state, instr); break;
3581
    case 0x401: case 0x405: case 0x409: case 0x40d:
3582
      status = TBCST (state, instr); break;
3583
    case 0x113: case 0x513: case 0x913: case 0xd13:
3584
      status = TANDC (state, instr); break;
3585
    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3586
      status = WACC (state, instr); break;
3587
    case 0x115: case 0x515: case 0x915: case 0xd15:
3588
      status = TORC (state, instr); break;
3589
    case 0x103: case 0x503: case 0x903: case 0xd03:
3590
      status = TMOVMSK (state, instr); break;
3591
    case 0x106: case 0x306: case 0x506: case 0x706:
3592
    case 0x906: case 0xb06: case 0xd06: case 0xf06:
3593
      status = WCMPGT (state, instr); break;
3594
    case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3595
    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3596
      status = WUNPCKEL (state, instr); break;
3597
    case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3598
    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3599
      status = WUNPCKEH (state, instr); break;
3600
    case 0x204: case 0x604: case 0xa04: case 0xe04:
3601
    case 0x214: case 0x614: case 0xa14: case 0xe14:
3602
      status = WSRL (state, instr); break;
3603
    case 0x004: case 0x404: case 0x804: case 0xc04:
3604
    case 0x014: case 0x414: case 0x814: case 0xc14:
3605
      status = WSRA (state, instr); break;
3606
    case 0x104: case 0x504: case 0x904: case 0xd04:
3607
    case 0x114: case 0x514: case 0x914: case 0xd14:
3608
      status = WSLL (state, instr); break;
3609
    case 0x304: case 0x704: case 0xb04: case 0xf04:
3610
    case 0x314: case 0x714: case 0xb14: case 0xf14:
3611
      status = WROR (state, instr); break;
3612
    case 0x116: case 0x316: case 0x516: case 0x716:
3613
    case 0x916: case 0xb16: case 0xd16: case 0xf16:
3614
      status = WMIN (state, instr); break;
3615
    case 0x016: case 0x216: case 0x416: case 0x616:
3616
    case 0x816: case 0xa16: case 0xc16: case 0xe16:
3617
      status = WMAX (state, instr); break;
3618
    case 0x002: case 0x102: case 0x202: case 0x302:
3619
    case 0x402: case 0x502: case 0x602: case 0x702:
3620
      status = WALIGNI (instr); break;
3621
    case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3622
    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3623
    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3624
    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3625
      status = WSUB (state, instr); break;
3626
    case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3627
    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3628
    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3629
    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3630
      status = WSHUFH (instr); break;
3631
    case 0x018: case 0x118: case 0x218: case 0x318:
3632
    case 0x418: case 0x518: case 0x618: case 0x718:
3633
    case 0x818: case 0x918: case 0xa18: case 0xb18:
3634
    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3635
      status = WADD (state, instr); break;
3636
    case 0x008: case 0x108: case 0x208: case 0x308:
3637
    case 0x408: case 0x508: case 0x608: case 0x708:
3638
    case 0x808: case 0x908: case 0xa08: case 0xb08:
3639
    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3640
      status = WPACK (state, instr); break;
3641
    case 0x201: case 0x203: case 0x205: case 0x207:
3642
    case 0x209: case 0x20b: case 0x20d: case 0x20f:
3643
    case 0x211: case 0x213: case 0x215: case 0x217:
3644
    case 0x219: case 0x21b: case 0x21d: case 0x21f:
3645
      switch (BITS (16, 19))
3646
        {
3647
        case 0x0: status = TMIA (state, instr); break;
3648
        case 0x8: status = TMIAPH (state, instr); break;
3649
        case 0xc:
3650
        case 0xd:
3651
        case 0xe:
3652
        case 0xf: status = TMIAxy (state, instr); break;
3653
        default: break;
3654
        }
3655
      break;
3656
    default:
3657
      break;
3658
    }
3659
  return status;
3660
}
3661
 
3662
/* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3663
   Return true if the instruction was handled.  */
3664
 
3665
int
3666
ARMul_HandleIwmmxt (ARMul_State * state, ARMword instr)
3667
{
3668
  int status = ARMul_BUSY;
3669
 
3670
  if (BITS (24, 27) == 0xe)
3671
    {
3672
      status = Process_Instruction (state, instr);
3673
    }
3674
  else if (BITS (25, 27) == 0x6)
3675
    {
3676
      if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3677
        status = TMCRR (state, instr);
3678
      else if (BITS (9, 11) == 0x0)
3679
        {
3680
          if (BIT (20) == 0x0)
3681
            status = WSTR (state, instr);
3682
          else if (BITS (20, 24) == 0x5)
3683
            status = TMRRC (state, instr);
3684
          else
3685
            status = WLDR (state, instr);
3686
        }
3687
    }
3688
 
3689
  if (status == ARMul_CANT)
3690
    {
3691
      /* If the instruction was a recognised but illegal,
3692
         perform the abort here rather than returning false.
3693
         If we return false then ARMul_MRC may be called which
3694
         will still abort, but which also perform the register
3695
         transfer...  */
3696
      ARMul_Abort (state, ARMul_UndefinedInstrV);
3697
      status = ARMul_DONE;
3698
    }
3699
 
3700
  return status == ARMul_DONE;
3701
}
3702
 
3703
int
3704
Fetch_Iwmmxt_Register (unsigned int regnum, unsigned char * memory)
3705
{
3706
  if (regnum >= 16)
3707
    {
3708
      memcpy (memory, wC + (regnum - 16), sizeof wC [0]);
3709
      return sizeof wC [0];
3710
    }
3711
  else
3712
    {
3713
      memcpy (memory, wR + regnum, sizeof wR [0]);
3714
      return sizeof wR [0];
3715
    }
3716
}
3717
 
3718
int
3719
Store_Iwmmxt_Register (unsigned int regnum, unsigned char * memory)
3720
{
3721
  if (regnum >= 16)
3722
    {
3723
      memcpy (wC + (regnum - 16), memory, sizeof wC [0]);
3724
      return sizeof wC [0];
3725
    }
3726
  else
3727
    {
3728
      memcpy (wR + regnum, memory, sizeof wR [0]);
3729
      return sizeof wR [0];
3730
    }
3731
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.