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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [arm/] [iwmmxt.c] - Blame information for rev 280

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

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

powered by: WebSVN 2.1.0

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