From 269c14e111ebc7745eda1a98585078ccd622fb82 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 11 Mar 1996 21:05:49 +0000 Subject: [PATCH] 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 --- gcc/config/h8300/h8300.c | 117 +++++++++++++++++--------- gcc/config/h8300/h8300.h | 28 ++++--- gcc/config/h8300/h8300.md | 168 +++++++++++++++++--------------------- 3 files changed, 171 insertions(+), 142 deletions(-) diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 5d2f2b422f9..cadff014961 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 f21957561ae..0babf4ac74a 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 6ad86168c9c..a68d54cf715 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 -- 2.30.2