Home | History | Annotate | Line # | Download | only in mips
dsp2.igen revision 1.1
      1  1.1  christos // -*- C -*-
      2  1.1  christos 
      3  1.1  christos // Simulator definition for the MIPS DSP REV 2 ASE.
      4  1.1  christos // Copyright (C) 2007, 2010 Free Software Foundation, Inc.
      5  1.1  christos // Contributed by MIPS Technologies, Inc.
      6  1.1  christos // Written by Chao-ying Fu (fu (a] mips.com).
      7  1.1  christos //
      8  1.1  christos // This file is part of GDB, the GNU debugger.
      9  1.1  christos //
     10  1.1  christos // This program is free software; you can redistribute it and/or modify
     11  1.1  christos // it under the terms of the GNU General Public License as published by
     12  1.1  christos // the Free Software Foundation; either version 3 of the License, or
     13  1.1  christos // (at your option) any later version.
     14  1.1  christos //
     15  1.1  christos // This program is distributed in the hope that it will be useful,
     16  1.1  christos // but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  1.1  christos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  1.1  christos // GNU General Public License for more details.
     19  1.1  christos //
     20  1.1  christos // You should have received a copy of the GNU General Public License
     21  1.1  christos // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     22  1.1  christos 
     23  1.1  christos 
     24  1.1  christos // op: 0 = ADD, 1 = SUB
     25  1.1  christos // sat: 0 = no saturation, 1 = saturation
     26  1.1  christos :function:::void:do_u_ph_op:int rd, int rs, int rt, int op, int sat
     27  1.1  christos {
     28  1.1  christos   int i;
     29  1.1  christos   unsigned32 h0;
     30  1.1  christos   unsigned16 h1, h2;
     31  1.1  christos   unsigned32 v1 = GPR[rs];
     32  1.1  christos   unsigned32 v2 = GPR[rt];
     33  1.1  christos   unsigned32 result = 0;
     34  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
     35  1.1  christos     {
     36  1.1  christos       h1 = (unsigned16)(v1 & 0xffff);
     37  1.1  christos       h2 = (unsigned16)(v2 & 0xffff);
     38  1.1  christos       if (op == 0) // ADD
     39  1.1  christos 	h0 = (unsigned32)h1 + (unsigned32)h2;
     40  1.1  christos       else // SUB
     41  1.1  christos 	h0 = (unsigned32)h1 - (unsigned32)h2;
     42  1.1  christos       if (op == 0 && (h0 > (unsigned32)0x0000ffff)) // ADD SAT
     43  1.1  christos 	{
     44  1.1  christos 	  DSPCR |= DSPCR_OUFLAG4;
     45  1.1  christos 	  if (sat == 1)
     46  1.1  christos 	    h0 = 0xffff;
     47  1.1  christos 	}
     48  1.1  christos       else if (op == 1 && h1 < h2) // SUB SAT
     49  1.1  christos 	{
     50  1.1  christos 	  DSPCR |= DSPCR_OUFLAG4;
     51  1.1  christos 	  if (sat == 1)
     52  1.1  christos 	    h0 = 0x0;
     53  1.1  christos 	}
     54  1.1  christos       result |= ((unsigned32)((unsigned16)h0) << i);
     55  1.1  christos     }
     56  1.1  christos   GPR[rd] = EXTEND32 (result);
     57  1.1  christos }
     58  1.1  christos 
     59  1.1  christos // op: 0 = ADD, 1 = SUB
     60  1.1  christos // round: 0 = no rounding, 1 = rounding
     61  1.1  christos :function:::void:do_uh_qb_op:int rd, int rs, int rt, int op, int round
     62  1.1  christos {
     63  1.1  christos   int i;
     64  1.1  christos   unsigned32 h0;
     65  1.1  christos   unsigned8 h1, h2;
     66  1.1  christos   unsigned32 v1 = GPR[rs];
     67  1.1  christos   unsigned32 v2 = GPR[rt];
     68  1.1  christos   unsigned32 result = 0;
     69  1.1  christos   for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
     70  1.1  christos     {
     71  1.1  christos       h1 = (unsigned8)(v1 & 0xff);
     72  1.1  christos       h2 = (unsigned8)(v2 & 0xff);
     73  1.1  christos       if (op == 0) // ADD
     74  1.1  christos 	h0 = (unsigned32)h1 + (unsigned32)h2;
     75  1.1  christos       else // SUB
     76  1.1  christos 	h0 = (unsigned32)h1 - (unsigned32)h2;
     77  1.1  christos       if (round == 1)
     78  1.1  christos 	h0 = (h0 + 1) >> 1;
     79  1.1  christos       else
     80  1.1  christos 	h0 = h0 >> 1;
     81  1.1  christos       result |= ((unsigned32)((unsigned8)h0) << i);
     82  1.1  christos     }
     83  1.1  christos   GPR[rd] = EXTEND32 (result);
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos // op: 0 = EQ, 1 = LT, 2 = LE
     87  1.1  christos :function:::void:do_qb_cmpgdu:int rd, int rs, int rt, int op
     88  1.1  christos {
     89  1.1  christos   int i, j;
     90  1.1  christos   unsigned32 v1 = GPR[rs];
     91  1.1  christos   unsigned32 v2 = GPR[rt];
     92  1.1  christos   unsigned8 h1, h2;
     93  1.1  christos   unsigned32 result = 0;
     94  1.1  christos   unsigned32 mask;
     95  1.1  christos   for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
     96  1.1  christos     {
     97  1.1  christos       h1 = (unsigned8)(v1 & 0xff);
     98  1.1  christos       h2 = (unsigned8)(v2 & 0xff);
     99  1.1  christos       mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
    100  1.1  christos       DSPCR &= mask;
    101  1.1  christos       if (op == 0) // EQ
    102  1.1  christos 	{
    103  1.1  christos 	  result |= ((h1 == h2) << j);
    104  1.1  christos 	  DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
    105  1.1  christos 	}
    106  1.1  christos       else if (op == 1) // LT
    107  1.1  christos 	{
    108  1.1  christos 	  result |= ((h1 < h2) << j);
    109  1.1  christos 	  DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
    110  1.1  christos 	}
    111  1.1  christos       else // LE
    112  1.1  christos 	{
    113  1.1  christos 	  result |= ((h1 <= h2) << j);
    114  1.1  christos 	  DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
    115  1.1  christos 	}
    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 = DPA 1 = DPS
    121  1.1  christos :function:::void:do_w_ph_dot_product:int ac, int rs, int rt, int op
    122  1.1  christos {
    123  1.1  christos   int i;
    124  1.1  christos   unsigned32 v1 = GPR[rs];
    125  1.1  christos   unsigned32 v2 = GPR[rt];
    126  1.1  christos   signed16 h1, h2;
    127  1.1  christos   signed32 result;
    128  1.1  christos   unsigned32 lo = DSPLO(ac);
    129  1.1  christos   unsigned32 hi = DSPHI(ac);
    130  1.1  christos   signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
    131  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
    132  1.1  christos     {
    133  1.1  christos       h1 = (signed16)(v1 & 0xffff);
    134  1.1  christos       h2 = (signed16)(v2 & 0xffff);
    135  1.1  christos       result = (signed32)h1 * (signed32)h2;
    136  1.1  christos       if (op == 0) // DPA
    137  1.1  christos         prod += (signed64)result;
    138  1.1  christos       else // DPS
    139  1.1  christos         prod -= (signed64)result;
    140  1.1  christos     }
    141  1.1  christos   DSPLO(ac) = EXTEND32 (prod);
    142  1.1  christos   DSPHI(ac) = EXTEND32 (prod >> 32);
    143  1.1  christos }
    144  1.1  christos 
    145  1.1  christos // round: 0 = no rounding, 1 = rounding
    146  1.1  christos :function:::void:do_w_mulq:int rd, int rs, int rt, int round
    147  1.1  christos {
    148  1.1  christos   unsigned32 v1 = GPR[rs];
    149  1.1  christos   unsigned32 v2 = GPR[rt];
    150  1.1  christos   signed32 w1, w2;
    151  1.1  christos   signed64 prod;
    152  1.1  christos   unsigned32 result;
    153  1.1  christos   w1 = (signed32) v1;
    154  1.1  christos   w2 = (signed32 )v2;
    155  1.1  christos   if (w1 == (signed32) 0x80000000 && w2 == (signed32) 0x80000000)
    156  1.1  christos     {
    157  1.1  christos       DSPCR |= DSPCR_OUFLAG5;
    158  1.1  christos       prod = 0x7fffffff;
    159  1.1  christos     }
    160  1.1  christos   else
    161  1.1  christos     {
    162  1.1  christos       prod = ((signed64) w1 * (signed64) w2) << 1;
    163  1.1  christos       if (round == 1)
    164  1.1  christos 	prod += 0x0000000080000000LL;
    165  1.1  christos       prod = prod >> 32;
    166  1.1  christos     }
    167  1.1  christos   result = (unsigned32) prod;
    168  1.1  christos   GPR[rd] = EXTEND32 (result);
    169  1.1  christos }
    170  1.1  christos 
    171  1.1  christos // round: 0 = no rounding, 1 = rounding
    172  1.1  christos :function:::void:do_precr_sra:int rt, int rs, int sa, int round
    173  1.1  christos {
    174  1.1  christos   unsigned32 v1 = GPR[rt];
    175  1.1  christos   unsigned32 v2 = GPR[rs];
    176  1.1  christos   signed32 w1 = (signed32) v1;
    177  1.1  christos   signed32 w2 = (signed32) v2;
    178  1.1  christos   signed32 result;
    179  1.1  christos   if (sa != 0)
    180  1.1  christos     {
    181  1.1  christos       if (round == 1 && (w1 & (1 << (sa - 1))))
    182  1.1  christos 	w1 = (w1 >> sa) + 1;
    183  1.1  christos       else
    184  1.1  christos 	w1 = w1 >> sa;
    185  1.1  christos 
    186  1.1  christos       if (round == 1 && (w2 & (1 << (sa - 1))))
    187  1.1  christos 	w2 = (w2 >> sa) + 1;
    188  1.1  christos       else
    189  1.1  christos 	w2 = w2 >> sa;
    190  1.1  christos     }
    191  1.1  christos   result = (w1 << 16) | (w2 & 0xffff);
    192  1.1  christos   GPR[rt] = EXTEND32 (result);
    193  1.1  christos }
    194  1.1  christos 
    195  1.1  christos // round: 0 = no rounding, 1 = rounding
    196  1.1  christos :function:::void:do_qb_shra:int rd, int rt, int shift, int round
    197  1.1  christos {
    198  1.1  christos   int i, j;
    199  1.1  christos   signed8 q0;
    200  1.1  christos   unsigned32 v1 = GPR[rt];
    201  1.1  christos   unsigned32 result = 0;
    202  1.1  christos   for (i = 0; i < 32; i += 8, v1 >>= 8)
    203  1.1  christos     {
    204  1.1  christos       q0 = (signed8)(v1 & 0xff);
    205  1.1  christos       if (shift != 0)
    206  1.1  christos  	{
    207  1.1  christos 	  if (round == 1 && (q0 & (1 << (shift - 1))))
    208  1.1  christos 	    q0 = (q0 >> shift) + 1;
    209  1.1  christos 	  else
    210  1.1  christos 	    q0 = q0 >> shift;
    211  1.1  christos  	}
    212  1.1  christos       result |= ((unsigned32)((unsigned8)q0) << i);
    213  1.1  christos     }
    214  1.1  christos   GPR[rd] = EXTEND32 (result);
    215  1.1  christos }
    216  1.1  christos 
    217  1.1  christos :function:::void:do_ph_shrl:int rd, int rt, int shift
    218  1.1  christos {
    219  1.1  christos   int i, j;
    220  1.1  christos   unsigned16 h0;
    221  1.1  christos   unsigned32 v1 = GPR[rt];
    222  1.1  christos   unsigned32 result = 0;
    223  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16)
    224  1.1  christos     {
    225  1.1  christos       h0 = (unsigned16)(v1 & 0xffff);
    226  1.1  christos       h0 = h0 >> shift;
    227  1.1  christos       result |= ((unsigned32)h0 << i);
    228  1.1  christos     }
    229  1.1  christos   GPR[rd] = EXTEND32 (result);
    230  1.1  christos }
    231  1.1  christos 
    232  1.1  christos // op: 0 = ADD, 1 = SUB
    233  1.1  christos // round: 0 = no rounding, 1 = rounding
    234  1.1  christos :function:::void:do_qh_ph_op:int rd, int rs, int rt, int op, int round
    235  1.1  christos {
    236  1.1  christos   int i;
    237  1.1  christos   signed32 h0;
    238  1.1  christos   signed16 h1, h2;
    239  1.1  christos   unsigned32 v1 = GPR[rs];
    240  1.1  christos   unsigned32 v2 = GPR[rt];
    241  1.1  christos   unsigned32 result = 0;
    242  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
    243  1.1  christos     {
    244  1.1  christos       h1 = (signed16)(v1 & 0xffff);
    245  1.1  christos       h2 = (signed16)(v2 & 0xffff);
    246  1.1  christos       if (op == 0) // ADD
    247  1.1  christos 	h0 = (signed32)h1 + (signed32)h2;
    248  1.1  christos       else // SUB
    249  1.1  christos 	h0 = (signed32)h1 - (signed32)h2;
    250  1.1  christos       if (round == 1)
    251  1.1  christos 	h0 = (h0 + 1) >> 1;
    252  1.1  christos       else
    253  1.1  christos 	h0 = h0 >> 1;
    254  1.1  christos       result |= ((unsigned32)((unsigned16)h0) << i);
    255  1.1  christos     }
    256  1.1  christos   GPR[rd] = EXTEND32 (result);
    257  1.1  christos }
    258  1.1  christos 
    259  1.1  christos // op: 0 = ADD, 1 = SUB
    260  1.1  christos // round: 0 = no rounding, 1 = rounding
    261  1.1  christos :function:::void:do_qh_w_op:int rd, int rs, int rt, int op, int round
    262  1.1  christos {
    263  1.1  christos   int i;
    264  1.1  christos   signed64 v0;
    265  1.1  christos   signed32 v1 = (signed32)GPR[rs];
    266  1.1  christos   signed32 v2 = (signed32)GPR[rt];
    267  1.1  christos   if (op == 0) // ADD
    268  1.1  christos     v0 = (signed64)v1 + (signed64)v2;
    269  1.1  christos   else // SUB
    270  1.1  christos     v0 = (signed64)v1 - (signed64)v2;
    271  1.1  christos   if (round == 1)
    272  1.1  christos     v0 = (v0 + 1) >> 1;
    273  1.1  christos   else
    274  1.1  christos     v0 = v0 >> 1;
    275  1.1  christos   GPR[rd] = EXTEND32 (v0);
    276  1.1  christos }
    277  1.1  christos 
    278  1.1  christos // op: 0 = DPAX, 1 = DPSX
    279  1.1  christos :function:::void:do_x_w_ph_dot_product:int ac, int rs, int rt, int op
    280  1.1  christos {
    281  1.1  christos   int i;
    282  1.1  christos   unsigned32 v1 = GPR[rs];
    283  1.1  christos   unsigned32 v2 = GPR[rt];
    284  1.1  christos   signed16 h1, h2;
    285  1.1  christos   signed32 result;
    286  1.1  christos   unsigned32 lo = DSPLO(ac);
    287  1.1  christos   unsigned32 hi = DSPHI(ac);
    288  1.1  christos   signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
    289  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 <<= 16)
    290  1.1  christos     {
    291  1.1  christos       h1 = (signed16)(v1 & 0xffff);
    292  1.1  christos       h2 = (signed16)((v2 & 0xffff0000) >> 16);
    293  1.1  christos       result = (signed32)h1 * (signed32)h2;
    294  1.1  christos       if (op == 0) // DPAX
    295  1.1  christos         prod += (signed64)result;
    296  1.1  christos       else // DPSX
    297  1.1  christos         prod -= (signed64)result;
    298  1.1  christos     }
    299  1.1  christos   DSPLO(ac) = EXTEND32 (prod);
    300  1.1  christos   DSPHI(ac) = EXTEND32 (prod >> 32);
    301  1.1  christos }
    302  1.1  christos 
    303  1.1  christos // op: 0 = DPAQX, 1 = DPSQX
    304  1.1  christos // sat: 0 = no saturation, 1 = saturation of the accumulator
    305  1.1  christos :function:::void:do_qx_w_ph_dot_product:int ac, int rs, int rt, int op, int sat
    306  1.1  christos {
    307  1.1  christos   int i;
    308  1.1  christos   unsigned32 v1 = GPR[rs];
    309  1.1  christos   unsigned32 v2 = GPR[rt];
    310  1.1  christos   signed16 h1, h2;
    311  1.1  christos   signed32 result;
    312  1.1  christos   unsigned32 lo = DSPLO(ac);
    313  1.1  christos   unsigned32 hi = DSPHI(ac);
    314  1.1  christos   signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
    315  1.1  christos   signed64 max, min;
    316  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 <<= 16)
    317  1.1  christos     {
    318  1.1  christos       h1 = (signed16)(v1 & 0xffff);
    319  1.1  christos       h2 = (signed16)((v2 & 0xffff0000) >> 16);
    320  1.1  christos       if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
    321  1.1  christos 	{
    322  1.1  christos 	  DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
    323  1.1  christos 	  result = 0x7fffffff;
    324  1.1  christos 	}
    325  1.1  christos       else
    326  1.1  christos 	result = ((signed32)h1 * (signed32)h2) << 1;
    327  1.1  christos       if (op == 0) // DPAQX
    328  1.1  christos         prod += (signed64)result;
    329  1.1  christos       else // DPSQX
    330  1.1  christos         prod -= (signed64)result;
    331  1.1  christos     }
    332  1.1  christos   // Saturation on the accumulator.
    333  1.1  christos   if (sat == 1)
    334  1.1  christos     {
    335  1.1  christos       max = (signed64) 0x7fffffffLL;
    336  1.1  christos       min = (signed64) 0xffffffff80000000LL;
    337  1.1  christos       if (prod > max)
    338  1.1  christos 	{
    339  1.1  christos 	  DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
    340  1.1  christos 	  prod = max;
    341  1.1  christos 	}
    342  1.1  christos       else if (prod < min)
    343  1.1  christos 	{
    344  1.1  christos 	  DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
    345  1.1  christos 	  prod = min;
    346  1.1  christos 	}
    347  1.1  christos     }
    348  1.1  christos   DSPLO(ac) = EXTEND32 (prod);
    349  1.1  christos   DSPHI(ac) = EXTEND32 (prod >> 32);
    350  1.1  christos }
    351  1.1  christos 
    352  1.1  christos 011111,00000,5.RT,5.RD,00001,010010:SPECIAL3:32::ABSQ_S.QB
    353  1.1  christos "absq_s.qb r<RD>, r<RT>"
    354  1.1  christos *dsp2:
    355  1.1  christos {
    356  1.1  christos   int i;
    357  1.1  christos   signed8 q0;
    358  1.1  christos   unsigned32 v1 = GPR[RT];
    359  1.1  christos   unsigned32 result = 0;
    360  1.1  christos   for (i = 0; i < 32; i += 8, v1 >>= 8)
    361  1.1  christos     {
    362  1.1  christos       q0 = (signed8)(v1 & 0xff);
    363  1.1  christos       if (q0 == (signed8)0x80)
    364  1.1  christos         {
    365  1.1  christos           DSPCR |= DSPCR_OUFLAG4;
    366  1.1  christos           q0 = 0x7f;
    367  1.1  christos         }
    368  1.1  christos       else if (q0 & 0x80)
    369  1.1  christos         q0 = -q0;
    370  1.1  christos       result |= ((unsigned32)((unsigned8)q0) << i);
    371  1.1  christos     }
    372  1.1  christos   GPR[RD] = EXTEND32 (result);
    373  1.1  christos }
    374  1.1  christos 
    375  1.1  christos 011111,5.RS,5.RT,5.RD,01000,010000:SPECIAL3:32::ADDU.PH
    376  1.1  christos "addu.ph r<RD>, r<RS>, r<RT>"
    377  1.1  christos *dsp2:
    378  1.1  christos {
    379  1.1  christos   do_u_ph_op (SD_, RD, RS, RT, 0, 0);
    380  1.1  christos }
    381  1.1  christos 
    382  1.1  christos 011111,5.RS,5.RT,5.RD,01100,010000:SPECIAL3:32::ADDU_S.PH
    383  1.1  christos "addu_s.ph r<RD>, r<RS>, r<RT>"
    384  1.1  christos *dsp2:
    385  1.1  christos {
    386  1.1  christos   do_u_ph_op (SD_, RD, RS, RT, 0, 1);
    387  1.1  christos }
    388  1.1  christos 
    389  1.1  christos 011111,5.RS,5.RT,5.RD,00000,011000:SPECIAL3:32::ADDUH.QB
    390  1.1  christos "adduh.qb r<RD>, r<RS>, r<RT>"
    391  1.1  christos *dsp2:
    392  1.1  christos {
    393  1.1  christos   do_uh_qb_op (SD_, RD, RS, RT, 0, 0);
    394  1.1  christos }
    395  1.1  christos 
    396  1.1  christos 011111,5.RS,5.RT,5.RD,00010,011000:SPECIAL3:32::ADDUH_R.QB
    397  1.1  christos "adduh_r.qb r<RD>, r<RS>, r<RT>"
    398  1.1  christos *dsp2:
    399  1.1  christos {
    400  1.1  christos   do_uh_qb_op (SD_, RD, RS, RT, 0, 1);
    401  1.1  christos }
    402  1.1  christos 
    403  1.1  christos 011111,5.RS,5.RT,5.SA,00000,110001:SPECIAL3:32::APPEND
    404  1.1  christos "append r<RT>, r<RS>, <SA>"
    405  1.1  christos *dsp2:
    406  1.1  christos {
    407  1.1  christos   unsigned32 v0 = GPR[RS];
    408  1.1  christos   unsigned32 v1 = GPR[RT];
    409  1.1  christos   unsigned32 result;
    410  1.1  christos   unsigned32 mask = (1 << SA) - 1;
    411  1.1  christos   result = (v1 << SA) | (v0 & mask);
    412  1.1  christos   GPR[RT] = EXTEND32 (result);
    413  1.1  christos }
    414  1.1  christos 
    415  1.1  christos 011111,5.RS,5.RT,000,2.BP,10000,110001:SPECIAL3:32::BALIGN
    416  1.1  christos "balign r<RT>, r<RS>, <BP>"
    417  1.1  christos *dsp2:
    418  1.1  christos {
    419  1.1  christos   unsigned32 v0 = GPR[RS];
    420  1.1  christos   unsigned32 v1 = GPR[RT];
    421  1.1  christos   unsigned32 result;
    422  1.1  christos   if (BP == 0)
    423  1.1  christos     result = v1;
    424  1.1  christos   else
    425  1.1  christos     result = (v1 << 8 * BP) | (v0 >> 8 * (4 - BP));
    426  1.1  christos   GPR[RT] = EXTEND32 (result);
    427  1.1  christos }
    428  1.1  christos 
    429  1.1  christos 011111,5.RS,5.RT,5.RD,11000,010001:SPECIAL3:32::CMPGDU.EQ.QB
    430  1.1  christos "cmpgdu.eq.qb r<RD>, r<RS>, r<RT>"
    431  1.1  christos *dsp2:
    432  1.1  christos {
    433  1.1  christos   do_qb_cmpgdu (SD_, RD, RS, RT, 0);
    434  1.1  christos }
    435  1.1  christos 
    436  1.1  christos 011111,5.RS,5.RT,5.RD,11001,010001:SPECIAL3:32::CMPGDU.LT.QB
    437  1.1  christos "cmpgdu.lt.qb r<RD>, r<RS>, r<RT>"
    438  1.1  christos *dsp2:
    439  1.1  christos {
    440  1.1  christos   do_qb_cmpgdu (SD_, RD, RS, RT, 1);
    441  1.1  christos }
    442  1.1  christos 
    443  1.1  christos 011111,5.RS,5.RT,5.RD,11010,010001:SPECIAL3:32::CMPGDU.LE.QB
    444  1.1  christos "cmpgdu.le.qb r<RD>, r<RS>, r<RT>"
    445  1.1  christos *dsp2:
    446  1.1  christos {
    447  1.1  christos   do_qb_cmpgdu (SD_, RD, RS, RT, 2);
    448  1.1  christos }
    449  1.1  christos 
    450  1.1  christos 011111,5.RS,5.RT,000,2.AC,00000,110000:SPECIAL3:32::DPA.W.PH
    451  1.1  christos "dpa.w.ph ac<AC>, r<RS>, r<RT>"
    452  1.1  christos *dsp2:
    453  1.1  christos {
    454  1.1  christos   do_w_ph_dot_product (SD_, AC, RS, RT, 0);
    455  1.1  christos }
    456  1.1  christos 
    457  1.1  christos 011111,5.RS,5.RT,000,2.AC,00001,110000:SPECIAL3:32::DPS.W.PH
    458  1.1  christos "dps.w.ph ac<AC>, r<RS>, r<RT>"
    459  1.1  christos *dsp2:
    460  1.1  christos {
    461  1.1  christos   do_w_ph_dot_product (SD_, AC, RS, RT, 1);
    462  1.1  christos }
    463  1.1  christos 
    464  1.1  christos 011111,5.RS,5.RT,5.RD,01100,011000:SPECIAL3:32::MUL.PH
    465  1.1  christos "mul.ph r<RD>, r<RS>, r<RT>"
    466  1.1  christos *dsp2:
    467  1.1  christos {
    468  1.1  christos   do_ph_op (SD_, RD, RS, RT, 2, 0);
    469  1.1  christos }
    470  1.1  christos 
    471  1.1  christos 011111,5.RS,5.RT,5.RD,01110,011000:SPECIAL3:32::MUL_S.PH
    472  1.1  christos "mul_s.ph r<RD>, r<RS>, r<RT>"
    473  1.1  christos *dsp2:
    474  1.1  christos {
    475  1.1  christos   do_ph_op (SD_, RD, RS, RT, 2, 1);
    476  1.1  christos }
    477  1.1  christos 
    478  1.1  christos 011111,5.RS,5.RT,5.RD,10111,011000:SPECIAL3:32::MULQ_RS.W
    479  1.1  christos "mulq_rs.w r<RD>, r<RS>, r<RT>"
    480  1.1  christos *dsp2:
    481  1.1  christos {
    482  1.1  christos   do_w_mulq (SD_, RD, RS, RT, 1);
    483  1.1  christos }
    484  1.1  christos 
    485  1.1  christos 011111,5.RS,5.RT,5.RD,11110,010000:SPECIAL3:32::MULQ_S.PH
    486  1.1  christos "mulq_s.ph r<RD>, r<RS>, r<RT>"
    487  1.1  christos *dsp2:
    488  1.1  christos {
    489  1.1  christos   do_ph_mulq (SD_, RD, RS, RT, 0);
    490  1.1  christos }
    491  1.1  christos 
    492  1.1  christos 011111,5.RS,5.RT,5.RD,10110,011000:SPECIAL3:32::MULQ_S.W
    493  1.1  christos "mulq_s.w r<RD>, r<RS>, r<RT>"
    494  1.1  christos *dsp2:
    495  1.1  christos {
    496  1.1  christos   do_w_mulq (SD_, RD, RS, RT, 0);
    497  1.1  christos }
    498  1.1  christos 
    499  1.1  christos 011111,5.RS,5.RT,000,2.AC,00010,110000:SPECIAL3:32::MULSA.W.PH
    500  1.1  christos "mulsa.w.ph ac<AC>, r<RS>, r<RT>"
    501  1.1  christos *dsp2:
    502  1.1  christos {
    503  1.1  christos   int i;
    504  1.1  christos   unsigned32 v1 = GPR[RS];
    505  1.1  christos   unsigned32 v2 = GPR[RT];
    506  1.1  christos   signed16 h1, h2;
    507  1.1  christos   signed32 result;
    508  1.1  christos   unsigned32 lo = DSPLO(AC);
    509  1.1  christos   unsigned32 hi = DSPHI(AC);
    510  1.1  christos   signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
    511  1.1  christos   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
    512  1.1  christos     {
    513  1.1  christos       h1 = (signed16)(v1 & 0xffff);
    514  1.1  christos       h2 = (signed16)(v2 & 0xffff);
    515  1.1  christos       result = (signed32)h1 * (signed32)h2;
    516  1.1  christos 
    517  1.1  christos       if (i == 0)
    518  1.1  christos         prod -= (signed64) result;
    519  1.1  christos       else
    520  1.1  christos         prod += (signed64) result;
    521  1.1  christos     }
    522  1.1  christos   DSPLO(AC) = EXTEND32 (prod);
    523  1.1  christos   DSPHI(AC) = EXTEND32 (prod >> 32);
    524  1.1  christos }
    525  1.1  christos 
    526  1.1  christos 011111,5.RS,5.RT,5.RD,01101,010001:SPECIAL3:32::PRECR.QB.PH
    527  1.1  christos "precr.qb.ph r<RD>, r<RS>, r<RT>"
    528  1.1  christos *dsp2:
    529  1.1  christos {
    530  1.1  christos   unsigned32 v1 = GPR[RS];
    531  1.1  christos   unsigned32 v2 = GPR[RT];
    532  1.1  christos   unsigned32 tempu = (v1 & 0xff0000) >> 16;
    533  1.1  christos   unsigned32 tempv = (v1 & 0xff);
    534  1.1  christos   unsigned32 tempw = (v2 & 0xff0000) >> 16;
    535  1.1  christos   unsigned32 tempx = (v2 & 0xff);
    536  1.1  christos   GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
    537  1.1  christos }
    538  1.1  christos 
    539  1.1  christos 011111,5.RS,5.RT,5.SA,11110,010001:SPECIAL3:32::PRECR_SRA.PH.W
    540  1.1  christos "precr_sra.ph.w r<RT>, r<RS>, <SA>"
    541  1.1  christos *dsp2:
    542  1.1  christos {
    543  1.1  christos   do_precr_sra (SD_, RT, RS, SA, 0);
    544  1.1  christos }
    545  1.1  christos 
    546  1.1  christos 011111,5.RS,5.RT,5.SA,11111,010001:SPECIAL3:32::PRECR_SRA_R.PH.W
    547  1.1  christos "precr_sra_r.ph.w r<RT>, r<RS>, <SA>"
    548  1.1  christos *dsp2:
    549  1.1  christos {
    550  1.1  christos   do_precr_sra (SD_, RT, RS, SA, 1);
    551  1.1  christos }
    552  1.1  christos 
    553  1.1  christos 011111,5.RS,5.RT,5.SA,00001,110001:SPECIAL3:32::PREPEND
    554  1.1  christos "prepend r<RT>, r<RS>, <SA>"
    555  1.1  christos *dsp2:
    556  1.1  christos {
    557  1.1  christos   unsigned32 v0 = GPR[RS];
    558  1.1  christos   unsigned32 v1 = GPR[RT];
    559  1.1  christos   unsigned32 result;
    560  1.1  christos   if (SA == 0)
    561  1.1  christos     result = v1;
    562  1.1  christos   else
    563  1.1  christos     result = (v0 << (32 - SA)) | (v1 >> SA);
    564  1.1  christos   GPR[RT] = EXTEND32 (result);
    565  1.1  christos }
    566  1.1  christos 
    567  1.1  christos 011111,00,3.SHIFT3,5.RT,5.RD,00100,010011:SPECIAL3:32::SHRA.QB
    568  1.1  christos "shra.qb r<RD>, r<RT>, <SHIFT3>"
    569  1.1  christos *dsp2:
    570  1.1  christos {
    571  1.1  christos   do_qb_shra (SD_, RD, RT, SHIFT3, 0);
    572  1.1  christos }
    573  1.1  christos 
    574  1.1  christos 011111,00,3.SHIFT3,5.RT,5.RD,00101,010011:SPECIAL3:32::SHRA_R.QB
    575  1.1  christos "shra_r.qb r<RD>, r<RT>, <SHIFT3>"
    576  1.1  christos *dsp2:
    577  1.1  christos {
    578  1.1  christos   do_qb_shra (SD_, RD, RT, SHIFT3, 1);
    579  1.1  christos }
    580  1.1  christos 
    581  1.1  christos 011111,5.RS,5.RT,5.RD,00110,010011:SPECIAL3:32::SHRAV.QB
    582  1.1  christos "shrav.qb r<RD>, r<RT>, r<RS>"
    583  1.1  christos *dsp2:
    584  1.1  christos {
    585  1.1  christos   unsigned32 shift = GPR[RS] & 0x7;
    586  1.1  christos   do_qb_shra (SD_, RD, RT, shift, 0);
    587  1.1  christos }
    588  1.1  christos 
    589  1.1  christos 011111,5.RS,5.RT,5.RD,00111,010011:SPECIAL3:32::SHRAV_R.QB
    590  1.1  christos "shrav_r.qb r<RD>, r<RT>, r<RS>"
    591  1.1  christos *dsp2:
    592  1.1  christos {
    593  1.1  christos   unsigned32 shift = GPR[RS] & 0x7;
    594  1.1  christos   do_qb_shra (SD_, RD, RT, shift, 1);
    595  1.1  christos }
    596  1.1  christos 
    597  1.1  christos 011111,0,4.SHIFT4,5.RT,5.RD,11001,010011:SPECIAL3:32::SHRL.PH
    598  1.1  christos "shrl.ph r<RD>, r<RT>, <SHIFT4>"
    599  1.1  christos *dsp2:
    600  1.1  christos {
    601  1.1  christos   do_ph_shrl (SD_, RD, RT, SHIFT4);
    602  1.1  christos }
    603  1.1  christos 
    604  1.1  christos 011111,5.RS,5.RT,5.RD,11011,010011:SPECIAL3:32::SHRLV.PH
    605  1.1  christos "shrlv.ph r<RD>, r<RT>, r<RS>"
    606  1.1  christos *dsp2:
    607  1.1  christos {
    608  1.1  christos   unsigned32 shift = GPR[RS] & 0xf;
    609  1.1  christos   do_ph_shrl (SD_, RD, RT, shift);
    610  1.1  christos }
    611  1.1  christos 
    612  1.1  christos 011111,5.RS,5.RT,5.RD,01001,010000:SPECIAL3:32::SUBU.PH
    613  1.1  christos "subu.ph r<RD>, r<RS>, r<RT>"
    614  1.1  christos *dsp2:
    615  1.1  christos {
    616  1.1  christos   do_u_ph_op (SD_, RD, RS, RT, 1, 0);
    617  1.1  christos }
    618  1.1  christos 
    619  1.1  christos 011111,5.RS,5.RT,5.RD,01101,010000:SPECIAL3:32::SUBU_S.PH
    620  1.1  christos "subu_s.ph r<RD>, r<RS>, r<RT>"
    621  1.1  christos *dsp2:
    622  1.1  christos {
    623  1.1  christos   do_u_ph_op (SD_, RD, RS, RT, 1, 1);
    624  1.1  christos }
    625  1.1  christos 
    626  1.1  christos 011111,5.RS,5.RT,5.RD,00001,011000:SPECIAL3:32::SUBUH.QB
    627  1.1  christos "subuh.qb r<RD>, r<RS>, r<RT>"
    628  1.1  christos *dsp2:
    629  1.1  christos {
    630  1.1  christos   do_uh_qb_op (SD_, RD, RS, RT, 1, 0);
    631  1.1  christos }
    632  1.1  christos 
    633  1.1  christos 011111,5.RS,5.RT,5.RD,00011,011000:SPECIAL3:32::SUBUH_R.QB
    634  1.1  christos "subuh_r.qb r<RD>, r<RS>, r<RT>"
    635  1.1  christos *dsp2:
    636  1.1  christos {
    637  1.1  christos   do_uh_qb_op (SD_, RD, RS, RT, 1, 1);
    638  1.1  christos }
    639  1.1  christos 
    640  1.1  christos 011111,5.RS,5.RT,5.RD,01000,011000:SPECIAL3:32::ADDQH.PH
    641  1.1  christos "addqh.ph r<RD>, r<RS>, r<RT>"
    642  1.1  christos *dsp2:
    643  1.1  christos {
    644  1.1  christos   do_qh_ph_op (SD_, RD, RS, RT, 0, 0);
    645  1.1  christos }
    646  1.1  christos 
    647  1.1  christos 011111,5.RS,5.RT,5.RD,01010,011000:SPECIAL3:32::ADDQH_R.PH
    648  1.1  christos "addqh_r.ph r<RD>, r<RS>, r<RT>"
    649  1.1  christos *dsp2:
    650  1.1  christos {
    651  1.1  christos   do_qh_ph_op (SD_, RD, RS, RT, 0, 1);
    652  1.1  christos }
    653  1.1  christos 
    654  1.1  christos 011111,5.RS,5.RT,5.RD,10000,011000:SPECIAL3:32::ADDQH.W
    655  1.1  christos "addqh.w r<RD>, r<RS>, r<RT>"
    656  1.1  christos *dsp2:
    657  1.1  christos {
    658  1.1  christos   do_qh_w_op (SD_, RD, RS, RT, 0, 0);
    659  1.1  christos }
    660  1.1  christos 
    661  1.1  christos 011111,5.RS,5.RT,5.RD,10010,011000:SPECIAL3:32::ADDQH_R.W
    662  1.1  christos "addqh_r.w r<RD>, r<RS>, r<RT>"
    663  1.1  christos *dsp2:
    664  1.1  christos {
    665  1.1  christos   do_qh_w_op (SD_, RD, RS, RT, 0, 1);
    666  1.1  christos }
    667  1.1  christos 
    668  1.1  christos 011111,5.RS,5.RT,5.RD,01001,011000:SPECIAL3:32::SUBQH.PH
    669  1.1  christos "subqh.ph r<RD>, r<RS>, r<RT>"
    670  1.1  christos *dsp2:
    671  1.1  christos {
    672  1.1  christos   do_qh_ph_op (SD_, RD, RS, RT, 1, 0);
    673  1.1  christos }
    674  1.1  christos 
    675  1.1  christos 011111,5.RS,5.RT,5.RD,01011,011000:SPECIAL3:32::SUBQH_R.PH
    676  1.1  christos "subqh_r.ph r<RD>, r<RS>, r<RT>"
    677  1.1  christos *dsp2:
    678  1.1  christos {
    679  1.1  christos   do_qh_ph_op (SD_, RD, RS, RT, 1, 1);
    680  1.1  christos }
    681  1.1  christos 
    682  1.1  christos 011111,5.RS,5.RT,5.RD,10001,011000:SPECIAL3:32::SUBQH.W
    683  1.1  christos "subqh.w r<RD>, r<RS>, r<RT>"
    684  1.1  christos *dsp2:
    685  1.1  christos {
    686  1.1  christos   do_qh_w_op (SD_, RD, RS, RT, 1, 0);
    687  1.1  christos }
    688  1.1  christos 
    689  1.1  christos 011111,5.RS,5.RT,5.RD,10011,011000:SPECIAL3:32::SUBQH_R.W
    690  1.1  christos "subqh_r.w r<RD>, r<RS>, r<RT>"
    691  1.1  christos *dsp2:
    692  1.1  christos {
    693  1.1  christos   do_qh_w_op (SD_, RD, RS, RT, 1, 1);
    694  1.1  christos }
    695  1.1  christos 
    696  1.1  christos 011111,5.RS,5.RT,000,2.AC,01000,110000:SPECIAL3:32::DPAX.W.PH
    697  1.1  christos "dpax.w.ph ac<AC>, r<RS>, r<RT>"
    698  1.1  christos *dsp2:
    699  1.1  christos {
    700  1.1  christos   do_x_w_ph_dot_product (SD_, AC, RS, RT, 0);
    701  1.1  christos }
    702  1.1  christos 
    703  1.1  christos 011111,5.RS,5.RT,000,2.AC,01001,110000:SPECIAL3:32::DPSX.W.PH
    704  1.1  christos "dpsx.w.ph ac<AC>, r<RS>, r<RT>"
    705  1.1  christos *dsp2:
    706  1.1  christos {
    707  1.1  christos   do_x_w_ph_dot_product (SD_, AC, RS, RT, 1);
    708  1.1  christos }
    709  1.1  christos 
    710  1.1  christos 011111,5.RS,5.RT,000,2.AC,11000,110000:SPECIAL3:32::DPAQX_S.W.PH
    711  1.1  christos "dpaqx_s.w.ph ac<AC>, r<RS>, r<RT>"
    712  1.1  christos *dsp2:
    713  1.1  christos {
    714  1.1  christos   do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 0);
    715  1.1  christos }
    716  1.1  christos 
    717  1.1  christos 011111,5.RS,5.RT,000,2.AC,11010,110000:SPECIAL3:32::DPAQX_SA.W.PH
    718  1.1  christos "dpaqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
    719  1.1  christos *dsp2:
    720  1.1  christos {
    721  1.1  christos   do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 1);
    722  1.1  christos }
    723  1.1  christos 
    724  1.1  christos 011111,5.RS,5.RT,000,2.AC,11001,110000:SPECIAL3:32::DPSQX_S.W.PH
    725  1.1  christos "dpsqx_s.w.ph ac<AC>, r<RS>, r<RT>"
    726  1.1  christos *dsp2:
    727  1.1  christos {
    728  1.1  christos   do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 0);
    729  1.1  christos }
    730  1.1  christos 
    731  1.1  christos 011111,5.RS,5.RT,000,2.AC,11011,110000:SPECIAL3:32::DPSQX_SA.W.PH
    732  1.1  christos "dpsqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
    733  1.1  christos *dsp2:
    734  1.1  christos {
    735  1.1  christos   do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 1);
    736  1.1  christos }
    737