Fix TCL error in gdb.python/py-format-string.exp.
[deliverable/binutils-gdb.git] / sim / frv / frv.c
index 2640b1c29c692c47daea0aeceb1e5f96349838c4..fb683852d0338fa85adef4a0f453c3e557232ba4 100644 (file)
@@ -1,23 +1,21 @@
 /* frv simulator support code
-   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software
-   Foundation, Inc.
+   Copyright (C) 1998-2020 Free Software Foundation, Inc.
    Contributed by Red Hat.
 
 This file is part of the GNU simulators.
 
 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/>.  */
 
 #define WANT_CPU
 #define WANT_CPU_FRVBF
@@ -173,7 +171,15 @@ check_register_alignment (SIM_CPU *current_cpu, UINT reg, int align_mask)
       SIM_DESC sd = CPU_STATE (current_cpu);
       switch (STATE_ARCHITECTURE (sd)->mach)
        {
+         /* Note: there is a discrepancy between V2.2 of the FR400 
+            instruction manual and the various FR4xx LSI specs.
+            The former claims that unaligned registers cause a
+            register_exception while the latter say it's an
+            illegal_instruction.  The LSI specs appear to be
+            correct; in fact, the FR4xx series is not documented
+            as having a register_exception.  */
        case bfd_mach_fr400:
+       case bfd_mach_fr450:
        case bfd_mach_fr550:
          frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
          break;
@@ -201,7 +207,9 @@ check_fr_register_alignment (SIM_CPU *current_cpu, UINT reg, int align_mask)
       SIM_DESC sd = CPU_STATE (current_cpu);
       switch (STATE_ARCHITECTURE (sd)->mach)
        {
+         /* See comment in check_register_alignment().  */
        case bfd_mach_fr400:
+       case bfd_mach_fr450:
        case bfd_mach_fr550:
          frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
          break;
@@ -233,7 +241,9 @@ check_memory_alignment (SIM_CPU *current_cpu, SI address, int align_mask)
       SIM_DESC sd = CPU_STATE (current_cpu);
       switch (STATE_ARCHITECTURE (sd)->mach)
        {
+         /* See comment in check_register_alignment().  */
        case bfd_mach_fr400:
+       case bfd_mach_fr450:
          frv_queue_data_access_error_interrupt (current_cpu, address);
          break;
        case bfd_mach_frvtomcat:
@@ -293,7 +303,7 @@ frvbf_h_fr_double_get_handler (SIM_CPU *current_cpu, UINT fr)
   /* Check the register alignment.  */
   fr = check_fr_register_alignment (current_cpu, fr, 1);
 
-  if (CURRENT_HOST_BYTE_ORDER == LITTLE_ENDIAN)
+  if (HOST_BYTE_ORDER == BFD_ENDIAN_LITTLE)
     {
       value.as_sf[1] = GET_H_FR (fr);
       value.as_sf[0] = GET_H_FR (fr + 1);
@@ -319,7 +329,7 @@ frvbf_h_fr_double_set_handler (SIM_CPU *current_cpu, UINT fr, DF newval)
   fr = check_fr_register_alignment (current_cpu, fr, 1);
 
   value.as_df = newval;
-  if (CURRENT_HOST_BYTE_ORDER == LITTLE_ENDIAN)
+  if (HOST_BYTE_ORDER == BFD_ENDIAN_LITTLE)
     {
       SET_H_FR (fr    , value.as_sf[1]);
       SET_H_FR (fr + 1, value.as_sf[0]);
@@ -990,10 +1000,11 @@ void
 frvbf_clear_accumulators (SIM_CPU *current_cpu, SI acc_ix, int A)
 {
   SIM_DESC sd = CPU_STATE (current_cpu);
-  int acc_num = 
-    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr500) ? 8 :
-    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) ? 8 :
-    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400) ? 4 :
+  int acc_mask =
+    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr500) ? 7 :
+    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) ? 7 :
+    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) ? 11 :
+    (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400) ? 3 :
     63;
   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
 
@@ -1003,15 +1014,16 @@ frvbf_clear_accumulators (SIM_CPU *current_cpu, SI acc_ix, int A)
     {
       /* This instruction is a nop if the referenced accumulator is not
         implemented. */
-      if (acc_ix < acc_num)
+      if ((acc_ix & acc_mask) == acc_ix)
        sim_queue_fn_di_write (current_cpu, frvbf_h_acc40S_set, acc_ix, 0);
     }
   else
     {
       /* Clear all implemented accumulators.  */
       int i;
-      for (i = 0; i < acc_num; ++i)
-       sim_queue_fn_di_write (current_cpu, frvbf_h_acc40S_set, i, 0);
+      for (i = 0; i <= acc_mask; ++i)
+       if ((i & acc_mask) == i)
+         sim_queue_fn_di_write (current_cpu, frvbf_h_acc40S_set, i, 0);
     }
 }
 \f
@@ -1042,6 +1054,7 @@ SI
 frvbf_cut (SIM_CPU *current_cpu, SI reg1, SI reg2, SI cut_point)
 {
   SI result;
+  cut_point &= 0x3f;
   if (cut_point < 32)
     {
       result = reg1 << cut_point;
@@ -1208,12 +1221,14 @@ do_media_average (SIM_CPU *current_cpu, HI arg1, HI arg2)
   HI result = sum >> 1;
   int rounding_value;
 
-  /* On fr400 and fr550, check the rounding mode.  On other machines rounding is always
-     toward negative infinity and the result is already correctly rounded.  */
+  /* On fr4xx and fr550, check the rounding mode.  On other machines
+     rounding is always toward negative infinity and the result is
+     already correctly rounded.  */
   switch (STATE_ARCHITECTURE (sd)->mach)
     {
       /* Need to check rounding mode. */
     case bfd_mach_fr400:
+    case bfd_mach_fr450:
     case bfd_mach_fr550:
       /* Check whether rounding will be required.  Rounding will be required
         if the sum is an odd number.  */
This page took 0.026398 seconds and 4 git commands to generate.