1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996, 1997, 1998 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. */
25 #define MEMOPS_DEFINE_INLINE
28 #define SEMOPS_DEFINE_INLINE
31 const char *mode_names
[] = {
49 /* Initialize cgen things.
50 This is called after sim_post_argv_init. */
53 cgen_init (SIM_DESC sd
)
58 /* If no profiling or tracing has been enabled, run in fast mode. */
59 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
61 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
63 for (i
= 0; i
< MAX_PROFILE_VALUES
; ++i
)
64 if (CPU_PROFILE_FLAGS (cpu
) [i
])
69 for (i
= 0; i
< MAX_TRACE_VALUES
; ++i
)
70 if (CPU_TRACE_FLAGS (cpu
) [i
])
78 STATE_RUN_FAST_P (sd
) = run_fast_p
;
81 /* Disassembly support.
82 ??? While executing an instruction, the insn has been decoded and all its
83 fields have been extracted. It is certainly possible to do the disassembly
84 with that data. This seems simpler, but maybe in the future the already
85 extracted fields will be used. */
87 /* Pseudo FILE object for strings. */
93 /* sprintf to a "stream" */
96 disasm_sprintf
VPARAMS ((SFILE
*f
, const char *format
, ...))
105 VA_START (args
, format
);
107 f
= va_arg (args
, SFILE
*);
108 format
= va_arg (args
, char *);
110 vsprintf (f
->current
, format
, args
);
111 f
->current
+= n
= strlen (f
->current
);
117 sim_disassemble_insn (SIM_CPU
*cpu
, const struct cgen_insn
*insn
,
118 const struct argbuf
*abuf
, PCADDR pc
, char *buf
)
121 unsigned long insn_value
;
122 struct disassemble_info disasm_info
;
123 struct cgen_fields fields
;
127 unsigned16 shorts
[8];
130 SIM_DESC sd
= CPU_STATE (cpu
);
132 sfile
.buffer
= sfile
.current
= buf
;
133 INIT_DISASSEMBLE_INFO (disasm_info
, (FILE *) &sfile
,
134 (fprintf_ftype
) disasm_sprintf
);
136 (bfd_big_endian (STATE_PROG_BFD (sd
)) ? BFD_ENDIAN_BIG
137 : bfd_little_endian (STATE_PROG_BFD (sd
)) ? BFD_ENDIAN_LITTLE
138 : BFD_ENDIAN_UNKNOWN
);
140 length
= sim_core_read_buffer (sd
, cpu
, sim_core_read_map
, &insn_buf
, pc
,
141 CGEN_INSN_BITSIZE (insn
) / 8);
145 case 1 : insn_value
= insn_buf
.bytes
[0]; break;
146 case 2 : insn_value
= T2H_2 (insn_buf
.shorts
[0]); break;
147 case 4 : insn_value
= T2H_4 (insn_buf
.words
[0]); break;
151 length
= (*CGEN_EXTRACT_FN (insn
)) (insn
, NULL
, insn_value
, &fields
);
152 /* Result of extract fn is in bits. */
153 /* ??? This assumes that each instruction has a fixed length (and thus
154 for insns with multiple versions of variable lengths they would each
155 have their own table entry). */
156 if (length
== CGEN_INSN_BITSIZE (insn
))
158 (*CGEN_PRINT_FN (insn
)) (&disasm_info
, insn
, &fields
, pc
, length
);
162 /* This shouldn't happen, but aborting is too drastic. */
163 strcpy (buf
, "***unknown***");
170 make_struct_di (hi
, lo
)
184 SI ahi
= GETHIDI (a
);
185 SI alo
= GETLODI (a
);
186 SI bhi
= GETHIDI (b
);
187 SI blo
= GETLODI (b
);
188 return MAKEDI (ahi
& bhi
, alo
& blo
);
195 SI ahi
= GETHIDI (a
);
196 SI alo
= GETLODI (a
);
197 SI bhi
= GETHIDI (b
);
198 SI blo
= GETLODI (b
);
199 return MAKEDI (ahi
| bhi
, alo
| blo
);
206 USI ahi
= GETHIDI (a
);
207 USI alo
= GETLODI (a
);
208 USI bhi
= GETHIDI (b
);
209 USI blo
= GETLODI (b
);
211 return MAKEDI (ahi
+ bhi
+ (x
< alo
), x
);
218 USI ahi
= GETHIDI (a
);
219 USI alo
= GETLODI (a
);
220 USI bhi
= GETHIDI (b
);
221 USI blo
= GETLODI (b
);
230 #define SI_TYPE_SIZE 32
231 #define BITS4 (SI_TYPE_SIZE / 4)
232 #define ll_B (1L << (SI_TYPE_SIZE / 2))
233 #define ll_lowpart(t) ((USI) (t) % ll_B)
234 #define ll_highpart(t) ((USI) (t) / ll_B)
235 x1
+= ll_highpart (x0
); /* this can't give carry */
236 x1
+= x2
; /* but this indeed can */
237 if (x1
< x2
) /* did we get it? */
238 x3
+= ll_B
; /* yes, add it in the proper pos. */
240 rhi
= x3
+ ll_highpart (x1
);
241 rlo
= ll_lowpart (x1
) * ll_B
+ ll_lowpart (x0
);
242 return MAKEDI (rhi
+ (alo
* bhi
) + (ahi
* blo
), rlo
);
250 USI hi
= GETHIDI (val
);
251 USI lo
= GETLODI (val
);
252 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
253 return MAKEDI ((hi
<< shift
) | (lo
>> (32 - shift
)), lo
<< shift
);
261 SI hi
= GETHIDI (val
);
262 USI lo
= GETLODI (val
);
263 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
264 return MAKEDI ((hi
<< shift
) | (lo
>> (32 - shift
)), lo
<< shift
);
272 SI hi
= GETHIDI (val
);
273 USI lo
= GETLODI (val
);
274 /* We use SRASI because the result is implementation defined if hi < 0. */
275 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
276 return MAKEDI (SRASI (hi
, shift
), (hi
<< (32 - shift
)) | (lo
>> shift
));
283 SI ahi
= GETHIDI (a
);
284 USI alo
= GETLODI (a
);
285 SI bhi
= GETHIDI (b
);
286 USI blo
= GETLODI (b
);
298 SI ahi
= GETHIDI (a
);
299 USI alo
= GETLODI (a
);
300 SI bhi
= GETHIDI (b
);
301 USI blo
= GETLODI (b
);
314 return MAKEDI (-1, val
);
316 return MAKEDI (0, val
);
324 return MAKEDI (-1, val
);
326 return MAKEDI (0, val
);
333 return GETLODI (val
);
336 #endif /* DI_FN_SUPPORT */