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