Commit e6219736 by Jeff Law

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
parent 731a7b1f
......@@ -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;
}
......@@ -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,
......
......@@ -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")])
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