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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [mips/] [dsp.igen] - Blame information for rev 309

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

Line No. Rev Author Line
1 24 jeremybenn
// -*- C -*-
2
 
3
// Simulator definition for the MIPS DSP ASE.
4
// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
5
// Contributed by MIPS Technologies, Inc.  Written by Chao-ying Fu.
6
//
7
// This file is part of GDB, the GNU debugger.
8
//
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 3 of the License, or
12
// (at your option) any later version.
13
//
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
//
19
// You should have received a copy of the GNU General Public License
20
// along with this program.  If not, see .
21
 
22
 
23
// op: 0 = ADD, 1 = SUB, 2 = MUL
24
// sat: 0 = no saturation, 1 = saturation
25
:function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat
26
{
27
  int i;
28
  signed32 h0 = 0;
29
  signed16 h1, h2;
30
  unsigned32 v1 = GPR[rs];
31
  unsigned32 v2 = GPR[rt];
32
  unsigned32 result = 0;
33
  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
34
    {
35
      h1 = (signed16)(v1 & 0xffff);
36
      h2 = (signed16)(v2 & 0xffff);
37
      if (op == 0) // ADD
38
        h0 = (signed32)h1 + (signed32)h2;
39
      else if (op == 1) // SUB
40
        h0 = (signed32)h1 - (signed32)h2;
41
      else // MUL
42
        h0 = (signed32)h1 * (signed32)h2;
43
      if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
44
        {
45
          if (op == 0 || op == 1) // ADD, SUB
46
            DSPCR |= DSPCR_OUFLAG4;
47
          else if (op == 2) // MUL
48
            DSPCR |= DSPCR_OUFLAG5;
49
          if (sat == 1)
50
            {
51
              if (h0 > (signed32)0x7fff)
52
                h0 = 0x7fff;
53
              else
54
                h0 = 0x8000;
55
            }
56
        }
57
      result |= ((unsigned32)((unsigned16)h0) << i);
58
    }
59
  GPR[rd] = EXTEND32 (result);
60
}
61
 
62
// op: 0 = ADD, 1 = SUB
63
:function:::void:do_w_op:int rd, int rs, int rt, int op
64
{
65
  signed64 h0;
66
  signed32 h1, h2;
67
  unsigned32 v1 = GPR[rs];
68
  unsigned32 v2 = GPR[rt];
69
  unsigned32 result = 0;
70
  h1 = (signed32)v1;
71
  h2 = (signed32)v2;
72
  if (op == 0) // ADD
73
    h0 = (signed64)h1 + (signed64)h2;
74
  else // SUB
75
    h0 = (signed64)h1 - (signed64)h2;
76
  if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
77
    {
78
      DSPCR |= DSPCR_OUFLAG4;
79
      if (h0 & 0x100000000LL)
80
        h0 = 0x80000000;
81
      else
82
        h0 = 0x7fffffff;
83
    }
84
  GPR[rd] = EXTEND32 (h0);
85
}
86
 
87
// op: 0 = ADD, 1 = SUB
88
// sat: 0 = no saturation, 1 = saturation
89
:function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat
90
{
91
  int i;
92
  unsigned32 h0;
93
  unsigned8 h1, h2;
94
  unsigned32 v1 = GPR[rs];
95
  unsigned32 v2 = GPR[rt];
96
  unsigned32 result = 0;
97
  for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
98
    {
99
      h1 = (unsigned8)(v1 & 0xff);
100
      h2 = (unsigned8)(v2 & 0xff);
101
      if (op == 0) // ADD
102
        h0 = (unsigned32)h1 + (unsigned32)h2;
103
      else // SUB
104
        h0 = (unsigned32)h1 - (unsigned32)h2;
105
      if (h0 & 0x100)
106
        {
107
          DSPCR |= DSPCR_OUFLAG4;
108
          if (sat == 1)
109
            {
110
              if (op == 0) // ADD
111
                h0 = 0xff;
112
              else // SUB
113
                h0 = 0;
114
            }
115
        }
116
      result |= ((unsigned32)((unsigned8)h0) << i);
117
    }
118
  GPR[rd] = EXTEND32 (result);
119
}
120
 
121
// op: 0 = left, 1 = right
122
:function:::void:do_qb_shift:int rd, int rt, int shift, int op
123
{
124
  int i, j;
125
  unsigned8 h0;
126
  unsigned32 v1 = GPR[rt];
127
  unsigned32 result = 0;
128
  for (i = 0; i < 32; i += 8, v1 >>= 8)
129
    {
130
      h0 = (unsigned8)(v1 & 0xff);
131
      if (op == 0) // left
132
        {
133
          for (j = 7; j >= 8 - shift; j--)
134
            {
135
              if (h0 & (1<
136
                {
137
                  DSPCR |= DSPCR_OUFLAG6;
138
                  break;
139
                }
140
            }
141
          h0 = h0 << shift;
142
        }
143
      else // right
144
        h0 = h0 >> shift;
145
      result |= ((unsigned32)h0 << i);
146
    }
147
  GPR[rd] = EXTEND32 (result);
148
}
149
 
150
// op: 0 = left, 1 = right
151
// sat: 0 = no saturation/rounding, 1 = saturation/rounding
152
:function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat
153
{
154
  int i, j;
155
  signed16 h0;
156
  unsigned32 v1 = GPR[rt];
157
  unsigned32 result = 0;
158
  int setcond;
159
  for (i = 0; i < 32; i += 16, v1 >>= 16)
160
    {
161
      h0 = (signed16)(v1 & 0xffff);
162
      if (op == 0) // left
163
        {
164
          setcond = 0;
165
          if (h0 & (1<<15))
166
            {
167
              for (j = 14; j >= 15 - shift; j--)
168
                {
169
                  if (!(h0 & (1 << j)))
170
                    {
171
                      DSPCR |= DSPCR_OUFLAG6;
172
                      setcond = 1;
173
                      break;
174
                    }
175
                }
176
            }
177
          else
178
            {
179
              for (j = 14; j >= 15 - shift; j--)
180
                {
181
                  if (h0 & (1 << j))
182
                    {
183
                      DSPCR |= DSPCR_OUFLAG6;
184
                      setcond = 2;
185
                      break;
186
                    }
187
                }
188
            }
189
          h0 = h0 << shift;
190
          if (sat == 1)
191
            {
192
              if (setcond == 2)
193
                h0 = 0x7fff;
194
              else if (setcond == 1)
195
                h0 = 0x8000;
196
            }
197
        }
198
      else // right
199
        {
200
          if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
201
            h0 = (h0 >> shift) + 1;
202
          else
203
            h0 = h0 >> shift;
204
        }
205
 
206
      result |= ((unsigned32)((unsigned16)h0) << i);
207
    }
208
  GPR[rd] = EXTEND32 (result);
209
}
210
 
211
:function:::void:do_w_shll:int rd, int rt, int shift
212
{
213
  int i;
214
  unsigned32 v1 = GPR[rt];
215
  unsigned32 result = 0;
216
  int setcond = 0;
217
  if (v1 & (1 << 31))
218
    {
219
      for (i = 30; i >= 31 - shift; i--)
220
        {
221
          if (!(v1 & (1 << i)))
222
            {
223
              DSPCR |= DSPCR_OUFLAG6;
224
              setcond = 1;
225
              break;
226
            }
227
        }
228
    }
229
  else
230
    {
231
      for (i = 30; i >= 31 - shift; i--)
232
        {
233
          if (v1 & (1 << i))
234
            {
235
              DSPCR |= DSPCR_OUFLAG6;
236
              setcond = 2;
237
              break;
238
            }
239
        }
240
    }
241
  if (setcond == 2)
242
    result = 0x7fffffff;
243
  else if (setcond == 1)
244
    result = 0x80000000;
245
  else
246
    result = v1 << shift;
247
  GPR[rd] = EXTEND32 (result);
248
}
249
 
250
:function:::void:do_w_shra:int rd, int rt, int shift
251
{
252
  unsigned32 result = GPR[rt];
253
  signed32 h0 = (signed32)result;
254
  if (shift != 0 && (h0 & (1 << (shift-1))))
255
    h0 = (h0 >> shift) + 1;
256
  else
257
    h0 = h0 >> shift;
258
  GPR[rd] = EXTEND32 (h0);
259
}
260
 
261
011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
262
"addq.ph r, r, r"
263
*dsp:
264
{
265
  do_ph_op (SD_, RD, RS, RT, 0, 0);
266
}
267
 
268
011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
269
"addq_s.ph r, r, r"
270
*dsp:
271
{
272
  do_ph_op (SD_, RD, RS, RT, 0, 1);
273
}
274
 
275
011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
276
"addq_s.w r, r, r"
277
*dsp:
278
{
279
  do_w_op (SD_, RD, RS, RT, 0);
280
}
281
 
282
011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
283
"addu.qb r, r, r"
284
*dsp:
285
{
286
  do_qb_op (SD_, RD, RS, RT, 0, 0);
287
}
288
 
289
011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
290
"addu_s.qb r, r, r"
291
*dsp:
292
{
293
  do_qb_op (SD_, RD, RS, RT, 0, 1);
294
}
295
 
296
011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
297
"subq.ph r, r, r"
298
*dsp:
299
{
300
  do_ph_op (SD_, RD, RS, RT, 1, 0);
301
}
302
 
303
011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
304
"subq_s.ph r, r, r"
305
*dsp:
306
{
307
  do_ph_op (SD_, RD, RS, RT, 1, 1);
308
}
309
 
310
011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
311
"subq_s.w r, r, r"
312
*dsp:
313
{
314
  do_w_op (SD_, RD, RS, RT, 1);
315
}
316
 
317
011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
318
"subu.qb r, r, r"
319
*dsp:
320
{
321
  do_qb_op (SD_, RD, RS, RT, 1, 0);
322
}
323
 
324
011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
325
"subu_s.qb r, r, r"
326
*dsp:
327
{
328
  do_qb_op (SD_, RD, RS, RT, 1, 1);
329
}
330
 
331
011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
332
"addsc r, r, r"
333
*dsp:
334
{
335
  unsigned32 v1 = GPR[RS];
336
  unsigned32 v2 = GPR[RT];
337
  unsigned64 h0;
338
  h0 = (unsigned64)v1 + (unsigned64)v2;
339
  if (h0 & 0x100000000LL)
340
    DSPCR |= DSPCR_CARRY;
341
  GPR[RD] = EXTEND32 (h0);
342
}
343
 
344
011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
345
"addwc r, r, r"
346
*dsp:
347
{
348
  unsigned32 v1 = GPR[RS];
349
  unsigned32 v2 = GPR[RT];
350
  unsigned64 h0;
351
  signed32 h1 = (signed32) v1;
352
  signed32 h2 = (signed32) v2;
353
  h0 = (signed64)h1 + (signed64)h2
354
       + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
355
  if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
356
    DSPCR |= DSPCR_OUFLAG4;
357
  GPR[RD] = EXTEND32 (h0);
358
}
359
 
360
011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
361
"modsub r, r, r"
362
*dsp:
363
{
364
  unsigned32 result = 0;
365
  unsigned32 v1 = GPR[RS];
366
  unsigned32 v2 = GPR[RT];
367
  unsigned32 decr = v2 & 0xff;
368
  unsigned32 lastindex = (v2 & 0xffff00) >> 8;
369
  if (v1 == 0)
370
    result = lastindex;
371
  else
372
    result =  v1 - decr;
373
  GPR[RD] = EXTEND32 (result);
374
}
375
 
376
011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
377
"raddu.w.qb r, r"
378
*dsp:
379
{
380
  int i;
381
  unsigned8 h0;
382
  unsigned32 v1 = GPR[RS];
383
  unsigned32 result = 0;
384
  for (i = 0; i < 32; i += 8, v1 >>= 8)
385
    {
386
      h0 = (unsigned8)(v1 & 0xff);
387
      result += (unsigned32)h0;
388
    }
389
  GPR[RD] = EXTEND32 (result);
390
}
391
 
392
011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
393
"absq_s.ph r, r"
394
*dsp:
395
{
396
  int i;
397
  signed16 h0;
398
  unsigned32 v1 = GPR[RT];
399
  unsigned32 result = 0;
400
  for (i = 0; i < 32; i += 16, v1 >>= 16)
401
    {
402
      h0 = (signed16)(v1 & 0xffff);
403
      if (h0 == (signed16)0x8000)
404
        {
405
          DSPCR |= DSPCR_OUFLAG4;
406
          h0 = 0x7fff;
407
        }
408
      else if (h0 & 0x8000)
409
        h0 = -h0;
410
      result |= ((unsigned32)((unsigned16)h0) << i);
411
    }
412
  GPR[RD] = EXTEND32 (result);
413
}
414
 
415
011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
416
"absq_s.w r, r"
417
*dsp:
418
{
419
  unsigned32 v1 = GPR[RT];
420
  signed32 h0 = (signed32)v1;
421
  if (h0 == (signed32)0x80000000)
422
    {
423
      DSPCR |= DSPCR_OUFLAG4;
424
      h0 = 0x7fffffff;
425
    }
426
  else if (h0 & 0x80000000)
427
    h0 = -h0;
428
  GPR[RD] = EXTEND32 (h0);
429
}
430
 
431
011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
432
"precrq.qb.ph r, r, r"
433
*dsp:
434
{
435
  unsigned32 v1 = GPR[RS];
436
  unsigned32 v2 = GPR[RT];
437
  unsigned32 tempu = (v1 & 0xff000000) >> 24;
438
  unsigned32 tempv = (v1 & 0xff00) >> 8;
439
  unsigned32 tempw = (v2 & 0xff000000) >> 24;
440
  unsigned32 tempx = (v2 & 0xff00) >> 8;
441
  GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
442
}
443
 
444
011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
445
"precrq.ph.w r, r, r"
446
*dsp:
447
{
448
  unsigned32 v1 = GPR[RS];
449
  unsigned32 v2 = GPR[RT];
450
  unsigned32 tempu = (v1 & 0xffff0000) >> 16;
451
  unsigned32 tempv = (v2 & 0xffff0000) >> 16;
452
  GPR[RD] = EXTEND32 ((tempu << 16) | tempv);
453
}
454
 
455
011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
456
"precrq_rs.ph.w r, r, r"
457
*dsp:
458
{
459
  unsigned32 v1 = GPR[RS];
460
  unsigned32 v2 = GPR[RT];
461
  signed32 h1 = (signed32)v1;
462
  signed32 h2 = (signed32)v2;
463
  signed64 temp1 = (signed64)h1 + (signed64)0x8000;
464
  signed32 temp2;
465
  signed64 temp3 = (signed64)h2 + (signed64)0x8000;
466
  signed32 temp4;
467
  if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
468
    {
469
      DSPCR |= DSPCR_OUFLAG6;
470
      temp2 = 0x7fff;
471
    }
472
  else
473
    temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
474
  if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
475
    {
476
      DSPCR |= DSPCR_OUFLAG6;
477
      temp4 = 0x7fff;
478
    }
479
  else
480
    temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
481
  GPR[RD] = EXTEND32 ((temp2 << 16) | temp4);
482
}
483
 
484
011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
485
"precrqu_s.qb.ph r, r, r"
486
*dsp:
487
{
488
  unsigned32 v1 = GPR[RS];
489
  unsigned32 v2 = GPR[RT];
490
  unsigned32 tempu, tempv, tempw, tempx;
491
  if (v1 & 0x80000000)
492
    {
493
      DSPCR |= DSPCR_OUFLAG6;
494
      tempu = 0;
495
    }
496
  else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
497
    {
498
      DSPCR |= DSPCR_OUFLAG6;
499
      tempu = 0xff;
500
    }
501
  else
502
    tempu = (v1 & 0x7f800000) >> 23;
503
  if (v1 & 0x8000)
504
    {
505
      DSPCR |= DSPCR_OUFLAG6;
506
      tempv = 0;
507
    }
508
  else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
509
    {
510
      DSPCR |= DSPCR_OUFLAG6;
511
      tempv = 0xff;
512
    }
513
  else
514
    tempv = (v1 & 0x7f80) >> 7;
515
  if (v2 & 0x80000000)
516
    {
517
      DSPCR |= DSPCR_OUFLAG6;
518
      tempw = 0;
519
    }
520
  else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
521
    {
522
      DSPCR |= DSPCR_OUFLAG6;
523
      tempw = 0xff;
524
    }
525
  else
526
    tempw = (v2 & 0x7f800000) >> 23;
527
  if (v2 & 0x8000)
528
    {
529
      DSPCR |= DSPCR_OUFLAG6;
530
      tempx = 0;
531
    }
532
  else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
533
    {
534
      DSPCR |= DSPCR_OUFLAG6;
535
      tempx = 0xff;
536
    }
537
  else
538
    tempx = (v2 & 0x7f80) >> 7;
539
  GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
540
}
541
 
542
011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
543
"preceq.w.phl r, r"
544
*dsp:
545
{
546
  unsigned32 v1 = GPR[RT];
547
  GPR[RD] = EXTEND32 (v1 & 0xffff0000);
548
}
549
 
550
011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
551
"preceq.w.phr r, r"
552
*dsp:
553
{
554
  unsigned32 v1 = GPR[RT];
555
  GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16);
556
}
557
 
558
011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
559
"precequ.ph.qbl r, r"
560
*dsp:
561
{
562
  unsigned32 v1 = GPR[RT];
563
  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
564
}
565
 
566
011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
567
"precequ.ph.qbr r, r"
568
*dsp:
569
{
570
  unsigned32 v1 = GPR[RT];
571
  GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
572
}
573
 
574
011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
575
"precequ.ph.qbla r, r"
576
*dsp:
577
{
578
  unsigned32 v1 = GPR[RT];
579
  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
580
}
581
 
582
011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
583
"precequ.ph.qbra r, r"
584
*dsp:
585
{
586
  unsigned32 v1 = GPR[RT];
587
  GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
588
}
589
 
590
011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
591
"preceu.ph.qbl r, r"
592
*dsp:
593
{
594
  unsigned32 v1 = GPR[RT];
595
  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
596
}
597
 
598
011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
599
"preceu.ph.qbr r, r"
600
*dsp:
601
{
602
  unsigned32 v1 = GPR[RT];
603
  GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
604
}
605
 
606
011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
607
"preceu.ph.qbla r, r"
608
*dsp:
609
{
610
  unsigned32 v1 = GPR[RT];
611
  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
612
}
613
 
614
011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
615
"preceu.ph.qbra r, r"
616
*dsp:
617
{
618
  unsigned32 v1 = GPR[RT];
619
  GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
620
}
621
 
622
011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
623
"shll.qb r, r, "
624
*dsp:
625
{
626
  do_qb_shift (SD_, RD, RT, SHIFT3, 0);
627
}
628
 
629
011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
630
"shllv.qb r, r, r"
631
*dsp:
632
{
633
  unsigned32 shift = GPR[RS] & 0x7;
634
  do_qb_shift (SD_, RD, RT, shift, 0);
635
}
636
 
637
011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
638
"shll.ph r, r, "
639
*dsp:
640
{
641
  do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
642
}
643
 
644
011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
645
"shllv.ph r, r, r"
646
*dsp:
647
{
648
  unsigned32 shift = GPR[RS] & 0xf;
649
  do_ph_shift (SD_, RD, RT, shift, 0, 0);
650
}
651
 
652
011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
653
"shll_s.ph r, r, "
654
*dsp:
655
{
656
  do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
657
}
658
 
659
011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
660
"shllv_s.ph r, r, r"
661
*dsp:
662
{
663
  unsigned32 shift = GPR[RS] & 0xf;
664
  do_ph_shift (SD_, RD, RT, shift, 0, 1);
665
}
666
 
667
011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
668
"shll_s.w r, r, "
669
*dsp:
670
{
671
  do_w_shll (SD_, RD, RT, SHIFT5);
672
}
673
 
674
011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
675
"shllv_s.w r, r, r"
676
*dsp:
677
{
678
  unsigned32 shift = GPR[RS] & 0x1f;
679
  do_w_shll (SD_, RD, RT, shift);
680
}
681
 
682
011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
683
"shrl.qb r, r, "
684
*dsp:
685
{
686
  do_qb_shift (SD_, RD, RT, SHIFT3, 1);
687
}
688
 
689
011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
690
"shrlv.qb r, r, r"
691
*dsp:
692
{
693
  unsigned32 shift = GPR[RS] & 0x7;
694
  do_qb_shift (SD_, RD, RT, shift, 1);
695
}
696
 
697
011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
698
"shra.ph r, r, "
699
*dsp:
700
{
701
  do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
702
}
703
 
704
011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
705
"shrav.ph r, r, r"
706
*dsp:
707
{
708
  unsigned32 shift = GPR[RS] & 0xf;
709
  do_ph_shift (SD_, RD, RT, shift, 1, 0);
710
}
711
 
712
011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
713
"shra_r.ph r, r, "
714
*dsp:
715
{
716
  do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
717
}
718
 
719
011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
720
"shrav_r.ph r, r, r"
721
*dsp:
722
{
723
  unsigned32 shift = GPR[RS] & 0xf;
724
  do_ph_shift (SD_, RD, RT, shift, 1, 1);
725
}
726
 
727
011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
728
"shra_r.w r, r, "
729
*dsp:
730
{
731
  do_w_shra (SD_, RD, RT, SHIFT5);
732
}
733
 
734
011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
735
"shrav_r.w r, r, r"
736
*dsp:
737
{
738
  unsigned32 shift = GPR[RS] & 0x1f;
739
  do_w_shra (SD_, RD, RT, shift);
740
}
741
 
742
// loc: 0 = qhl, 1 = qhr
743
:function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
744
{
745
  int i;
746
  unsigned32 result = 0;
747
  unsigned32 v1 = GPR[rs];
748
  unsigned32 v2 = GPR[rt];
749
  unsigned16 h1, h2;
750
  unsigned32 prod;
751
  if (loc == 0)
752
    v1 >>= 16;
753
  for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
754
    {
755
      h1 = (unsigned16)(v1 & 0xff);
756
      h2 = (unsigned16)(v2 & 0xffff);
757
      prod = (unsigned32)h1 * (unsigned32)h2;
758
      if (prod > 0xffff)
759
        {
760
          DSPCR |= DSPCR_OUFLAG5;
761
          prod = 0xffff;
762
        }
763
      result |= ((unsigned32)prod << i);
764
    }
765
  GPR[rd] = EXTEND32 (result);
766
}
767
 
768
011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
769
"muleu_s.ph.qbl r, r, r"
770
*dsp:
771
{
772
  do_qb_muleu (SD_, RD, RS, RT, 0);
773
}
774
 
775
011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
776
"muleu_s.ph.qbr r, r, r"
777
*dsp:
778
{
779
  do_qb_muleu (SD_, RD, RS, RT, 1);
780
}
781
 
782
// round: 0 = no rounding, 1 = rounding
783
:function:::void:do_ph_mulq:int rd, int rs, int rt, int round
784
{
785
  int i;
786
  unsigned32 result = 0;
787
  unsigned32 v1 = GPR[rs];
788
  unsigned32 v2 = GPR[rt];
789
  signed16 h1, h2;
790
  signed32 prod;
791
  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
792
    {
793
      h1 = (signed16)(v1 & 0xffff);
794
      h2 = (signed16)(v2 & 0xffff);
795
      if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
796
        {
797
          DSPCR |= DSPCR_OUFLAG5;
798
          prod = 0x7fffffff;
799
        }
800
      else
801
        {
802
          prod = ((signed32)h1 * (signed32)h2) << 1;
803
          if (round == 1)
804
            prod += (signed32)0x8000;
805
        }
806
      result |= (((unsigned32)prod >> 16) << i);
807
    }
808
  GPR[rd] = EXTEND32 (result);
809
}
810
 
811
011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
812
"mulq_rs.ph r, r, r"
813
*dsp:
814
{
815
  do_ph_mulq (SD_, RD, RS, RT, 1);
816
}
817
 
818
// loc: 0 = phl, 1 = phr
819
:function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
820
{
821
  unsigned32 v1 = GPR[rs];
822
  unsigned32 v2 = GPR[rt];
823
  signed16 h1, h2;
824
  signed32 prod;
825
  if (loc == 0)
826
    {
827
      h1 = (signed16)(v1 >> 16);
828
      h2 = (signed16)(v2 >> 16);
829
    }
830
  else
831
    {
832
      h1 = (signed16)(v1 & 0xffff);
833
      h2 = (signed16)(v2 & 0xffff);
834
    }
835
  if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
836
    {
837
      DSPCR |= DSPCR_OUFLAG5;
838
      prod = 0x7fffffff;
839
    }
840
  else
841
    prod = ((signed32)h1 * (signed32)h2) << 1;
842
  GPR[rd] = EXTEND32 (prod);
843
}
844
 
845
011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
846
"muleq_s.w.phl r, r, r"
847
*dsp:
848
{
849
  do_ph_muleq (SD_, RD, RS, RT, 0);
850
}
851
 
852
011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
853
"muleq_s.w.phr r, r, r"
854
*dsp:
855
{
856
  do_ph_muleq (SD_, RD, RS, RT, 1);
857
}
858
 
859
// op: 0 = DPAU 1 = DPSU
860
// loc: 0 = qbl, 1 = qbr
861
:function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
862
{
863
  int i;
864
  unsigned32 v1 = GPR[rs];
865
  unsigned32 v2 = GPR[rt];
866
  unsigned8 h1, h2;
867
  unsigned32 lo = DSPLO(ac);
868
  unsigned32 hi = DSPHI(ac);
869
  unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
870
  if (loc == 0)
871
    {
872
      v1 >>= 16;
873
      v2 >>= 16;
874
    }
875
  for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
876
    {
877
      h1 = (unsigned8)(v1 & 0xff);
878
      h2 = (unsigned8)(v2 & 0xff);
879
      if (op == 0) // DPAU
880
        prod += (unsigned64)h1 * (unsigned64)h2;
881
      else // DPSU
882
        prod -= (unsigned64)h1 * (unsigned64)h2;
883
    }
884
  DSPLO(ac) = EXTEND32 (prod);
885
  DSPHI(ac) = EXTEND32 (prod >> 32);
886
}
887
 
888
011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
889
"dpau.h.qbl ac, r, r"
890
*dsp:
891
{
892
  do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
893
}
894
 
895
011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
896
"dpau.h.qbr ac, r, r"
897
*dsp:
898
{
899
  do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
900
}
901
 
902
011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
903
"dpsu.h.qbl ac, r, r"
904
*dsp:
905
{
906
  do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
907
}
908
 
909
011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
910
"dpsu.h.qbr ac, r, r"
911
*dsp:
912
{
913
  do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
914
}
915
 
916
// op: 0 = DPAQ 1 = DPSQ
917
:function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
918
{
919
  int i;
920
  unsigned32 v1 = GPR[rs];
921
  unsigned32 v2 = GPR[rt];
922
  signed16 h1, h2;
923
  signed32 result;
924
  unsigned32 lo = DSPLO(ac);
925
  unsigned32 hi = DSPHI(ac);
926
  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
927
  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
928
    {
929
      h1 = (signed16)(v1 & 0xffff);
930
      h2 = (signed16)(v2 & 0xffff);
931
      if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
932
        {
933
          DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
934
          result = (signed32)0x7fffffff;
935
        }
936
      else
937
        result = ((signed32)h1 * (signed32)h2) << 1;
938
 
939
      if (op == 0) // DPAQ
940
        prod += (signed64)result;
941
      else // DPSQ
942
        prod -= (signed64)result;
943
    }
944
  DSPLO(ac) = EXTEND32 (prod);
945
  DSPHI(ac) = EXTEND32 (prod >> 32);
946
}
947
 
948
011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
949
"dpaq_s.w.ph ac, r, r"
950
*dsp:
951
{
952
  do_ph_dot_product (SD_, AC, RS, RT, 0);
953
}
954
 
955
011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
956
"dpsq_s.w.ph ac, r, r"
957
*dsp:
958
{
959
  do_ph_dot_product (SD_, AC, RS, RT, 1);
960
}
961
 
962
011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
963
"mulsaq_s.w.ph ac, r, r"
964
*dsp:
965
{
966
  int i;
967
  unsigned32 v1 = GPR[RS];
968
  unsigned32 v2 = GPR[RT];
969
  signed16 h1, h2;
970
  signed32 result;
971
  unsigned32 lo = DSPLO(AC);
972
  unsigned32 hi = DSPHI(AC);
973
  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
974
  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
975
    {
976
      h1 = (signed16)(v1 & 0xffff);
977
      h2 = (signed16)(v2 & 0xffff);
978
      if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
979
        {
980
          DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC));
981
          result = (signed32) 0x7fffffff;
982
        }
983
      else
984
        result = ((signed32)h1 * (signed32)h2) << 1;
985
 
986
      if (i == 0)
987
        prod -= (signed64) result;
988
      else
989
        prod += (signed64) result;
990
    }
991
  DSPLO(AC) = EXTEND32 (prod);
992
  DSPHI(AC) = EXTEND32 (prod >> 32);
993
}
994
 
995
// op: 0 = DPAQ 1 = DPSQ
996
:function:::void:do_w_dot_product:int ac, int rs, int rt, int op
997
{
998
  unsigned32 v1 = GPR[rs];
999
  unsigned32 v2 = GPR[rt];
1000
  signed32 h1, h2;
1001
  signed64 result;
1002
  unsigned32 lo = DSPLO(ac);
1003
  unsigned32 hi = DSPHI(ac);
1004
  unsigned32 resultlo;
1005
  unsigned32 resulthi;
1006
  unsigned32 carry;
1007
  unsigned64 temp1;
1008
  signed64 temp2;
1009
  h1 = (signed32) v1;
1010
  h2 = (signed32) v2;
1011
  if (h1 == 0x80000000 && h2 == 0x80000000)
1012
    {
1013
      DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1014
      result = (signed64) 0x7fffffffffffffffLL;
1015
    }
1016
  else
1017
    result = ((signed64)h1 * (signed64)h2) << 1;
1018
  resultlo = (unsigned32)(result);
1019
  resulthi = (unsigned32)(result >> 32);
1020
  if (op ==0) // DPAQ
1021
    {
1022
      temp1 = (unsigned64)lo + (unsigned64)resultlo;
1023
      carry = (unsigned32)((temp1 >> 32) & 1);
1024
      temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) +
1025
              (signed64)((signed32)carry);
1026
    }
1027
  else // DPSQ
1028
    {
1029
      temp1 = (unsigned64)lo - (unsigned64)resultlo;
1030
      carry = (unsigned32)((temp1 >> 32) & 1);
1031
      temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) -
1032
              (signed64)((signed32)carry);
1033
    }
1034
  if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1035
    {
1036
      DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1037
      if (temp2 & 0x100000000LL)
1038
        {
1039
          DSPLO(ac) = EXTEND32 (0x00000000);
1040
          DSPHI(ac) = EXTEND32 (0x80000000);
1041
        }
1042
      else
1043
        {
1044
          DSPLO(ac) = EXTEND32 (0xffffffff);
1045
          DSPHI(ac) = EXTEND32 (0x7fffffff);
1046
        }
1047
    }
1048
  else
1049
    {
1050
      DSPLO(ac) = EXTEND32 (temp1);
1051
      DSPHI(ac) = EXTEND32 (temp2);
1052
    }
1053
}
1054
 
1055
011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1056
"dpaq_sa.l.w ac, r, r"
1057
*dsp:
1058
{
1059
  do_w_dot_product (SD_, AC, RS, RT, 0);
1060
}
1061
 
1062
011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1063
"dpsq_sa.l.w ac, r, r"
1064
*dsp:
1065
{
1066
  do_w_dot_product (SD_, AC, RS, RT, 1);
1067
}
1068
 
1069
// op: 0 = MAQ_S 1 = MAQ_SA
1070
// loc: 0 = phl, 1 = phr
1071
:function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1072
{
1073
  int i;
1074
  unsigned32 v1 = GPR[rs];
1075
  unsigned32 v2 = GPR[rt];
1076
  signed16 h1, h2;
1077
  signed32 result;
1078
  unsigned32 lo = DSPLO(ac);
1079
  unsigned32 hi = DSPHI(ac);
1080
  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1081
  if (loc == 0)
1082
    {
1083
      h1 = (signed16)(v1 >> 16);
1084
      h2 = (signed16)(v2 >> 16);
1085
    }
1086
  else
1087
    {
1088
      h1 = (signed16)(v1 & 0xffff);
1089
      h2 = (signed16)(v2 & 0xffff);
1090
    }
1091
  if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1092
    {
1093
      DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1094
      result = (signed32)0x7fffffff;
1095
    }
1096
  else
1097
    result = ((signed32)h1 * (signed32)h2) << 1;
1098
  prod += (signed64)result;
1099
  if (op == 1) // MAQ_SA
1100
    {
1101
      if (prod & 0x8000000000000000LL)
1102
        {
1103
          for (i = 62; i >= 31; i--)
1104
            {
1105
              if (!(prod & ((signed64)1 << i)))
1106
                {
1107
                  DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1108
                  prod = 0xffffffff80000000LL;
1109
                  break;
1110
                }
1111
            }
1112
        }
1113
      else
1114
        {
1115
          for (i = 62; i >= 31; i--)
1116
            {
1117
              if (prod & ((signed64)1 << i))
1118
                {
1119
                  DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1120
                  prod = 0x7fffffff;
1121
                  break;
1122
                }
1123
            }
1124
        }
1125
    }
1126
  DSPLO(ac) = EXTEND32 (prod);
1127
  DSPHI(ac) = EXTEND32 (prod >> 32);
1128
}
1129
 
1130
011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1131
"maq_s.w.phl ac, r, r"
1132
*dsp:
1133
{
1134
  do_ph_maq (SD_, AC, RS, RT, 0, 0);
1135
}
1136
 
1137
011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1138
"maq_s.w.phr ac, r, r"
1139
*dsp:
1140
{
1141
  do_ph_maq (SD_, AC, RS, RT, 0, 1);
1142
}
1143
 
1144
011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1145
"maq_sa.w.phl ac, r, r"
1146
*dsp:
1147
{
1148
  do_ph_maq (SD_, AC, RS, RT, 1, 0);
1149
}
1150
 
1151
011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1152
"maq_sa.w.phr ac, r, r"
1153
*dsp:
1154
{
1155
  do_ph_maq (SD_, AC, RS, RT, 1, 1);
1156
}
1157
 
1158
011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1159
"bitrev r, r"
1160
*dsp:
1161
{
1162
  int i;
1163
  unsigned32 v1 = GPR[RT];
1164
  unsigned32 h1 = 0;
1165
  for (i = 0; i < 16; i++)
1166
    {
1167
      if (v1 & (1 << i))
1168
        h1 |= (1 << (15 - i));
1169
    }
1170
  GPR[RD] = EXTEND32 (h1);
1171
}
1172
 
1173
011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1174
"insv r, r"
1175
*dsp:
1176
{
1177
  unsigned32 v1 = GPR[RS];
1178
  unsigned32 v2 = GPR[RT];
1179
  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1180
  unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
1181
  unsigned32 mask1, mask2, mask3, result;
1182
  if (size < 32)
1183
    mask1 = (1 << size) - 1;
1184
  else
1185
    mask1 = 0xffffffff;
1186
  mask2 = (1 << pos) - 1;
1187
  if (pos + size < 32)
1188
    mask3 = ~((1 << (pos + size)) - 1);
1189
  else
1190
    mask3 = 0;
1191
  result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
1192
  GPR[RT] = EXTEND32 (result);
1193
}
1194
 
1195
011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1196
"repl.qb r, "
1197
*dsp:
1198
{
1199
  GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8);
1200
}
1201
 
1202
011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1203
"replv.qb r, r"
1204
*dsp:
1205
{
1206
  unsigned32 v1 = GPR[RT];
1207
  v1 = v1 & 0xff;
1208
  GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
1209
}
1210
 
1211
011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1212
"repl.ph r, "
1213
*dsp:
1214
{
1215
  signed32 v1 = IMM10;
1216
  if (v1 & 0x200)
1217
    v1 |= 0xfffffc00;
1218
  GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
1219
}
1220
 
1221
011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1222
"replv.ph r, r"
1223
*dsp:
1224
{
1225
  unsigned32 v1 = GPR[RT];
1226
  v1 = v1 & 0xffff;
1227
  GPR[RD] = EXTEND32 ((v1 << 16) | v1);
1228
}
1229
 
1230
// op: 0 = EQ, 1 = LT, 2 = LE
1231
:function:::void:do_qb_cmpu:int rs, int rt, int op
1232
{
1233
  int i, j;
1234
  unsigned32 v1 = GPR[rs];
1235
  unsigned32 v2 = GPR[rt];
1236
  unsigned8 h1, h2;
1237
  unsigned32 mask;
1238
  for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1239
    {
1240
      h1 = (unsigned8)(v1 & 0xff);
1241
      h2 = (unsigned8)(v2 & 0xff);
1242
      mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1243
      DSPCR &= mask;
1244
      if (op == 0) // EQ
1245
        DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1246
      else if (op == 1) // LT
1247
        DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1248
      else // LE
1249
        DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1250
    }
1251
}
1252
 
1253
011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1254
"cmpu.eq.qb r, r"
1255
*dsp:
1256
{
1257
  do_qb_cmpu (SD_, RS, RT, 0);
1258
}
1259
 
1260
011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1261
"cmpu.lt.qb r, r"
1262
*dsp:
1263
{
1264
  do_qb_cmpu (SD_, RS, RT, 1);
1265
}
1266
 
1267
011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1268
"cmpu.le.qb r, r"
1269
*dsp:
1270
{
1271
  do_qb_cmpu (SD_, RS, RT, 2);
1272
}
1273
 
1274
// op: 0 = EQ, 1 = LT, 2 = LE
1275
:function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1276
{
1277
  int i, j;
1278
  unsigned32 v1 = GPR[rs];
1279
  unsigned32 v2 = GPR[rt];
1280
  unsigned8 h1, h2;
1281
  unsigned32 result = 0;
1282
  for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1283
    {
1284
      h1 = (unsigned8)(v1 & 0xff);
1285
      h2 = (unsigned8)(v2 & 0xff);
1286
      if (op == 0) // EQ
1287
        result |= ((h1 == h2) << j);
1288
      else if (op == 1) // LT
1289
        result |= ((h1 < h2) << j);
1290
      else // LE
1291
        result |= ((h1 <= h2) << j);
1292
    }
1293
  GPR[rd] = EXTEND32 (result);
1294
}
1295
 
1296
011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1297
"cmpgu.eq.qb r, r, r"
1298
*dsp:
1299
{
1300
  do_qb_cmpgu (SD_, RD, RS, RT, 0);
1301
}
1302
 
1303
011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1304
"cmpgu.lt.qb r, r, r"
1305
*dsp:
1306
{
1307
  do_qb_cmpgu (SD_, RD, RS, RT, 1);
1308
}
1309
 
1310
011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1311
"cmpgu.le.qb r, r, r"
1312
*dsp:
1313
{
1314
  do_qb_cmpgu (SD_, RD, RS, RT, 2);
1315
}
1316
 
1317
// op: 0 = EQ, 1 = LT, 2 = LE
1318
:function:::void:do_ph_cmpu:int rs, int rt, int op
1319
{
1320
  int i, j;
1321
  unsigned32 v1 = GPR[rs];
1322
  unsigned32 v2 = GPR[rt];
1323
  signed16 h1, h2;
1324
  unsigned32 mask;
1325
  for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1326
    {
1327
      h1 = (signed16)(v1 & 0xffff);
1328
      h2 = (signed16)(v2 & 0xffff);
1329
      mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1330
      DSPCR &= mask;
1331
      if (op == 0) // EQ
1332
        DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1333
      else if (op == 1) // LT
1334
        DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1335
      else // LE
1336
        DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1337
    }
1338
}
1339
 
1340
011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1341
"cmp.eq.ph r, r"
1342
*dsp:
1343
{
1344
  do_ph_cmpu (SD_, RS, RT, 0);
1345
}
1346
 
1347
011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1348
"cmp.lt.ph r, r"
1349
*dsp:
1350
{
1351
  do_ph_cmpu (SD_, RS, RT, 1);
1352
}
1353
 
1354
011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1355
"cmp.le.ph r, r"
1356
*dsp:
1357
{
1358
  do_ph_cmpu (SD_, RS, RT, 2);
1359
}
1360
 
1361
011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1362
"pick.qb r, r, r"
1363
*dsp:
1364
{
1365
  int i, j;
1366
  unsigned32 v1 = GPR[RS];
1367
  unsigned32 v2 = GPR[RT];
1368
  unsigned8 h1, h2;
1369
  unsigned32 result = 0;
1370
  for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1371
    {
1372
      h1 = (unsigned8)(v1 & 0xff);
1373
      h2 = (unsigned8)(v2 & 0xff);
1374
      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1375
        result |= (unsigned32)(h1 << i);
1376
      else
1377
        result |= (unsigned32)(h2 << i);
1378
    }
1379
  GPR[RD] = EXTEND32 (result);
1380
}
1381
 
1382
011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1383
"pick.ph r, r, r"
1384
*dsp:
1385
{
1386
  int i, j;
1387
  unsigned32 v1 = GPR[RS];
1388
  unsigned32 v2 = GPR[RT];
1389
  unsigned16 h1, h2;
1390
  unsigned32 result = 0;
1391
  for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1392
    {
1393
      h1 = (unsigned16)(v1 & 0xffff);
1394
      h2 = (unsigned16)(v2 & 0xffff);
1395
      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1396
        result |= (unsigned32)(h1 << i);
1397
      else
1398
        result |= (unsigned32)(h2 << i);
1399
    }
1400
  GPR[RD] = EXTEND32 (result);
1401
}
1402
 
1403
011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1404
"packrl.ph r, r, r"
1405
*dsp:
1406
{
1407
  unsigned32 v1 = GPR[RS];
1408
  unsigned32 v2 = GPR[RT];
1409
  GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16));
1410
}
1411
 
1412
// op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1413
:function:::void:do_w_extr:int rt, int ac, int shift, int op
1414
{
1415
  int i;
1416
  unsigned32 lo = DSPLO(ac);
1417
  unsigned32 hi = DSPHI(ac);
1418
  unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1419
  signed64 result = (signed64)prod;
1420
  int setcond = 0;
1421
  if (!(prod & 0x8000000000000000LL))
1422
    {
1423
      for (i = 62; i >= (shift + 31); i--)
1424
        {
1425
          if (prod & ((unsigned64)1 << i))
1426
            {
1427
              DSPCR |= DSPCR_OUFLAG7;
1428
              setcond = 1;
1429
              break;
1430
            }
1431
        }
1432
      if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1433
        {
1434
          DSPCR |= DSPCR_OUFLAG7;
1435
          setcond = 1;
1436
        }
1437
    }
1438
  else
1439
    {
1440
      for (i = 62; i >= (shift + 31); i--)
1441
        {
1442
          if (!(prod & ((unsigned64)1 << i)))
1443
            {
1444
              DSPCR |= DSPCR_OUFLAG7;
1445
              setcond = 2;
1446
              break;
1447
            }
1448
        }
1449
    }
1450
  if (op == 0) // EXTR
1451
    result = result >> shift;
1452
  else if (op == 1) // EXTR_R
1453
    {
1454
      if (shift != 0)
1455
        result = ((result >> (shift - 1)) + 1) >> 1;
1456
      else
1457
        result = result >> shift;
1458
    }
1459
  else // EXTR_RS
1460
    {
1461
      if (setcond == 1)
1462
        result = 0x7fffffff;
1463
      else if (setcond == 2)
1464
        result = 0x80000000;
1465
      else
1466
        {
1467
          if (shift != 0)
1468
            result = ((result >> (shift - 1)) + 1) >> 1;
1469
          else
1470
            result = result >> shift;
1471
        }
1472
    }
1473
  GPR[rt] = EXTEND32 (result);
1474
}
1475
 
1476
011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1477
"extr.w r, ac, "
1478
*dsp:
1479
{
1480
  do_w_extr (SD_, RT, AC, SHIFT, 0);
1481
}
1482
 
1483
011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1484
"extrv.w r, ac, r"
1485
*dsp:
1486
{
1487
  unsigned32 shift = GPR[RS] & 0x1f;
1488
  do_w_extr (SD_, RT, AC, shift, 0);
1489
}
1490
 
1491
011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1492
"extr_r.w r, ac, "
1493
*dsp:
1494
{
1495
  do_w_extr (SD_, RT, AC, SHIFT, 1);
1496
}
1497
 
1498
011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1499
"extrv_r.w r, ac, r"
1500
*dsp:
1501
{
1502
  unsigned32 shift = GPR[RS] & 0x1f;
1503
  do_w_extr (SD_, RT, AC, shift, 1);
1504
}
1505
 
1506
011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1507
"extr_rs.w r, ac, "
1508
*dsp:
1509
{
1510
  do_w_extr (SD_, RT, AC, SHIFT, 2);
1511
}
1512
 
1513
011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1514
"extrv_rs.w r, ac, r"
1515
*dsp:
1516
{
1517
  unsigned32 shift = GPR[RS] & 0x1f;
1518
  do_w_extr (SD_, RT, AC, shift, 2);
1519
}
1520
 
1521
:function:::void:do_h_extr:int rt, int ac, int shift
1522
{
1523
  int i;
1524
  unsigned32 lo = DSPLO(ac);
1525
  unsigned32 hi = DSPHI(ac);
1526
  unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1527
  signed64 result = (signed64)prod;
1528
  signed64 value = 0xffffffffffff8000LL;
1529
  result >>= shift;
1530
  if (result > 0x7fff)
1531
    {
1532
      result = 0x7fff;
1533
      DSPCR |= DSPCR_OUFLAG7;
1534
    }
1535
  else if (result < value)
1536
    {
1537
      result = value;
1538
      DSPCR |= DSPCR_OUFLAG7;
1539
    }
1540
  GPR[rt] = EXTEND32 (result);
1541
}
1542
 
1543
011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1544
"extr_s.h r, ac, "
1545
*dsp:
1546
{
1547
  do_h_extr (SD_, RT, AC, SHIFT);
1548
}
1549
 
1550
011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1551
"extrv_s.h r, ac, r"
1552
*dsp:
1553
{
1554
  unsigned32 shift = GPR[RS] & 0x1f;
1555
  do_h_extr (SD_, RT, AC, shift);
1556
}
1557
 
1558
// op: 0 = EXTP, 1 = EXTPDP
1559
:function:::void:do_extp:int rt, int ac, int size, int op
1560
{
1561
  signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1562
  unsigned32 lo = DSPLO(ac);
1563
  unsigned32 hi = DSPHI(ac);
1564
  unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1565
  unsigned64 result = 0;
1566
  if (pos - (size + 1) >= -1)
1567
    {
1568
      prod >>= (pos - size);
1569
      result = prod & (((unsigned64)1 << (size + 1)) - 1);
1570
      DSPCR &= (~DSPCR_EFI_SMASK);
1571
      if (op == 1) // EXTPDP
1572
        {
1573
          if (pos - (size + 1) >= 0)
1574
            {
1575
              DSPCR &= (~DSPCR_POS_SMASK);
1576
              DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1577
            }
1578
          else if (pos - (size + 1) == -1)
1579
            {
1580
              DSPCR |= DSPCR_POS_SMASK;
1581
            }
1582
        }
1583
    }
1584
  else
1585
    {
1586
      DSPCR |= DSPCR_EFI;
1587
      Unpredictable ();
1588
    }
1589
  GPR[rt] = EXTEND32 (result);
1590
}
1591
 
1592
011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1593
"extp r, ac, "
1594
*dsp:
1595
{
1596
  do_extp (SD_, RT, AC, SIZE, 0);
1597
}
1598
 
1599
011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1600
"extpv r, ac, r"
1601
*dsp:
1602
{
1603
  unsigned32 size = GPR[RS] & 0x1f;
1604
  do_extp (SD_, RT, AC, size, 0);
1605
}
1606
 
1607
011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1608
"extpdp r, ac, "
1609
*dsp:
1610
{
1611
  do_extp (SD_, RT, AC, SIZE, 1);
1612
}
1613
 
1614
011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1615
"extpdpv r, ac, r"
1616
*dsp:
1617
{
1618
  unsigned32 size = GPR[RS] & 0x1f;
1619
  do_extp (SD_, RT, AC, size, 1);
1620
}
1621
 
1622
:function:::void:do_shilo:int ac, int shift
1623
{
1624
  unsigned32 lo = DSPLO(ac);
1625
  unsigned32 hi = DSPHI(ac);
1626
  unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1627
  if (shift > 31)
1628
    shift = shift - 64;
1629
  if (shift >= 0)
1630
    prod >>= shift;
1631
  else
1632
    prod <<= (-shift);
1633
  DSPLO(ac) = EXTEND32 (prod);
1634
  DSPHI(ac) = EXTEND32 (prod >> 32);
1635
}
1636
 
1637
011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
1638
"shilo ac, "
1639
*dsp:
1640
{
1641
  do_shilo (SD_, AC, SHIFT6);
1642
}
1643
 
1644
011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
1645
"shilov ac, r"
1646
*dsp:
1647
{
1648
  signed32 shift = GPR[RS] & 0x3f;
1649
  do_shilo (SD_, AC, shift);
1650
}
1651
 
1652
011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
1653
"mthlip r, ac"
1654
*dsp:
1655
{
1656
  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1657
  DSPHI(AC) = DSPLO(AC);
1658
  DSPLO(AC) = GPR[RS];
1659
  if (pos >= 32)
1660
    Unpredictable ();
1661
  else
1662
    pos += 32;
1663
  DSPCR &= (~DSPCR_POS_SMASK);
1664
  DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1665
}
1666
 
1667
011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
1668
"wrdsp r":MASK10 == 1111111111
1669
"wrdsp r, "
1670
*dsp:
1671
{
1672
  unsigned32 v1 = GPR[RS];
1673
  if (MASK10 & 0x1)
1674
    {
1675
      DSPCR &= (~DSPCR_POS_SMASK);
1676
      DSPCR |= (v1 & DSPCR_POS_SMASK);
1677
    }
1678
  if (MASK10 & 0x2)
1679
    {
1680
      DSPCR &= (~DSPCR_SCOUNT_SMASK);
1681
      DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
1682
    }
1683
  if (MASK10 & 0x4)
1684
    {
1685
      DSPCR &= (~DSPCR_CARRY_SMASK);
1686
      DSPCR |= (v1 & DSPCR_CARRY_SMASK);
1687
    }
1688
  if (MASK10 & 0x8)
1689
    {
1690
      DSPCR &= (~DSPCR_OUFLAG_SMASK);
1691
      DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
1692
    }
1693
  if (MASK10 & 0x10)
1694
    {
1695
      DSPCR &= (~DSPCR_CCOND_SMASK);
1696
      DSPCR |= (v1 & DSPCR_CCOND_SMASK);
1697
    }
1698
  if (MASK10 & 0x20)
1699
    {
1700
      DSPCR &= (~DSPCR_EFI_SMASK);
1701
      DSPCR |= (v1 & DSPCR_EFI_SMASK);
1702
    }
1703
}
1704
 
1705
011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
1706
"rddsp r":MASK10 == 1111111111
1707
"rddsp r, "
1708
*dsp:
1709
{
1710
  unsigned32 result = 0;
1711
  if (MASK10 & 0x1)
1712
    {
1713
      result &= (~DSPCR_POS_SMASK);
1714
      result |= (DSPCR & DSPCR_POS_SMASK);
1715
    }
1716
  if (MASK10 & 0x2)
1717
    {
1718
      result &= (~DSPCR_SCOUNT_SMASK);
1719
      result |= (DSPCR & DSPCR_SCOUNT_SMASK);
1720
    }
1721
  if (MASK10 & 0x4)
1722
    {
1723
      result &= (~DSPCR_CARRY_SMASK);
1724
      result |= (DSPCR & DSPCR_CARRY_SMASK);
1725
    }
1726
  if (MASK10 & 0x8)
1727
    {
1728
      result &= (~DSPCR_OUFLAG_SMASK);
1729
      result |= (DSPCR & DSPCR_OUFLAG_SMASK);
1730
    }
1731
  if (MASK10 & 0x10)
1732
    {
1733
      result &= (~DSPCR_CCOND_SMASK);
1734
      result |= (DSPCR & DSPCR_CCOND_SMASK);
1735
    }
1736
  if (MASK10 & 0x20)
1737
    {
1738
      result &= (~DSPCR_EFI_SMASK);
1739
      result |= (DSPCR & DSPCR_EFI_SMASK);
1740
    }
1741
  GPR[RD] = EXTEND32 (result);
1742
}
1743
 
1744
011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
1745
"lbux r, r(r)"
1746
*dsp:
1747
{
1748
  GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]);
1749
}
1750
 
1751
011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
1752
"lhx r, r(r)"
1753
*dsp:
1754
{
1755
  GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX]));
1756
}
1757
 
1758
011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
1759
"lwx r, r(r)"
1760
*dsp:
1761
{
1762
  GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
1763
}
1764
 
1765
000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
1766
"bposge32 "
1767
*dsp:
1768
{
1769
  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1770
  address_word offset = EXTEND16 (OFFSET) << 2;
1771
  if (pos >= 32)
1772
    {
1773
      DELAY_SLOT (NIA + offset);
1774
    }
1775
}

powered by: WebSVN 2.1.0

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