]>
Commit | Line | Data |
---|---|---|
b34f6357 | 1 | /* Profiling definitions for the FRV simulator |
6aba47ca DJ |
2 | Copyright (C) 1998, 1999, 2000, 2001, 2003, 2007 |
3 | Free Software Foundation, Inc. | |
b34f6357 DB |
4 | Contributed by Red Hat. |
5 | ||
6 | This file is part of the GNU 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 2, or (at your option) | |
11 | 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 along | |
19 | with this program; if not, write to the Free Software Foundation, Inc., | |
20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #ifndef PROFILE_H | |
23 | #define PROFILE_H | |
24 | ||
153431d6 DB |
25 | #include "frv-desc.h" |
26 | ||
b34f6357 DB |
27 | /* This struct defines the state of profiling. All fields are of general |
28 | use to all machines. */ | |
29 | typedef struct | |
30 | { | |
31 | long vliw_insns; /* total number of VLIW insns. */ | |
32 | long vliw_wait; /* number of cycles that the current VLIW insn must wait. */ | |
33 | long post_wait; /* number of cycles that post processing in the current | |
34 | VLIW insn must wait. */ | |
35 | long vliw_cycles;/* number of cycles used by current VLIW insn. */ | |
36 | ||
37 | int past_first_p; /* Not the first insns in the VLIW */ | |
38 | ||
39 | /* Register latencies. Must be signed since they can be temporarily | |
40 | negative. */ | |
41 | int gr_busy[64]; /* Cycles until GR is available. */ | |
42 | int fr_busy[64]; /* Cycles until FR is available. */ | |
43 | int acc_busy[64]; /* Cycles until FR is available. */ | |
44 | int ccr_busy[8]; /* Cycles until ICC/FCC is available. */ | |
153431d6 | 45 | int spr_busy[4096]; /* Cycles until spr is available. */ |
b34f6357 DB |
46 | int idiv_busy[2]; /* Cycles until integer division unit is available. */ |
47 | int fdiv_busy[2]; /* Cycles until float division unit is available. */ | |
48 | int fsqrt_busy[2]; /* Cycles until square root unit is available. */ | |
e930b1f5 DB |
49 | int float_busy[4]; /* Cycles until floating point unit is available. */ |
50 | int media_busy[4]; /* Cycles until media unit is available. */ | |
b34f6357 DB |
51 | int branch_penalty; /* Cycles until branch is complete. */ |
52 | ||
53 | int gr_latency[64]; /* Cycles until target GR is available. */ | |
54 | int fr_latency[64]; /* Cycles until target FR is available. */ | |
55 | int acc_latency[64]; /* Cycles until target FR is available. */ | |
56 | int ccr_latency[8]; /* Cycles until target ICC/FCC is available. */ | |
153431d6 | 57 | int spr_latency[4096]; /* Cycles until target spr is available. */ |
b34f6357 DB |
58 | |
59 | /* Some registers are busy for a shorter number of cycles than normal | |
60 | depending on how they are used next. the xxx_busy_adjust arrays keep track | |
61 | of how many cycles to adjust down. | |
62 | */ | |
63 | int fr_busy_adjust[64]; | |
64 | int acc_busy_adjust[64]; | |
65 | ||
66 | /* Register flags. Each bit represents one register. */ | |
67 | DI cur_gr_complex; | |
68 | DI prev_gr_complex; | |
69 | ||
70 | /* Keep track of the total queued post-processing time required before a | |
71 | resource is available. This is applied to the resource's latency once all | |
72 | pending loads for the resource are completed. */ | |
73 | int fr_ptime[64]; | |
74 | ||
75 | int branch_hint; /* hint field from branch insn. */ | |
76 | USI branch_address; /* Address of predicted branch. */ | |
77 | USI insn_fetch_address;/* Address of sequential insns fetched. */ | |
e930b1f5 DB |
78 | int mclracc_acc; /* ACC number of register cleared by mclracc. */ |
79 | int mclracc_A; /* A field of mclracc. */ | |
b34f6357 DB |
80 | |
81 | /* We need to know when the first branch of a vliw insn is taken, so that | |
82 | we don't consider the remaining branches in the vliw insn. */ | |
83 | int vliw_branch_taken; | |
84 | ||
85 | /* Keep track of the maximum load stall for each VLIW insn. */ | |
86 | int vliw_load_stall; | |
87 | ||
88 | /* Need to know if all cache entries are affected by various cache | |
89 | operations. */ | |
90 | int all_cache_entries; | |
91 | } FRV_PROFILE_STATE; | |
92 | ||
93 | #define DUAL_REG(reg) ((reg) >= 0 && (reg) < 63 ? (reg) + 1 : -1) | |
94 | #define DUAL_DOUBLE(reg) ((reg) >= 0 && (reg) < 61 ? (reg) + 2 : -1) | |
95 | ||
153431d6 DB |
96 | /* Return the GNER register associated with the given GR register. |
97 | There is no GNER associated with gr0. */ | |
98 | #define GNER_FOR_GR(gr) ((gr) > 63 ? -1 : \ | |
99 | (gr) > 31 ? H_SPR_GNER0 : \ | |
100 | (gr) > 0 ? H_SPR_GNER1 : \ | |
101 | -1) | |
102 | /* Return the GNER register associated with the given GR register. | |
103 | There is no GNER associated with gr0. */ | |
104 | #define FNER_FOR_FR(fr) ((fr) > 63 ? -1 : \ | |
105 | (fr) > 31 ? H_SPR_FNER0 : \ | |
106 | (fr) > 0 ? H_SPR_FNER1 : \ | |
107 | -1) | |
108 | ||
b34f6357 DB |
109 | /* Top up the latency of the given GR by the given number of cycles. */ |
110 | void update_GR_latency (SIM_CPU *, INT, int); | |
111 | void update_GRdouble_latency (SIM_CPU *, INT, int); | |
112 | void update_GR_latency_for_load (SIM_CPU *, INT, int); | |
113 | void update_GRdouble_latency_for_load (SIM_CPU *, INT, int); | |
114 | void update_GR_latency_for_swap (SIM_CPU *, INT, int); | |
115 | void update_FR_latency (SIM_CPU *, INT, int); | |
116 | void update_FRdouble_latency (SIM_CPU *, INT, int); | |
117 | void update_FR_latency_for_load (SIM_CPU *, INT, int); | |
118 | void update_FRdouble_latency_for_load (SIM_CPU *, INT, int); | |
1c453cd6 DB |
119 | void update_FR_ptime (SIM_CPU *, INT, int); |
120 | void update_FRdouble_ptime (SIM_CPU *, INT, int); | |
b34f6357 DB |
121 | void decrease_ACC_busy (SIM_CPU *, INT, int); |
122 | void decrease_FR_busy (SIM_CPU *, INT, int); | |
123 | void decrease_GR_busy (SIM_CPU *, INT, int); | |
124 | void increase_FR_busy (SIM_CPU *, INT, int); | |
e930b1f5 | 125 | void increase_ACC_busy (SIM_CPU *, INT, int); |
b34f6357 DB |
126 | void update_ACC_latency (SIM_CPU *, INT, int); |
127 | void update_CCR_latency (SIM_CPU *, INT, int); | |
153431d6 | 128 | void update_SPR_latency (SIM_CPU *, INT, int); |
b34f6357 DB |
129 | void update_idiv_resource_latency (SIM_CPU *, INT, int); |
130 | void update_fdiv_resource_latency (SIM_CPU *, INT, int); | |
131 | void update_fsqrt_resource_latency (SIM_CPU *, INT, int); | |
e930b1f5 DB |
132 | void update_float_resource_latency (SIM_CPU *, INT, int); |
133 | void update_media_resource_latency (SIM_CPU *, INT, int); | |
b34f6357 DB |
134 | void update_branch_penalty (SIM_CPU *, int); |
135 | void update_ACC_ptime (SIM_CPU *, INT, int); | |
1c453cd6 | 136 | void update_SPR_ptime (SIM_CPU *, INT, int); |
b34f6357 DB |
137 | void vliw_wait_for_GR (SIM_CPU *, INT); |
138 | void vliw_wait_for_GRdouble (SIM_CPU *, INT); | |
139 | void vliw_wait_for_FR (SIM_CPU *, INT); | |
140 | void vliw_wait_for_FRdouble (SIM_CPU *, INT); | |
141 | void vliw_wait_for_CCR (SIM_CPU *, INT); | |
142 | void vliw_wait_for_ACC (SIM_CPU *, INT); | |
153431d6 | 143 | void vliw_wait_for_SPR (SIM_CPU *, INT); |
b34f6357 DB |
144 | void vliw_wait_for_idiv_resource (SIM_CPU *, INT); |
145 | void vliw_wait_for_fdiv_resource (SIM_CPU *, INT); | |
146 | void vliw_wait_for_fsqrt_resource (SIM_CPU *, INT); | |
e930b1f5 DB |
147 | void vliw_wait_for_float_resource (SIM_CPU *, INT); |
148 | void vliw_wait_for_media_resource (SIM_CPU *, INT); | |
b34f6357 DB |
149 | void load_wait_for_GR (SIM_CPU *, INT); |
150 | void load_wait_for_FR (SIM_CPU *, INT); | |
151 | void load_wait_for_GRdouble (SIM_CPU *, INT); | |
152 | void load_wait_for_FRdouble (SIM_CPU *, INT); | |
153 | void enforce_full_fr_latency (SIM_CPU *, INT); | |
e930b1f5 | 154 | void enforce_full_acc_latency (SIM_CPU *, INT); |
b34f6357 DB |
155 | int post_wait_for_FR (SIM_CPU *, INT); |
156 | int post_wait_for_FRdouble (SIM_CPU *, INT); | |
157 | int post_wait_for_ACC (SIM_CPU *, INT); | |
158 | int post_wait_for_CCR (SIM_CPU *, INT); | |
1c453cd6 | 159 | int post_wait_for_SPR (SIM_CPU *, INT); |
b34f6357 DB |
160 | int post_wait_for_fdiv (SIM_CPU *, INT); |
161 | int post_wait_for_fsqrt (SIM_CPU *, INT); | |
e930b1f5 DB |
162 | int post_wait_for_float (SIM_CPU *, INT); |
163 | int post_wait_for_media (SIM_CPU *, INT); | |
b34f6357 DB |
164 | |
165 | void trace_vliw_wait_cycles (SIM_CPU *); | |
166 | void handle_resource_wait (SIM_CPU *); | |
167 | ||
168 | void request_cache_load (SIM_CPU *, INT, int, int); | |
169 | void request_cache_flush (SIM_CPU *, FRV_CACHE *, int); | |
170 | void request_cache_invalidate (SIM_CPU *, FRV_CACHE *, int); | |
171 | void request_cache_preload (SIM_CPU *, FRV_CACHE *, int); | |
172 | void request_cache_unlock (SIM_CPU *, FRV_CACHE *, int); | |
173 | int load_pending_for_register (SIM_CPU *, int, int, int); | |
174 | ||
175 | void set_use_is_gr_complex (SIM_CPU *, INT); | |
176 | void set_use_not_gr_complex (SIM_CPU *, INT); | |
177 | int use_is_gr_complex (SIM_CPU *, INT); | |
178 | ||
179 | typedef struct | |
180 | { | |
181 | SI address; | |
182 | unsigned reqno; | |
183 | } FRV_INSN_FETCH_BUFFER; | |
184 | ||
185 | extern FRV_INSN_FETCH_BUFFER frv_insn_fetch_buffer[]; | |
186 | ||
187 | PROFILE_INFO_CPU_CALLBACK_FN frv_profile_info; | |
188 | ||
189 | enum { | |
190 | /* Simulator specific profile bits begin here. */ | |
191 | /* Profile caches. */ | |
192 | PROFILE_CACHE_IDX = PROFILE_NEXT_IDX, | |
193 | /* Profile parallelization. */ | |
194 | PROFILE_PARALLEL_IDX | |
195 | }; | |
196 | ||
197 | /* Masks so WITH_PROFILE can have symbolic values. | |
198 | The case choice here is on purpose. The lowercase parts are args to | |
199 | --with-profile. */ | |
200 | #define PROFILE_cache (1 << PROFILE_INSN_IDX) | |
201 | #define PROFILE_parallel (1 << PROFILE_INSN_IDX) | |
202 | ||
203 | /* Preprocessor macros to simplify tests of WITH_PROFILE. */ | |
204 | #define WITH_PROFILE_CACHE_P (WITH_PROFILE & PROFILE_insn) | |
205 | #define WITH_PROFILE_PARALLEL_P (WITH_PROFILE & PROFILE_insn) | |
206 | ||
207 | #define FRV_COUNT_CYCLES(cpu, condition) \ | |
208 | ((PROFILE_MODEL_P (cpu) && (condition)) || frv_interrupt_state.timer.enabled) | |
209 | ||
210 | /* Modelling support. */ | |
211 | extern int frv_save_profile_model_p; | |
212 | ||
213 | extern enum FRV_INSN_MODELING { | |
214 | FRV_INSN_NO_MODELING = 0, | |
215 | FRV_INSN_MODEL_PASS_1, | |
216 | FRV_INSN_MODEL_PASS_2, | |
217 | FRV_INSN_MODEL_WRITEBACK | |
218 | } model_insn; | |
219 | ||
220 | void | |
221 | frv_model_advance_cycles (SIM_CPU *, int); | |
222 | void | |
223 | frv_model_trace_wait_cycles (SIM_CPU *, int, const char *); | |
224 | ||
225 | /* Register types for queued load requests. */ | |
226 | #define REGTYPE_NONE 0 | |
227 | #define REGTYPE_FR 1 | |
228 | #define REGTYPE_ACC 2 | |
229 | ||
230 | #endif /* PROFILE_H */ |