]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/cr16/interp.c
remove PARAMS from include/cgen
[thirdparty/binutils-gdb.git] / sim / cr16 / interp.c
CommitLineData
fee8ec00 1/* Simulation code for the CR16 processor.
ecd75fc8 2 Copyright (C) 2008-2014 Free Software Foundation, Inc.
fee8ec00
SR
3 Contributed by M Ranga Swami Reddy <MR.Swami.Reddy@nsc.com>
4
5 This file is part of GDB, the GNU debugger.
6
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
dc3cf14f 9 the Free Software Foundation; either version 3, or (at your option)
fee8ec00
SR
10 any later version.
11
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.
16
052d9a54
SR
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
fee8ec00 19
26687999 20#include "config.h"
fee8ec00 21#include <signal.h>
26687999
MF
22#include <stdlib.h>
23#include <string.h>
fee8ec00
SR
24#include "bfd.h"
25#include "gdb/callback.h"
26#include "gdb/remote-sim.h"
27
28#include "cr16_sim.h"
29#include "gdb/sim-cr16.h"
30#include "gdb/signals.h"
31#include "opcode/cr16.h"
32
fee8ec00
SR
33static char *myname;
34static SIM_OPEN_KIND sim_kind;
35int cr16_debug;
36
37/* Set this to true to get the previous segment layout. */
38
39int old_segment_mapping;
40
41host_callback *cr16_callback;
42unsigned long ins_type_counters[ (int)INS_MAX ];
43
44uint32 OP[4];
45uint32 sign_flag;
46
47static int init_text_p = 0;
48/* non-zero if we opened prog_bfd */
49static int prog_bfd_was_opened_p;
50bfd *prog_bfd;
51asection *text;
52bfd_vma text_start;
53bfd_vma text_end;
54
052d9a54
SR
55static struct hash_entry *lookup_hash PARAMS ((uint64 ins, int size));
56static void get_operands PARAMS ((operand_desc *s, uint64 mcode, int isize, int nops));
57static int do_run PARAMS ((uint64 mc));
fee8ec00
SR
58static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
59extern void sim_set_profile PARAMS ((int n));
60extern void sim_set_profile_size PARAMS ((int n));
61static INLINE uint8 *map_memory (unsigned phys_addr);
62
63#ifdef NEED_UI_LOOP_HOOK
64/* How often to run the ui_loop update, when in use */
65#define UI_LOOP_POLL_INTERVAL 0x14000
66
67/* Counter for the ui_loop_hook update */
68static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
69
70/* Actual hook to call to run through gdb's gui event loop */
71extern int (*deprecated_ui_loop_hook) PARAMS ((int signo));
72#endif /* NEED_UI_LOOP_HOOK */
73
74#ifndef INLINE
75#if defined(__GNUC__) && defined(__OPTIMIZE__)
76#define INLINE __inline__
77#else
78#define INLINE
79#endif
80#endif
052d9a54
SR
81#define MAX_HASH 16
82
83struct hash_entry
84{
85 struct hash_entry *next;
86 uint32 opcode;
87 uint32 mask;
88 int format;
89 int size;
90 struct simops *ops;
91};
92
93struct hash_entry hash_table[MAX_HASH+1];
94
95INLINE static long
96hash(unsigned long long insn, int format)
97{
98 unsigned int i = 4, tmp;
99 if (format)
100 {
101 while ((insn >> i) != 0) i +=4;
102
103 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
104 }
105 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
106}
107
108
109INLINE static struct hash_entry *
110lookup_hash (uint64 ins, int size)
111{
112 uint32 mask;
113 struct hash_entry *h;
114
115 h = &hash_table[hash(ins,1)];
116
117
118 mask = (((1 << (32 - h->mask)) -1) << h->mask);
119
120 /* Adjuest mask for branch with 2 word instructions. */
121 if ((h->ops->mnimonic != NULL) &&
122 ((streq(h->ops->mnimonic,"b") && h->size == 2)))
123 mask = 0xff0f0000;
124
125
126 while ((ins & mask) != (BIN(h->opcode, h->mask)))
127 {
128 if (h->next == NULL)
129 {
130 State.exception = SIGILL;
131 State.pc_changed = 1; /* Don't increment the PC. */
132 return NULL;
133 }
134 h = h->next;
135
136 mask = (((1 << (32 - h->mask)) -1) << h->mask);
137 /* Adjuest mask for branch with 2 word instructions. */
138 if ((streq(h->ops->mnimonic,"b")) && h->size == 2)
139 mask = 0xff0f0000;
140
141 }
142 return (h);
143}
fee8ec00
SR
144
145INLINE static void
052d9a54 146get_operands (operand_desc *s, uint64 ins, int isize, int nops)
fee8ec00
SR
147{
148 uint32 i, opn = 0, start_bit = 0, op_type = 0;
149 int32 op_size = 0, mask = 0;
150
151 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
152 ins = ins >> 16;
153
052d9a54 154 for (i=0; i < 4; ++i,++opn)
fee8ec00 155 {
052d9a54 156 if (s[opn].op_type == dummy) break;
fee8ec00 157
052d9a54 158 op_type = s[opn].op_type;
fee8ec00
SR
159 start_bit = s[opn].shift;
160 op_size = cr16_optab[op_type].bit_size;
161
162 switch (op_type)
052d9a54 163 {
fee8ec00 164 case imm3: case imm4: case imm5: case imm6:
052d9a54
SR
165 {
166 if (isize == 1)
167 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
fee8ec00 168 else
052d9a54
SR
169 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
170
171 if (OP[i] & ((long)1 << (op_size -1)))
172 {
173 sign_flag = 1;
174 OP[i] = ~(OP[i]) + 1;
175 }
176 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
fee8ec00 177 }
052d9a54 178 break;
fee8ec00
SR
179
180 case uimm3: case uimm3_1: case uimm4_1:
052d9a54
SR
181 switch (isize)
182 {
183 case 1:
184 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
185 case 2:
186 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
187 default: /* for case 3. */
188 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
189 break;
190 }
191 break;
fee8ec00
SR
192
193 case uimm4:
052d9a54
SR
194 switch (isize)
195 {
196 case 1:
197 if (start_bit == 20)
198 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
199 else
200 OP[i] = (ins & ((1 << op_size) -1));
201 break;
202 case 2:
203 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
204 break;
205 case 3:
206 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
207 break;
208 default:
209 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
210 break;
211 }
212 break;
fee8ec00
SR
213
214 case imm16: case uimm16:
215 OP[i] = ins & 0xFFFF;
052d9a54 216 break;
fee8ec00
SR
217
218 case uimm20: case imm20:
052d9a54
SR
219 OP[i] = ins & (((long)1 << op_size) - 1);
220 break;
fee8ec00
SR
221
222 case imm32: case uimm32:
223 OP[i] = ins & 0xFFFFFFFF;
052d9a54 224 break;
fee8ec00 225
052d9a54 226 case uimm5: break; /*NOT USED. */
fee8ec00
SR
227 OP[i] = ins & ((1 << op_size) - 1); break;
228
229 case disps5:
230 OP[i] = (ins >> 4) & ((1 << 4) - 1);
231 OP[i] = (OP[i] * 2) + 2;
052d9a54
SR
232 if (OP[i] & ((long)1 << 5))
233 {
234 sign_flag = 1;
235 OP[i] = ~(OP[i]) + 1;
236 OP[i] = (unsigned long int)(OP[i] & 0x1F);
237 }
238 break;
239
240 case dispe9:
241 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
242 OP[i] <<= 1;
243 if (OP[i] & ((long)1 << 8))
244 {
245 sign_flag = 1;
246 OP[i] = ~(OP[i]) + 1;
247 OP[i] = (unsigned long int)(OP[i] & 0xFF);
248 }
249 break;
250
251 case disps17:
252 OP[i] = (ins & 0xFFFF);
253 if (OP[i] & 1)
254 {
255 OP[i] = (OP[i] & 0xFFFE);
256 sign_flag = 1;
257 OP[i] = ~(OP[i]) + 1;
258 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
fee8ec00 259 }
052d9a54
SR
260 break;
261
262 case disps25:
263 if (isize == 2)
264 OP[i] = (ins & 0xFFFFFF);
265 else
266 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
267 (((ins >> 16) & 0xf) << 20);
268
269 if (OP[i] & 1)
270 {
271 OP[i] = (OP[i] & 0xFFFFFE);
272 sign_flag = 1;
273 OP[i] = ~(OP[i]) + 1;
274 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
fee8ec00 275 }
052d9a54 276 break;
fee8ec00
SR
277
278 case abs20:
052d9a54 279 if (isize == 3)
fee8ec00 280 OP[i] = (ins) & 0xFFFFF;
052d9a54 281 else
fee8ec00 282 OP[i] = (ins >> start_bit) & 0xFFFFF;
052d9a54 283 break;
fee8ec00 284 case abs24:
052d9a54
SR
285 if (isize == 3)
286 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
287 | (((ins >> 24) & 0xf) << 16));
288 else
289 OP[i] = (ins >> 16) & 0xFFFFFF;
290 break;
fee8ec00
SR
291
292 case rra:
293 case rbase: break; /* NOT USED. */
294 case rbase_disps20: case rbase_dispe20:
295 case rpbase_disps20: case rpindex_disps20:
052d9a54
SR
296 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
297 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
298 break;
fee8ec00 299 case rpbase_disps0:
052d9a54
SR
300 OP[i] = 0; /* 4 bit disp const. */
301 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
302 break;
fee8ec00 303 case rpbase_dispe4:
052d9a54
SR
304 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
305 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
306 break;
fee8ec00 307 case rpbase_disps4:
052d9a54
SR
308 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
309 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
310 break;
fee8ec00 311 case rpbase_disps16:
052d9a54
SR
312 OP[i] = (ins) & 0xFFFF;
313 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
314 break;
fee8ec00 315 case rpindex_disps0:
052d9a54
SR
316 OP[i] = 0;
317 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
318 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
319 break;
fee8ec00 320 case rpindex_disps14:
052d9a54
SR
321 OP[i] = (ins) & 0x3FFF;
322 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */
323 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
fee8ec00
SR
324 case rindex7_abs20:
325 case rindex8_abs20:
052d9a54
SR
326 OP[i] = (ins) & 0xFFFFF;
327 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */
328 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */
329 break;
fee8ec00 330 case regr: case regp: case pregr: case pregrp:
052d9a54
SR
331 switch(isize)
332 {
333 case 1:
334 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
335 else if (start_bit == 16) OP[i] = ins & 0xF;
336 break;
337 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
338 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
339 }
340 break;
fee8ec00 341 case cc:
052d9a54
SR
342 {
343 if (isize == 1) OP[i] = (ins >> 4) & 0xF;
344 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF;
345 else OP[i] = (ins >> (start_bit + 16)) & 0xF;
346 break;
347 }
348 default: break;
349 }
fee8ec00 350
052d9a54 351 /* For ESC on uimm4_1 operand. */
fee8ec00 352 if (op_type == uimm4_1)
052d9a54
SR
353 if (OP[i] == 9)
354 OP[i] = -1;
355
356 /* For increment by 1. */
357 if ((op_type == pregr) || (op_type == pregrp))
358 OP[i] += 1;
fee8ec00
SR
359 }
360 /* FIXME: for tracing, update values that need to be updated each
361 instruction decode cycle */
fee8ec00 362 State.trace.psw = PSR;
fee8ec00
SR
363}
364
365bfd_vma
366decode_pc ()
367{
368 asection *s;
369 if (!init_text_p && prog_bfd != NULL)
370 {
371 init_text_p = 1;
372 for (s = prog_bfd->sections; s; s = s->next)
052d9a54
SR
373 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
374 {
375 text = s;
376 text_start = bfd_get_section_vma (prog_bfd, s);
377 text_end = text_start + bfd_section_size (prog_bfd, s);
378 break;
379 }
fee8ec00
SR
380 }
381
382 return (PC) + text_start;
383}
384
385
386
052d9a54
SR
387static int
388do_run(uint64 mcode)
fee8ec00
SR
389{
390 struct simops *s= Simops;
052d9a54 391 struct hash_entry *h;
fee8ec00 392 char func[12]="\0";
052d9a54 393 uint8 *iaddr;
fee8ec00
SR
394#ifdef DEBUG
395 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
052d9a54 396 (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
fee8ec00
SR
397#endif
398
052d9a54
SR
399 h = lookup_hash(mcode, 1);
400
401 if ((h == NULL) || (h->opcode == NULL)) return 0;
402
403 if (h->size == 3)
404 {
405 iaddr = imem_addr ((uint32)PC + 2);
406 mcode = (mcode << 16) | get_longword( iaddr );
407 }
408
409 /* Re-set OP list. */
fee8ec00
SR
410 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
411
052d9a54
SR
412 /* for push/pop/pushrtn with RA instructions. */
413 if ((h->format & REG_LIST) && (mcode & 0x800000))
414 OP[2] = 1; /* Set 1 for RA operand. */
fee8ec00 415
052d9a54
SR
416 /* numops == 0 means, no operands. */
417 if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
418 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
fee8ec00 419
052d9a54
SR
420 //State.ins_type = h->flags;
421
422 (h->ops->func)();
423
424 return h->size;
fee8ec00
SR
425}
426
427static char *
428add_commas(char *buf, int sizeof_buf, unsigned long value)
429{
430 int comma = 3;
431 char *endbuf = buf + sizeof_buf - 1;
432
433 *--endbuf = '\0';
434 do {
435 if (comma-- == 0)
436 {
052d9a54
SR
437 *--endbuf = ',';
438 comma = 2;
fee8ec00
SR
439 }
440
441 *--endbuf = (value % 10) + '0';
442 } while ((value /= 10) != 0);
443
444 return endbuf;
445}
446
447void
448sim_size (int power)
449{
450 int i;
451 for (i = 0; i < IMEM_SEGMENTS; i++)
452 {
453 if (State.mem.insn[i])
052d9a54 454 free (State.mem.insn[i]);
fee8ec00
SR
455 }
456 for (i = 0; i < DMEM_SEGMENTS; i++)
457 {
458 if (State.mem.data[i])
052d9a54 459 free (State.mem.data[i]);
fee8ec00
SR
460 }
461 for (i = 0; i < UMEM_SEGMENTS; i++)
462 {
463 if (State.mem.unif[i])
052d9a54 464 free (State.mem.unif[i]);
fee8ec00
SR
465 }
466 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
467 registers. */
468 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
469}
470
471/* For tracing - leave info on last access around. */
472static char *last_segname = "invalid";
473static char *last_from = "invalid";
474static char *last_to = "invalid";
475
476enum
477 {
478 IMAP0_OFFSET = 0xff00,
479 DMAP0_OFFSET = 0xff08,
480 DMAP2_SHADDOW = 0xff04,
481 DMAP2_OFFSET = 0xff0c
482 };
483
484static void
485set_dmap_register (int reg_nr, unsigned long value)
486{
487 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
052d9a54 488 + DMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
489 WRITE_16 (raw, value);
490#ifdef DEBUG
491 if ((cr16_debug & DEBUG_MEMORY))
492 {
493 (*cr16_callback->printf_filtered)
052d9a54 494 (cr16_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
fee8ec00
SR
495 }
496#endif
497}
498
499static unsigned long
500dmap_register (void *regcache, int reg_nr)
501{
502 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
052d9a54 503 + DMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
504 return READ_16 (raw);
505}
506
507static void
508set_imap_register (int reg_nr, unsigned long value)
509{
510 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
052d9a54 511 + IMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
512 WRITE_16 (raw, value);
513#ifdef DEBUG
514 if ((cr16_debug & DEBUG_MEMORY))
515 {
516 (*cr16_callback->printf_filtered)
052d9a54 517 (cr16_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
fee8ec00
SR
518 }
519#endif
520}
521
522static unsigned long
523imap_register (void *regcache, int reg_nr)
524{
525 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
052d9a54 526 + IMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
527 return READ_16 (raw);
528}
529
530enum
531 {
532 HELD_SPI_IDX = 0,
533 HELD_SPU_IDX = 1
534 };
535
536static unsigned long
537spu_register (void)
538{
539 return GPR (SP_IDX);
540}
541
542static unsigned long
543spi_register (void)
544{
545 return GPR (SP_IDX);
546}
547
548static void
549set_spi_register (unsigned long value)
550{
551 SET_GPR (SP_IDX, value);
552}
553
554static void
555set_spu_register (unsigned long value)
556{
557 SET_GPR (SP_IDX, value);
558}
559
560/* Given a virtual address in the DMAP address space, translate it
561 into a physical address. */
562
563unsigned long
564sim_cr16_translate_dmap_addr (unsigned long offset,
052d9a54
SR
565 int nr_bytes,
566 unsigned long *phys,
567 void *regcache,
568 unsigned long (*dmap_register) (void *regcache,
569 int reg_nr))
fee8ec00
SR
570{
571 short map;
572 int regno;
573 last_from = "logical-data";
574 if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS)
575 {
576 /* Logical address out side of data segments, not supported */
577 return 0;
578 }
579 regno = (offset / DMAP_BLOCK_SIZE);
580 offset = (offset % DMAP_BLOCK_SIZE);
581
582#if 1
583 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
584 {
585 /* Don't cross a BLOCK boundary */
586 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
587 }
588 map = dmap_register (regcache, regno);
589 if (regno == 3)
590 {
591 /* Always maps to data memory */
592 int iospi = (offset / 0x1000) % 4;
593 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
594 last_to = "io-space";
595 *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
596 }
597 else
598 {
599 int sp = ((map & 0x3000) >> 12);
600 int segno = (map & 0x3ff);
601 switch (sp)
052d9a54
SR
602 {
603 case 0: /* 00: Unified memory */
604 *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
605 last_to = "unified";
606 break;
607 case 1: /* 01: Instruction Memory */
608 *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
609 last_to = "chip-insn";
610 break;
611 case 2: /* 10: Internal data memory */
612 *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
613 last_to = "chip-data";
614 break;
615 case 3: /* 11: Reserved */
616 return 0;
617 }
fee8ec00
SR
618 }
619#endif
620 return nr_bytes;
621}
622
623/* Given a virtual address in the IMAP address space, translate it
624 into a physical address. */
625
626unsigned long
627sim_cr16_translate_imap_addr (unsigned long offset,
052d9a54
SR
628 int nr_bytes,
629 unsigned long *phys,
630 void *regcache,
631 unsigned long (*imap_register) (void *regcache,
632 int reg_nr))
fee8ec00
SR
633{
634 short map;
635 int regno;
636 int sp;
637 int segno;
638 last_from = "logical-insn";
639 if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS))
640 {
641 /* Logical address outside of IMAP segments, not supported */
642 return 0;
643 }
644 regno = (offset / IMAP_BLOCK_SIZE);
645 offset = (offset % IMAP_BLOCK_SIZE);
646 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
647 {
648 /* Don't cross a BLOCK boundary */
649 nr_bytes = IMAP_BLOCK_SIZE - offset;
650 }
651 map = imap_register (regcache, regno);
652 sp = (map & 0x3000) >> 12;
653 segno = (map & 0x007f);
654 switch (sp)
655 {
656 case 0: /* 00: unified memory */
657 *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset;
658 last_to = "unified";
659 break;
660 case 1: /* 01: instruction memory */
661 *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
662 last_to = "chip-insn";
663 break;
664 case 2: /*10*/
665 /* Reserved. */
666 return 0;
667 case 3: /* 11: for testing - instruction memory */
668 offset = (offset % 0x800);
669 *phys = SIM_CR16_MEMORY_INSN + offset;
670 if (offset + nr_bytes > 0x800)
052d9a54
SR
671 /* don't cross VM boundary */
672 nr_bytes = 0x800 - offset;
fee8ec00
SR
673 last_to = "test-insn";
674 break;
675 }
676 return nr_bytes;
677}
678
679unsigned long
052d9a54
SR
680sim_cr16_translate_addr (unsigned long memaddr, int nr_bytes,
681 unsigned long *targ_addr, void *regcache,
682 unsigned long (*dmap_register) (void *regcache,
683 int reg_nr),
684 unsigned long (*imap_register) (void *regcache,
685 int reg_nr))
fee8ec00
SR
686{
687 unsigned long phys;
688 unsigned long seg;
689 unsigned long off;
690
691 last_from = "unknown";
692 last_to = "unknown";
693
694 seg = (memaddr >> 24);
695 off = (memaddr & 0xffffffL);
696
697 /* However, if we've asked to use the previous generation of segment
698 mapping, rearrange the segments as follows. */
699
700 if (old_segment_mapping)
701 {
702 switch (seg)
052d9a54
SR
703 {
704 case 0x00: /* DMAP translated memory */
705 seg = 0x10;
706 break;
707 case 0x01: /* IMAP translated memory */
708 seg = 0x11;
709 break;
710 case 0x10: /* On-chip data memory */
711 seg = 0x02;
712 break;
713 case 0x11: /* On-chip insn memory */
714 seg = 0x01;
715 break;
716 case 0x12: /* Unified memory */
717 seg = 0x00;
718 break;
719 }
fee8ec00
SR
720 }
721
722 switch (seg)
723 {
052d9a54 724 case 0x00: /* Physical unified memory */
fee8ec00
SR
725 last_from = "phys-unified";
726 last_to = "unified";
727 phys = SIM_CR16_MEMORY_UNIFIED + off;
728 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 729 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
730 break;
731
052d9a54 732 case 0x01: /* Physical instruction memory */
fee8ec00
SR
733 last_from = "phys-insn";
734 last_to = "chip-insn";
735 phys = SIM_CR16_MEMORY_INSN + off;
736 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 737 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
738 break;
739
052d9a54 740 case 0x02: /* Physical data memory segment */
fee8ec00
SR
741 last_from = "phys-data";
742 last_to = "chip-data";
743 phys = SIM_CR16_MEMORY_DATA + off;
744 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 745 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
746 break;
747
052d9a54 748 case 0x10: /* in logical data address segment */
fee8ec00 749 nr_bytes = sim_cr16_translate_dmap_addr (off, nr_bytes, &phys, regcache,
052d9a54 750 dmap_register);
fee8ec00
SR
751 break;
752
052d9a54 753 case 0x11: /* in logical instruction address segment */
fee8ec00 754 nr_bytes = sim_cr16_translate_imap_addr (off, nr_bytes, &phys, regcache,
052d9a54 755 imap_register);
fee8ec00
SR
756 break;
757
758 default:
759 return 0;
760 }
761
762 *targ_addr = phys;
763 return nr_bytes;
764}
765
766/* Return a pointer into the raw buffer designated by phys_addr. It
767 is assumed that the client has already ensured that the access
768 isn't going to cross a segment boundary. */
769
770uint8 *
771map_memory (unsigned phys_addr)
772{
773 uint8 **memory;
774 uint8 *raw;
775 unsigned offset;
776 int segment = ((phys_addr >> 24) & 0xff);
777
778 switch (segment)
779 {
780
781 case 0x00: /* Unified memory */
782 {
052d9a54
SR
783 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
784 last_segname = "umem";
785 break;
fee8ec00
SR
786 }
787
788 case 0x01: /* On-chip insn memory */
789 {
052d9a54
SR
790 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
791 last_segname = "imem";
792 break;
fee8ec00
SR
793 }
794
795 case 0x02: /* On-chip data memory */
796 {
052d9a54
SR
797 if ((phys_addr & 0xff00) == 0xff00)
798 {
799 phys_addr = (phys_addr & 0xffff);
800 if (phys_addr == DMAP2_SHADDOW)
801 {
802 phys_addr = DMAP2_OFFSET;
803 last_segname = "dmap";
804 }
805 else
806 last_segname = "reg";
807 }
808 else
809 last_segname = "dmem";
810 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
811 break;
fee8ec00
SR
812 }
813
814 default:
815 /* OOPS! */
816 last_segname = "scrap";
817 return State.mem.fault;
818 }
819
820 if (*memory == NULL)
821 {
822 *memory = calloc (1, SEGMENT_SIZE);
823 if (*memory == NULL)
052d9a54
SR
824 {
825 (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n");
826 return State.mem.fault;
827 }
fee8ec00
SR
828 }
829
830 offset = (phys_addr % SEGMENT_SIZE);
831 raw = *memory + offset;
832 return raw;
833}
834
835/* Transfer data to/from simulated memory. Since a bug in either the
836 simulated program or in gdb or the simulator itself may cause a
837 bogus address to be passed in, we need to do some sanity checking
838 on addresses to make sure they are within bounds. When an address
839 fails the bounds check, treat it as a zero length read/write rather
840 than aborting the entire run. */
841
842static int
843xfer_mem (SIM_ADDR virt,
052d9a54
SR
844 unsigned char *buffer,
845 int size,
846 int write_p)
fee8ec00
SR
847{
848 uint8 *memory;
849 unsigned long phys;
850 int phys_size;
851 phys_size = sim_cr16_translate_addr (virt, size, &phys, NULL,
052d9a54 852 dmap_register, imap_register);
fee8ec00
SR
853 if (phys_size == 0)
854 return 0;
855
856 memory = map_memory (phys);
857
858#ifdef DEBUG
859 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
860 {
861 (*cr16_callback->printf_filtered)
052d9a54
SR
862 (cr16_callback,
863 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
864 (write_p ? "write" : "read"),
865 phys_size, virt, last_from,
866 phys, last_to,
867 (long) memory, last_segname);
fee8ec00
SR
868 }
869#endif
870
871 if (write_p)
872 {
873 memcpy (memory, buffer, phys_size);
874 }
875 else
876 {
877 memcpy (buffer, memory, phys_size);
878 }
879
880 return phys_size;
881}
882
883
884int
885sim_write (sd, addr, buffer, size)
886 SIM_DESC sd;
887 SIM_ADDR addr;
5558e7e6 888 const unsigned char *buffer;
fee8ec00
SR
889 int size;
890{
891 /* FIXME: this should be performing a virtual transfer */
892 return xfer_mem( addr, buffer, size, 1);
893}
894
895int
896sim_read (sd, addr, buffer, size)
897 SIM_DESC sd;
898 SIM_ADDR addr;
899 unsigned char *buffer;
900 int size;
901{
902 /* FIXME: this should be performing a virtual transfer */
903 return xfer_mem( addr, buffer, size, 0);
904}
905
fee8ec00
SR
906SIM_DESC
907sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct bfd *abfd, char **argv)
908{
909 struct simops *s;
052d9a54 910 struct hash_entry *h;
fee8ec00
SR
911 static int init_p = 0;
912 char **p;
913
914 sim_kind = kind;
915 cr16_callback = callback;
916 myname = argv[0];
917 old_segment_mapping = 0;
918
919 /* NOTE: This argument parsing is only effective when this function
920 is called by GDB. Standalone argument parsing is handled by
921 sim/common/run.c. */
922#if 0
923 for (p = argv + 1; *p; ++p)
924 {
925 if (strcmp (*p, "-oldseg") == 0)
052d9a54 926 old_segment_mapping = 1;
fee8ec00
SR
927#ifdef DEBUG
928 else if (strcmp (*p, "-t") == 0)
052d9a54 929 cr16_debug = DEBUG;
fee8ec00 930 else if (strncmp (*p, "-t", 2) == 0)
052d9a54 931 cr16_debug = atoi (*p + 2);
fee8ec00
SR
932#endif
933 else
052d9a54 934 (*cr16_callback->printf_filtered) (cr16_callback, "ERROR: unsupported option(s): %s\n",*p);
fee8ec00
SR
935 }
936#endif
937
052d9a54
SR
938 /* put all the opcodes in the hash table. */
939 if (!init_p++)
940 {
941 for (s = Simops; s->func; s++)
942 {
943 switch(32 - s->mask)
944 {
945 case 0x4:
946 h = &hash_table[hash(s->opcode, 0)];
947 break;
948
949 case 0x7:
950 if (((s->opcode << 1) >> 4) != 0)
951 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
952 else
953 h = &hash_table[hash((s->opcode << 1), 0)];
954 break;
955
956 case 0x8:
957 if ((s->opcode >> 4) != 0)
958 h = &hash_table[hash(s->opcode >> 4, 0)];
959 else
960 h = &hash_table[hash(s->opcode, 0)];
961 break;
962
963 case 0x9:
964 if (((s->opcode >> 1) >> 4) != 0)
965 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
966 else
967 h = &hash_table[hash((s->opcode >> 1), 0)];
968 break;
969
970 case 0xa:
971 if ((s->opcode >> 8) != 0)
972 h = &hash_table[hash(s->opcode >> 8, 0)];
973 else if ((s->opcode >> 4) != 0)
974 h = &hash_table[hash(s->opcode >> 4, 0)];
975 else
976 h = &hash_table[hash(s->opcode, 0)];
977 break;
978
979 case 0xc:
980 if ((s->opcode >> 8) != 0)
981 h = &hash_table[hash(s->opcode >> 8, 0)];
982 else if ((s->opcode >> 4) != 0)
983 h = &hash_table[hash(s->opcode >> 4, 0)];
984 else
985 h = &hash_table[hash(s->opcode, 0)];
986 break;
987
988 case 0xd:
989 if (((s->opcode >> 1) >> 8) != 0)
990 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
991 else if (((s->opcode >> 1) >> 4) != 0)
992 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
993 else
994 h = &hash_table[hash((s->opcode >>1), 0)];
995 break;
996
997 case 0x10:
998 if ((s->opcode >> 0xc) != 0)
999 h = &hash_table[hash(s->opcode >> 12, 0)];
1000 else if ((s->opcode >> 8) != 0)
1001 h = &hash_table[hash(s->opcode >> 8, 0)];
1002 else if ((s->opcode >> 4) != 0)
1003 h = &hash_table[hash(s->opcode >> 4, 0)];
1004 else
1005 h = &hash_table[hash(s->opcode, 0)];
1006 break;
1007
1008 case 0x14:
1009 if ((s->opcode >> 16) != 0)
1010 h = &hash_table[hash(s->opcode >> 16, 0)];
1011 else if ((s->opcode >> 12) != 0)
1012 h = &hash_table[hash(s->opcode >> 12, 0)];
1013 else if ((s->opcode >> 8) != 0)
1014 h = &hash_table[hash(s->opcode >> 8, 0)];
1015 else if ((s->opcode >> 4) != 0)
1016 h = &hash_table[hash(s->opcode >> 4, 0)];
1017 else
1018 h = &hash_table[hash(s->opcode, 0)];
1019 break;
1020 default:
1021 break;
1022 }
1023
1024 /* go to the last entry in the chain. */
1025 while (h->next)
1026 h = h->next;
1027
1028 if (h->ops)
1029 {
1030 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
1031 if (!h->next)
1032 perror ("malloc failure");
1033
1034 h = h->next;
1035 }
1036 h->ops = s;
1037 h->mask = s->mask;
1038 h->opcode = s->opcode;
1039 h->format = s->format;
1040 h->size = s->size;
1041 }
1042 }
1043
fee8ec00
SR
1044 /* reset the processor state */
1045 if (!State.mem.data[0])
1046 sim_size (1);
1047 sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
1048
1049 /* Fudge our descriptor. */
1050 return (SIM_DESC) 1;
1051}
1052
1053
1054void
1055sim_close (sd, quitting)
1056 SIM_DESC sd;
1057 int quitting;
1058{
1059 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1060 {
1061 bfd_close (prog_bfd);
1062 prog_bfd = NULL;
1063 prog_bfd_was_opened_p = 0;
1064 }
1065}
1066
1067void
1068sim_set_profile (int n)
1069{
1070 (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile %d\n",n);
1071}
1072
1073void
1074sim_set_profile_size (int n)
1075{
1076 (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile_size %d\n",n);
1077}
1078
1079uint8 *
1080dmem_addr (uint32 offset)
1081{
1082 unsigned long phys;
1083 uint8 *mem;
1084 int phys_size;
1085
1086 /* Note: DMEM address range is 0..0x10000. Calling code can compute
1087 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
1088 is uint16 this is modulo'ed onto 0x0e5d. */
1089
1090 phys_size = sim_cr16_translate_dmap_addr (offset, 1, &phys, NULL,
052d9a54 1091 dmap_register);
fee8ec00
SR
1092 if (phys_size == 0)
1093 {
1094 mem = State.mem.fault;
1095 }
1096 else
1097 mem = map_memory (phys);
1098#ifdef DEBUG
1099 if ((cr16_debug & DEBUG_MEMORY))
1100 {
1101 (*cr16_callback->printf_filtered)
052d9a54
SR
1102 (cr16_callback,
1103 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1104 offset, last_from,
1105 phys, phys_size, last_to,
1106 (long) mem, last_segname);
fee8ec00
SR
1107 }
1108#endif
1109 return mem;
1110}
1111
1112uint8 *
1113imem_addr (uint32 offset)
1114{
1115 unsigned long phys;
1116 uint8 *mem;
1117 int phys_size = sim_cr16_translate_imap_addr (offset, 1, &phys, NULL,
052d9a54 1118 imap_register);
fee8ec00
SR
1119 if (phys_size == 0)
1120 {
1121 return State.mem.fault;
1122 }
1123 mem = map_memory (phys);
1124#ifdef DEBUG
1125 if ((cr16_debug & DEBUG_MEMORY))
1126 {
1127 (*cr16_callback->printf_filtered)
052d9a54
SR
1128 (cr16_callback,
1129 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1130 offset, last_from,
1131 phys, phys_size, last_to,
1132 (long) mem, last_segname);
fee8ec00
SR
1133 }
1134#endif
1135 return mem;
1136}
1137
1138static int stop_simulator = 0;
1139
1140int
1141sim_stop (sd)
1142 SIM_DESC sd;
1143{
1144 stop_simulator = 1;
1145 return 1;
1146}
1147
1148
1149/* Run (or resume) the program. */
1150void
1151sim_resume (SIM_DESC sd, int step, int siggnal)
1152{
052d9a54
SR
1153 uint32 curr_ins_size = 0;
1154 uint64 mcode = 0;
fee8ec00
SR
1155 uint8 *iaddr;
1156
1157#ifdef DEBUG
1158// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1159#endif
1160
1161 State.exception = 0;
1162 if (step)
1163 sim_stop (sd);
1164
1165 switch (siggnal)
1166 {
1167 case 0:
1168 break;
1169#ifdef SIGBUS
1170 case SIGBUS:
1171#endif
1172 case SIGSEGV:
1173 SET_PC (PC);
1174 SET_PSR (PSR);
1175 JMP (AE_VECTOR_START);
1176 SLOT_FLUSH ();
1177 break;
1178 case SIGILL:
1179 SET_PC (PC);
1180 SET_PSR (PSR);
1181 SET_HW_PSR ((PSR & (PSR_C_BIT)));
1182 JMP (RIE_VECTOR_START);
1183 SLOT_FLUSH ();
1184 break;
1185 default:
1186 /* just ignore it */
1187 break;
1188 }
1189
1190 do
1191 {
1192 iaddr = imem_addr ((uint32)PC);
fee8ec00 1193 if (iaddr == State.mem.fault)
052d9a54 1194 {
5a06d7c4 1195#ifdef SIGBUS
052d9a54 1196 State.exception = SIGBUS;
5a06d7c4
MF
1197#else
1198 State.exception = SIGSEGV;
1199#endif
052d9a54
SR
1200 break;
1201 }
fee8ec00
SR
1202
1203 mcode = get_longword( iaddr );
1204
1205 State.pc_changed = 0;
1206
052d9a54 1207 curr_ins_size = do_run(mcode);
fee8ec00
SR
1208
1209#if CR16_DEBUG
1210 (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
1211#endif
fee8ec00 1212
fee8ec00 1213 if (!State.pc_changed)
052d9a54
SR
1214 {
1215 if (curr_ins_size == 0)
1216 {
1217 State.exception = SIG_CR16_EXIT; /* exit trap */
1218 break;
1219 }
1220 else
1221 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
1222 }
1223
fee8ec00 1224#if 0
052d9a54
SR
1225 /* Check for a breakpoint trap on this instruction. This
1226 overrides any pending branches or loops */
fee8ec00 1227 if (PSR_DB && PC == DBS)
052d9a54
SR
1228 {
1229 SET_BPC (PC);
1230 SET_BPSR (PSR);
1231 SET_PC (SDBT_VECTOR_START);
1232 }
fee8ec00
SR
1233#endif
1234
1235 /* Writeback all the DATA / PC changes */
1236 SLOT_FLUSH ();
1237
1238#ifdef NEED_UI_LOOP_HOOK
1239 if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
052d9a54
SR
1240 {
1241 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1242 deprecated_ui_loop_hook (0);
1243 }
fee8ec00
SR
1244#endif /* NEED_UI_LOOP_HOOK */
1245 }
1246 while ( !State.exception && !stop_simulator);
1247
1248 if (step && !State.exception)
1249 State.exception = SIGTRAP;
1250}
1251
1252void
1253sim_set_trace (void)
1254{
1255#ifdef DEBUG
1256 cr16_debug = DEBUG;
1257#endif
1258}
1259
1260void
1261sim_info (SIM_DESC sd, int verbose)
1262{
1263 char buf1[40];
1264 char buf2[40];
1265 char buf3[40];
1266 char buf4[40];
1267 char buf5[40];
1268#if 0
052d9a54
SR
1269 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1270 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1271 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1272 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1273 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1274
1275 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1276 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1277 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1278 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1279 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1280
1281 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1282 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1283 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1284 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1285 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1286 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1287 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1288 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1289 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1290 unsigned long total = (unknown + left_total + right_total + ins_long);
1291
1292 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1293 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1294 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1295 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1296 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1297 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
fee8ec00
SR
1298
1299 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1300 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1301 size, add_commas (buf1, sizeof (buf1), left_total),
1302 normal_size, add_commas (buf2, sizeof (buf2), left),
1303 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1304 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1305 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
fee8ec00
SR
1306
1307 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1308 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1309 size, add_commas (buf1, sizeof (buf1), right_total),
1310 normal_size, add_commas (buf2, sizeof (buf2), right),
1311 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1312 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1313 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
fee8ec00
SR
1314
1315 if (ins_long)
1316 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1317 "executed %*s long instruction(s)\n",
1318 size, add_commas (buf1, sizeof (buf1), ins_long));
fee8ec00
SR
1319
1320 if (parallel)
1321 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1322 "executed %*s parallel instruction(s)\n",
1323 size, add_commas (buf1, sizeof (buf1), parallel));
fee8ec00
SR
1324
1325 if (leftright)
1326 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1327 "executed %*s instruction(s) encoded L->R\n",
1328 size, add_commas (buf1, sizeof (buf1), leftright));
fee8ec00
SR
1329
1330 if (rightleft)
1331 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1332 "executed %*s instruction(s) encoded R->L\n",
1333 size, add_commas (buf1, sizeof (buf1), rightleft));
fee8ec00
SR
1334
1335 if (unknown)
1336 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1337 "executed %*s unknown instruction(s)\n",
1338 size, add_commas (buf1, sizeof (buf1), unknown));
fee8ec00
SR
1339
1340 if (cond_true)
1341 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1342 "executed %*s instruction(s) due to EXExxx condition being true\n",
1343 size, add_commas (buf1, sizeof (buf1), cond_true));
fee8ec00
SR
1344
1345 if (cond_false)
1346 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1347 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1348 size, add_commas (buf1, sizeof (buf1), cond_false));
fee8ec00
SR
1349
1350 if (cond_jump)
1351 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1352 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1353 size, add_commas (buf1, sizeof (buf1), cond_jump));
fee8ec00
SR
1354
1355 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1356 "executed %*s cycle(s)\n",
1357 size, add_commas (buf1, sizeof (buf1), cycles));
fee8ec00
SR
1358
1359 (*cr16_callback->printf_filtered) (cr16_callback,
052d9a54
SR
1360 "executed %*s total instructions\n",
1361 size, add_commas (buf1, sizeof (buf1), total));
fee8ec00
SR
1362#endif
1363}
1364
1365SIM_RC
1366sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
1367{
1368 bfd_vma start_address;
1369
1370 /* reset all state information */
1371 memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
1372
1373 /* There was a hack here to copy the values of argc and argv into r0
1374 and r1. The values were also saved into some high memory that
1375 won't be overwritten by the stack (0x7C00). The reason for doing
1376 this was to allow the 'run' program to accept arguments. Without
1377 the hack, this is not possible anymore. If the simulator is run
1378 from the debugger, arguments cannot be passed in, so this makes
1379 no difference. */
1380
1381 /* set PC */
1382 if (abfd != NULL)
1383 start_address = bfd_get_start_address (abfd);
1384 else
1385 start_address = 0x0;
1386#ifdef DEBUG
1387 if (cr16_debug)
1388 (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1389#endif
1390 SET_CREG (PC_CR, start_address);
1391
1392 SLOT_FLUSH ();
1393 return SIM_RC_OK;
1394}
1395
1396
1397void
1398sim_set_callbacks (p)
1399 host_callback *p;
1400{
1401 cr16_callback = p;
1402}
1403
1404void
1405sim_stop_reason (sd, reason, sigrc)
1406 SIM_DESC sd;
1407 enum sim_stop *reason;
1408 int *sigrc;
1409{
1410/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1411
1412 switch (State.exception)
1413 {
052d9a54 1414 case SIG_CR16_STOP: /* stop instruction */
fee8ec00
SR
1415 *reason = sim_stopped;
1416 *sigrc = 0;
1417 break;
1418
052d9a54 1419 case SIG_CR16_EXIT: /* exit trap */
fee8ec00
SR
1420 *reason = sim_exited;
1421 *sigrc = GPR (2);
1422 break;
1423
1424 case SIG_CR16_BUS:
1425 *reason = sim_stopped;
a493e3e2 1426 *sigrc = GDB_SIGNAL_BUS;
fee8ec00
SR
1427 break;
1428//
1429// case SIG_CR16_IAD:
1430// *reason = sim_stopped;
a493e3e2 1431// *sigrc = GDB_SIGNAL_IAD;
fee8ec00
SR
1432// break;
1433
052d9a54 1434 default: /* some signal */
fee8ec00
SR
1435 *reason = sim_stopped;
1436 if (stop_simulator && !State.exception)
a493e3e2 1437 *sigrc = GDB_SIGNAL_INT;
fee8ec00 1438 else
052d9a54 1439 *sigrc = State.exception;
fee8ec00
SR
1440 break;
1441 }
1442
1443 stop_simulator = 0;
1444}
1445
1446int
1447sim_fetch_register (sd, rn, memory, length)
1448 SIM_DESC sd;
1449 int rn;
1450 unsigned char *memory;
1451 int length;
1452{
1453 int size;
1454 switch ((enum sim_cr16_regs) rn)
1455 {
1456 case SIM_CR16_R0_REGNUM:
1457 case SIM_CR16_R1_REGNUM:
1458 case SIM_CR16_R2_REGNUM:
1459 case SIM_CR16_R3_REGNUM:
1460 case SIM_CR16_R4_REGNUM:
1461 case SIM_CR16_R5_REGNUM:
1462 case SIM_CR16_R6_REGNUM:
1463 case SIM_CR16_R7_REGNUM:
1464 case SIM_CR16_R8_REGNUM:
1465 case SIM_CR16_R9_REGNUM:
1466 case SIM_CR16_R10_REGNUM:
1467 case SIM_CR16_R11_REGNUM:
1468 WRITE_16 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1469 size = 2;
1470 break;
1471 case SIM_CR16_R12_REGNUM:
1472 case SIM_CR16_R13_REGNUM:
1473 case SIM_CR16_R14_REGNUM:
1474 case SIM_CR16_R15_REGNUM:
1475 //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1476 write_longword (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1477 size = 4;
1478 break;
1479 case SIM_CR16_PC_REGNUM:
1480 case SIM_CR16_ISP_REGNUM:
1481 case SIM_CR16_USP_REGNUM:
1482 case SIM_CR16_INTBASE_REGNUM:
1483 case SIM_CR16_PSR_REGNUM:
1484 case SIM_CR16_CFG_REGNUM:
1485 case SIM_CR16_DBS_REGNUM:
1486 case SIM_CR16_DCR_REGNUM:
1487 case SIM_CR16_DSR_REGNUM:
1488 case SIM_CR16_CAR0_REGNUM:
1489 case SIM_CR16_CAR1_REGNUM:
1490 //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1491 write_longword (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1492 size = 4;
1493 break;
1494 default:
1495 size = 0;
1496 break;
1497 }
1498 return size;
1499}
1500
1501int
1502sim_store_register (sd, rn, memory, length)
1503 SIM_DESC sd;
1504 int rn;
1505 unsigned char *memory;
1506 int length;
1507{
1508 int size;
1509 switch ((enum sim_cr16_regs) rn)
1510 {
1511 case SIM_CR16_R0_REGNUM:
1512 case SIM_CR16_R1_REGNUM:
1513 case SIM_CR16_R2_REGNUM:
1514 case SIM_CR16_R3_REGNUM:
1515 case SIM_CR16_R4_REGNUM:
1516 case SIM_CR16_R5_REGNUM:
1517 case SIM_CR16_R6_REGNUM:
1518 case SIM_CR16_R7_REGNUM:
1519 case SIM_CR16_R8_REGNUM:
1520 case SIM_CR16_R9_REGNUM:
1521 case SIM_CR16_R10_REGNUM:
1522 case SIM_CR16_R11_REGNUM:
1523 SET_GPR (rn - SIM_CR16_R0_REGNUM, READ_16 (memory));
1524 size = 2;
1525 break;
1526 case SIM_CR16_R12_REGNUM:
1527 case SIM_CR16_R13_REGNUM:
1528 case SIM_CR16_R14_REGNUM:
1529 case SIM_CR16_R15_REGNUM:
1530 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, get_longword (memory));
1531 size = 4;
1532 break;
1533 case SIM_CR16_PC_REGNUM:
1534 case SIM_CR16_ISP_REGNUM:
1535 case SIM_CR16_USP_REGNUM:
1536 case SIM_CR16_INTBASE_REGNUM:
1537 case SIM_CR16_PSR_REGNUM:
1538 case SIM_CR16_CFG_REGNUM:
1539 case SIM_CR16_DBS_REGNUM:
1540 case SIM_CR16_DCR_REGNUM:
1541 case SIM_CR16_DSR_REGNUM:
1542 case SIM_CR16_CAR0_REGNUM:
1543 case SIM_CR16_CAR1_REGNUM:
1544 SET_CREG (rn - SIM_CR16_PC_REGNUM, get_longword (memory));
1545 size = 4;
1546 break;
1547 default:
1548 size = 0;
1549 break;
1550 }
1551 SLOT_FLUSH ();
1552 return size;
1553}
1554
4881a75b 1555char **
3cb2ab1a 1556sim_complete_command (SIM_DESC sd, const char *text, const char *word)
4881a75b
MF
1557{
1558 return NULL;
1559}
fee8ec00
SR
1560
1561void
1562sim_do_command (sd, cmd)
1563 SIM_DESC sd;
1564 char *cmd;
1565{
1566 (*cr16_callback->printf_filtered) (cr16_callback, "sim_do_command: %s\n",cmd);
1567}
1568
1569SIM_RC
1570sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
1571{
1572 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1573
1574 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1575 {
1576 bfd_close (prog_bfd);
1577 prog_bfd_was_opened_p = 0;
1578 }
1579 prog_bfd = sim_load_file (sd, myname, cr16_callback, prog, abfd,
052d9a54
SR
1580 sim_kind == SIM_OPEN_DEBUG,
1581 1/*LMA*/, sim_write);
fee8ec00
SR
1582 if (prog_bfd == NULL)
1583 return SIM_RC_FAIL;
1584 prog_bfd_was_opened_p = abfd == NULL;
1585 return SIM_RC_OK;
1586}