]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/mips/dsp.igen
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / mips / dsp.igen
index 9c39b7160fd0a5d779bdda059d2be47b42a8db9a..39a32f3bd5ff979edf57b53140a6317e9248eb75 100644 (file)
@@ -1,32 +1,31 @@
 // -*- C -*-
 
 // Simulator definition for the MIPS DSP ASE.
-// Copyright (C) 2005 Free Software Foundation, Inc.
+// Copyright (C) 2005-2013 Free Software Foundation, Inc.
 // Contributed by MIPS Technologies, Inc.  Written by Chao-ying Fu.
 //
 // This file is part of GDB, the GNU debugger.
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2, or (at your option)
-// any later version.
-// 
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
-// op: 0 = ADD, 1 = SUB
+// op: 0 = ADD, 1 = SUB, 2 = MUL
 // sat: 0 = no saturation, 1 = saturation
 :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat
 {
   int i;
-  signed32 h0;
+  signed32 h0 = 0;
   signed16 h1, h2;
   unsigned32 v1 = GPR[rs];
   unsigned32 v2 = GPR[rt];
       h2 = (signed16)(v2 & 0xffff);
       if (op == 0) // ADD
        h0 = (signed32)h1 + (signed32)h2;
-      else // SUB
+      else if (op == 1) // SUB
         h0 = (signed32)h1 - (signed32)h2;
-      if (((h0 & 0x10000) >> 1) != (h0 & 0x8000))
+      else // MUL
+        h0 = (signed32)h1 * (signed32)h2;
+      if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
        {
-         DSPCR |= DSPCR_OUFLAG4;
+         if (op == 0 || op == 1) // ADD, SUB
+           DSPCR |= DSPCR_OUFLAG4;
+         else if (op == 2) // MUL
+           DSPCR |= DSPCR_OUFLAG5;
          if (sat == 1)
            {
-             if (h0 & 0x10000)
-               h0 = 0x8000;
-             else
+             if (h0 > (signed32)0x7fff)
                h0 = 0x7fff;
+             else
+               h0 = 0x8000;
            }
        }
       result |= ((unsigned32)((unsigned16)h0) << i);
     h0 = (signed64)h1 + (signed64)h2;
   else // SUB
     h0 = (signed64)h1 - (signed64)h2;
-  if (((h0 & 0x100000000) >> 1) != (h0 & 0x80000000))
+  if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
     {
       DSPCR |= DSPCR_OUFLAG4;
-      if (h0 & 0x100000000)
+      if (h0 & 0x100000000LL)
        h0 = 0x80000000;
       else
        h0 = 0x7fffffff;
        }
       else // right
        {
-         if (sat == 1 && shift != 0)
-           h0 += (1 << (shift - 1));
-         h0 = h0 >> shift;
+         if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
+           h0 = (h0 >> shift) + 1;
+         else
+           h0 = h0 >> shift;
        }
 
       result |= ((unsigned32)((unsigned16)h0) << i);
 {
   unsigned32 result = GPR[rt];
   signed32 h0 = (signed32)result;
-  if (shift != 0)
-    h0 += (1 << (shift - 1));
-  h0 = h0 >> shift;
+  if (shift != 0 && (h0 & (1 << (shift-1))))
+    h0 = (h0 >> shift) + 1;
+  else
+    h0 = h0 >> shift;
   GPR[rd] = EXTEND32 (h0);
 }
 
   do_qb_muleu (SD_, RD, RS, RT, 1);
 }
 
-011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
-"mulq_rs.ph r<RD>, r<RS>, r<RT>"
-*dsp:
+// round: 0 = no rounding, 1 = rounding
+:function:::void:do_ph_mulq:int rd, int rs, int rt, int round
 {
   int i;
   unsigned32 result = 0;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
   signed16 h1, h2;
   signed32 prod;
   for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
          prod = 0x7fffffff;
        }
       else
-       prod = (((signed32)h1 * (signed32)h2) << 1) + (signed32)0x8000;
-
+       {
+         prod = ((signed32)h1 * (signed32)h2) << 1;
+         if (round == 1)
+           prod += (signed32)0x8000;
+       }
       result |= (((unsigned32)prod >> 16) << i);
     }
-  GPR[RD] = EXTEND32 (result);
+  GPR[rd] = EXTEND32 (result);
+}
+
+011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
+"mulq_rs.ph r<RD>, r<RS>, r<RT>"
+*dsp:
+{
+  do_ph_mulq (SD_, RD, RS, RT, 1);
 }
 
 // loc: 0 = phl, 1 = phr
   DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
 }
 
-000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHIdsp
-"mfhi r<RD>":AC == 0
-"mfhi r<RD>, ac<AC>"
-*mips32:
-*mips32r2:
-*mips64:
-*mips64r2:
-*dsp:
-{
-  if (AC == 0)
-    do_mfhi (SD_, RD);
-  else
-    GPR[RD] = DSPHI(AC);
-}
-
-000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLOdsp
-"mflo r<RD>":AC == 0
-"mflo r<RD>, ac<AC>"
-*mips32:
-*mips32r2:
-*mips64:
-*mips64r2:
-*dsp:
-{
-  if (AC == 0)
-    do_mflo (SD_, RD);
-  else
-    GPR[RD] = DSPLO(AC);
-}
-
-000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHIdsp
-"mthi r<RS>":AC == 0
-"mthi r<RS>, ac<AC>"
-*mips32:
-*mips32r2:
-*mips64:
-*mips64r2:
-*dsp:
-{
-  if (AC == 0)
-    check_mt_hilo (SD_, HIHISTORY);
-  DSPHI(AC) = GPR[RS];
-}
-
-000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLOdsp
-"mtlo r<RS>":AC == 0
-"mtlo r<RS>, ac<AC>"
-*mips32:
-*mips32r2:
-*mips64:
-*mips64r2:
-*dsp:
-{
-  if (AC == 0)
-    check_mt_hilo (SD_, LOHISTORY);
-  DSPLO(AC) = GPR[RS];
-}
-
 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
 "wrdsp r<RS>":MASK10 == 1111111111
 "wrdsp r<RS>, <MASK10>"