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