arm: Support pac_key_* register operand for MRS/MSR in Armv8.1-M Mainline
[binutils-gdb.git] / sim / mips / dsp.igen
bloba52da17d187e1cb01ba5819cd0da697b3134a5f0
1 // -*- C -*-
3 // Simulator definition for the MIPS DSP ASE.
4 // Copyright (C) 2005-2024 Free Software Foundation, Inc.
5 // Contributed by MIPS Technologies, Inc.  Written by Chao-ying Fu.
6 //
7 // This file is part of the MIPS sim
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.
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.
19 // You should have received a copy of the GNU General Public License
20 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
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
27   int i;
28   int32_t h0 = 0;
29   int16_t h1, h2;
30   uint32_t v1 = GPR[rs];
31   uint32_t v2 = GPR[rt];
32   uint32_t result = 0;
33   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
34     {
35       h1 = (int16_t)(v1 & 0xffff);
36       h2 = (int16_t)(v2 & 0xffff);
37       if (op == 0) // ADD
38         h0 = (int32_t)h1 + (int32_t)h2;
39       else if (op == 1) // SUB
40         h0 = (int32_t)h1 - (int32_t)h2;
41       else // MUL
42         h0 = (int32_t)h1 * (int32_t)h2;
43       if (h0 > (int32_t)0x7fff || h0 < (int32_t)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 > (int32_t)0x7fff)
52                 h0 = 0x7fff;
53               else
54                 h0 = 0x8000;
55             }
56         }
57       result |= ((uint32_t)((uint16_t)h0) << i);
58     }
59   GPR[rd] = EXTEND32 (result);
62 // op: 0 = ADD, 1 = SUB
63 :function:::void:do_w_op:int rd, int rs, int rt, int op
65   int64_t h0;
66   int32_t h1, h2;
67   uint32_t v1 = GPR[rs];
68   uint32_t v2 = GPR[rt];
69   h1 = (int32_t)v1;
70   h2 = (int32_t)v2;
71   if (op == 0) // ADD
72     h0 = (int64_t)h1 + (int64_t)h2;
73   else // SUB
74     h0 = (int64_t)h1 - (int64_t)h2;
75   if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
76     {
77       DSPCR |= DSPCR_OUFLAG4;
78       if (h0 & 0x100000000LL)
79         h0 = 0x80000000;
80       else
81         h0 = 0x7fffffff;
82     }
83   GPR[rd] = EXTEND32 (h0);
86 // op: 0 = ADD, 1 = SUB
87 // sat: 0 = no saturation, 1 = saturation
88 :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat
90   int i;
91   uint32_t h0;
92   uint8_t h1, h2;
93   uint32_t v1 = GPR[rs];
94   uint32_t v2 = GPR[rt];
95   uint32_t result = 0;
96   for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
97     {
98       h1 = (uint8_t)(v1 & 0xff);
99       h2 = (uint8_t)(v2 & 0xff);
100       if (op == 0) // ADD
101         h0 = (uint32_t)h1 + (uint32_t)h2;
102       else // SUB
103         h0 = (uint32_t)h1 - (uint32_t)h2;
104       if (h0 & 0x100)
105         {
106           DSPCR |= DSPCR_OUFLAG4;
107           if (sat == 1)
108             {
109               if (op == 0) // ADD
110                 h0 = 0xff;
111               else // SUB
112                 h0 = 0;
113             }
114         }
115       result |= ((uint32_t)((uint8_t)h0) << i);
116     }
117   GPR[rd] = EXTEND32 (result);
120 // op: 0 = left, 1 = right
121 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
123   int i, j;
124   uint8_t h0;
125   uint32_t v1 = GPR[rt];
126   uint32_t result = 0;
127   for (i = 0; i < 32; i += 8, v1 >>= 8)
128     {
129       h0 = (uint8_t)(v1 & 0xff);
130       if (op == 0) // left
131         {
132           for (j = 7; j >= 8 - shift; j--)
133             {
134               if (h0 & (1<<j))
135                 {
136                   DSPCR |= DSPCR_OUFLAG6;
137                   break;
138                 }
139             }
140           h0 = h0 << shift;
141         }
142       else // right
143         h0 = h0 >> shift;
144       result |= ((uint32_t)h0 << i);
145     }
146   GPR[rd] = EXTEND32 (result);
149 // op: 0 = left, 1 = right
150 // sat: 0 = no saturation/rounding, 1 = saturation/rounding
151 :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat
153   int i, j;
154   int16_t h0;
155   uint32_t v1 = GPR[rt];
156   uint32_t result = 0;
157   int setcond;
158   for (i = 0; i < 32; i += 16, v1 >>= 16)
159     {
160       h0 = (int16_t)(v1 & 0xffff);
161       if (op == 0) // left
162         {
163           setcond = 0;
164           if (h0 & (1<<15))
165             {
166               for (j = 14; j >= 15 - shift; j--)
167                 {
168                   if (!(h0 & (1 << j)))
169                     {
170                       DSPCR |= DSPCR_OUFLAG6;
171                       setcond = 1;
172                       break;
173                     }
174                 }
175             }
176           else
177             {
178               for (j = 14; j >= 15 - shift; j--)
179                 {
180                   if (h0 & (1 << j))
181                     {
182                       DSPCR |= DSPCR_OUFLAG6;
183                       setcond = 2;
184                       break;
185                     }
186                 }
187             }
188           h0 = h0 << shift;
189           if (sat == 1)
190             {
191               if (setcond == 2)
192                 h0 = 0x7fff;
193               else if (setcond == 1)
194                 h0 = 0x8000;
195             }
196         }
197       else // right
198         {
199           if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
200             h0 = (h0 >> shift) + 1;
201           else
202             h0 = h0 >> shift;
203         }
205       result |= ((uint32_t)((uint16_t)h0) << i);
206     }
207   GPR[rd] = EXTEND32 (result);
210 :function:::void:do_w_shll:int rd, int rt, int shift
212   int i;
213   uint32_t v1 = GPR[rt];
214   uint32_t result = 0;
215   int setcond = 0;
216   if (v1 & (1 << 31))
217     {
218       for (i = 30; i >= 31 - shift; i--)
219         {
220           if (!(v1 & (1 << i)))
221             {
222               DSPCR |= DSPCR_OUFLAG6;
223               setcond = 1;
224               break;
225             }
226         }
227     }
228   else
229     {
230       for (i = 30; i >= 31 - shift; i--)
231         {
232           if (v1 & (1 << i))
233             {
234               DSPCR |= DSPCR_OUFLAG6;
235               setcond = 2;
236               break;
237             }
238         }
239     }
240   if (setcond == 2)
241     result = 0x7fffffff;
242   else if (setcond == 1)
243     result = 0x80000000;
244   else
245     result = v1 << shift;
246   GPR[rd] = EXTEND32 (result);
249 :function:::void:do_ph_s_absq:int rd, int rt
251   int i;
252   int16_t h0;
253   uint32_t v1 = GPR[rt];
254   uint32_t result = 0;
255   for (i = 0; i < 32; i += 16, v1 >>= 16)
256     {
257       h0 = (int16_t)(v1 & 0xffff);
258       if (h0 == (int16_t)0x8000)
259         {
260           DSPCR |= DSPCR_OUFLAG4;
261           h0 = 0x7fff;
262         }
263       else if (h0 & 0x8000)
264         h0 = -h0;
265       result |= ((uint32_t)((uint16_t)h0) << i);
266     }
267   GPR[rd] = EXTEND32 (result);
270 :function:::void:do_w_s_absq:int rd, int rt
272   uint32_t v1 = GPR[rt];
273   int32_t h0 = (int32_t)v1;
274   if (h0 == (int32_t)0x80000000)
275     {
276       DSPCR |= DSPCR_OUFLAG4;
277       h0 = 0x7fffffff;
278     }
279   else if (h0 & 0x80000000)
280     h0 = -h0;
281   GPR[rd] = EXTEND32 (h0);
284 :function:::void:do_qb_s_absq:int rd, int rt
286   int i;
287   int8_t q0;
288   uint32_t v1 = GPR[rt];
289   uint32_t result = 0;
290   for (i = 0; i < 32; i += 8, v1 >>= 8)
291     {
292       q0 = (int8_t)(v1 & 0xff);
293       if (q0 == (int8_t)0x80)
294         {
295           DSPCR |= DSPCR_OUFLAG4;
296           q0 = 0x7f;
297         }
298       else if (q0 & 0x80)
299         q0 = -q0;
300       result |= ((uint32_t)((uint8_t)q0) << i);
301     }
302   GPR[rd] = EXTEND32 (result);
305 :function:::void:do_addsc:int rd, int rs, int rt
307   uint32_t v1 = GPR[rs];
308   uint32_t v2 = GPR[rt];
309   uint64_t h0;
310   h0 = (uint64_t)v1 + (uint64_t)v2;
311   if (h0 & 0x100000000LL)
312     DSPCR |= DSPCR_CARRY;
313   GPR[rd] = EXTEND32 (h0);
316 :function:::void:do_addwc:int rd, int rs, int rt
318   uint32_t v1 = GPR[rs];
319   uint32_t v2 = GPR[rt];
320   uint64_t h0;
321   int32_t h1 = (int32_t) v1;
322   int32_t h2 = (int32_t) v2;
323   h0 = (int64_t)h1 + (int64_t)h2
324     + (int64_t)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
325   if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
326     DSPCR |= DSPCR_OUFLAG4;
327   GPR[rd] = EXTEND32 (h0);
330 :function:::void:do_bitrev:int rd, int rt
332   int i;
333   uint32_t v1 = GPR[rt];
334   uint32_t h1 = 0;
335   for (i = 0; i < 16; i++)
336     {
337       if (v1 & (1 << i))
338         h1 |= (1 << (15 - i));
339     }
340   GPR[rd] = EXTEND32 (h1);
343 // op: 0 = EXTPV, 1 = EXTPDPV
344 :function:::void:do_extpv:int rt, int ac, int rs, int op
346   uint32_t size = GPR[rs] & 0x1f;
347   do_extp (SD_, rt, ac, size, op);
350 // op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS
351 :function:::void:do_extrv:int rt, int ac, int rs, int op
353   uint32_t shift = GPR[rs] & 0x1f;
354   do_w_extr (SD_, rt, ac, shift, op);
357 :function:::void:do_extrv_s_h:int rt, int ac, int rs
359   uint32_t shift = GPR[rs] & 0x1f;
360   do_h_extr (SD_, rt, ac, shift);
363 :function:::void:do_insv:int rt, int rs
365   uint32_t v1 = GPR[rs];
366   uint32_t v2 = GPR[rt];
367   uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
368   uint32_t size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
369   uint32_t mask1, mask2, mask3, result;
370   if (size < 32)
371     mask1 = (1 << size) - 1;
372   else
373     mask1 = 0xffffffff;
374   mask2 = (1 << pos) - 1;
375   if (pos + size < 32)
376     mask3 = ~((1 << (pos + size)) - 1);
377   else
378     mask3 = 0;
379   result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
380   GPR[rt] = EXTEND32 (result);
383 // op: 0 = NORMAL,  1 = EXTEND16, 2 = EXTEND32
384 :function:::void:do_lxx:int rd, int base, int index, int op
386   if (op == 0)
387     GPR[rd] = do_load (SD_, AccessLength_BYTE, GPR[base], GPR[index]);
388   else if (op == 1)
389     GPR[rd] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], GPR[index]));
390   else if (op == 2)
391     GPR[rd] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
394 :function:::void:do_modsub:int rd, int rs, int rt
396   uint32_t result = 0;
397   uint32_t v1 = GPR[rs];
398   uint32_t v2 = GPR[rt];
399   uint32_t decr = v2 & 0xff;
400   uint32_t lastindex = (v2 & 0xffff00) >> 8;
401   if (v1 == 0)
402     result = lastindex;
403   else
404     result =  v1 - decr;
405   GPR[rd] = EXTEND32 (result);
408 :function:::void:do_mthlip:int rs, int ac
410   uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
411   DSPHI(ac) = DSPLO(ac);
412   DSPLO(ac) = GPR[rs];
413   if (pos >= 32)
414     Unpredictable ();
415   else
416     pos += 32;
417   DSPCR &= (~DSPCR_POS_SMASK);
418   DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
421 :function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt
423   int i;
424   uint32_t v1 = GPR[rs];
425   uint32_t v2 = GPR[rt];
426   int16_t h1, h2;
427   int32_t result;
428   uint32_t lo = DSPLO(ac);
429   uint32_t hi = DSPHI(ac);
430   int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo);
431   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
432     {
433       h1 = (int16_t)(v1 & 0xffff);
434       h2 = (int16_t)(v2 & 0xffff);
435       if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000)
436         {
437           DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
438           result = (int32_t) 0x7fffffff;
439         }
440       else
441         result = ((int32_t)h1 * (int32_t)h2) << 1;
443       if (i == 0)
444         prod -= (int64_t) result;
445       else
446         prod += (int64_t) result;
447     }
448   DSPLO(ac) = EXTEND32 (prod);
449   DSPHI(ac) = EXTEND32 (prod >> 32);
452 :function:::void:do_ph_packrl:int rd, int rs, int rt
455   uint32_t v1 = GPR[rs];
456   uint32_t v2 = GPR[rt];
457   GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16));
460 :function:::void:do_qb_pick:int rd, int rs, int rt
462   int i, j;
463   uint32_t v1 = GPR[rs];
464   uint32_t v2 = GPR[rt];
465   uint8_t h1, h2;
466   uint32_t result = 0;
467   for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
468     {
469       h1 = (uint8_t)(v1 & 0xff);
470       h2 = (uint8_t)(v2 & 0xff);
471       if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
472         result |= (uint32_t)(h1 << i);
473       else
474         result |= (uint32_t)(h2 << i);
475     }
476   GPR[rd] = EXTEND32 (result);
479 :function:::void:do_ph_pick:int rd, int rs, int rt
481   int i, j;
482   uint32_t v1 = GPR[rs];
483   uint32_t v2 = GPR[rt];
484   uint16_t h1, h2;
485   uint32_t result = 0;
486   for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
487     {
488       h1 = (uint16_t)(v1 & 0xffff);
489       h2 = (uint16_t)(v2 & 0xffff);
490       if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
491         result |= (uint32_t)(h1 << i);
492       else
493         result |= (uint32_t)(h2 << i);
494     }
495   GPR[rd] = EXTEND32 (result);
498 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
499 :function:::void:do_qb_ph_precequ:int rd, int rt, int op
501   uint32_t v1 = GPR[rt];
502   if (op == 0)
503     GPR[rd] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
504   else if (op == 1)
505     GPR[rd] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
506   else if (op == 2)
507     GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
508   else if (op == 3)
509     GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
512 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
513 :function:::void:do_qb_ph_preceu:int rd, int rt, int op
515   uint32_t v1 = GPR[rt];
516   if (op == 0)
517     GPR[rd] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
518   else if (op == 1)
519     GPR[rd] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
520   else if (op == 2)
521     GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
522   else if (op == 3)
523     GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
526 // op: 0 = .PHL, 1 = PHR
527 :function:::void:do_w_preceq:int rd, int rt, int op
529   uint32_t v1 = GPR[rt];
530   if (op == 0)
531     GPR[rd] = EXTEND32 (v1 & 0xffff0000);
532   else if (op == 1)
533     GPR[rd] = EXTEND32 ((v1 & 0xffff) << 16);
536 :function:::void:do_w_ph_precrq:int rd, int rs, int rt
538   uint32_t v1 = GPR[rs];
539   uint32_t v2 = GPR[rt];
540   uint32_t tempu = (v1 & 0xffff0000) >> 16;
541   uint32_t tempv = (v2 & 0xffff0000) >> 16;
542   GPR[rd] = EXTEND32 ((tempu << 16) | tempv);
545 // sat: 0 = PRECRQ.QB.PH, 1 = PRECRQU_S.QB.PH
546 :function:::void:do_ph_qb_precrq:int rd, int rs, int rt, int sat
548   uint32_t v1 = GPR[rs];
549   uint32_t v2 = GPR[rt];
550   uint32_t tempu = 0, tempv = 0, tempw = 0, tempx = 0;
551   if (sat == 0)
552     {
553       tempu = (v1 & 0xff000000) >> 24;
554       tempv = (v1 & 0xff00) >> 8;
555       tempw = (v2 & 0xff000000) >> 24;
556       tempx = (v2 & 0xff00) >> 8;
557     }
558   else if (sat == 1)
559     {
560       if (v1 & 0x80000000)
561         {
562           DSPCR |= DSPCR_OUFLAG6;
563           tempu = 0;
564         }
565       else if (!(v1 & 0x80000000) && ((v1 >> 16) > (uint32_t)0x7f80))
566         {
567           DSPCR |= DSPCR_OUFLAG6;
568           tempu = 0xff;
569         }
570       else
571         tempu = (v1 & 0x7f800000) >> 23;
572       if (v1 & 0x8000)
573         {
574           DSPCR |= DSPCR_OUFLAG6;
575           tempv = 0;
576         }
577       else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (uint32_t)0x7f80))
578         {
579           DSPCR |= DSPCR_OUFLAG6;
580           tempv = 0xff;
581         }
582       else
583         tempv = (v1 & 0x7f80) >> 7;
584       if (v2 & 0x80000000)
585         {
586           DSPCR |= DSPCR_OUFLAG6;
587           tempw = 0;
588         }
589       else if (!(v2 & 0x80000000) && ((v2 >> 16) > (uint32_t)0x7f80))
590         {
591           DSPCR |= DSPCR_OUFLAG6;
592           tempw = 0xff;
593         }
594       else
595         tempw = (v2 & 0x7f800000) >> 23;
596       if (v2 & 0x8000)
597         {
598           DSPCR |= DSPCR_OUFLAG6;
599           tempx = 0;
600         }
601       else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (uint32_t)0x7f80))
602         {
603           DSPCR |= DSPCR_OUFLAG6;
604           tempx = 0xff;
605         }
606       else
607         tempx = (v2 & 0x7f80) >> 7;
608     }
609   GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
612 :function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt
614   uint32_t v1 = GPR[rs];
615   uint32_t v2 = GPR[rt];
616   int32_t h1 = (int32_t)v1;
617   int32_t h2 = (int32_t)v2;
618   int64_t temp1 = (int64_t)h1 + (int64_t)0x8000;
619   int32_t temp2;
620   int64_t temp3 = (int64_t)h2 + (int64_t)0x8000;
621   int32_t temp4;
622   if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
623     {
624       DSPCR |= DSPCR_OUFLAG6;
625       temp2 = 0x7fff;
626     }
627   else
628     temp2 = (int32_t)((temp1 & 0xffff0000) >> 16);
629   if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
630     {
631       DSPCR |= DSPCR_OUFLAG6;
632       temp4 = 0x7fff;
633     }
634   else
635     temp4 = (int32_t)((temp3 & 0xffff0000) >> 16);
636   GPR[rd] = EXTEND32 ((temp2 << 16) | temp4);
639 :function:::void:do_qb_w_raddu:int rd, int rs
641   int i;
642   uint8_t h0;
643   uint32_t v1 = GPR[rs];
644   uint32_t result = 0;
645   for (i = 0; i < 32; i += 8, v1 >>= 8)
646     {
647       h0 = (uint8_t)(v1 & 0xff);
648       result += (uint32_t)h0;
649     }
650   GPR[rd] = EXTEND32 (result);
653 :function:::void:do_rddsp:int rd, int mask
655   uint32_t result = 0;
656   if (mask & 0x1)
657     {
658       result &= (~DSPCR_POS_SMASK);
659       result |= (DSPCR & DSPCR_POS_SMASK);
660     }
661   if (mask & 0x2)
662     {
663       result &= (~DSPCR_SCOUNT_SMASK);
664       result |= (DSPCR & DSPCR_SCOUNT_SMASK);
665     }
666   if (mask & 0x4)
667     {
668       result &= (~DSPCR_CARRY_SMASK);
669       result |= (DSPCR & DSPCR_CARRY_SMASK);
670     }
671   if (mask & 0x8)
672     {
673       result &= (~DSPCR_OUFLAG_SMASK);
674       result |= (DSPCR & DSPCR_OUFLAG_SMASK);
675     }
676   if (mask & 0x10)
677     {
678       result &= (~DSPCR_CCOND_SMASK);
679       result |= (DSPCR & DSPCR_CCOND_SMASK);
680     }
681   if (mask & 0x20)
682     {
683       result &= (~DSPCR_EFI_SMASK);
684       result |= (DSPCR & DSPCR_EFI_SMASK);
685     }
686   GPR[rd] = EXTEND32 (result);
689 // op: 0 = REPL.QB, 1 = REPLV.QB, 2 = REPL.PH, 3 = REPLV.PH
690 :function:::void:do_repl:int rd, int p2, int op
692   if (op == 0)
693     GPR[rd] = EXTEND32 ((p2 << 24) | (p2 << 16) | (p2 << 8) | p2);
694   else if (op == 1)
695     {
696       uint32_t v1 = GPR[p2] & 0xff;
697       GPR[rd] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
698     }
699   else if (op == 2)
700     {
701       int32_t v1 = p2;
702       if (v1 & 0x200)
703         v1 |= 0xfffffc00;
704       GPR[rd] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
705     }
706   else if (op == 3)
707     {
708       uint32_t v1 = GPR[p2];
709       v1 = v1 & 0xffff;
710       GPR[rd] = EXTEND32 ((v1 << 16) | v1);
711     }
714 :function:::void:do_shilov:int ac, int rs
716   int32_t shift = GPR[rs] & 0x3f;
717   do_shilo (SD_, ac, shift);
720 // op: 0 = SHLLV, 1 = SHRAV
721 // sat: 0 =  normal, 1 = saturate/rounding
722 :function:::void:do_ph_shl:int rd, int rt, int rs, int op, int sat
724   uint32_t shift = GPR[rs] & 0xf;
725   do_ph_shift (SD_, rd, rt, shift, op, sat);
728 // op: 0 = SHLLV, 1 = SHRLV
729 :function:::void:do_qb_shl:int rd, int rt, int rs, int op
731   uint32_t shift = GPR[rs] & 0x7;
732   do_qb_shift (SD_, rd, rt, shift, op);
735 :function:::void:do_w_s_shllv:int rd, int rt, int rs
737   uint32_t shift = GPR[rs] & 0x1f;
738   do_w_shll (SD_, rd, rt, shift);
741 :function:::void:do_ph_shrlv:int rd, int rt, int rs
743   uint32_t shift = GPR[rs] & 0xf;
744   do_ph_shrl (SD_, rd, rt, shift);
747 :function:::void:do_w_r_shrav:int rd, int rt, int rs
749   uint32_t shift = GPR[rs] & 0x1f;
750   do_w_shra (SD_, rd, rt, shift);
753 :function:::void:do_wrdsp:int rs, int mask
755   uint32_t v1 = GPR[rs];
756   if (mask & 0x1)
757     {
758       DSPCR &= (~DSPCR_POS_SMASK);
759       DSPCR |= (v1 & DSPCR_POS_SMASK);
760     }
761   if (mask & 0x2)
762     {
763       DSPCR &= (~DSPCR_SCOUNT_SMASK);
764       DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
765     }
766   if (mask & 0x4)
767     {
768       DSPCR &= (~DSPCR_CARRY_SMASK);
769       DSPCR |= (v1 & DSPCR_CARRY_SMASK);
770     }
771   if (mask & 0x8)
772     {
773       DSPCR &= (~DSPCR_OUFLAG_SMASK);
774       DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
775     }
776   if (mask & 0x10)
777     {
778       DSPCR &= (~DSPCR_CCOND_SMASK);
779       DSPCR |= (v1 & DSPCR_CCOND_SMASK);
780     }
781   if (mask & 0x20)
782     {
783       DSPCR &= (~DSPCR_EFI_SMASK);
784       DSPCR |= (v1 & DSPCR_EFI_SMASK);
785     }
788 // round: 0 = no rounding, 1 = rounding
789 :function:::void:do_qb_shrav:int rd, int rt, int rs, int round
791   uint32_t shift = GPR[rs] & 0x7;
792   do_qb_shra (SD_, rd, rt, shift, round);
795 :function:::void:do_append:int rt, int rs, int sa
797   uint32_t v0 = GPR[rs];
798   uint32_t v1 = GPR[rt];
799   uint32_t result;
800   uint32_t mask = (1 << sa) - 1;
801   result = (v1 << sa) | (v0 & mask);
802   GPR[rt] = EXTEND32 (result);
805 :function:::void:do_balign:int rt, int rs, int bp
807   uint32_t v0 = GPR[rs];
808   uint32_t v1 = GPR[rt];
809   uint32_t result;
810   if (bp == 0)
811     result = v1;
812   else
813     result = (v1 << 8 * bp) | (v0 >> 8 * (4 - bp));
814   GPR[rt] = EXTEND32 (result);
817 :function:::void:do_ph_w_mulsa:int ac, int rs, int rt
819   int i;
820   uint32_t v1 = GPR[rs];
821   uint32_t v2 = GPR[rt];
822   int16_t h1, h2;
823   int32_t result;
824   uint32_t lo = DSPLO(ac);
825   uint32_t hi = DSPHI(ac);
826   int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo);
827   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
828     {
829       h1 = (int16_t)(v1 & 0xffff);
830       h2 = (int16_t)(v2 & 0xffff);
831       result = (int32_t)h1 * (int32_t)h2;
833       if (i == 0)
834         prod -= (int64_t) result;
835       else
836         prod += (int64_t) result;
837     }
838   DSPLO(ac) = EXTEND32 (prod);
839   DSPHI(ac) = EXTEND32 (prod >> 32);
842 :function:::void:do_ph_qb_precr:int rd, int rs, int rt
844   uint32_t v1 = GPR[rs];
845   uint32_t v2 = GPR[rt];
846   uint32_t tempu = (v1 & 0xff0000) >> 16;
847   uint32_t tempv = (v1 & 0xff);
848   uint32_t tempw = (v2 & 0xff0000) >> 16;
849   uint32_t tempx = (v2 & 0xff);
850   GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
853 :function:::void:do_prepend:int rt, int rs, int sa
855   uint32_t v0 = GPR[rs];
856   uint32_t v1 = GPR[rt];
857   uint32_t result;
858   if (sa == 0)
859     result = v1;
860   else
861     result = (v0 << (32 - sa)) | (v1 >> sa);
862   GPR[rt] = EXTEND32 (result);
865 :function:::void:do_w_shra:int rd, int rt, int shift
867   uint32_t result = GPR[rt];
868   int32_t h0 = (int32_t)result;
869   if (shift != 0 && (h0 & (1 << (shift-1))))
870     h0 = (h0 >> shift) + 1;
871   else
872     h0 = h0 >> shift;
873   GPR[rd] = EXTEND32 (h0);
876 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
877 "addq.ph r<RD>, r<RS>, r<RT>"
878 *dsp:
880   do_ph_op (SD_, RD, RS, RT, 0, 0);
883 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
884 "addq_s.ph r<RD>, r<RS>, r<RT>"
885 *dsp:
887   do_ph_op (SD_, RD, RS, RT, 0, 1);
890 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
891 "addq_s.w r<RD>, r<RS>, r<RT>"
892 *dsp:
894   do_w_op (SD_, RD, RS, RT, 0);
897 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
898 "addu.qb r<RD>, r<RS>, r<RT>"
899 *dsp:
901   do_qb_op (SD_, RD, RS, RT, 0, 0);
904 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
905 "addu_s.qb r<RD>, r<RS>, r<RT>"
906 *dsp:
908   do_qb_op (SD_, RD, RS, RT, 0, 1);
911 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
912 "subq.ph r<RD>, r<RS>, r<RT>"
913 *dsp:
915   do_ph_op (SD_, RD, RS, RT, 1, 0);
918 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
919 "subq_s.ph r<RD>, r<RS>, r<RT>"
920 *dsp:
922   do_ph_op (SD_, RD, RS, RT, 1, 1);
925 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
926 "subq_s.w r<RD>, r<RS>, r<RT>"
927 *dsp:
929   do_w_op (SD_, RD, RS, RT, 1);
932 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
933 "subu.qb r<RD>, r<RS>, r<RT>"
934 *dsp:
936   do_qb_op (SD_, RD, RS, RT, 1, 0);
939 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
940 "subu_s.qb r<RD>, r<RS>, r<RT>"
941 *dsp:
943   do_qb_op (SD_, RD, RS, RT, 1, 1);
946 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
947 "addsc r<RD>, r<RS>, r<RT>"
948 *dsp:
950   do_addsc (SD_, RD, RS, RT);
953 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
954 "addwc r<RD>, r<RS>, r<RT>"
955 *dsp:
957   do_addwc (SD_, RD, RS, RT);
960 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
961 "modsub r<RD>, r<RS>, r<RT>"
962 *dsp:
964   do_modsub (SD_, RD, RS, RT);
967 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
968 "raddu.w.qb r<RD>, r<RS>"
969 *dsp:
971   do_qb_w_raddu (SD_, RD, RS);
974 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
975 "absq_s.ph r<RD>, r<RT>"
976 *dsp:
978   do_ph_s_absq (SD_, RD, RT);
981 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
982 "absq_s.w r<RD>, r<RT>"
983 *dsp:
985   do_w_s_absq (SD_, RD, RT);
988 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
989 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
990 *dsp:
992   do_ph_qb_precrq (SD_, RD, RS, RT, 0);
995 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
996 "precrq.ph.w r<RD>, r<RS>, r<RT>"
997 *dsp:
999   do_w_ph_precrq (SD_, RD, RS, RT);
1002 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
1003 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
1004 *dsp:
1006   do_w_ph_rs_precrq (SD_, RD, RS, RT);
1009 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
1010 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
1011 *dsp:
1013   do_ph_qb_precrq (SD_, RD, RS, RT, 1);
1016 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
1017 "preceq.w.phl r<RD>, r<RT>"
1018 *dsp:
1020   do_w_preceq (SD_, RD, RT, 0);
1023 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
1024 "preceq.w.phr r<RD>, r<RT>"
1025 *dsp:
1027   do_w_preceq (SD_, RD, RT, 1);
1030 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
1031 "precequ.ph.qbl r<RD>, r<RT>"
1032 *dsp:
1034   do_qb_ph_precequ (SD_, RD, RT, 2);
1037 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
1038 "precequ.ph.qbr r<RD>, r<RT>"
1039 *dsp:
1041   do_qb_ph_precequ (SD_, RD, RT, 0);
1044 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
1045 "precequ.ph.qbla r<RD>, r<RT>"
1046 *dsp:
1048   do_qb_ph_precequ (SD_, RD, RT, 3);
1051 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
1052 "precequ.ph.qbra r<RD>, r<RT>"
1053 *dsp:
1055   do_qb_ph_precequ (SD_, RD, RT, 1);
1058 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
1059 "preceu.ph.qbl r<RD>, r<RT>"
1060 *dsp:
1062   do_qb_ph_preceu (SD_, RD, RT, 2);
1065 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
1066 "preceu.ph.qbr r<RD>, r<RT>"
1067 *dsp:
1069   do_qb_ph_preceu (SD_, RD, RT, 0);
1072 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
1073 "preceu.ph.qbla r<RD>, r<RT>"
1074 *dsp:
1076   do_qb_ph_preceu (SD_, RD, RT, 3);
1079 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
1080 "preceu.ph.qbra r<RD>, r<RT>"
1081 *dsp:
1083   do_qb_ph_preceu (SD_, RD, RT, 1);
1086 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
1087 "shll.qb r<RD>, r<RT>, <SHIFT3>"
1088 *dsp:
1090   do_qb_shift (SD_, RD, RT, SHIFT3, 0);
1093 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
1094 "shllv.qb r<RD>, r<RT>, r<RS>"
1095 *dsp:
1097   do_qb_shl (SD_, RD, RT, RS, 0);
1100 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
1101 "shll.ph r<RD>, r<RT>, <SHIFT4>"
1102 *dsp:
1104   do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
1107 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
1108 "shllv.ph r<RD>, r<RT>, r<RS>"
1109 *dsp:
1111   do_ph_shl (SD_, RD, RT, RS, 0, 0);
1114 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
1115 "shll_s.ph r<RD>, r<RT>, <SHIFT4>"
1116 *dsp:
1118   do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
1121 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
1122 "shllv_s.ph r<RD>, r<RT>, r<RS>"
1123 *dsp:
1125   do_ph_shl (SD_, RD, RT, RS, 0, 1);
1128 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
1129 "shll_s.w r<RD>, r<RT>, <SHIFT5>"
1130 *dsp:
1132   do_w_shll (SD_, RD, RT, SHIFT5);
1135 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
1136 "shllv_s.w r<RD>, r<RT>, r<RS>"
1137 *dsp:
1139   do_w_s_shllv (SD_, RD, RT, RS);
1142 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
1143 "shrl.qb r<RD>, r<RT>, <SHIFT3>"
1144 *dsp:
1146   do_qb_shift (SD_, RD, RT, SHIFT3, 1);
1149 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
1150 "shrlv.qb r<RD>, r<RT>, r<RS>"
1151 *dsp:
1153   do_qb_shl (SD_, RD, RT, RS, 1);
1156 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
1157 "shra.ph r<RD>, r<RT>, <SHIFT4>"
1158 *dsp:
1160   do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
1163 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
1164 "shrav.ph r<RD>, r<RT>, r<RS>"
1165 *dsp:
1167   do_ph_shl (SD_, RD, RT, RS, 1, 0);
1170 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
1171 "shra_r.ph r<RD>, r<RT>, <SHIFT4>"
1172 *dsp:
1174   do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
1177 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
1178 "shrav_r.ph r<RD>, r<RT>, r<RS>"
1179 *dsp:
1181   do_ph_shl (SD_, RD, RT, RS, 1, 1);
1184 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
1185 "shra_r.w r<RD>, r<RT>, <SHIFT5>"
1186 *dsp:
1188   do_w_shra (SD_, RD, RT, SHIFT5);
1191 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
1192 "shrav_r.w r<RD>, r<RT>, r<RS>"
1193 *dsp:
1195   do_w_r_shrav (SD_, RD, RT, RS);
1198 // loc: 0 = qhl, 1 = qhr
1199 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
1201   int i;
1202   uint32_t result = 0;
1203   uint32_t v1 = GPR[rs];
1204   uint32_t v2 = GPR[rt];
1205   uint16_t h1, h2;
1206   uint32_t prod;
1207   if (loc == 0)
1208     v1 >>= 16;
1209   for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
1210     {
1211       h1 = (uint16_t)(v1 & 0xff);
1212       h2 = (uint16_t)(v2 & 0xffff);
1213       prod = (uint32_t)h1 * (uint32_t)h2;
1214       if (prod > 0xffff)
1215         {
1216           DSPCR |= DSPCR_OUFLAG5;
1217           prod = 0xffff;
1218         }
1219       result |= ((uint32_t)prod << i);
1220     }
1221   GPR[rd] = EXTEND32 (result);
1224 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
1225 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
1226 *dsp:
1228   do_qb_muleu (SD_, RD, RS, RT, 0);
1231 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
1232 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
1233 *dsp:
1235   do_qb_muleu (SD_, RD, RS, RT, 1);
1238 // round: 0 = no rounding, 1 = rounding
1239 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round
1241   int i;
1242   uint32_t result = 0;
1243   uint32_t v1 = GPR[rs];
1244   uint32_t v2 = GPR[rt];
1245   int16_t h1, h2;
1246   int32_t prod;
1247   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
1248     {
1249       h1 = (int16_t)(v1 & 0xffff);
1250       h2 = (int16_t)(v2 & 0xffff);
1251       if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000)
1252         {
1253           DSPCR |= DSPCR_OUFLAG5;
1254           prod = 0x7fffffff;
1255         }
1256       else
1257         {
1258           prod = ((int32_t)h1 * (int32_t)h2) << 1;
1259           if (round == 1)
1260             prod += (int32_t)0x8000;
1261         }
1262       result |= (((uint32_t)prod >> 16) << i);
1263     }
1264   GPR[rd] = EXTEND32 (result);
1267 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
1268 "mulq_rs.ph r<RD>, r<RS>, r<RT>"
1269 *dsp:
1271   do_ph_mulq (SD_, RD, RS, RT, 1);
1274 // loc: 0 = phl, 1 = phr
1275 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
1277   uint32_t v1 = GPR[rs];
1278   uint32_t v2 = GPR[rt];
1279   int16_t h1, h2;
1280   int32_t prod;
1281   if (loc == 0)
1282     {
1283       h1 = (int16_t)(v1 >> 16);
1284       h2 = (int16_t)(v2 >> 16);
1285     }
1286   else
1287     {
1288       h1 = (int16_t)(v1 & 0xffff);
1289       h2 = (int16_t)(v2 & 0xffff);
1290     }
1291   if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000)
1292     {
1293       DSPCR |= DSPCR_OUFLAG5;
1294       prod = 0x7fffffff;
1295     }
1296   else
1297     prod = ((int32_t)h1 * (int32_t)h2) << 1;
1298   GPR[rd] = EXTEND32 (prod);
1301 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
1302 "muleq_s.w.phl r<RD>, r<RS>, r<RT>"
1303 *dsp:
1305   do_ph_muleq (SD_, RD, RS, RT, 0);
1308 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
1309 "muleq_s.w.phr r<RD>, r<RS>, r<RT>"
1310 *dsp:
1312   do_ph_muleq (SD_, RD, RS, RT, 1);
1315 // op: 0 = DPAU 1 = DPSU
1316 // loc: 0 = qbl, 1 = qbr
1317 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
1319   int i;
1320   uint32_t v1 = GPR[rs];
1321   uint32_t v2 = GPR[rt];
1322   uint8_t h1, h2;
1323   uint32_t lo = DSPLO(ac);
1324   uint32_t hi = DSPHI(ac);
1325   uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo;
1326   if (loc == 0)
1327     {
1328       v1 >>= 16;
1329       v2 >>= 16;
1330     }
1331   for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
1332     {
1333       h1 = (uint8_t)(v1 & 0xff);
1334       h2 = (uint8_t)(v2 & 0xff);
1335       if (op == 0) // DPAU
1336         prod += (uint64_t)h1 * (uint64_t)h2;
1337       else // DPSU
1338         prod -= (uint64_t)h1 * (uint64_t)h2;
1339     }
1340   DSPLO(ac) = EXTEND32 (prod);
1341   DSPHI(ac) = EXTEND32 (prod >> 32);
1344 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
1345 "dpau.h.qbl ac<AC>, r<RS>, r<RT>"
1346 *dsp:
1348   do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
1351 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
1352 "dpau.h.qbr ac<AC>, r<RS>, r<RT>"
1353 *dsp:
1355   do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
1358 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
1359 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
1360 *dsp:
1362   do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
1365 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
1366 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
1367 *dsp:
1369   do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
1372 // op: 0 = DPAQ 1 = DPSQ
1373 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
1375   int i;
1376   uint32_t v1 = GPR[rs];
1377   uint32_t v2 = GPR[rt];
1378   int16_t h1, h2;
1379   int32_t result;
1380   uint32_t lo = DSPLO(ac);
1381   uint32_t hi = DSPHI(ac);
1382   int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo);
1383   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
1384     {
1385       h1 = (int16_t)(v1 & 0xffff);
1386       h2 = (int16_t)(v2 & 0xffff);
1387       if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000)
1388         {
1389           DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1390           result = (int32_t)0x7fffffff;
1391         }
1392       else
1393         result = ((int32_t)h1 * (int32_t)h2) << 1;
1395       if (op == 0) // DPAQ
1396         prod += (int64_t)result;
1397       else // DPSQ
1398         prod -= (int64_t)result;
1399     }
1400   DSPLO(ac) = EXTEND32 (prod);
1401   DSPHI(ac) = EXTEND32 (prod >> 32);
1404 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
1405 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
1406 *dsp:
1408   do_ph_dot_product (SD_, AC, RS, RT, 0);
1411 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
1412 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
1413 *dsp:
1415   do_ph_dot_product (SD_, AC, RS, RT, 1);
1418 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
1419 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
1420 *dsp:
1422   do_mulsaq_s_w_ph (SD_, AC, RS, RT);
1425 // op: 0 = DPAQ 1 = DPSQ
1426 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
1428   uint32_t v1 = GPR[rs];
1429   uint32_t v2 = GPR[rt];
1430   int32_t h1, h2;
1431   int64_t result;
1432   uint32_t lo = DSPLO(ac);
1433   uint32_t hi = DSPHI(ac);
1434   uint32_t resultlo;
1435   uint32_t resulthi;
1436   uint32_t carry;
1437   uint64_t temp1;
1438   int64_t temp2;
1439   h1 = (int32_t) v1;
1440   h2 = (int32_t) v2;
1441   if (h1 == 0x80000000 && h2 == 0x80000000)
1442     {
1443       DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1444       result = (int64_t) 0x7fffffffffffffffLL;
1445     }
1446   else
1447     result = ((int64_t)h1 * (int64_t)h2) << 1;
1448   resultlo = (uint32_t)(result);
1449   resulthi = (uint32_t)(result >> 32);
1450   if (op ==0) // DPAQ
1451     {
1452       temp1 = (uint64_t)lo + (uint64_t)resultlo;
1453       carry = (uint32_t)((temp1 >> 32) & 1);
1454       temp2 = (int64_t)((int32_t)hi) + (int64_t)((int32_t)resulthi) +
1455               (int64_t)((int32_t)carry);
1456     }
1457   else // DPSQ
1458     {
1459       temp1 = (uint64_t)lo - (uint64_t)resultlo;
1460       carry = (uint32_t)((temp1 >> 32) & 1);
1461       temp2 = (int64_t)((int32_t)hi) - (int64_t)((int32_t)resulthi) -
1462               (int64_t)((int32_t)carry);
1463     }
1464   if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1465     {
1466       DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1467       if (temp2 & 0x100000000LL)
1468         {
1469           DSPLO(ac) = EXTEND32 (0x00000000);
1470           DSPHI(ac) = EXTEND32 (0x80000000);
1471         }
1472       else
1473         {
1474           DSPLO(ac) = EXTEND32 (0xffffffff);
1475           DSPHI(ac) = EXTEND32 (0x7fffffff);
1476         }
1477     }
1478   else
1479     {
1480       DSPLO(ac) = EXTEND32 (temp1);
1481       DSPHI(ac) = EXTEND32 (temp2);
1482     }
1485 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1486 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
1487 *dsp:
1489   do_w_dot_product (SD_, AC, RS, RT, 0);
1492 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1493 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
1494 *dsp:
1496   do_w_dot_product (SD_, AC, RS, RT, 1);
1499 // op: 0 = MAQ_S 1 = MAQ_SA
1500 // loc: 0 = phl, 1 = phr
1501 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1503   int i;
1504   uint32_t v1 = GPR[rs];
1505   uint32_t v2 = GPR[rt];
1506   int16_t h1, h2;
1507   int32_t result;
1508   uint32_t lo = DSPLO(ac);
1509   uint32_t hi = DSPHI(ac);
1510   int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo);
1511   if (loc == 0)
1512     {
1513       h1 = (int16_t)(v1 >> 16);
1514       h2 = (int16_t)(v2 >> 16);
1515     }
1516   else
1517     {
1518       h1 = (int16_t)(v1 & 0xffff);
1519       h2 = (int16_t)(v2 & 0xffff);
1520     }
1521   if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000)
1522     {
1523       DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1524       result = (int32_t)0x7fffffff;
1525     }
1526   else
1527     result = ((int32_t)h1 * (int32_t)h2) << 1;
1528   prod += (int64_t)result;
1529   if (op == 1) // MAQ_SA
1530     {
1531       if (prod & 0x8000000000000000LL)
1532         {
1533           for (i = 62; i >= 31; i--)
1534             {
1535               if (!(prod & ((int64_t)1 << i)))
1536                 {
1537                   DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1538                   prod = 0xffffffff80000000LL;
1539                   break;
1540                 }
1541             }
1542         }
1543       else
1544         {
1545           for (i = 62; i >= 31; i--)
1546             {
1547               if (prod & ((int64_t)1 << i))
1548                 {
1549                   DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1550                   prod = 0x7fffffff;
1551                   break;
1552                 }
1553             }
1554         }
1555     }
1556   DSPLO(ac) = EXTEND32 (prod);
1557   DSPHI(ac) = EXTEND32 (prod >> 32);
1560 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1561 "maq_s.w.phl ac<AC>, r<RS>, r<RT>"
1562 *dsp:
1564   do_ph_maq (SD_, AC, RS, RT, 0, 0);
1567 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1568 "maq_s.w.phr ac<AC>, r<RS>, r<RT>"
1569 *dsp:
1571   do_ph_maq (SD_, AC, RS, RT, 0, 1);
1574 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1575 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
1576 *dsp:
1578   do_ph_maq (SD_, AC, RS, RT, 1, 0);
1581 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1582 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
1583 *dsp:
1585   do_ph_maq (SD_, AC, RS, RT, 1, 1);
1588 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1589 "bitrev r<RD>, r<RT>"
1590 *dsp:
1592   do_bitrev (SD_, RD, RT);
1595 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1596 "insv r<RT>, r<RS>"
1597 *dsp:
1599   do_insv (SD_, RT, RS);
1602 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1603 "repl.qb r<RD>, <IMM8>"
1604 *dsp:
1606   do_repl (SD_, RD, IMM8, 0);
1609 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1610 "replv.qb r<RD>, r<RT>"
1611 *dsp:
1613   do_repl (SD_, RD, RT, 1);
1616 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1617 "repl.ph r<RD>, <IMM10>"
1618 *dsp:
1620   do_repl (SD_, RD, IMM10, 2);
1623 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1624 "replv.ph r<RD>, r<RT>"
1625 *dsp:
1627   do_repl (SD_, RD, RT, 3);
1630 // op: 0 = EQ, 1 = LT, 2 = LE
1631 :function:::void:do_qb_cmpu:int rs, int rt, int op
1633   int i, j;
1634   uint32_t v1 = GPR[rs];
1635   uint32_t v2 = GPR[rt];
1636   uint8_t h1, h2;
1637   uint32_t mask;
1638   for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1639     {
1640       h1 = (uint8_t)(v1 & 0xff);
1641       h2 = (uint8_t)(v2 & 0xff);
1642       mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1643       DSPCR &= mask;
1644       if (op == 0) // EQ
1645         DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1646       else if (op == 1) // LT
1647         DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1648       else // LE
1649         DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1650     }
1653 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1654 "cmpu.eq.qb r<RS>, r<RT>"
1655 *dsp:
1657   do_qb_cmpu (SD_, RS, RT, 0);
1660 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1661 "cmpu.lt.qb r<RS>, r<RT>"
1662 *dsp:
1664   do_qb_cmpu (SD_, RS, RT, 1);
1667 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1668 "cmpu.le.qb r<RS>, r<RT>"
1669 *dsp:
1671   do_qb_cmpu (SD_, RS, RT, 2);
1674 // op: 0 = EQ, 1 = LT, 2 = LE
1675 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1677   int i, j;
1678   uint32_t v1 = GPR[rs];
1679   uint32_t v2 = GPR[rt];
1680   uint8_t h1, h2;
1681   uint32_t result = 0;
1682   for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1683     {
1684       h1 = (uint8_t)(v1 & 0xff);
1685       h2 = (uint8_t)(v2 & 0xff);
1686       if (op == 0) // EQ
1687         result |= ((h1 == h2) << j);
1688       else if (op == 1) // LT
1689         result |= ((h1 < h2) << j);
1690       else // LE
1691         result |= ((h1 <= h2) << j);
1692     }
1693   GPR[rd] = EXTEND32 (result);
1696 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1697 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
1698 *dsp:
1700   do_qb_cmpgu (SD_, RD, RS, RT, 0);
1703 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1704 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
1705 *dsp:
1707   do_qb_cmpgu (SD_, RD, RS, RT, 1);
1710 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1711 "cmpgu.le.qb r<RD>, r<RS>, r<RT>"
1712 *dsp:
1714   do_qb_cmpgu (SD_, RD, RS, RT, 2);
1717 // op: 0 = EQ, 1 = LT, 2 = LE
1718 :function:::void:do_ph_cmpu:int rs, int rt, int op
1720   int i, j;
1721   uint32_t v1 = GPR[rs];
1722   uint32_t v2 = GPR[rt];
1723   int16_t h1, h2;
1724   uint32_t mask;
1725   for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1726     {
1727       h1 = (int16_t)(v1 & 0xffff);
1728       h2 = (int16_t)(v2 & 0xffff);
1729       mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1730       DSPCR &= mask;
1731       if (op == 0) // EQ
1732         DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1733       else if (op == 1) // LT
1734         DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1735       else // LE
1736         DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1737     }
1740 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1741 "cmp.eq.ph r<RS>, r<RT>"
1742 *dsp:
1744   do_ph_cmpu (SD_, RS, RT, 0);
1747 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1748 "cmp.lt.ph r<RS>, r<RT>"
1749 *dsp:
1751   do_ph_cmpu (SD_, RS, RT, 1);
1754 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1755 "cmp.le.ph r<RS>, r<RT>"
1756 *dsp:
1758   do_ph_cmpu (SD_, RS, RT, 2);
1761 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1762 "pick.qb r<RD>, r<RS>, r<RT>"
1763 *dsp:
1765   do_qb_pick (SD_, RD, RS, RT);
1768 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1769 "pick.ph r<RD>, r<RS>, r<RT>"
1770 *dsp:
1772   do_ph_pick (SD_, RD, RS, RT);
1775 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1776 "packrl.ph r<RD>, r<RS>, r<RT>"
1777 *dsp:
1779   do_ph_packrl (SD_, RD, RS, RT);
1782 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1783 :function:::void:do_w_extr:int rt, int ac, int shift, int op
1785   int i;
1786   uint32_t lo = DSPLO(ac);
1787   uint32_t hi = DSPHI(ac);
1788   uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo;
1789   int64_t result = (int64_t)prod;
1790   int setcond = 0;
1791   if (!(prod & 0x8000000000000000LL))
1792     {
1793       for (i = 62; i >= (shift + 31); i--)
1794         {
1795           if (prod & ((uint64_t)1 << i))
1796             {
1797               DSPCR |= DSPCR_OUFLAG7;
1798               setcond = 1;
1799               break;
1800             }
1801         }
1802       if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1803         {
1804           DSPCR |= DSPCR_OUFLAG7;
1805           setcond = 1;
1806         }
1807     }
1808   else
1809     {
1810       for (i = 62; i >= (shift + 31); i--)
1811         {
1812           if (!(prod & ((uint64_t)1 << i)))
1813             {
1814               DSPCR |= DSPCR_OUFLAG7;
1815               setcond = 2;
1816               break;
1817             }
1818         }
1819     }
1820   if (op == 0) // EXTR
1821     result = result >> shift;
1822   else if (op == 1) // EXTR_R
1823     {
1824       if (shift != 0)
1825         result = ((result >> (shift - 1)) + 1) >> 1;
1826       else
1827         result = result >> shift;
1828     }
1829   else // EXTR_RS
1830     {
1831       if (setcond == 1)
1832         result = 0x7fffffff;
1833       else if (setcond == 2)
1834         result = 0x80000000;
1835       else
1836         {
1837           if (shift != 0)
1838             result = ((result >> (shift - 1)) + 1) >> 1;
1839           else
1840             result = result >> shift;
1841         }
1842     }
1843   GPR[rt] = EXTEND32 (result);
1846 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1847 "extr.w r<RT>, ac<AC>, <SHIFT>"
1848 *dsp:
1850   do_w_extr (SD_, RT, AC, SHIFT, 0);
1853 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1854 "extrv.w r<RT>, ac<AC>, r<RS>"
1855 *dsp:
1857   do_extrv (SD_, RT, AC, RS, 0);
1860 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1861 "extr_r.w r<RT>, ac<AC>, <SHIFT>"
1862 *dsp:
1864   do_w_extr (SD_, RT, AC, SHIFT, 1);
1867 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1868 "extrv_r.w r<RT>, ac<AC>, r<RS>"
1869 *dsp:
1871   do_extrv (SD_, RT, AC, RS, 1);
1874 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1875 "extr_rs.w r<RT>, ac<AC>, <SHIFT>"
1876 *dsp:
1878   do_w_extr (SD_, RT, AC, SHIFT, 2);
1881 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1882 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
1883 *dsp:
1885   do_extrv (SD_, RT, AC, RS, 2);
1888 :function:::void:do_h_extr:int rt, int ac, int shift
1890   uint32_t lo = DSPLO(ac);
1891   uint32_t hi = DSPHI(ac);
1892   uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo;
1893   int64_t result = (int64_t)prod;
1894   int64_t value = 0xffffffffffff8000LL;
1895   result >>= shift;
1896   if (result > 0x7fff)
1897     {
1898       result = 0x7fff;
1899       DSPCR |= DSPCR_OUFLAG7;
1900     }
1901   else if (result < value)
1902     {
1903       result = value;
1904       DSPCR |= DSPCR_OUFLAG7;
1905     }
1906   GPR[rt] = EXTEND32 (result);
1909 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1910 "extr_s.h r<RT>, ac<AC>, <SHIFT>"
1911 *dsp:
1913   do_h_extr (SD_, RT, AC, SHIFT);
1916 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1917 "extrv_s.h r<RT>, ac<AC>, r<RS>"
1918 *dsp:
1920   do_extrv_s_h (SD_, RT, AC, RS);
1923 // op: 0 = EXTP, 1 = EXTPDP
1924 :function:::void:do_extp:int rt, int ac, int size, int op
1926   int32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1927   uint32_t lo = DSPLO(ac);
1928   uint32_t hi = DSPHI(ac);
1929   uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo;
1930   uint64_t result = 0;
1931   if (pos - (size + 1) >= -1)
1932     {
1933       prod >>= (pos - size);
1934       result = prod & (((uint64_t)1 << (size + 1)) - 1);
1935       DSPCR &= (~DSPCR_EFI_SMASK);
1936       if (op == 1) // EXTPDP
1937         {
1938           if (pos - (size + 1) >= 0)
1939             {
1940               DSPCR &= (~DSPCR_POS_SMASK);
1941               DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1942             }
1943           else if (pos - (size + 1) == -1)
1944             {
1945               DSPCR |= DSPCR_POS_SMASK;
1946             }
1947         }
1948     }
1949   else
1950     {
1951       DSPCR |= DSPCR_EFI;
1952       Unpredictable ();
1953     }
1954   GPR[rt] = EXTEND32 (result);
1957 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1958 "extp r<RT>, ac<AC>, <SIZE>"
1959 *dsp:
1961   do_extp (SD_, RT, AC, SIZE, 0);
1964 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1965 "extpv r<RT>, ac<AC>, r<RS>"
1966 *dsp:
1968   do_extpv (SD_, RT, AC, RS, 0);
1971 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1972 "extpdp r<RT>, ac<AC>, <SIZE>"
1973 *dsp:
1975   do_extp (SD_, RT, AC, SIZE, 1);
1978 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1979 "extpdpv r<RT>, ac<AC>, r<RS>"
1980 *dsp:
1982   do_extpv (SD_, RT, AC, RS, 1);
1985 :function:::void:do_shilo:int ac, int shift
1987   uint32_t lo = DSPLO(ac);
1988   uint32_t hi = DSPHI(ac);
1989   uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo;
1990   if (shift > 31)
1991     shift = shift - 64;
1992   if (shift >= 0)
1993     prod >>= shift;
1994   else
1995     prod <<= (-shift);
1996   DSPLO(ac) = EXTEND32 (prod);
1997   DSPHI(ac) = EXTEND32 (prod >> 32);
2000 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
2001 "shilo ac<AC>, <SHIFT6>"
2002 *dsp:
2004   do_shilo (SD_, AC, SHIFT6);
2007 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
2008 "shilov ac<AC>, r<RS>"
2009 *dsp:
2011   do_shilov (SD_, AC, RS);
2014 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
2015 "mthlip r<RS>, ac<AC>"
2016 *dsp:
2018   do_mthlip (SD_, RS, AC);
2021 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
2022 "wrdsp r<RS>":MASK10 == 1111111111
2023 "wrdsp r<RS>, <MASK10>"
2024 *dsp:
2026   do_wrdsp (SD_, RS, MASK10);
2029 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
2030 "rddsp r<RD>":MASK10 == 1111111111
2031 "rddsp r<RD>, <MASK10>"
2032 *dsp:
2034   do_rddsp (SD_, RD, MASK10);
2037 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
2038 "lbux r<RD>, r<INDEX>(r<BASE>)"
2039 *dsp:
2041   do_lxx (SD_, RD, BASE, INDEX, 0);
2044 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
2045 "lhx r<RD>, r<INDEX>(r<BASE>)"
2046 *dsp:
2048   do_lxx (SD_, RD, BASE, INDEX, 1);
2051 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
2052 "lwx r<RD>, r<INDEX>(r<BASE>)"
2053 *dsp:
2055   do_lxx (SD_, RD, BASE, INDEX, 2);
2058 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
2059 "bposge32 <OFFSET>"
2060 *dsp:
2062   uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
2063   address_word offset = EXTEND16 (OFFSET) << 2;
2064   if (pos >= 32)
2065     {
2066       DELAY_SLOT (NIA + offset);
2067     }