aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1996-03-11 21:05:49 +0000
committerDoug Evans <dje@gnu.org>1996-03-11 21:05:49 +0000
commit269c14e111ebc7745eda1a98585078ccd622fb82 (patch)
tree0a6168f0637dbceaa64e84f383b2c20ef4e55b19
parent4e74d8ec4b55e5a28738f5d3a2cb99335c0098f4 (diff)
downloadgcc-269c14e111ebc7745eda1a98585078ccd622fb82.zip
gcc-269c14e111ebc7745eda1a98585078ccd622fb82.tar.gz
gcc-269c14e111ebc7745eda1a98585078ccd622fb82.tar.bz2
h8300.h (SP_AND_G_REGS): Renamed from SP_AND_G_REG.
* h8300/h8300.h (SP_AND_G_REGS): Renamed from SP_AND_G_REG. (CC_DONE_CBIT): Delete. (CC_OVERFLOW_0,CC_OVERFLOW_UNUSABLE,CC_NO_CARRY): Define. * h8300/h8300.c (cond_string): Delete CC_DONE_CBIT handling. (notice_update_cc): Delete CC_CBIT, CC_WHOOPS. Add CC_SET_ZN_C0. (restore_compare_p): New function. (shift_one): Use shll instead of shal so overflow bit is usable. Set cc_valid bits to cc_status.flags values. (emit_a_shift): Set cc_status.flags. * h8300/h8300.md (attr cc): Delete whoops,cbit. Add set_zn_c0. (all patterns) Update cc attr setting. (tstqi,tsthi,tstsi): Delete CC_DONE_CBIT handling. (addhi3,subhi3): Change define_expand to define_insn. (branch_true,branch_false): Check if compare needs to be restored. From-SVN: r11514
-rw-r--r--gcc/config/h8300/h8300.c117
-rw-r--r--gcc/config/h8300/h8300.h28
-rw-r--r--gcc/config/h8300/h8300.md168
3 files changed, 171 insertions, 142 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 5d2f2b4..cadff01 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -757,12 +757,8 @@ cond_string (code)
switch (code)
{
case NE:
- if (cc_prev_status.flags & CC_DONE_CBIT)
- return "cs";
return "ne";
case EQ:
- if (cc_prev_status.flags & CC_DONE_CBIT)
- return "cc";
return "eq";
case GE:
return "ge";
@@ -800,8 +796,7 @@ print_operand (file, x, code)
/* This is used for communication between the 'P' and 'U' codes. */
static char *last_p;
- /* This is used for communication between the 'Z' and 'Y' codes. */
- /* ??? 'V' and 'W' use it too. */
+ /* This is used for communication between codes V,W,Z and Y. */
static int bitint;
switch (code)
@@ -1081,7 +1076,7 @@ print_operand (file, x, code)
switch (GET_MODE (x))
{
case QImode:
-#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
+#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
fprintf (file, "%s", byte_reg (x, 0));
#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
fprintf (file, "%s", names_big[REGNO (x)]);
@@ -1271,49 +1266,89 @@ notice_update_cc (body, insn)
switch (get_attr_cc (insn))
{
case CC_NONE:
- /* Insn does not affect the CC at all */
+ /* Insn does not affect CC at all. */
break;
case CC_NONE_0HIT:
- /* Insn does not change the CC, but the 0't operand has been changed. */
-
+ /* Insn does not change CC, but the 0'th operand has been changed. */
if (cc_status.value1 != 0
&& reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
cc_status.value1 = 0;
-
+ /* ??? Is value2 ever set?. */
if (cc_status.value2 != 0
&& reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
cc_status.value2 = 0;
-
break;
case CC_SET:
- /* Insn sets CC to recog_operand[0], but overflow is impossible. */
+ /* Insn sets the Z,N flags of CC to recog_operand[0].
+ V is always set to 0. C may or may not be set to 0 but that's ok
+ because alter_cond will change tests to use EQ/NE. */
CC_STATUS_INIT;
- cc_status.flags |= CC_NO_OVERFLOW;
+ cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
cc_status.value1 = recog_operand[0];
break;
- case CC_COMPARE:
- /* The insn is a compare instruction */
+ case CC_SET_ZN_C0:
+ /* Insn sets the Z,N flags of CC to recog_operand[0].
+ The V flag is unusable. The C flag may or may not be known but
+ that's ok because alter_cond will change tests to use EQ/NE. */
CC_STATUS_INIT;
- cc_status.value1 = SET_SRC (body);
+ cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
break;
- case CC_CBIT:
+ case CC_COMPARE:
+ /* The insn is a compare instruction. */
CC_STATUS_INIT;
- cc_status.flags |= CC_DONE_CBIT;
- cc_status.value1 = 0;
+ cc_status.value1 = SET_SRC (body);
break;
- case CC_WHOOPS:
case CC_CLOBBER:
- /* Insn clobbers CC. */
+ /* Insn doesn't leave CC in a usable state. */
CC_STATUS_INIT;
break;
}
}
+/* Return 1 if a previous compare needs to be re-issued. This will happen
+ if the compare was deleted because the previous insn set it, but the
+ branch needs CC flags not set.
+
+ OP is the comparison being performed. */
+
+int
+restore_compare_p (op)
+ rtx op;
+{
+ switch (GET_CODE (op))
+ {
+ case EQ:
+ case NE:
+ break;
+ case LT:
+ case LE:
+ case GT:
+ case GE:
+ if (cc_status.flags & CC_OVERFLOW_UNUSABLE)
+ return 1;
+ break;
+ case LTU:
+ case LEU:
+ case GTU:
+ case GEU:
+ /* If the carry flag isn't usable, the test should have been changed
+ by alter_cond. */
+ if (cc_status.flags & CC_NO_CARRY)
+ abort ();
+ break;
+ default:
+ abort ();
+ }
+
+ return 0;
+}
+
/* Recognize valid operators for bit instructions */
int
@@ -1486,8 +1521,9 @@ enum shift_mode
QIshift, HIshift, SIshift
};
-/* For single bit shift insns, record assembler and whether the condition code
- is valid afterwards. */
+/* For single bit shift insns, record assembler and what bits of the
+ condition code are valid afterwards (represented as various CC_FOO
+ bits, 0 means CC isn't left in a usable state). */
struct shift_insn
{
@@ -1507,19 +1543,19 @@ static const struct shift_insn shift_one[2][3][3] =
{
/* SHIFT_ASHIFT */
{
- { "shal %X0", 1 },
- { "add.w %T0,%T0\t; shal.w", 1 },
+ { "shll %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
+ { "add.w %T0,%T0\t; shal.w", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
{ "add.w %f0,%f0\t; shal.l\n\taddx %y0,%y0\n\taddx %z0,%z0\t; end shal.l", 0 }
},
/* SHIFT_LSHIFTRT */
{
- { "shlr %X0", 1 },
+ { "shlr %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "shlr %t0\t; shlr.w\n\trotxr %s0\t; end shlr.w", 0 },
{ "shlr %z0\t; shlr.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shlr.l", 0 }
},
/* SHIFT_ASHIFTRT */
{
- { "shar %X0", 1 },
+ { "shar %X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
{ "shar %t0\t; shar.w\n\trotxr %s0\t; end shar.w", 0 },
{ "shar %z0\t; shar.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shar.l", 0 }
}
@@ -1528,21 +1564,21 @@ static const struct shift_insn shift_one[2][3][3] =
{
/* SHIFT_ASHIFT */
{
- { "shal.b %X0", 1 },
- { "shal.w %T0", 1 },
- { "shal.l %S0", 1 }
+ { "shll.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
+ { "shll.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
+ { "shll.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
},
/* SHIFT_LSHIFTRT */
{
- { "shlr.b %X0", 1 },
- { "shlr.w %T0", 1 },
- { "shlr.l %S0", 1 }
+ { "shlr.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
+ { "shlr.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
+ { "shlr.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
},
/* SHIFT_ASHIFTRT */
{
- { "shar.b %X0", 1 },
- { "shar.w %T0", 1 },
- { "shar.l %S0", 1 }
+ { "shar.b %X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
+ { "shar.w %T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
+ { "shar.l %S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
}
}
};
@@ -1911,7 +1947,10 @@ emit_a_shift (insn, operands)
while (--n >= 0)
output_asm_insn (assembler, operands);
if (cc_valid)
- cc_status.value1 = operands[0];
+ {
+ cc_status.value1 = operands[0];
+ cc_status.flags |= cc_valid;
+ }
return "";
case SHIFT_ROT_AND:
{
@@ -1934,6 +1973,7 @@ emit_a_shift (insn, operands)
sprintf (insn_buf, "and #%d,%%X0\t; end shift %d via rotate+and",
mask, n);
cc_status.value1 = operands[0];
+ cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
break;
case HImode:
sprintf (insn_buf, "and #%d,%%s0\n\tand #%d,%%t0\t; end shift %d via rotate+and",
@@ -1949,6 +1989,7 @@ emit_a_shift (insn, operands)
"bwl"[shift_mode], mask,
mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
cc_status.value1 = operands[0];
+ cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
}
output_asm_insn (insn_buf, operands);
return "";
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index f219575..0babf4a 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -322,14 +322,18 @@ do { \
/* The h8 has only one kind of register, but we mustn't do byte by
byte operations on the sp, so we keep it as a different class */
-enum reg_class { NO_REGS, LONG_REGS, GENERAL_REGS, SP_REG, SP_AND_G_REG, ALL_REGS, LIM_REG_CLASSES };
+enum reg_class {
+ NO_REGS, LONG_REGS, GENERAL_REGS, SP_REG, SP_AND_G_REGS,
+ ALL_REGS, LIM_REG_CLASSES
+};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- {"NO_REGS", "LONG_REGS", "GENERAL_REGS", "SP_REG", "SP_AND_G_REG", "ALL_REGS", "LIM_REGS" }
+{ "NO_REGS", "LONG_REGS", "GENERAL_REGS", "SP_REG", "SP_AND_G_REGS", \
+ "ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
@@ -340,7 +344,7 @@ enum reg_class { NO_REGS, LONG_REGS, GENERAL_REGS, SP_REG, SP_AND_G_REG, ALL_RE
0x07f, /* LONG_REGS */ \
0x07f, /* GENERAL_REGS */ \
0x080, /* SP_REG */ \
- 0x0ff, /* SP_AND_G_REG */ \
+ 0x0ff, /* SP_AND_G_REGS */ \
0x1ff, /* ALL_REGS */ \
}
@@ -971,14 +975,18 @@ extern int current_function_anonymous_args;
Do not alter them if the instruction would not alter the cc's. */
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-#define CC_DONE_CBIT 0400
-#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \
-{ \
- if (cc_status.flags & CC_NO_OVERFLOW) \
- return NO_OV; \
- return NORMAL; \
-}
+/* The mov,and,or,xor insns always set V to 0. */
+#define CC_OVERFLOW_0 0400
+/* The add insns don't set overflow in a usable way. */
+#define CC_OVERFLOW_UNUSABLE 01000
+/* The mov,and,or,xor insns don't set carry. That's ok though as the
+ Z bit is all we need when doing unsigned comparisons on the result of
+ these insns (since they're always with 0). However, conditions.h has
+ CC_NO_OVERFLOW defined for this purpose. Rename it to something more
+ understandable. */
+#define CC_NO_CARRY CC_NO_OVERFLOW
+/* ??? Use CC_Z_IN_NOT_C for bld insns? */
/* Control the assembler format that we output. */
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 6ad8616..a68d54c 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -1,5 +1,5 @@
;; GCC machine description for Hitachi H8/300
-;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com),
;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -21,7 +21,6 @@
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-
;; The original PO technology requires these to be ordered by speed,
;; so that assigner will pick the fastest.
@@ -58,9 +57,20 @@
(eq_attr "type" "call") (const_int 4)]
(const_int 200)))
-(define_attr "cc" "none,clobber,none_0hit,set,compare,whoops,cbit"
- (const_string "whoops"))
-
+;; Condition code settings.
+;; none - insn does not affect cc
+;; none_0hit - insn does not affect cc but it does modify operand 0
+;; This attribute is used to keep track of when operand 0 changes.
+;; See the description of NOTICE_UPDATE_CC for more info.
+;; set - insn sets flags z,n. v,c are set to 0.
+;; (c may not really be set to 0 but that's ok, we don't need it anyway).
+;; set_zn_c0 - insn sets z,n to usable values. v is unknown. c may or may not
+;; be known (if it isn't that's ok, we don't need it anyway).
+;; compare - compare instruction
+;; clobber - value of cc is unknown
+(define_attr "cc" "none,none_0hit,set,set_zn_c0,compare,clobber"
+ (const_string "clobber"))
+
;; ----------------------------------------------------------------------
;; MOVE INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -82,10 +92,12 @@
(set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
(set_attr "cc" "set")])
+;; ??? Use of the `c' constraint doesn't seem right.
(define_insn "movqi_internal"
[(set (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<,r")
(match_operand:QI 1 "general_operand_src" "I,r>,io,r,r,c"))]
- "register_operand (operands[0],QImode) || register_operand (operands[1], QImode)"
+ "register_operand (operands[0],QImode)
+ || register_operand (operands[1], QImode)"
"@
sub.b %X0,%X0
mov.b %X1,%X0
@@ -100,7 +112,7 @@
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))
(const_int 4)])
- (set_attr "cc" "set,set,set,set,set,none")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set,clobber")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand_dst" "")
@@ -132,7 +144,7 @@
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set")])
;; movhi
@@ -167,7 +179,7 @@
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set")])
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand_dst" "")
@@ -199,7 +211,7 @@
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set")])
;; movsi
@@ -380,7 +392,7 @@
mov.l %S1,%S0"
[(set_attr "type" "move")
(set_attr "length" "2,2,8,8,4,4")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
(define_insn "movsf_h8300h"
[(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
@@ -397,8 +409,8 @@
mov.l %S1,%S0"
[(set_attr "type" "move")
(set_attr "length" "2,2,8,8,4,4")
- (set_attr "cc" "set")])
-
+ (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
+
;; ----------------------------------------------------------------------
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -406,46 +418,25 @@
(define_insn "tstqi"
[(set (cc0) (match_operand:QI 0 "register_operand" "ra"))]
""
- "*
-{
- /* ??? I don't think this is right. --Jim */
- if (cc_prev_status.flags & CC_DONE_CBIT)
- return \"btst #0,%X0\";
- else
- return \"cmp.b #0,%X0\";
-}"
+ "cmp.b #0,%X0"
[(set_attr "type" "arith")
- (set_attr "length" "4")
+ (set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "tsthi"
[(set (cc0) (match_operand:HI 0 "general_operand" "ra"))]
""
- "*
-{
- /* ??? I don't think this is right. --Jim */
- if (cc_prev_status.flags & CC_DONE_CBIT)
- return \"btst #0,%0l\";
- else
- return \"mov.w %T0,%T0\";
-}"
+ "mov.w %T0,%T0"
[(set_attr "type" "arith")
- (set_attr "length" "4")
+ (set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "tstsi"
[(set (cc0) (match_operand:SI 0 "general_operand" "ra"))]
"TARGET_H8300H"
- "*
-{
- /* ??? I don't think this is right. --Jim */
- if (cc_prev_status.flags & CC_DONE_CBIT)
- return \"btst #0,%0l\";
- else
- return \"mov.l %S0,%S0\";
-}"
+ "mov.l %S0,%S0"
[(set_attr "type" "arith")
- (set_attr "length" "4")
+ (set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "cmpqi"
@@ -481,7 +472,7 @@
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "compare")])
-
+
;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -494,13 +485,13 @@
"add.b %X2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0")])
-;; ??? adds operates on the 32bit register. We can use it because we don't
+;; h8300h: adds operates on the 32bit register. We can use it because we don't
;; use the e0-7 registers.
;; ??? 4 can be handled in one insn on the 300h.
-(define_insn "addhi3_internal"
+(define_insn "addhi3"
[(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,ra,r,ra")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:HI 2 "nonmemory_operand" "K,M,L,N,n,ra")))]
@@ -514,15 +505,7 @@
add.w %T2,%T0"
[(set_attr "type" "arith,multi,arith,multi,multi,arith")
(set_attr "length" "2,4,2,4,4,2")
- (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set")])
-
-;; ??? Why is this here?
-(define_expand "addhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (plus:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
- ""
- "")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set_zn_c0")])
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "")
@@ -562,7 +545,7 @@
add.l %S2,%S0"
[(set_attr "type" "multi,multi,multi,multi,arith,arith")
(set_attr "length" "2,4,2,4,6,2")
- (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,clobber")])
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,set_zn_c0,set_zn_c0")])
;; ----------------------------------------------------------------------
;; SUBTRACT INSTRUCTIONS
@@ -578,15 +561,15 @@
add.b %G2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0")])
-;; ??? subs operates on the 32bit register. We can use it because we don't
+;; h8300h: subs operates on the 32bit register. We can use it because we don't
;; use the e0-7 registers.
;; ??? 4 can be handled in one insn on the 300h.
;; ??? The fourth alternative can use sub.w on the 300h.
;; ??? Should the 'n' constraint be an 'i' here?
-(define_insn "subhi3_internal"
+(define_insn "subhi3"
[(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,r")
(minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
(match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))]
@@ -598,15 +581,7 @@
add.b %E2,%s0\;addx %F2,%t0 ; -%0"
[(set_attr "type" "multi")
(set_attr "length" "2,4,2,4")
- (set_attr "cc" "none_0hit,none_0hit,set,clobber")])
-
-;; ??? Why is this here?
-(define_expand "subhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (minus:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
- ""
- "")
+ (set_attr "cc" "none_0hit,none_0hit,set_zn_c0,clobber")])
(define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "")
@@ -639,8 +614,8 @@
sub.l %S2,%S0"
[(set_attr "type" "multi")
(set_attr "length" "2,4,2,6")
- (set_attr "cc" "none_0hit,none_0hit,set,set")])
-
+ (set_attr "cc" "none_0hit,none_0hit,set_zn_c0,set_zn_c0")])
+
;; ----------------------------------------------------------------------
;; MULTIPLY INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -655,7 +630,7 @@
"mulxs.b %X2,%T0"
[(set_attr "type" "multi")
(set_attr "length" "4")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0")])
(define_insn "mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -665,7 +640,7 @@
"mulxs.w %T2,%S0"
[(set_attr "type" "multi")
(set_attr "length" "4")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0")])
(define_insn "umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -776,7 +751,7 @@
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
-
+
;; ----------------------------------------------------------------------
;; AND INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -805,6 +780,7 @@
}")
;; ??? Should have a bclr case here also.
+;; ??? This should be symmetric with iorhi3.
(define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -840,7 +816,7 @@
and %S2,%S0"
[(set_attr "type" "arith")
(set_attr "length" "4,6")
- (set_attr "cc" "clobber")])
+ (set_attr "cc" "set")])
;; ----------------------------------------------------------------------
;; OR INSTRUCTIONS
@@ -870,6 +846,7 @@
}")
;; ??? Should have a bset case here also.
+;; ??? This should be symmetric with andhi3.
(define_insn "iorhi3"
[(set (match_operand:HI 0 "general_operand" "=r,r")
@@ -960,6 +937,8 @@
DONE;
}")
+;; ??? This should be symmetric with andhi3.
+
(define_insn "xorhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(xor:HI (match_operand:HI 1 "general_operand" "%0")
@@ -988,8 +967,8 @@
xor %S2,%S0"
[(set_attr "type" "arith")
(set_attr "length" "4,6")
- (set_attr "cc" "clobber")])
-
+ (set_attr "cc" "set")])
+
;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -1001,7 +980,7 @@
"neg %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+ (set_attr "cc" "set_zn_c0")])
(define_expand "neghi2"
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -1032,7 +1011,7 @@
"neg %T0"
[(set_attr "type" "arith")
(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+ (set_attr "cc" "set_zn_c0")])
(define_expand "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -1063,7 +1042,7 @@
"neg %S0"
[(set_attr "type" "arith")
(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+ (set_attr "cc" "set_zn_c0")])
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
@@ -1108,7 +1087,7 @@
;; ??? length is wrong for 300h
(set_attr "length" "8")
(set_attr "cc" "clobber")])
-
+
;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -1214,6 +1193,11 @@
""
"*
{
+ /* If we erroneously deleted a compare insn (which can happen if we need
+ CC bits set that aren't), emit the compare. */
+ if (restore_compare_p (operands[1]))
+ return 0;
+
if (get_attr_length (insn) == 2)
return \"b%j1 %l0\";
else if (get_attr_length (insn) == 4)
@@ -1234,6 +1218,11 @@
;; ??? We don't take advantage of 16 bit relative jumps in the 300h.
"*
{
+ /* If we erroneously deleted a compare insn (which can happen if we need
+ CC bits set that aren't), emit the compare. */
+ if (restore_compare_p (operands[1]))
+ return 0;
+
if (get_attr_length (insn) == 2)
return \"b%k1 %l0\";
else if (get_attr_length (insn) == 4)
@@ -1290,14 +1279,6 @@
;; This is a define expand, because pointers may be either 16 or 32 bits.
-;(define_insn "indirect_jump"
-; [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
-; ""
-; "jmp @%0"
-; [(set_attr "type" "branch")
-; (set_attr "cc" "none")
-; (set_attr "length" "2")])
-
(define_expand "indirect_jump"
[(set (pc) (match_operand 0 "jump_address_operand" "Vr"))]
""
@@ -1358,7 +1339,7 @@
[(set_attr "type" "multi")
(set_attr "cc" "none")
(set_attr "length" "2")])
-
+
;; ----------------------------------------------------------------------
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -1481,7 +1462,7 @@
}"
[(set_attr "length" "10")
(set_attr "cc" "clobber")])
-
+
;; ----------------------------------------------------------------------
;; SHIFTS
;; ----------------------------------------------------------------------
@@ -1626,12 +1607,12 @@
;; However, for cases that loop or are done in pieces, cc does not contain
;; what we want. Emit_a_shift is free to tweak cc_status as desired.
(set_attr "cc" "clobber")])
-
+
;; -----------------------------------------------------------------
;; BIT FIELDS
;; -----------------------------------------------------------------
;; The H8/300 has given 1/8th of its opcode space to bitfield
-;; instructions so let's use them as well as we can
+;; instructions so let's use them as well as we can.
;; BCC and BCS patterns.
@@ -1912,7 +1893,7 @@
operands[1] = mem;
}
}")
-
+
;; -----------------------------------------------------------------
;; STACK POINTER MANIPULATIONS
;; -----------------------------------------------------------------
@@ -1931,7 +1912,7 @@
"mov.w %T1,%T0\;add.w %T2,%T0"
[(set_attr "type" "arith")
(set_attr "length" "6")
- (set_attr "cc" "set")])
+ (set_attr "cc" "set_zn_c0")])
;; -------------------------------------------
@@ -1981,7 +1962,7 @@
DONE;
}")
-
+
;; ----------------------------------------------
;; Peepholes go at the end.
;; ----------------------------------------------
@@ -2086,7 +2067,6 @@
""
"mov.b %X2,%X0\;bset %X1,%X0")
-
(define_insn "fancybclr4"
[(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
(and:QI