summaryrefslogtreecommitdiff
path: root/sim/frv/profile-fr500.c
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2003-09-24 19:05:39 +0000
committerDave Brolley <brolley@redhat.com>2003-09-24 19:05:39 +0000
commit1c453cd621376a909aa0035c01f9c22d782be7fc (patch)
treea915b204d9f28fb5f7ad4d8621b8e00c2649764f /sim/frv/profile-fr500.c
parentd03124067c162553fb099983d2a6c9bf6e247284 (diff)
downloadbinutils-gdb-1c453cd621376a909aa0035c01f9c22d782be7fc.tar.gz
2003-09-24 Dave Brolley <brolley@redhat.com>
* profile.h (update_FR_ptime): New prototype. (update_FRdouble_ptime): Ditto. (update_SPR_ptime): Ditto. (increase_ACC_busy): Ditto. (enforce_full_acc_latency): Ditto. (post_wait_for_SPR): Ditto. * profile.c (update_FR_ptime): Moved here from profile-fr500.c. (update_FRdouble_ptime): Ditto. (update_SPR_ptime): New function. (increase_ACC_busy): Ditto. (enforce_full_acc_latency): Ditto. (vliw_wait_for_fdiv_resource): Correct resource name. (vliw_wait_for_fsqrt_resource): Ditto. (post_wait_for_SPR): New function. * profile-fr500.c (frvbf_model_fr500_u_commit): New function. (frvbf_model_fr500_u_gr2fr): Pass out_FRk as output register to adjust_float_register_busy. (frvbf_model_fr500_u_gr_load): Record latency of SPR registers. (frvbf_model_fr500_u_fr_load): Wait for and record latency of SPR registers. (frvbf_model_fr500_u_float_arith): Ditto. (frvbf_model_fr500_u_float_dual_arith): Ditto. (frvbf_model_fr500_u_float_div): Ditto. (frvbf_model_fr500_u_float_sqrt): Ditto. (frvbf_model_fr500_u_float_convert): Ditto. (update_FR_ptime): Moved to profile.c (update_FRdouble_ptime): Moved to profile.c * profile-fr400.c (update_FR_ptime): Removed. Identical to functions for other machines. (update_FRdouble_ptime): Ditto. * arch.h,cpu.h,sem.c,decode.[ch],model.c,sem.c: Regenerated.
Diffstat (limited to 'sim/frv/profile-fr500.c')
-rw-r--r--sim/frv/profile-fr500.c190
1 files changed, 139 insertions, 51 deletions
diff --git a/sim/frv/profile-fr500.c b/sim/frv/profile-fr500.c
index 7591d1f8210..610927c462c 100644
--- a/sim/frv/profile-fr500.c
+++ b/sim/frv/profile-fr500.c
@@ -580,6 +580,41 @@ frvbf_model_fr500_u_clrfr (SIM_CPU *cpu, const IDESC *idesc,
}
int
+frvbf_model_fr500_u_commit (SIM_CPU *cpu, const IDESC *idesc,
+ int unit_num, int referenced,
+ INT in_GRk, INT in_FRk)
+{
+ int cycles;
+
+ if (model_insn == FRV_INSN_MODEL_PASS_1)
+ {
+ /* If GR is specified, then FR is not and vice-versa. If neither is
+ then it's a commitga or commitfa. Check the insn attribute to
+ figure out which. */
+ if (in_GRk != -1)
+ vliw_wait_for_SPR (cpu, GNER_FOR_GR (in_GRk));
+ else if (in_FRk != -1)
+ vliw_wait_for_SPR (cpu, FNER_FOR_FR (in_FRk));
+ else if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_FR_ACCESS))
+ {
+ vliw_wait_for_SPR (cpu, H_SPR_FNER0);
+ vliw_wait_for_SPR (cpu, H_SPR_FNER1);
+ }
+ else
+ {
+ vliw_wait_for_SPR (cpu, H_SPR_GNER0);
+ vliw_wait_for_SPR (cpu, H_SPR_GNER1);
+ }
+ handle_resource_wait (cpu);
+ trace_vliw_wait_cycles (cpu);
+ return 0;
+ }
+
+ cycles = idesc->timing->units[unit_num].done;
+ return cycles;
+}
+
+int
frvbf_model_fr500_u_set_hilo (SIM_CPU *cpu, const IDESC *idesc,
int unit_num, int referenced,
INT out_GRkhi, INT out_GRklo)
@@ -656,9 +691,20 @@ frvbf_model_fr500_u_gr_load (SIM_CPU *cpu, const IDESC *idesc,
update_GR_latency_for_load (cpu, out_GRk, cycles);
update_GRdouble_latency_for_load (cpu, out_GRdoublek, cycles);
- set_use_is_gr_complex (cpu, out_GRk);
- set_use_is_gr_complex (cpu, out_GRdoublek);
- set_use_is_gr_complex (cpu, out_GRdoublek + 1);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ /* GNER has a latency of 2 cycles. */
+ update_SPR_latency (cpu, GNER_FOR_GR (out_GRk), cycles + 2);
+ update_SPR_latency (cpu, GNER_FOR_GR (out_GRdoublek), cycles + 2);
+ }
+
+ if (out_GRk >= 0)
+ set_use_is_gr_complex (cpu, out_GRk);
+ if (out_GRdoublek != -1)
+ {
+ set_use_is_gr_complex (cpu, out_GRdoublek);
+ set_use_is_gr_complex (cpu, out_GRdoublek + 1);
+ }
return cycles;
}
@@ -786,6 +832,11 @@ frvbf_model_fr500_u_fr_load (SIM_CPU *cpu, const IDESC *idesc,
vliw_wait_for_GR (cpu, in_GRj);
vliw_wait_for_FR (cpu, out_FRk);
vliw_wait_for_FRdouble (cpu, out_FRdoublek);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ vliw_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
+ vliw_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
+ }
handle_resource_wait (cpu);
load_wait_for_GR (cpu, in_GRi);
load_wait_for_GR (cpu, in_GRj);
@@ -802,6 +853,13 @@ frvbf_model_fr500_u_fr_load (SIM_CPU *cpu, const IDESC *idesc,
update_FR_latency_for_load (cpu, out_FRk, cycles);
update_FRdouble_latency_for_load (cpu, out_FRdoublek, cycles);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ /* FNER has a latency of 3 cycles. */
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), cycles + 3);
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), cycles + 3);
+ }
+
fr500_reset_fr_flags (cpu, out_FRk);
return cycles;
@@ -1061,7 +1119,7 @@ frvbf_model_fr500_u_gr2fr (SIM_CPU *cpu, const IDESC *idesc,
if (use_is_media (cpu, out_FRk))
decrease_FR_busy (cpu, out_FRk, 1);
else
- adjust_float_register_busy (cpu, -1, out_FRk, -1, 1);
+ adjust_float_register_busy (cpu, -1, -1, out_FRk, 1);
}
vliw_wait_for_GR (cpu, in_GRj);
vliw_wait_for_FR (cpu, out_FRk);
@@ -1385,52 +1443,6 @@ frvbf_model_fr500_u_dcul (SIM_CPU *cpu, const IDESC *idesc,
return cycles;
}
-/* Top up the post-processing time of the given FR by the given number of
- cycles. */
-static void
-update_FR_ptime (SIM_CPU *cpu, INT out_FR, int cycles)
-{
- if (out_FR >= 0)
- {
- FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
- /* If a load is pending on this register, then add the cycles to
- the post processing time for this register. Otherwise apply it
- directly to the latency of the register. */
- if (! load_pending_for_register (cpu, out_FR, 1, REGTYPE_FR))
- {
- int *fr = ps->fr_latency;
- fr[out_FR] += cycles;
- }
- else
- ps->fr_ptime[out_FR] += cycles;
- }
-}
-
-static void
-update_FRdouble_ptime (SIM_CPU *cpu, INT out_FR, int cycles)
-{
- if (out_FR >= 0)
- {
- FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
- /* If a load is pending on this register, then add the cycles to
- the post processing time for this register. Otherwise apply it
- directly to the latency of the register. */
- if (! load_pending_for_register (cpu, out_FR, 2, REGTYPE_FR))
- {
- int *fr = ps->fr_latency;
- fr[out_FR] += cycles;
- if (out_FR < 63)
- fr[out_FR + 1] += cycles;
- }
- else
- {
- ps->fr_ptime[out_FR] += cycles;
- if (out_FR < 63)
- ps->fr_ptime[out_FR + 1] += cycles;
- }
- }
-}
-
int
frvbf_model_fr500_u_float_arith (SIM_CPU *cpu, const IDESC *idesc,
int unit_num, int referenced,
@@ -1460,6 +1472,11 @@ frvbf_model_fr500_u_float_arith (SIM_CPU *cpu, const IDESC *idesc,
post_wait_for_FRdouble (cpu, in_FRdoublei);
post_wait_for_FRdouble (cpu, in_FRdoublej);
post_wait_for_FRdouble (cpu, out_FRdoublek);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
+ }
restore_float_register_busy (cpu, in_FRi, in_FRj, out_FRk, 1);
restore_double_register_busy (cpu, in_FRdoublei, in_FRdoublej, out_FRdoublek,
1);
@@ -1468,10 +1485,22 @@ frvbf_model_fr500_u_float_arith (SIM_CPU *cpu, const IDESC *idesc,
update_FR_latency (cpu, out_FRk, ps->post_wait);
update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
+ }
+
/* Once initiated, post-processing will take 3 cycles. */
update_FR_ptime (cpu, out_FRk, 3);
update_FRdouble_ptime (cpu, out_FRdoublek, 3);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 3);
+ }
+
/* Mark this use of the register as a floating point op. */
if (out_FRk >= 0)
set_use_is_fpop (cpu, out_FRk);
@@ -1536,6 +1565,13 @@ frvbf_model_fr500_u_float_dual_arith (SIM_CPU *cpu, const IDESC *idesc,
post_wait_for_FRdouble (cpu, dual_FRdoublei);
post_wait_for_FRdouble (cpu, dual_FRdoublej);
post_wait_for_FRdouble (cpu, dual_FRdoublek);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (dual_FRk));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (dual_FRdoublek));
+ }
restore_float_register_busy (cpu, in_FRi, in_FRj, out_FRk, 1);
restore_float_register_busy (cpu, dual_FRi, dual_FRj, dual_FRk, 1);
restore_double_register_busy (cpu, in_FRdoublei, in_FRdoublej, out_FRdoublek,
@@ -1549,12 +1585,28 @@ frvbf_model_fr500_u_float_dual_arith (SIM_CPU *cpu, const IDESC *idesc,
update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
update_FRdouble_latency (cpu, dual_FRdoublek, ps->post_wait);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (dual_FRk), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (dual_FRdoublek), ps->post_wait);
+ }
+
/* Once initiated, post-processing will take 3 cycles. */
update_FR_ptime (cpu, out_FRk, 3);
update_FR_ptime (cpu, dual_FRk, 3);
update_FRdouble_ptime (cpu, out_FRdoublek, 3);
update_FRdouble_ptime (cpu, dual_FRdoublek, 3);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (dual_FRk), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (dual_FRdoublek), 3);
+ }
+
/* Mark this use of the register as a floating point op. */
if (out_FRk >= 0)
set_use_is_fpop (cpu, out_FRk);
@@ -1599,6 +1651,8 @@ frvbf_model_fr500_u_float_div (SIM_CPU *cpu, const IDESC *idesc,
post_wait_for_FR (cpu, in_FRi);
post_wait_for_FR (cpu, in_FRj);
post_wait_for_FR (cpu, out_FRk);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
vliw = CPU_VLIW (cpu);
slot = vliw->next_slot - 1;
slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
@@ -1610,6 +1664,13 @@ frvbf_model_fr500_u_float_div (SIM_CPU *cpu, const IDESC *idesc,
update_FR_latency (cpu, out_FRk, ps->post_wait);
update_FR_ptime (cpu, out_FRk, 10);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ /* FNER has a latency of 10 cycles. */
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 10);
+ }
+
/* The latency of the fdiv unit will be at least the latency of the other
inputs. Once initiated, post-processing will take 9 cycles. */
update_fdiv_resource_latency (cpu, slot, ps->post_wait + 9);
@@ -1646,6 +1707,8 @@ frvbf_model_fr500_u_float_sqrt (SIM_CPU *cpu, const IDESC *idesc,
post_wait_for_FR (cpu, out_FRk);
post_wait_for_FRdouble (cpu, in_FRdoublej);
post_wait_for_FRdouble (cpu, out_FRdoublek);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
vliw = CPU_VLIW (cpu);
slot = vliw->next_slot - 1;
slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
@@ -1656,11 +1719,16 @@ frvbf_model_fr500_u_float_sqrt (SIM_CPU *cpu, const IDESC *idesc,
/* The latency of FRk will be at least the latency of the other inputs. */
update_FR_latency (cpu, out_FRk, ps->post_wait);
update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
/* Once initiated, post-processing will take 15 cycles. */
update_FR_ptime (cpu, out_FRk, 15);
update_FRdouble_ptime (cpu, out_FRdoublek, 15);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 15);
+
/* The latency of the sqrt unit will be the latency of the other
inputs plus 14 cycles. */
update_fsqrt_resource_latency (cpu, slot, ps->post_wait + 14);
@@ -1844,6 +1912,12 @@ frvbf_model_fr500_u_float_convert (SIM_CPU *cpu, const IDESC *idesc,
post_wait_for_FR (cpu, out_FRk);
post_wait_for_FR (cpu, out_FRintk);
post_wait_for_FRdouble (cpu, out_FRdoublek);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRintk));
+ post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
+ }
restore_float_register_busy (cpu, -1, in_FRj, out_FRk, 1);
restore_float_register_busy (cpu, -1, in_FRintj, out_FRintk, 1);
restore_double_register_busy (cpu, -1, in_FRdoublej, out_FRdoublek, 1);
@@ -1853,11 +1927,25 @@ frvbf_model_fr500_u_float_convert (SIM_CPU *cpu, const IDESC *idesc,
update_FR_latency (cpu, out_FRintk, ps->post_wait);
update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRintk), ps->post_wait);
+ update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
+ }
+
/* Once initiated, post-processing will take 3 cycles. */
update_FR_ptime (cpu, out_FRk, 3);
update_FR_ptime (cpu, out_FRintk, 3);
update_FRdouble_ptime (cpu, out_FRdoublek, 3);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRintk), 3);
+ update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 3);
+ }
+
/* Mark this use of the register as a floating point op. */
if (out_FRk >= 0)
set_use_is_fpop (cpu, out_FRk);
@@ -2632,7 +2720,7 @@ frvbf_model_fr500_u_media_dual_expand (SIM_CPU *cpu, const IDESC *idesc,
if (dual_FRk >= 0)
fr[dual_FRk] += busy_adjustment[2];
- /* The latency of tht output register will be at least the latency of the
+ /* The latency of the output register will be at least the latency of the
other inputs. Once initiated, post-processing will take 3 cycles. */
update_FR_latency (cpu, out_FRk, ps->post_wait);
update_FR_ptime (cpu, out_FRk, 3);