[PATCH 2/7] [ARC] Avoid use of hard registers before reg-alloc.
Andrew Burgess
andrew.burgess@embecosm.com
Wed May 31 14:52:00 GMT 2017
* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-05-19 12:30:57 +0200]:
> gcc/
> 2017-04-10 Claudiu Zissulescu <claziss@synopsys.com>
>
> * config/arc/arc.md (mulsi3): Avoid use of hard registers before
> reg-alloc when having mul64 or mul32x16 instructions.
> (mulsidi3): Likewise.
> (umulsidi3): Likewise.
> (mulsi32x16): New pattern.
> (mulsi64): Likewise.
> (mulsidi64): Likewise.
> (umulsidi64): Likewise.
> (MUL32x16_REG): Define.
> (mul64_600): Use MUL32x16_REG.
> (mac64_600): Likewise.
> (umul64_600): Likewise.
> (umac64_600): Likewise.
Looks good, thanks,
Andrew
> ---
> gcc/config/arc/arc.md | 168 +++++++++++++++++++++++++++++++++++---------------
> 1 file changed, 119 insertions(+), 49 deletions(-)
>
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index db5867c..c0ad86c 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -176,6 +176,7 @@
> (ILINK2_REGNUM 30)
> (RETURN_ADDR_REGNUM 31)
> (MUL64_OUT_REG 58)
> + (MUL32x16_REG 56)
> (ARCV2_ACC 58)
>
> (LP_COUNT 60)
> @@ -1940,29 +1941,17 @@
> }
> else if (TARGET_MUL64_SET)
> {
> - emit_insn (gen_mulsi_600 (operands[1], operands[2],
> - gen_mlo (), gen_mhi ()));
> - emit_move_insn (operands[0], gen_mlo ());
> - DONE;
> + rtx tmp = gen_reg_rtx (SImode);
> + emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
> + emit_move_insn (operands[0], tmp);
> + DONE;
> }
> else if (TARGET_MULMAC_32BY16_SET)
> {
> - if (immediate_operand (operands[2], SImode)
> - && INTVAL (operands[2]) >= 0
> - && INTVAL (operands[2]) <= 65535)
> - {
> - emit_insn (gen_umul_600 (operands[1], operands[2],
> - gen_acc2 (), gen_acc1 ()));
> - emit_move_insn (operands[0], gen_acc2 ());
> - DONE;
> - }
> - operands[2] = force_reg (SImode, operands[2]);
> - emit_insn (gen_umul_600 (operands[1], operands[2],
> - gen_acc2 (), gen_acc1 ()));
> - emit_insn (gen_mac_600 (operands[1], operands[2],
> - gen_acc2 (), gen_acc1 ()));
> - emit_move_insn (operands[0], gen_acc2 ());
> - DONE;
> + rtx tmp = gen_reg_rtx (SImode);
> + emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
> + emit_move_insn (operands[0], tmp);
> + DONE;
> }
> else
> {
> @@ -1974,6 +1963,35 @@
> }
> })
>
> +(define_insn_and_split "mulsi32x16"
> + [(set (match_operand:SI 0 "register_operand" "=w")
> + (mult:SI (match_operand:SI 1 "register_operand" "%c")
> + (match_operand:SI 2 "nonmemory_operand" "ci")))
> + (clobber (reg:DI MUL32x16_REG))]
> + "TARGET_MULMAC_32BY16_SET"
> + "#"
> + "TARGET_MULMAC_32BY16_SET && reload_completed"
> + [(const_int 0)]
> + {
> + if (immediate_operand (operands[2], SImode)
> + && INTVAL (operands[2]) >= 0
> + && INTVAL (operands[2]) <= 65535)
> + {
> + emit_insn (gen_umul_600 (operands[1], operands[2],
> + gen_acc2 (), gen_acc1 ()));
> + emit_move_insn (operands[0], gen_acc2 ());
> + DONE;
> + }
> + emit_insn (gen_umul_600 (operands[1], operands[2],
> + gen_acc2 (), gen_acc1 ()));
> + emit_insn (gen_mac_600 (operands[1], operands[2],
> + gen_acc2 (), gen_acc1 ()));
> + emit_move_insn (operands[0], gen_acc2 ());
> + DONE;
> + }
> + [(set_attr "type" "multi")
> + (set_attr "length" "8")])
> +
> ; mululw conditional execution without a LIMM clobbers an input register;
> ; we'd need a different pattern to describe this.
> ; To make the conditional execution valid for the LIMM alternative, we
> @@ -2011,6 +2029,24 @@
> (set_attr "predicable" "no, no, yes")
> (set_attr "cond" "nocond, canuse_limm, canuse")])
>
> +(define_insn_and_split "mulsi64"
> + [(set (match_operand:SI 0 "register_operand" "=w")
> + (mult:SI (match_operand:SI 1 "register_operand" "%c")
> + (match_operand:SI 2 "nonmemory_operand" "ci")))
> + (clobber (reg:DI MUL64_OUT_REG))]
> + "TARGET_MUL64_SET"
> + "#"
> + "TARGET_MUL64_SET && reload_completed"
> + [(const_int 0)]
> +{
> + emit_insn (gen_mulsi_600 (operands[1], operands[2],
> + gen_mlo (), gen_mhi ()));
> + emit_move_insn (operands[0], gen_mlo ());
> + DONE;
> +}
> + [(set_attr "type" "multi")
> + (set_attr "length" "8")])
> +
> (define_insn "mulsi_600"
> [(set (match_operand:SI 2 "mlo_operand" "")
> (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
> @@ -2155,8 +2191,7 @@
> (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
> (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
> "TARGET_ANY_MPY"
> -"
> -{
> + {
> if (TARGET_PLUS_MACD)
> {
> if (CONST_INT_P (operands[2]))
> @@ -2189,18 +2224,37 @@
> }
> else if (TARGET_MULMAC_32BY16_SET)
> {
> - rtx result_hi = gen_highpart(SImode, operands[0]);
> - rtx result_low = gen_lowpart(SImode, operands[0]);
> -
> - emit_insn (gen_mul64_600 (operands[1], operands[2]));
> - emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
> - emit_move_insn (result_low, gen_acc2 ());
> + operands[2] = force_reg (SImode, operands[2]);
> + emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
> DONE;
> }
> -}")
> + operands[2] = force_reg (SImode, operands[2]);
> + })
> +
> +(define_insn_and_split "mulsidi64"
> + [(set (match_operand:DI 0 "register_operand" "=w")
> + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
> + (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
> + (clobber (reg:DI MUL32x16_REG))]
> + "TARGET_MULMAC_32BY16_SET"
> + "#"
> + "TARGET_MULMAC_32BY16_SET && reload_completed"
> + [(const_int 0)]
> + {
> + rtx result_hi = gen_highpart (SImode, operands[0]);
> + rtx result_low = gen_lowpart (SImode, operands[0]);
> +
> + emit_insn (gen_mul64_600 (operands[1], operands[2]));
> + emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
> + emit_move_insn (result_low, gen_acc2 ());
> + DONE;
> + }
> + [(set_attr "type" "multi")
> + (set_attr "length" "8")])
> +
>
> (define_insn "mul64_600"
> - [(set (reg:DI 56)
> + [(set (reg:DI MUL32x16_REG)
> (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
> "c,c,c"))
> (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
> @@ -2218,14 +2272,14 @@
>
> ;; ??? check if this is canonical rtl
> (define_insn "mac64_600"
> - [(set (reg:DI 56)
> + [(set (reg:DI MUL32x16_REG)
> (plus:DI
> (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
> (ashift:DI
> (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
> (const_int 16) (const_int 16))
> (const_int 16)))
> - (reg:DI 56)))
> + (reg:DI MUL32x16_REG)))
> (set (match_operand:SI 0 "register_operand" "=w,w,w")
> (zero_extract:SI
> (plus:DI
> @@ -2234,7 +2288,7 @@
> (sign_extract:DI (match_dup 2)
> (const_int 16) (const_int 16))
> (const_int 16)))
> - (reg:DI 56))
> + (reg:DI MUL32x16_REG))
> (const_int 32) (const_int 32)))]
> "TARGET_MULMAC_32BY16_SET"
> "machlw%? %0, %1, %2"
> @@ -2428,20 +2482,14 @@
> }
> else if (TARGET_MUL64_SET)
> {
> - emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
> + operands[2] = force_reg (SImode, operands[2]);
> + emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
> DONE;
> }
> else if (TARGET_MULMAC_32BY16_SET)
> {
> - rtx result_hi = gen_reg_rtx (SImode);
> - rtx result_low = gen_reg_rtx (SImode);
> -
> - result_hi = gen_highpart(SImode , operands[0]);
> - result_low = gen_lowpart(SImode , operands[0]);
> -
> - emit_insn (gen_umul64_600 (operands[1], operands[2]));
> - emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
> - emit_move_insn (result_low, gen_acc2 ());
> + operands[2] = force_reg (SImode, operands[2]);
> + emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
> DONE;
> }
> else
> @@ -2454,8 +2502,32 @@
> }
> })
>
> +(define_insn_and_split "umulsidi64"
> + [(set (match_operand:DI 0 "register_operand" "=w")
> + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
> + (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
> + (clobber (reg:DI MUL32x16_REG))]
> + "TARGET_MULMAC_32BY16_SET"
> + "#"
> + "TARGET_MULMAC_32BY16_SET && reload_completed"
> + [(const_int 0)]
> + {
> + rtx result_hi;
> + rtx result_low;
> +
> + result_hi = gen_highpart (SImode, operands[0]);
> + result_low = gen_lowpart (SImode, operands[0]);
> +
> + emit_insn (gen_umul64_600 (operands[1], operands[2]));
> + emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
> + emit_move_insn (result_low, gen_acc2 ());
> + DONE;
> + }
> + [(set_attr "type" "multi")
> + (set_attr "length" "8")])
> +
> (define_insn "umul64_600"
> - [(set (reg:DI 56)
> + [(set (reg:DI MUL32x16_REG)
> (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
> "c,c,c"))
> (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
> @@ -2472,14 +2544,14 @@
>
>
> (define_insn "umac64_600"
> - [(set (reg:DI 56)
> + [(set (reg:DI MUL32x16_REG)
> (plus:DI
> (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
> (ashift:DI
> (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
> (const_int 16) (const_int 16))
> (const_int 16)))
> - (reg:DI 56)))
> + (reg:DI MUL32x16_REG)))
> (set (match_operand:SI 0 "register_operand" "=w,w,w")
> (zero_extract:SI
> (plus:DI
> @@ -2488,7 +2560,7 @@
> (zero_extract:DI (match_dup 2)
> (const_int 16) (const_int 16))
> (const_int 16)))
> - (reg:DI 56))
> + (reg:DI MUL32x16_REG))
> (const_int 32) (const_int 32)))]
> "TARGET_MULMAC_32BY16_SET"
> "machulw%? %0, %1, %2"
> @@ -2497,8 +2569,6 @@
> (set_attr "predicable" "no,no,yes")
> (set_attr "cond" "nocond, canuse_limm, canuse")])
>
> -
> -
> ;; DI <- DI(unsigned SI) * DI(unsigned SI)
> (define_insn_and_split "umulsidi3_700"
> [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
> --
> 1.9.1
>
More information about the Gcc-patches
mailing list