Update devo version of m32r sim to build with recent sim/common changes.
[deliverable/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
b9c8cd10
DE
1/* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "sim-main.h"
1fe05280 22#include <signal.h>
b9c8cd10
DE
23#include "dis-asm.h"
24#include "cpu-opc.h"
25#include "decode.h"
26
27#define MEMOPS_DEFINE_INLINE
3e324f89 28#include "mem-ops.h"
b9c8cd10
DE
29
30#define SEMOPS_DEFINE_INLINE
3e324f89 31#include "sem-ops.h"
b9c8cd10
DE
32
33const char *mode_names[] = {
34 "VM",
35 "BI",
36 "QI",
37 "HI",
38 "SI",
39 "DI",
40 "UBI",
41 "UQI",
42 "UHI",
43 "USI",
44 "UDI",
45 "SF",
46 "DF",
47 "XF",
48 "TF",
49};
50
260b2c47
DE
51/* Initialize cgen things.
52 This is called after sim_post_argv_init. */
53
54void
55cgen_init (SIM_DESC sd)
56{
57 int i, c;
58 int run_fast_p = 1;
59
60 /* If no profiling or tracing has been enabled, run in fast mode. */
61 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
62 {
63 sim_cpu *cpu = STATE_CPU (sd, c);
64
65 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
66 if (CPU_PROFILE_FLAGS (cpu) [i])
67 {
68 run_fast_p = 0;
69 break;
70 }
71 for (i = 0; i < MAX_TRACE_VALUES; ++i)
72 if (CPU_TRACE_FLAGS (cpu) [i])
73 {
74 run_fast_p = 0;
75 break;
76 }
77 if (! run_fast_p)
78 break;
79 }
80 STATE_RUN_FAST_P (sd) = run_fast_p;
81}
82\f
b9c8cd10
DE
83void
84engine_halt (cpu, reason, sigrc)
85 sim_cpu *cpu;
86 enum exec_state reason;
87 int sigrc;
88{
89 CPU_EXEC_STATE (cpu) = reason;
90 CPU_HALT_SIGRC (cpu) = sigrc;
91
92 longjmp (STATE_HALT_JMP_BUF (CPU_STATE (cpu)), 1);
93}
94
95void
96engine_signal (cpu, sig)
97 sim_cpu *cpu;
98 enum sim_signal_type sig;
99{
100 engine_halt (cpu, EXEC_STATE_STOPPED, sig);
101}
102
103/* Convert SIM_SIGFOO to SIGFOO. */
104
105int
106sim_signal_to_host (sig)
107 int sig;
108{
109 switch (sig)
110 {
111 case SIM_SIGILL :
112#ifdef SIGILL
113 return SIGILL;
114#endif
115 break;
116
117 case SIM_SIGTRAP :
118#ifdef SIGTRAP
119 return SIGTRAP;
120#else
121#ifdef _MSC_VER
122 /* Wingdb uses this value. */
123 return 5;
124#endif
125#endif
126 break;
127
128 case SIM_SIGALIGN :
129 case SIM_SIGACCESS :
130#ifdef SIGSEGV
131 return SIGSEGV;
132#endif
133 break;
134
135 case SIM_SIGXCPU :
136#ifdef SIGXCPU
137 return SIGXCPU;
138#endif
139 break;
140 }
141 return 1;
142}
143\f
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. */
148
149void
150ex_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
151{
152 abuf->length = CGEN_BASE_INSN_SIZE;
153 abuf->addr = pc;
154 /* Leave signalling to semantic fn. */
155}
156
157void
158exc_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf)
159{
160 abuf->length = CGEN_BASE_INSN_SIZE;
161 abuf->addr = pc;
162 /* Leave signalling to semantic fn. */
163}
164
165PCADDR
166sem_illegal (current_cpu, sem_arg)
167 SIM_CPU *current_cpu;
168 struct argbuf *sem_arg;
169{
170 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
171 return 0;
172}
173
174PCADDR
175semc_illegal (current_cpu, sem_arg)
176 SIM_CPU *current_cpu;
177 struct scache *sem_arg;
178{
179 engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL);
180 return 0;
181}
182\f
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. */
188
189/* Pseudo FILE object for strings. */
190typedef struct {
191 char *buffer;
192 char *current;
193} SFILE;
194
195/* sprintf to a "stream" */
196
197static int
198disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
199{
200#ifndef __STDC__
201 SFILE *f;
202 const char *format;
203#endif
204 int n;
205 va_list args;
206
207 VA_START (args, format);
208#ifndef __STDC__
209 f = va_arg (args, SFILE *);
210 format = va_arg (args, char *);
211#endif
212 vsprintf (f->current, format, args);
213 f->current += n = strlen (f->current);
214 va_end (args);
215 return n;
216}
217
218void
260b2c47
DE
219sim_disassemble_insn (SIM_CPU *cpu, const struct cgen_insn *insn,
220 const struct argbuf *abuf, PCADDR pc, char *buf)
b9c8cd10
DE
221{
222 int length;
223 unsigned long insn_value;
224 struct disassemble_info disasm_info;
225 struct cgen_fields fields;
226 SFILE sfile;
227 char insn_buf[20];
260b2c47 228 SIM_DESC sd = CPU_STATE (cpu);
b9c8cd10
DE
229
230 sfile.buffer = sfile.current = buf;
231 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
232 (fprintf_ftype) disasm_sprintf);
233 disasm_info.endian =
260b2c47
DE
234 (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
235 : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
b9c8cd10
DE
236 : BFD_ENDIAN_UNKNOWN);
237
b9c8cd10
DE
238 switch (abuf->length)
239 {
240 case 1 :
1fe05280 241 insn_value = sim_core_read_1 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
b9c8cd10
DE
242 break;
243 case 2 :
1fe05280 244 insn_value = sim_core_read_2 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
b9c8cd10
DE
245 break;
246 case 4 :
1fe05280 247 insn_value = sim_core_read_4 (CPU_STATE (cpu), sim_core_read_map, pc, NULL, NULL_CIA);
b9c8cd10
DE
248 break;
249 default:
250 abort ();
251 }
252
253 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
254 if (length != abuf->length)
255 {
256 (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length);
257 }
258 else
259 {
260 /* This shouldn't happen, but aborting is too drastic. */
261 strcpy (buf, "***unknown***");
262 }
263}
264\f
265#ifdef DI_FN_SUPPORT
266
267DI
268make_struct_di (hi, lo)
269 SI hi, lo;
270{
271 DI result;
272
273 result.hi = hi;
274 result.lo = lo;
275 return result;
276}
277
278DI
279ANDDI (a, b)
280 DI a, b;
281{
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);
287}
288
289DI
290ORDI (a, b)
291 DI a, b;
292{
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);
298}
299
300DI
301ADDDI (a, b)
302 DI a, b;
303{
304 USI ahi = GETHIDI (a);
305 USI alo = GETLODI (a);
306 USI bhi = GETHIDI (b);
307 USI blo = GETLODI (b);
308 USI x = alo + blo;
309 return MAKEDI (ahi + bhi + (x < alo), x);
310}
311
312DI
313MULDI (a, b)
314 DI a, b;
315{
316 USI ahi = GETHIDI (a);
317 USI alo = GETLODI (a);
318 USI bhi = GETHIDI (b);
319 USI blo = GETLODI (b);
320 USI rhi,rlo;
321 USI x0, x1, x2, x3;
322
323 x0 = alo * blo;
324 x1 = alo * bhi;
325 x2 = ahi * blo;
326 x3 = ahi * bhi;
327
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. */
337
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);
341}
342
343DI
344SHLDI (val, shift)
345 DI val;
346 SI shift;
347{
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);
352}
353
354DI
355SLADI (val, shift)
356 DI val;
357 SI shift;
358{
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);
363}
364
365DI
366SRADI (val, shift)
367 DI val;
368 SI shift;
369{
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));
375}
376
377int
378GEDI (a, b)
379 DI a, b;
380{
381 SI ahi = GETHIDI (a);
382 USI alo = GETLODI (a);
383 SI bhi = GETHIDI (b);
384 USI blo = GETLODI (b);
385 if (ahi > bhi)
386 return 1;
387 if (ahi == bhi)
388 return alo >= blo;
389 return 0;
390}
391
392int
393LEDI (a, b)
394 DI a, b;
395{
396 SI ahi = GETHIDI (a);
397 USI alo = GETLODI (a);
398 SI bhi = GETHIDI (b);
399 USI blo = GETLODI (b);
400 if (ahi < bhi)
401 return 1;
402 if (ahi == bhi)
403 return alo <= blo;
404 return 0;
405}
406
407DI
408CONVHIDI (val)
409 HI val;
410{
411 if (val < 0)
412 return MAKEDI (-1, val);
413 else
414 return MAKEDI (0, val);
415}
416
417DI
418CONVSIDI (val)
419 SI val;
420{
421 if (val < 0)
422 return MAKEDI (-1, val);
423 else
424 return MAKEDI (0, val);
425}
426
427SI
428CONVDISI (val)
429 DI val;
430{
431 return GETLODI (val);
432}
433
434#endif /* DI_FN_SUPPORT */
This page took 0.038754 seconds and 4 git commands to generate.