Home | History | Annotate | Line # | Download | only in common
cgen-utils.c revision 1.9.2.1
      1 /* Support code for various pieces of CGEN simulators.
      2    Copyright (C) 1996-2023 Free Software Foundation, Inc.
      3    Contributed by Cygnus Support.
      4 
      5 This file is part of GDB, the GNU debugger.
      6 
      7 This program is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU General Public License as published by
      9 the Free Software Foundation; either version 3 of the License, or
     10 (at your option) any later version.
     11 
     12 This program is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 /* This must come before any other includes.  */
     21 #include "defs.h"
     22 
     23 #include "bfd.h"
     24 #include "dis-asm.h"
     25 
     26 #include "sim-main.h"
     27 #include "sim-signal.h"
     28 
     29 #define MEMOPS_DEFINE_INLINE
     30 #include "cgen-mem.h"
     31 
     32 #define SEMOPS_DEFINE_INLINE
     33 #include "cgen-ops.h"
     34 
     35 const char * const cgen_mode_names[] = {
     36   "VOID",
     37   "BI",
     38   "QI",
     39   "HI",
     40   "SI",
     41   "DI",
     42   "UQI",
     43   "UHI",
     44   "USI",
     45   "UDI",
     46   "SF",
     47   "DF",
     48   "XF",
     49   "TF",
     50   0, /* MODE_TARGET_MAX */
     51   "INT",
     52   "UINT",
     53   "PTR"
     54 };
     55 
     56 /* Opcode table for virtual insns used by the simulator.  */
     57 
     58 #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
     59 
     60 static const CGEN_IBASE virtual_insn_entries[] =
     61 {
     62   {
     63     VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
     64   },
     65   {
     66     VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
     67   },
     68   {
     69     VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
     70   },
     71   {
     72     VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
     73   },
     74   {
     75     VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
     76   },
     77   {
     78     VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
     79   }
     80 };
     81 
     82 #undef V
     83 
     84 const CGEN_INSN cgen_virtual_insn_table[] =
     85 {
     86   { & virtual_insn_entries[0] },
     87   { & virtual_insn_entries[1] },
     88   { & virtual_insn_entries[2] },
     89   { & virtual_insn_entries[3] },
     90   { & virtual_insn_entries[4] },
     91   { & virtual_insn_entries[5] }
     92 };
     93 
     94 /* Return the name of insn number I.  */
     95 
     96 const char *
     97 cgen_insn_name (SIM_CPU *cpu, int i)
     98 {
     99   return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
    100 }
    101 
    102 /* Return the maximum number of extra bytes required for a SIM_CPU struct.  */
    103 
    104 int
    105 cgen_cpu_max_extra_bytes (SIM_DESC sd)
    106 {
    107   const SIM_MACH * const *machp;
    108   int extra = 0;
    109 
    110   SIM_ASSERT (STATE_MACHS (sd) != NULL);
    111 
    112   for (machp = STATE_MACHS (sd); *machp != NULL; ++machp)
    113     {
    114       int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (*machp));
    115       if (size > extra)
    116 	extra = size;
    117     }
    118   return extra;
    119 }
    120 
    121 #ifdef DI_FN_SUPPORT
    123 
    124 DI
    125 ANDDI (a, b)
    126      DI a, b;
    127 {
    128   SI ahi = GETHIDI (a);
    129   SI alo = GETLODI (a);
    130   SI bhi = GETHIDI (b);
    131   SI blo = GETLODI (b);
    132   return MAKEDI (ahi & bhi, alo & blo);
    133 }
    134 
    135 DI
    136 ORDI (a, b)
    137      DI a, b;
    138 {
    139   SI ahi = GETHIDI (a);
    140   SI alo = GETLODI (a);
    141   SI bhi = GETHIDI (b);
    142   SI blo = GETLODI (b);
    143   return MAKEDI (ahi | bhi, alo | blo);
    144 }
    145 
    146 DI
    147 ADDDI (a, b)
    148      DI a, b;
    149 {
    150   USI ahi = GETHIDI (a);
    151   USI alo = GETLODI (a);
    152   USI bhi = GETHIDI (b);
    153   USI blo = GETLODI (b);
    154   USI x = alo + blo;
    155   return MAKEDI (ahi + bhi + (x < alo), x);
    156 }
    157 
    158 DI
    159 MULDI (a, b)
    160      DI a, b;
    161 {
    162   USI ahi = GETHIDI (a);
    163   USI alo = GETLODI (a);
    164   USI bhi = GETHIDI (b);
    165   USI blo = GETLODI (b);
    166   USI rhi,rlo;
    167   USI x0, x1, x2, x3;
    168 
    169   x0 = alo * blo;
    170   x1 = alo * bhi;
    171   x2 = ahi * blo;
    172   x3 = ahi * bhi;
    173 
    174 #define SI_TYPE_SIZE 32
    175 #define BITS4 (SI_TYPE_SIZE / 4)
    176 #define ll_B (1L << (SI_TYPE_SIZE / 2))
    177 #define ll_lowpart(t) ((USI) (t) % ll_B)
    178 #define ll_highpart(t) ((USI) (t) / ll_B)
    179   x1 += ll_highpart (x0);	/* this can't give carry */
    180   x1 += x2;			/* but this indeed can */
    181   if (x1 < x2)			/* did we get it? */
    182     x3 += ll_B;			/* yes, add it in the proper pos. */
    183 
    184   rhi = x3 + ll_highpart (x1);
    185   rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
    186   return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
    187 }
    188 
    189 DI
    190 SHLDI (val, shift)
    191      DI val;
    192      SI shift;
    193 {
    194   USI hi = GETHIDI (val);
    195   USI lo = GETLODI (val);
    196   /* FIXME: Need to worry about shift < 0 || shift >= 32.  */
    197   return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
    198 }
    199 
    200 DI
    201 SLADI (val, shift)
    202      DI val;
    203      SI shift;
    204 {
    205   SI hi = GETHIDI (val);
    206   USI lo = GETLODI (val);
    207   /* FIXME: Need to worry about shift < 0 || shift >= 32.  */
    208   return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
    209 }
    210 
    211 DI
    212 SRADI (val, shift)
    213      DI val;
    214      SI shift;
    215 {
    216   SI hi = GETHIDI (val);
    217   USI lo = GETLODI (val);
    218   /* We use SRASI because the result is implementation defined if hi < 0.  */
    219   /* FIXME: Need to worry about shift < 0 || shift >= 32.  */
    220   return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
    221 }
    222 
    223 int
    224 GEDI (a, b)
    225      DI a, b;
    226 {
    227   SI ahi = GETHIDI (a);
    228   USI alo = GETLODI (a);
    229   SI bhi = GETHIDI (b);
    230   USI blo = GETLODI (b);
    231   if (ahi > bhi)
    232     return 1;
    233   if (ahi == bhi)
    234     return alo >= blo;
    235   return 0;
    236 }
    237 
    238 int
    239 LEDI (a, b)
    240      DI a, b;
    241 {
    242   SI ahi = GETHIDI (a);
    243   USI alo = GETLODI (a);
    244   SI bhi = GETHIDI (b);
    245   USI blo = GETLODI (b);
    246   if (ahi < bhi)
    247     return 1;
    248   if (ahi == bhi)
    249     return alo <= blo;
    250   return 0;
    251 }
    252 
    253 DI
    254 CONVHIDI (val)
    255      HI val;
    256 {
    257   if (val < 0)
    258     return MAKEDI (-1, val);
    259   else
    260     return MAKEDI (0, val);
    261 }
    262 
    263 DI
    264 CONVSIDI (val)
    265      SI val;
    266 {
    267   if (val < 0)
    268     return MAKEDI (-1, val);
    269   else
    270     return MAKEDI (0, val);
    271 }
    272 
    273 SI
    274 CONVDISI (val)
    275      DI val;
    276 {
    277   return GETLODI (val);
    278 }
    279 
    280 #endif /* DI_FN_SUPPORT */
    281 
    282 QI
    284 RORQI (QI val, int shift)
    285 {
    286   if (shift != 0)
    287     {
    288       int remain = 8 - shift;
    289       int mask = (1 << shift) - 1;
    290       QI result = (val & mask) << remain;
    291       mask = (1 << remain) - 1;
    292       result |= (val >> shift) & mask;
    293       return result;
    294     }
    295   return val;
    296 }
    297 
    298 QI
    299 ROLQI (QI val, int shift)
    300 {
    301   if (shift != 0)
    302     {
    303       int remain = 8 - shift;
    304       int mask = (1 << remain) - 1;
    305       QI result = (val & mask) << shift;
    306       mask = (1 << shift) - 1;
    307       result |= (val >> remain) & mask;
    308       return result;
    309     }
    310   return val;
    311 }
    312 
    313 HI
    314 RORHI (HI val, int shift)
    315 {
    316   if (shift != 0)
    317     {
    318       int remain = 16 - shift;
    319       int mask = (1 << shift) - 1;
    320       HI result = (val & mask) << remain;
    321       mask = (1 << remain) - 1;
    322       result |= (val >> shift) & mask;
    323       return result;
    324     }
    325   return val;
    326 }
    327 
    328 HI
    329 ROLHI (HI val, int shift)
    330 {
    331   if (shift != 0)
    332     {
    333       int remain = 16 - shift;
    334       int mask = (1 << remain) - 1;
    335       HI result = (val & mask) << shift;
    336       mask = (1 << shift) - 1;
    337       result |= (val >> remain) & mask;
    338       return result;
    339     }
    340   return val;
    341 }
    342 
    343 SI
    344 RORSI (SI val, int shift)
    345 {
    346   if (shift != 0)
    347     {
    348       int remain = 32 - shift;
    349       int mask = (1 << shift) - 1;
    350       SI result = (val & mask) << remain;
    351       mask = (1 << remain) - 1;
    352       result |= (val >> shift) & mask;
    353       return result;
    354     }
    355   return val;
    356 }
    357 
    358 SI
    359 ROLSI (SI val, int shift)
    360 {
    361   if (shift != 0)
    362     {
    363       int remain = 32 - shift;
    364       int mask = (1 << remain) - 1;
    365       SI result = (val & mask) << shift;
    366       mask = (1 << shift) - 1;
    367       result |= (val >> remain) & mask;
    368       return result;
    369     }
    370 
    371   return val;
    372 }
    373 
    374 /* Emit an error message from CGEN RTL.  */
    375 
    376 void
    377 cgen_rtx_error (SIM_CPU *cpu, const char * msg)
    378 {
    379   SIM_DESC sd = CPU_STATE (cpu);
    380 
    381   sim_io_printf (sd, "%s", msg);
    382   sim_io_printf (sd, "\n");
    383 
    384   sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
    385 }
    386