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