Commit | Line | Data |
---|---|---|
aa49c64f | 1 | #include "config.h" |
2934d1c9 MH |
2 | #include <stdio.h> |
3 | #include <ctype.h> | |
7eebfc62 | 4 | #include <limits.h> |
2934d1c9 | 5 | #include "ansidecl.h" |
87178dbd | 6 | #include "callback.h" |
2934d1c9 | 7 | #include "opcode/d10v.h" |
b30cdd35 | 8 | #include "bfd.h" |
2934d1c9 | 9 | |
7eebfc62 MM |
10 | #define DEBUG_TRACE 0x00000001 |
11 | #define DEBUG_VALUES 0x00000002 | |
5c255669 MM |
12 | #define DEBUG_LINE_NUMBER 0x00000004 |
13 | #define DEBUG_MEMSIZE 0x00000008 | |
14 | #define DEBUG_INSTRUCTION 0x00000010 | |
19431a02 | 15 | #define DEBUG_TRAP 0x00000020 |
5c255669 MM |
16 | |
17 | #ifndef DEBUG | |
18 | #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER) | |
19 | #endif | |
87178dbd | 20 | |
7eebfc62 | 21 | extern int d10v_debug; |
87178dbd | 22 | |
aa49c64f AC |
23 | #include "sim-types.h" |
24 | typedef unsigned8 uint8; | |
25 | typedef unsigned16 uint16; | |
26 | typedef signed16 int16; | |
27 | typedef unsigned32 uint32; | |
28 | typedef signed32 int32; | |
29 | typedef unsigned64 uint64; | |
30 | typedef signed64 int64; | |
7eebfc62 | 31 | |
2934d1c9 MH |
32 | /* FIXME: D10V defines */ |
33 | typedef uint16 reg_t; | |
34 | ||
35 | struct simops | |
36 | { | |
37 | long opcode; | |
aa49c64f | 38 | int is_long; |
2934d1c9 MH |
39 | long mask; |
40 | int format; | |
41 | int cycles; | |
42 | int unit; | |
43 | int exec_type; | |
44 | void (*func)(); | |
45 | int numops; | |
46 | int operands[9]; | |
47 | }; | |
48 | ||
87178dbd MM |
49 | enum _ins_type |
50 | { | |
aeb1f26b | 51 | INS_UNKNOWN, /* unknown instruction */ |
aeb1f26b MM |
52 | INS_COND_TRUE, /* # times EXExxx executed other instruction */ |
53 | INS_COND_FALSE, /* # times EXExxx did not execute other instruction */ | |
c422ecc7 | 54 | INS_COND_JUMP, /* # times JUMP skipped other instruction */ |
aeb1f26b | 55 | INS_CYCLES, /* # cycles */ |
c422ecc7 MH |
56 | INS_LONG, /* long instruction (both containers, ie FM == 11) */ |
57 | INS_LEFTRIGHT, /* # times instruction encoded as L -> R (ie, FM == 01) */ | |
58 | INS_RIGHTLEFT, /* # times instruction encoded as L <- R (ie, FM == 10) */ | |
59 | INS_PARALLEL, /* # times instruction encoded as L || R (ie, RM == 00) */ | |
aeb1f26b MM |
60 | |
61 | INS_LEFT, /* normal left instructions */ | |
62 | INS_LEFT_PARALLEL, /* left side of || */ | |
63 | INS_LEFT_COND_TEST, /* EXExx test on left side */ | |
64 | INS_LEFT_COND_EXE, /* execution after EXExxx test on right side succeeded */ | |
65 | INS_LEFT_NOPS, /* NOP on left side */ | |
66 | ||
67 | INS_RIGHT, /* normal right instructions */ | |
68 | INS_RIGHT_PARALLEL, /* right side of || */ | |
69 | INS_RIGHT_COND_TEST, /* EXExx test on right side */ | |
70 | INS_RIGHT_COND_EXE, /* execution after EXExxx test on left side succeeded */ | |
71 | INS_RIGHT_NOPS, /* NOP on right side */ | |
72 | ||
7eebfc62 | 73 | INS_MAX |
87178dbd MM |
74 | }; |
75 | ||
aeb1f26b | 76 | extern unsigned long ins_type_counters[ (int)INS_MAX ]; |
7eebfc62 | 77 | |
ac9a7d8a AC |
78 | enum { |
79 | SP_IDX = 15, | |
80 | }; | |
81 | ||
2934d1c9 MH |
82 | struct _state |
83 | { | |
84 | reg_t regs[16]; /* general-purpose registers */ | |
5c255669 | 85 | reg_t cregs[16]; /* control registers */ |
ac9a7d8a | 86 | reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */ |
5c255669 | 87 | int64 a[2]; /* accumulators */ |
2934d1c9 MH |
88 | uint8 SM; |
89 | uint8 EA; | |
90 | uint8 DB; | |
7f48c9fe | 91 | uint8 DM; |
2934d1c9 MH |
92 | uint8 IE; |
93 | uint8 RP; | |
94 | uint8 MD; | |
95 | uint8 FX; | |
96 | uint8 ST; | |
97 | uint8 F0; | |
98 | uint8 F1; | |
99 | uint8 C; | |
100 | uint8 exe; | |
aa49c64f AC |
101 | int exception; |
102 | int pc_changed; | |
c422ecc7 | 103 | /* everything below this line is not reset by sim_create_inferior() */ |
2934d1c9 MH |
104 | uint8 *imem; |
105 | uint8 *dmem; | |
c422ecc7 | 106 | uint8 *umem[128]; |
87178dbd | 107 | enum _ins_type ins_type; |
2934d1c9 MH |
108 | } State; |
109 | ||
87178dbd | 110 | extern host_callback *d10v_callback; |
2934d1c9 MH |
111 | extern uint16 OP[4]; |
112 | extern struct simops Simops[]; | |
b30cdd35 MM |
113 | extern asection *text; |
114 | extern bfd_vma text_start; | |
115 | extern bfd_vma text_end; | |
aa49c64f | 116 | extern bfd *prog_bfd; |
2934d1c9 | 117 | |
bc6df23d AC |
118 | enum |
119 | { | |
120 | PSW_CR = 0, | |
121 | BPSW_CR = 1, | |
122 | PC_CR = 2, | |
123 | BPC_CR = 3, | |
19431a02 | 124 | DPSW_CR = 4, |
bc6df23d AC |
125 | RPT_C_CR = 7, |
126 | RPT_S_CR = 8, | |
127 | RPT_E_CR = 9, | |
128 | MOD_S_CR = 10, | |
129 | MOD_E_CR = 11, | |
130 | IBA_CR = 14, | |
131 | }; | |
132 | ||
133 | enum | |
134 | { | |
135 | PSW_SM_BIT = 0x8000, | |
136 | PSW_EA_BIT = 0x2000, | |
137 | PSW_DB_BIT = 0x1000, | |
138 | PSW_DM_BIT = 0x0800, | |
139 | PSW_IE_BIT = 0x0400, | |
140 | PSW_RP_BIT = 0x0200, | |
141 | PSW_MD_BIT = 0x0100, | |
142 | PSW_FX_BIT = 0x0080, | |
143 | PSW_ST_BIT = 0x0040, | |
144 | PSW_F0_BIT = 0x0008, | |
145 | PSW_F1_BIT = 0x0004, | |
146 | PSW_C_BIT = 0x0001, | |
147 | }; | |
148 | ||
149 | /* See simopsc.:move_to_cr() for registers that can not be read-from | |
150 | or assigned-to directly */ | |
151 | #define PC (State.cregs[PC_CR]) | |
152 | #define PSW (move_from_cr (PSW_CR)) | |
19431a02 | 153 | #define BPSW (0 + State.cregs[BPSW_CR]) |
bc6df23d AC |
154 | #define BPC (State.cregs[BPC_CR]) |
155 | #define RPT_C (State.cregs[RPT_C_CR]) | |
38d0ccc2 | 156 | #define RPT_S (State.cregs[RPT_S_CR]) |
bc6df23d AC |
157 | #define RPT_E (State.cregs[RPT_E_CR]) |
158 | #define MOD_S (0 + State.cregs[MOD_S_CR]) | |
159 | #define MOD_E (0 + State.cregs[MOD_E_CR]) | |
160 | #define IBA (State.cregs[IBA_CR]) | |
2934d1c9 | 161 | |
5c255669 MM |
162 | #define SIG_D10V_STOP -1 |
163 | #define SIG_D10V_EXIT -2 | |
164 | ||
2934d1c9 MH |
165 | #define SEXT3(x) ((((x)&0x7)^(~3))+4) |
166 | ||
167 | /* sign-extend a 4-bit number */ | |
168 | #define SEXT4(x) ((((x)&0xf)^(~7))+8) | |
169 | ||
170 | /* sign-extend an 8-bit number */ | |
171 | #define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80) | |
172 | ||
173 | /* sign-extend a 16-bit number */ | |
174 | #define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000) | |
175 | ||
4f425a32 | 176 | /* sign-extend a 32-bit number */ |
aa49c64f | 177 | #define SEXT32(x) ((((x)&SIGNED64(0xffffffff))^(~SIGNED64(0x7fffffff)))+SIGNED64(0x80000000)) |
4f425a32 | 178 | |
4c38885c | 179 | /* sign extend a 40 bit number */ |
aa49c64f | 180 | #define SEXT40(x) ((((x)&SIGNED64(0xffffffffff))^(~SIGNED64(0x7fffffffff)))+SIGNED64(0x8000000000)) |
4c38885c | 181 | |
d70b4d42 | 182 | /* sign extend a 44 bit number */ |
aa49c64f AC |
183 | #define SEXT44(x) ((((x)&SIGNED64(0xfffffffffff))^(~SIGNED64(0x7ffffffffff)))+SIGNED64(0x80000000000)) |
184 | ||
185 | /* sign extend a 56 bit number */ | |
186 | #define SEXT56(x) ((((x)&SIGNED64(0xffffffffffffff))^(~SIGNED64(0x7fffffffffffff)))+SIGNED64(0x80000000000000)) | |
d70b4d42 MH |
187 | |
188 | /* sign extend a 60 bit number */ | |
aa49c64f | 189 | #define SEXT60(x) ((((x)&SIGNED64(0xfffffffffffffff))^(~SIGNED64(0x7ffffffffffffff)))+SIGNED64(0x800000000000000)) |
d70b4d42 | 190 | |
aa49c64f AC |
191 | #define MAX32 SIGNED64(0x7fffffff) |
192 | #define MIN32 SIGNED64(0xff80000000) | |
193 | #define MASK32 SIGNED64(0xffffffff) | |
194 | #define MASK40 SIGNED64(0xffffffffff) | |
2934d1c9 | 195 | |
aa49c64f AC |
196 | /* The alignment of MOD_E in the following macro depends upon "i" always being a power of 2. */ |
197 | #define INC_ADDR(x,i) x = ((State.MD && x == (MOD_E & ~((i)-1))) ? MOD_S : (x)+(i)) | |
4f425a32 | 198 | |
c422ecc7 | 199 | extern uint8 *dmem_addr PARAMS ((uint32)); |
19431a02 | 200 | extern uint8 *imem_addr PARAMS ((uint32)); |
b30cdd35 | 201 | extern bfd_vma decode_pc PARAMS ((void)); |
c422ecc7 MH |
202 | |
203 | #define RB(x) (*(dmem_addr(x))) | |
4c38885c | 204 | #define SB(addr,data) ( RB(addr) = (data & 0xff)) |
2934d1c9 | 205 | |
5c255669 MM |
206 | #if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE) |
207 | #define ENDIAN_INLINE static __inline__ | |
208 | #include "endian.c" | |
209 | #undef ENDIAN_INLINE | |
2934d1c9 MH |
210 | |
211 | #else | |
d6fe5ca5 MM |
212 | extern uint32 get_longword PARAMS ((uint8 *)); |
213 | extern uint16 get_word PARAMS ((uint8 *)); | |
214 | extern int64 get_longlong PARAMS ((uint8 *)); | |
215 | extern void write_word PARAMS ((uint8 *addr, uint16 data)); | |
216 | extern void write_longword PARAMS ((uint8 *addr, uint32 data)); | |
217 | extern void write_longlong PARAMS ((uint8 *addr, int64 data)); | |
5c255669 | 218 | #endif |
d70b4d42 | 219 | |
c422ecc7 MH |
220 | #define SW(addr,data) write_word(dmem_addr(addr),data) |
221 | #define RW(x) get_word(dmem_addr(x)) | |
222 | #define SLW(addr,data) write_longword(dmem_addr(addr),data) | |
223 | #define RLW(x) get_longword(dmem_addr(x)) | |
d70b4d42 MH |
224 | #define READ_16(x) get_word(x) |
225 | #define WRITE_16(addr,data) write_word(addr,data) | |
226 | #define READ_64(x) get_longlong(x) | |
227 | #define WRITE_64(addr,data) write_longlong(addr,data) | |
c422ecc7 MH |
228 | |
229 | #define IMAP0 RW(0xff00) | |
230 | #define IMAP1 RW(0xff02) | |
231 | #define DMAP RW(0xff04) | |
232 | #define SET_IMAP0(x) SW(0xff00,x) | |
233 | #define SET_IMAP1(x) SW(0xff02,x) | |
234 | #define SET_DMAP(x) SW(0xff04,x) | |
aa49c64f AC |
235 | |
236 | #define JMP(x) { PC = (x); State.pc_changed = 1; } | |
bc6df23d AC |
237 | |
238 | #define AE_VECTOR_START 0xffc3 | |
239 | #define RIE_VECTOR_START 0xffc2 | |
240 | #define SDBT_VECTOR_START 0xffd5 | |
241 | #define TRAP_VECTOR_START 0xffc4 /* vector for trap 0 */ | |
242 | ||
243 | extern void move_to_cr PARAMS ((int cr, reg_t val)); | |
244 | extern reg_t move_from_cr PARAMS ((int cr)); |