From: Segher Boessenkool Date: Tue, 2 Sep 2014 11:21:09 +0000 (+0200) Subject: rs6000.md (any_extend): New code iterator. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eb8fb2ca6104819607e47529d4b029cb3694fb0f;p=gcc.git rs6000.md (any_extend): New code iterator. 2014-09-02 Segher Boessenkool * config/rs6000/rs6000.md (any_extend): New code iterator. (u, su): New code attributes. (dmode, DMODE): New mode attributes. (mul3_highpart): New. (*mul3_highpart): New. (mulsi3_highpart_le): New. (muldi3_highpart_le): New. (mulsi3_highpart_64): New. (mul3): New. (mulsidi3, umulsidi3, smulsi3_highpart, umulsi3_highpart, and two splitters): Delete. (mulditi3, umulditi3, smuldi3_highpart, umuldi3_highpart, and two splitters): Delete. From-SVN: r214814 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10c3554ee96..79fb3f84aa5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2014-09-02 Segher Boessenkool + + * config/rs6000/rs6000.md (any_extend): New code iterator. + (u, su): New code attributes. + (dmode, DMODE): New mode attributes. + (mul3_highpart): New. + (*mul3_highpart): New. + (mulsi3_highpart_le): New. + (muldi3_highpart_le): New. + (mulsi3_highpart_64): New. + (mul3): New. + (mulsidi3, umulsidi3, smulsi3_highpart, umulsi3_highpart, and two + splitters): Delete. + (mulditi3, umulditi3, smuldi3_highpart, umuldi3_highpart, and two + splitters): Delete. + 2014-09-02 Segher Boessenkool * config/rs6000/rs6000.md (mulsi3, *mulsi3_internal1, diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d903e4a0472..f9e1ebaa2d7 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -431,6 +431,11 @@ (simple_return "1")]) (define_code_attr return_str [(return "") (simple_return "simple_")]) +; Signed/unsigned variants of ops. +(define_code_iterator any_extend [sign_extend zero_extend]) +(define_code_attr u [(sign_extend "") (zero_extend "u")]) +(define_code_attr su [(sign_extend "s") (zero_extend "u")]) + ; Various instructions that come in SI and DI forms. ; A generic w/d attribute, for things like cmpw/cmpd. (define_mode_attr wd [(QI "b") @@ -454,6 +459,10 @@ ;; Bitmask for shift instructions (define_mode_attr hH [(SI "h") (DI "H")]) +;; A mode twice the size of the given mode +(define_mode_attr dmode [(SI "di") (DI "ti")]) +(define_mode_attr DMODE [(SI "DI") (DI "TI")]) + ;; Suffix for reload patterns (define_mode_attr ptrsize [(SI "32bit") (DI "64bit")]) @@ -2767,6 +2776,100 @@ (set_attr "length" "4,8")]) +(define_expand "mul3_highpart" + [(set (match_operand:GPR 0 "gpc_reg_operand") + (subreg:GPR + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand"))) + 0))] + "" +{ + if (mode == SImode && TARGET_POWERPC64) + { + emit_insn (gen_mulsi3_highpart_64 (operands[0], operands[1], + operands[2])); + DONE; + } + + if (!WORDS_BIG_ENDIAN) + { + emit_insn (gen_mul3_highpart_le (operands[0], operands[1], + operands[2])); + DONE; + } +}) + +(define_insn "*mul3_highpart" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (subreg:GPR + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand" "r")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand" "r"))) + 0))] + "WORDS_BIG_ENDIAN && !(mode == SImode && TARGET_POWERPC64)" + "mulh %0,%1,%2" + [(set_attr "type" "mul") + (set_attr "size" "")]) + +(define_insn "mulsi3_highpart_le" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (subreg:SI + (mult:DI (any_extend:DI + (match_operand:SI 1 "gpc_reg_operand" "r")) + (any_extend:DI + (match_operand:SI 2 "gpc_reg_operand" "r"))) + 4))] + "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" + "mulhw %0,%1,%2" + [(set_attr "type" "mul")]) + +(define_insn "muldi3_highpart_le" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (subreg:DI + (mult:TI (any_extend:TI + (match_operand:DI 1 "gpc_reg_operand" "r")) + (any_extend:TI + (match_operand:DI 2 "gpc_reg_operand" "r"))) + 8))] + "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" + "mulhd %0,%1,%2" + [(set_attr "type" "mul") + (set_attr "size" "64")]) + +(define_insn "mulsi3_highpart_64" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (truncate:SI + (lshiftrt:DI + (mult:DI (any_extend:DI + (match_operand:SI 1 "gpc_reg_operand" "r")) + (any_extend:DI + (match_operand:SI 2 "gpc_reg_operand" "r"))) + (const_int 32))))] + "TARGET_POWERPC64" + "mulhw %0,%1,%2" + [(set_attr "type" "mul")]) + +(define_expand "mul3" + [(set (match_operand: 0 "gpc_reg_operand") + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand"))))] + "!(mode == SImode && TARGET_POWERPC64)" +{ + rtx l = gen_reg_rtx (mode); + rtx h = gen_reg_rtx (mode); + emit_insn (gen_mul3 (l, operands[1], operands[2])); + emit_insn (gen_mul3_highpart (h, operands[1], operands[2])); + emit_move_insn (gen_lowpart (mode, operands[0]), l); + emit_move_insn (gen_highpart (mode, operands[0]), h); + DONE; +}) + + (define_insn "udiv3" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") @@ -6622,96 +6725,6 @@ [(set_attr "type" "two") (set_attr "length" "8")]) -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\"; -} - [(set_attr "type" "mul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "mul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "smulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhw %0,%1,%2" - [(set_attr "type" "mul")]) - -(define_insn "umulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhwu %0,%1,%2" - [(set_attr "type" "mul")]) ;; Shift by a variable amount is too complex to be worth open-coding. We ;; just handle shifts by constants. @@ -6758,60 +6771,6 @@ ;; PowerPC64 DImode operations. -(define_insn "smuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (sign_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (sign_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhd %0,%1,%2" - [(set_attr "type" "mul") - (set_attr "size" "64")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (zero_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhdu %0,%1,%2" - [(set_attr "type" "mul") - (set_attr "size" "64")]) - -(define_expand "mulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - -(define_expand "umulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - (define_insn "*rotldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")