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