[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