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