From 7d6ac401b6272a6a2109bdcca220798bbf6ddf90 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu@cs.umass.edu>
Date: Wed, 25 Dec 2002 14:54:50 +0000
Subject: [PATCH] h8300-protos.h: Add prototypes for output_plussi,
 compute_plussi_length, and compute_plussi_cc.

	* 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.

From-SVN: r60500
---
 gcc/ChangeLog                   |  10 ++
 gcc/config/h8300/h8300-protos.h |   3 +
 gcc/config/h8300/h8300.c        | 170 ++++++++++++++++++++++++++++++++
 gcc/config/h8300/h8300.md       |  18 ++--
 4 files changed, 191 insertions(+), 10 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e427f0f75b91..d51ea40d6cae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
 2002-12-24  Kazu Hirata  <kazu@cs.umass.edu>
 
 	* config/h8300/h8300.md (two peepholes): Use match_dup instead
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 70ec579547cb..990fff7b0ebd 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -26,6 +26,9 @@ Boston, MA 02111-1307, USA.  */
 
 /* 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 *));
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index f45ac1656948..28405dd6f6e1 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1894,6 +1894,176 @@ bit_operator (x, mode)
 }
 
 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;
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 39805fb395c9..19c95fa4d975 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -837,17 +837,15 @@
    (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")))]
+  [(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"
-  "@
-   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")])
+  "* 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")
-- 
GitLab