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.

Reply via email to