Commit 269c14e1 by Doug Evans

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
parent 4e74d8ec
...@@ -757,12 +757,8 @@ cond_string (code) ...@@ -757,12 +757,8 @@ cond_string (code)
switch (code) switch (code)
{ {
case NE: case NE:
if (cc_prev_status.flags & CC_DONE_CBIT)
return "cs";
return "ne"; return "ne";
case EQ: case EQ:
if (cc_prev_status.flags & CC_DONE_CBIT)
return "cc";
return "eq"; return "eq";
case GE: case GE:
return "ge"; return "ge";
...@@ -800,8 +796,7 @@ print_operand (file, x, code) ...@@ -800,8 +796,7 @@ print_operand (file, x, code)
/* This is used for communication between the 'P' and 'U' codes. */ /* This is used for communication between the 'P' and 'U' codes. */
static char *last_p; static char *last_p;
/* This is used for communication between the 'Z' and 'Y' codes. */ /* This is used for communication between codes V,W,Z and Y. */
/* ??? 'V' and 'W' use it too. */
static int bitint; static int bitint;
switch (code) switch (code)
...@@ -1081,7 +1076,7 @@ print_operand (file, x, code) ...@@ -1081,7 +1076,7 @@ print_operand (file, x, code)
switch (GET_MODE (x)) switch (GET_MODE (x))
{ {
case QImode: 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)); fprintf (file, "%s", byte_reg (x, 0));
#else /* ... or is it asm ("mov.b %0l,r2l", ...) */ #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
fprintf (file, "%s", names_big[REGNO (x)]); fprintf (file, "%s", names_big[REGNO (x)]);
...@@ -1271,49 +1266,89 @@ notice_update_cc (body, insn) ...@@ -1271,49 +1266,89 @@ notice_update_cc (body, insn)
switch (get_attr_cc (insn)) switch (get_attr_cc (insn))
{ {
case CC_NONE: case CC_NONE:
/* Insn does not affect the CC at all */ /* Insn does not affect CC at all. */
break; break;
case CC_NONE_0HIT: 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 if (cc_status.value1 != 0
&& reg_overlap_mentioned_p (recog_operand[0], cc_status.value1)) && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
cc_status.value1 = 0; cc_status.value1 = 0;
/* ??? Is value2 ever set?. */
if (cc_status.value2 != 0 if (cc_status.value2 != 0
&& reg_overlap_mentioned_p (recog_operand[0], cc_status.value2)) && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
cc_status.value2 = 0; cc_status.value2 = 0;
break; break;
case CC_SET: 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_INIT;
cc_status.flags |= CC_NO_OVERFLOW; cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
cc_status.value1 = recog_operand[0]; cc_status.value1 = recog_operand[0];
break; break;
case CC_COMPARE: case CC_SET_ZN_C0:
/* The insn is a compare instruction */ /* 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_INIT;
cc_status.value1 = SET_SRC (body); cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
cc_status.value1 = recog_operand[0];
break; break;
case CC_CBIT: case CC_COMPARE:
/* The insn is a compare instruction. */
CC_STATUS_INIT; CC_STATUS_INIT;
cc_status.flags |= CC_DONE_CBIT; cc_status.value1 = SET_SRC (body);
cc_status.value1 = 0;
break; break;
case CC_WHOOPS:
case CC_CLOBBER: case CC_CLOBBER:
/* Insn clobbers CC. */ /* Insn doesn't leave CC in a usable state. */
CC_STATUS_INIT; CC_STATUS_INIT;
break; 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 */ /* Recognize valid operators for bit instructions */
int int
...@@ -1486,8 +1521,9 @@ enum shift_mode ...@@ -1486,8 +1521,9 @@ enum shift_mode
QIshift, HIshift, SIshift QIshift, HIshift, SIshift
}; };
/* For single bit shift insns, record assembler and whether the condition code /* For single bit shift insns, record assembler and what bits of the
is valid afterwards. */ condition code are valid afterwards (represented as various CC_FOO
bits, 0 means CC isn't left in a usable state). */
struct shift_insn struct shift_insn
{ {
...@@ -1507,19 +1543,19 @@ static const struct shift_insn shift_one[2][3][3] = ...@@ -1507,19 +1543,19 @@ static const struct shift_insn shift_one[2][3][3] =
{ {
/* SHIFT_ASHIFT */ /* SHIFT_ASHIFT */
{ {
{ "shal %X0", 1 }, { "shll %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "add.w %T0,%T0\t; shal.w", 1 }, { "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 } { "add.w %f0,%f0\t; shal.l\n\taddx %y0,%y0\n\taddx %z0,%z0\t; end shal.l", 0 }
}, },
/* SHIFT_LSHIFTRT */ /* 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 %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 } { "shlr %z0\t; shlr.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shlr.l", 0 }
}, },
/* SHIFT_ASHIFTRT */ /* 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 %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 } { "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] = ...@@ -1528,21 +1564,21 @@ static const struct shift_insn shift_one[2][3][3] =
{ {
/* SHIFT_ASHIFT */ /* SHIFT_ASHIFT */
{ {
{ "shal.b %X0", 1 }, { "shll.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "shal.w %T0", 1 }, { "shll.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "shal.l %S0", 1 } { "shll.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
}, },
/* SHIFT_LSHIFTRT */ /* SHIFT_LSHIFTRT */
{ {
{ "shlr.b %X0", 1 }, { "shlr.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "shlr.w %T0", 1 }, { "shlr.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
{ "shlr.l %S0", 1 } { "shlr.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
}, },
/* SHIFT_ASHIFTRT */ /* SHIFT_ASHIFTRT */
{ {
{ "shar.b %X0", 1 }, { "shar.b %X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
{ "shar.w %T0", 1 }, { "shar.w %T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
{ "shar.l %S0", 1 } { "shar.l %S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
} }
} }
}; };
...@@ -1911,7 +1947,10 @@ emit_a_shift (insn, operands) ...@@ -1911,7 +1947,10 @@ emit_a_shift (insn, operands)
while (--n >= 0) while (--n >= 0)
output_asm_insn (assembler, operands); output_asm_insn (assembler, operands);
if (cc_valid) if (cc_valid)
cc_status.value1 = operands[0]; {
cc_status.value1 = operands[0];
cc_status.flags |= cc_valid;
}
return ""; return "";
case SHIFT_ROT_AND: case SHIFT_ROT_AND:
{ {
...@@ -1934,6 +1973,7 @@ emit_a_shift (insn, operands) ...@@ -1934,6 +1973,7 @@ emit_a_shift (insn, operands)
sprintf (insn_buf, "and #%d,%%X0\t; end shift %d via rotate+and", sprintf (insn_buf, "and #%d,%%X0\t; end shift %d via rotate+and",
mask, n); mask, n);
cc_status.value1 = operands[0]; cc_status.value1 = operands[0];
cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
break; break;
case HImode: case HImode:
sprintf (insn_buf, "and #%d,%%s0\n\tand #%d,%%t0\t; end shift %d via rotate+and", 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) ...@@ -1949,6 +1989,7 @@ emit_a_shift (insn, operands)
"bwl"[shift_mode], mask, "bwl"[shift_mode], mask,
mode == QImode ? 'X' : mode == HImode ? 'T' : 'S'); mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
cc_status.value1 = operands[0]; cc_status.value1 = operands[0];
cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
} }
output_asm_insn (insn_buf, operands); output_asm_insn (insn_buf, operands);
return ""; return "";
......
...@@ -322,14 +322,18 @@ do { \ ...@@ -322,14 +322,18 @@ do { \
/* The h8 has only one kind of register, but we mustn't do byte by /* 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 */ 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 #define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */ /* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \ #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. /* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET 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 ...@@ -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, /* LONG_REGS */ \
0x07f, /* GENERAL_REGS */ \ 0x07f, /* GENERAL_REGS */ \
0x080, /* SP_REG */ \ 0x080, /* SP_REG */ \
0x0ff, /* SP_AND_G_REG */ \ 0x0ff, /* SP_AND_G_REGS */ \
0x1ff, /* ALL_REGS */ \ 0x1ff, /* ALL_REGS */ \
} }
...@@ -971,14 +975,18 @@ extern int current_function_anonymous_args; ...@@ -971,14 +975,18 @@ extern int current_function_anonymous_args;
Do not alter them if the instruction would not alter the cc's. */ 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 NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
#define CC_DONE_CBIT 0400
#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ /* The mov,and,or,xor insns always set V to 0. */
{ \ #define CC_OVERFLOW_0 0400
if (cc_status.flags & CC_NO_OVERFLOW) \ /* The add insns don't set overflow in a usable way. */
return NO_OV; \ #define CC_OVERFLOW_UNUSABLE 01000
return NORMAL; \ /* 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. */ /* Control the assembler format that we output. */
......
;; GCC machine description for Hitachi H8/300 ;; 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), ;; Contributed by Steve Chamberlain (sac@cygnus.com),
;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). ;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. ;; Boston, MA 02111-1307, USA.
;; The original PO technology requires these to be ordered by speed, ;; The original PO technology requires these to be ordered by speed,
;; so that assigner will pick the fastest. ;; so that assigner will pick the fastest.
...@@ -58,9 +57,20 @@ ...@@ -58,9 +57,20 @@
(eq_attr "type" "call") (const_int 4)] (eq_attr "type" "call") (const_int 4)]
(const_int 200))) (const_int 200)))
(define_attr "cc" "none,clobber,none_0hit,set,compare,whoops,cbit" ;; Condition code settings.
(const_string "whoops")) ;; 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 ;; MOVE INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -82,10 +92,12 @@ ...@@ -82,10 +92,12 @@
(set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))) (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
(set_attr "cc" "set")]) (set_attr "cc" "set")])
;; ??? Use of the `c' constraint doesn't seem right.
(define_insn "movqi_internal" (define_insn "movqi_internal"
[(set (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<,r") [(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"))] (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 sub.b %X0,%X0
mov.b %X1,%X0 mov.b %X1,%X0
...@@ -100,7 +112,7 @@ ...@@ -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 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)) (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))
(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" (define_expand "movqi"
[(set (match_operand:QI 0 "general_operand_dst" "") [(set (match_operand:QI 0 "general_operand_dst" "")
...@@ -132,7 +144,7 @@ ...@@ -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 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))]) (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 ;; movhi
...@@ -167,7 +179,7 @@ ...@@ -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 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))]) (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" (define_expand "movhi"
[(set (match_operand:HI 0 "general_operand_dst" "") [(set (match_operand:HI 0 "general_operand_dst" "")
...@@ -199,7 +211,7 @@ ...@@ -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 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))]) (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 ;; movsi
...@@ -380,7 +392,7 @@ ...@@ -380,7 +392,7 @@
mov.l %S1,%S0" mov.l %S1,%S0"
[(set_attr "type" "move") [(set_attr "type" "move")
(set_attr "length" "2,2,8,8,4,4") (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" (define_insn "movsf_h8300h"
[(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
...@@ -397,8 +409,8 @@ ...@@ -397,8 +409,8 @@
mov.l %S1,%S0" mov.l %S1,%S0"
[(set_attr "type" "move") [(set_attr "type" "move")
(set_attr "length" "2,2,8,8,4,4") (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 ;; TEST INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -406,46 +418,25 @@ ...@@ -406,46 +418,25 @@
(define_insn "tstqi" (define_insn "tstqi"
[(set (cc0) (match_operand:QI 0 "register_operand" "ra"))] [(set (cc0) (match_operand:QI 0 "register_operand" "ra"))]
"" ""
"* "cmp.b #0,%X0"
{
/* ??? 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\";
}"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "4") (set_attr "length" "2")
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "tsthi" (define_insn "tsthi"
[(set (cc0) (match_operand:HI 0 "general_operand" "ra"))] [(set (cc0) (match_operand:HI 0 "general_operand" "ra"))]
"" ""
"* "mov.w %T0,%T0"
{
/* ??? 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\";
}"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "4") (set_attr "length" "2")
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "tstsi" (define_insn "tstsi"
[(set (cc0) (match_operand:SI 0 "general_operand" "ra"))] [(set (cc0) (match_operand:SI 0 "general_operand" "ra"))]
"TARGET_H8300H" "TARGET_H8300H"
"* "mov.l %S0,%S0"
{
/* ??? 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\";
}"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "4") (set_attr "length" "2")
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "cmpqi" (define_insn "cmpqi"
...@@ -481,7 +472,7 @@ ...@@ -481,7 +472,7 @@
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (set_attr "length" "2")
(set_attr "cc" "compare")]) (set_attr "cc" "compare")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS ;; ADD INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -494,13 +485,13 @@ ...@@ -494,13 +485,13 @@
"add.b %X2,%X0" "add.b %X2,%X0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (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. ;; use the e0-7 registers.
;; ??? 4 can be handled in one insn on the 300h. ;; ??? 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") [(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") (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")))] (match_operand:HI 2 "nonmemory_operand" "K,M,L,N,n,ra")))]
...@@ -514,15 +505,7 @@ ...@@ -514,15 +505,7 @@
add.w %T2,%T0" add.w %T2,%T0"
[(set_attr "type" "arith,multi,arith,multi,multi,arith") [(set_attr "type" "arith,multi,arith,multi,multi,arith")
(set_attr "length" "2,4,2,4,4,2") (set_attr "length" "2,4,2,4,4,2")
(set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set")]) (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set_zn_c0")])
;; ??? 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" "")))]
""
"")
(define_expand "addsi3" (define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
...@@ -562,7 +545,7 @@ ...@@ -562,7 +545,7 @@
add.l %S2,%S0" add.l %S2,%S0"
[(set_attr "type" "multi,multi,multi,multi,arith,arith") [(set_attr "type" "multi,multi,multi,multi,arith,arith")
(set_attr "length" "2,4,2,4,6,2") (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 ;; SUBTRACT INSTRUCTIONS
...@@ -578,15 +561,15 @@ ...@@ -578,15 +561,15 @@
add.b %G2,%X0" add.b %G2,%X0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (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. ;; use the e0-7 registers.
;; ??? 4 can be handled in one insn on the 300h. ;; ??? 4 can be handled in one insn on the 300h.
;; ??? The fourth alternative can use sub.w on the 300h. ;; ??? The fourth alternative can use sub.w on the 300h.
;; ??? Should the 'n' constraint be an 'i' here? ;; ??? 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") [(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,r")
(minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
(match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))] (match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))]
...@@ -598,15 +581,7 @@ ...@@ -598,15 +581,7 @@
add.b %E2,%s0\;addx %F2,%t0 ; -%0" add.b %E2,%s0\;addx %F2,%t0 ; -%0"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "2,4,2,4") (set_attr "length" "2,4,2,4")
(set_attr "cc" "none_0hit,none_0hit,set,clobber")]) (set_attr "cc" "none_0hit,none_0hit,set_zn_c0,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" "")))]
""
"")
(define_expand "subsi3" (define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
...@@ -639,8 +614,8 @@ ...@@ -639,8 +614,8 @@
sub.l %S2,%S0" sub.l %S2,%S0"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "2,4,2,6") (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 ;; MULTIPLY INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -655,7 +630,7 @@ ...@@ -655,7 +630,7 @@
"mulxs.b %X2,%T0" "mulxs.b %X2,%T0"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "4") (set_attr "length" "4")
(set_attr "cc" "set")]) (set_attr "cc" "set_zn_c0")])
(define_insn "mulhisi3" (define_insn "mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
...@@ -665,7 +640,7 @@ ...@@ -665,7 +640,7 @@
"mulxs.w %T2,%S0" "mulxs.w %T2,%S0"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "4") (set_attr "length" "4")
(set_attr "cc" "set")]) (set_attr "cc" "set_zn_c0")])
(define_insn "umulqihi3" (define_insn "umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
...@@ -776,7 +751,7 @@ ...@@ -776,7 +751,7 @@
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "6") (set_attr "length" "6")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; AND INSTRUCTIONS ;; AND INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -805,6 +780,7 @@ ...@@ -805,6 +780,7 @@
}") }")
;; ??? Should have a bclr case here also. ;; ??? Should have a bclr case here also.
;; ??? This should be symmetric with iorhi3.
(define_insn "andhi3" (define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
...@@ -840,7 +816,7 @@ ...@@ -840,7 +816,7 @@
and %S2,%S0" and %S2,%S0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "4,6") (set_attr "length" "4,6")
(set_attr "cc" "clobber")]) (set_attr "cc" "set")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; OR INSTRUCTIONS ;; OR INSTRUCTIONS
...@@ -870,6 +846,7 @@ ...@@ -870,6 +846,7 @@
}") }")
;; ??? Should have a bset case here also. ;; ??? Should have a bset case here also.
;; ??? This should be symmetric with andhi3.
(define_insn "iorhi3" (define_insn "iorhi3"
[(set (match_operand:HI 0 "general_operand" "=r,r") [(set (match_operand:HI 0 "general_operand" "=r,r")
...@@ -960,6 +937,8 @@ ...@@ -960,6 +937,8 @@
DONE; DONE;
}") }")
;; ??? This should be symmetric with andhi3.
(define_insn "xorhi3" (define_insn "xorhi3"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(xor:HI (match_operand:HI 1 "general_operand" "%0") (xor:HI (match_operand:HI 1 "general_operand" "%0")
...@@ -988,8 +967,8 @@ ...@@ -988,8 +967,8 @@
xor %S2,%S0" xor %S2,%S0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "4,6") (set_attr "length" "4,6")
(set_attr "cc" "clobber")]) (set_attr "cc" "set")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS ;; NEGATION INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -1001,7 +980,7 @@ ...@@ -1001,7 +980,7 @@
"neg %X0" "neg %X0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (set_attr "length" "2")
(set_attr "cc" "clobber")]) (set_attr "cc" "set_zn_c0")])
(define_expand "neghi2" (define_expand "neghi2"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
...@@ -1032,7 +1011,7 @@ ...@@ -1032,7 +1011,7 @@
"neg %T0" "neg %T0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (set_attr "length" "2")
(set_attr "cc" "clobber")]) (set_attr "cc" "set_zn_c0")])
(define_expand "negsi2" (define_expand "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
...@@ -1063,7 +1042,7 @@ ...@@ -1063,7 +1042,7 @@
"neg %S0" "neg %S0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "2") (set_attr "length" "2")
(set_attr "cc" "clobber")]) (set_attr "cc" "set_zn_c0")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS ;; NOT INSTRUCTIONS
...@@ -1108,7 +1087,7 @@ ...@@ -1108,7 +1087,7 @@
;; ??? length is wrong for 300h ;; ??? length is wrong for 300h
(set_attr "length" "8") (set_attr "length" "8")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS ;; JUMP INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -1214,6 +1193,11 @@ ...@@ -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) if (get_attr_length (insn) == 2)
return \"b%j1 %l0\"; return \"b%j1 %l0\";
else if (get_attr_length (insn) == 4) else if (get_attr_length (insn) == 4)
...@@ -1234,6 +1218,11 @@ ...@@ -1234,6 +1218,11 @@
;; ??? We don't take advantage of 16 bit relative jumps in the 300h. ;; ??? 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) if (get_attr_length (insn) == 2)
return \"b%k1 %l0\"; return \"b%k1 %l0\";
else if (get_attr_length (insn) == 4) else if (get_attr_length (insn) == 4)
...@@ -1290,14 +1279,6 @@ ...@@ -1290,14 +1279,6 @@
;; This is a define expand, because pointers may be either 16 or 32 bits. ;; 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" (define_expand "indirect_jump"
[(set (pc) (match_operand 0 "jump_address_operand" "Vr"))] [(set (pc) (match_operand 0 "jump_address_operand" "Vr"))]
"" ""
...@@ -1358,7 +1339,7 @@ ...@@ -1358,7 +1339,7 @@
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "cc" "none") (set_attr "cc" "none")
(set_attr "length" "2")]) (set_attr "length" "2")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; EXTEND INSTRUCTIONS ;; EXTEND INSTRUCTIONS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -1481,7 +1462,7 @@ ...@@ -1481,7 +1462,7 @@
}" }"
[(set_attr "length" "10") [(set_attr "length" "10")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; SHIFTS ;; SHIFTS
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
...@@ -1626,12 +1607,12 @@ ...@@ -1626,12 +1607,12 @@
;; However, for cases that loop or are done in pieces, cc does not contain ;; 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. ;; what we want. Emit_a_shift is free to tweak cc_status as desired.
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
;; ----------------------------------------------------------------- ;; -----------------------------------------------------------------
;; BIT FIELDS ;; BIT FIELDS
;; ----------------------------------------------------------------- ;; -----------------------------------------------------------------
;; The H8/300 has given 1/8th of its opcode space to bitfield ;; 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. ;; BCC and BCS patterns.
...@@ -1912,7 +1893,7 @@ ...@@ -1912,7 +1893,7 @@
operands[1] = mem; operands[1] = mem;
} }
}") }")
;; ----------------------------------------------------------------- ;; -----------------------------------------------------------------
;; STACK POINTER MANIPULATIONS ;; STACK POINTER MANIPULATIONS
;; ----------------------------------------------------------------- ;; -----------------------------------------------------------------
...@@ -1931,7 +1912,7 @@ ...@@ -1931,7 +1912,7 @@
"mov.w %T1,%T0\;add.w %T2,%T0" "mov.w %T1,%T0\;add.w %T2,%T0"
[(set_attr "type" "arith") [(set_attr "type" "arith")
(set_attr "length" "6") (set_attr "length" "6")
(set_attr "cc" "set")]) (set_attr "cc" "set_zn_c0")])
;; ------------------------------------------- ;; -------------------------------------------
...@@ -1981,7 +1962,7 @@ ...@@ -1981,7 +1962,7 @@
DONE; DONE;
}") }")
;; ---------------------------------------------- ;; ----------------------------------------------
;; Peepholes go at the end. ;; Peepholes go at the end.
;; ---------------------------------------------- ;; ----------------------------------------------
...@@ -2086,7 +2067,6 @@ ...@@ -2086,7 +2067,6 @@
"" ""
"mov.b %X2,%X0\;bset %X1,%X0") "mov.b %X2,%X0\;bset %X1,%X0")
(define_insn "fancybclr4" (define_insn "fancybclr4"
[(set (match_operand:QI 0 "general_operand" "=Ur,Ur") [(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
(and:QI (and:QI
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment