[gcc r16-6487] [PATCH] c6x: fix the scheduling of floating-point multiplication instructions
Jeff Law
law@gcc.gnu.org
Sun Jan 4 18:44:51 GMT 2026
https://gcc.gnu.org/g:2971767bc77a48dd57e87b0e95b6b9ca0a76a356
commit r16-6487-g2971767bc77a48dd57e87b0e95b6b9ca0a76a356
Author: Richard Braun <rbraun@sceen.net>
Date: Sun Jan 4 11:43:35 2026 -0700
[PATCH] c6x: fix the scheduling of floating-point multiplication instructions
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>
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.
More information about the Gcc-cvs
mailing list