+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
/* 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 *));
}
\f
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;
+ }
+}
+\f
+const char *
output_logical_op (mode, operands)
enum machine_mode mode;
rtx *operands;
(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")