]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/cr16/cr16_sim.h
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / cr16 / cr16_sim.h
CommitLineData
fee8ec00 1/* Simulation code for the CR16 processor.
8acc9f48 2 Copyright (C) 2008-2013 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
8e26b0f4
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/>. */
19
fee8ec00
SR
20
21#include "config.h"
22#include <stdio.h>
23#include <ctype.h>
24#include <limits.h>
25#include "ansidecl.h"
26#include "gdb/callback.h"
27#include "opcode/cr16.h"
28#include "bfd.h"
29
30#define DEBUG_TRACE 0x00000001
31#define DEBUG_VALUES 0x00000002
32#define DEBUG_LINE_NUMBER 0x00000004
33#define DEBUG_MEMSIZE 0x00000008
34#define DEBUG_INSTRUCTION 0x00000010
35#define DEBUG_TRAP 0x00000020
36#define DEBUG_MEMORY 0x00000040
37
38#ifndef DEBUG
39#define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER)
40#endif
41
42extern int cr16_debug;
43
44#include "gdb/remote-sim.h"
45#include "sim-config.h"
46#include "sim-types.h"
47
48typedef unsigned8 uint8;
49typedef signed8 int8;
50typedef unsigned16 uint16;
51typedef signed16 int16;
52typedef unsigned32 uint32;
53typedef signed32 int32;
54typedef unsigned64 uint64;
55typedef signed64 int64;
56
57/* FIXME: CR16 defines */
58typedef uint16 reg_t;
59typedef uint32 creg_t;
60
61struct simops
62{
8e26b0f4
SR
63 char mnimonic[12];
64 uint32 size;
65 uint32 mask;
66 uint32 opcode;
fee8ec00 67 int format;
8e26b0f4 68 char fname[12];
fee8ec00
SR
69 void (*func)();
70 int numops;
8e26b0f4 71 operand_desc operands[4];
fee8ec00
SR
72};
73
74enum _ins_type
75{
76 INS_UNKNOWN, /* unknown instruction */
77 INS_NO_TYPE_INS,
78 INS_ARITH_INS,
79 INS_LD_STOR_INS,
80 INS_BRANCH_INS,
81 INS_ARITH_BYTE_INS,
82 INS_SHIFT_INS,
83 INS_BRANCH_NEQ_INS,
84 INS_STOR_IMM_INS,
85 INS_CSTBIT_INS,
86 INS_MAX
87};
88
89extern unsigned long ins_type_counters[ (int)INS_MAX ];
90
91enum {
92 SP_IDX = 15,
93};
94
95/* Write-back slots */
96union slot_data {
97 unsigned_1 _1;
98 unsigned_2 _2;
99 unsigned_4 _4;
100};
101struct slot {
102 void *dest;
103 int size;
104 union slot_data data;
105 union slot_data mask;
106};
107enum {
108 NR_SLOTS = 16
109};
110#define SLOT (State.slot)
111#define SLOT_NR (State.slot_nr)
112#define SLOT_PEND_MASK(DEST, MSK, VAL) \
113 do \
114 { \
115 SLOT[SLOT_NR].dest = &(DEST); \
116 SLOT[SLOT_NR].size = sizeof (DEST); \
117 switch (sizeof (DEST)) \
118 { \
119 case 1: \
120 SLOT[SLOT_NR].data._1 = (unsigned_1) (VAL); \
121 SLOT[SLOT_NR].mask._1 = (unsigned_1) (MSK); \
122 break; \
123 case 2: \
124 SLOT[SLOT_NR].data._2 = (unsigned_2) (VAL); \
125 SLOT[SLOT_NR].mask._2 = (unsigned_2) (MSK); \
126 break; \
127 case 4: \
128 SLOT[SLOT_NR].data._4 = (unsigned_4) (VAL); \
129 SLOT[SLOT_NR].mask._4 = (unsigned_4) (MSK); \
130 break; \
131 } \
132 SLOT_NR = (SLOT_NR + 1); \
133 } \
134 while (0)
135#define SLOT_PEND(DEST, VAL) SLOT_PEND_MASK(DEST, 0, VAL)
136#define SLOT_DISCARD() (SLOT_NR = 0)
137#define SLOT_FLUSH() \
138 do \
139 { \
140 int i; \
141 for (i = 0; i < SLOT_NR; i++) \
142 { \
143 switch (SLOT[i].size) \
144 { \
145 case 1: \
146 *(unsigned_1*) SLOT[i].dest &= SLOT[i].mask._1; \
147 *(unsigned_1*) SLOT[i].dest |= SLOT[i].data._1; \
148 break; \
149 case 2: \
150 *(unsigned_2*) SLOT[i].dest &= SLOT[i].mask._2; \
151 *(unsigned_2*) SLOT[i].dest |= SLOT[i].data._2; \
152 break; \
153 case 4: \
154 *(unsigned_4*) SLOT[i].dest &= SLOT[i].mask._4; \
155 *(unsigned_4*) SLOT[i].dest |= SLOT[i].data._4; \
156 break; \
157 } \
158 } \
159 SLOT_NR = 0; \
160 } \
161 while (0)
162#define SLOT_DUMP() \
163 do \
164 { \
165 int i; \
166 for (i = 0; i < SLOT_NR; i++) \
167 { \
168 switch (SLOT[i].size) \
169 { \
170 case 1: \
171 printf ("SLOT %d *0x%08lx & 0x%02x | 0x%02x\n", i, \
172 (long) SLOT[i].dest, \
173 (unsigned) SLOT[i].mask._1, \
174 (unsigned) SLOT[i].data._1); \
175 break; \
176 case 2: \
177 printf ("SLOT %d *0x%08lx & 0x%04x | 0x%04x\n", i, \
178 (long) SLOT[i].dest, \
179 (unsigned) SLOT[i].mask._2, \
180 (unsigned) SLOT[i].data._2); \
181 break; \
182 case 4: \
183 printf ("SLOT %d *0x%08lx & 0x%08x | 0x%08x\n", i, \
184 (long) SLOT[i].dest, \
185 (unsigned) SLOT[i].mask._4, \
186 (unsigned) SLOT[i].data._4); \
187 break; \
188 case 8: \
189 printf ("SLOT %d *0x%08lx & 0x%08x%08x | 0x%08x%08x\n", i, \
190 (long) SLOT[i].dest, \
191 (unsigned) (SLOT[i].mask._8 >> 32), \
192 (unsigned) SLOT[i].mask._8, \
193 (unsigned) (SLOT[i].data._8 >> 32), \
194 (unsigned) SLOT[i].data._8); \
195 break; \
196 } \
197 } \
198 } \
199 while (0)
200
201/* cr16 memory: There are three separate cr16 memory regions IMEM,
202 UMEM and DMEM. The IMEM and DMEM are further broken down into
203 blocks (very like VM pages). */
204
205enum
206{
207 IMAP_BLOCK_SIZE = 0x2000000,
208 DMAP_BLOCK_SIZE = 0x4000000
209};
210
211/* Implement the three memory regions using sparse arrays. Allocate
212 memory using ``segments''. A segment must be at least as large as
213 a BLOCK - ensures that an access that doesn't cross a block
214 boundary can't cross a segment boundary */
215
216enum
217{
218 SEGMENT_SIZE = 0x2000000, /* 128KB - MAX(IMAP_BLOCK_SIZE,DMAP_BLOCK_SIZE) */
219 IMEM_SEGMENTS = 8, /* 1MB */
220 DMEM_SEGMENTS = 8, /* 1MB */
221 UMEM_SEGMENTS = 128 /* 16MB */
222};
223
224struct cr16_memory
225{
226 uint8 *insn[IMEM_SEGMENTS];
227 uint8 *data[DMEM_SEGMENTS];
228 uint8 *unif[UMEM_SEGMENTS];
229 uint8 fault[16];
230};
231
232struct _state
233{
234 creg_t regs[16]; /* general-purpose registers */
235#define GPR(N) (State.regs[(N)] + 0)
236#define SET_GPR(N,VAL) (State.regs[(N)] = (VAL))
237
238#define GPR32(N) \
239 (N < 12) ? \
240 ((((uint16) State.regs[(N) + 1]) << 16) | (uint16) State.regs[(N)]) \
241 : GPR (N)
242
243#define SET_GPR32(N,VAL) do { \
244 if (N < 11) \
245 { SET_GPR (N + 1, (VAL) >> 16); SET_GPR (N, ((VAL) & 0xffff));} \
246 else { if ( N == 11) \
247 { SET_GPR (N + 1, ((GPR32 (12)) & 0xffff0000)|((VAL) >> 16)); \
248 SET_GPR (N, ((VAL) & 0xffff));} \
249 else SET_GPR (N, (VAL));} \
250 } while (0)
251
252 creg_t cregs[16]; /* control registers */
253#define CREG(N) (State.cregs[(N)] + 0)
254#define SET_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 0)
255#define SET_HW_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 1)
256
257 reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */
258#define HELD_SP(N) (State.sp[(N)] + 0)
259#define SET_HELD_SP(N,VAL) SLOT_PEND (State.sp[(N)], (VAL))
260
261 /* writeback info */
262 struct slot slot[NR_SLOTS];
263 int slot_nr;
264
265 /* trace data */
266 struct {
267 uint16 psw;
268 } trace;
269
270 uint8 exe;
271 int exception;
272 int pc_changed;
273
274 /* NOTE: everything below this line is not reset by
275 sim_create_inferior() */
276
277 struct cr16_memory mem;
278
279 enum _ins_type ins_type;
280
281} State;
282
283
284extern host_callback *cr16_callback;
285extern uint32 OP[4];
286extern uint32 sign_flag;
287extern struct simops Simops[];
288extern asection *text;
289extern bfd_vma text_start;
290extern bfd_vma text_end;
291extern bfd *prog_bfd;
292
293enum
294{
295 PC_CR = 0,
296 BDS_CR = 1,
297 BSR_CR = 2,
298 DCR_CR = 3,
299 CAR0_CR = 5,
300 CAR1_CR = 7,
301 CFG_CR = 9,
302 PSR_CR = 10,
303 INTBASE_CR = 11,
304 ISP_CR = 13,
305 USP_CR = 15
306};
307
308enum
309{
310 PSR_I_BIT = 0x0800,
311 PSR_P_BIT = 0x0400,
312 PSR_E_BIT = 0x0200,
8e26b0f4 313 PSR_N_BIT = 0x0080,
fee8ec00
SR
314 PSR_Z_BIT = 0x0040,
315 PSR_F_BIT = 0x0020,
8e26b0f4 316 PSR_U_BIT = 0x0008,
fee8ec00
SR
317 PSR_L_BIT = 0x0004,
318 PSR_T_BIT = 0x0002,
8e26b0f4 319 PSR_C_BIT = 0x0001
fee8ec00
SR
320};
321
322#define PSR CREG (PSR_CR)
323#define SET_PSR(VAL) SET_CREG (PSR_CR, (VAL))
324#define SET_HW_PSR(VAL) SET_HW_CREG (PSR_CR, (VAL))
325#define SET_PSR_BIT(MASK,VAL) move_to_cr (PSR_CR, ~((creg_t) MASK), (VAL) ? (MASK) : 0, 1)
326
327#define PSR_SM ((PSR & PSR_SM_BIT) != 0)
328#define SET_PSR_SM(VAL) SET_PSR_BIT (PSR_SM_BIT, (VAL))
329
330#define PSR_I ((PSR & PSR_I_BIT) != 0)
331#define SET_PSR_I(VAL) SET_PSR_BIT (PSR_I_BIT, (VAL))
332
333#define PSR_DB ((PSR & PSR_DB_BIT) != 0)
334#define SET_PSR_DB(VAL) SET_PSR_BIT (PSR_DB_BIT, (VAL))
335
336#define PSR_P ((PSR & PSR_P_BIT) != 0)
337#define SET_PSR_P(VAL) SET_PSR_BIT (PSR_P_BIT, (VAL))
338
339#define PSR_E ((PSR & PSR_E_BIT) != 0)
340#define SET_PSR_E(VAL) SET_PSR_BIT (PSR_E_BIT, (VAL))
341
342#define PSR_N ((PSR & PSR_N_BIT) != 0)
343#define SET_PSR_N(VAL) SET_PSR_BIT (PSR_N_BIT, (VAL))
344
345#define PSR_Z ((PSR & PSR_Z_BIT) != 0)
346#define SET_PSR_Z(VAL) SET_PSR_BIT (PSR_Z_BIT, (VAL))
347
348#define PSR_F ((PSR & PSR_F_BIT) != 0)
349#define SET_PSR_F(VAL) SET_PSR_BIT (PSR_F_BIT, (VAL))
350
351#define PSR_U ((PSR & PSR_U_BIT) != 0)
352#define SET_PSR_U(VAL) SET_PSR_BIT (PSR_U_BIT, (VAL))
353
354#define PSR_L ((PSR & PSR_L_BIT) != 0)
355#define SET_PSR_L(VAL) SET_PSR_BIT (PSR_L_BIT, (VAL))
356
357#define PSR_T ((PSR & PSR_T_BIT) != 0)
358#define SET_PSR_T(VAL) SET_PSR_BIT (PSR_T_BIT, (VAL))
359
360#define PSR_C ((PSR & PSR_C_BIT) != 0)
361#define SET_PSR_C(VAL) SET_PSR_BIT (PSR_C_BIT, (VAL))
362
363/* See simopsc.:move_to_cr() for registers that can not be read-from
364 or assigned-to directly */
365
366#define PC CREG (PC_CR)
367#define SET_PC(VAL) SET_CREG (PC_CR, (VAL))
368//#define SET_PC(VAL) (State.cregs[PC_CR] = (VAL))
369
370#define BPSR CREG (BPSR_CR)
371#define SET_BPSR(VAL) SET_CREG (BPSR_CR, (VAL))
372
373#define BPC CREG (BPC_CR)
374#define SET_BPC(VAL) SET_CREG (BPC_CR, (VAL))
375
376#define DPSR CREG (DPSR_CR)
377#define SET_DPSR(VAL) SET_CREG (DPSR_CR, (VAL))
378
379#define DPC CREG (DPC_CR)
380#define SET_DPC(VAL) SET_CREG (DPC_CR, (VAL))
381
382#define RPT_C CREG (RPT_C_CR)
383#define SET_RPT_C(VAL) SET_CREG (RPT_C_CR, (VAL))
384
385#define RPT_S CREG (RPT_S_CR)
386#define SET_RPT_S(VAL) SET_CREG (RPT_S_CR, (VAL))
387
388#define RPT_E CREG (RPT_E_CR)
389#define SET_RPT_E(VAL) SET_CREG (RPT_E_CR, (VAL))
390
391#define MOD_S CREG (MOD_S_CR)
392#define SET_MOD_S(VAL) SET_CREG (MOD_S_CR, (VAL))
393
394#define MOD_E CREG (MOD_E_CR)
395#define SET_MOD_E(VAL) SET_CREG (MOD_E_CR, (VAL))
396
397#define IBA CREG (IBA_CR)
398#define SET_IBA(VAL) SET_CREG (IBA_CR, (VAL))
399
400
401#define SIG_CR16_STOP -1
402#define SIG_CR16_EXIT -2
403#define SIG_CR16_BUS -3
404#define SIG_CR16_IAD -4
405
406#define SEXT3(x) ((((x)&0x7)^(~3))+4)
407
408/* sign-extend a 4-bit number */
409#define SEXT4(x) ((((x)&0xf)^(~7))+8)
410
411/* sign-extend an 8-bit number */
412#define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80)
413
414/* sign-extend a 16-bit number */
415#define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000)
416
417/* sign-extend a 24-bit number */
418#define SEXT24(x) ((((x)&0xffffff)^(~0x7fffff))+0x800000)
419
420/* sign-extend a 32-bit number */
421#define SEXT32(x) ((((x)&0xffffffff)^(~0x7fffffff))+0x80000000)
422
423extern uint8 *dmem_addr (uint32 offset);
424extern uint8 *imem_addr PARAMS ((uint32));
425extern bfd_vma decode_pc PARAMS ((void));
426
427#define RB(x) (*(dmem_addr(x)))
428#define SB(addr,data) ( RB(addr) = (data & 0xff))
429
430#if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE)
431#define ENDIAN_INLINE static __inline__
432#include "endian.c"
433#undef ENDIAN_INLINE
434
435#else
436extern uint32 get_longword PARAMS ((uint8 *));
437extern uint16 get_word PARAMS ((uint8 *));
438extern int64 get_longlong PARAMS ((uint8 *));
439extern void write_word PARAMS ((uint8 *addr, uint16 data));
440extern void write_longword PARAMS ((uint8 *addr, uint32 data));
441extern void write_longlong PARAMS ((uint8 *addr, int64 data));
442#endif
443
444#define SW(addr,data) write_word(dmem_addr(addr),data)
445#define RW(x) get_word(dmem_addr(x))
446#define SLW(addr,data) write_longword(dmem_addr(addr),data)
447#define RLW(x) get_longword(dmem_addr(x))
448#define READ_16(x) get_word(x)
449#define WRITE_16(addr,data) write_word(addr,data)
450#define READ_64(x) get_longlong(x)
451#define WRITE_64(addr,data) write_longlong(addr,data)
452
453#define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0)
454
455#define RIE_VECTOR_START 0xffc2
456#define AE_VECTOR_START 0xffc3
457#define TRAP_VECTOR_START 0xffc4 /* vector for trap 0 */
458#define DBT_VECTOR_START 0xffd4
459#define SDBT_VECTOR_START 0xffd5
460
461#define INT_VECTOR_START 0xFFFE00 /*maskable interrupt - mapped to ICU */
462#define NMI_VECTOR_START 0xFFFF00 /*non-maskable interrupt;for observability*/
463#define ISE_VECTOR_START 0xFFFC00 /*in-system emulation trap */
464#define ADBG_VECTOR_START 0xFFFC02 /*alternate debug trap */
465#define ATRC_VECTOR_START 0xFFFC0C /*alternate trace trap */
466#define ABPT_VECTOR_START 0xFFFC0E /*alternate break point trap */
467
468
469/* Scedule a store of VAL into cr[CR]. MASK indicates the bits in
470 cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) |
471 (VAL & ~MASK)). In addition, unless PSR_HW_P, a VAL intended for
472 PSR is masked for zero bits. */
473
474extern creg_t move_to_cr (int cr, creg_t mask, creg_t val, int psw_hw_p);
5a06d7c4
MF
475
476#ifndef SIGTRAP
477#define SIGTRAP 5
478#endif
479/* Special purpose trap */
480#define TRAP_BREAKPOINT 8