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[] = {
51 engine_halt (cpu, reason, sigrc)
53 enum exec_state reason;
56 CPU_EXEC_STATE (cpu) = reason;
57 CPU_HALT_SIGRC (cpu) = sigrc;
59 longjmp (STATE_HALT_JMP_BUF (CPU_STATE (cpu)), 1);
63 engine_signal (cpu, sig)
65 enum sim_signal_type sig;
67 engine_halt (cpu, EXEC_STATE_STOPPED, sig);
70 /* Convert SIM_SIGFOO to SIGFOO. */
73 sim_signal_to_host (sig)
89 /* Wingdb uses this value. */
111 /* FIXME: Add "no return" attribute to illegal insn handlers.
112 They all call longjmp. */
113 /* FIXME: May wish to call a target supplied routine which can then call
114 sim_halt if it wants: to allow target to gain control for moment. */
117 ex_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
119 abuf->length = CGEN_BASE_INSN_SIZE;
121 /* Leave signalling to semantic fn. */
125 exc_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
127 abuf->length = CGEN_BASE_INSN_SIZE;
129 /* Leave signalling to semantic fn. */
133 sem_illegal (current_cpu, sem_arg)
134 SIM_CPU *current_cpu;
135 struct argbuf *sem_arg;
137 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
142 semc_illegal (current_cpu, sem_arg)
143 SIM_CPU *current_cpu;
144 struct scache *sem_arg;
146 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
150 /* Disassembly support.
151 ??? While executing an instruction, the insn has been decoded and all its
152 fields have been extracted. It is certainly possible to do the disassembly
153 with that data. This seems simpler, but maybe in the future the already
154 extracted fields will be used. */
156 /* Pseudo FILE object for strings. */
162 /* sprintf to a "stream" */
165 disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
174 VA_START (args, format);
176 f = va_arg (args, SFILE *);
177 format = va_arg (args, char *);
179 vsprintf (f->current, format, args);
180 f->current += n = strlen (f->current);
186 sim_disassemble_insn (insn, abuf, pc, buf)
187 const struct cgen_insn *insn;
188 const struct argbuf *abuf;
193 unsigned long insn_value;
194 struct disassemble_info disasm_info;
195 struct cgen_fields fields;
198 STATE state = current_state;
200 sfile.buffer = sfile.current = buf;
201 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
202 (fprintf_ftype) disasm_sprintf);
204 (bfd_big_endian (STATE_PROG_BFD (state)) ? BFD_ENDIAN_BIG
205 : bfd_little_endian (STATE_PROG_BFD (state)) ? BFD_ENDIAN_LITTLE
206 : BFD_ENDIAN_UNKNOWN);
208 /* (*STATE_MEM_READ (state)) (state, pc, insn_buf, abuf->length);*/
210 switch (abuf->length)
213 insn_value = insn_buf[0];
216 insn_value = disasm_info.endian == BFD_ENDIAN_BIG ? bfd_getb16 (insn_buf) : bfd_getl16 (insn_buf);
219 insn_value = disasm_info.endian == BFD_ENDIAN_BIG ? bfd_getb32 (insn_buf) : bfd_getl32 (insn_buf);
225 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
226 if (length != abuf->length)
228 (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length);
232 /* This shouldn't happen, but aborting is too drastic. */
233 strcpy (buf, "***unknown***");
240 make_struct_di (hi, lo)
254 SI ahi = GETHIDI (a);
255 SI alo = GETLODI (a);
256 SI bhi = GETHIDI (b);
257 SI blo = GETLODI (b);
258 return MAKEDI (ahi & bhi, alo & blo);
265 SI ahi = GETHIDI (a);
266 SI alo = GETLODI (a);
267 SI bhi = GETHIDI (b);
268 SI blo = GETLODI (b);
269 return MAKEDI (ahi | bhi, alo | blo);
276 USI ahi = GETHIDI (a);
277 USI alo = GETLODI (a);
278 USI bhi = GETHIDI (b);
279 USI blo = GETLODI (b);
281 return MAKEDI (ahi + bhi + (x < alo), x);
288 USI ahi = GETHIDI (a);
289 USI alo = GETLODI (a);
290 USI bhi = GETHIDI (b);
291 USI blo = GETLODI (b);
300 #define SI_TYPE_SIZE 32
301 #define BITS4 (SI_TYPE_SIZE / 4)
302 #define ll_B (1L << (SI_TYPE_SIZE / 2))
303 #define ll_lowpart(t) ((USI) (t) % ll_B)
304 #define ll_highpart(t) ((USI) (t) / ll_B)
305 x1 += ll_highpart (x0); /* this can't give carry */
306 x1 += x2; /* but this indeed can */
307 if (x1 < x2) /* did we get it? */
308 x3 += ll_B; /* yes, add it in the proper pos. */
310 rhi = x3 + ll_highpart (x1);
311 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
312 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
320 USI hi = GETHIDI (val);
321 USI lo = GETLODI (val);
322 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
323 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
331 SI hi = GETHIDI (val);
332 USI lo = GETLODI (val);
333 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
334 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
342 SI hi = GETHIDI (val);
343 USI lo = GETLODI (val);
344 /* We use SRASI because the result is implementation defined if hi < 0. */
345 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
346 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
353 SI ahi = GETHIDI (a);
354 USI alo = GETLODI (a);
355 SI bhi = GETHIDI (b);
356 USI blo = GETLODI (b);
368 SI ahi = GETHIDI (a);
369 USI alo = GETLODI (a);
370 SI bhi = GETHIDI (b);
371 USI blo = GETLODI (b);
384 return MAKEDI (-1, val);
386 return MAKEDI (0, val);
394 return MAKEDI (-1, val);
396 return MAKEDI (0, val);
403 return GETLODI (val);
406 #endif /* DI_FN_SUPPORT */