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