]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] c6x: fix the scheduling of floating-point multiplication instructions
authorRichard Braun <rbraun@sceen.net>
Sun, 4 Jan 2026 18:43:35 +0000 (11:43 -0700)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Sun, 4 Jan 2026 18:44:19 +0000 (11:44 -0700)
From: Richard Braun <richard.braun@sbg-systems.com>

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 <richard.braun@sbg-systems.com>
gcc/config/c6x/c6x-sched.md
gcc/config/c6x/c6x-sched.md.in
gcc/config/c6x/c6x.md

index 10e4b79642dfcfd3ec5bb577cf401f838110a7bb..0602b2df6a87b7440acfad39246344b86499aaae 100644 (file)
        (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
 
        (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
 
        (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
 
        (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")
index ccc7dc14e72a6acda06265865d0977cc66068df7..a6e8064977eacb50cc521ec7d6cf38153e16b840 100644 (file)
        (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")
index 8e2225b219d68f7cb87e03b13b9eb6cc2c766f03..370f067e686e2f9a5e5d90802d6c2876089ed627 100644 (file)
 (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.