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. */
26 #define MEMOPS_DEFINE_INLINE
29 #define SEMOPS_DEFINE_INLINE
32 const char *mode_names[] = {
50 /* Initialize cgen things.
51 This is called after sim_post_argv_init. */
54 cgen_init (SIM_DESC sd)
59 /* If no profiling or tracing has been enabled, run in fast mode. */
60 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
62 sim_cpu *cpu = STATE_CPU (sd, c);
64 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
65 if (CPU_PROFILE_FLAGS (cpu) [i])
70 for (i = 0; i < MAX_TRACE_VALUES; ++i)
71 if (CPU_TRACE_FLAGS (cpu) [i])
79 STATE_RUN_FAST_P (sd) = run_fast_p;
83 engine_halt (cpu, reason, sigrc)
85 enum exec_state reason;
88 CPU_EXEC_STATE (cpu) = reason;
89 CPU_HALT_SIGRC (cpu) = sigrc;
91 longjmp (STATE_HALT_JMP_BUF (CPU_STATE (cpu)), 1);
95 engine_signal (cpu, sig)
97 enum sim_signal_type sig;
99 engine_halt (cpu, EXEC_STATE_STOPPED, sig);
102 /* Convert SIM_SIGFOO to SIGFOO. */
105 sim_signal_to_host (sig)
121 /* Wingdb uses this value. */
143 /* FIXME: Add "no return" attribute to illegal insn handlers.
144 They all call longjmp. */
145 /* FIXME: May wish to call a target supplied routine which can then call
146 sim_halt if it wants: to allow target to gain control for moment. */
149 ex_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
151 abuf->length = CGEN_BASE_INSN_SIZE;
153 /* Leave signalling to semantic fn. */
157 exc_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
159 abuf->length = CGEN_BASE_INSN_SIZE;
161 /* Leave signalling to semantic fn. */
165 sem_illegal (current_cpu, sem_arg)
166 SIM_CPU *current_cpu;
167 struct argbuf *sem_arg;
169 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
174 semc_illegal (current_cpu, sem_arg)
175 SIM_CPU *current_cpu;
176 struct scache *sem_arg;
178 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
182 /* Disassembly support.
183 ??? While executing an instruction, the insn has been decoded and all its
184 fields have been extracted. It is certainly possible to do the disassembly
185 with that data. This seems simpler, but maybe in the future the already
186 extracted fields will be used. */
188 /* Pseudo FILE object for strings. */
194 /* sprintf to a "stream" */
197 disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
206 VA_START (args, format);
208 f = va_arg (args, SFILE *);
209 format = va_arg (args, char *);
211 vsprintf (f->current, format, args);
212 f->current += n = strlen (f->current);
218 sim_disassemble_insn (SIM_CPU *cpu, const struct cgen_insn *insn,
219 const struct argbuf *abuf, PCADDR pc, char *buf)
222 unsigned long insn_value;
223 struct disassemble_info disasm_info;
224 struct cgen_fields fields;
227 SIM_DESC sd = CPU_STATE (cpu);
229 sfile.buffer = sfile.current = buf;
230 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
231 (fprintf_ftype) disasm_sprintf);
233 (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
234 : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
235 : BFD_ENDIAN_UNKNOWN);
237 switch (abuf->length)
240 insn_value = sim_core_read_1 (CPU_STATE (cpu), sim_core_read_map, pc);
243 insn_value = sim_core_read_2 (CPU_STATE (cpu), sim_core_read_map, pc);
246 insn_value = sim_core_read_4 (CPU_STATE (cpu), sim_core_read_map, pc);
252 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
253 if (length != abuf->length)
255 (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length);
259 /* This shouldn't happen, but aborting is too drastic. */
260 strcpy (buf, "***unknown***");
267 make_struct_di (hi, lo)
281 SI ahi = GETHIDI (a);
282 SI alo = GETLODI (a);
283 SI bhi = GETHIDI (b);
284 SI blo = GETLODI (b);
285 return MAKEDI (ahi & bhi, alo & blo);
292 SI ahi = GETHIDI (a);
293 SI alo = GETLODI (a);
294 SI bhi = GETHIDI (b);
295 SI blo = GETLODI (b);
296 return MAKEDI (ahi | bhi, alo | blo);
303 USI ahi = GETHIDI (a);
304 USI alo = GETLODI (a);
305 USI bhi = GETHIDI (b);
306 USI blo = GETLODI (b);
308 return MAKEDI (ahi + bhi + (x < alo), x);
315 USI ahi = GETHIDI (a);
316 USI alo = GETLODI (a);
317 USI bhi = GETHIDI (b);
318 USI blo = GETLODI (b);
327 #define SI_TYPE_SIZE 32
328 #define BITS4 (SI_TYPE_SIZE / 4)
329 #define ll_B (1L << (SI_TYPE_SIZE / 2))
330 #define ll_lowpart(t) ((USI) (t) % ll_B)
331 #define ll_highpart(t) ((USI) (t) / ll_B)
332 x1 += ll_highpart (x0); /* this can't give carry */
333 x1 += x2; /* but this indeed can */
334 if (x1 < x2) /* did we get it? */
335 x3 += ll_B; /* yes, add it in the proper pos. */
337 rhi = x3 + ll_highpart (x1);
338 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
339 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
347 USI hi = GETHIDI (val);
348 USI lo = GETLODI (val);
349 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
350 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
358 SI hi = GETHIDI (val);
359 USI lo = GETLODI (val);
360 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
361 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
369 SI hi = GETHIDI (val);
370 USI lo = GETLODI (val);
371 /* We use SRASI because the result is implementation defined if hi < 0. */
372 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
373 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
380 SI ahi = GETHIDI (a);
381 USI alo = GETLODI (a);
382 SI bhi = GETHIDI (b);
383 USI blo = GETLODI (b);
395 SI ahi = GETHIDI (a);
396 USI alo = GETLODI (a);
397 SI bhi = GETHIDI (b);
398 USI blo = GETLODI (b);
411 return MAKEDI (-1, val);
413 return MAKEDI (0, val);
421 return MAKEDI (-1, val);
423 return MAKEDI (0, val);
430 return GETLODI (val);
433 #endif /* DI_FN_SUPPORT */