This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch] Model Latency of SPR registers
- From: Dave Brolley <brolley at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 12 Sep 2003 18:16:28 -0400
- Subject: [patch] Model Latency of SPR registers
I've committed the attached patch which:
1) Corrects the range of ACC registers checked for fr400 in
frv_check_spr_read_access
2) Removes some unused variables from functions is profile-fr500.c
3) Adds the capability to model latency of SPR registers and applies it
to the *div*, clrg*, clrf*, movsg and movgs insns.
Dave
2003-09-12 Dave Brolley <brolley@redhat.com>
* frv.cpu (u-clrgr, u-clrfr): New units of model fr500.
(clear-ne-flag-r): Pass insn profiling in as an argument. Call
frv_ref_SI to get input register referenced for profiling.
(clear-ne-flag-all): Pass insn profiling in as an argument.
(clrgr,clrfr,clrga,clrfa): Add profiling information.
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.
Index: cpu/frv.cpu
===================================================================
RCS file: /cvs/src/src/cpu/frv.cpu,v
retrieving revision 1.9
diff -c -p -r1.9 frv.cpu
*** cpu/frv.cpu 9 Sep 2003 22:27:28 -0000 1.9
--- cpu/frv.cpu 12 Sep 2003 21:58:31 -0000
***************
*** 1,6 ****
; Fujitsu FRV opcode support, for GNU Binutils. -*- Scheme -*-
;
! ; Copyright 2000, 2001 Free Software Foundation, Inc.
;
; Contributed by Red Hat Inc; developed under contract from Fujitsu.
;
--- 1,6 ----
; Fujitsu FRV opcode support, for GNU Binutils. -*- Scheme -*-
;
! ; Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
;
; Contributed by Red Hat Inc; developed under contract from Fujitsu.
;
***************
*** 158,163 ****
--- 158,179 ----
() ; outputs
() ; profile action (default)
)
+ ; Clrgr unit
+ (unit u-clrgr "Clrgr Unit" ()
+ 1 1 ; issue done
+ () ; state
+ ((GRk INT -1)) ; inputs
+ () ; outputs
+ () ; profile action (default)
+ )
+ ; Clrfr unit
+ (unit u-clrfr "Clrfr Unit" ()
+ 1 1 ; issue done
+ () ; state
+ ((FRk INT -1)) ; inputs
+ () ; outputs
+ () ; profile action (default)
+ )
; GR set half unit
(unit u-set-hilo "GR Set Half" ()
1 1 ; issue done
***************
*** 5734,5766 ****
(c-call VOID "@cpu@_clear_ne_flags" target_index is_float)
)
! (define-pmacro (clear-ne-flag-r name op ope reg is_float attr comment)
(dni name
(comment)
((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
(.str name "$pack $" reg "k")
(+ pack (.sym reg k) op (rs-null) ope (GRj-null))
! (clear-ne-flag-semantics (index-of (.sym reg k)) is_float)
! ()
)
)
! (clear-ne-flag-r clrgr OP_0A OPE1_00 GR 0 NA "Clear GR NE flag")
! (clear-ne-flag-r clrfr OP_0A OPE1_02 FR 1 FR-ACCESS "Clear FR NE flag")
! (define-pmacro (clear-ne-flag-all name op ope is_float attr comment)
(dni name
(comment)
((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
(.str name "$pack")
(+ pack (rd-null) op (rs-null) ope (GRj-null))
(clear-ne-flag-semantics -1 is_float)
! ()
)
)
! (clear-ne-flag-all clrga OP_0A OPE1_01 0 NA "Clear GR NE flag ALL")
! (clear-ne-flag-all clrfa OP_0A OPE1_03 1 FR-ACCESS "Clear FR NE flag ALL")
(define-pmacro (commit-semantics target_index is_float)
(c-call VOID "@cpu@_commit" target_index is_float)
--- 5750,5793 ----
(c-call VOID "@cpu@_clear_ne_flags" target_index is_float)
)
! (define-pmacro (clear-ne-flag-r name op ope reg is_float attr profile comment)
(dni name
(comment)
((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
(.str name "$pack $" reg "k")
(+ pack (.sym reg k) op (rs-null) ope (GRj-null))
! (sequence ()
! ; hack to get this referenced for profiling
! (c-raw-call VOID "frv_ref_SI" (.sym reg k))
! (clear-ne-flag-semantics (index-of (.sym reg k)) is_float))
! profile
)
)
! (clear-ne-flag-r clrgr OP_0A OPE1_00 GR 0 NA
! ((fr500 (unit u-clrgr)))
! "Clear GR NE flag")
! (clear-ne-flag-r clrfr OP_0A OPE1_02 FR 1 FR-ACCESS
! ((fr500 (unit u-clrfr)))
! "Clear FR NE flag")
! (define-pmacro (clear-ne-flag-all name op ope is_float attr profile comment)
(dni name
(comment)
((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
(.str name "$pack")
(+ pack (rd-null) op (rs-null) ope (GRj-null))
(clear-ne-flag-semantics -1 is_float)
! profile
)
)
! (clear-ne-flag-all clrga OP_0A OPE1_01 0 NA
! ((fr500 (unit u-clrgr)))
! "Clear GR NE flag ALL")
! (clear-ne-flag-all clrfa OP_0A OPE1_03 1 FR-ACCESS
! ((fr500 (unit u-clrfr)))
Index: sim/frv/frv-sim.h
===================================================================
RCS file: /cvs/src/src/sim/frv/frv-sim.h,v
retrieving revision 1.1
diff -c -p -r1.1 frv-sim.h
*** sim/frv/frv-sim.h 29 Aug 2003 16:35:46 -0000 1.1
--- sim/frv/frv-sim.h 12 Sep 2003 21:58:37 -0000
***************
*** 1,5 ****
/* collection of junk waiting time to sort out
! Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
--- 1,5 ----
/* collection of junk waiting time to sort out
! Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
*************** with this program; if not, write to the
*** 24,32 ****
#include "sim-options.h"
/* Not defined in the cgen cpu file for access restriction purposes. */
! #define H_SPR_ACC0 1408
#define H_SPR_ACC63 1471
! #define H_SPR_ACCG0 1472
#define H_SPR_ACCG63 1535
/* gdb register numbers. */
--- 24,32 ----
#include "sim-options.h"
/* Not defined in the cgen cpu file for access restriction purposes. */
! #define H_SPR_ACC4 1412
#define H_SPR_ACC63 1471
! #define H_SPR_ACCG4 1476
#define H_SPR_ACCG63 1535
/* gdb register numbers. */
Index: sim/frv/profile-fr500.c
===================================================================
RCS file: /cvs/src/src/sim/frv/profile-fr500.c,v
retrieving revision 1.1
diff -c -p -r1.1 profile-fr500.c
*** sim/frv/profile-fr500.c 29 Aug 2003 16:35:46 -0000 1.1
--- sim/frv/profile-fr500.c 12 Sep 2003 21:58:38 -0000
***************
*** 1,6 ****
/* frv simulator fr500 dependent profiling code.
! Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat
This file is part of the GNU simulators.
--- 1,6 ----
/* frv simulator fr500 dependent profiling code.
! Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Red Hat
This file is part of the GNU simulators.
*************** frvbf_model_fr500_u_idiv (SIM_CPU *cpu,
*** 382,387 ****
--- 382,393 ----
update_CCR_latency (cpu, out_ICCi_1, cycles + 19);
set_use_is_cc_complex (cpu, out_ICCi_1);
+ if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
+ {
+ /* GNER has a latency of 18 cycles. */
+ update_SPR_latency (cpu, GNER_FOR_GR (out_GRk), cycles + 18);
+ }
+
/* the idiv resource has a latency of 18 cycles! */
update_idiv_resource_latency (cpu, slot, cycles + 18);
*************** frvbf_model_fr500_u_trap (SIM_CPU *cpu,
*** 458,464 ****
INT in_ICCi_2, INT in_FCCi_2)
{
int cycles;
- FRV_PROFILE_STATE *ps;
if (model_insn == FRV_INSN_MODEL_PASS_1)
{
--- 464,469 ----
*************** frvbf_model_fr500_u_check (SIM_CPU *cpu,
*** 502,508 ****
INT in_ICCi_3, INT in_FCCi_3)
{
int cycles;
- FRV_PROFILE_STATE *ps;
if (model_insn == FRV_INSN_MODEL_PASS_1)
{
--- 507,512 ----
*************** frvbf_model_fr500_u_check (SIM_CPU *cpu,
*** 524,529 ****
--- 528,585 ----
}
int
+ frvbf_model_fr500_u_clrgr (SIM_CPU *cpu, const IDESC *idesc,
+ int unit_num, int referenced,
+ INT in_GRk)
+ {
+ int cycles;
+
+ if (model_insn == FRV_INSN_MODEL_PASS_1)
+ {
+ /* Wait for both GNER registers or just the one specified. */
+ if (in_GRk == -1)
+ {
+ vliw_wait_for_SPR (cpu, H_SPR_GNER0);
+ vliw_wait_for_SPR (cpu, H_SPR_GNER1);
+ }
+ else
+ vliw_wait_for_SPR (cpu, GNER_FOR_GR (in_GRk));
+ 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_clrfr (SIM_CPU *cpu, const IDESC *idesc,
+ int unit_num, int referenced,
+ INT in_FRk)
+ {
+ int cycles;
+
+ if (model_insn == FRV_INSN_MODEL_PASS_1)
+ {
+ /* Wait for both GNER registers or just the one specified. */
+ if (in_FRk == -1)
+ {
+ vliw_wait_for_SPR (cpu, H_SPR_FNER0);
+ vliw_wait_for_SPR (cpu, H_SPR_FNER1);
+ }
+ else
+ vliw_wait_for_SPR (cpu, FNER_FOR_FR (in_FRk));
+ 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)
*************** frvbf_model_fr500_u_spr2gr (SIM_CPU *cpu
*** 962,969 ****
if (model_insn == FRV_INSN_MODEL_PASS_1)
{
/* The entire VLIW insn must wait if there is a dependency on a register
! which is not ready yet.
! SPR registers appear to have no latency effects. */
vliw_wait_for_GR (cpu, out_GRj);
handle_resource_wait (cpu);
load_wait_for_GR (cpu, out_GRj);
--- 1018,1025 ----
if (model_insn == FRV_INSN_MODEL_PASS_1)
{
/* The entire VLIW insn must wait if there is a dependency on a register
! which is not ready yet. */
! vliw_wait_for_SPR (cpu, in_spr);
vliw_wait_for_GR (cpu, out_GRj);
handle_resource_wait (cpu);
load_wait_for_GR (cpu, out_GRj);
*************** frvbf_model_fr500_u_gr2spr (SIM_CPU *cpu
*** 1046,1051 ****
--- 1102,1108 ----
decrease_GR_busy (cpu, in_GRj, 1);
}
vliw_wait_for_GR (cpu, in_GRj);
+ vliw_wait_for_SPR (cpu, out_spr);
handle_resource_wait (cpu);
load_wait_for_GR (cpu, in_GRj);
trace_vliw_wait_cycles (cpu);
Index: sim/frv/profile.c
===================================================================
RCS file: /cvs/src/src/sim/frv/profile.c,v
retrieving revision 1.2
diff -c -p -r1.2 profile.c
*** sim/frv/profile.c 10 Sep 2003 20:40:47 -0000 1.2
--- sim/frv/profile.c 12 Sep 2003 21:58:39 -0000
*************** update_latencies (SIM_CPU *cpu, int cycl
*** 681,686 ****
--- 681,687 ----
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)
{
*************** update_latencies (SIM_CPU *cpu, int cycl
*** 734,739 ****
--- 735,750 ----
*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;
*************** update_target_latencies (SIM_CPU *cpu)
*** 805,814 ****
--- 816,827 ----
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)
{
*************** update_target_latencies (SIM_CPU *cpu)
*** 843,848 ****
--- 856,873 ----
}
++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. */
*************** update_CCR_latency (SIM_CPU *cpu, INT ou
*** 1207,1212 ****
--- 1232,1250 ----
}
}
+ /* 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
*************** vliw_wait_for_ACC (SIM_CPU *cpu, INT in_
*** 1373,1378 ****
--- 1411,1433 ----
if (TRACE_INSN_P (cpu))
sprintf (hazard_name, "Data hazard for acc%d:", in_ACC);
ps->vliw_wait = acc[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];
}
}
Index: sim/frv/profile.h
===================================================================
RCS file: /cvs/src/src/sim/frv/profile.h,v
retrieving revision 1.1
diff -c -p -r1.1 profile.h
*** sim/frv/profile.h 29 Aug 2003 16:35:46 -0000 1.1
--- sim/frv/profile.h 12 Sep 2003 21:58:39 -0000
***************
*** 1,5 ****
/* Profiling definitions for the FRV simulator
! Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
--- 1,5 ----
/* Profiling definitions for the FRV simulator
! Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
*************** with this program; if not, write to the
*** 21,26 ****
--- 21,28 ----
#ifndef PROFILE_H
#define PROFILE_H
+ #include "frv-desc.h"
+
/* This struct defines the state of profiling. All fields are of general
use to all machines. */
typedef struct
*************** typedef struct
*** 39,44 ****
--- 41,47 ----
int fr_busy[64]; /* Cycles until FR is available. */
int acc_busy[64]; /* Cycles until FR is available. */
int ccr_busy[8]; /* Cycles until ICC/FCC is available. */
+ int spr_busy[4096]; /* Cycles until spr is available. */
int idiv_busy[2]; /* Cycles until integer division unit is available. */
int fdiv_busy[2]; /* Cycles until float division unit is available. */
int fsqrt_busy[2]; /* Cycles until square root unit is available. */
*************** typedef struct
*** 48,53 ****
--- 51,57 ----
int fr_latency[64]; /* Cycles until target FR is available. */
int acc_latency[64]; /* Cycles until target FR is available. */
int ccr_latency[8]; /* Cycles until target ICC/FCC is available. */
+ int spr_latency[4096]; /* Cycles until target spr is available. */
/* Some registers are busy for a shorter number of cycles than normal
depending on how they are used next. the xxx_busy_adjust arrays keep track
*************** typedef struct
*** 84,89 ****
--- 88,106 ----
#define DUAL_REG(reg) ((reg) >= 0 && (reg) < 63 ? (reg) + 1 : -1)
#define DUAL_DOUBLE(reg) ((reg) >= 0 && (reg) < 61 ? (reg) + 2 : -1)
+ /* Return the GNER register associated with the given GR register.
+ There is no GNER associated with gr0. */
+ #define GNER_FOR_GR(gr) ((gr) > 63 ? -1 : \
+ (gr) > 31 ? H_SPR_GNER0 : \
+ (gr) > 0 ? H_SPR_GNER1 : \
+ -1)
+ /* Return the GNER register associated with the given GR register.
+ There is no GNER associated with gr0. */
+ #define FNER_FOR_FR(fr) ((fr) > 63 ? -1 : \
+ (fr) > 31 ? H_SPR_FNER0 : \
+ (fr) > 0 ? H_SPR_FNER1 : \
+ -1)
+
/* Top up the latency of the given GR by the given number of cycles. */
void update_GR_latency (SIM_CPU *, INT, int);
void update_GRdouble_latency (SIM_CPU *, INT, int);
*************** void decrease_GR_busy (SIM_CPU *, INT, i
*** 100,105 ****
--- 117,123 ----
void increase_FR_busy (SIM_CPU *, INT, int);
void update_ACC_latency (SIM_CPU *, INT, int);
void update_CCR_latency (SIM_CPU *, INT, int);
+ void update_SPR_latency (SIM_CPU *, INT, int);
void update_idiv_resource_latency (SIM_CPU *, INT, int);
void update_fdiv_resource_latency (SIM_CPU *, INT, int);
void update_fsqrt_resource_latency (SIM_CPU *, INT, int);
*************** void vliw_wait_for_FR (SIM_CPU *, INT);
*** 111,116 ****
--- 129,135 ----
void vliw_wait_for_FRdouble (SIM_CPU *, INT);
void vliw_wait_for_CCR (SIM_CPU *, INT);
void vliw_wait_for_ACC (SIM_CPU *, INT);
+ void vliw_wait_for_SPR (SIM_CPU *, INT);
void vliw_wait_for_idiv_resource (SIM_CPU *, INT);
void vliw_wait_for_fdiv_resource (SIM_CPU *, INT);
void vliw_wait_for_fsqrt_resource (SIM_CPU *, INT);
Index: sim/frv/registers.c
===================================================================
RCS file: /cvs/src/src/sim/frv/registers.c,v
retrieving revision 1.1
diff -c -p -r1.1 registers.c
*** sim/frv/registers.c 29 Aug 2003 16:35:46 -0000 1.1
--- sim/frv/registers.c 12 Sep 2003 21:58:39 -0000
***************
*** 1,5 ****
/* frv simulator support code
! Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
--- 1,5 ----
/* frv simulator support code
! Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
*************** frv_check_spr_read_access (SIM_CPU *curr
*** 4278,4285 ****
/* On the fr400: if this is an unimplemented accumulator, then
generate an illegal_instruction_interrupt, otherwise no interrupt.
*/
! if (spr >= H_SPR_ACC0 && spr <= H_SPR_ACC63
! || spr >= H_SPR_ACCG0 && spr <= H_SPR_ACCG63)
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
}
else
--- 4278,4285 ----
/* On the fr400: if this is an unimplemented accumulator, then
generate an illegal_instruction_interrupt, otherwise no interrupt.
*/
! if (spr >= H_SPR_ACC4 && spr <= H_SPR_ACC63
! || spr >= H_SPR_ACCG4 && spr <= H_SPR_ACCG63)
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
}
else