From e62197363e27c2ee4aca61c467185851acc7e776 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 30 Apr 1996 14:56:24 -0600 Subject: [PATCH] h8300.c (one_insn_adds_subs_operand): New function. * h8300/h8300.c (one_insn_adds_subs_operand): New function. (h8300_adjust_insn_length): New function. * h8300/h8300.h (ADJUST_INSN_LENGTH): Define. * h8300/h8300.md: Remove obsolete comments. (move patterns): Tweak constraints. (tst patterns): Use "register_operand" for predicate. (adds pattern): Use one_insn_adds_subs_operand to get length computation correct. (subs pattern): Similarly. (movstrhi): Remove unused expander. (fancy*, pxor, and-not patterns): Remove. No longer needed. From-SVN: r11907 --- gcc/config/h8300/h8300.c | 91 ++++++++++++++++ gcc/config/h8300/h8300.h | 3 + gcc/config/h8300/h8300.md | 258 ++++++---------------------------------------- 3 files changed, 126 insertions(+), 226 deletions(-) diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 0bca23f..87e45e4 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -454,6 +454,24 @@ adds_subs_operand (op, mode) return 0; } +/* Return nonzero if op is an adds/subs operand which only requires + one insn to implement. It is assumed that OP is already an adds/subs + operand. */ +int +one_insn_adds_subs_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + int val = INTVAL (op); + + if (val == 1 || val == -1 + || val == 2 || val == -2 + || (TARGET_H8300H + && (val == 4 || val == -4))) + return 1; + return 0; +} + char * output_adds_subs (operands) rtx *operands; @@ -2253,3 +2271,76 @@ output_simode_bld (bild, log2, operands) /* All done. */ return ""; } + +/* Given INSN and it's current length LENGTH, return the adjustment + (in bytes) to correctly compute INSN's length. + + We use this to get the lengths of various memory references correct. */ + +h8300_adjust_insn_length (insn, length) + rtx insn; + int length; +{ + rtx pat = PATTERN (insn); + + /* Adjust length for reg->mem and mem->reg copies. */ + if (GET_CODE (pat) == SET + && (GET_CODE (SET_SRC (pat)) == MEM + || GET_CODE (SET_DEST (pat)) == MEM)) + { + /* This insn might need a length adjustment. */ + rtx addr; + + if (GET_CODE (SET_SRC (pat)) == MEM) + addr = XEXP (SET_SRC (pat), 0); + else + addr = XEXP (SET_DEST (pat), 0); + + /* On the H8/300, only one adjustment is necessary; if the + address mode is register indirect, then this insn is two + bytes shorter than indicated in the machine description. */ + if (TARGET_H8300 && GET_CODE (addr) == REG) + return -2; + + /* On the H8/300H, register indirect is 6 bytes shorter than + indicated in the machine description. */ + if (TARGET_H8300H && GET_CODE (addr) == REG) + return -6; + + /* On the H8/300H, reg + d, for small displacements is 4 bytes + shorter than indicated in the machine description. */ + if (TARGET_H8300H + && GET_CODE (addr) == PLUS + && GET_CODE (XEXP (addr, 0)) == REG + && GET_CODE (XEXP (addr, 1)) == CONST_INT + && INTVAL (XEXP (addr, 1)) > -32768 + && INTVAL (XEXP (addr, 1)) < 32767) + return -4; + } + + /* Loading some constants needs adjustment. */ + if (GET_CODE (pat) == SET + && GET_CODE (SET_SRC (pat)) == CONST_INT + && GET_MODE (SET_DEST (pat)) == SImode + && INTVAL (SET_SRC (pat)) != 0) + { + if (TARGET_H8300 + && ((INTVAL (SET_SRC (pat)) & 0xffff) == 0 + || ((INTVAL (SET_SRC (pat)) >> 16) & 0xffff) == 0)) + return -2; + + if (TARGET_H8300H) + { + int val = INTVAL (SET_SRC (pat)); + + if (val == (val & 0xff) + || val == (val & 0xff00)) + return -6; + + if (val == -4 || val == -2 || val == -1) + return -6; + } + } + + return 0; +} diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index aa87769..0b6667e 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -929,6 +929,9 @@ extern int h8300_valid_machine_decl_attribute (); #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \ h8300_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS) +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ + LENGTH += h8300_adjust_insn_length (INSN, LENGTH); + /* Compute the cost of computing a constant rtl expression RTX whose rtx-code is CODE. The body of this macro is a portion of a switch statement. If the code is computed here, diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index e7049dd..f490310 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -29,27 +29,10 @@ (define_attr "cpu" "h8300,h8300h" (const (symbol_ref "cpu_type"))) -;; ??? If we can remove the operand type on all the insns, do it. -;; ??? Otherwise, try to have the operand type on all the insns. -;; ??? Many patterns have overly conservative lengths. In particular: -;; -;; * movXX insns using register indirect addressing. -;; * insns referencing the 8-bit area with an 8-bit address. - -;; Loading some 32bit integer constants could be done more -;; efficiently. For example loading the value 4 as a 32bit -;; is normally done via mov.l #4,erX. sub.l erX,erX, inc.l #4,erX -;; would be more efficient time and space-wise. Similar sequences -;; can be found using bit-set insns dec, etc - ;; Many logical operations should have "bit" variants if only one ;; bit is going to be operated on. ;; Should be HI & SImode tstXX insns which test one bit using btst. -;; -;; Some insns allow general operations, but lengths don't take -;; into account that a general operand may be a memory reference -;; with a long length. (EXTEND insns) ;; On the h8300h, adds/subs operate on the 32bit "er" registers. Right ;; now GCC doesn't expose the "e" half to the compiler, so using add/subs @@ -203,7 +186,7 @@ (define_insn "movhi_internal" [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,o") - (match_operand:HI 1 "general_operand_src" "I,r>,r,ion,r"))] + (match_operand:HI 1 "general_operand_src" "I,r>,r,io,r"))] "register_operand (operands[0],HImode) || register_operand (operands[1], HImode)" "@ @@ -293,7 +276,7 @@ (define_insn "movsi_h8300" [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))] + (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))] "TARGET_H8300 && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" @@ -358,7 +341,7 @@ (define_insn "movsf_h8300" [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))] + (match_operand:SF 1 "general_operand_src" "I,r,io,r,r,>"))] "TARGET_H8300 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" @@ -417,7 +400,7 @@ (define_insn "movsi_h8300h" [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))] + (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))] "TARGET_H8300H && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" @@ -458,7 +441,7 @@ (define_insn "movsf_h8300h" [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))] + (match_operand:SF 1 "general_operand_src" "I,r,io,r,r,>"))] "TARGET_H8300H && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" @@ -485,21 +468,21 @@ (set_attr "cc" "set_zn_c0")]) (define_insn "tstqi" - [(set (cc0) (match_operand:QI 0 "general_operand" "r"))] + [(set (cc0) (match_operand:QI 0 "register_operand" "r"))] "" "mov.b %X0,%X0" [(set_attr "length" "2") (set_attr "cc" "set")]) (define_insn "tsthi" - [(set (cc0) (match_operand:HI 0 "general_operand" "r"))] + [(set (cc0) (match_operand:HI 0 "register_operand" "r"))] "" "mov.w %T0,%T0" [(set_attr "length" "2") (set_attr "cc" "set")]) (define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "general_operand" "r"))] + [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] "TARGET_H8300H" "mov.l %S0,%S0" [(set_attr "length" "2") @@ -582,8 +565,12 @@ (match_operand:HI 2 "adds_subs_operand" "i")))] "" "* return output_adds_subs (operands);" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) + [(set_attr "cc" "none_0hit") + (set (attr "length") + (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") + (const_int 0)) + (const_int 2) + (const_int 4)))]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=&r,r,&r") @@ -623,8 +610,12 @@ (match_operand:SI 2 "adds_subs_operand" "i")))] "TARGET_H8300H" "* return output_adds_subs (operands);" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) + [(set_attr "cc" "none_0hit") + (set (attr "length") + (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") + (const_int 0)) + (const_int 2) + (const_int 4)))]) (define_insn "addsi_h8300" [(set (match_operand:SI 0 "register_operand" "=r,r,&r") @@ -684,8 +675,12 @@ operands[2] = GEN_INT (-INTVAL (operands[2])); return output_adds_subs (operands); }" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) + [(set_attr "cc" "none_0hit") + (set (attr "length") + (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") + (const_int 0)) + (const_int 2) + (const_int 4)))]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r,&r") @@ -738,8 +733,12 @@ operands[2] = GEN_INT (-INTVAL (operands[2])); return output_adds_subs (operands); }" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) + [(set_attr "cc" "none_0hit") + (set (attr "length") + (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") + (const_int 0)) + (const_int 2) + (const_int 4)))]) (define_insn "subsi3_h8300h" [(set (match_operand:SI 0 "register_operand" "=r,r") @@ -2280,54 +2279,6 @@ (set_attr "length" "6")]) -;; ------------------------------------------- -;; BLK moves -;; ------------------------------------------- - -(define_expand "movstrhi" - [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) - (mem:BLK (match_operand:BLK 1 "general_operand" ""))) - (use (match_operand:HI 2 "general_operand" "")) - (use (match_operand:HI 3 "immediate_operand" "")) - (clobber (match_dup 3)) - ])] - "" - " -{ - rtx src_ptr = copy_to_mode_reg (Pmode, XEXP(operands[1], 0)); - rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP(operands[0], 0)); - - int max = GET_CODE (operands[2]) == CONST_INT - ? MIN (INTVAL (operands[2]), INTVAL (operands[3])) : 1; - enum machine_mode mode = max >= 2 ? HImode : QImode; - rtx tmpreg = gen_reg_rtx (mode); - rtx increment = mode == QImode ? const1_rtx : const2_rtx; - rtx length = operands[2]; - rtx label = gen_label_rtx (); - rtx end_src_ptr = gen_reg_rtx (Pmode); - -/* emit_move_insn (length, gen_rtx(MINUS, HImode, length, increment));*/ - FAIL; - if (Pmode == HImode) - emit_insn (gen_addhi3 (end_src_ptr, src_ptr, length)); - else - emit_insn (gen_addsi3 (end_src_ptr, src_ptr, length)); - - emit_label (label); - emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr)); - emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg); - emit_insn (gen_rtx (SET, VOIDmode, src_ptr, - gen_rtx (PLUS, Pmode, src_ptr, increment))); - emit_insn (gen_rtx (SET, VOIDmode, dst_ptr, - gen_rtx (PLUS, Pmode, dst_ptr, increment))); - - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, - gen_rtx (COMPARE, Pmode, src_ptr, end_src_ptr))); - emit_jump_insn (gen_bne (label)); - - DONE; -}") - ;; ---------------------------------------------- ;; Peepholes go at the end. ;; ---------------------------------------------- @@ -2400,148 +2351,3 @@ [(set_attr "length" "2") (set_attr "cc" "set")]) -(define_insn "fancybset1" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI - (ashift:HI (const_int 1) - (subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0) - (match_dup 0)))] - "" - "bset %X1,%R0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "fancybset" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI - (ashift:HI (const_int 1) - (match_operand:HI 1 "nonmemory_operand" "ri") ) 0) - (match_operand:QI 2 "general_operand_src" "Ur>")))] - "" - "mov.b %R2,%R0\;bset %X1,%R0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "fancybclr4" - [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) - (match_operand:QI 1 "general_operand" "0,Ur"))) - (clobber (match_scratch:HI 3 "=X,&r"))] - "" - "@ - bclr %X2,%R0; l1 - mov.b %R1,%X3\;mov.b %3,%0\;bclr %X2,%R0; l3" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) - -(define_insn "fancybclr5" - [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) - (match_operand:QI 1 "general_operand" "0,Ur"))) - (clobber (match_scratch:HI 3 "=X,&r"))] - "" - "@ - bclr %X2,%R0; l1 - mov.b %R1,%X3\;mov.b %3,%0\;bclr %X2,%R0;l2" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) - -(define_insn "fancybclr2" - [(set (match_operand:QI 0 "general_operand" "=U,r") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) - (match_operand:QI 1 "general_operand" "0,0")))] - "" - "bclr %X2,%R0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "fancybclr3" - [(set (match_operand:QI 0 "general_operand" "=U,r") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) - (match_operand:QI 1 "general_operand" "0,0")))] - "" - "bclr %X2,%R0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "fancybsetp3" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r")) 0) - (match_operand:QI 2 "bit_operand" "0")))] - "" - "bset %X1,%R0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "fancybsetp2" - [(set (match_operand:QI 0 "general_operand" "=r,U") - (ior:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r,r")) 0) - (match_operand:QI 2 "general_operand_src" "U,r>")))] - "" - "mov.b %R2,%R0\;bset %X1,%R0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "fancybnot" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (xor:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r")) 0) - (match_operand:QI 2 "bit_operand" "0")))] - - "" - "bnot %X1,%R0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "pxor" - [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "=r,r") - (const_int 1) - (match_operand 1 "immediate_operand" "n,n")) - (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U")) - (const_int 1)))] - "" - "bld #0,%R2\;bist %1,%0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=r") - (and:QI (not:QI (match_operand:QI 1 "register_operand" "0")) - (match_operand:QI 2 "nonmemory_operand" "rJ")))] - "" - "not.b %X0\;and.b %X2,%X0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (and:HI (not:HI (match_operand:HI 1 "register_operand" "0")) - (match_operand:HI 2 "nonmemory_operand" "rJ")))] - "TARGET_H8300H" - "not.w %T0\;and.w %T2,%T0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "0")) - (match_operand:QI 2 "nonmemory_operand" "rJ")))] - "TARGET_H8300H" - "not.l %S0\;and.l %S2,%S0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -- 2.7.4