aboutsummaryrefslogtreecommitdiff
path: root/sim/frv/profile.c
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2003-09-12 22:05:22 +0000
committerDave Brolley <brolley@redhat.com>2003-09-12 22:05:22 +0000
commit153431d6b1197e76ef2a6908034260aa56bc411f (patch)
treecd389cb67d7b9ca20c97e9bbd3f3f1d186e2d1f5 /sim/frv/profile.c
parent23600bb3cd7709fca21684899cb172b83f89b74a (diff)
downloadfsf-binutils-gdb-153431d6b1197e76ef2a6908034260aa56bc411f.zip
fsf-binutils-gdb-153431d6b1197e76ef2a6908034260aa56bc411f.tar.gz
fsf-binutils-gdb-153431d6b1197e76ef2a6908034260aa56bc411f.tar.bz2
2003-09-12 Dave Brolley <brolley@redhat.com>
* registers.c (frv_check_spr_read_access): Check for access to ACC4-ACC63 and ACCG4-ACCG63. * profile.h (frv-desc.h): #include it. (spr_busy): New member of FRV_PROFILE_STATE. (spr_latency): Ditto. (GNER_FOR_GR): New macro. (FNER_FOR_FR): New maccro. (update_SPR_latency): New function. (vliw_wait_for_SPR): New function. * profile.c (profile-fr550.h): #include it. (update_latencies): Update SPR latencies. (update_target_latencies): Ditto. (update_SPR_latency): New function. (vliw_wait_for_SPR): New function. * profile-fr500.c (frvbf_model_fr500_u_idiv): Record GNER latency. (frvbf_model_fr500_u_trap): Removed unused variable, ps. (frvbf_model_fr500_u_check): Ditto. (frvbf_model_fr500_u_clrgr): New unit modeller for fr500. (frvbf_model_fr500_u_clrfr): Ditto. (frvbf_model_fr500_u_spr2gr): Wait for SPR. (frvbf_model_fr500_u_gr2spr): Ditto. * frv-sim.h (H_SPR_ACC4): New macro. (H_SPR_ACCG4): New macro; (H_SPR_ACC0): Removed. (H_SPR_ACCG0): Removed. * arch.h,model.c,sem[ch],decode.[ch]: Regenerated.
Diffstat (limited to 'sim/frv/profile.c')
-rw-r--r--sim/frv/profile.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/sim/frv/profile.c b/sim/frv/profile.c
index 822e5d6..6ef1e35 100644
--- a/sim/frv/profile.c
+++ b/sim/frv/profile.c
@@ -681,6 +681,7 @@ update_latencies (SIM_CPU *cpu, int cycles)
int *gr = ps->gr_busy;
int *fr = ps->fr_busy;
int *acc = ps->acc_busy;
+ int *spr;
/* This loop handles GR, FR and ACC registers. */
for (i = 0; i < 64; ++i)
{
@@ -734,6 +735,16 @@ update_latencies (SIM_CPU *cpu, int cycles)
*ccr -= cycles;
++ccr;
}
+ /* This loop handles SPR registers. */
+ spr = ps->spr_busy;
+ for (i = 0; i < 4096; ++i)
+ {
+ if (*spr <= cycles)
+ *spr = 0;
+ else
+ *spr -= cycles;
+ ++spr;
+ }
/* This loop handles resources. */
idiv = ps->idiv_busy;
fdiv = ps->fdiv_busy;
@@ -805,10 +816,12 @@ update_target_latencies (SIM_CPU *cpu)
int *gr_lat = ps->gr_latency;
int *fr_lat = ps->fr_latency;
int *acc_lat = ps->acc_latency;
+ int *spr_lat;
int *ccr;
int *gr = ps->gr_busy;
int *fr = ps->fr_busy;
int *acc = ps->acc_busy;
+ int *spr;
/* This loop handles GR, FR and ACC registers. */
for (i = 0; i < 64; ++i)
{
@@ -843,6 +856,18 @@ update_target_latencies (SIM_CPU *cpu)
}
++ccr; ++ccr_lat;
}
+ /* This loop handles SPR registers. */
+ spr = ps->spr_busy;
+ spr_lat = ps->spr_latency;
+ for (i = 0; i < 4096; ++i)
+ {
+ if (*spr_lat)
+ {
+ *spr = *spr_lat;
+ *spr_lat = 0;
+ }
+ ++spr; ++spr_lat;
+ }
}
/* Run the caches until all pending cache flushes are complete. */
@@ -1207,6 +1232,19 @@ update_CCR_latency (SIM_CPU *cpu, INT out_CCR, int cycles)
}
}
+/* Top up the latency of the given SPR by the given number of cycles. */
+void
+update_SPR_latency (SIM_CPU *cpu, INT out_SPR, int cycles)
+{
+ if (out_SPR >= 0)
+ {
+ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
+ int *spr = ps->spr_latency;
+ if (spr[out_SPR] < cycles)
+ spr[out_SPR] = cycles;
+ }
+}
+
/* Top up the latency of the given integer division resource by the given
number of cycles. */
void
@@ -1376,6 +1414,23 @@ vliw_wait_for_ACC (SIM_CPU *cpu, INT in_ACC)
}
}
+/* Check the availability of the given SPR register and update the number
+ of cycles the current VLIW insn must wait until it is available. */
+void
+vliw_wait_for_SPR (SIM_CPU *cpu, INT in_SPR)
+{
+ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
+ int *spr = ps->spr_busy;
+ /* If the latency of the register is greater than the current wait
+ then update the current wait. */
+ if (in_SPR >= 0 && spr[in_SPR] > ps->vliw_wait)
+ {
+ if (TRACE_INSN_P (cpu))
+ sprintf (hazard_name, "Data hazard for spr %d:", in_SPR);
+ ps->vliw_wait = spr[in_SPR];
+ }
+}
+
/* Check the availability of the given integer division resource and update
the number of cycles the current VLIW insn must wait until it is available.
*/