s/sanitize-m32rx/sanitize-cygnus/
[deliverable/binutils-gdb.git] / sim / sparc / sparc-sim.h
1 /* collection of junk waiting time to sort out
2 Copyright (C) 1999 Cygnus Solutions. */
3
4 #ifndef SPARC_SIM_H
5 #define SPARC_SIM_H
6
7 /* GDB register numbers, will eventually live in more public place. */
8 #define SPARC32_PC_REGNUM 68
9 #define SPARC32_NPC_REGNUM 69
10 #define SPARC64_PC_REGNUM ?
11 #define SPARC64_NPC_REGNUM ?
12
13 /* Commonly used registers. */
14 #define REG_O0 8
15 #define REG_O1 9
16 #define REG_O2 10
17 #define REG_O3 11
18 #define REG_O4 12
19 #define REG_O5 13
20 #define REG_SP 14
21 #define REG_FP 30
22
23 #define CURRENT_GREGS(cpu) (& (cpu)->current_regs[0])
24 #define CURRENT_OREGS(cpu) (& (cpu)->current_regs[8])
25 #define CURRENT_LREGS(cpu) (& (cpu)->current_regs[16])
26 #define CURRENT_IREGS(cpu) (& (cpu)->current_regs[24])
27
28 /* The register windows are recorded in a seemingly backwards manner.
29 %i0-7 live at lower addresses in memory than %o0-7 (even though they
30 have higher register numbers). This is because on v9 the stack grows
31 upwards in the sense that CWP increases during a "push" (save) operation.
32 On v8 CWP decreases during a "push" (save) operation. */
33
34 #define REAL_GREGS(cpu) \
35 (& (cpu)->global_regs[0])
36 #define REAL_IREGS(cpu, win) \
37 (& (cpu)->win_regs[win][0])
38 #define REAL_LREGS(cpu, win) \
39 (& (cpu)->win_regs[win][8])
40 #ifdef WANT_CPU_SPARC32
41 #define REAL_OREGS(cpu, win) \
42 (& (cpu)->win_regs[ROUND_WIN ((win) - 1)][0])
43 #endif
44 #ifdef WANT_CPU_SPARC64
45 #define REAL_OREGS(cpu, win) \
46 (& (cpu)->win_regs[ROUND_WIN ((win) + 1)][0])
47 #endif
48 \f
49 /* Window state. */
50
51 /* Various ways to handle register windows:
52 - don't, do all index calculations at runtime
53 - table of lookup tables, one entry for each window
54 - working copy of registers that is swapped in/out on each
55 register window change
56 - table of 32 pointers, one for each regs
57 - table of 4 pointers, one for each of g,o,l,i regs
58 - ???
59 */
60
61 /* FIXME: Hardcodes number of windows. */
62 #define GET_NWINDOWS() NWINDOWS
63
64 /* We take advantage of the fact that NWINDOWS is always a power of two. */
65 #define ROUND_WIN(x) ((x) & (NWINDOWS - 1))
66
67 /* Return the next and previous windows of WIN.
68 Note that the next window for sparc32 is win-1 whereas the next window
69 for sparc64 is win+1. */
70 #ifdef WANT_CPU_SPARC32
71 #define NEXT_WIN(win) ROUND_WIN ((win) - 1)
72 #define PREV_WIN(win) ROUND_WIN ((win) + 1)
73 #endif
74 #ifdef WANT_CPU_SPARC64
75 #define NEXT_WIN(win) ROUND_WIN ((win) + 1)
76 #define PREV_WIN(win) ROUND_WIN ((win) - 1)
77 #endif
78
79 #if 0 /* FIXME: Use GET_H_FOO */
80 /* These are v9 specific. */
81 #define GET_CANSAVE(cpu_) (cpu_->cgen_cpu.cpu.h_cansave)
82 #define GET_CANRESTORE(cpu_) (cpu_->cgen_cpu.cpu.h_canrestore)
83 #define GET_CLEANWIN(cpu_) (cpu_->cgen_cpu.cpu.h_cleanwin)
84 #define GET_OTHERWIN(cpu_) (cpu_->cgen_cpu.cpu.h_otherwin)
85 #define GET_WSTATE(cpu_) (cpu_->cgen_cpu.cpu.h_wstate)
86
87 /* These are v9 specific. */
88 #define SET_CANSAVE(cpu_, x) (cpu_->cgen_cpu.cpu.h_cansave = (x))
89 #define SET_CANRESTORE(cpu_, x) (cpu_->cgen_cpu.cpu.h_canrestore = (x))
90 #define SET_CLEANWIN(cpu_, x) (cpu_->cgen_cpu.cpu.h_cleanwin = (x))
91 #define SET_OTHERWIN(cpu_, x) (cpu_->cgen_cpu.cpu.h_otherwin = (x))
92 #define SET_WSTATE(cpu_, x) (cpu_->cgen_cpu.cpu.h_wstate = (x))
93 #endif
94 \f
95 #define CPU32_CGEN(cpu) (& (cpu)->sparc_cpu.sparc32.cpu_cgen)
96
97 #ifdef WANT_CPU_SPARC32
98 /*#define ARGBUF SPARC32_ARGBUF*/
99 #define CPU_PROFILE_STATE(cpu) (& CPU32 (cpu)->cpu_profile)
100 /* Macro to access heart of cpu: the registers, etc. */
101 #define CPU_CGEN(cpu) CPU32_CGEN (cpu)
102 #endif
103 \f
104 #define CPU64_CGEN(cpu) (& (cpu)->sparc_cpu.sparc64.cpu_cgen)
105
106 #ifdef WANT_CPU_SPARC64
107 /*#define ARGBUF SPARC64_ARGBUF*/
108 #define CPU_PROFILE_STATE(cpu) (& CPU64 (cpu)->cpu_profile)
109 /* Macro to access heart of cpu: the registers, etc. */
110 #define CPU_CGEN(cpu) CPU64_CGEN (cpu)
111 #endif
112 \f
113 /* ASI accesses. */
114
115 #define DECLARE_GETMEM(mode, size) \
116 extern mode XCONCAT3 (GETMEM,mode,ASI) (SIM_CPU *, IADDR, ADDR, INT);
117
118 DECLARE_GETMEM (QI, 1)
119 DECLARE_GETMEM (UQI, 1)
120 DECLARE_GETMEM (HI, 2)
121 DECLARE_GETMEM (UHI, 2)
122 DECLARE_GETMEM (SI, 4)
123 DECLARE_GETMEM (USI, 4)
124 DECLARE_GETMEM (DI, 8)
125 DECLARE_GETMEM (UDI, 8)
126
127 #undef DECLARE_GETMEM
128
129 #define DECLARE_SETMEM(mode, size) \
130 extern void XCONCAT3 (SETMEM,mode,ASI) (SIM_CPU *, IADDR, ADDR, INT, mode);
131
132 DECLARE_SETMEM (QI, 1)
133 DECLARE_SETMEM (UQI, 1)
134 DECLARE_SETMEM (HI, 2)
135 DECLARE_SETMEM (UHI, 2)
136 DECLARE_SETMEM (SI, 4)
137 DECLARE_SETMEM (USI, 4)
138 DECLARE_SETMEM (DI, 8)
139 DECLARE_SETMEM (UDI, 8)
140
141 #undef DECLARE_SETMEM
142 \f
143 /* Misc. support routines. */
144
145 void sparc32_cold_reset (SIM_CPU *, int userland_p_);
146
147 SI sparc32_do_restore (SIM_CPU *, IADDR pc_, SI rs1_, SI rs2_simm13_);
148 SI sparc32_do_save (SIM_CPU *, IADDR pc_, SI rs1_, SI rs2_simm13_);
149
150 void sparc32_do_ldstub (SIM_CPU *, IADDR pc_, INT rd_regno_,
151 SI rs1_, SI rs2_simm13_, INT asi_);
152 void sparc32_do_swap (SIM_CPU *, IADDR pc_, INT rd_regno_,
153 SI rs1_, SI rs2_simm13_, INT asi_);
154
155 void sparc32_invalid_insn (SIM_CPU *, IADDR pc_);
156 void sparc32_core_signal (SIM_DESC, SIM_CPU *, sim_cia pc_,
157 unsigned int map_, int nr_bytes_, address_word addr_,
158 transfer_type transfer_, sim_core_signals sig_);
159 \f
160 /* Profiling support. */
161
162 void model_mark_get_h_gr (SIM_CPU *, void *);
163 void model_mark_set_h_gr (SIM_CPU *, void *);
164 void model_mark_busy_reg (SIM_CPU *, void *);
165 void model_mark_unbusy_reg (SIM_CPU *, void *);
166 \f
167 /* Called by semantic code to annul the next insn. */
168
169 #define SEM_ANNUL_INSN(cpu, pc, yes) \
170 do { CPU_CGEN_HW (cpu)->h_annul_p = (yes); } while (0)
171
172 #if 0 /* old experiment */
173
174 /* Macros used by the semantic code generator and cgen-run.c to control
175 branches. */
176
177 /* Value returned for the next PC when a branch has occured. */
178 #define PC_BRANCH_INSN 3
179
180 /* Value of npc when there is no delay slot. */
181 #define NPC_NO_DELAY_INSN 3
182
183 /* CURRENT_CPU isn't used, a variable of same name must exist for SET_H_NPC */
184 #define BRANCH_NEW_PC(current_cpu, var, addr) \
185 do { \
186 SET_H_PC (var); \
187 SET_H_NPC (addr); \
188 var = PC_BRANCH_INSN; \
189 } while (0)
190
191 /* Mark the next instruction as being annulled if YES is non-zero.
192 VAR is the local variable that contains the next PC value.
193 CURRENT_CPU isn't used, a variable of same name must exist for SET_H_NPC */
194 #define ANNUL_NEXT_INSN(current_cpu, var, yes) \
195 do { \
196 if (yes) \
197 { \
198 SET_H_ANNUL_P (yes); \
199 var = PC_BRANCH_INSN; \
200 } \
201 } while (0)
202
203 /* Update the PC.
204 We also have to watch for delay slots and annulled insns.
205 current_cpu isn't used, a variable of same name must exist for SET_H_PC */
206 #define UPDATE_PC(current_cpu, new_pc) \
207 do { \
208 if ((new_pc) == PC_BRANCH_INSN) \
209 { \
210 int annul_p = GET_H_ANNUL_P (); \
211 PCADDR npc = GET_H_NPC (); \
212 SET_H_ANNUL_P (0); \
213 if (npc != NPC_NO_DELAY_INSN) \
214 { \
215 if (annul_p) \
216 { \
217 /* FIXME: Could update cycle count. */ \
218 SET_H_PC (npc); \
219 SET_H_NPC (NPC_NO_DELAY_INSN) ; \
220 } \
221 else \
222 goto GotoFirstInsn; \
223 } \
224 else \
225 { \
226 /* Untaken annulled branch. */ \
227 /* FIXME: Could update cycle count. */ \
228 ASSERT (annul_p); \
229 SET_H_PC (GET_H_PC () + 8); \
230 } \
231 } \
232 else \
233 SET_H_PC (new_pc); \
234 } while (0)
235
236 /* Return nonzero if in non-annulled delay slot. */
237 #define EXECUTE_FIRST_INSN_P(current_cpu) \
238 (GET_H_NPC () != NPC_NO_DELAY_INSN)
239
240 /* Called when the first instruction is in non-annulled delay slot. */
241
242 #define EXECUTE_FIRST_INSN(current_cpu, sc, fast_p) \
243 do { \
244 PCADDR new_pc = execute (current_cpu, sc, fast_p); \
245 if (new_pc == PC_BRANCH_INSN) \
246 { \
247 abort (); /* FIXME: dcti in delay slot not handled yet */ \
248 } \
249 else \
250 { \
251 SET_H_PC (GET_H_NPC ()); \
252 SET_H_NPC (NPC_NO_DELAY_INSN); \
253 } \
254 } while (0)
255
256 #endif /* old experiment */
257
258 #endif /* SPARC_SIM_H */
This page took 0.035101 seconds and 4 git commands to generate.