aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-04-30 14:56:24 -0600
committerJeff Law <law@gcc.gnu.org>1996-04-30 14:56:24 -0600
commite62197363e27c2ee4aca61c467185851acc7e776 (patch)
treed22fe2caba0f3339195ac4d7de79901bada97b4d /gcc
parent731a7b1f40a1a5c2a2128ab535e1395f92eee053 (diff)
downloadgcc-e62197363e27c2ee4aca61c467185851acc7e776.zip
gcc-e62197363e27c2ee4aca61c467185851acc7e776.tar.gz
gcc-e62197363e27c2ee4aca61c467185851acc7e776.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/h8300/h8300.c91
-rw-r--r--gcc/config/h8300/h8300.h3
-rw-r--r--gcc/config/h8300/h8300.md258
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")])
-