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