Home | History | Annotate | Line # | Download | only in mips
      1 // -*- C -*-
      2 
      3 // Simulator definition for the MIPS DSP ASE.
      4 // Copyright (C) 2005-2025 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.
     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 <http://www.gnu.org/licenses/>.
     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   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);
     60 }
     61 
     62 // op: 0 = ADD, 1 = SUB
     63 :function:::void:do_w_op:int rd, int rs, int rt, int op
     64 {
     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);
     84 }
     85 
     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
     89 {
     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);
    118 }
    119 
    120 // op: 0 = left, 1 = right
    121 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
    122 {
    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);
    147 }
    148 
    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
    152 {
    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 	}
    204 
    205       result |= ((uint32_t)((uint16_t)h0) << i);
    206     }
    207   GPR[rd] = EXTEND32 (result);
    208 }
    209 
    210 :function:::void:do_w_shll:int rd, int rt, int shift
    211 {
    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);
    247 }
    248 
    249 :function:::void:do_ph_s_absq:int rd, int rt
    250 {
    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);
    268 }
    269 
    270 :function:::void:do_w_s_absq:int rd, int rt
    271 {
    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);
    282 }
    283 
    284 :function:::void:do_qb_s_absq:int rd, int rt
    285 {
    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);
    303 }
    304 
    305 :function:::void:do_addsc:int rd, int rs, int rt
    306 {
    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);
    314 }
    315 
    316 :function:::void:do_addwc:int rd, int rs, int rt
    317 {
    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);
    328 }
    329 
    330 :function:::void:do_bitrev:int rd, int rt
    331 {
    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);
    341 }
    342 
    343 // op: 0 = EXTPV, 1 = EXTPDPV
    344 :function:::void:do_extpv:int rt, int ac, int rs, int op
    345 {
    346   uint32_t size = GPR[rs] & 0x1f;
    347   do_extp (SD_, rt, ac, size, op);
    348 }
    349 
    350 // op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS
    351 :function:::void:do_extrv:int rt, int ac, int rs, int op
    352 {
    353   uint32_t shift = GPR[rs] & 0x1f;
    354   do_w_extr (SD_, rt, ac, shift, op);
    355 }
    356 
    357 :function:::void:do_extrv_s_h:int rt, int ac, int rs
    358 {
    359   uint32_t shift = GPR[rs] & 0x1f;
    360   do_h_extr (SD_, rt, ac, shift);
    361 }
    362 
    363 :function:::void:do_insv:int rt, int rs
    364 {
    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);
    381 }
    382 
    383 // op: 0 = NORMAL,  1 = EXTEND16, 2 = EXTEND32
    384 :function:::void:do_lxx:int rd, int base, int index, int op
    385 {
    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]));
    392 }
    393 
    394 :function:::void:do_modsub:int rd, int rs, int rt
    395 {
    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);
    406 }
    407 
    408 :function:::void:do_mthlip:int rs, int ac
    409 {
    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;
    419 }
    420 
    421 :function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt
    422 {
    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;
    442 
    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);
    450 }
    451 
    452 :function:::void:do_ph_packrl:int rd, int rs, int rt
    453 {
    454 
    455   uint32_t v1 = GPR[rs];
    456   uint32_t v2 = GPR[rt];
    457   GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16));
    458 }
    459 
    460 :function:::void:do_qb_pick:int rd, int rs, int rt
    461 {
    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);
    477 }
    478 
    479 :function:::void:do_ph_pick:int rd, int rs, int rt
    480 {
    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);
    496 }
    497 
    498 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
    499 :function:::void:do_qb_ph_precequ:int rd, int rt, int op
    500 {
    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);
    510 }
    511 
    512 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
    513 :function:::void:do_qb_ph_preceu:int rd, int rt, int op
    514 {
    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);
    524 }
    525 
    526 // op: 0 = .PHL, 1 = PHR
    527 :function:::void:do_w_preceq:int rd, int rt, int op
    528 {
    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);
    534 }
    535 
    536 :function:::void:do_w_ph_precrq:int rd, int rs, int rt
    537 {
    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);
    543 }
    544 
    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
    547 {
    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);
    610 }
    611 
    612 :function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt
    613 {
    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);
    637 }
    638 
    639 :function:::void:do_qb_w_raddu:int rd, int rs
    640 {
    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);
    651 }
    652 
    653 :function:::void:do_rddsp:int rd, int mask
    654 {
    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);
    687 }
    688 
    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
    691 {
    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     }
    712 }
    713 
    714 :function:::void:do_shilov:int ac, int rs
    715 {
    716   int32_t shift = GPR[rs] & 0x3f;
    717   do_shilo (SD_, ac, shift);
    718 }
    719 
    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
    723 {
    724   uint32_t shift = GPR[rs] & 0xf;
    725   do_ph_shift (SD_, rd, rt, shift, op, sat);
    726 }
    727 
    728 // op: 0 = SHLLV, 1 = SHRLV
    729 :function:::void:do_qb_shl:int rd, int rt, int rs, int op
    730 {
    731   uint32_t shift = GPR[rs] & 0x7;
    732   do_qb_shift (SD_, rd, rt, shift, op);
    733 }
    734 
    735 :function:::void:do_w_s_shllv:int rd, int rt, int rs
    736 {
    737   uint32_t shift = GPR[rs] & 0x1f;
    738   do_w_shll (SD_, rd, rt, shift);
    739 }
    740 
    741 :function:::void:do_ph_shrlv:int rd, int rt, int rs
    742 {
    743   uint32_t shift = GPR[rs] & 0xf;
    744   do_ph_shrl (SD_, rd, rt, shift);
    745 }
    746 
    747 :function:::void:do_w_r_shrav:int rd, int rt, int rs
    748 {
    749   uint32_t shift = GPR[rs] & 0x1f;
    750   do_w_shra (SD_, rd, rt, shift);
    751 }
    752 
    753 :function:::void:do_wrdsp:int rs, int mask
    754 {
    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     }
    786 }
    787 
    788 // round: 0 = no rounding, 1 = rounding
    789 :function:::void:do_qb_shrav:int rd, int rt, int rs, int round
    790 {
    791   uint32_t shift = GPR[rs] & 0x7;
    792   do_qb_shra (SD_, rd, rt, shift, round);
    793 }
    794 
    795 :function:::void:do_append:int rt, int rs, int sa
    796 {
    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);
    803 }
    804 
    805 :function:::void:do_balign:int rt, int rs, int bp
    806 {
    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);
    815 }
    816 
    817 :function:::void:do_ph_w_mulsa:int ac, int rs, int rt
    818 {
    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;
    832 
    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);
    840 }
    841 
    842 :function:::void:do_ph_qb_precr:int rd, int rs, int rt
    843 {
    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);
    851 }
    852 
    853 :function:::void:do_prepend:int rt, int rs, int sa
    854 {
    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);
    863 }
    864 
    865 :function:::void:do_w_shra:int rd, int rt, int shift
    866 {
    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);
    874 }
    875 
    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:
    879 {
    880   do_ph_op (SD_, RD, RS, RT, 0, 0);
    881 }
    882 
    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:
    886 {
    887   do_ph_op (SD_, RD, RS, RT, 0, 1);
    888 }
    889 
    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:
    893 {
    894   do_w_op (SD_, RD, RS, RT, 0);
    895 }
    896 
    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:
    900 {
    901   do_qb_op (SD_, RD, RS, RT, 0, 0);
    902 }
    903 
    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:
    907 {
    908   do_qb_op (SD_, RD, RS, RT, 0, 1);
    909 }
    910 
    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:
    914 {
    915   do_ph_op (SD_, RD, RS, RT, 1, 0);
    916 }
    917 
    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:
    921 {
    922   do_ph_op (SD_, RD, RS, RT, 1, 1);
    923 }
    924 
    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:
    928 {
    929   do_w_op (SD_, RD, RS, RT, 1);
    930 }
    931 
    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:
    935 {
    936   do_qb_op (SD_, RD, RS, RT, 1, 0);
    937 }
    938 
    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:
    942 {
    943   do_qb_op (SD_, RD, RS, RT, 1, 1);
    944 }
    945 
    946 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
    947 "addsc r<RD>, r<RS>, r<RT>"
    948 *dsp:
    949 {
    950   do_addsc (SD_, RD, RS, RT);
    951 }
    952 
    953 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
    954 "addwc r<RD>, r<RS>, r<RT>"
    955 *dsp:
    956 {
    957   do_addwc (SD_, RD, RS, RT);
    958 }
    959 
    960 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
    961 "modsub r<RD>, r<RS>, r<RT>"
    962 *dsp:
    963 {
    964   do_modsub (SD_, RD, RS, RT);
    965 }
    966 
    967 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
    968 "raddu.w.qb r<RD>, r<RS>"
    969 *dsp:
    970 {
    971   do_qb_w_raddu (SD_, RD, RS);
    972 }
    973 
    974 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
    975 "absq_s.ph r<RD>, r<RT>"
    976 *dsp:
    977 {
    978   do_ph_s_absq (SD_, RD, RT);
    979 }
    980 
    981 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
    982 "absq_s.w r<RD>, r<RT>"
    983 *dsp:
    984 {
    985   do_w_s_absq (SD_, RD, RT);
    986 }
    987 
    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:
    991 {
    992   do_ph_qb_precrq (SD_, RD, RS, RT, 0);
    993 }
    994 
    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:
    998 {
    999   do_w_ph_precrq (SD_, RD, RS, RT);
   1000 }
   1001 
   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:
   1005 {
   1006   do_w_ph_rs_precrq (SD_, RD, RS, RT);
   1007 }
   1008 
   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:
   1012 {
   1013   do_ph_qb_precrq (SD_, RD, RS, RT, 1);
   1014 }
   1015 
   1016 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
   1017 "preceq.w.phl r<RD>, r<RT>"
   1018 *dsp:
   1019 {
   1020   do_w_preceq (SD_, RD, RT, 0);
   1021 }
   1022 
   1023 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
   1024 "preceq.w.phr r<RD>, r<RT>"
   1025 *dsp:
   1026 {
   1027   do_w_preceq (SD_, RD, RT, 1);
   1028 }
   1029 
   1030 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
   1031 "precequ.ph.qbl r<RD>, r<RT>"
   1032 *dsp:
   1033 {
   1034   do_qb_ph_precequ (SD_, RD, RT, 2);
   1035 }
   1036 
   1037 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
   1038 "precequ.ph.qbr r<RD>, r<RT>"
   1039 *dsp:
   1040 {
   1041   do_qb_ph_precequ (SD_, RD, RT, 0);
   1042 }
   1043 
   1044 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
   1045 "precequ.ph.qbla r<RD>, r<RT>"
   1046 *dsp:
   1047 {
   1048   do_qb_ph_precequ (SD_, RD, RT, 3);
   1049 }
   1050 
   1051 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
   1052 "precequ.ph.qbra r<RD>, r<RT>"
   1053 *dsp:
   1054 {
   1055   do_qb_ph_precequ (SD_, RD, RT, 1);
   1056 }
   1057 
   1058 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
   1059 "preceu.ph.qbl r<RD>, r<RT>"
   1060 *dsp:
   1061 {
   1062   do_qb_ph_preceu (SD_, RD, RT, 2);
   1063 }
   1064 
   1065 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
   1066 "preceu.ph.qbr r<RD>, r<RT>"
   1067 *dsp:
   1068 {
   1069   do_qb_ph_preceu (SD_, RD, RT, 0);
   1070 }
   1071 
   1072 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
   1073 "preceu.ph.qbla r<RD>, r<RT>"
   1074 *dsp:
   1075 {
   1076   do_qb_ph_preceu (SD_, RD, RT, 3);
   1077 }
   1078 
   1079 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
   1080 "preceu.ph.qbra r<RD>, r<RT>"
   1081 *dsp:
   1082 {
   1083   do_qb_ph_preceu (SD_, RD, RT, 1);
   1084 }
   1085 
   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:
   1089 {
   1090   do_qb_shift (SD_, RD, RT, SHIFT3, 0);
   1091 }
   1092 
   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:
   1096 {
   1097   do_qb_shl (SD_, RD, RT, RS, 0);
   1098 }
   1099 
   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:
   1103 {
   1104   do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
   1105 }
   1106 
   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:
   1110 {
   1111   do_ph_shl (SD_, RD, RT, RS, 0, 0);
   1112 }
   1113 
   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:
   1117 {
   1118   do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
   1119 }
   1120 
   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:
   1124 {
   1125   do_ph_shl (SD_, RD, RT, RS, 0, 1);
   1126 }
   1127 
   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:
   1131 {
   1132   do_w_shll (SD_, RD, RT, SHIFT5);
   1133 }
   1134 
   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:
   1138 {
   1139   do_w_s_shllv (SD_, RD, RT, RS);
   1140 }
   1141 
   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:
   1145 {
   1146   do_qb_shift (SD_, RD, RT, SHIFT3, 1);
   1147 }
   1148 
   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:
   1152 {
   1153   do_qb_shl (SD_, RD, RT, RS, 1);
   1154 }
   1155 
   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:
   1159 {
   1160   do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
   1161 }
   1162 
   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:
   1166 {
   1167   do_ph_shl (SD_, RD, RT, RS, 1, 0);
   1168 }
   1169 
   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:
   1173 {
   1174   do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
   1175 }
   1176 
   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:
   1180 {
   1181   do_ph_shl (SD_, RD, RT, RS, 1, 1);
   1182 }
   1183 
   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:
   1187 {
   1188   do_w_shra (SD_, RD, RT, SHIFT5);
   1189 }
   1190 
   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:
   1194 {
   1195   do_w_r_shrav (SD_, RD, RT, RS);
   1196 }
   1197 
   1198 // loc: 0 = qhl, 1 = qhr
   1199 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
   1200 {
   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);
   1222 }
   1223 
   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:
   1227 {
   1228   do_qb_muleu (SD_, RD, RS, RT, 0);
   1229 }
   1230 
   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:
   1234 {
   1235   do_qb_muleu (SD_, RD, RS, RT, 1);
   1236 }
   1237 
   1238 // round: 0 = no rounding, 1 = rounding
   1239 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round
   1240 {
   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);
   1265 }
   1266 
   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:
   1270 {
   1271   do_ph_mulq (SD_, RD, RS, RT, 1);
   1272 }
   1273 
   1274 // loc: 0 = phl, 1 = phr
   1275 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
   1276 {
   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);
   1299 }
   1300 
   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:
   1304 {
   1305   do_ph_muleq (SD_, RD, RS, RT, 0);
   1306 }
   1307 
   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:
   1311 {
   1312   do_ph_muleq (SD_, RD, RS, RT, 1);
   1313 }
   1314 
   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
   1318 {
   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);
   1342 }
   1343 
   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:
   1347 {
   1348   do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
   1349 }
   1350 
   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:
   1354 {
   1355   do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
   1356 }
   1357 
   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:
   1361 {
   1362   do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
   1363 }
   1364 
   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:
   1368 {
   1369   do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
   1370 }
   1371 
   1372 // op: 0 = DPAQ 1 = DPSQ
   1373 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
   1374 {
   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;
   1394 
   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);
   1402 }
   1403 
   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:
   1407 {
   1408   do_ph_dot_product (SD_, AC, RS, RT, 0);
   1409 }
   1410 
   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:
   1414 {
   1415   do_ph_dot_product (SD_, AC, RS, RT, 1);
   1416 }
   1417 
   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:
   1421 {
   1422   do_mulsaq_s_w_ph (SD_, AC, RS, RT);
   1423 }
   1424 
   1425 // op: 0 = DPAQ 1 = DPSQ
   1426 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
   1427 {
   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     }
   1483 }
   1484 
   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:
   1488 {
   1489   do_w_dot_product (SD_, AC, RS, RT, 0);
   1490 }
   1491 
   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:
   1495 {
   1496   do_w_dot_product (SD_, AC, RS, RT, 1);
   1497 }
   1498 
   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
   1502 {
   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);
   1558 }
   1559 
   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:
   1563 {
   1564   do_ph_maq (SD_, AC, RS, RT, 0, 0);
   1565 }
   1566 
   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:
   1570 {
   1571   do_ph_maq (SD_, AC, RS, RT, 0, 1);
   1572 }
   1573 
   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:
   1577 {
   1578   do_ph_maq (SD_, AC, RS, RT, 1, 0);
   1579 }
   1580 
   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:
   1584 {
   1585   do_ph_maq (SD_, AC, RS, RT, 1, 1);
   1586 }
   1587 
   1588 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
   1589 "bitrev r<RD>, r<RT>"
   1590 *dsp:
   1591 {
   1592   do_bitrev (SD_, RD, RT);
   1593 }
   1594 
   1595 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
   1596 "insv r<RT>, r<RS>"
   1597 *dsp:
   1598 {
   1599   do_insv (SD_, RT, RS);
   1600 }
   1601 
   1602 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
   1603 "repl.qb r<RD>, <IMM8>"
   1604 *dsp:
   1605 {
   1606   do_repl (SD_, RD, IMM8, 0);
   1607 }
   1608 
   1609 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
   1610 "replv.qb r<RD>, r<RT>"
   1611 *dsp:
   1612 {
   1613   do_repl (SD_, RD, RT, 1);
   1614 }
   1615 
   1616 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
   1617 "repl.ph r<RD>, <IMM10>"
   1618 *dsp:
   1619 {
   1620   do_repl (SD_, RD, IMM10, 2);
   1621 }
   1622 
   1623 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
   1624 "replv.ph r<RD>, r<RT>"
   1625 *dsp:
   1626 {
   1627   do_repl (SD_, RD, RT, 3);
   1628 }
   1629 
   1630 // op: 0 = EQ, 1 = LT, 2 = LE
   1631 :function:::void:do_qb_cmpu:int rs, int rt, int op
   1632 {
   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     }
   1651 }
   1652 
   1653 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
   1654 "cmpu.eq.qb r<RS>, r<RT>"
   1655 *dsp:
   1656 {
   1657   do_qb_cmpu (SD_, RS, RT, 0);
   1658 }
   1659 
   1660 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
   1661 "cmpu.lt.qb r<RS>, r<RT>"
   1662 *dsp:
   1663 {
   1664   do_qb_cmpu (SD_, RS, RT, 1);
   1665 }
   1666 
   1667 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
   1668 "cmpu.le.qb r<RS>, r<RT>"
   1669 *dsp:
   1670 {
   1671   do_qb_cmpu (SD_, RS, RT, 2);
   1672 }
   1673 
   1674 // op: 0 = EQ, 1 = LT, 2 = LE
   1675 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
   1676 {
   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);
   1694 }
   1695 
   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:
   1699 {
   1700   do_qb_cmpgu (SD_, RD, RS, RT, 0);
   1701 }
   1702 
   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:
   1706 {
   1707   do_qb_cmpgu (SD_, RD, RS, RT, 1);
   1708 }
   1709 
   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:
   1713 {
   1714   do_qb_cmpgu (SD_, RD, RS, RT, 2);
   1715 }
   1716 
   1717 // op: 0 = EQ, 1 = LT, 2 = LE
   1718 :function:::void:do_ph_cmpu:int rs, int rt, int op
   1719 {
   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     }
   1738 }
   1739 
   1740 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
   1741 "cmp.eq.ph r<RS>, r<RT>"
   1742 *dsp:
   1743 {
   1744   do_ph_cmpu (SD_, RS, RT, 0);
   1745 }
   1746 
   1747 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
   1748 "cmp.lt.ph r<RS>, r<RT>"
   1749 *dsp:
   1750 {
   1751   do_ph_cmpu (SD_, RS, RT, 1);
   1752 }
   1753 
   1754 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
   1755 "cmp.le.ph r<RS>, r<RT>"
   1756 *dsp:
   1757 {
   1758   do_ph_cmpu (SD_, RS, RT, 2);
   1759 }
   1760 
   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:
   1764 {
   1765   do_qb_pick (SD_, RD, RS, RT);
   1766 }
   1767 
   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:
   1771 {
   1772   do_ph_pick (SD_, RD, RS, RT);
   1773 }
   1774 
   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:
   1778 {
   1779   do_ph_packrl (SD_, RD, RS, RT);
   1780 }
   1781 
   1782 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
   1783 :function:::void:do_w_extr:int rt, int ac, int shift, int op
   1784 {
   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);
   1844 }
   1845 
   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:
   1849 {
   1850   do_w_extr (SD_, RT, AC, SHIFT, 0);
   1851 }
   1852 
   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:
   1856 {
   1857   do_extrv (SD_, RT, AC, RS, 0);
   1858 }
   1859 
   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:
   1863 {
   1864   do_w_extr (SD_, RT, AC, SHIFT, 1);
   1865 }
   1866 
   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:
   1870 {
   1871   do_extrv (SD_, RT, AC, RS, 1);
   1872 }
   1873 
   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:
   1877 {
   1878   do_w_extr (SD_, RT, AC, SHIFT, 2);
   1879 }
   1880 
   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:
   1884 {
   1885   do_extrv (SD_, RT, AC, RS, 2);
   1886 }
   1887 
   1888 :function:::void:do_h_extr:int rt, int ac, int shift
   1889 {
   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);
   1907 }
   1908 
   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:
   1912 {
   1913   do_h_extr (SD_, RT, AC, SHIFT);
   1914 }
   1915 
   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:
   1919 {
   1920   do_extrv_s_h (SD_, RT, AC, RS);
   1921 }
   1922 
   1923 // op: 0 = EXTP, 1 = EXTPDP
   1924 :function:::void:do_extp:int rt, int ac, int size, int op
   1925 {
   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);
   1955 }
   1956 
   1957 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
   1958 "extp r<RT>, ac<AC>, <SIZE>"
   1959 *dsp:
   1960 {
   1961   do_extp (SD_, RT, AC, SIZE, 0);
   1962 }
   1963 
   1964 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
   1965 "extpv r<RT>, ac<AC>, r<RS>"
   1966 *dsp:
   1967 {
   1968   do_extpv (SD_, RT, AC, RS, 0);
   1969 }
   1970 
   1971 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
   1972 "extpdp r<RT>, ac<AC>, <SIZE>"
   1973 *dsp:
   1974 {
   1975   do_extp (SD_, RT, AC, SIZE, 1);
   1976 }
   1977 
   1978 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
   1979 "extpdpv r<RT>, ac<AC>, r<RS>"
   1980 *dsp:
   1981 {
   1982   do_extpv (SD_, RT, AC, RS, 1);
   1983 }
   1984 
   1985 :function:::void:do_shilo:int ac, int shift
   1986 {
   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);
   1998 }
   1999 
   2000 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
   2001 "shilo ac<AC>, <SHIFT6>"
   2002 *dsp:
   2003 {
   2004   do_shilo (SD_, AC, SHIFT6);
   2005 }
   2006 
   2007 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
   2008 "shilov ac<AC>, r<RS>"
   2009 *dsp:
   2010 {
   2011   do_shilov (SD_, AC, RS);
   2012 }
   2013 
   2014 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
   2015 "mthlip r<RS>, ac<AC>"
   2016 *dsp:
   2017 {
   2018   do_mthlip (SD_, RS, AC);
   2019 }
   2020 
   2021 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
   2022 "wrdsp r<RS>":MASK10 == 1111111111
   2023 "wrdsp r<RS>, <MASK10>"
   2024 *dsp:
   2025 {
   2026   do_wrdsp (SD_, RS, MASK10);
   2027 }
   2028 
   2029 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
   2030 "rddsp r<RD>":MASK10 == 1111111111
   2031 "rddsp r<RD>, <MASK10>"
   2032 *dsp:
   2033 {
   2034   do_rddsp (SD_, RD, MASK10);
   2035 }
   2036 
   2037 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
   2038 "lbux r<RD>, r<INDEX>(r<BASE>)"
   2039 *dsp:
   2040 {
   2041   do_lxx (SD_, RD, BASE, INDEX, 0);
   2042 }
   2043 
   2044 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
   2045 "lhx r<RD>, r<INDEX>(r<BASE>)"
   2046 *dsp:
   2047 {
   2048   do_lxx (SD_, RD, BASE, INDEX, 1);
   2049 }
   2050 
   2051 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
   2052 "lwx r<RD>, r<INDEX>(r<BASE>)"
   2053 *dsp:
   2054 {
   2055   do_lxx (SD_, RD, BASE, INDEX, 2);
   2056 }
   2057 
   2058 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
   2059 "bposge32 <OFFSET>"
   2060 *dsp:
   2061 {
   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     }
   2068 }
   2069