From: Richard Braun Date: Sun, 4 Jan 2026 18:43:35 +0000 (-0700) Subject: [PATCH] c6x: fix the scheduling of floating-point multiplication instructions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2971767bc77a48dd57e87b0e95b6b9ca0a76a356;p=thirdparty%2Fgcc.git [PATCH] c6x: fix the scheduling of floating-point multiplication instructions From: Richard Braun 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 --- diff --git a/gcc/config/c6x/c6x-sched.md b/gcc/config/c6x/c6x-sched.md index 10e4b79642d..0602b2df6a8 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 ccc7dc14e72..a6e8064977e 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 8e2225b219d..370f067e686 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.