This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] h8300.md: Optimize addsi_h8300h.


Hi,

Attached is a patch to optimize addsi_h8300h.

A constant addition in SImode can be optimized in various ways.  In
particular, if the lower 16-bit of the constant is 0, we can use
instructions like add.w, inc.w, and dec.w.

Tested on h8300 port.  Committed.

Kazu Hirata

2002-12-25  Kazu Hirata  <kazu@cs.umass.edu>

	* config/h8300/h8300-protos.h: Add prototypes for
	output_plussi, compute_plussi_length, and compute_plussi_cc.
	* config/h8300/h8300.c (output_plussi): New.
	(compute_plussi_length): Likewise.
	(compute_plussi_cc): Likewise.
	* config/h8300/h8300.md (addsi_h8300h): Call
	output_plussi, compute_plussi_length, and compute_plussi_cc.

Index: h8300-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300-protos.h,v
retrieving revision 1.37
diff -c -r1.37 h8300-protos.h
*** h8300-protos.h	23 Dec 2002 14:58:53 -0000	1.37
--- h8300-protos.h	25 Dec 2002 14:45:04 -0000
***************
*** 26,31 ****
--- 26,34 ----
  
  /* Declarations for functions used in insn-output.c.  */
  #ifdef RTX_CODE
+ extern const char *output_plussi PARAMS ((rtx *));
+ extern unsigned int compute_plussi_length PARAMS ((rtx *));
+ extern enum attr_cc compute_plussi_cc PARAMS ((rtx *));
  extern const char *output_a_shift PARAMS ((rtx *));
  extern unsigned int compute_a_shift_length PARAMS ((rtx, rtx *));
  extern const char *emit_a_rotate PARAMS ((enum rtx_code, rtx *));
Index: h8300.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.c,v
retrieving revision 1.183
diff -c -r1.183 h8300.c
*** h8300.c	23 Dec 2002 14:58:53 -0000	1.183
--- h8300.c	25 Dec 2002 14:45:05 -0000
***************
*** 1894,1899 ****
--- 1894,2069 ----
  }
  
  const char *
+ output_plussi (operands)
+      rtx *operands;
+ {
+   enum machine_mode mode = GET_MODE (operands[0]);
+ 
+   if (mode != SImode)
+     abort ();
+ 
+   if (TARGET_H8300)
+     {
+       /* Currently we do not support H8/300 here yet.  */
+       abort ();
+     }
+   else
+     {
+       if (GET_CODE (operands[2]) == REG)
+ 	return "add.l\t%S2,%S0";
+ 
+       if (GET_CODE (operands[2]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT intval = INTVAL (operands[2]);
+ 
+ 	  /* See if we can finish with 2 bytes.  */
+ 
+ 	  switch (intval & 0xffffffff)
+ 	    {
+ 	    case 0x00000001:
+ 	    case 0x00000002:
+ 	    case 0x00000004:
+ 	      return "adds\t%2,%S0";
+ 
+ 	    case 0xffffffff:
+ 	    case 0xfffffffe:
+ 	    case 0xfffffffc:
+ 	      return "subs\t%G2,%S0";
+ 
+ 	    case 0x00010000:
+ 	    case 0x00020000:
+ 	      operands[2] = GEN_INT (intval >> 16);
+ 	      return "inc.w\t%2,%e0";
+ 
+ 	    case 0xffff0000:
+ 	    case 0xfffe0000:
+ 	      operands[2] = GEN_INT (intval >> 16);
+ 	      return "dec.w\t%G2,%e0";
+ 	    }
+ 
+ 	  /* See if we can finish with 4 bytes.  */
+ 	  if ((intval & 0xffff) == 0)
+ 	    {
+ 	      operands[2] = GEN_INT (intval >> 16);
+ 	      return "add.w\t%2,%e0";
+ 	    }
+ 	}
+ 
+       return "add.l\t%S2,%S0";
+     }
+ }
+ 
+ unsigned int
+ compute_plussi_length (operands)
+      rtx *operands;
+ {
+   enum machine_mode mode = GET_MODE (operands[0]);
+ 
+   if (mode != SImode)
+     abort ();
+ 
+   if (TARGET_H8300)
+     {
+       /* Currently we do not support H8/300 here yet.  */
+       abort ();
+     }
+   else
+     {
+       if (GET_CODE (operands[2]) == REG)
+ 	return 2;
+ 
+       if (GET_CODE (operands[2]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT intval = INTVAL (operands[2]);
+ 
+ 	  /* See if we can finish with 2 bytes.  */
+ 
+ 	  switch (intval & 0xffffffff)
+ 	    {
+ 	    case 0x00000001:
+ 	    case 0x00000002:
+ 	    case 0x00000004:
+ 	      return 2;
+ 
+ 	    case 0xffffffff:
+ 	    case 0xfffffffe:
+ 	    case 0xfffffffc:
+ 	      return 2;
+ 
+ 	    case 0x00010000:
+ 	    case 0x00020000:
+ 	      return 2;
+ 
+ 	    case 0xffff0000:
+ 	    case 0xfffe0000:
+ 	      return 2;
+ 	    }
+ 
+ 	  /* See if we can finish with 4 bytes.  */
+ 	  if ((intval & 0xffff) == 0)
+ 	    return 4;
+ 	}
+ 
+       return 6;
+     }
+ }
+ 
+ enum attr_cc
+ compute_plussi_cc (operands)
+      rtx *operands;
+ {
+   enum machine_mode mode = GET_MODE (operands[0]);
+ 
+   if (mode != SImode)
+     abort ();
+ 
+   if (TARGET_H8300)
+     {
+       /* Currently we do not support H8/300 here yet.  */
+       abort ();
+     }
+   else
+     {
+       if (GET_CODE (operands[2]) == REG)
+ 	return CC_SET_ZN;
+ 
+       if (GET_CODE (operands[2]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT intval = INTVAL (operands[2]);
+ 
+ 	  /* See if we can finish with 2 bytes.  */
+ 
+ 	  switch (intval & 0xffffffff)
+ 	    {
+ 	    case 0x00000001:
+ 	    case 0x00000002:
+ 	    case 0x00000004:
+ 	      return CC_NONE_0HIT;
+ 
+ 	    case 0xffffffff:
+ 	    case 0xfffffffe:
+ 	    case 0xfffffffc:
+ 	      return CC_NONE_0HIT;
+ 
+ 	    case 0x00010000:
+ 	    case 0x00020000:
+ 	      return CC_CLOBBER;
+ 
+ 	    case 0xffff0000:
+ 	    case 0xfffe0000:
+ 	      return CC_CLOBBER;
+ 	    }
+ 
+ 	  /* See if we can finish with 4 bytes.  */
+ 	  if ((intval & 0xffff) == 0)
+ 	    return CC_CLOBBER;
+ 	}
+ 
+       return CC_SET_ZN;
+     }
+ }
+ 
+ const char *
  output_logical_op (mode, operands)
       enum machine_mode mode;
       rtx *operands;
Index: h8300.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.md,v
retrieving revision 1.132
diff -c -r1.132 h8300.md
*** h8300.md	25 Dec 2002 01:30:41 -0000	1.132
--- h8300.md	25 Dec 2002 14:45:06 -0000
***************
*** 837,853 ****
     (set_attr "cc" "clobber")])
  
  (define_insn "addsi_h8300h"
!   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
! 	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
! 		 (match_operand:SI 2 "nonmemory_operand" "L,N,i,r")))]
    "TARGET_H8300H || TARGET_H8300S"
!   "@
!    adds	%2,%S0
!    subs	%G2,%S0
!    add.l	%S2,%S0
!    add.l	%S2,%S0"
!   [(set_attr "length" "2,2,6,2")
!    (set_attr "cc" "none_0hit,none_0hit,set_zn,set_zn")])
  
  (define_insn "addsi3_incdec"
    [(set (match_operand:SI 0 "register_operand" "=r,r")
--- 837,851 ----
     (set_attr "cc" "clobber")])
  
  (define_insn "addsi_h8300h"
!   [(set (match_operand:SI 0 "register_operand" "=r,r")
! 	(plus:SI (match_operand:SI 1 "register_operand" "%0,0")
! 		 (match_operand:SI 2 "nonmemory_operand" "i,r")))]
    "TARGET_H8300H || TARGET_H8300S"
!   "* return output_plussi (operands);"
!   [(set (attr "length")
! 	(symbol_ref "compute_plussi_length (operands)"))
!    (set (attr "cc")
! 	(symbol_ref "compute_plussi_cc (operands)"))])
  
  (define_insn "addsi3_incdec"
    [(set (match_operand:SI 0 "register_operand" "=r,r")


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]