https://gcc.gnu.org/g:2971767bc77a48dd57e87b0e95b6b9ca0a76a356
commit r16-6487-g2971767bc77a48dd57e87b0e95b6b9ca0a76a356 Author: Richard Braun <[email protected]> Date: Sun Jan 4 11:43:35 2026 -0700 [PATCH] c6x: fix the scheduling of floating-point multiplication instructions From: Richard Braun <[email protected]> Instructions have two time-related units associated with them: the number of delay slots, and the functional unit latency. But some floating-point multiplication instructions have a functional unit latency that actually varies depending on the following instructions scheduled on the same functional unit [1]. For example, the MPYDP instruction is described with a functional unit latency of 4, but there are additional "cycle-other resource conflicts" with a following MPYSPDP instruction. In order to describe that, this patch introduces one pseudo functional unit per affected instruction, and augments reservations individually for all implemented instructions that may be affected when following. [1] 4.3.2 .M-Unit Constraints - SPRUFE8B TMS320C674x DSP CPU and Instruction Set Reference Guide gcc/ * config/c6x/c6x-sched.md.in (mpydp_m_N__CROSS_, mpyspdp_m_N__CROSS_, mpysp2dp_m_N__CROSS_): Update reservations. * config/c6x/c6x-sched.md: Regenerated. * config/c6x/c6x.md (m1dp, m1spdp, m2dp, m2spdp): New CPU units. Signed-off-by: Richard Braun <[email protected]> Diff: --- gcc/config/c6x/c6x-sched.md | 24 ++++++++++++------------ gcc/config/c6x/c6x-sched.md.in | 6 +++--- gcc/config/c6x/c6x.md | 4 ++++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/gcc/config/c6x/c6x-sched.md b/gcc/config/c6x/c6x-sched.md index 10e4b79642df..0602b2df6a87 100644 --- a/gcc/config/c6x/c6x-sched.md +++ b/gcc/config/c6x/c6x-sched.md @@ -218,21 +218,21 @@ (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "(m1)*4,nothing*4,m1w*2") + "(m1)*4+m1dp*4,m1spdp*3,nothing,m1w*2") (define_insn_reservation "mpyspdp_m1n" 7 (and (eq_attr "type" "mpyspdp") (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "(m1)*2,nothing*3,m1w*2") + "(m1)*3+m1spdp*3,m1dp,nothing,m1w*2") (define_insn_reservation "mpysp2dp_m1n" 5 (and (eq_attr "type" "mpysp2dp") (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "m1,nothing*2,m1w*2") + "(m1)*2+m1dp*2+m1spdp*2,nothing,m1w*2") ;; Definitions for side 2, cross n @@ -451,21 +451,21 @@ (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "(m2)*4,nothing*4,m2w*2") + "(m2)*4+m2dp*4,m2spdp*3,nothing,m2w*2") (define_insn_reservation "mpyspdp_m2n" 7 (and (eq_attr "type" "mpyspdp") (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "(m2)*2,nothing*3,m2w*2") + "(m2)*3+m2spdp*3,m2dp,nothing,m2w*2") (define_insn_reservation "mpysp2dp_m2n" 5 (and (eq_attr "type" "mpysp2dp") (and (eq_attr "cross" "n") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "m2,nothing*2,m2w*2") + "(m2)*2+m2dp*2+m2spdp*2,nothing,m2w*2") ;; Definitions for side 1, cross y @@ -684,21 +684,21 @@ (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "(m1+x1)*4,nothing*4,m1w*2") + "(m1+x1)*4+m1dp*4,m1spdp*3,nothing,m1w*2") (define_insn_reservation "mpyspdp_m1y" 7 (and (eq_attr "type" "mpyspdp") (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "(m1+x1)*2,nothing*3,m1w*2") + "(m1+x1)*3+m1spdp*3,m1dp,nothing,m1w*2") (define_insn_reservation "mpysp2dp_m1y" 5 (and (eq_attr "type" "mpysp2dp") (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "a")))) - "m1+x1,nothing*2,m1w*2") + "(m1+x1)*2+m1dp*2+m1spdp*2,nothing,m1w*2") ;; Definitions for side 2, cross y @@ -917,18 +917,18 @@ (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "(m2+x2)*4,nothing*4,m2w*2") + "(m2+x2)*4+m2dp*4,m2spdp*3,nothing,m2w*2") (define_insn_reservation "mpyspdp_m2y" 7 (and (eq_attr "type" "mpyspdp") (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "(m2+x2)*2,nothing*3,m2w*2") + "(m2+x2)*3+m2spdp*3,m2dp,nothing,m2w*2") (define_insn_reservation "mpysp2dp_m2y" 5 (and (eq_attr "type" "mpysp2dp") (and (eq_attr "cross" "y") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "b")))) - "m2+x2,nothing*2,m2w*2") + "(m2+x2)*2+m2dp*2+m2spdp*2,nothing,m2w*2") diff --git a/gcc/config/c6x/c6x-sched.md.in b/gcc/config/c6x/c6x-sched.md.in index ccc7dc14e72a..a6e8064977ea 100644 --- a/gcc/config/c6x/c6x-sched.md.in +++ b/gcc/config/c6x/c6x-sched.md.in @@ -213,18 +213,18 @@ (and (eq_attr "cross" "_CROSS_") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "_RF_")))) - "(m_N__CUNIT_)*4,nothing*4,m_N_w*2") + "(m_N__CUNIT_)*4+m_N_dp*4,m_N_spdp*3,nothing,m_N_w*2") (define_insn_reservation "mpyspdp_m_N__CROSS_" 7 (and (eq_attr "type" "mpyspdp") (and (eq_attr "cross" "_CROSS_") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "_RF_")))) - "(m_N__CUNIT_)*2,nothing*3,m_N_w*2") + "(m_N__CUNIT_)*3+m_N_spdp*3,m_N_dp,nothing,m_N_w*2") (define_insn_reservation "mpysp2dp_m_N__CROSS_" 5 (and (eq_attr "type" "mpysp2dp") (and (eq_attr "cross" "_CROSS_") (and (eq_attr "units" "m") (eq_attr "dest_regfile" "_RF_")))) - "m_N__CUNIT_,nothing*2,m_N_w*2") + "(m_N__CUNIT_)*2+m_N_dp*2+m_N_spdp*2,nothing,m_N_w*2") diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md index 8e2225b219d6..370f067e686e 100644 --- a/gcc/config/c6x/c6x.md +++ b/gcc/config/c6x/c6x.md @@ -274,12 +274,16 @@ (define_cpu_unit "l1w,s1w" "c6x_1") (define_query_cpu_unit "m1" "c6x_m1") (define_cpu_unit "m1w" "c6x_m1") +(define_cpu_unit "m1dp" "c6x_m1") +(define_cpu_unit "m1spdp" "c6x_m1") (define_cpu_unit "t1" "c6x_t1") (define_query_cpu_unit "d2,l2,s2" "c6x_2") (define_cpu_unit "x2" "c6x_2") (define_cpu_unit "l2w,s2w" "c6x_2") (define_query_cpu_unit "m2" "c6x_m2") (define_cpu_unit "m2w" "c6x_m2") +(define_cpu_unit "m2dp" "c6x_m1") +(define_cpu_unit "m2spdp" "c6x_m2") (define_cpu_unit "t2" "c6x_t2") ;; A special set of units used to identify specific reservations, rather than ;; just units.
