Commit eda328bf by Pat Haugen Committed by Pat Haugen

rs6000.md ('type' attribute): Add htmsimple/dfp types.

	* config/rs6000/rs6000.md ('type' attribute): Add htmsimple/dfp types.
	('size' attribute): Add '128'.
	Include power9.md.
	(*mov<mode>_hardfloat32, *mov<mode>_hardfloat64, *movdi_internal32,
	*movdi_internal64, *movdf_update1): Set size attribute to '64'.
	(add<mode>3, sub<mode>3, mul<mode>3, div<mode>3, sqrt<mode>2,
	copysign<mode>3, neg<mode>2_hw, abs<mode>2_hw, *nabs<mode>2_hw,
	*fma<mode>4_hw, *fms<mode>4_hw, *nfma<mode>4_hw, *nfms<mode>4_hw,
	extend<SFDF:mode><IEEE128:mode>2_hw, trunc<mode>df2_hw,
	*xscvqp<su>wz_<mode>, *xscvqp<su>dz_<mode>, *xscv<su>dqp_<mode>,
	*trunc<mode>df2_odd): Set size attribute to '128'.
	(*cmp<mode>_hw): Change type to veccmp and set size attribute to '128'.
	* config/rs6000/power6.md (power6-fp): Include dfp type.
	* config/rs6000/power7.md (power7-fp): Likewise.
	* config/rs6000/power8.md (power8-fp): Likewise.
	* config/rs6000/power9.md: New file.
	* config/rs6000/t-rs6000 (MD_INCLUDES): Add power9.md.
	* config/rs6000/htm.md (*tabort, *tabort<wd>c, *tabort<wd>ci,
	*trechkpt, *treclaim, *tsr, *ttest): Change type attribute to
	htmsimple.
	* config/rs6000/dfp.md (extendsddd2, truncddsd2, extendddtd2,
	trunctddd2, adddd3, addtd3, subdd3, subtd3, muldd3, multd3, divdd3,
	divtd3, *cmpdd_internal1, *cmptd_internal1, floatdidd2, floatditd2,
	ftruncdd2, fixdddi2, ftrunctd2, fixtddi2, dfp_ddedpd_<mode>,
	dfp_denbcd_<mode>, dfp_dxex_<mode>, dfp_diex_<mode>, dfp_dscli_<mode>,
	dfp_dscri_<mode>): Change type attribute to dfp.
	* config/rs6000/crypto.md (crypto_vshasigma<CR_char>): Change type
	attribute to vecsimple.
	* config/rs6000/rs6000.c (power9_cost): Update costs, cache size
	and prefetch streams.
	(rs6000_option_override_internal): Remove temporary code setting
	tuning to power8.  Don't set rs6000_sched_groups for power9.
	(last_scheduled_insn): Change to rtx_insn *.
	(divide_cnt, vec_load_pendulum): New variables.
	(rs6000_adjust_cost): Add Power9 to test for store->load separation.
	(rs6000_issue_rate): Set issue rate for Power9.
	(is_power9_pairable_vec_type): New.
	(power9_sched_reorder2): New.
	(rs6000_sched_reorder2): Call new function for Power9 specific
	reordering.
	(insn_must_be_first_in_group): Remove Power9.
	(insn_must_be_last_in_group): Likewise.
	(force_new_group): Likewise.
	(rs6000_sched_init): Fix initialization of last_scheduled_insn.
	Initialize divide_cnt/vec_load_pendulum.
	(_rs6000_sched_context, rs6000_init_sched_context,
	rs6000_set_sched_context): Handle context save/restore of new
	variables.

From-SVN: r237820
parent 7d4cdbd4
2016-06-28 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/rs6000.md ('type' attribute): Add htmsimple/dfp types.
('size' attribute): Add '128'.
Include power9.md.
(*mov<mode>_hardfloat32, *mov<mode>_hardfloat64, *movdi_internal32,
*movdi_internal64, *movdf_update1): Set size attribute to '64'.
(add<mode>3, sub<mode>3, mul<mode>3, div<mode>3, sqrt<mode>2,
copysign<mode>3, neg<mode>2_hw, abs<mode>2_hw, *nabs<mode>2_hw,
*fma<mode>4_hw, *fms<mode>4_hw, *nfma<mode>4_hw, *nfms<mode>4_hw,
extend<SFDF:mode><IEEE128:mode>2_hw, trunc<mode>df2_hw,
*xscvqp<su>wz_<mode>, *xscvqp<su>dz_<mode>, *xscv<su>dqp_<mode>,
*trunc<mode>df2_odd): Set size attribute to '128'.
(*cmp<mode>_hw): Change type to veccmp and set size attribute to '128'.
* config/rs6000/power6.md (power6-fp): Include dfp type.
* config/rs6000/power7.md (power7-fp): Likewise.
* config/rs6000/power8.md (power8-fp): Likewise.
* config/rs6000/power9.md: New file.
* config/rs6000/t-rs6000 (MD_INCLUDES): Add power9.md.
* config/rs6000/htm.md (*tabort, *tabort<wd>c, *tabort<wd>ci,
*trechkpt, *treclaim, *tsr, *ttest): Change type attribute to
htmsimple.
* config/rs6000/dfp.md (extendsddd2, truncddsd2, extendddtd2,
trunctddd2, adddd3, addtd3, subdd3, subtd3, muldd3, multd3, divdd3,
divtd3, *cmpdd_internal1, *cmptd_internal1, floatdidd2, floatditd2,
ftruncdd2, fixdddi2, ftrunctd2, fixtddi2, dfp_ddedpd_<mode>,
dfp_denbcd_<mode>, dfp_dxex_<mode>, dfp_diex_<mode>, dfp_dscli_<mode>,
dfp_dscri_<mode>): Change type attribute to dfp.
* config/rs6000/crypto.md (crypto_vshasigma<CR_char>): Change type
attribute to vecsimple.
* config/rs6000/rs6000.c (power9_cost): Update costs, cache size
and prefetch streams.
(rs6000_option_override_internal): Remove temporary code setting
tuning to power8. Don't set rs6000_sched_groups for power9.
(last_scheduled_insn): Change to rtx_insn *.
(divide_cnt, vec_load_pendulum): New variables.
(rs6000_adjust_cost): Add Power9 to test for store->load separation.
(rs6000_issue_rate): Set issue rate for Power9.
(is_power9_pairable_vec_type): New.
(power9_sched_reorder2): New.
(rs6000_sched_reorder2): Call new function for Power9 specific
reordering.
(insn_must_be_first_in_group): Remove Power9.
(insn_must_be_last_in_group): Likewise.
(force_new_group): Likewise.
(rs6000_sched_init): Fix initialization of last_scheduled_insn.
Initialize divide_cnt/vec_load_pendulum.
(_rs6000_sched_context, rs6000_init_sched_context,
rs6000_set_sched_context): Handle context save/restore of new
variables.
2016-06-28 Richard Biener <rguenther@suse.de> 2016-06-28 Richard Biener <rguenther@suse.de>
* tree-ssa-alias.c (nonoverlapping_component_refs_of_decl_p): * tree-ssa-alias.c (nonoverlapping_component_refs_of_decl_p):
......
...@@ -107,4 +107,4 @@ ...@@ -107,4 +107,4 @@
UNSPEC_VSHASIGMA))] UNSPEC_VSHASIGMA))]
"TARGET_CRYPTO" "TARGET_CRYPTO"
"vshasigma<CR_char> %0,%1,%2,%3" "vshasigma<CR_char> %0,%1,%2,%3"
[(set_attr "type" "crypto")]) [(set_attr "type" "vecsimple")])
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
(float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))] (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
"TARGET_DFP" "TARGET_DFP"
"dctdp %0,%1" "dctdp %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_expand "extendsdtd2" (define_expand "extendsdtd2"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
(float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))] (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"drsp %0,%1" "drsp %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_expand "negdd2" (define_expand "negdd2"
[(set (match_operand:DD 0 "gpc_reg_operand" "") [(set (match_operand:DD 0 "gpc_reg_operand" "")
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
(float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))] (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dctqpq %0,%1" "dctqpq %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; The result of drdpq is an even/odd register pair with the converted ;; The result of drdpq is an even/odd register pair with the converted
;; value in the even register and zero in the odd register. ;; value in the even register and zero in the odd register.
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
(clobber (match_scratch:TD 2 "=d"))] (clobber (match_scratch:TD 2 "=d"))]
"TARGET_DFP" "TARGET_DFP"
"drdpq %2,%1\;fmr %0,%2" "drdpq %2,%1\;fmr %0,%2"
[(set_attr "type" "fp") [(set_attr "type" "dfp")
(set_attr "length" "8")]) (set_attr "length" "8")])
(define_insn "adddd3" (define_insn "adddd3"
...@@ -182,7 +182,7 @@ ...@@ -182,7 +182,7 @@
(match_operand:DD 2 "gpc_reg_operand" "d")))] (match_operand:DD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dadd %0,%1,%2" "dadd %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "addtd3" (define_insn "addtd3"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
...@@ -190,7 +190,7 @@ ...@@ -190,7 +190,7 @@
(match_operand:TD 2 "gpc_reg_operand" "d")))] (match_operand:TD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"daddq %0,%1,%2" "daddq %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "subdd3" (define_insn "subdd3"
[(set (match_operand:DD 0 "gpc_reg_operand" "=d") [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
...@@ -198,7 +198,7 @@ ...@@ -198,7 +198,7 @@
(match_operand:DD 2 "gpc_reg_operand" "d")))] (match_operand:DD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dsub %0,%1,%2" "dsub %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "subtd3" (define_insn "subtd3"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
...@@ -206,7 +206,7 @@ ...@@ -206,7 +206,7 @@
(match_operand:TD 2 "gpc_reg_operand" "d")))] (match_operand:TD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dsubq %0,%1,%2" "dsubq %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "muldd3" (define_insn "muldd3"
[(set (match_operand:DD 0 "gpc_reg_operand" "=d") [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
...@@ -214,7 +214,7 @@ ...@@ -214,7 +214,7 @@
(match_operand:DD 2 "gpc_reg_operand" "d")))] (match_operand:DD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dmul %0,%1,%2" "dmul %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "multd3" (define_insn "multd3"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
...@@ -222,7 +222,7 @@ ...@@ -222,7 +222,7 @@
(match_operand:TD 2 "gpc_reg_operand" "d")))] (match_operand:TD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dmulq %0,%1,%2" "dmulq %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "divdd3" (define_insn "divdd3"
[(set (match_operand:DD 0 "gpc_reg_operand" "=d") [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
(match_operand:DD 2 "gpc_reg_operand" "d")))] (match_operand:DD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"ddiv %0,%1,%2" "ddiv %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "divtd3" (define_insn "divtd3"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
(match_operand:TD 2 "gpc_reg_operand" "d")))] (match_operand:TD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"ddivq %0,%1,%2" "ddivq %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "*cmpdd_internal1" (define_insn "*cmpdd_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y") [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
(match_operand:DD 2 "gpc_reg_operand" "d")))] (match_operand:DD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dcmpu %0,%1,%2" "dcmpu %0,%1,%2"
[(set_attr "type" "fpcompare")]) [(set_attr "type" "dfp")])
(define_insn "*cmptd_internal1" (define_insn "*cmptd_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y") [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
...@@ -254,21 +254,21 @@ ...@@ -254,21 +254,21 @@
(match_operand:TD 2 "gpc_reg_operand" "d")))] (match_operand:TD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dcmpuq %0,%1,%2" "dcmpuq %0,%1,%2"
[(set_attr "type" "fpcompare")]) [(set_attr "type" "dfp")])
(define_insn "floatdidd2" (define_insn "floatdidd2"
[(set (match_operand:DD 0 "gpc_reg_operand" "=d") [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
(float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))] (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_DFP && TARGET_POPCNTD" "TARGET_DFP && TARGET_POPCNTD"
"dcffix %0,%1" "dcffix %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "floatditd2" (define_insn "floatditd2"
[(set (match_operand:TD 0 "gpc_reg_operand" "=d") [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
(float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))] (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dcffixq %0,%1" "dcffixq %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; Convert a decimal64 to a decimal64 whose value is an integer. ;; Convert a decimal64 to a decimal64 whose value is an integer.
;; This is the first stage of converting it to an integer type. ;; This is the first stage of converting it to an integer type.
...@@ -278,7 +278,7 @@ ...@@ -278,7 +278,7 @@
(fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"drintn. 0,%0,%1,1" "drintn. 0,%0,%1,1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; Convert a decimal64 whose value is an integer to an actual integer. ;; Convert a decimal64 whose value is an integer to an actual integer.
;; This is the second stage of converting decimal float to integer type. ;; This is the second stage of converting decimal float to integer type.
...@@ -288,7 +288,7 @@ ...@@ -288,7 +288,7 @@
(fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))] (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dctfix %0,%1" "dctfix %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; Convert a decimal128 to a decimal128 whose value is an integer. ;; Convert a decimal128 to a decimal128 whose value is an integer.
;; This is the first stage of converting it to an integer type. ;; This is the first stage of converting it to an integer type.
...@@ -298,7 +298,7 @@ ...@@ -298,7 +298,7 @@
(fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"drintnq. 0,%0,%1,1" "drintnq. 0,%0,%1,1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; Convert a decimal128 whose value is an integer to an actual integer. ;; Convert a decimal128 whose value is an integer to an actual integer.
;; This is the second stage of converting decimal float to integer type. ;; This is the second stage of converting decimal float to integer type.
...@@ -308,7 +308,7 @@ ...@@ -308,7 +308,7 @@
(fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))] (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP" "TARGET_DFP"
"dctfixq %0,%1" "dctfixq %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
;; Decimal builtin support ;; Decimal builtin support
...@@ -333,7 +333,7 @@ ...@@ -333,7 +333,7 @@
UNSPEC_DDEDPD))] UNSPEC_DDEDPD))]
"TARGET_DFP" "TARGET_DFP"
"ddedpd<dfp_suffix> %1,%0,%2" "ddedpd<dfp_suffix> %1,%0,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "dfp_denbcd_<mode>" (define_insn "dfp_denbcd_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
...@@ -342,7 +342,7 @@ ...@@ -342,7 +342,7 @@
UNSPEC_DENBCD))] UNSPEC_DENBCD))]
"TARGET_DFP" "TARGET_DFP"
"denbcd<dfp_suffix> %1,%0,%2" "denbcd<dfp_suffix> %1,%0,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "dfp_dxex_<mode>" (define_insn "dfp_dxex_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
...@@ -350,7 +350,7 @@ ...@@ -350,7 +350,7 @@
UNSPEC_DXEX))] UNSPEC_DXEX))]
"TARGET_DFP" "TARGET_DFP"
"dxex<dfp_suffix> %0,%1" "dxex<dfp_suffix> %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "dfp_diex_<mode>" (define_insn "dfp_diex_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
...@@ -359,7 +359,7 @@ ...@@ -359,7 +359,7 @@
UNSPEC_DXEX))] UNSPEC_DXEX))]
"TARGET_DFP" "TARGET_DFP"
"diex<dfp_suffix> %0,%1,%2" "diex<dfp_suffix> %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "dfp_dscli_<mode>" (define_insn "dfp_dscli_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
...@@ -368,7 +368,7 @@ ...@@ -368,7 +368,7 @@
UNSPEC_DSCLI))] UNSPEC_DSCLI))]
"TARGET_DFP" "TARGET_DFP"
"dscli<dfp_suffix> %0,%1,%2" "dscli<dfp_suffix> %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
(define_insn "dfp_dscri_<mode>" (define_insn "dfp_dscri_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
...@@ -377,4 +377,4 @@ ...@@ -377,4 +377,4 @@
UNSPEC_DSCRI))] UNSPEC_DSCRI))]
"TARGET_DFP" "TARGET_DFP"
"dscri<dfp_suffix> %0,%1,%2" "dscri<dfp_suffix> %0,%1,%2"
[(set_attr "type" "fp")]) [(set_attr "type" "dfp")])
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
(set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"tabort. %0" "tabort. %0"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "tabort<wd>c" (define_expand "tabort<wd>c"
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
(set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"tabort<wd>c. %0,%1,%2" "tabort<wd>c. %0,%1,%2"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "tabort<wd>ci" (define_expand "tabort<wd>ci"
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
(set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"tabort<wd>ci. %0,%1,%2" "tabort<wd>ci. %0,%1,%2"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "tbegin" (define_expand "tbegin"
...@@ -208,7 +208,7 @@ ...@@ -208,7 +208,7 @@
(set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"trechkpt." "trechkpt."
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "treclaim" (define_expand "treclaim"
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
(set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"treclaim. %0" "treclaim. %0"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "tsr" (define_expand "tsr"
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
(set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"tsr. %0" "tsr. %0"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_expand "ttest" (define_expand "ttest"
...@@ -272,7 +272,7 @@ ...@@ -272,7 +272,7 @@
(set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
"TARGET_HTM" "TARGET_HTM"
"tabortwci. 0,1,0" "tabortwci. 0,1,0"
[(set_attr "type" "htm") [(set_attr "type" "htmsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "htm_mfspr_<mode>" (define_insn "htm_mfspr_<mode>"
......
...@@ -500,7 +500,7 @@ ...@@ -500,7 +500,7 @@
(define_bypass 9 "power6-mtcr" "power6-branch") (define_bypass 9 "power6-mtcr" "power6-branch")
(define_insn_reservation "power6-fp" 6 (define_insn_reservation "power6-fp" 6
(and (eq_attr "type" "fp,fpsimple,dmul") (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
(eq_attr "cpu" "power6")) (eq_attr "cpu" "power6"))
"FPU_power6") "FPU_power6")
......
...@@ -292,7 +292,7 @@ ...@@ -292,7 +292,7 @@
; VS Unit (includes FP/VSX/VMX/DFP) ; VS Unit (includes FP/VSX/VMX/DFP)
(define_insn_reservation "power7-fp" 6 (define_insn_reservation "power7-fp" 6
(and (eq_attr "type" "fp,fpsimple,dmul") (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
(eq_attr "cpu" "power7")) (eq_attr "cpu" "power7"))
"DU_power7,VSU_power7") "DU_power7,VSU_power7")
......
...@@ -317,7 +317,7 @@ ...@@ -317,7 +317,7 @@
; VS Unit (includes FP/VSX/VMX/DFP/Crypto) ; VS Unit (includes FP/VSX/VMX/DFP/Crypto)
(define_insn_reservation "power8-fp" 6 (define_insn_reservation "power8-fp" 6
(and (eq_attr "type" "fp,fpsimple,dmul") (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
(eq_attr "cpu" "power8")) (eq_attr "cpu" "power8"))
"DU_any_power8,VSU_power8") "DU_any_power8,VSU_power8")
......
;; Scheduling description for IBM POWER9 processor.
;; Copyright (C) 2016 Free Software Foundation, Inc.
;;
;; Contributed by Pat Haugen (pthaugen@us.ibm.com).
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_automaton "power9dsp,power9lsu,power9vsu,power9misc")
(define_cpu_unit "lsu0_power9,lsu1_power9,lsu2_power9,lsu3_power9" "power9lsu")
(define_cpu_unit "vsu0_power9,vsu1_power9,vsu2_power9,vsu3_power9" "power9vsu")
; Two vector permute units, part of vsu
(define_cpu_unit "prm0_power9,prm1_power9" "power9vsu")
; Two fixed point divide units, not pipelined
(define_cpu_unit "fx_div0_power9,fx_div1_power9" "power9misc")
(define_cpu_unit "bru_power9,cryptu_power9,dfu_power9" "power9misc")
(define_cpu_unit "x0_power9,x1_power9,xa0_power9,xa1_power9,
x2_power9,x3_power9,xb0_power9,xb1_power9,
br0_power9,br1_power9" "power9dsp")
; Dispatch port reservations
;
; Power9 can dispatch a maximum of 6 iops per cycle with the following
; general restrictions (other restrictions also apply):
; 1) At most 2 iops per execution slice
; 2) At most 2 iops to the branch unit
; Note that insn position in a dispatch group of 6 insns does not infer which
; execution slice the insn is routed to. The units are used to infer the
; conflicts that exist (i.e. an 'even' requirement will preclude dispatch
; with 2 insns with 'superslice' requirement).
; The xa0/xa1 units really represent the 3rd dispatch port for a superslice but
; are listed as separate units to allow those insns that preclude its use to
; still be scheduled two to a superslice while reserving the 3rd slot. The
; same applies for xb0/xb1.
(define_reservation "DU_xa_power9" "xa0_power9+xa1_power9")
(define_reservation "DU_xb_power9" "xb0_power9+xb1_power9")
; Any execution slice dispatch
(define_reservation "DU_any_power9"
"x0_power9|x1_power9|DU_xa_power9|x2_power9|x3_power9|
DU_xb_power9")
; Even slice, actually takes even/odd slots
(define_reservation "DU_even_power9" "x0_power9+x1_power9|x2_power9+x3_power9")
; Slice plus 3rd slot
(define_reservation "DU_slice_3_power9"
"x0_power9+xa0_power9|x1_power9+xa1_power9|
x2_power9+xb0_power9|x3_power9+xb1_power9")
; Superslice
(define_reservation "DU_super_power9"
"x0_power9+x1_power9|x2_power9+x3_power9")
; 2-way cracked
(define_reservation "DU_C2_power9" "x0_power9+x1_power9|
x1_power9+DU_xa_power9|
x1_power9+x2_power9|
DU_xa_power9+x2_power9|
x2_power9+x3_power9|
x3_power9+DU_xb_power9")
; 2-way cracked plus 3rd slot
(define_reservation "DU_C2_3_power9" "x0_power9+x1_power9+xa0_power9|
x1_power9+x2_power9+xa0_power9|
x1_power9+x2_power9+xb0_power9|
x2_power9+x3_power9+xb0_power9")
; 3-way cracked (consumes whole decode/dispatch cycle)
(define_reservation "DU_C3_power9"
"x0_power9+x1_power9+xa0_power9+xa1_power9+x2_power9+
x3_power9+xb0_power9+xb1_power9+br0_power9+br1_power9")
; Branch ports
(define_reservation "DU_branch_power9" "br0_power9|br1_power9")
; Execution unit reservations
(define_reservation "LSU_power9"
"lsu0_power9|lsu1_power9|lsu2_power9|lsu3_power9")
(define_reservation "LSU_pair_power9"
"lsu0_power9+lsu1_power9|lsu1_power9+lsu2_power9|
lsu2_power9+lsu3_power9|lsu3_power9+lsu0_power9")
(define_reservation "VSU_power9"
"vsu0_power9|vsu1_power9|vsu2_power9|vsu3_power9")
(define_reservation "VSU_super_power9"
"vsu0_power9+vsu1_power9|vsu2_power9+vsu3_power9")
(define_reservation "VSU_PRM_power9" "prm0_power9|prm1_power9")
; LS Unit
(define_insn_reservation "power9-load" 4
(and (eq_attr "type" "load")
(eq_attr "sign_extend" "no")
(eq_attr "update" "no")
(eq_attr "cpu" "power9"))
"DU_any_power9,LSU_power9")
(define_insn_reservation "power9-load-update" 4
(and (eq_attr "type" "load")
(eq_attr "sign_extend" "no")
(eq_attr "update" "yes")
(eq_attr "cpu" "power9"))
"DU_C2_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-load-ext" 6
(and (eq_attr "type" "load")
(eq_attr "sign_extend" "yes")
(eq_attr "update" "no")
(eq_attr "cpu" "power9"))
"DU_C2_power9,LSU_power9")
(define_insn_reservation "power9-load-ext-update" 6
(and (eq_attr "type" "load")
(eq_attr "sign_extend" "yes")
(eq_attr "update" "yes")
(eq_attr "cpu" "power9"))
"DU_C3_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-fpload-double" 4
(and (eq_attr "type" "fpload")
(eq_attr "update" "no")
(eq_attr "size" "64")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,LSU_power9")
(define_insn_reservation "power9-fpload-update-double" 4
(and (eq_attr "type" "fpload")
(eq_attr "update" "yes")
(eq_attr "size" "64")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9+VSU_power9")
; SFmode loads are cracked and have additional 2 cycles over DFmode
(define_insn_reservation "power9-fpload-single" 6
(and (eq_attr "type" "fpload")
(eq_attr "update" "no")
(eq_attr "size" "32")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9")
(define_insn_reservation "power9-fpload-update-single" 6
(and (eq_attr "type" "fpload")
(eq_attr "update" "yes")
(eq_attr "size" "32")
(eq_attr "cpu" "power9"))
"DU_C3_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-vecload" 5
(and (eq_attr "type" "vecload")
(eq_attr "cpu" "power9"))
"DU_any_power9,LSU_pair_power9")
; Store data can issue 2 cycles after AGEN issue, 3 cycles for vector store
(define_insn_reservation "power9-store" 0
(and (eq_attr "type" "store")
(eq_attr "update" "no")
(eq_attr "indexed" "no")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,LSU_power9")
(define_insn_reservation "power9-store-indexed" 0
(and (eq_attr "type" "store")
(eq_attr "update" "no")
(eq_attr "indexed" "yes")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,LSU_power9")
; Update forms have 2 cycle latency for updated addr reg
(define_insn_reservation "power9-store-update" 2
(and (eq_attr "type" "store")
(eq_attr "update" "yes")
(eq_attr "indexed" "no")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9+VSU_power9")
; Update forms have 2 cycle latency for updated addr reg
(define_insn_reservation "power9-store-update-indexed" 2
(and (eq_attr "type" "store")
(eq_attr "update" "yes")
(eq_attr "indexed" "yes")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-fpstore" 0
(and (eq_attr "type" "fpstore")
(eq_attr "update" "no")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,LSU_power9")
; Update forms have 2 cycle latency for updated addr reg
(define_insn_reservation "power9-fpstore-update" 2
(and (eq_attr "type" "fpstore")
(eq_attr "update" "yes")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-vecstore" 0
(and (eq_attr "type" "vecstore")
(eq_attr "cpu" "power9"))
"DU_super_power9,LSU_pair_power9")
(define_insn_reservation "power9-larx" 4
(and (eq_attr "type" "load_l")
(eq_attr "cpu" "power9"))
"DU_any_power9,LSU_power9")
(define_insn_reservation "power9-stcx" 2
(and (eq_attr "type" "store_c")
(eq_attr "cpu" "power9"))
"DU_C2_3_power9,LSU_power9+VSU_power9")
(define_insn_reservation "power9-sync" 4
(and (eq_attr "type" "sync,isync")
(eq_attr "cpu" "power9"))
"DU_any_power9,LSU_power9")
; VSU Execution Unit
; Fixed point ops
; Most ALU insns are simple 2 cycle, including record form
(define_insn_reservation "power9-alu" 2
(and (ior (eq_attr "type" "add,cmp,exts,integer,logical,isel")
(and (eq_attr "type" "insert,shift")
(eq_attr "dot" "no")))
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
; Record form rotate/shift are cracked
(define_insn_reservation "power9-cracked-alu" 2
(and (eq_attr "type" "insert,shift")
(eq_attr "dot" "yes")
(eq_attr "cpu" "power9"))
"DU_C2_power9,VSU_power9")
; 4 cycle CR latency
(define_bypass 4 "power9-cracked-alu"
"power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch")
(define_insn_reservation "power9-alu2" 3
(and (eq_attr "type" "cntlz,popcnt,trap")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
; Treat 'two' and 'three' types as 2 or 3 way cracked
(define_insn_reservation "power9-two" 4
(and (eq_attr "type" "two")
(eq_attr "cpu" "power9"))
"DU_C2_power9,VSU_power9")
(define_insn_reservation "power9-three" 6
(and (eq_attr "type" "three")
(eq_attr "cpu" "power9"))
"DU_C3_power9,VSU_power9")
(define_insn_reservation "power9-mul" 4
(and (eq_attr "type" "mul")
(eq_attr "dot" "no")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
(define_insn_reservation "power9-mul-compare" 4
(and (eq_attr "type" "mul")
(eq_attr "dot" "yes")
(eq_attr "cpu" "power9"))
"DU_C2_power9,VSU_power9")
; 6 cycle CR latency
(define_bypass 6 "power9-mul-compare"
"power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch")
; Fixed point divides reserve the divide units for a minimum of 8 cycles
(define_insn_reservation "power9-idiv" 16
(and (eq_attr "type" "div")
(eq_attr "size" "32")
(eq_attr "cpu" "power9"))
"DU_even_power9,fx_div0_power9*8|fx_div1_power9*8")
(define_insn_reservation "power9-ldiv" 24
(and (eq_attr "type" "div")
(eq_attr "size" "64")
(eq_attr "cpu" "power9"))
"DU_even_power9,fx_div0_power9*8|fx_div1_power9*8")
(define_insn_reservation "power9-crlogical" 2
(and (eq_attr "type" "cr_logical,delayed_cr")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
(define_insn_reservation "power9-mfcrf" 2
(and (eq_attr "type" "mfcrf")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
(define_insn_reservation "power9-mfcr" 6
(and (eq_attr "type" "mfcr")
(eq_attr "cpu" "power9"))
"DU_C3_power9,VSU_power9")
; Should differentiate between 1 cr field and > 1 since target of > 1 cr
; is cracked
(define_insn_reservation "power9-mtcr" 2
(and (eq_attr "type" "mtcr")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
; Move to LR/CTR are executed in VSU
(define_insn_reservation "power9-mtjmpr" 5
(and (eq_attr "type" "mtjmpr")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
; Floating point/Vector ops
(define_insn_reservation "power9-fpsimple" 2
(and (eq_attr "type" "fpsimple")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-fp" 7
(and (eq_attr "type" "fp,dmul")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-fpcompare" 3
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
; FP div/sqrt are executed in the VSU slices. They are not pipelined wrt other
; divide insns, but for the most part do not block pipelined ops.
(define_insn_reservation "power9-sdiv" 22
(and (eq_attr "type" "sdiv")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-ddiv" 33
(and (eq_attr "type" "ddiv")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-sqrt" 26
(and (eq_attr "type" "ssqrt")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-dsqrt" 36
(and (eq_attr "type" "dsqrt")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-vec-2cyc" 2
(and (eq_attr "type" "vecmove,veclogical,vecexts,veccmpfx")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-veccmp" 3
(and (eq_attr "type" "veccmp")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-vecsimple" 3
(and (eq_attr "type" "vecsimple")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-vecnormal" 7
(and (eq_attr "type" "vecfloat,vecdouble")
(eq_attr "size" "!128")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
; Quad-precision FP ops, execute in DFU
(define_insn_reservation "power9-qp" 12
(and (eq_attr "type" "vecfloat,vecdouble")
(eq_attr "size" "128")
(eq_attr "cpu" "power9"))
"DU_super_power9,dfu_power9")
(define_insn_reservation "power9-vecperm" 3
(and (eq_attr "type" "vecperm")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_PRM_power9")
(define_insn_reservation "power9-veccomplex" 7
(and (eq_attr "type" "veccomplex")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-vecfdiv" 28
(and (eq_attr "type" "vecfdiv")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-vecdiv" 32
(and (eq_attr "type" "vecdiv")
(eq_attr "size" "!128")
(eq_attr "cpu" "power9"))
"DU_super_power9,VSU_super_power9")
(define_insn_reservation "power9-qpdiv" 56
(and (eq_attr "type" "vecdiv")
(eq_attr "size" "128")
(eq_attr "cpu" "power9"))
"DU_super_power9,dfu_power9")
(define_insn_reservation "power9-mffgpr" 2
(and (eq_attr "type" "mffgpr")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
(define_insn_reservation "power9-mftgpr" 2
(and (eq_attr "type" "mftgpr")
(eq_attr "cpu" "power9"))
"DU_slice_3_power9,VSU_power9")
; Branch Unit
; Move from LR/CTR are executed in BRU but consume a writeback port from an
; execution slice.
(define_insn_reservation "power9-mfjmpr" 6
(and (eq_attr "type" "mfjmpr")
(eq_attr "cpu" "power9"))
"DU_branch_power9,bru_power9+VSU_power9")
; Branch is 2 cycles
(define_insn_reservation "power9-branch" 2
(and (eq_attr "type" "jmpreg,branch")
(eq_attr "cpu" "power9"))
"DU_branch_power9,bru_power9")
; Crypto Unit
(define_insn_reservation "power9-crypto" 6
(and (eq_attr "type" "crypto")
(eq_attr "cpu" "power9"))
"DU_super_power9,cryptu_power9")
; HTM Unit
(define_insn_reservation "power9-htm" 4
(and (eq_attr "type" "htm")
(eq_attr "cpu" "power9"))
"DU_C2_power9,LSU_power9")
(define_insn_reservation "power9-htm-simple" 2
(and (eq_attr "type" "htmsimple")
(eq_attr "cpu" "power9"))
"DU_any_power9,VSU_power9")
; DFP Unit
(define_insn_reservation "power9-dfp" 12
(and (eq_attr "type" "dfp")
(eq_attr "cpu" "power9"))
"DU_even_power9,dfu_power9")
...@@ -1104,16 +1104,16 @@ struct processor_costs power9_cost = { ...@@ -1104,16 +1104,16 @@ struct processor_costs power9_cost = {
COSTS_N_INSNS (3), /* mulsi_const */ COSTS_N_INSNS (3), /* mulsi_const */
COSTS_N_INSNS (3), /* mulsi_const9 */ COSTS_N_INSNS (3), /* mulsi_const9 */
COSTS_N_INSNS (3), /* muldi */ COSTS_N_INSNS (3), /* muldi */
COSTS_N_INSNS (19), /* divsi */ COSTS_N_INSNS (8), /* divsi */
COSTS_N_INSNS (35), /* divdi */ COSTS_N_INSNS (12), /* divdi */
COSTS_N_INSNS (3), /* fp */ COSTS_N_INSNS (3), /* fp */
COSTS_N_INSNS (3), /* dmul */ COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (14), /* sdiv */ COSTS_N_INSNS (13), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */ COSTS_N_INSNS (18), /* ddiv */
128, /* cache line size */ 128, /* cache line size */
32, /* l1 cache */ 32, /* l1 cache */
256, /* l2 cache */ 512, /* l2 cache */
12, /* prefetch streams */ 8, /* prefetch streams */
COSTS_N_INSNS (3), /* SF->DF convert */ COSTS_N_INSNS (3), /* SF->DF convert */
}; };
...@@ -3846,25 +3846,10 @@ rs6000_option_override_internal (bool global_init_p) ...@@ -3846,25 +3846,10 @@ rs6000_option_override_internal (bool global_init_p)
if (rs6000_tune_index >= 0) if (rs6000_tune_index >= 0)
tune_index = rs6000_tune_index; tune_index = rs6000_tune_index;
else if (have_cpu) else if (have_cpu)
{
/* Until power9 tuning is available, use power8 tuning if -mcpu=power9. */
if (processor_target_table[cpu_index].processor != PROCESSOR_POWER9)
rs6000_tune_index = tune_index = cpu_index; rs6000_tune_index = tune_index = cpu_index;
else else
{ {
size_t i; size_t i;
tune_index = -1;
for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
if (processor_target_table[i].processor == PROCESSOR_POWER8)
{
rs6000_tune_index = tune_index = i;
break;
}
}
}
else
{
size_t i;
enum processor_type tune_proc enum processor_type tune_proc
= (TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT); = (TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT);
...@@ -4623,8 +4608,7 @@ rs6000_option_override_internal (bool global_init_p) ...@@ -4623,8 +4608,7 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
|| rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER5
|| rs6000_cpu == PROCESSOR_POWER7 || rs6000_cpu == PROCESSOR_POWER7
|| rs6000_cpu == PROCESSOR_POWER8 || rs6000_cpu == PROCESSOR_POWER8);
|| rs6000_cpu == PROCESSOR_POWER9);
rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
|| rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER5
|| rs6000_cpu == PROCESSOR_POWER6 || rs6000_cpu == PROCESSOR_POWER6
...@@ -29864,13 +29848,20 @@ output_function_profiler (FILE *file, int labelno) ...@@ -29864,13 +29848,20 @@ output_function_profiler (FILE *file, int labelno)
/* The following variable value is the last issued insn. */ /* The following variable value is the last issued insn. */
static rtx last_scheduled_insn; static rtx_insn *last_scheduled_insn;
/* The following variable helps to balance issuing of load and /* The following variable helps to balance issuing of load and
store instructions */ store instructions */
static int load_store_pendulum; static int load_store_pendulum;
/* The following variable helps pair divide insns during scheduling. */
static int divide_cnt;
/* The following variable helps pair and alternate vector and vector load
insns during scheduling. */
static int vec_load_pendulum;
/* Power4 load update and store update instructions are cracked into a /* Power4 load update and store update instructions are cracked into a
load or store and an integer insn which are executed in the same cycle. load or store and an integer insn which are executed in the same cycle.
Branches have their own dispatch slot which does not count against the Branches have their own dispatch slot which does not count against the
...@@ -29945,7 +29936,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost) ...@@ -29945,7 +29936,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
some cycles later. */ some cycles later. */
/* Separate a load from a narrower, dependent store. */ /* Separate a load from a narrower, dependent store. */
if (rs6000_sched_groups if ((rs6000_sched_groups || rs6000_cpu_attr == CPU_POWER9)
&& GET_CODE (PATTERN (insn)) == SET && GET_CODE (PATTERN (insn)) == SET
&& GET_CODE (PATTERN (dep_insn)) == SET && GET_CODE (PATTERN (dep_insn)) == SET
&& GET_CODE (XEXP (PATTERN (insn), 1)) == MEM && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
...@@ -30185,6 +30176,8 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost) ...@@ -30185,6 +30176,8 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
break; break;
} }
} }
/* Fall through, no cost for output dependency. */
case REG_DEP_ANTI: case REG_DEP_ANTI:
/* Anti dependency; DEP_INSN reads a register that INSN writes some /* Anti dependency; DEP_INSN reads a register that INSN writes some
cycles later. */ cycles later. */
...@@ -30557,8 +30550,9 @@ rs6000_issue_rate (void) ...@@ -30557,8 +30550,9 @@ rs6000_issue_rate (void)
case CPU_POWER7: case CPU_POWER7:
return 5; return 5;
case CPU_POWER8: case CPU_POWER8:
case CPU_POWER9:
return 7; return 7;
case CPU_POWER9:
return 6;
default: default:
return 1; return 1;
} }
...@@ -30716,6 +30710,28 @@ is_store_insn (rtx insn, rtx *str_mem) ...@@ -30716,6 +30710,28 @@ is_store_insn (rtx insn, rtx *str_mem)
return is_store_insn1 (PATTERN (insn), str_mem); return is_store_insn1 (PATTERN (insn), str_mem);
} }
/* Return whether TYPE is a Power9 pairable vector instruction type. */
static bool
is_power9_pairable_vec_type (enum attr_type type)
{
switch (type)
{
case TYPE_VECSIMPLE:
case TYPE_VECCOMPLEX:
case TYPE_VECDIV:
case TYPE_VECCMP:
case TYPE_VECPERM:
case TYPE_VECFLOAT:
case TYPE_VECFDIV:
case TYPE_VECDOUBLE:
return true;
default:
break;
}
return false;
}
/* Returns whether the dependence between INSN and NEXT is considered /* Returns whether the dependence between INSN and NEXT is considered
costly by the given target. */ costly by the given target. */
...@@ -30792,6 +30808,229 @@ get_next_active_insn (rtx_insn *insn, rtx_insn *tail) ...@@ -30792,6 +30808,229 @@ get_next_active_insn (rtx_insn *insn, rtx_insn *tail)
return insn; return insn;
} }
/* Do Power9 specific sched_reorder2 reordering of ready list. */
static int
power9_sched_reorder2 (rtx_insn **ready, int lastpos)
{
int pos;
int i;
rtx_insn *tmp;
enum attr_type type;
type = get_attr_type (last_scheduled_insn);
/* Try to issue fixed point divides back-to-back in pairs so they will be
routed to separate execution units and execute in parallel. */
if (type == TYPE_DIV && divide_cnt == 0)
{
/* First divide has been scheduled. */
divide_cnt = 1;
/* Scan the ready list looking for another divide, if found move it
to the end of the list so it is chosen next. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& get_attr_type (ready[pos]) == TYPE_DIV)
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
break;
}
pos--;
}
}
else
{
/* Last insn was the 2nd divide or not a divide, reset the counter. */
divide_cnt = 0;
/* Power9 can execute 2 vector operations and 2 vector loads in a single
cycle. So try to pair up and alternate groups of vector and vector
load instructions.
To aid this formation, a counter is maintained to keep track of
vec/vecload insns issued. The value of vec_load_pendulum maintains
the current state with the following values:
0 : Initial state, no vec/vecload group has been started.
-1 : 1 vector load has been issued and another has been found on
the ready list and moved to the end.
-2 : 2 vector loads have been issued and a vector operation has
been found and moved to the end of the ready list.
-3 : 2 vector loads and a vector insn have been issued and a
vector operation has been found and moved to the end of the
ready list.
1 : 1 vector insn has been issued and another has been found and
moved to the end of the ready list.
2 : 2 vector insns have been issued and a vector load has been
found and moved to the end of the ready list.
3 : 2 vector insns and a vector load have been issued and another
vector load has been found and moved to the end of the ready
list. */
if (type == TYPE_VECLOAD)
{
/* Issued a vecload. */
if (vec_load_pendulum == 0)
{
/* We issued a single vecload, look for another and move it to
the end of the ready list so it will be scheduled next.
Set pendulum if found. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& get_attr_type (ready[pos]) == TYPE_VECLOAD)
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
vec_load_pendulum = -1;
return cached_can_issue_more;
}
pos--;
}
}
else if (vec_load_pendulum == -1)
{
/* This is the second vecload we've issued, search the ready
list for a vector operation so we can try to schedule a
pair of those next. If found move to the end of the ready
list so it is scheduled next and set the pendulum. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& is_power9_pairable_vec_type (
get_attr_type (ready[pos])))
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
vec_load_pendulum = -2;
return cached_can_issue_more;
}
pos--;
}
}
else if (vec_load_pendulum == 2)
{
/* Two vector ops have been issued and we've just issued a
vecload, look for another vecload and move to end of ready
list if found. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& get_attr_type (ready[pos]) == TYPE_VECLOAD)
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
/* Set pendulum so that next vecload will be seen as
finishing a group, not start of one. */
vec_load_pendulum = 3;
return cached_can_issue_more;
}
pos--;
}
}
}
else if (is_power9_pairable_vec_type (type))
{
/* Issued a vector operation. */
if (vec_load_pendulum == 0)
/* We issued a single vec op, look for another and move it
to the end of the ready list so it will be scheduled next.
Set pendulum if found. */
{
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& is_power9_pairable_vec_type (
get_attr_type (ready[pos])))
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
vec_load_pendulum = 1;
return cached_can_issue_more;
}
pos--;
}
}
else if (vec_load_pendulum == 1)
{
/* This is the second vec op we've issued, search the ready
list for a vecload operation so we can try to schedule a
pair of those next. If found move to the end of the ready
list so it is scheduled next and set the pendulum. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& get_attr_type (ready[pos]) == TYPE_VECLOAD)
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
vec_load_pendulum = 2;
return cached_can_issue_more;
}
pos--;
}
}
else if (vec_load_pendulum == -2)
{
/* Two vecload ops have been issued and we've just issued a
vec op, look for another vec op and move to end of ready
list if found. */
pos = lastpos;
while (pos >= 0)
{
if (recog_memoized (ready[pos]) >= 0
&& is_power9_pairable_vec_type (
get_attr_type (ready[pos])))
{
tmp = ready[pos];
for (i = pos; i < lastpos; i++)
ready[i] = ready[i + 1];
ready[lastpos] = tmp;
/* Set pendulum so that next vec op will be seen as
finishing a group, not start of one. */
vec_load_pendulum = -3;
return cached_can_issue_more;
}
pos--;
}
}
}
/* We've either finished a vec/vecload group, couldn't find an insn to
continue the current group, or the last insn had nothing to do with
with a group. In any case, reset the pendulum. */
vec_load_pendulum = 0;
}
return cached_can_issue_more;
}
/* We are about to begin issuing insns for this clock cycle. */ /* We are about to begin issuing insns for this clock cycle. */
static int static int
...@@ -31023,6 +31262,11 @@ rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx_insn **ready, ...@@ -31023,6 +31262,11 @@ rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx_insn **ready,
} }
} }
/* Do Power9 dependent reordering if necessary. */
if (rs6000_cpu == PROCESSOR_POWER9 && last_scheduled_insn
&& recog_memoized (last_scheduled_insn) >= 0)
return power9_sched_reorder2 (ready, *pn_ready - 1);
return cached_can_issue_more; return cached_can_issue_more;
} }
...@@ -31191,7 +31435,6 @@ insn_must_be_first_in_group (rtx_insn *insn) ...@@ -31191,7 +31435,6 @@ insn_must_be_first_in_group (rtx_insn *insn)
} }
break; break;
case PROCESSOR_POWER8: case PROCESSOR_POWER8:
case PROCESSOR_POWER9:
type = get_attr_type (insn); type = get_attr_type (insn);
switch (type) switch (type)
...@@ -31322,7 +31565,6 @@ insn_must_be_last_in_group (rtx_insn *insn) ...@@ -31322,7 +31565,6 @@ insn_must_be_last_in_group (rtx_insn *insn)
} }
break; break;
case PROCESSOR_POWER8: case PROCESSOR_POWER8:
case PROCESSOR_POWER9:
type = get_attr_type (insn); type = get_attr_type (insn);
switch (type) switch (type)
...@@ -31441,7 +31683,7 @@ force_new_group (int sched_verbose, FILE *dump, rtx *group_insns, ...@@ -31441,7 +31683,7 @@ force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
/* Do we have a special group ending nop? */ /* Do we have a special group ending nop? */
if (rs6000_cpu_attr == CPU_POWER6 || rs6000_cpu_attr == CPU_POWER7 if (rs6000_cpu_attr == CPU_POWER6 || rs6000_cpu_attr == CPU_POWER7
|| rs6000_cpu_attr == CPU_POWER8 || rs6000_cpu_attr == CPU_POWER9) || rs6000_cpu_attr == CPU_POWER8)
{ {
nop = gen_group_ending_nop (); nop = gen_group_ending_nop ();
emit_insn_before (nop, next_insn); emit_insn_before (nop, next_insn);
...@@ -31695,8 +31937,10 @@ rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED, ...@@ -31695,8 +31937,10 @@ rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
int sched_verbose ATTRIBUTE_UNUSED, int sched_verbose ATTRIBUTE_UNUSED,
int max_ready ATTRIBUTE_UNUSED) int max_ready ATTRIBUTE_UNUSED)
{ {
last_scheduled_insn = NULL_RTX; last_scheduled_insn = NULL;
load_store_pendulum = 0; load_store_pendulum = 0;
divide_cnt = 0;
vec_load_pendulum = 0;
} }
/* The following function is called at the end of scheduling BB. /* The following function is called at the end of scheduling BB.
...@@ -31737,14 +31981,16 @@ rs6000_sched_finish (FILE *dump, int sched_verbose) ...@@ -31737,14 +31981,16 @@ rs6000_sched_finish (FILE *dump, int sched_verbose)
} }
} }
struct _rs6000_sched_context struct rs6000_sched_context
{ {
short cached_can_issue_more; short cached_can_issue_more;
rtx last_scheduled_insn; rtx_insn *last_scheduled_insn;
int load_store_pendulum; int load_store_pendulum;
int divide_cnt;
int vec_load_pendulum;
}; };
typedef struct _rs6000_sched_context rs6000_sched_context_def; typedef struct rs6000_sched_context rs6000_sched_context_def;
typedef rs6000_sched_context_def *rs6000_sched_context_t; typedef rs6000_sched_context_def *rs6000_sched_context_t;
/* Allocate store for new scheduling context. */ /* Allocate store for new scheduling context. */
...@@ -31764,14 +32010,18 @@ rs6000_init_sched_context (void *_sc, bool clean_p) ...@@ -31764,14 +32010,18 @@ rs6000_init_sched_context (void *_sc, bool clean_p)
if (clean_p) if (clean_p)
{ {
sc->cached_can_issue_more = 0; sc->cached_can_issue_more = 0;
sc->last_scheduled_insn = NULL_RTX; sc->last_scheduled_insn = NULL;
sc->load_store_pendulum = 0; sc->load_store_pendulum = 0;
sc->divide_cnt = 0;
sc->vec_load_pendulum = 0;
} }
else else
{ {
sc->cached_can_issue_more = cached_can_issue_more; sc->cached_can_issue_more = cached_can_issue_more;
sc->last_scheduled_insn = last_scheduled_insn; sc->last_scheduled_insn = last_scheduled_insn;
sc->load_store_pendulum = load_store_pendulum; sc->load_store_pendulum = load_store_pendulum;
sc->divide_cnt = divide_cnt;
sc->vec_load_pendulum = vec_load_pendulum;
} }
} }
...@@ -31786,6 +32036,8 @@ rs6000_set_sched_context (void *_sc) ...@@ -31786,6 +32036,8 @@ rs6000_set_sched_context (void *_sc)
cached_can_issue_more = sc->cached_can_issue_more; cached_can_issue_more = sc->cached_can_issue_more;
last_scheduled_insn = sc->last_scheduled_insn; last_scheduled_insn = sc->last_scheduled_insn;
load_store_pendulum = sc->load_store_pendulum; load_store_pendulum = sc->load_store_pendulum;
divide_cnt = sc->divide_cnt;
vec_load_pendulum = sc->vec_load_pendulum;
} }
/* Free _SC. */ /* Free _SC. */
...@@ -184,12 +184,12 @@ ...@@ -184,12 +184,12 @@
vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
veclogical,veccmpfx,vecexts,vecmove, veclogical,veccmpfx,vecexts,vecmove,
htm" htm,htmsimple,dfp"
(const_string "integer")) (const_string "integer"))
;; What data size does this instruction work on? ;; What data size does this instruction work on?
;; This is used for insert, mul. ;; This is used for insert, mul and others as necessary.
(define_attr "size" "8,16,32,64" (const_string "32")) (define_attr "size" "8,16,32,64,128" (const_string "32"))
;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
;; This is used for add, logical, shift, exts, mul. ;; This is used for add, logical, shift, exts, mul.
...@@ -299,6 +299,7 @@ ...@@ -299,6 +299,7 @@
(include "power6.md") (include "power6.md")
(include "power7.md") (include "power7.md")
(include "power8.md") (include "power8.md")
(include "power9.md")
(include "cell.md") (include "cell.md")
(include "xfpu.md") (include "xfpu.md")
(include "a2.md") (include "a2.md")
...@@ -6792,6 +6793,7 @@ ...@@ -6792,6 +6793,7 @@
# #
#" #"
[(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two") [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
(set_attr "size" "64")
(set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
(define_insn "*mov<mode>_softfloat32" (define_insn "*mov<mode>_softfloat32"
...@@ -6837,6 +6839,7 @@ ...@@ -6837,6 +6839,7 @@
mfvsrd %0,%x1 mfvsrd %0,%x1
mtvsrd %x0,%1" mtvsrd %x0,%1"
[(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
(set_attr "size" "64")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "*mov<mode>_softfloat64" (define_insn "*mov<mode>_softfloat64"
...@@ -7888,7 +7891,8 @@ ...@@ -7888,7 +7891,8 @@
"store, load, *, fpstore, fpload, fpsimple, "store, load, *, fpstore, fpload, fpsimple,
*, fpstore, fpstore, fpload, fpload, veclogical, *, fpstore, fpstore, fpload, fpload, veclogical,
vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple, vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
vecsimple")]) vecsimple")
(set_attr "size" "64")])
(define_split (define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
...@@ -7977,6 +7981,7 @@ ...@@ -7977,6 +7981,7 @@
veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *, veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
mftgpr, mffgpr, mftgpr, mffgpr") mftgpr, mffgpr, mftgpr, mffgpr")
(set_attr "size" "64")
(set_attr "length" (set_attr "length"
"4, 4, 4, 4, 4, 20, "4, 4, 4, 4, 4, 20,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
...@@ -9026,7 +9031,8 @@ ...@@ -9026,7 +9031,8 @@
lfdu %3,%2(%0)" lfdu %3,%2(%0)"
[(set_attr "type" "fpload") [(set_attr "type" "fpload")
(set_attr "update" "yes") (set_attr "update" "yes")
(set_attr "indexed" "yes,no")]) (set_attr "indexed" "yes,no")
(set_attr "size" "64")])
(define_insn "*movdf_update2" (define_insn "*movdf_update2"
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
...@@ -13431,7 +13437,8 @@ ...@@ -13431,7 +13437,8 @@
(match_operand:IEEE128 2 "altivec_register_operand" "v")))] (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsaddqp %0,%1,%2" "xsaddqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "sub<mode>3" (define_insn "sub<mode>3"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13440,7 +13447,8 @@ ...@@ -13440,7 +13447,8 @@
(match_operand:IEEE128 2 "altivec_register_operand" "v")))] (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xssubqp %0,%1,%2" "xssubqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "mul<mode>3" (define_insn "mul<mode>3"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13449,7 +13457,8 @@ ...@@ -13449,7 +13457,8 @@
(match_operand:IEEE128 2 "altivec_register_operand" "v")))] (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsmulqp %0,%1,%2" "xsmulqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "div<mode>3" (define_insn "div<mode>3"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13458,7 +13467,8 @@ ...@@ -13458,7 +13467,8 @@
(match_operand:IEEE128 2 "altivec_register_operand" "v")))] (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsdivqp %0,%1,%2" "xsdivqp %0,%1,%2"
[(set_attr "type" "vecdiv")]) [(set_attr "type" "vecdiv")
(set_attr "size" "128")])
(define_insn "sqrt<mode>2" (define_insn "sqrt<mode>2"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13466,7 +13476,8 @@ ...@@ -13466,7 +13476,8 @@
(match_operand:IEEE128 1 "altivec_register_operand" "v")))] (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xssqrtqp %0,%1" "xssqrtqp %0,%1"
[(set_attr "type" "vecdiv")]) [(set_attr "type" "vecdiv")
(set_attr "size" "128")])
(define_expand "copysign<mode>3" (define_expand "copysign<mode>3"
[(use (match_operand:IEEE128 0 "altivec_register_operand")) [(use (match_operand:IEEE128 0 "altivec_register_operand"))
...@@ -13494,7 +13505,8 @@ ...@@ -13494,7 +13505,8 @@
UNSPEC_COPYSIGN))] UNSPEC_COPYSIGN))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscpsgnqp %0,%2,%1" "xscpsgnqp %0,%2,%1"
[(set_attr "type" "vecmove")]) [(set_attr "type" "vecmove")
(set_attr "size" "128")])
(define_insn "copysign<mode>3_soft" (define_insn "copysign<mode>3_soft"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13514,7 +13526,8 @@ ...@@ -13514,7 +13526,8 @@
(match_operand:IEEE128 1 "altivec_register_operand" "v")))] (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsnegqp %0,%1" "xsnegqp %0,%1"
[(set_attr "type" "vecmove")]) [(set_attr "type" "vecmove")
(set_attr "size" "128")])
(define_insn "abs<mode>2_hw" (define_insn "abs<mode>2_hw"
...@@ -13523,7 +13536,8 @@ ...@@ -13523,7 +13536,8 @@
(match_operand:IEEE128 1 "altivec_register_operand" "v")))] (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsabsqp %0,%1" "xsabsqp %0,%1"
[(set_attr "type" "vecmove")]) [(set_attr "type" "vecmove")
(set_attr "size" "128")])
(define_insn "*nabs<mode>2_hw" (define_insn "*nabs<mode>2_hw"
...@@ -13533,7 +13547,8 @@ ...@@ -13533,7 +13547,8 @@
(match_operand:IEEE128 1 "altivec_register_operand" "v"))))] (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsnabsqp %0,%1" "xsnabsqp %0,%1"
[(set_attr "type" "vecmove")]) [(set_attr "type" "vecmove")
(set_attr "size" "128")])
;; Initially don't worry about doing fusion ;; Initially don't worry about doing fusion
(define_insn "*fma<mode>4_hw" (define_insn "*fma<mode>4_hw"
...@@ -13544,7 +13559,8 @@ ...@@ -13544,7 +13559,8 @@
(match_operand:IEEE128 3 "altivec_register_operand" "0")))] (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsmaddqp %0,%1,%2" "xsmaddqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*fms<mode>4_hw" (define_insn "*fms<mode>4_hw"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13555,7 +13571,8 @@ ...@@ -13555,7 +13571,8 @@
(match_operand:IEEE128 3 "altivec_register_operand" "0"))))] (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsmsubqp %0,%1,%2" "xsmsubqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*nfma<mode>4_hw" (define_insn "*nfma<mode>4_hw"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13566,7 +13583,8 @@ ...@@ -13566,7 +13583,8 @@
(match_operand:IEEE128 3 "altivec_register_operand" "0"))))] (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsnmaddqp %0,%1,%2" "xsnmaddqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*nfms<mode>4_hw" (define_insn "*nfms<mode>4_hw"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13578,7 +13596,8 @@ ...@@ -13578,7 +13596,8 @@
(match_operand:IEEE128 3 "altivec_register_operand" "0")))))] (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xsnmsubqp %0,%1,%2" "xsnmsubqp %0,%1,%2"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13586,7 +13605,8 @@ ...@@ -13586,7 +13605,8 @@
(match_operand:SFDF 1 "altivec_register_operand" "v")))] (match_operand:SFDF 1 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
"xscvdpqp %0,%1" "xscvdpqp %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
;; point is a simple copy. ;; point is a simple copy.
...@@ -13628,7 +13648,8 @@ ...@@ -13628,7 +13648,8 @@
(match_operand:IEEE128 1 "altivec_register_operand" "v")))] (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscvqpdp %0,%1" "xscvqpdp %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
;; the KFmode -> DFmode conversion using round to odd rather than the normal ;; the KFmode -> DFmode conversion using round to odd rather than the normal
...@@ -13725,7 +13746,8 @@ ...@@ -13725,7 +13746,8 @@
UNSPEC_IEEE128_CONVERT))] UNSPEC_IEEE128_CONVERT))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscvqp<su>wz %0,%1" "xscvqp<su>wz %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*xscvqp<su>dz_<mode>" (define_insn "*xscvqp<su>dz_<mode>"
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v") [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
...@@ -13735,7 +13757,8 @@ ...@@ -13735,7 +13757,8 @@
UNSPEC_IEEE128_CONVERT))] UNSPEC_IEEE128_CONVERT))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscvqp<su>dz %0,%1" "xscvqp<su>dz %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*xscv<su>dqp_<mode>" (define_insn "*xscv<su>dqp_<mode>"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
...@@ -13744,7 +13767,8 @@ ...@@ -13744,7 +13767,8 @@
UNSPEC_IEEE128_CONVERT)))] UNSPEC_IEEE128_CONVERT)))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscv<su>dqp %0,%1" "xscv<su>dqp %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
(define_insn "*ieee128_mfvsrd_64bit" (define_insn "*ieee128_mfvsrd_64bit"
[(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi") [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
...@@ -13821,7 +13845,8 @@ ...@@ -13821,7 +13845,8 @@
UNSPEC_ROUND_TO_ODD))] UNSPEC_ROUND_TO_ODD))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscvqpdpo %0,%1" "xscvqpdpo %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")
(set_attr "size" "128")])
;; IEEE 128-bit comparisons ;; IEEE 128-bit comparisons
(define_insn "*cmp<mode>_hw" (define_insn "*cmp<mode>_hw"
...@@ -13830,7 +13855,8 @@ ...@@ -13830,7 +13855,8 @@
(match_operand:IEEE128 2 "altivec_register_operand" "v")))] (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscmpuqp %0,%1,%2" "xscmpuqp %0,%1,%2"
[(set_attr "type" "fpcompare")]) [(set_attr "type" "veccmp")
(set_attr "size" "128")])
......
...@@ -50,6 +50,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \ ...@@ -50,6 +50,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
$(srcdir)/config/rs6000/power6.md \ $(srcdir)/config/rs6000/power6.md \
$(srcdir)/config/rs6000/power7.md \ $(srcdir)/config/rs6000/power7.md \
$(srcdir)/config/rs6000/power8.md \ $(srcdir)/config/rs6000/power8.md \
$(srcdir)/config/rs6000/power9.md \
$(srcdir)/config/rs6000/cell.md \ $(srcdir)/config/rs6000/cell.md \
$(srcdir)/config/rs6000/xfpu.md \ $(srcdir)/config/rs6000/xfpu.md \
$(srcdir)/config/rs6000/a2.md \ $(srcdir)/config/rs6000/a2.md \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment