cr16-sim.h revision 1.1.1.1 1 1.1 christos /* Simulation code for the CR16 processor.
2 1.1 christos Copyright (C) 2008-2024 Free Software Foundation, Inc.
3 1.1 christos Contributed by M Ranga Swami Reddy <MR.Swami.Reddy (at) nsc.com>
4 1.1 christos
5 1.1 christos This file is part of GDB, the GNU debugger.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3, or (at your option)
10 1.1 christos any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos
21 1.1 christos #include <stdio.h>
22 1.1 christos #include <ctype.h>
23 1.1 christos #include <limits.h>
24 1.1 christos #include "ansidecl.h"
25 1.1 christos #include "sim/callback.h"
26 1.1 christos #include "opcode/cr16.h"
27 1.1 christos #include "bfd.h"
28 1.1 christos #include "sim-main.h"
29 1.1 christos
30 1.1 christos #define DEBUG_TRACE 0x00000001
31 1.1 christos #define DEBUG_VALUES 0x00000002
32 1.1 christos #define DEBUG_LINE_NUMBER 0x00000004
33 1.1 christos #define DEBUG_MEMSIZE 0x00000008
34 1.1 christos #define DEBUG_INSTRUCTION 0x00000010
35 1.1 christos #define DEBUG_TRAP 0x00000020
36 1.1 christos #define DEBUG_MEMORY 0x00000040
37 1.1 christos
38 1.1 christos #ifndef DEBUG
39 1.1 christos #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER)
40 1.1 christos #endif
41 1.1 christos
42 1.1 christos extern int cr16_debug;
43 1.1 christos
44 1.1 christos #include "sim/sim.h"
45 1.1 christos #include "sim-config.h"
46 1.1 christos #include "sim-types.h"
47 1.1 christos
48 1.1 christos /* FIXME: CR16 defines */
49 1.1 christos typedef uint16_t reg_t;
50 1.1 christos typedef uint32_t creg_t;
51 1.1 christos
52 1.1 christos struct simops
53 1.1 christos {
54 1.1 christos char mnemonic[12];
55 1.1 christos uint32_t size;
56 1.1 christos uint32_t mask;
57 1.1 christos uint32_t opcode;
58 1.1 christos int format;
59 1.1 christos char fname[12];
60 1.1 christos void (*func)(SIM_DESC, SIM_CPU *);
61 1.1 christos int numops;
62 1.1 christos operand_desc operands[4];
63 1.1 christos };
64 1.1 christos
65 1.1 christos enum _ins_type
66 1.1 christos {
67 1.1 christos INS_UNKNOWN, /* unknown instruction */
68 1.1 christos INS_NO_TYPE_INS,
69 1.1 christos INS_ARITH_INS,
70 1.1 christos INS_LD_STOR_INS,
71 1.1 christos INS_BRANCH_INS,
72 1.1 christos INS_ARITH_BYTE_INS,
73 1.1 christos INS_SHIFT_INS,
74 1.1 christos INS_BRANCH_NEQ_INS,
75 1.1 christos INS_STOR_IMM_INS,
76 1.1 christos INS_CSTBIT_INS,
77 1.1 christos INS_MAX
78 1.1 christos };
79 1.1 christos
80 1.1 christos extern unsigned long ins_type_counters[ (int)INS_MAX ];
81 1.1 christos
82 1.1 christos enum {
83 1.1 christos SP_IDX = 15,
84 1.1 christos };
85 1.1 christos
86 1.1 christos /* Write-back slots */
87 1.1 christos union slot_data {
88 1.1 christos unsigned_1 _1;
89 1.1 christos unsigned_2 _2;
90 1.1 christos unsigned_4 _4;
91 1.1 christos };
92 1.1 christos struct slot {
93 1.1 christos void *dest;
94 1.1 christos int size;
95 1.1 christos union slot_data data;
96 1.1 christos union slot_data mask;
97 1.1 christos };
98 1.1 christos enum {
99 1.1 christos NR_SLOTS = 16
100 1.1 christos };
101 1.1 christos #define SLOT (State.slot)
102 1.1 christos #define SLOT_NR (State.slot_nr)
103 1.1 christos #define SLOT_PEND_MASK(DEST, MSK, VAL) \
104 1.1 christos do \
105 1.1 christos { \
106 1.1 christos SLOT[SLOT_NR].dest = &(DEST); \
107 1.1 christos SLOT[SLOT_NR].size = sizeof (DEST); \
108 1.1 christos switch (sizeof (DEST)) \
109 1.1 christos { \
110 1.1 christos case 1: \
111 1.1 christos SLOT[SLOT_NR].data._1 = (unsigned_1) (VAL); \
112 1.1 christos SLOT[SLOT_NR].mask._1 = (unsigned_1) (MSK); \
113 1.1 christos break; \
114 1.1 christos case 2: \
115 1.1 christos SLOT[SLOT_NR].data._2 = (unsigned_2) (VAL); \
116 1.1 christos SLOT[SLOT_NR].mask._2 = (unsigned_2) (MSK); \
117 1.1 christos break; \
118 1.1 christos case 4: \
119 1.1 christos SLOT[SLOT_NR].data._4 = (unsigned_4) (VAL); \
120 1.1 christos SLOT[SLOT_NR].mask._4 = (unsigned_4) (MSK); \
121 1.1 christos break; \
122 1.1 christos } \
123 1.1 christos SLOT_NR = (SLOT_NR + 1); \
124 1.1 christos } \
125 1.1 christos while (0)
126 1.1 christos #define SLOT_PEND(DEST, VAL) SLOT_PEND_MASK(DEST, 0, VAL)
127 1.1 christos #define SLOT_DISCARD() (SLOT_NR = 0)
128 1.1 christos #define SLOT_FLUSH() \
129 1.1 christos do \
130 1.1 christos { \
131 1.1 christos int i; \
132 1.1 christos for (i = 0; i < SLOT_NR; i++) \
133 1.1 christos { \
134 1.1 christos switch (SLOT[i].size) \
135 1.1 christos { \
136 1.1 christos case 1: \
137 1.1 christos *(unsigned_1*) SLOT[i].dest &= SLOT[i].mask._1; \
138 1.1 christos *(unsigned_1*) SLOT[i].dest |= SLOT[i].data._1; \
139 1.1 christos break; \
140 1.1 christos case 2: \
141 1.1 christos *(unsigned_2*) SLOT[i].dest &= SLOT[i].mask._2; \
142 1.1 christos *(unsigned_2*) SLOT[i].dest |= SLOT[i].data._2; \
143 1.1 christos break; \
144 1.1 christos case 4: \
145 1.1 christos *(unsigned_4*) SLOT[i].dest &= SLOT[i].mask._4; \
146 1.1 christos *(unsigned_4*) SLOT[i].dest |= SLOT[i].data._4; \
147 1.1 christos break; \
148 1.1 christos } \
149 1.1 christos } \
150 1.1 christos SLOT_NR = 0; \
151 1.1 christos } \
152 1.1 christos while (0)
153 1.1 christos #define SLOT_DUMP() \
154 1.1 christos do \
155 1.1 christos { \
156 1.1 christos int i; \
157 1.1 christos for (i = 0; i < SLOT_NR; i++) \
158 1.1 christos { \
159 1.1 christos switch (SLOT[i].size) \
160 1.1 christos { \
161 1.1 christos case 1: \
162 1.1 christos printf ("SLOT %d *0x%08lx & 0x%02x | 0x%02x\n", i, \
163 1.1 christos (long) SLOT[i].dest, \
164 1.1 christos (unsigned) SLOT[i].mask._1, \
165 1.1 christos (unsigned) SLOT[i].data._1); \
166 1.1 christos break; \
167 1.1 christos case 2: \
168 1.1 christos printf ("SLOT %d *0x%08lx & 0x%04x | 0x%04x\n", i, \
169 1.1 christos (long) SLOT[i].dest, \
170 1.1 christos (unsigned) SLOT[i].mask._2, \
171 1.1 christos (unsigned) SLOT[i].data._2); \
172 1.1 christos break; \
173 1.1 christos case 4: \
174 1.1 christos printf ("SLOT %d *0x%08lx & 0x%08x | 0x%08x\n", i, \
175 1.1 christos (long) SLOT[i].dest, \
176 1.1 christos (unsigned) SLOT[i].mask._4, \
177 1.1 christos (unsigned) SLOT[i].data._4); \
178 1.1 christos break; \
179 1.1 christos case 8: \
180 1.1 christos printf ("SLOT %d *0x%08lx & 0x%08x%08x | 0x%08x%08x\n", i, \
181 1.1 christos (long) SLOT[i].dest, \
182 1.1 christos (unsigned) (SLOT[i].mask._8 >> 32), \
183 1.1 christos (unsigned) SLOT[i].mask._8, \
184 1.1 christos (unsigned) (SLOT[i].data._8 >> 32), \
185 1.1 christos (unsigned) SLOT[i].data._8); \
186 1.1 christos break; \
187 1.1 christos } \
188 1.1 christos } \
189 1.1 christos } \
190 1.1 christos while (0)
191 1.1 christos
192 1.1 christos struct _state
193 1.1 christos {
194 1.1 christos creg_t regs[16]; /* general-purpose registers */
195 1.1 christos #define GPR(N) (State.regs[(N)] + 0)
196 1.1 christos #define SET_GPR(N,VAL) (State.regs[(N)] = (VAL))
197 1.1 christos
198 1.1 christos #define GPR32(N) \
199 1.1 christos (N < 12) ? \
200 1.1 christos ((((uint16_t) State.regs[(N) + 1]) << 16) | (uint16_t) State.regs[(N)]) \
201 1.1 christos : GPR (N)
202 1.1 christos
203 1.1 christos #define SET_GPR32(N,VAL) do { \
204 1.1 christos if (N < 11) \
205 1.1 christos { SET_GPR (N + 1, (VAL) >> 16); SET_GPR (N, ((VAL) & 0xffff));} \
206 1.1 christos else { if ( N == 11) \
207 1.1 christos { SET_GPR (N + 1, ((GPR32 (12)) & 0xffff0000)|((VAL) >> 16)); \
208 1.1 christos SET_GPR (N, ((VAL) & 0xffff));} \
209 1.1 christos else SET_GPR (N, (VAL));} \
210 1.1 christos } while (0)
211 1.1 christos
212 1.1 christos creg_t cregs[16]; /* control registers */
213 1.1 christos #define CREG(N) (State.cregs[(N)] + 0)
214 1.1 christos #define SET_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 0)
215 1.1 christos #define SET_HW_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 1)
216 1.1 christos
217 1.1 christos reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */
218 1.1 christos #define HELD_SP(N) (State.sp[(N)] + 0)
219 1.1 christos #define SET_HELD_SP(N,VAL) SLOT_PEND (State.sp[(N)], (VAL))
220 1.1 christos
221 1.1 christos /* writeback info */
222 1.1 christos struct slot slot[NR_SLOTS];
223 1.1 christos int slot_nr;
224 1.1 christos
225 1.1 christos /* trace data */
226 1.1 christos struct {
227 1.1 christos uint16_t psw;
228 1.1 christos } trace;
229 1.1 christos
230 1.1 christos int pc_changed;
231 1.1 christos
232 1.1 christos /* NOTE: everything below this line is not reset by
233 1.1 christos sim_create_inferior() */
234 1.1 christos
235 1.1 christos enum _ins_type ins_type;
236 1.1 christos
237 1.1 christos };
238 1.1 christos
239 1.1 christos extern struct _state State;
240 1.1 christos
241 1.1 christos
242 1.1 christos extern uint32_t OP[4];
243 1.1 christos extern uint32_t sign_flag;
244 1.1 christos extern struct simops Simops[];
245 1.1 christos
246 1.1 christos enum
247 1.1 christos {
248 1.1 christos PC_CR = 0,
249 1.1 christos BDS_CR = 1,
250 1.1 christos BSR_CR = 2,
251 1.1 christos DCR_CR = 3,
252 1.1 christos CAR0_CR = 5,
253 1.1 christos CAR1_CR = 7,
254 1.1 christos CFG_CR = 9,
255 1.1 christos PSR_CR = 10,
256 1.1 christos INTBASE_CR = 11,
257 1.1 christos ISP_CR = 13,
258 1.1 christos USP_CR = 15
259 1.1 christos };
260 1.1 christos
261 1.1 christos enum
262 1.1 christos {
263 1.1 christos PSR_I_BIT = 0x0800,
264 1.1 christos PSR_P_BIT = 0x0400,
265 1.1 christos PSR_E_BIT = 0x0200,
266 1.1 christos PSR_N_BIT = 0x0080,
267 1.1 christos PSR_Z_BIT = 0x0040,
268 1.1 christos PSR_F_BIT = 0x0020,
269 1.1 christos PSR_U_BIT = 0x0008,
270 1.1 christos PSR_L_BIT = 0x0004,
271 1.1 christos PSR_T_BIT = 0x0002,
272 1.1 christos PSR_C_BIT = 0x0001
273 1.1 christos };
274 1.1 christos
275 1.1 christos #define PSR CREG (PSR_CR)
276 1.1 christos #define SET_PSR(VAL) SET_CREG (PSR_CR, (VAL))
277 1.1 christos #define SET_HW_PSR(VAL) SET_HW_CREG (PSR_CR, (VAL))
278 1.1 christos #define SET_PSR_BIT(MASK,VAL) move_to_cr (sd, cpu, PSR_CR, ~((creg_t) MASK), (VAL) ? (MASK) : 0, 1)
279 1.1 christos
280 1.1 christos #define PSR_SM ((PSR & PSR_SM_BIT) != 0)
281 1.1 christos #define SET_PSR_SM(VAL) SET_PSR_BIT (PSR_SM_BIT, (VAL))
282 1.1 christos
283 1.1 christos #define PSR_I ((PSR & PSR_I_BIT) != 0)
284 1.1 christos #define SET_PSR_I(VAL) SET_PSR_BIT (PSR_I_BIT, (VAL))
285 1.1 christos
286 1.1 christos #define PSR_DB ((PSR & PSR_DB_BIT) != 0)
287 1.1 christos #define SET_PSR_DB(VAL) SET_PSR_BIT (PSR_DB_BIT, (VAL))
288 1.1 christos
289 1.1 christos #define PSR_P ((PSR & PSR_P_BIT) != 0)
290 1.1 christos #define SET_PSR_P(VAL) SET_PSR_BIT (PSR_P_BIT, (VAL))
291 1.1 christos
292 1.1 christos #define PSR_E ((PSR & PSR_E_BIT) != 0)
293 1.1 christos #define SET_PSR_E(VAL) SET_PSR_BIT (PSR_E_BIT, (VAL))
294 1.1 christos
295 1.1 christos #define PSR_N ((PSR & PSR_N_BIT) != 0)
296 1.1 christos #define SET_PSR_N(VAL) SET_PSR_BIT (PSR_N_BIT, (VAL))
297 1.1 christos
298 1.1 christos #define PSR_Z ((PSR & PSR_Z_BIT) != 0)
299 1.1 christos #define SET_PSR_Z(VAL) SET_PSR_BIT (PSR_Z_BIT, (VAL))
300 1.1 christos
301 1.1 christos #define PSR_F ((PSR & PSR_F_BIT) != 0)
302 1.1 christos #define SET_PSR_F(VAL) SET_PSR_BIT (PSR_F_BIT, (VAL))
303 1.1 christos
304 1.1 christos #define PSR_U ((PSR & PSR_U_BIT) != 0)
305 1.1 christos #define SET_PSR_U(VAL) SET_PSR_BIT (PSR_U_BIT, (VAL))
306 1.1 christos
307 1.1 christos #define PSR_L ((PSR & PSR_L_BIT) != 0)
308 1.1 christos #define SET_PSR_L(VAL) SET_PSR_BIT (PSR_L_BIT, (VAL))
309 1.1 christos
310 1.1 christos #define PSR_T ((PSR & PSR_T_BIT) != 0)
311 1.1 christos #define SET_PSR_T(VAL) SET_PSR_BIT (PSR_T_BIT, (VAL))
312 1.1 christos
313 1.1 christos #define PSR_C ((PSR & PSR_C_BIT) != 0)
314 1.1 christos #define SET_PSR_C(VAL) SET_PSR_BIT (PSR_C_BIT, (VAL))
315 1.1 christos
316 1.1 christos /* See simopsc.:move_to_cr() for registers that can not be read-from
317 1.1 christos or assigned-to directly */
318 1.1 christos
319 1.1 christos #define PC CREG (PC_CR)
320 1.1 christos #define SET_PC(VAL) SET_CREG (PC_CR, (VAL))
321 1.1 christos //#define SET_PC(VAL) (State.cregs[PC_CR] = (VAL))
322 1.1 christos
323 1.1 christos #define BPSR CREG (BPSR_CR)
324 1.1 christos #define SET_BPSR(VAL) SET_CREG (BPSR_CR, (VAL))
325 1.1 christos
326 1.1 christos #define BPC CREG (BPC_CR)
327 1.1 christos #define SET_BPC(VAL) SET_CREG (BPC_CR, (VAL))
328 1.1 christos
329 1.1 christos #define DPSR CREG (DPSR_CR)
330 1.1 christos #define SET_DPSR(VAL) SET_CREG (DPSR_CR, (VAL))
331 1.1 christos
332 1.1 christos #define DPC CREG (DPC_CR)
333 1.1 christos #define SET_DPC(VAL) SET_CREG (DPC_CR, (VAL))
334 1.1 christos
335 1.1 christos #define RPT_C CREG (RPT_C_CR)
336 1.1 christos #define SET_RPT_C(VAL) SET_CREG (RPT_C_CR, (VAL))
337 1.1 christos
338 1.1 christos #define RPT_S CREG (RPT_S_CR)
339 1.1 christos #define SET_RPT_S(VAL) SET_CREG (RPT_S_CR, (VAL))
340 1.1 christos
341 1.1 christos #define RPT_E CREG (RPT_E_CR)
342 1.1 christos #define SET_RPT_E(VAL) SET_CREG (RPT_E_CR, (VAL))
343 1.1 christos
344 1.1 christos #define MOD_S CREG (MOD_S_CR)
345 1.1 christos #define SET_MOD_S(VAL) SET_CREG (MOD_S_CR, (VAL))
346 1.1 christos
347 1.1 christos #define MOD_E CREG (MOD_E_CR)
348 1.1 christos #define SET_MOD_E(VAL) SET_CREG (MOD_E_CR, (VAL))
349 1.1 christos
350 1.1 christos #define IBA CREG (IBA_CR)
351 1.1 christos #define SET_IBA(VAL) SET_CREG (IBA_CR, (VAL))
352 1.1 christos
353 1.1 christos
354 1.1 christos #define SIG_CR16_STOP -1
355 1.1 christos #define SIG_CR16_EXIT -2
356 1.1 christos #define SIG_CR16_BUS -3
357 1.1 christos #define SIG_CR16_IAD -4
358 1.1 christos
359 1.1 christos /* TODO: Resolve conflicts with common headers. */
360 1.1 christos #undef SEXT8
361 1.1 christos #undef SEXT16
362 1.1 christos #undef SEXT32
363 1.1 christos
364 1.1 christos #define SEXT3(x) ((((x)&0x7)^(~3))+4)
365 1.1 christos
366 1.1 christos /* sign-extend a 4-bit number */
367 1.1 christos #define SEXT4(x) ((((x)&0xf)^(~7))+8)
368 1.1 christos
369 1.1 christos /* sign-extend an 8-bit number */
370 1.1 christos #define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80)
371 1.1 christos
372 1.1 christos /* sign-extend a 16-bit number */
373 1.1 christos #define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000)
374 1.1 christos
375 1.1 christos /* sign-extend a 24-bit number */
376 1.1 christos #define SEXT24(x) ((((x)&0xffffff)^(~0x7fffff))+0x800000)
377 1.1 christos
378 1.1 christos /* sign-extend a 32-bit number */
379 1.1 christos #define SEXT32(x) ((((x)&0xffffffff)^(~0x7fffffff))+0x80000000)
380 1.1 christos
381 1.1 christos #define SB(addr, data) sim_core_write_1 (cpu, PC, read_map, addr, data)
382 1.1 christos #define RB(addr) sim_core_read_1 (cpu, PC, read_map, addr)
383 1.1 christos #define SW(addr, data) sim_core_write_unaligned_2 (cpu, PC, read_map, addr, data)
384 1.1 christos #define RW(addr) sim_core_read_unaligned_2 (cpu, PC, read_map, addr)
385 1.1 christos #define SLW(addr, data) sim_core_write_unaligned_4 (cpu, PC, read_map, addr, data)
386 1.1 christos
387 1.1 christos /* Yes, this is as whacked as it looks. The sim currently reads little endian
388 1.1 christos for 16 bits, but then merge them like big endian to get 32 bits. */
389 1.1 christos static inline uint32_t get_longword (SIM_CPU *cpu, address_word addr)
390 1.1 christos {
391 1.1 christos return (RW (addr) << 16) | RW (addr + 2);
392 1.1 christos }
393 1.1 christos #define RLW(addr) get_longword (cpu, addr)
394 1.1 christos
395 1.1 christos #define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0)
396 1.1 christos
397 1.1 christos #define RIE_VECTOR_START 0xffc2
398 1.1 christos #define AE_VECTOR_START 0xffc3
399 1.1 christos #define TRAP_VECTOR_START 0xffc4 /* vector for trap 0 */
400 1.1 christos #define DBT_VECTOR_START 0xffd4
401 1.1 christos #define SDBT_VECTOR_START 0xffd5
402 1.1 christos
403 1.1 christos #define INT_VECTOR_START 0xFFFE00 /*maskable interrupt - mapped to ICU */
404 1.1 christos #define NMI_VECTOR_START 0xFFFF00 /*non-maskable interrupt;for observability*/
405 1.1 christos #define ISE_VECTOR_START 0xFFFC00 /*in-system emulation trap */
406 1.1 christos #define ADBG_VECTOR_START 0xFFFC02 /*alternate debug trap */
407 1.1 christos #define ATRC_VECTOR_START 0xFFFC0C /*alternate trace trap */
408 1.1 christos #define ABPT_VECTOR_START 0xFFFC0E /*alternate break point trap */
409 1.1 christos
410 1.1 christos
411 1.1 christos /* Scedule a store of VAL into cr[CR]. MASK indicates the bits in
412 1.1 christos cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) |
413 1.1 christos (VAL & ~MASK)). In addition, unless PSR_HW_P, a VAL intended for
414 1.1 christos PSR is masked for zero bits. */
415 1.1 christos
416 1.1 christos extern creg_t move_to_cr (SIM_DESC, SIM_CPU *, int cr, creg_t mask, creg_t val, int psw_hw_p);
417 1.1 christos
418 1.1 christos #ifndef SIGTRAP
419 1.1 christos #define SIGTRAP 5
420 1.1 christos #endif
421 1.1 christos /* Special purpose trap */
422 1.1 christos #define TRAP_BREAKPOINT 8
423