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