1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996-2015 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #define MEMOPS_DEFINE_INLINE
28 #define SEMOPS_DEFINE_INLINE
32 #define min(a,b) ((a) < (b) ? (a) : (b))
34 const char *mode_names[] = {
49 0, /* MODE_TARGET_MAX */
55 /* Opcode table for virtual insns used by the simulator. */
57 #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
59 static const CGEN_IBASE virtual_insn_entries[] =
62 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, { 0 } }
65 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, { 0 } }
68 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, { 0 } }
71 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, { 0 } }
74 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, { 0 } }
77 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, { 0 } }
83 const CGEN_INSN cgen_virtual_insn_table[] =
85 { & virtual_insn_entries[0] },
86 { & virtual_insn_entries[1] },
87 { & virtual_insn_entries[2] },
88 { & virtual_insn_entries[3] },
89 { & virtual_insn_entries[4] },
90 { & virtual_insn_entries[5] }
93 /* Initialize cgen things.
94 This is called after sim_post_argv_init. */
97 cgen_init (SIM_DESC sd)
101 /* If no profiling or tracing has been enabled, run in fast mode. */
105 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
107 SIM_CPU *cpu = STATE_CPU (sd, c);
109 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
110 if (CPU_PROFILE_FLAGS (cpu) [i])
115 for (i = 0; i < MAX_TRACE_VALUES; ++i)
116 if (CPU_TRACE_FLAGS (cpu) [i])
124 STATE_RUN_FAST_P (sd) = run_fast_p;
128 /* Return the name of insn number I. */
131 cgen_insn_name (SIM_CPU *cpu, int i)
133 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
136 /* Return the maximum number of extra bytes required for a SIM_CPU struct. */
139 cgen_cpu_max_extra_bytes (void)
144 for (i = 0; sim_machs[i] != 0; ++i)
146 int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i]));
156 make_struct_di (hi, lo)
170 SI ahi = GETHIDI (a);
171 SI alo = GETLODI (a);
172 SI bhi = GETHIDI (b);
173 SI blo = GETLODI (b);
174 return MAKEDI (ahi & bhi, alo & blo);
181 SI ahi = GETHIDI (a);
182 SI alo = GETLODI (a);
183 SI bhi = GETHIDI (b);
184 SI blo = GETLODI (b);
185 return MAKEDI (ahi | bhi, alo | blo);
192 USI ahi = GETHIDI (a);
193 USI alo = GETLODI (a);
194 USI bhi = GETHIDI (b);
195 USI blo = GETLODI (b);
197 return MAKEDI (ahi + bhi + (x < alo), x);
204 USI ahi = GETHIDI (a);
205 USI alo = GETLODI (a);
206 USI bhi = GETHIDI (b);
207 USI blo = GETLODI (b);
216 #define SI_TYPE_SIZE 32
217 #define BITS4 (SI_TYPE_SIZE / 4)
218 #define ll_B (1L << (SI_TYPE_SIZE / 2))
219 #define ll_lowpart(t) ((USI) (t) % ll_B)
220 #define ll_highpart(t) ((USI) (t) / ll_B)
221 x1 += ll_highpart (x0); /* this can't give carry */
222 x1 += x2; /* but this indeed can */
223 if (x1 < x2) /* did we get it? */
224 x3 += ll_B; /* yes, add it in the proper pos. */
226 rhi = x3 + ll_highpart (x1);
227 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
228 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
236 USI hi = GETHIDI (val);
237 USI lo = GETLODI (val);
238 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
239 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
247 SI hi = GETHIDI (val);
248 USI lo = GETLODI (val);
249 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
250 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
258 SI hi = GETHIDI (val);
259 USI lo = GETLODI (val);
260 /* We use SRASI because the result is implementation defined if hi < 0. */
261 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
262 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
269 SI ahi = GETHIDI (a);
270 USI alo = GETLODI (a);
271 SI bhi = GETHIDI (b);
272 USI blo = GETLODI (b);
284 SI ahi = GETHIDI (a);
285 USI alo = GETLODI (a);
286 SI bhi = GETHIDI (b);
287 USI blo = GETLODI (b);
300 return MAKEDI (-1, val);
302 return MAKEDI (0, val);
310 return MAKEDI (-1, val);
312 return MAKEDI (0, val);
319 return GETLODI (val);
322 #endif /* DI_FN_SUPPORT */
331 int remain = 8 - shift;
332 int mask = (1 << shift) - 1;
333 QI result = (val & mask) << remain;
334 mask = (1 << remain) - 1;
335 result |= (val >> shift) & mask;
348 int remain = 8 - shift;
349 int mask = (1 << remain) - 1;
350 QI result = (val & mask) << shift;
351 mask = (1 << shift) - 1;
352 result |= (val >> remain) & mask;
365 int remain = 16 - shift;
366 int mask = (1 << shift) - 1;
367 HI result = (val & mask) << remain;
368 mask = (1 << remain) - 1;
369 result |= (val >> shift) & mask;
382 int remain = 16 - shift;
383 int mask = (1 << remain) - 1;
384 HI result = (val & mask) << shift;
385 mask = (1 << shift) - 1;
386 result |= (val >> remain) & mask;
399 int remain = 32 - shift;
400 int mask = (1 << shift) - 1;
401 SI result = (val & mask) << remain;
402 mask = (1 << remain) - 1;
403 result |= (val >> shift) & mask;
416 int remain = 32 - shift;
417 int mask = (1 << remain) - 1;
418 SI result = (val & mask) << shift;
419 mask = (1 << shift) - 1;
420 result |= (val >> remain) & mask;
427 /* Emit an error message from CGEN RTL. */
430 cgen_rtx_error (SIM_CPU *cpu, const char * msg)
432 SIM_DESC sd = CPU_STATE (cpu);
434 sim_io_printf (sd, msg);
435 sim_io_printf (sd, "\n");
437 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);