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