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