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