1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996, 1997 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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #define MEMOPS_DEFINE_INLINE
30 #define SEMOPS_DEFINE_INLINE
33 const char *mode_names[] = {
51 /* Initialize cgen things.
52 This is called after sim_post_argv_init. */
55 cgen_init (SIM_DESC sd)
60 /* If no profiling or tracing has been enabled, run in fast mode. */
61 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
63 sim_cpu *cpu = STATE_CPU (sd, c);
65 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
66 if (CPU_PROFILE_FLAGS (cpu) [i])
71 for (i = 0; i < MAX_TRACE_VALUES; ++i)
72 if (CPU_TRACE_FLAGS (cpu) [i])
80 STATE_RUN_FAST_P (sd) = run_fast_p;
84 engine_halt (cpu, reason, sigrc)
86 enum exec_state reason;
89 CPU_EXEC_STATE (cpu) = reason;
90 CPU_HALT_SIGRC (cpu) = sigrc;
92 longjmp (STATE_HALT_JMP_BUF (CPU_STATE (cpu)), 1);
96 engine_signal (cpu, sig)
98 enum sim_signal_type sig;
100 engine_halt (cpu, EXEC_STATE_STOPPED, sig);
103 /* Convert SIM_SIGFOO to SIGFOO. */
106 sim_signal_to_host (sig)
122 /* Wingdb uses this value. */
144 /* FIXME: Add "no return" attribute to illegal insn handlers.
145 They all call longjmp. */
146 /* FIXME: May wish to call a target supplied routine which can then call
147 sim_halt if it wants: to allow target to gain control for moment. */
150 ex_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
152 abuf->length = CGEN_BASE_INSN_SIZE;
154 /* Leave signalling to semantic fn. */
158 exc_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
160 abuf->length = CGEN_BASE_INSN_SIZE;
162 /* Leave signalling to semantic fn. */
166 sem_illegal (current_cpu, sem_arg)
167 SIM_CPU *current_cpu;
168 struct argbuf *sem_arg;
170 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
175 semc_illegal (current_cpu, sem_arg)
176 SIM_CPU *current_cpu;
177 struct scache *sem_arg;
179 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
183 /* Disassembly support.
184 ??? While executing an instruction, the insn has been decoded and all its
185 fields have been extracted. It is certainly possible to do the disassembly
186 with that data. This seems simpler, but maybe in the future the already
187 extracted fields will be used. */
189 /* Pseudo FILE object for strings. */
195 /* sprintf to a "stream" */
198 disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
207 VA_START (args, format);
209 f = va_arg (args, SFILE *);
210 format = va_arg (args, char *);
212 vsprintf (f->current, format, args);
213 f->current += n = strlen (f->current);
219 sim_disassemble_insn (SIM_CPU *cpu, const struct cgen_insn *insn,
220 const struct argbuf *abuf, PCADDR pc, char *buf)
223 unsigned long insn_value;
224 struct disassemble_info disasm_info;
225 struct cgen_fields fields;
228 SIM_DESC sd = CPU_STATE (cpu);
230 sfile.buffer = sfile.current = buf;
231 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
232 (fprintf_ftype) disasm_sprintf);
234 (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
235 : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
236 : BFD_ENDIAN_UNKNOWN);
238 switch (abuf->length)
241 insn_value = sim_core_read_1 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
244 insn_value = sim_core_read_2 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
247 insn_value = sim_core_read_4 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
253 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
254 if (length != abuf->length)
256 (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length);
260 /* This shouldn't happen, but aborting is too drastic. */
261 strcpy (buf, "***unknown***");
268 make_struct_di (hi, lo)
282 SI ahi = GETHIDI (a);
283 SI alo = GETLODI (a);
284 SI bhi = GETHIDI (b);
285 SI blo = GETLODI (b);
286 return MAKEDI (ahi & bhi, alo & blo);
293 SI ahi = GETHIDI (a);
294 SI alo = GETLODI (a);
295 SI bhi = GETHIDI (b);
296 SI blo = GETLODI (b);
297 return MAKEDI (ahi | bhi, alo | blo);
304 USI ahi = GETHIDI (a);
305 USI alo = GETLODI (a);
306 USI bhi = GETHIDI (b);
307 USI blo = GETLODI (b);
309 return MAKEDI (ahi + bhi + (x < alo), x);
316 USI ahi = GETHIDI (a);
317 USI alo = GETLODI (a);
318 USI bhi = GETHIDI (b);
319 USI blo = GETLODI (b);
328 #define SI_TYPE_SIZE 32
329 #define BITS4 (SI_TYPE_SIZE / 4)
330 #define ll_B (1L << (SI_TYPE_SIZE / 2))
331 #define ll_lowpart(t) ((USI) (t) % ll_B)
332 #define ll_highpart(t) ((USI) (t) / ll_B)
333 x1 += ll_highpart (x0); /* this can't give carry */
334 x1 += x2; /* but this indeed can */
335 if (x1 < x2) /* did we get it? */
336 x3 += ll_B; /* yes, add it in the proper pos. */
338 rhi = x3 + ll_highpart (x1);
339 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
340 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
348 USI hi = GETHIDI (val);
349 USI lo = GETLODI (val);
350 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
351 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
359 SI hi = GETHIDI (val);
360 USI lo = GETLODI (val);
361 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
362 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
370 SI hi = GETHIDI (val);
371 USI lo = GETLODI (val);
372 /* We use SRASI because the result is implementation defined if hi < 0. */
373 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
374 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
381 SI ahi = GETHIDI (a);
382 USI alo = GETLODI (a);
383 SI bhi = GETHIDI (b);
384 USI blo = GETLODI (b);
396 SI ahi = GETHIDI (a);
397 USI alo = GETLODI (a);
398 SI bhi = GETHIDI (b);
399 USI blo = GETLODI (b);
412 return MAKEDI (-1, val);
414 return MAKEDI (0, val);
422 return MAKEDI (-1, val);
424 return MAKEDI (0, val);
431 return GETLODI (val);
434 #endif /* DI_FN_SUPPORT */