1/* Memory ops header for CGEN-based simulators.
2   Copyright (C) 1996, 1997, 1998, 1999, 2007, 2008, 2009, 2010, 2011
3   Free Software Foundation, Inc.
4   Contributed by Cygnus Solutions.
5
6This file is part of the GNU Simulators.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21#ifndef CGEN_MEM_H
22#define CGEN_MEM_H
23
24#ifdef MEMOPS_DEFINE_INLINE
25#define MEMOPS_INLINE
26#else
27#define MEMOPS_INLINE extern inline
28#endif
29
30/* Integer memory read support.
31
32   There is no floating point support.  In this context there are no
33   floating point modes, only floating point operations (whose arguments
34   and results are arrays of bits that we treat as integer modes).  */
35
36#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
37#define DECLARE_GETMEM(mode, size) \
38MEMOPS_INLINE mode \
39XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
40{ \
41  PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
42  /* Don't read anything into "unaligned" here.  Bad name choice.  */\
43  return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
44}
45#else
46#define DECLARE_GETMEM(mode, size) \
47extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
48#endif
49
50DECLARE_GETMEM (QI, 1)  /* TAGS: GETMEMQI */
51DECLARE_GETMEM (UQI, 1) /* TAGS: GETMEMUQI */
52DECLARE_GETMEM (HI, 2)  /* TAGS: GETMEMHI */
53DECLARE_GETMEM (UHI, 2) /* TAGS: GETMEMUHI */
54DECLARE_GETMEM (SI, 4)  /* TAGS: GETMEMSI */
55DECLARE_GETMEM (USI, 4) /* TAGS: GETMEMUSI */
56DECLARE_GETMEM (DI, 8)  /* TAGS: GETMEMDI */
57DECLARE_GETMEM (UDI, 8) /* TAGS: GETMEMUDI */
58
59#undef DECLARE_GETMEM
60
61/* Integer memory write support.  */
62
63#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
64#define DECLARE_SETMEM(mode, size) \
65MEMOPS_INLINE void \
66XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
67{ \
68  PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
69  /* Don't read anything into "unaligned" here.  Bad name choice.  */ \
70  XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
71}
72#else
73#define DECLARE_SETMEM(mode, size) \
74extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
75#endif
76
77DECLARE_SETMEM (QI, 1)  /* TAGS: SETMEMQI */
78DECLARE_SETMEM (UQI, 1) /* TAGS: SETMEMUQI */
79DECLARE_SETMEM (HI, 2)  /* TAGS: SETMEMHI */
80DECLARE_SETMEM (UHI, 2) /* TAGS: SETMEMUHI */
81DECLARE_SETMEM (SI, 4)  /* TAGS: SETMEMSI */
82DECLARE_SETMEM (USI, 4) /* TAGS: SETMEMUSI */
83DECLARE_SETMEM (DI, 8)  /* TAGS: SETMEMDI */
84DECLARE_SETMEM (UDI, 8) /* TAGS: SETMEMUDI */
85
86#undef DECLARE_SETMEM
87
88/* Instruction read support.  */
89
90#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
91#define DECLARE_GETIMEM(mode, size) \
92MEMOPS_INLINE mode \
93XCONCAT2 (GETIMEM,mode) (SIM_CPU *cpu, IADDR a) \
94{ \
95  /*PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode));*/ \
96  /* Don't read anything into "unaligned" here.  Bad name choice.  */\
97  return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, a, exec_map, a); \
98}
99#else
100#define DECLARE_GETIMEM(mode, size) \
101extern mode XCONCAT2 (GETIMEM,mode) (SIM_CPU *, ADDR);
102#endif
103
104DECLARE_GETIMEM (UQI, 1) /* TAGS: GETIMEMUQI */
105DECLARE_GETIMEM (UHI, 2) /* TAGS: GETIMEMUHI */
106DECLARE_GETIMEM (USI, 4) /* TAGS: GETIMEMUSI */
107DECLARE_GETIMEM (UDI, 8) /* TAGS: GETIMEMUDI */
108
109#undef DECLARE_GETIMEM
110
111/* Floating point support.
112
113   ??? One can specify that the integer memory ops should be used instead,
114   and treat fp values as just a series of bits.  One might even bubble
115   that notion up into the description language.  However, that departs from
116   gcc.  One could cross over from gcc's notion and a "series of bits" notion
117   between there and here, and thus still not require these routines.  However,
118   that's a complication of its own (not that having these fns isn't).
119   But for now, we do things this way.  */
120
121#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
122#define DECLARE_GETMEM(mode, size) \
123MEMOPS_INLINE mode \
124XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
125{ \
126  PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
127  /* Don't read anything into "unaligned" here.  Bad name choice.  */\
128  return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
129}
130#else
131#define DECLARE_GETMEM(mode, size) \
132extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
133#endif
134
135DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */
136DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */
137
138#undef DECLARE_GETMEM
139
140#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
141#define DECLARE_SETMEM(mode, size) \
142MEMOPS_INLINE void \
143XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
144{ \
145  PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
146  /* Don't read anything into "unaligned" here.  Bad name choice.  */ \
147  XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
148}
149#else
150#define DECLARE_SETMEM(mode, size) \
151extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
152#endif
153
154DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */
155DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */
156
157#undef DECLARE_SETMEM
158
159/* GETT<mode>: translate target value at P to host value.
160   This needn't be very efficient (i.e. can call memcpy) as this is
161   only used when interfacing with the outside world (e.g. gdb).  */
162
163#if defined (MEMOPS_DEFINE_INLINE)
164#define DECLARE_GETT(mode, size) \
165mode \
166XCONCAT2 (GETT,mode) (unsigned char *p) \
167{ \
168  mode tmp; \
169  memcpy (&tmp, p, sizeof (mode)); \
170  return XCONCAT2 (T2H_,size) (tmp); \
171}
172#else
173#define DECLARE_GETT(mode, size) \
174extern mode XCONCAT2 (GETT,mode) (unsigned char *);
175#endif
176
177DECLARE_GETT (QI, 1)  /* TAGS: GETTQI */
178DECLARE_GETT (UQI, 1) /* TAGS: GETTUQI */
179DECLARE_GETT (HI, 2)  /* TAGS: GETTHI */
180DECLARE_GETT (UHI, 2) /* TAGS: GETTUHI */
181DECLARE_GETT (SI, 4)  /* TAGS: GETTSI */
182DECLARE_GETT (USI, 4) /* TAGS: GETTUSI */
183DECLARE_GETT (DI, 8)  /* TAGS: GETTDI */
184DECLARE_GETT (UDI, 8) /* TAGS: GETTUDI */
185
186#if 0 /* ??? defered until necessary */
187DECLARE_GETT (SF, 4)  /* TAGS: GETTSF */
188DECLARE_GETT (DF, 8)  /* TAGS: GETTDF */
189DECLARE_GETT (TF, 16) /* TAGS: GETTTF */
190#endif
191
192#undef DECLARE_GETT
193
194/* SETT<mode>: translate host value to target value and store at P.
195   This needn't be very efficient (i.e. can call memcpy) as this is
196   only used when interfacing with the outside world (e.g. gdb).  */
197
198#if defined (MEMOPS_DEFINE_INLINE)
199#define DECLARE_SETT(mode, size) \
200void \
201XCONCAT2 (SETT,mode) (unsigned char *buf, mode val) \
202{ \
203  mode tmp; \
204  tmp = XCONCAT2 (H2T_,size) (val); \
205  memcpy (buf, &tmp, sizeof (mode)); \
206}
207#else
208#define DECLARE_SETT(mode, size) \
209extern mode XCONCAT2 (SETT,mode) (unsigned char *, mode);
210#endif
211
212DECLARE_SETT (QI, 1)  /* TAGS: SETTQI */
213DECLARE_SETT (UQI, 1) /* TAGS: SETTUQI */
214DECLARE_SETT (HI, 2)  /* TAGS: SETTHI */
215DECLARE_SETT (UHI, 2) /* TAGS: SETTUHI */
216DECLARE_SETT (SI, 4)  /* TAGS: SETTSI */
217DECLARE_SETT (USI, 4) /* TAGS: SETTUSI */
218DECLARE_SETT (DI, 8)  /* TAGS: SETTDI */
219DECLARE_SETT (UDI, 8) /* TAGS: SETTUDI */
220
221#if 0 /* ??? defered until necessary */
222DECLARE_SETT (SF, 4)  /* TAGS: SETTSF */
223DECLARE_SETT (DF, 8)  /* TAGS: SETTDF */
224DECLARE_SETT (TF, 16) /* TAGS: SETTTF */
225#endif
226
227#undef DECLARE_SETT
228
229#endif /* CGEN_MEM_H */
230