Home | History | Annotate | Line # | Download | only in common
      1       1.1  christos /* Memory ops header for CGEN-based simulators.
      2  1.1.1.11  christos    Copyright (C) 1996-2024 Free Software Foundation, Inc.
      3       1.1  christos    Contributed by Cygnus Solutions.
      4       1.1  christos 
      5       1.1  christos This file is part of the GNU Simulators.
      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 #ifndef CGEN_MEM_H
     21       1.1  christos #define CGEN_MEM_H
     22       1.1  christos 
     23  1.1.1.11  christos #include "symcat.h"
     24  1.1.1.11  christos 
     25   1.1.1.5  christos /* TODO: This should get moved into sim-inline.h.  */
     26       1.1  christos #ifdef MEMOPS_DEFINE_INLINE
     27       1.1  christos #define MEMOPS_INLINE
     28       1.1  christos #else
     29   1.1.1.5  christos #define MEMOPS_INLINE EXTERN_INLINE
     30       1.1  christos #endif
     31       1.1  christos 
     32       1.1  christos /* Integer memory read support.
     33       1.1  christos 
     34       1.1  christos    There is no floating point support.  In this context there are no
     35       1.1  christos    floating point modes, only floating point operations (whose arguments
     36       1.1  christos    and results are arrays of bits that we treat as integer modes).  */
     37       1.1  christos 
     38  1.1.1.10  christos #define DECLARE_GETMEM_EXTERN(mode, size) \
     39  1.1.1.10  christos extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
     40  1.1.1.10  christos 
     41       1.1  christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
     42       1.1  christos #define DECLARE_GETMEM(mode, size) \
     43  1.1.1.10  christos DECLARE_GETMEM_EXTERN (mode, size) \
     44       1.1  christos MEMOPS_INLINE mode \
     45       1.1  christos XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
     46       1.1  christos { \
     47       1.1  christos   PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
     48       1.1  christos   /* Don't read anything into "unaligned" here.  Bad name choice.  */\
     49       1.1  christos   return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
     50       1.1  christos }
     51       1.1  christos #else
     52  1.1.1.10  christos #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size)
     53       1.1  christos #endif
     54       1.1  christos 
     55       1.1  christos DECLARE_GETMEM (QI, 1)  /* TAGS: GETMEMQI */
     56       1.1  christos DECLARE_GETMEM (UQI, 1) /* TAGS: GETMEMUQI */
     57       1.1  christos DECLARE_GETMEM (HI, 2)  /* TAGS: GETMEMHI */
     58       1.1  christos DECLARE_GETMEM (UHI, 2) /* TAGS: GETMEMUHI */
     59       1.1  christos DECLARE_GETMEM (SI, 4)  /* TAGS: GETMEMSI */
     60       1.1  christos DECLARE_GETMEM (USI, 4) /* TAGS: GETMEMUSI */
     61       1.1  christos DECLARE_GETMEM (DI, 8)  /* TAGS: GETMEMDI */
     62       1.1  christos DECLARE_GETMEM (UDI, 8) /* TAGS: GETMEMUDI */
     63       1.1  christos 
     64       1.1  christos #undef DECLARE_GETMEM
     65  1.1.1.10  christos #undef DECLARE_GETMEM_EXTERN
     66       1.1  christos 
     67       1.1  christos /* Integer memory write support.  */
     69  1.1.1.10  christos 
     70  1.1.1.10  christos #define DECLARE_SETMEM_EXTERN(mode, size) \
     71  1.1.1.10  christos extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
     72       1.1  christos 
     73       1.1  christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
     74  1.1.1.10  christos #define DECLARE_SETMEM(mode, size) \
     75       1.1  christos DECLARE_SETMEM_EXTERN (mode, size) \
     76       1.1  christos MEMOPS_INLINE void \
     77       1.1  christos XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
     78       1.1  christos { \
     79       1.1  christos   PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
     80       1.1  christos   /* Don't read anything into "unaligned" here.  Bad name choice.  */ \
     81       1.1  christos   XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
     82       1.1  christos }
     83  1.1.1.10  christos #else
     84       1.1  christos #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size)
     85       1.1  christos #endif
     86       1.1  christos 
     87       1.1  christos DECLARE_SETMEM (QI, 1)  /* TAGS: SETMEMQI */
     88       1.1  christos DECLARE_SETMEM (UQI, 1) /* TAGS: SETMEMUQI */
     89       1.1  christos DECLARE_SETMEM (HI, 2)  /* TAGS: SETMEMHI */
     90       1.1  christos DECLARE_SETMEM (UHI, 2) /* TAGS: SETMEMUHI */
     91       1.1  christos DECLARE_SETMEM (SI, 4)  /* TAGS: SETMEMSI */
     92       1.1  christos DECLARE_SETMEM (USI, 4) /* TAGS: SETMEMUSI */
     93       1.1  christos DECLARE_SETMEM (DI, 8)  /* TAGS: SETMEMDI */
     94       1.1  christos DECLARE_SETMEM (UDI, 8) /* TAGS: SETMEMUDI */
     95       1.1  christos 
     96  1.1.1.10  christos #undef DECLARE_SETMEM
     97       1.1  christos #undef DECLARE_SETMEM_EXTERN
     98       1.1  christos 
     99       1.1  christos /* Instruction read support.  */
    101  1.1.1.10  christos 
    102  1.1.1.10  christos #define DECLARE_GETIMEM_EXTERN(mode, size) \
    103       1.1  christos extern mode XCONCAT2 (GETIMEM,mode) (SIM_CPU *, ADDR);
    104       1.1  christos 
    105  1.1.1.10  christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
    106       1.1  christos #define DECLARE_GETIMEM(mode, size) \
    107       1.1  christos DECLARE_GETIMEM_EXTERN (mode, size) \
    108       1.1  christos MEMOPS_INLINE mode \
    109       1.1  christos XCONCAT2 (GETIMEM,mode) (SIM_CPU *cpu, IADDR a) \
    110       1.1  christos { \
    111       1.1  christos   /*PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode));*/ \
    112       1.1  christos   /* Don't read anything into "unaligned" here.  Bad name choice.  */\
    113       1.1  christos   return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, a, exec_map, a); \
    114  1.1.1.10  christos }
    115       1.1  christos #else
    116       1.1  christos #define DECLARE_GETIMEM(mode, size) DECLARE_GETIMEM_EXTERN (mode, size)
    117       1.1  christos #endif
    118       1.1  christos 
    119       1.1  christos DECLARE_GETIMEM (UQI, 1) /* TAGS: GETIMEMUQI */
    120       1.1  christos DECLARE_GETIMEM (UHI, 2) /* TAGS: GETIMEMUHI */
    121       1.1  christos DECLARE_GETIMEM (USI, 4) /* TAGS: GETIMEMUSI */
    122       1.1  christos DECLARE_GETIMEM (UDI, 8) /* TAGS: GETIMEMUDI */
    123  1.1.1.10  christos 
    124       1.1  christos #undef DECLARE_GETIMEM
    125       1.1  christos #undef DECLARE_GETIMEM_EXTERN
    126       1.1  christos 
    127       1.1  christos /* Floating point support.
    129       1.1  christos 
    130       1.1  christos    ??? One can specify that the integer memory ops should be used instead,
    131       1.1  christos    and treat fp values as just a series of bits.  One might even bubble
    132       1.1  christos    that notion up into the description language.  However, that departs from
    133       1.1  christos    gcc.  One could cross over from gcc's notion and a "series of bits" notion
    134       1.1  christos    between there and here, and thus still not require these routines.  However,
    135  1.1.1.10  christos    that's a complication of its own (not that having these fns isn't).
    136  1.1.1.10  christos    But for now, we do things this way.  */
    137  1.1.1.10  christos 
    138       1.1  christos #define DECLARE_GETMEM_EXTERN(mode, size) \
    139       1.1  christos extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
    140  1.1.1.10  christos 
    141       1.1  christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
    142       1.1  christos #define DECLARE_GETMEM(mode, size) \
    143       1.1  christos DECLARE_GETMEM_EXTERN (mode, size) \
    144       1.1  christos MEMOPS_INLINE mode \
    145       1.1  christos XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
    146       1.1  christos { \
    147       1.1  christos   PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
    148       1.1  christos   /* Don't read anything into "unaligned" here.  Bad name choice.  */\
    149  1.1.1.10  christos   return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
    150       1.1  christos }
    151       1.1  christos #else
    152       1.1  christos #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size)
    153       1.1  christos #endif
    154       1.1  christos 
    155       1.1  christos DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */
    156  1.1.1.10  christos DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */
    157  1.1.1.10  christos 
    158  1.1.1.10  christos #undef DECLARE_GETMEM
    159  1.1.1.10  christos #undef DECLARE_GETMEM_EXTERN
    160       1.1  christos 
    161       1.1  christos #define DECLARE_SETMEM_EXTERN(mode, size) \
    162       1.1  christos extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
    163  1.1.1.10  christos 
    164       1.1  christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
    165       1.1  christos #define DECLARE_SETMEM(mode, size) \
    166       1.1  christos DECLARE_SETMEM_EXTERN (mode, size) \
    167       1.1  christos MEMOPS_INLINE void \
    168       1.1  christos XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
    169       1.1  christos { \
    170       1.1  christos   PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
    171       1.1  christos   /* Don't read anything into "unaligned" here.  Bad name choice.  */ \
    172  1.1.1.10  christos   XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
    173       1.1  christos }
    174       1.1  christos #else
    175       1.1  christos #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size
    176       1.1  christos #endif
    177       1.1  christos 
    178       1.1  christos DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */
    179  1.1.1.10  christos DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */
    180       1.1  christos 
    181       1.1  christos #undef DECLARE_SETMEM
    182       1.1  christos #undef DECLARE_SETMEM_EXTERN
    183       1.1  christos 
    184       1.1  christos /* GETT<mode>: translate target value at P to host value.
    186  1.1.1.10  christos    This needn't be very efficient (i.e. can call memcpy) as this is
    187  1.1.1.10  christos    only used when interfacing with the outside world (e.g. gdb).  */
    188       1.1  christos 
    189       1.1  christos #define DECLARE_GETT_EXTERN(mode, size) \
    190  1.1.1.10  christos extern mode XCONCAT2 (GETT,mode) (const unsigned char *);
    191       1.1  christos 
    192  1.1.1.10  christos #if defined (MEMOPS_DEFINE_INLINE)
    193       1.1  christos #define DECLARE_GETT(mode, size) \
    194       1.1  christos DECLARE_GETT_EXTERN (mode, size) \
    195       1.1  christos mode \
    196       1.1  christos XCONCAT2 (GETT,mode) (const unsigned char *p) \
    197       1.1  christos { \
    198       1.1  christos   mode tmp; \
    199  1.1.1.10  christos   memcpy (&tmp, p, sizeof (mode)); \
    200       1.1  christos   return XCONCAT2 (T2H_,size) (tmp); \
    201       1.1  christos }
    202       1.1  christos #else
    203       1.1  christos #define DECLARE_GETT(mode, size) DECLARE_GETT_EXTERN (mode, size)
    204       1.1  christos #endif
    205       1.1  christos 
    206       1.1  christos DECLARE_GETT (QI, 1)  /* TAGS: GETTQI */
    207       1.1  christos DECLARE_GETT (UQI, 1) /* TAGS: GETTUQI */
    208       1.1  christos DECLARE_GETT (HI, 2)  /* TAGS: GETTHI */
    209       1.1  christos DECLARE_GETT (UHI, 2) /* TAGS: GETTUHI */
    210       1.1  christos DECLARE_GETT (SI, 4)  /* TAGS: GETTSI */
    211       1.1  christos DECLARE_GETT (USI, 4) /* TAGS: GETTUSI */
    212       1.1  christos DECLARE_GETT (DI, 8)  /* TAGS: GETTDI */
    213       1.1  christos DECLARE_GETT (UDI, 8) /* TAGS: GETTUDI */
    214       1.1  christos 
    215       1.1  christos #if 0 /* ??? defered until necessary */
    216       1.1  christos DECLARE_GETT (SF, 4)  /* TAGS: GETTSF */
    217       1.1  christos DECLARE_GETT (DF, 8)  /* TAGS: GETTDF */
    218  1.1.1.10  christos DECLARE_GETT (TF, 16) /* TAGS: GETTTF */
    219       1.1  christos #endif
    220       1.1  christos 
    221       1.1  christos #undef DECLARE_GETT
    222       1.1  christos #undef DECLARE_GETT_EXTERN
    223       1.1  christos 
    224  1.1.1.10  christos /* SETT<mode>: translate host value to target value and store at P.
    226  1.1.1.10  christos    This needn't be very efficient (i.e. can call memcpy) as this is
    227       1.1  christos    only used when interfacing with the outside world (e.g. gdb).  */
    228       1.1  christos 
    229  1.1.1.10  christos #define DECLARE_SETT_EXTERN(mode, size) \
    230       1.1  christos extern void XCONCAT2 (SETT,mode) (unsigned char *, mode);
    231       1.1  christos 
    232       1.1  christos #if defined (MEMOPS_DEFINE_INLINE)
    233       1.1  christos #define DECLARE_SETT(mode, size) \
    234       1.1  christos DECLARE_SETT_EXTERN (mode, size) \
    235       1.1  christos void \
    236       1.1  christos XCONCAT2 (SETT,mode) (unsigned char *buf, mode val) \
    237       1.1  christos { \
    238  1.1.1.10  christos   mode tmp; \
    239       1.1  christos   tmp = XCONCAT2 (H2T_,size) (val); \
    240       1.1  christos   memcpy (buf, &tmp, sizeof (mode)); \
    241       1.1  christos }
    242       1.1  christos #else
    243       1.1  christos #define DECLARE_SETT(mode, size) DECLARE_SETT_EXTERN (mode, size)
    244       1.1  christos #endif
    245       1.1  christos 
    246       1.1  christos DECLARE_SETT (QI, 1)  /* TAGS: SETTQI */
    247       1.1  christos DECLARE_SETT (UQI, 1) /* TAGS: SETTUQI */
    248       1.1  christos DECLARE_SETT (HI, 2)  /* TAGS: SETTHI */
    249       1.1  christos DECLARE_SETT (UHI, 2) /* TAGS: SETTUHI */
    250       1.1  christos DECLARE_SETT (SI, 4)  /* TAGS: SETTSI */
    251       1.1  christos DECLARE_SETT (USI, 4) /* TAGS: SETTUSI */
    252       1.1  christos DECLARE_SETT (DI, 8)  /* TAGS: SETTDI */
    253       1.1  christos DECLARE_SETT (UDI, 8) /* TAGS: SETTUDI */
    254       1.1  christos 
    255       1.1  christos #if 0 /* ??? defered until necessary */
    256       1.1  christos DECLARE_SETT (SF, 4)  /* TAGS: SETTSF */
    257  1.1.1.10  christos DECLARE_SETT (DF, 8)  /* TAGS: SETTDF */
    258       1.1  christos DECLARE_SETT (TF, 16) /* TAGS: SETTTF */
    259       1.1  christos #endif
    260                     
    261                     #undef DECLARE_SETT
    262                     #undef DECLARE_SETT_EXTERN
    263                     
    264                     #endif /* CGEN_MEM_H */
    265