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