From: Claudiu Zissulescu Date: Thu, 1 Jun 2017 09:41:46 +0000 (+0200) Subject: [ARC] Avoid use of hard registers before reg-alloc. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f75b66845b1ae16de13f02234d4c9be8193f49e;p=gcc.git [ARC] Avoid use of hard registers before reg-alloc. gcc/ 2017-06-01 Claudiu Zissulescu * 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. From-SVN: r248777 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2af5953aaee..909c1dd8e93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2017-06-01 Claudiu Zissulescu + + * 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. + 2017-06-01 Claudiu Zissulescu * config/arc/arc.md (mulsi3_700): Make it commutative. diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index cce5973ce6c..3628efcc098 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")