Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / sim / bfin / bfin-sim.h
CommitLineData
ef016f83
MF
1/* Simulator for Analog Devices Blackfin processors.
2
b811d2c2 3 Copyright (C) 2005-2020 Free Software Foundation, Inc.
ef016f83
MF
4 Contributed by Analog Devices, Inc.
5
6 This file is part of simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#ifndef _BFIN_SIM_H_
22#define _BFIN_SIM_H_
23
24#include <stdbool.h>
25#include <stdint.h>
26
27typedef uint8_t bu8;
28typedef uint16_t bu16;
29typedef uint32_t bu32;
30typedef uint64_t bu40;
31typedef uint64_t bu64;
32typedef int8_t bs8;
33typedef int16_t bs16;
34typedef int32_t bs32;
35typedef int64_t bs40;
36typedef int64_t bs64;
37
38/* For dealing with parallel instructions, we must avoid changing our register
39 file until all parallel insns have been simulated. This queue of stores
40 can be used to delay a modification.
41 XXX: Should go and convert all 32 bit insns to use this. */
42struct store {
43 bu32 *addr;
44 bu32 val;
45};
46
99265d6b
MF
47enum bfin_parallel_group {
48 BFIN_PARALLEL_NONE,
49 BFIN_PARALLEL_GROUP0, /* 32bit slot. */
50 BFIN_PARALLEL_GROUP1, /* 16bit group1. */
51 BFIN_PARALLEL_GROUP2, /* 16bit group2. */
52};
53
ef016f83
MF
54/* The KSP/USP handling wrt SP may not follow the hardware exactly (the hw
55 looks at current mode and uses either SP or USP based on that. We instead
56 always operate on SP and mirror things in KSP and USP. During a CEC
57 transition, we take care of syncing the values. This lowers the simulation
58 complexity and speeds things up a bit. */
59struct bfin_cpu_state
60{
61 bu32 dpregs[16], iregs[4], mregs[4], bregs[4], lregs[4], cycles[3];
62 bu32 ax[2], aw[2];
63 bu32 lt[2], lc[2], lb[2];
64 bu32 ksp, usp, seqstat, syscfg, rets, reti, retx, retn, rete;
65 bu32 pc, emudat[2];
66 /* These ASTAT flags need not be bu32, but it makes pointers easier. */
67 bu32 ac0, ac0_copy, ac1, an, aq;
68 union { struct { bu32 av0; bu32 av1; }; bu32 av [2]; };
69 union { struct { bu32 av0s; bu32 av1s; }; bu32 avs[2]; };
70 bu32 az, cc, v, v_copy, vs;
71 bu32 rnd_mod;
72 bu32 v_internal;
73 bu32 astat_reserved;
74
75 /* Set by an instruction emulation function if we performed a jump. We
76 cannot compare oldpc to newpc as this ignores the "jump 0;" case. */
77 bool did_jump;
78
79 /* Used by the CEC to figure out where to return to. */
80 bu32 insn_len;
81
82 /* How many cycles did this insn take to complete ? */
83 bu32 cycle_delay;
84
85 /* The pc currently being interpreted in parallel insns. */
86 bu32 multi_pc;
87
99265d6b
MF
88 /* Some insns are valid in group1, and others in group2, so we
89 need to keep track of the exact slot we're processing. */
90 enum bfin_parallel_group group;
91
ef016f83
MF
92 /* Needed for supporting the DISALGNEXCPT instruction */
93 int dis_algn_expt;
94
95 /* See notes above for struct store. */
96 struct store stores[20];
97 int n_stores;
98
99#if (WITH_HW)
100 /* Cache heavily used CPU-specific device pointers. */
101 void *cec_cache;
102 void *evt_cache;
103 void *mmu_cache;
104 void *trace_cache;
105#endif
106};
107
108#define REG_H_L(h, l) (((h) & 0xffff0000) | ((l) & 0x0000ffff))
109
110#define DREG(x) (BFIN_CPU_STATE.dpregs[x])
111#define PREG(x) (BFIN_CPU_STATE.dpregs[x + 8])
112#define SPREG PREG (6)
113#define FPREG PREG (7)
114#define IREG(x) (BFIN_CPU_STATE.iregs[x])
115#define MREG(x) (BFIN_CPU_STATE.mregs[x])
116#define BREG(x) (BFIN_CPU_STATE.bregs[x])
117#define LREG(x) (BFIN_CPU_STATE.lregs[x])
118#define AXREG(x) (BFIN_CPU_STATE.ax[x])
119#define AWREG(x) (BFIN_CPU_STATE.aw[x])
120#define CCREG (BFIN_CPU_STATE.cc)
121#define LCREG(x) (BFIN_CPU_STATE.lc[x])
122#define LTREG(x) (BFIN_CPU_STATE.lt[x])
123#define LBREG(x) (BFIN_CPU_STATE.lb[x])
124#define CYCLESREG (BFIN_CPU_STATE.cycles[0])
125#define CYCLES2REG (BFIN_CPU_STATE.cycles[1])
126#define CYCLES2SHDREG (BFIN_CPU_STATE.cycles[2])
127#define KSPREG (BFIN_CPU_STATE.ksp)
128#define USPREG (BFIN_CPU_STATE.usp)
129#define SEQSTATREG (BFIN_CPU_STATE.seqstat)
130#define SYSCFGREG (BFIN_CPU_STATE.syscfg)
131#define RETSREG (BFIN_CPU_STATE.rets)
132#define RETIREG (BFIN_CPU_STATE.reti)
133#define RETXREG (BFIN_CPU_STATE.retx)
134#define RETNREG (BFIN_CPU_STATE.retn)
135#define RETEREG (BFIN_CPU_STATE.rete)
136#define PCREG (BFIN_CPU_STATE.pc)
137#define EMUDAT_INREG (BFIN_CPU_STATE.emudat[0])
138#define EMUDAT_OUTREG (BFIN_CPU_STATE.emudat[1])
139#define INSN_LEN (BFIN_CPU_STATE.insn_len)
99265d6b 140#define PARALLEL_GROUP (BFIN_CPU_STATE.group)
ef016f83
MF
141#define CYCLE_DELAY (BFIN_CPU_STATE.cycle_delay)
142#define DIS_ALGN_EXPT (BFIN_CPU_STATE.dis_algn_expt)
143
144#define EXCAUSE_SHIFT 0
145#define EXCAUSE_MASK (0x3f << EXCAUSE_SHIFT)
146#define EXCAUSE ((SEQSTATREG & EXCAUSE_MASK) >> EXCAUSE_SHIFT)
147#define HWERRCAUSE_SHIFT 14
148#define HWERRCAUSE_MASK (0x1f << HWERRCAUSE_SHIFT)
149#define HWERRCAUSE ((SEQSTATREG & HWERRCAUSE_MASK) >> HWERRCAUSE_SHIFT)
150
151#define _SET_CORE32REG_IDX(reg, p, x, val) \
152 do { \
153 bu32 __v = (val); \
154 TRACE_REGISTER (cpu, "wrote "#p"%i = %#x", x, __v); \
155 reg = __v; \
156 } while (0)
157#define SET_DREG(x, val) _SET_CORE32REG_IDX (DREG (x), R, x, val)
158#define SET_PREG(x, val) _SET_CORE32REG_IDX (PREG (x), P, x, val)
159#define SET_IREG(x, val) _SET_CORE32REG_IDX (IREG (x), I, x, val)
160#define SET_MREG(x, val) _SET_CORE32REG_IDX (MREG (x), M, x, val)
161#define SET_BREG(x, val) _SET_CORE32REG_IDX (BREG (x), B, x, val)
162#define SET_LREG(x, val) _SET_CORE32REG_IDX (LREG (x), L, x, val)
163#define SET_LCREG(x, val) _SET_CORE32REG_IDX (LCREG (x), LC, x, val)
164#define SET_LTREG(x, val) _SET_CORE32REG_IDX (LTREG (x), LT, x, val)
165#define SET_LBREG(x, val) _SET_CORE32REG_IDX (LBREG (x), LB, x, val)
166
167#define SET_DREG_L_H(x, l, h) SET_DREG (x, REG_H_L (h, l))
168#define SET_DREG_L(x, l) SET_DREG (x, REG_H_L (DREG (x), l))
169#define SET_DREG_H(x, h) SET_DREG (x, REG_H_L (h, DREG (x)))
170
171#define _SET_CORE32REG_ALU(reg, p, x, val) \
172 do { \
173 bu32 __v = (val); \
174 TRACE_REGISTER (cpu, "wrote A%i"#p" = %#x", x, __v); \
175 reg = __v; \
176 } while (0)
177#define SET_AXREG(x, val) _SET_CORE32REG_ALU (AXREG (x), X, x, val)
178#define SET_AWREG(x, val) _SET_CORE32REG_ALU (AWREG (x), W, x, val)
179
180#define SET_AREG(x, val) \
181 do { \
182 bu40 __a = (val); \
183 SET_AXREG (x, (__a >> 32) & 0xff); \
184 SET_AWREG (x, __a); \
185 } while (0)
186#define SET_AREG32(x, val) \
187 do { \
188 SET_AWREG (x, val); \
189 SET_AXREG (x, -(AWREG (x) >> 31)); \
190 } while (0)
191
192#define _SET_CORE32REG(reg, val) \
193 do { \
194 bu32 __v = (val); \
195 TRACE_REGISTER (cpu, "wrote "#reg" = %#x", __v); \
196 reg##REG = __v; \
197 } while (0)
198#define SET_FPREG(val) _SET_CORE32REG (FP, val)
199#define SET_SPREG(val) _SET_CORE32REG (SP, val)
200#define SET_CYCLESREG(val) _SET_CORE32REG (CYCLES, val)
201#define SET_CYCLES2REG(val) _SET_CORE32REG (CYCLES2, val)
202#define SET_CYCLES2SHDREG(val) _SET_CORE32REG (CYCLES2SHD, val)
203#define SET_KSPREG(val) _SET_CORE32REG (KSP, val)
204#define SET_USPREG(val) _SET_CORE32REG (USP, val)
205#define SET_SYSCFGREG(val) _SET_CORE32REG (SYSCFG, val)
206#define SET_RETSREG(val) _SET_CORE32REG (RETS, val)
207#define SET_RETIREG(val) _SET_CORE32REG (RETI, val)
208#define SET_RETXREG(val) _SET_CORE32REG (RETX, val)
209#define SET_RETNREG(val) _SET_CORE32REG (RETN, val)
210#define SET_RETEREG(val) _SET_CORE32REG (RETE, val)
211#define SET_PCREG(val) _SET_CORE32REG (PC, val)
212
213#define _SET_CORE32REGFIELD(reg, field, val, mask, shift) \
214 do { \
215 bu32 __f = (val); \
216 bu32 __v = ((reg##REG) & ~(mask)) | (__f << (shift)); \
217 TRACE_REGISTER (cpu, "wrote "#field" = %#x ("#reg" = %#x)", __f, __v); \
218 reg##REG = __v; \
219 } while (0)
220#define SET_SEQSTATREG(val) _SET_CORE32REG (SEQSTAT, val)
221#define SET_EXCAUSE(excp) _SET_CORE32REGFIELD (SEQSTAT, EXCAUSE, excp, EXCAUSE_MASK, EXCAUSE_SHIFT)
222#define SET_HWERRCAUSE(hwerr) _SET_CORE32REGFIELD (SEQSTAT, HWERRCAUSE, hwerr, HWERRCAUSE_MASK, HWERRCAUSE_SHIFT)
223
224#define AZ_BIT 0
225#define AN_BIT 1
226#define AC0_COPY_BIT 2
227#define V_COPY_BIT 3
228#define CC_BIT 5
229#define AQ_BIT 6
230#define RND_MOD_BIT 8
231#define AC0_BIT 12
232#define AC1_BIT 13
233#define AV0_BIT 16
234#define AV0S_BIT 17
235#define AV1_BIT 18
236#define AV1S_BIT 19
237#define V_BIT 24
238#define VS_BIT 25
239#define ASTAT_DEFINED_BITS \
240 ((1 << AZ_BIT) | (1 << AN_BIT) | (1 << AC0_COPY_BIT) | (1 << V_COPY_BIT) \
241 |(1 << CC_BIT) | (1 << AQ_BIT) \
242 |(1 << RND_MOD_BIT) \
243 |(1 << AC0_BIT) | (1 << AC1_BIT) \
244 |(1 << AV0_BIT) | (1 << AV0S_BIT) | (1 << AV1_BIT) | (1 << AV1S_BIT) \
245 |(1 << V_BIT) | (1 << VS_BIT))
246
247#define ASTATREG(field) (BFIN_CPU_STATE.field)
248#define ASTAT_DEPOSIT(field, bit) (ASTATREG(field) << (bit))
249#define ASTAT \
250 (ASTAT_DEPOSIT(az, AZ_BIT) \
251 |ASTAT_DEPOSIT(an, AN_BIT) \
252 |ASTAT_DEPOSIT(ac0_copy, AC0_COPY_BIT) \
253 |ASTAT_DEPOSIT(v_copy, V_COPY_BIT) \
254 |ASTAT_DEPOSIT(cc, CC_BIT) \
255 |ASTAT_DEPOSIT(aq, AQ_BIT) \
256 |ASTAT_DEPOSIT(rnd_mod, RND_MOD_BIT) \
257 |ASTAT_DEPOSIT(ac0, AC0_BIT) \
258 |ASTAT_DEPOSIT(ac1, AC1_BIT) \
259 |ASTAT_DEPOSIT(av0, AV0_BIT) \
260 |ASTAT_DEPOSIT(av0s, AV0S_BIT) \
261 |ASTAT_DEPOSIT(av1, AV1_BIT) \
262 |ASTAT_DEPOSIT(av1s, AV1S_BIT) \
263 |ASTAT_DEPOSIT(v, V_BIT) \
264 |ASTAT_DEPOSIT(vs, VS_BIT) \
265 |ASTATREG(astat_reserved))
266
267#define ASTAT_EXTRACT(a, bit) (((a) >> bit) & 1)
268#define _SET_ASTAT(a, field, bit) (ASTATREG(field) = ASTAT_EXTRACT(a, bit))
269#define SET_ASTAT(a) \
270 do { \
271 TRACE_REGISTER (cpu, "wrote ASTAT = %#x", a); \
272 _SET_ASTAT(a, az, AZ_BIT); \
273 _SET_ASTAT(a, an, AN_BIT); \
274 _SET_ASTAT(a, ac0_copy, AC0_COPY_BIT); \
275 _SET_ASTAT(a, v_copy, V_COPY_BIT); \
276 _SET_ASTAT(a, cc, CC_BIT); \
277 _SET_ASTAT(a, aq, AQ_BIT); \
278 _SET_ASTAT(a, rnd_mod, RND_MOD_BIT); \
279 _SET_ASTAT(a, ac0, AC0_BIT); \
280 _SET_ASTAT(a, ac1, AC1_BIT); \
281 _SET_ASTAT(a, av0, AV0_BIT); \
282 _SET_ASTAT(a, av0s, AV0S_BIT); \
283 _SET_ASTAT(a, av1, AV1_BIT); \
284 _SET_ASTAT(a, av1s, AV1S_BIT); \
285 _SET_ASTAT(a, v, V_BIT); \
286 _SET_ASTAT(a, vs, VS_BIT); \
287 ASTATREG(astat_reserved) = (a) & ~ASTAT_DEFINED_BITS; \
288 } while (0)
289#define SET_ASTATREG(field, val) \
290 do { \
291 int __v = !!(val); \
292 TRACE_REGISTER (cpu, "wrote ASTAT["#field"] = %i", __v); \
293 ASTATREG (field) = __v; \
294 if (&ASTATREG (field) == &ASTATREG (ac0)) \
295 { \
296 TRACE_REGISTER (cpu, "wrote ASTAT["#field"_copy] = %i", __v); \
297 ASTATREG (ac0_copy) = __v; \
298 } \
299 else if (&ASTATREG (field) == &ASTATREG (v)) \
300 { \
301 TRACE_REGISTER (cpu, "wrote ASTAT["#field"_copy] = %i", __v); \
302 ASTATREG (v_copy) = __v; \
303 } \
304 } while (0)
305#define SET_CCREG(val) SET_ASTATREG (cc, val)
306
307#define SYSCFG_SSSTEP (1 << 0)
308#define SYSCFG_CCEN (1 << 1)
309#define SYSCFG_SNEN (1 << 2)
310
311#define __PUT_MEM(taddr, v, size) \
312do { \
313 bu##size __v = (v); \
314 bu32 __taddr = (taddr); \
315 int __cnt, __bytes = size / 8; \
316 mmu_check_addr (cpu, __taddr, true, false, __bytes); \
317 __cnt = sim_core_write_buffer (CPU_STATE(cpu), cpu, write_map, \
318 (void *)&__v, __taddr, __bytes); \
319 if (__cnt != __bytes) \
320 mmu_process_fault (cpu, __taddr, true, false, false, true); \
bb11f3ed 321 BFIN_TRACE_CORE (cpu, __taddr, __bytes, write_map, __v); \
ef016f83
MF
322} while (0)
323#define PUT_BYTE(taddr, v) __PUT_MEM(taddr, v, 8)
324#define PUT_WORD(taddr, v) __PUT_MEM(taddr, v, 16)
325#define PUT_LONG(taddr, v) __PUT_MEM(taddr, v, 32)
326
327#define __GET_MEM(taddr, size, inst, map) \
328({ \
329 bu##size __ret; \
330 bu32 __taddr = (taddr); \
331 int __cnt, __bytes = size / 8; \
332 mmu_check_addr (cpu, __taddr, false, inst, __bytes); \
333 __cnt = sim_core_read_buffer (CPU_STATE(cpu), cpu, map, \
334 (void *)&__ret, __taddr, __bytes); \
335 if (__cnt != __bytes) \
336 mmu_process_fault (cpu, __taddr, false, inst, false, true); \
bb11f3ed 337 BFIN_TRACE_CORE (cpu, __taddr, __bytes, map, __ret); \
ef016f83
MF
338 __ret; \
339})
340#define _GET_MEM(taddr, size) __GET_MEM(taddr, size, false, read_map)
341#define GET_BYTE(taddr) _GET_MEM(taddr, 8)
342#define GET_WORD(taddr) _GET_MEM(taddr, 16)
343#define GET_LONG(taddr) _GET_MEM(taddr, 32)
344
345#define IFETCH(taddr) __GET_MEM(taddr, 16, true, exec_map)
346#define IFETCH_CHECK(taddr) mmu_check_addr (cpu, taddr, false, true, 2)
347
348extern void bfin_syscall (SIM_CPU *);
349extern bu32 interp_insn_bfin (SIM_CPU *, bu32);
350extern bu32 hwloop_get_next_pc (SIM_CPU *, bu32, bu32);
351
352/* Defines for Blackfin memory layouts. */
353#define BFIN_ASYNC_BASE 0x20000000
354#define BFIN_SYSTEM_MMR_BASE 0xFFC00000
355#define BFIN_CORE_MMR_BASE 0xFFE00000
356#define BFIN_L1_SRAM_SCRATCH 0xFFB00000
357#define BFIN_L1_SRAM_SCRATCH_SIZE 0x1000
358#define BFIN_L1_SRAM_SCRATCH_END (BFIN_L1_SRAM_SCRATCH + BFIN_L1_SRAM_SCRATCH_SIZE)
359
360#define BFIN_L1_CACHE_BYTES 32
361
362#endif
This page took 0.416576 seconds and 4 git commands to generate.