]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/cr16/interp.c
sim: cr16: convert to common sim memory modules
[thirdparty/binutils-gdb.git] / sim / cr16 / interp.c
CommitLineData
fee8ec00 1/* Simulation code for the CR16 processor.
32d0add0 2 Copyright (C) 2008-2015 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"
5aedb83b 21#include <inttypes.h>
fee8ec00 22#include <signal.h>
26687999
MF
23#include <stdlib.h>
24#include <string.h>
fee8ec00
SR
25#include "bfd.h"
26#include "gdb/callback.h"
27#include "gdb/remote-sim.h"
28
247ac9ee
MF
29#include "sim-main.h"
30#include "sim-options.h"
31
fee8ec00
SR
32#include "gdb/sim-cr16.h"
33#include "gdb/signals.h"
34#include "opcode/cr16.h"
35
fee8ec00
SR
36int cr16_debug;
37
fee8ec00 38host_callback *cr16_callback;
fee8ec00
SR
39
40uint32 OP[4];
41uint32 sign_flag;
42
267b3b8e 43static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size);
bdca5ee4 44static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops);
fee8ec00 45
052d9a54
SR
46#define MAX_HASH 16
47
48struct hash_entry
49{
50 struct hash_entry *next;
51 uint32 opcode;
52 uint32 mask;
53 int format;
54 int size;
55 struct simops *ops;
56};
57
58struct hash_entry hash_table[MAX_HASH+1];
59
60INLINE static long
61hash(unsigned long long insn, int format)
62{
63 unsigned int i = 4, tmp;
64 if (format)
65 {
66 while ((insn >> i) != 0) i +=4;
67
68 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
69 }
70 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
71}
72
73
74INLINE static struct hash_entry *
267b3b8e 75lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64 ins, int size)
052d9a54
SR
76{
77 uint32 mask;
78 struct hash_entry *h;
79
80 h = &hash_table[hash(ins,1)];
81
82
83 mask = (((1 << (32 - h->mask)) -1) << h->mask);
84
85 /* Adjuest mask for branch with 2 word instructions. */
86 if ((h->ops->mnimonic != NULL) &&
87 ((streq(h->ops->mnimonic,"b") && h->size == 2)))
88 mask = 0xff0f0000;
89
90
91 while ((ins & mask) != (BIN(h->opcode, h->mask)))
92 {
93 if (h->next == NULL)
94 {
95 State.exception = SIGILL;
96 State.pc_changed = 1; /* Don't increment the PC. */
97 return NULL;
98 }
99 h = h->next;
100
101 mask = (((1 << (32 - h->mask)) -1) << h->mask);
102 /* Adjuest mask for branch with 2 word instructions. */
103 if ((streq(h->ops->mnimonic,"b")) && h->size == 2)
104 mask = 0xff0f0000;
105
106 }
107 return (h);
108}
fee8ec00
SR
109
110INLINE static void
052d9a54 111get_operands (operand_desc *s, uint64 ins, int isize, int nops)
fee8ec00
SR
112{
113 uint32 i, opn = 0, start_bit = 0, op_type = 0;
114 int32 op_size = 0, mask = 0;
115
116 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
117 ins = ins >> 16;
118
052d9a54 119 for (i=0; i < 4; ++i,++opn)
fee8ec00 120 {
052d9a54 121 if (s[opn].op_type == dummy) break;
fee8ec00 122
052d9a54 123 op_type = s[opn].op_type;
fee8ec00
SR
124 start_bit = s[opn].shift;
125 op_size = cr16_optab[op_type].bit_size;
126
127 switch (op_type)
052d9a54 128 {
fee8ec00 129 case imm3: case imm4: case imm5: case imm6:
052d9a54
SR
130 {
131 if (isize == 1)
132 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
fee8ec00 133 else
052d9a54
SR
134 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
135
136 if (OP[i] & ((long)1 << (op_size -1)))
137 {
138 sign_flag = 1;
139 OP[i] = ~(OP[i]) + 1;
140 }
141 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
fee8ec00 142 }
052d9a54 143 break;
fee8ec00
SR
144
145 case uimm3: case uimm3_1: case uimm4_1:
052d9a54
SR
146 switch (isize)
147 {
148 case 1:
149 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
150 case 2:
151 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
152 default: /* for case 3. */
153 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
154 break;
155 }
156 break;
fee8ec00
SR
157
158 case uimm4:
052d9a54
SR
159 switch (isize)
160 {
161 case 1:
162 if (start_bit == 20)
163 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
164 else
165 OP[i] = (ins & ((1 << op_size) -1));
166 break;
167 case 2:
168 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
169 break;
170 case 3:
171 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
172 break;
173 default:
174 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
175 break;
176 }
177 break;
fee8ec00
SR
178
179 case imm16: case uimm16:
180 OP[i] = ins & 0xFFFF;
052d9a54 181 break;
fee8ec00
SR
182
183 case uimm20: case imm20:
052d9a54
SR
184 OP[i] = ins & (((long)1 << op_size) - 1);
185 break;
fee8ec00
SR
186
187 case imm32: case uimm32:
188 OP[i] = ins & 0xFFFFFFFF;
052d9a54 189 break;
fee8ec00 190
052d9a54 191 case uimm5: break; /*NOT USED. */
fee8ec00
SR
192 OP[i] = ins & ((1 << op_size) - 1); break;
193
194 case disps5:
195 OP[i] = (ins >> 4) & ((1 << 4) - 1);
196 OP[i] = (OP[i] * 2) + 2;
052d9a54
SR
197 if (OP[i] & ((long)1 << 5))
198 {
199 sign_flag = 1;
200 OP[i] = ~(OP[i]) + 1;
201 OP[i] = (unsigned long int)(OP[i] & 0x1F);
202 }
203 break;
204
205 case dispe9:
206 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
207 OP[i] <<= 1;
208 if (OP[i] & ((long)1 << 8))
209 {
210 sign_flag = 1;
211 OP[i] = ~(OP[i]) + 1;
212 OP[i] = (unsigned long int)(OP[i] & 0xFF);
213 }
214 break;
215
216 case disps17:
217 OP[i] = (ins & 0xFFFF);
218 if (OP[i] & 1)
219 {
220 OP[i] = (OP[i] & 0xFFFE);
221 sign_flag = 1;
222 OP[i] = ~(OP[i]) + 1;
223 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
fee8ec00 224 }
052d9a54
SR
225 break;
226
227 case disps25:
228 if (isize == 2)
229 OP[i] = (ins & 0xFFFFFF);
230 else
231 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
232 (((ins >> 16) & 0xf) << 20);
233
234 if (OP[i] & 1)
235 {
236 OP[i] = (OP[i] & 0xFFFFFE);
237 sign_flag = 1;
238 OP[i] = ~(OP[i]) + 1;
239 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
fee8ec00 240 }
052d9a54 241 break;
fee8ec00
SR
242
243 case abs20:
052d9a54 244 if (isize == 3)
fee8ec00 245 OP[i] = (ins) & 0xFFFFF;
052d9a54 246 else
fee8ec00 247 OP[i] = (ins >> start_bit) & 0xFFFFF;
052d9a54 248 break;
fee8ec00 249 case abs24:
052d9a54
SR
250 if (isize == 3)
251 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
252 | (((ins >> 24) & 0xf) << 16));
253 else
254 OP[i] = (ins >> 16) & 0xFFFFFF;
255 break;
fee8ec00
SR
256
257 case rra:
258 case rbase: break; /* NOT USED. */
259 case rbase_disps20: case rbase_dispe20:
260 case rpbase_disps20: case rpindex_disps20:
052d9a54
SR
261 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
262 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
263 break;
fee8ec00 264 case rpbase_disps0:
052d9a54
SR
265 OP[i] = 0; /* 4 bit disp const. */
266 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
267 break;
fee8ec00 268 case rpbase_dispe4:
052d9a54
SR
269 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
270 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
271 break;
fee8ec00 272 case rpbase_disps4:
052d9a54
SR
273 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
274 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
275 break;
fee8ec00 276 case rpbase_disps16:
052d9a54
SR
277 OP[i] = (ins) & 0xFFFF;
278 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
279 break;
fee8ec00 280 case rpindex_disps0:
052d9a54
SR
281 OP[i] = 0;
282 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
283 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
284 break;
fee8ec00 285 case rpindex_disps14:
052d9a54
SR
286 OP[i] = (ins) & 0x3FFF;
287 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */
288 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
fee8ec00
SR
289 case rindex7_abs20:
290 case rindex8_abs20:
052d9a54
SR
291 OP[i] = (ins) & 0xFFFFF;
292 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */
293 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */
294 break;
fee8ec00 295 case regr: case regp: case pregr: case pregrp:
052d9a54
SR
296 switch(isize)
297 {
298 case 1:
299 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
300 else if (start_bit == 16) OP[i] = ins & 0xF;
301 break;
302 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
303 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
304 }
305 break;
fee8ec00 306 case cc:
052d9a54
SR
307 {
308 if (isize == 1) OP[i] = (ins >> 4) & 0xF;
309 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF;
310 else OP[i] = (ins >> (start_bit + 16)) & 0xF;
311 break;
312 }
313 default: break;
314 }
fee8ec00 315
052d9a54 316 /* For ESC on uimm4_1 operand. */
fee8ec00 317 if (op_type == uimm4_1)
052d9a54
SR
318 if (OP[i] == 9)
319 OP[i] = -1;
320
321 /* For increment by 1. */
322 if ((op_type == pregr) || (op_type == pregrp))
323 OP[i] += 1;
fee8ec00
SR
324 }
325 /* FIXME: for tracing, update values that need to be updated each
326 instruction decode cycle */
fee8ec00 327 State.trace.psw = PSR;
fee8ec00
SR
328}
329
052d9a54 330static int
267b3b8e 331do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode)
fee8ec00 332{
247ac9ee 333 host_callback *cr16_callback = STATE_CALLBACK (sd);
fee8ec00 334 struct simops *s= Simops;
052d9a54 335 struct hash_entry *h;
fee8ec00
SR
336 char func[12]="\0";
337#ifdef DEBUG
338 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
052d9a54 339 (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
fee8ec00 340#endif
267b3b8e
MF
341
342 h = lookup_hash (sd, cpu, mcode, 1);
052d9a54 343
5aedb83b
MF
344 if ((h == NULL) || (h->opcode == 0))
345 return 0;
052d9a54 346
761e171a
MF
347 if (h->size == 3)
348 mcode = (mcode << 16) | RW (PC + 4);
052d9a54
SR
349
350 /* Re-set OP list. */
fee8ec00
SR
351 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
352
052d9a54
SR
353 /* for push/pop/pushrtn with RA instructions. */
354 if ((h->format & REG_LIST) && (mcode & 0x800000))
355 OP[2] = 1; /* Set 1 for RA operand. */
fee8ec00 356
052d9a54
SR
357 /* numops == 0 means, no operands. */
358 if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
359 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
fee8ec00 360
052d9a54
SR
361 //State.ins_type = h->flags;
362
267b3b8e 363 (h->ops->func) (sd, cpu);
052d9a54
SR
364
365 return h->size;
fee8ec00
SR
366}
367
27b97b40
MF
368static sim_cia
369cr16_pc_get (sim_cpu *cpu)
370{
371 return PC;
372}
373
374static void
375cr16_pc_set (sim_cpu *cpu, sim_cia pc)
376{
267b3b8e 377 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
378 SET_PC (pc);
379}
380
247ac9ee
MF
381static void
382free_state (SIM_DESC sd)
383{
384 if (STATE_MODULES (sd) != NULL)
385 sim_module_uninstall (sd);
386 sim_cpu_free_all (sd);
387 sim_state_free (sd);
388}
389
c2270cd8
MF
390static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int);
391static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int);
392
fee8ec00 393SIM_DESC
247ac9ee 394sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, char **argv)
fee8ec00
SR
395{
396 struct simops *s;
052d9a54 397 struct hash_entry *h;
fee8ec00
SR
398 static int init_p = 0;
399 char **p;
247ac9ee
MF
400 int i;
401 SIM_DESC sd = sim_state_alloc (kind, cb);
402 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
403
404 /* The cpu data is kept in a separately allocated chunk of memory. */
405 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
406 {
407 free_state (sd);
408 return 0;
409 }
410
411 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
412 {
413 free_state (sd);
414 return 0;
415 }
416
417 /* getopt will print the error message so we just have to exit if this fails.
418 FIXME: Hmmm... in the case of gdb we need getopt to call
419 print_filtered. */
420 if (sim_parse_args (sd, argv) != SIM_RC_OK)
421 {
422 free_state (sd);
423 return 0;
424 }
425
426 /* Check for/establish the a reference program image. */
427 if (sim_analyze_program (sd,
428 (STATE_PROG_ARGV (sd) != NULL
429 ? *STATE_PROG_ARGV (sd)
430 : NULL), abfd) != SIM_RC_OK)
431 {
432 free_state (sd);
433 return 0;
434 }
435
436 /* Configure/verify the target byte order and other runtime
437 configuration options. */
438 if (sim_config (sd) != SIM_RC_OK)
439 {
440 sim_module_uninstall (sd);
441 return 0;
442 }
443
444 if (sim_post_argv_init (sd) != SIM_RC_OK)
445 {
446 /* Uninstall the modules to avoid memory leaks,
447 file descriptor leaks, etc. */
448 sim_module_uninstall (sd);
449 return 0;
450 }
fee8ec00 451
27b97b40
MF
452 /* CPU specific initialization. */
453 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
454 {
455 SIM_CPU *cpu = STATE_CPU (sd, i);
456
c2270cd8
MF
457 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
458 CPU_REG_STORE (cpu) = cr16_reg_store;
27b97b40
MF
459 CPU_PC_FETCH (cpu) = cr16_pc_get;
460 CPU_PC_STORE (cpu) = cr16_pc_set;
461 }
462
761e171a
MF
463 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently
464 handle that. Revisit if anyone ever implements operating mode. */
465 /* cr16 memory: There are three separate cr16 memory regions IMEM,
466 UMEM and DMEM. The IMEM and DMEM are further broken down into
467 blocks (very like VM pages). This might not match the hardware,
468 but it matches what the toolchain currently expects. Ugh. */
469 sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024);
470
247ac9ee 471 cr16_callback = cb;
fee8ec00 472
052d9a54
SR
473 /* put all the opcodes in the hash table. */
474 if (!init_p++)
475 {
476 for (s = Simops; s->func; s++)
477 {
478 switch(32 - s->mask)
479 {
480 case 0x4:
481 h = &hash_table[hash(s->opcode, 0)];
482 break;
483
484 case 0x7:
485 if (((s->opcode << 1) >> 4) != 0)
486 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
487 else
488 h = &hash_table[hash((s->opcode << 1), 0)];
489 break;
490
491 case 0x8:
492 if ((s->opcode >> 4) != 0)
493 h = &hash_table[hash(s->opcode >> 4, 0)];
494 else
495 h = &hash_table[hash(s->opcode, 0)];
496 break;
497
498 case 0x9:
499 if (((s->opcode >> 1) >> 4) != 0)
500 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
501 else
502 h = &hash_table[hash((s->opcode >> 1), 0)];
503 break;
504
505 case 0xa:
506 if ((s->opcode >> 8) != 0)
507 h = &hash_table[hash(s->opcode >> 8, 0)];
508 else if ((s->opcode >> 4) != 0)
509 h = &hash_table[hash(s->opcode >> 4, 0)];
510 else
511 h = &hash_table[hash(s->opcode, 0)];
512 break;
513
514 case 0xc:
515 if ((s->opcode >> 8) != 0)
516 h = &hash_table[hash(s->opcode >> 8, 0)];
517 else if ((s->opcode >> 4) != 0)
518 h = &hash_table[hash(s->opcode >> 4, 0)];
519 else
520 h = &hash_table[hash(s->opcode, 0)];
521 break;
522
523 case 0xd:
524 if (((s->opcode >> 1) >> 8) != 0)
525 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
526 else if (((s->opcode >> 1) >> 4) != 0)
527 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
528 else
529 h = &hash_table[hash((s->opcode >>1), 0)];
530 break;
531
532 case 0x10:
533 if ((s->opcode >> 0xc) != 0)
534 h = &hash_table[hash(s->opcode >> 12, 0)];
535 else if ((s->opcode >> 8) != 0)
536 h = &hash_table[hash(s->opcode >> 8, 0)];
537 else if ((s->opcode >> 4) != 0)
538 h = &hash_table[hash(s->opcode >> 4, 0)];
539 else
540 h = &hash_table[hash(s->opcode, 0)];
541 break;
542
543 case 0x14:
544 if ((s->opcode >> 16) != 0)
545 h = &hash_table[hash(s->opcode >> 16, 0)];
546 else if ((s->opcode >> 12) != 0)
547 h = &hash_table[hash(s->opcode >> 12, 0)];
548 else if ((s->opcode >> 8) != 0)
549 h = &hash_table[hash(s->opcode >> 8, 0)];
550 else if ((s->opcode >> 4) != 0)
551 h = &hash_table[hash(s->opcode >> 4, 0)];
552 else
553 h = &hash_table[hash(s->opcode, 0)];
554 break;
555 default:
556 break;
557 }
558
559 /* go to the last entry in the chain. */
560 while (h->next)
561 h = h->next;
562
563 if (h->ops)
564 {
565 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
566 if (!h->next)
567 perror ("malloc failure");
568
569 h = h->next;
570 }
571 h->ops = s;
572 h->mask = s->mask;
573 h->opcode = s->opcode;
574 h->format = s->format;
575 h->size = s->size;
576 }
577 }
578
247ac9ee 579 return sd;
fee8ec00
SR
580}
581
fee8ec00
SR
582static int stop_simulator = 0;
583
584int
5aedb83b 585sim_stop (SIM_DESC sd)
fee8ec00
SR
586{
587 stop_simulator = 1;
588 return 1;
589}
590
591
592/* Run (or resume) the program. */
593void
594sim_resume (SIM_DESC sd, int step, int siggnal)
595{
267b3b8e 596 SIM_CPU *cpu = STATE_CPU (sd, 0);
052d9a54 597 uint32 curr_ins_size = 0;
761e171a 598 uint64 mcode;
fee8ec00
SR
599
600#ifdef DEBUG
601// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
602#endif
603
604 State.exception = 0;
605 if (step)
606 sim_stop (sd);
607
608 switch (siggnal)
609 {
610 case 0:
611 break;
612#ifdef SIGBUS
613 case SIGBUS:
614#endif
615 case SIGSEGV:
616 SET_PC (PC);
617 SET_PSR (PSR);
618 JMP (AE_VECTOR_START);
619 SLOT_FLUSH ();
620 break;
621 case SIGILL:
622 SET_PC (PC);
623 SET_PSR (PSR);
624 SET_HW_PSR ((PSR & (PSR_C_BIT)));
625 JMP (RIE_VECTOR_START);
626 SLOT_FLUSH ();
627 break;
628 default:
629 /* just ignore it */
630 break;
631 }
632
633 do
634 {
761e171a
MF
635 mcode = RLW (PC);
636
fee8ec00
SR
637 State.pc_changed = 0;
638
267b3b8e 639 curr_ins_size = do_run (sd, cpu, mcode);
fee8ec00
SR
640
641#if CR16_DEBUG
642 (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
643#endif
fee8ec00 644
fee8ec00 645 if (!State.pc_changed)
052d9a54
SR
646 {
647 if (curr_ins_size == 0)
648 {
649 State.exception = SIG_CR16_EXIT; /* exit trap */
650 break;
651 }
652 else
653 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
654 }
655
fee8ec00 656#if 0
052d9a54
SR
657 /* Check for a breakpoint trap on this instruction. This
658 overrides any pending branches or loops */
fee8ec00 659 if (PSR_DB && PC == DBS)
052d9a54
SR
660 {
661 SET_BPC (PC);
662 SET_BPSR (PSR);
663 SET_PC (SDBT_VECTOR_START);
664 }
fee8ec00
SR
665#endif
666
667 /* Writeback all the DATA / PC changes */
668 SLOT_FLUSH ();
fee8ec00
SR
669 }
670 while ( !State.exception && !stop_simulator);
671
672 if (step && !State.exception)
673 State.exception = SIGTRAP;
674}
675
fee8ec00
SR
676SIM_RC
677sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
678{
679 bfd_vma start_address;
680
681 /* reset all state information */
761e171a 682 memset (&State, 0, sizeof (State));
fee8ec00
SR
683
684 /* There was a hack here to copy the values of argc and argv into r0
685 and r1. The values were also saved into some high memory that
686 won't be overwritten by the stack (0x7C00). The reason for doing
687 this was to allow the 'run' program to accept arguments. Without
688 the hack, this is not possible anymore. If the simulator is run
689 from the debugger, arguments cannot be passed in, so this makes
690 no difference. */
691
692 /* set PC */
693 if (abfd != NULL)
694 start_address = bfd_get_start_address (abfd);
695 else
696 start_address = 0x0;
697#ifdef DEBUG
698 if (cr16_debug)
699 (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
700#endif
267b3b8e
MF
701 {
702 SIM_CPU *cpu = STATE_CPU (sd, 0);
703 SET_CREG (PC_CR, start_address);
704 }
fee8ec00
SR
705
706 SLOT_FLUSH ();
707 return SIM_RC_OK;
708}
709
fee8ec00 710void
5aedb83b 711sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
fee8ec00
SR
712{
713/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
714
715 switch (State.exception)
716 {
052d9a54 717 case SIG_CR16_STOP: /* stop instruction */
fee8ec00
SR
718 *reason = sim_stopped;
719 *sigrc = 0;
720 break;
721
052d9a54 722 case SIG_CR16_EXIT: /* exit trap */
fee8ec00
SR
723 *reason = sim_exited;
724 *sigrc = GPR (2);
725 break;
726
727 case SIG_CR16_BUS:
728 *reason = sim_stopped;
a493e3e2 729 *sigrc = GDB_SIGNAL_BUS;
fee8ec00
SR
730 break;
731//
732// case SIG_CR16_IAD:
733// *reason = sim_stopped;
a493e3e2 734// *sigrc = GDB_SIGNAL_IAD;
fee8ec00
SR
735// break;
736
052d9a54 737 default: /* some signal */
fee8ec00
SR
738 *reason = sim_stopped;
739 if (stop_simulator && !State.exception)
a493e3e2 740 *sigrc = GDB_SIGNAL_INT;
fee8ec00 741 else
052d9a54 742 *sigrc = State.exception;
fee8ec00
SR
743 break;
744 }
745
746 stop_simulator = 0;
747}
748
c2270cd8
MF
749static uint32
750cr16_extract_unsigned_integer (unsigned char *addr, int len)
751{
752 uint32 retval;
753 unsigned char * p;
754 unsigned char * startaddr = (unsigned char *)addr;
755 unsigned char * endaddr = startaddr + len;
756
757 retval = 0;
758
759 for (p = endaddr; p > startaddr;)
760 retval = (retval << 8) | *--p;
761
762 return retval;
763}
764
765static void
766cr16_store_unsigned_integer (unsigned char *addr, int len, uint32 val)
767{
768 unsigned char *p;
769 unsigned char *startaddr = addr;
770 unsigned char *endaddr = startaddr + len;
771
772 for (p = startaddr; p < endaddr;)
773 {
774 *p++ = val & 0xff;
775 val >>= 8;
776 }
777}
778
779static int
780cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00
SR
781{
782 int size;
783 switch ((enum sim_cr16_regs) rn)
784 {
785 case SIM_CR16_R0_REGNUM:
786 case SIM_CR16_R1_REGNUM:
787 case SIM_CR16_R2_REGNUM:
788 case SIM_CR16_R3_REGNUM:
789 case SIM_CR16_R4_REGNUM:
790 case SIM_CR16_R5_REGNUM:
791 case SIM_CR16_R6_REGNUM:
792 case SIM_CR16_R7_REGNUM:
793 case SIM_CR16_R8_REGNUM:
794 case SIM_CR16_R9_REGNUM:
795 case SIM_CR16_R10_REGNUM:
796 case SIM_CR16_R11_REGNUM:
c2270cd8 797 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
798 size = 2;
799 break;
800 case SIM_CR16_R12_REGNUM:
801 case SIM_CR16_R13_REGNUM:
802 case SIM_CR16_R14_REGNUM:
803 case SIM_CR16_R15_REGNUM:
c2270cd8 804 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
805 size = 4;
806 break;
807 case SIM_CR16_PC_REGNUM:
808 case SIM_CR16_ISP_REGNUM:
809 case SIM_CR16_USP_REGNUM:
810 case SIM_CR16_INTBASE_REGNUM:
811 case SIM_CR16_PSR_REGNUM:
812 case SIM_CR16_CFG_REGNUM:
813 case SIM_CR16_DBS_REGNUM:
814 case SIM_CR16_DCR_REGNUM:
815 case SIM_CR16_DSR_REGNUM:
816 case SIM_CR16_CAR0_REGNUM:
817 case SIM_CR16_CAR1_REGNUM:
c2270cd8 818 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
fee8ec00
SR
819 size = 4;
820 break;
821 default:
822 size = 0;
823 break;
824 }
825 return size;
826}
c2270cd8
MF
827
828static int
829cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00 830{
267b3b8e 831 SIM_DESC sd = CPU_STATE (cpu);
fee8ec00
SR
832 int size;
833 switch ((enum sim_cr16_regs) rn)
834 {
835 case SIM_CR16_R0_REGNUM:
836 case SIM_CR16_R1_REGNUM:
837 case SIM_CR16_R2_REGNUM:
838 case SIM_CR16_R3_REGNUM:
839 case SIM_CR16_R4_REGNUM:
840 case SIM_CR16_R5_REGNUM:
841 case SIM_CR16_R6_REGNUM:
842 case SIM_CR16_R7_REGNUM:
843 case SIM_CR16_R8_REGNUM:
844 case SIM_CR16_R9_REGNUM:
845 case SIM_CR16_R10_REGNUM:
846 case SIM_CR16_R11_REGNUM:
c2270cd8 847 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
848 size = 2;
849 break;
850 case SIM_CR16_R12_REGNUM:
851 case SIM_CR16_R13_REGNUM:
852 case SIM_CR16_R14_REGNUM:
853 case SIM_CR16_R15_REGNUM:
c2270cd8 854 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
855 size = 4;
856 break;
857 case SIM_CR16_PC_REGNUM:
858 case SIM_CR16_ISP_REGNUM:
859 case SIM_CR16_USP_REGNUM:
860 case SIM_CR16_INTBASE_REGNUM:
861 case SIM_CR16_PSR_REGNUM:
862 case SIM_CR16_CFG_REGNUM:
863 case SIM_CR16_DBS_REGNUM:
864 case SIM_CR16_DCR_REGNUM:
865 case SIM_CR16_DSR_REGNUM:
866 case SIM_CR16_CAR0_REGNUM:
867 case SIM_CR16_CAR1_REGNUM:
c2270cd8 868 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
fee8ec00
SR
869 size = 4;
870 break;
871 default:
872 size = 0;
873 break;
874 }
875 SLOT_FLUSH ();
876 return size;
877}