;; GCC machine description for Renesas H8/300
-;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 1992-2020 Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com),
;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GCC is distributed in the hope that it will be useful,
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
;; We compute exact length on each instruction for most of the time.
;; In some case, most notably bit operations that may involve memory
[(UNSPEC_INCDEC 0)
(UNSPEC_MONITOR 1)])
+(define_constants
+ [(UNSPEC_MOVMD 100)
+ (UNSPEC_STPCPY 101)])
+
(define_constants
[(R0_REG 0)
(SC_REG 3)
+ (COUNTER_REG 4)
+ (SOURCE_REG 5)
+ (DESTINATION_REG 6)
(HFP_REG 6)
(SP_REG 7)
(MAC_REG 8)
(define_attr "cpu" "h8300,h8300h"
(const (symbol_ref "cpu_type")))
-(define_attr "type" "branch,arith"
+(define_attr "type" "branch,arith,bitbranch,call"
(const_string "arith"))
+(define_attr "length_table" "none,add,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
+ (const_string "none"))
+
;; The size of instructions in bytes.
(define_attr "length" ""
(cond [(eq_attr "type" "branch")
+ ;; In a forward delayed branch, (pc) represents the end of the
+ ;; delay sequence, not the end of the branch itself.
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -126))
- (le (minus (match_dup 0) (pc))
- (const_int 126)))
+ (le (plus (minus (match_dup 0) (pc))
+ (symbol_ref "DELAY_SLOT_LENGTH (insn)"))
+ (const_int 125)))
(const_int 2)
(if_then_else (and (eq_attr "cpu" "h8300h")
(and (ge (minus (pc) (match_dup 0))
(le (minus (pc) (match_dup 0))
(const_int 32000))))
(const_int 4)
- (const_int 6)))]
+ (const_int 6)))
+ (eq_attr "type" "bitbranch")
+ (if_then_else (and (ge (minus (match_dup 0) (pc))
+ (const_int -126))
+ (le (minus (match_dup 0) (pc))
+ (const_int 126)))
+ (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
+ (const_int 2))
+ (if_then_else (and (eq_attr "cpu" "h8300h")
+ (and (ge (minus (pc) (match_dup 0))
+ (const_int -32000))
+ (le (minus (pc) (match_dup 0))
+ (const_int 32000))))
+ (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
+ (const_int 4))
+ (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
+ (const_int 6))))
+ (eq_attr "length_table" "!none")
+ (symbol_ref "h8300_insn_length_from_table (insn, operands)")]
(const_int 200)))
;; Condition code settings.
(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
(const_string "clobber"))
+;; Type of delay slot. NONE means the instruction has no delay slot.
+;; JUMP means it is an unconditional jump that (if short enough)
+;; could be implemented using bra/s.
+
+(define_attr "delay_slot" "none,jump"
+ (const_string "none"))
+
+;; "yes" if the instruction can be put into a delay slot. It's not
+;; entirely clear that jsr is not valid in delay slots, but it
+;; definitely doesn't have the effect of causing the called function
+;; to return to the target of the delayed branch.
+
+(define_attr "can_delay" "no,yes"
+ (cond [(eq_attr "type" "branch,bitbranch,call")
+ (const_string "no")
+ (geu (symbol_ref "get_attr_length (insn)") (const_int 2))
+ (const_string "no")]
+ (const_string "yes")))
+
+;; Only allow jumps to have a delay slot if we think they might
+;; be short enough. This is just an optimization: we don't know
+;; for certain whether they will be or not.
+
+(define_delay (and (eq_attr "delay_slot" "jump")
+ (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
+ [(eq_attr "can_delay" "yes")
+ (nil)
+ (nil)])
+
;; Provide the maximum length of an assembly instruction in an asm
;; statement. The maximum length of 14 bytes is achieved on H8SX.
(define_asm_attributes
[(set (attr "length")
- (cond [(ne (symbol_ref "TARGET_H8300") (const_int 0)) (const_int 4)
- (ne (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 10)
- (ne (symbol_ref "TARGET_H8300S") (const_int 0)) (const_int 10)]
+ (cond [(match_test "TARGET_H8300") (const_int 4)
+ (match_test "TARGET_H8300H") (const_int 10)
+ (match_test "TARGET_H8300S") (const_int 10)]
(const_int 14)))])
+
+(include "predicates.md")
+(include "constraints.md")
\f
;; ----------------------------------------------------------------------
-;; MOVE INSTRUCTIONS
+;; MACRO DEFINITIONS
;; ----------------------------------------------------------------------
-;; movqi
+;; This mode iterator allows :P to be used for patterns that operate on
+;; pointer-sized quantities. Exactly one of the two alternatives will match.
-(define_insn "pushqi1_h8300"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -2)))
- (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1)))
- (match_operand:QI 0 "register_operand" "r"))])]
- "TARGET_H8300
- && operands[0] != stack_pointer_rtx"
- "mov.w\\t%T0,@-r7"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+(define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
-(define_insn "pushqi1_h8300hs"
- [(parallel [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int -4)))
- (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
- (match_operand:QI 0 "register_operand" "r"))])]
- "(TARGET_H8300H || TARGET_H8300S)
- && operands[0] != stack_pointer_rtx"
- "mov.l\\t%S0,@-er7"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
+(define_mode_iterator QHI [QI HI])
-(define_insn "pushqi1_h8300hs_normal"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -4)))
- (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
- (match_operand:QI 0 "register_operand" "r"))])]
- "(TARGET_H8300H || TARGET_H8300S)
- && operands[0] != stack_pointer_rtx"
- "mov.l\\t%S0,@-er7"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
+(define_mode_iterator HSI [HI SI])
-(define_expand "pushqi1"
- [(match_operand:QI 0 "register_operand" "")]
- ""
- "
-{
- if (TARGET_H8300)
- emit_insn (gen_pushqi1_h8300 (operands[0]));
- else if (!TARGET_NORMAL_MODE)
- emit_insn (gen_pushqi1_h8300hs (operands[0]));
- else
- emit_insn (gen_pushqi1_h8300hs_normal (operands[0]));
- DONE;
-}")
+(define_mode_iterator QHSI [QI HI SI])
-(define_insn "*movqi_h8300"
- [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
- (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
- "TARGET_H8300
- && (register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode))"
- "@
- sub.b %X0,%X0
- mov.b %R1,%X0
- mov.b %X1,%R0
- mov.b %R1,%X0
- mov.b %R1,%X0
- mov.b %X1,%R0"
- [(set_attr "length" "2,2,2,2,4,4")
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+(define_mode_iterator QHSIF [QI HI SI SF])
+
+(define_code_iterator shifts [ashift ashiftrt lshiftrt])
+
+(define_code_iterator ors [ior xor])
+\f
+;; ----------------------------------------------------------------------
+;; MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
-(define_insn "*movqi_h8300hs"
+;; movqi
+
+(define_insn "*movqi_h8nosx"
[(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
- "(TARGET_H8300H || TARGET_H8300S)
- && (register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode))"
+ "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+ && h8300_move_ok (operands[0], operands[1])"
"@
sub.b %X0,%X0
mov.b %R1,%X0
mov.b %X1,%R0"
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
-(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand_dst" "")
- (match_operand:QI 1 "general_operand_src" ""))]
+(define_insn "*movqi_h8sx"
+ [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
+ (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
+ "TARGET_H8300SX"
+ "@
+ mov.b %X1:4,%X0
+ mov.b %X1,%X0"
+ [(set_attr "length_table" "mov_imm4,movb")
+ (set_attr "cc" "set_znv")])
+
+(define_expand "mov<mode>"
+ [(set (match_operand:QHSIF 0 "general_operand_dst" "")
+ (match_operand:QHSIF 1 "general_operand_src" ""))]
""
- "
-{
- /* One of the ops has to be in a register. */
- if (!register_operand (operand0, QImode)
- && !register_operand (operand1, QImode))
- {
- operands[1] = copy_to_mode_reg (QImode, operand1);
- }
-}")
+ {
+ enum machine_mode mode = <MODE>mode;
+ if (TARGET_H8300 && (mode == SImode || mode == SFmode))
+ {
+ /* The original H8/300 needs to split up 32 bit moves. */
+ if (h8300_expand_movsi (operands))
+ DONE;
+ }
+ else if (!TARGET_H8300SX)
+ {
+ /* Other H8 chips, except the H8/SX family can only handle a
+ single memory operand, which is checked by h8300_move_ok.
+
+ We could perhaps have h8300_move_ok handle the H8/SX better
+ and just remove the !TARGET_H8300SX conditional. */
+ if (!h8300_move_ok (operands[0], operands[1]))
+ operands[1] = copy_to_mode_reg (mode, operand1);
+ }
+ })
(define_insn "movstrictqi"
- [(set (strict_low_part
- (match_operand:QI 0 "register_operand" "+r,r,r,r,r"))
- (match_operand:QI 1 "general_operand_src" " I,r,n,>,m"))]
+ [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
+ (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
""
"@
sub.b %X0,%X0
- mov.b %X1,%X0
- mov.b %R1,%X0
- mov.b %X1,%X0
- mov.b %R1,%X0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
+ mov.b %X1,%X0"
+ [(set_attr "length" "2,*")
+ (set_attr "length_table" "*,movb")
+ (set_attr "cc" "set_zn,set_znv")])
;; movhi
-(define_expand "pushhi1_h8300"
- [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
- (match_operand:HI 0 "register_operand" ""))]
- "TARGET_H8300
- && operands[0] != stack_pointer_rtx"
- "")
-
-(define_insn "pushhi1_h8300hs"
- [(parallel [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int -4)))
- (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
- (match_operand:HI 0 "register_operand" "r"))])]
- "(TARGET_H8300H || TARGET_H8300S)
- && operands[0] != stack_pointer_rtx"
- "mov.l\\t%S0,@-er7"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
-
-(define_insn "pushhi1_h8300hs_normal"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -4)))
- (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
- (match_operand:HI 0 "register_operand" "r"))])]
- "(TARGET_H8300H || TARGET_H8300S)
- && operands[0] != stack_pointer_rtx"
- "mov.l\\t%S0,@-er7"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
-
-(define_expand "pushhi1"
- [(match_operand:HI 0 "register_operand" "")]
- ""
- "
-{
- if (TARGET_H8300)
- emit_insn (gen_pushhi1_h8300 (operands[0]));
- else if (!TARGET_NORMAL_MODE)
- emit_insn (gen_pushhi1_h8300hs (operands[0]));
- else
- emit_insn (gen_pushhi1_h8300hs_normal (operands[0]));
- DONE;
-}")
-
-(define_insn "*movhi_h8300"
+(define_insn "*movhi_h8nosx"
[(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
- "TARGET_H8300
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode))
- && !(GET_CODE (operands[0]) == MEM
- && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
- && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
- && GET_CODE (operands[1]) == REG
- && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
+ "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+ && h8300_move_ok (operands[0], operands[1])"
"@
sub.w %T0,%T0
mov.w %T1,%T0
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
-(define_insn "*movhi_h8300hs"
- [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
- (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
- "(TARGET_H8300H || TARGET_H8300S)
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode))"
+(define_insn "*movhi_h8sx"
+ [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
+ (match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
+ "TARGET_H8300SX"
"@
sub.w %T0,%T0
- mov.w %T1,%T0
- mov.w %T1,%T0
- mov.w %T1,%T0
+ mov.w %T1:3,%T0
+ mov.w %T1:4,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
-
-(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand_dst" "")
- (match_operand:HI 1 "general_operand_src" ""))]
- ""
- "
-{
- /* One of the ops has to be in a register. */
- if (!register_operand (operand1, HImode)
- && !register_operand (operand0, HImode))
- {
- operands[1] = copy_to_mode_reg (HImode, operand1);
- }
-}")
+ [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
+ (set_attr "length" "2,2,*,*,*")
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
(define_insn "movstricthi"
- [(set (strict_low_part
- (match_operand:HI 0 "register_operand" "+r,r,r,r,r"))
- (match_operand:HI 1 "general_operand_src" " I,r,i,>,m"))]
+ [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
+ (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
""
"@
sub.w %T0,%T0
mov.w %T1,%T0
- mov.w %T1,%T0
- mov.w %T1,%T0
mov.w %T1,%T0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
+ [(set_attr "length" "2,2,*")
+ (set_attr "length_table" "*,*,movw")
+ (set_attr "cc" "set_zn,set_znv,set_znv")])
;; movsi
-(define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand_dst" "")
- (match_operand:SI 1 "general_operand_src" ""))]
- ""
- "
-{
- if (TARGET_H8300)
- {
- if (h8300_expand_movsi (operands))
- DONE;
- }
- else
- {
- /* One of the ops has to be in a register. */
- if (!register_operand (operand1, SImode)
- && !register_operand (operand0, SImode))
- {
- operands[1] = copy_to_mode_reg (SImode, operand1);
- }
- }
-}")
-
-(define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand_dst" "")
- (match_operand:SF 1 "general_operand_src" ""))]
- ""
- "
-{
- if (TARGET_H8300)
- {
- if (h8300_expand_movsi (operands))
- DONE;
- }
- else
- {
- /* One of the ops has to be in a register. */
- if (!register_operand (operand1, SFmode)
- && !register_operand (operand0, SFmode))
- {
- operands[1] = copy_to_mode_reg (SFmode, operand1);
- }
- }
-}")
-
(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,io,r,r,>"))]
"TARGET_H8300
- && (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode))"
- "*
+ && h8300_move_ok (operands[0], operands[1])"
{
unsigned int rn = -1;
switch (which_alternative)
{
case 0:
- return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
+ return "sub.w %e0,%e0\;sub.w %f0,%f0";
case 1:
if (REGNO (operands[0]) < REGNO (operands[1]))
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
else
- return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
+ return "mov.w %f1,%f0\;mov.w %e1,%e0";
case 2:
/* Make sure we don't trample the register we index with. */
if (GET_CODE (operands[1]) == MEM)
if (rn == REGNO (operands[0]))
{
/* Move the second word first. */
- return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
+ return "mov.w %f1,%f0\;mov.w %e1,%e0";
}
else
{
/* If either half is zero, use sub.w to clear that
half. */
if ((INTVAL (operands[1]) & 0xffff) == 0)
- return \"mov.w %e1,%e0\;sub.w %f0,%f0\";
+ return "mov.w %e1,%e0\;sub.w %f0,%f0";
if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
- return \"sub.w %e0,%e0\;mov.w %f1,%f0\";
+ return "sub.w %e0,%e0\;mov.w %f1,%f0";
/* If the upper half and the lower half are the same,
copy one half to the other. */
if ((INTVAL (operands[1]) & 0xffff)
== ((INTVAL (operands[1]) >> 16) & 0xffff))
- return \"mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0\";
- }
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
- }
- case 3:
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
- case 4:
- return \"mov.w %f1,%T0\;mov.w %e1,%T0\";
- case 5:
- return \"mov.w %T1,%e0\;mov.w %T1,%f0\";
- default:
- abort ();
- }
-}"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "clobber")])
-
-(define_insn "*movsf_h8300"
- [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
- (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
- "TARGET_H8300
- && (register_operand (operands[0], SFmode)
- || register_operand (operands[1], SFmode))"
- "*
-{
- /* Copy of the movsi stuff. */
- unsigned int rn = -1;
- switch (which_alternative)
- {
- case 0:
- return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
- case 1:
- if (REGNO (operands[0]) < REGNO (operands[1]))
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
- else
- return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
- case 2:
- /* Make sure we don't trample the register we index with. */
- if (GET_CODE (operands[1]) == MEM)
- {
- rtx inside = XEXP (operands[1], 0);
- if (REG_P (inside))
- {
- rn = REGNO (inside);
- }
- else if (GET_CODE (inside) == PLUS)
- {
- rtx lhs = XEXP (inside, 0);
- rtx rhs = XEXP (inside, 1);
- if (REG_P (lhs)) rn = REGNO (lhs);
- if (REG_P (rhs)) rn = REGNO (rhs);
+ return "mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0";
}
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
}
- if (rn == REGNO (operands[0]))
- /* Move the second word first. */
- return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
- else
- /* Move the first word first. */
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
-
case 3:
- return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
case 4:
- return \"mov.w %f1,%T0\;mov.w %e1,%T0\";
+ return "mov.w %f1,%T0\;mov.w %e1,%T0";
case 5:
- return \"mov.w %T1,%e0\;mov.w %T1,%f0\";
+ return "mov.w %T1,%e0\;mov.w %T1,%f0";
default:
- abort ();
+ gcc_unreachable ();
}
-}"
+}
[(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "clobber")])
+ (symbol_ref "compute_mov_length (operands)"))])
(define_insn "*movsi_h8300hs"
[(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
(match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
- "(TARGET_H8300S || TARGET_H8300H)
- && (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode))
- && !(GET_CODE (operands[0]) == MEM
- && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
- && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
- && GET_CODE (operands[1]) == REG
- && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
- "*
+ "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
+ && h8300_move_ok (operands[0], operands[1])"
{
switch (which_alternative)
{
case 0:
- return \"sub.l %S0,%S0\";
+ return "sub.l %S0,%S0";
case 7:
- return \"clrmac\";
+ return "clrmac";
case 8:
- return \"clrmac\;ldmac %1,macl\";
+ return "clrmac\;ldmac %1,macl";
case 9:
- return \"stmac macl,%0\";
+ return "stmac macl,%0";
default:
if (GET_CODE (operands[1]) == CONST_INT)
{
if (val == (val & 0xff))
{
operands[1] = GEN_INT ((char) val & 0xff);
- return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\";
+ return "sub.l\\t%S0,%S0\;add.b\\t%1,%w0";
}
if (val == (val & 0xff00))
{
operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
- return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
+ return "sub.l\\t%S0,%S0\;add.b\\t%1,%x0";
}
/* Look for constants that can be obtained by subs, inc, and
switch (val & 0xffffffff)
{
case 0xffffffff:
- return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
+ return "sub.l\\t%S0,%S0\;subs\\t#1,%S0";
case 0xfffffffe:
- return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
+ return "sub.l\\t%S0,%S0\;subs\\t#2,%S0";
case 0xfffffffc:
- return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
+ return "sub.l\\t%S0,%S0\;subs\\t#4,%S0";
case 0x0000ffff:
- return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
+ return "sub.l\\t%S0,%S0\;dec.w\\t#1,%f0";
case 0x0000fffe:
- return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
+ return "sub.l\\t%S0,%S0\;dec.w\\t#2,%f0";
case 0xffff0000:
- return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
+ return "sub.l\\t%S0,%S0\;dec.w\\t#1,%e0";
case 0xfffe0000:
- return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
+ return "sub.l\\t%S0,%S0\;dec.w\\t#2,%e0";
case 0x00010000:
- return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
+ return "sub.l\\t%S0,%S0\;inc.w\\t#1,%e0";
case 0x00020000:
- return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
+ return "sub.l\\t%S0,%S0\;inc.w\\t#2,%e0";
}
}
}
- return \"mov.l %S1,%S0\";
-}"
+ return "mov.l %S1,%S0";
+}
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+(define_insn "*movsi_h8sx"
+ [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
+ (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
+ "TARGET_H8300SX"
+ "@
+ sub.l %S0,%S0
+ mov.l %S1:3,%S0
+ mov.l %S1,%S0
+ mov.l %S1,%S0
+ clrmac
+ clrmac\;ldmac %1,macl
+ stmac macl,%0"
+ [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
+ (set_attr "length" "2,2,*,*,2,6,4")
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+
+(define_insn "*movsf_h8sx"
+ [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
+ (match_operand:SF 1 "general_operand_src" "G,rQi"))]
+ "TARGET_H8300SX"
+ "@
+ sub.l %S0,%S0
+ mov.l %S1,%S0"
+ [(set_attr "length" "2,*")
+ (set_attr "length_table" "*,movl")
+ (set_attr "cc" "set_zn,set_znv")])
+
+;; Implement block copies using movmd. Defining cpymemsi allows the full
+;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
+;; See h8sx_emit_movmd for details.
+
+(define_expand "cpymemsi"
+ [(use (match_operand:BLK 0 "memory_operand" ""))
+ (use (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:SI 2 "" ""))
+ (use (match_operand:SI 3 "const_int_operand" ""))]
+ "TARGET_H8300SX && 0"
+ {
+ if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3])))
+ DONE;
+ else
+ FAIL;
+ })
+
+;; Expander for generating movmd insns. Operand 0 is the destination
+;; memory region, operand 1 is the source, operand 2 is the counter
+;; register and operand 3 is the chunk size (1, 2 or 4).
+
+(define_expand "movmd"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (unspec [(match_operand:HI 2 "register_operand" "")
+ (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))
+ (set (match_dup 2)
+ (const_int 0))])]
+ "TARGET_H8300SX && 0"
+ {
+ operands[4] = copy_rtx (XEXP (operands[0], 0));
+ operands[5] = copy_rtx (XEXP (operands[1], 0));
+ })
+
+;; This is a difficult instruction to reload since operand 0 must be the
+;; frame pointer. See h8300_reg_class_from_letter for an explanation.
+
+(define_insn "movmd_internal_<mode>"
+ [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
+ (mem:BLK (match_operand:P 4 "register_operand" "1,1")))
+ (unspec [(match_operand:HI 5 "register_operand" "2,2")
+ (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
+ (clobber (match_operand:P 0 "register_operand" "=d,??D"))
+ (clobber (match_operand:P 1 "register_operand" "=f,f"))
+ (set (match_operand:HI 2 "register_operand" "=c,c")
+ (const_int 0))]
+ "TARGET_H8300SX && 0"
+ "@
+ movmd%m6
+ #"
+ [(set_attr "length" "2,14")
+ (set_attr "can_delay" "no")
+ (set_attr "cc" "none,clobber")])
+
+;; Split the above instruction if the destination register isn't er6.
+;; We need a sequence like:
+;;
+;; mov.l er6,@-er7
+;; mov.l <dest>,er6
+;; movmd.sz
+;; mov.l er6,<dest>
+;; mov.l @er7+,er6
+;;
+;; where <dest> is the current destination register (operand 4).
+;; The fourth instruction will be deleted if <dest> dies here.
+
+(define_split
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (unspec [(match_operand:HI 2 "register_operand" "")
+ (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
+ (clobber (match_operand:P 4 "register_operand" ""))
+ (clobber (match_operand:P 5 "register_operand" ""))
+ (set (match_dup 2)
+ (const_int 0))]
+ "TARGET_H8300SX && reload_completed
+ && 0
+ && REGNO (operands[4]) != DESTINATION_REG"
+ [(const_int 0)]
+ {
+ rtx dest;
+
+ h8300_swap_into_er6 (XEXP (operands[0], 0));
+ dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
+ emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
+ h8300_swap_out_of_er6 (operands[4]);
+ DONE;
+ })
+
+;; Expand a call to stpcpy() using movsd. Operand 0 should point to
+;; the final character, but movsd leaves it pointing to the character
+;; after that.
+
+(define_expand "movstr"
+ [(use (match_operand 0 "register_operand" ""))
+ (use (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:BLK 2 "memory_operand" ""))]
+ "TARGET_H8300SX && 0"
+ {
+ operands[1] = replace_equiv_address
+ (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
+ operands[2] = replace_equiv_address
+ (operands[2], copy_to_mode_reg (Pmode, XEXP (operands[2], 0)));
+ emit_insn (gen_movsd (operands[1], operands[2], gen_reg_rtx (Pmode)));
+ emit_insn (gen_add3_insn (operands[0], XEXP (operands[1], 0), constm1_rtx));
+ DONE;
+ })
+
+;; Expander for generating a movsd instruction. Operand 0 is the
+;; destination string, operand 1 is the source string and operand 2
+;; is a scratch register.
+
+(define_expand "movsd"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")]
+ UNSPEC_STPCPY))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_operand 2 "register_operand" ""))])]
+ "TARGET_H8300SX && 0"
+ {
+ operands[3] = copy_rtx (XEXP (operands[0], 0));
+ operands[4] = copy_rtx (XEXP (operands[1], 0));
+ })
+
+;; See comments above memcpy_internal().
+
+(define_insn "stpcpy_internal_<mode>"
+ [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
+ (unspec:BLK [(mem:BLK (match_operand:P 4 "register_operand" "1,1"))]
+ UNSPEC_STPCPY))
+ (clobber (match_operand:P 0 "register_operand" "=d,??D"))
+ (clobber (match_operand:P 1 "register_operand" "=f,f"))
+ (clobber (match_operand:P 2 "register_operand" "=c,c"))]
+ "TARGET_H8300SX && 0"
+ "@
+ \n1:\tmovsd\t2f\;bra\t1b\n2:
+ #"
+ [(set_attr "length" "6,18")
+ (set_attr "cc" "none,clobber")])
+
+;; Split the above instruction if the destination isn't er6. This works
+;; in the same way as the movmd splitter.
+
+(define_split
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
+ (clobber (match_operand:P 2 "register_operand" ""))
+ (clobber (match_operand:P 3 "register_operand" ""))
+ (clobber (match_operand:P 4 "register_operand" ""))]
+ "TARGET_H8300SX && reload_completed
+ && 0
+ && REGNO (operands[2]) != DESTINATION_REG"
+ [(const_int 0)]
+ {
+ rtx dest;
+
+ h8300_swap_into_er6 (XEXP (operands[0], 0));
+ dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
+ emit_insn (gen_movsd (dest, operands[1], operands[4]));
+ h8300_swap_out_of_er6 (operands[2]);
+ DONE;
+ })
+
+(include "mova.md")
+
+(define_insn "*movsf_h8300"
+ [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
+ (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
+ "TARGET_H8300
+ && (register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))"
+{
+ /* Copy of the movsi stuff. */
+ unsigned int rn = -1;
+ switch (which_alternative)
+ {
+ case 0:
+ return "sub.w %e0,%e0\;sub.w %f0,%f0";
+ case 1:
+ if (REGNO (operands[0]) < REGNO (operands[1]))
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
+ else
+ return "mov.w %f1,%f0\;mov.w %e1,%e0";
+ case 2:
+ /* Make sure we don't trample the register we index with. */
+ if (GET_CODE (operands[1]) == MEM)
+ {
+ rtx inside = XEXP (operands[1], 0);
+ if (REG_P (inside))
+ {
+ rn = REGNO (inside);
+ }
+ else if (GET_CODE (inside) == PLUS)
+ {
+ rtx lhs = XEXP (inside, 0);
+ rtx rhs = XEXP (inside, 1);
+ if (REG_P (lhs)) rn = REGNO (lhs);
+ if (REG_P (rhs)) rn = REGNO (rhs);
+ }
+ }
+ if (rn == REGNO (operands[0]))
+ /* Move the second word first. */
+ return "mov.w %f1,%f0\;mov.w %e1,%e0";
+ else
+ /* Move the first word first. */
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
+
+ case 3:
+ return "mov.w %e1,%e0\;mov.w %f1,%f0";
+ case 4:
+ return "mov.w %f1,%T0\;mov.w %e1,%T0";
+ case 5:
+ return "mov.w %T1,%e0\;mov.w %T1,%f0";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set (attr "length")
+ (symbol_ref "compute_mov_length (operands)"))])
+
(define_insn "*movsf_h8300hs"
[(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
- "(TARGET_H8300H || TARGET_H8300S)
- && (register_operand (operands[0], SFmode)
- || register_operand (operands[1], SFmode))"
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+ && (register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))"
"@
sub.l %S0,%S0
mov.l %S1,%S0
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
\f
;; ----------------------------------------------------------------------
+;; PUSH INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*pushqi1_h8300"
+ [(set (mem:QI
+ (pre_modify:HI
+ (reg:HI SP_REG)
+ (plus:HI (reg:HI SP_REG) (const_int -2))))
+ (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
+ "TARGET_H8300"
+ "mov.w\\t%T0,@-r7"
+ [(set_attr "length" "2")])
+
+(define_insn "*push1_h8300hs_<QHI:mode>"
+ [(set (mem:QHI
+ (pre_modify:P
+ (reg:P SP_REG)
+ (plus:P (reg:P SP_REG) (const_int -4))))
+ (match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
+ "TARGET_H8300H || TARGET_H8300S"
+ "mov.l\\t%S0,@-er7"
+ [(set_attr "length" "4")])
+
+\f
+;; ----------------------------------------------------------------------
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_insn ""
- [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n,n")))]
+ [(set (cc0)
+ (compare (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n,n"))
+ (const_int 0)))]
"TARGET_H8300"
"btst %Z1,%Y0"
[(set_attr "length" "2,4")
(set_attr "cc" "set_zn,set_zn")])
-(define_insn ""
- [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))]
- "TARGET_H8300"
- "btst %Z1,%Y0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
(define_insn_and_split "*tst_extzv_1_n"
[(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n,n,n")))
+ (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n,n,n"))
+ (const_int 0)))
(clobber (match_scratch:QI 2 "=X,X,&r"))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"@
btst\\t%Z1,%Y0
btst\\t%Z1,%Y0
#"
"&& reload_completed
- && !EXTRA_CONSTRAINT (operands[0], 'U')"
+ && !satisfies_constraint_U (operands[0])"
[(set (match_dup 2)
(match_dup 0))
- (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 1)))
+ (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+ (const_int 1)
+ (match_dup 1))
+ (const_int 0)))
(clobber (scratch:QI))])]
""
[(set_attr "length" "2,8,10")
(set_attr "cc" "set_zn,set_zn,set_zn")])
(define_insn ""
- [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[1]) <= 15"
+ [(set (cc0)
+ (compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))]
+ "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S)
+ && INTVAL (operands[1]) <= 15"
"btst %Z1,%Y0"
[(set_attr "length" "2")
(set_attr "cc" "set_zn")])
(define_insn_and_split "*tstsi_upper_bit"
[(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))
(clobber (match_scratch:SI 2 "=&r"))]
"(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[1]) >= 16"
+ && INTVAL (operands[1]) >= 16"
"#"
"&& reload_completed"
[(set (match_dup 2)
(lshiftrt:SI (match_dup 0)
(const_int 16))))
(set (cc0)
- (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 3)))]
- "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
+ (compare (zero_extract:SI (match_dup 2)
+ (const_int 1)
+ (match_dup 3))
+ (const_int 0)))]
+ {
+ operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
+ })
(define_insn "*tstsi_variable_bit"
[(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 7))))]
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 7)))
+ (const_int 0)))]
"TARGET_H8300H || TARGET_H8300S"
"btst %w1,%w0"
[(set_attr "length" "2")
(define_insn_and_split "*tstsi_variable_bit_qi"
[(set (cc0)
- (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
- (const_int 7))))
+ (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+ (const_int 1)
+ (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+ (const_int 7)))
+ (const_int 0)))
(clobber (match_scratch:QI 2 "=X,X,&r"))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"@
btst\\t%w1,%X0
btst\\t%w1,%X0
#"
"&& reload_completed
- && !EXTRA_CONSTRAINT (operands[0], 'U')"
+ && !satisfies_constraint_U (operands[0])"
[(set (match_dup 2)
(match_dup 0))
- (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
- (const_int 1)
- (and:SI (match_dup 1)
- (const_int 7))))
+ (parallel [(set (cc0)
+ (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+ (const_int 1)
+ (and:SI (match_dup 1)
+ (const_int 7)))
+ (const_int 0)))
(clobber (scratch:QI))])]
""
[(set_attr "length" "2,8,10")
(set_attr "cc" "set_zn,set_zn,set_zn")])
-(define_insn "tstqi"
- [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
- ""
- "mov.b %X0,%X0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
-
-(define_insn "tsthi"
- [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
+(define_insn "*tst<mode>"
+ [(set (cc0)
+ (compare (match_operand:QHI 0 "register_operand" "r")
+ (const_int 0)))]
""
- "mov.w %T0,%T0"
+ {
+ if (<MODE>mode == QImode)
+ return "mov.b %X0,%X0";
+ else if (<MODE>mode == HImode)
+ return "mov.w %T0,%T0";
+ gcc_unreachable ();
+ }
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
(define_insn "*tsthi_upper"
[(set (cc0)
- (and:HI (match_operand:HI 0 "register_operand" "r")
- (const_int -256)))]
+ (compare (and:HI (match_operand:HI 0 "register_operand" "r")
+ (const_int -256))
+ (const_int 0)))]
""
"mov.b %t0,%t0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_insn "tstsi"
- [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+(define_insn "*tstsi"
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "r")
+ (const_int 0)))]
"TARGET_H8300H || TARGET_H8300S"
"mov.l %S0,%S0"
[(set_attr "length" "2")
(define_insn "*tstsi_upper"
[(set (cc0)
- (and:SI (match_operand:SI 0 "register_operand" "r")
- (const_int -65536)))]
+ (compare (and:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int -65536))
+ (const_int 0)))]
""
"mov.w %e0,%e0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
[(set (cc0)
- (compare (match_operand:QI 0 "register_operand" "r")
- (match_operand:QI 1 "nonmemory_operand" "rn")))]
+ (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
+ (match_operand:QI 1 "h8300_src_operand" "rQi")))]
""
"cmp.b %X1,%X0"
- [(set_attr "length" "2")
+ [(set_attr "length_table" "add")
(set_attr "cc" "compare")])
-(define_expand "cmphi"
- [(set (cc0)
- (compare (match_operand:HI 0 "register_operand" "")
- (match_operand:HI 1 "nonmemory_operand" "")))]
- ""
- "
-{
- /* Force operand1 into a register if we're compiling
- for the H8/300. */
- if (GET_CODE (operands[1]) != REG && TARGET_H8300)
- operands[1] = force_reg (HImode, operands[1]);
-}")
-
-(define_insn "*cmphi_h8300"
+(define_insn "*cmphi_h8300_znvc"
[(set (cc0)
(compare (match_operand:HI 0 "register_operand" "r")
(match_operand:HI 1 "register_operand" "r")))]
[(set_attr "length" "2")
(set_attr "cc" "compare")])
-(define_insn "*cmphi_h8300hs"
+(define_insn "*cmphi_h8300hs_znvc"
[(set (cc0)
- (compare (match_operand:HI 0 "register_operand" "r,r")
- (match_operand:HI 1 "nonmemory_operand" "r,n")))]
+ (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
+ (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
"TARGET_H8300H || TARGET_H8300S"
- "cmp.w %T1,%T0"
- [(set_attr "length" "2,4")
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (!TARGET_H8300SX)
+ return "cmp.w %T1,%T0";
+ else
+ return "cmp.w %T1:3,%T0";
+ case 1:
+ return "cmp.w %T1,%T0";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "length_table" "short_immediate,add")
(set_attr "cc" "compare,compare")])
(define_insn "cmpsi"
[(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r,r")
- (match_operand:SI 1 "nonmemory_operand" "r,i")))]
+ (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
+ (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
"TARGET_H8300H || TARGET_H8300S"
- "cmp.l %S1,%S0"
- [(set_attr "length" "2,6")
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (!TARGET_H8300SX)
+ return "cmp.l %S1,%S0";
+ else
+ return "cmp.l %S1:3,%S0";
+ case 1:
+ return "cmp.l %S1,%S0";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "length" "2,*")
+ (set_attr "length_table" "*,add")
(set_attr "cc" "compare,compare")])
\f
;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "addqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (plus:QI (match_operand:QI 1 "register_operand" "%0")
- (match_operand:QI 2 "nonmemory_operand" "rn")))]
+(define_expand "add<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
+ "")
+
+(define_insn "*addqi3"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
+ (match_operand:QI 2 "h8300_src_operand" "rQi")))]
+ "h8300_operands_match_p (operands)"
"add.b %X2,%X0"
- [(set_attr "length" "2")
+ [(set_attr "length_table" "add")
(set_attr "cc" "set_zn")])
-(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_insn "*addhi3_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
+ (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
"TARGET_H8300"
"@
adds %2,%T0
[(set (match_operand:HI 0 "stack_pointer_operand" "")
(plus:HI (match_dup 0)
(match_operand 1 "const_int_gt_2_operand" "")))]
- "TARGET_H8300 && flow2_completed"
+ "TARGET_H8300 && epilogue_completed"
[(const_int 0)]
- "split_adds_subs (HImode, operands); DONE;")
+ {
+ split_adds_subs (HImode, operands);
+ DONE;
+ })
(define_peephole2
[(match_scratch:HI 2 "r")
(define_insn "*addhi3_h8300hs"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
- "TARGET_H8300H || TARGET_H8300S"
+ (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
"@
adds %2,%S0
subs %G2,%S0
[(set_attr "length" "2,2,2,4,2")
(set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
-(define_insn "*addhi3_incdec"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
- (match_operand:HI 2 "incdec_operand" "M,O")]
- UNSPEC_INCDEC))]
+(define_insn "*add<mode>3_incdec"
+ [(set (match_operand:HSI 0 "register_operand" "=r,r")
+ (unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
+ (match_operand:HSI 2 "incdec_operand" "M,O")]
+ UNSPEC_INCDEC))]
"TARGET_H8300H || TARGET_H8300S"
- "@
- inc.w %2,%T0
- dec.w %G2,%T0"
+ {
+ if (which_alternative == 0)
+ return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
+ else if (which_alternative == 1)
+ return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
+ gcc_unreachable ();
+ }
[(set_attr "length" "2,2")
(set_attr "cc" "set_zn,set_zn")])
+(define_insn "*addhi3_h8sx"
+ [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
+ (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
+ (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
+ "TARGET_H8300SX && h8300_operands_match_p (operands)"
+ "@
+ add.w %T2:3,%T0
+ sub.w %G2:3,%T0
+ add.b %t2,%t0
+ add.w %T2,%T0"
+ [(set_attr "length_table" "short_immediate,short_immediate,*,add")
+ (set_attr "length" "*,*,2,*")
+ (set_attr "cc" "set_zn")])
+
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_dup 0)
(match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
""
[(const_int 0)]
- "split_adds_subs (HImode, operands); DONE;")
+ {
+ split_adds_subs (HImode, operands);
+ DONE;
+ })
-(define_expand "addsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "")
(define_insn "*addsi_h8300"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0")
- (match_operand:SI 2 "nonmemory_operand" "n,r")))]
+ (match_operand:SI 2 "h8300_src_operand" "n,r")))]
"TARGET_H8300"
- "* return output_plussi (operands);"
+{
+ return output_plussi (operands);
+}
[(set (attr "length")
(symbol_ref "compute_plussi_length (operands)"))
(set (attr "cc")
(symbol_ref "compute_plussi_cc (operands)"))])
(define_insn "*addsi_h8300hs"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
- (match_operand:SI 2 "nonmemory_operand" "i,r")))]
- "TARGET_H8300H || TARGET_H8300S"
- "* return output_plussi (operands);"
+ [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
+ (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
+ (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+{
+ return output_plussi (operands);
+}
[(set (attr "length")
(symbol_ref "compute_plussi_length (operands)"))
(set (attr "cc")
(symbol_ref "compute_plussi_cc (operands)"))])
-(define_insn "*addsi3_incdec"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "incdec_operand" "M,O")]
- UNSPEC_INCDEC))]
- "TARGET_H8300H || TARGET_H8300S"
- "@
- inc.l %2,%S0
- dec.l %G2,%S0"
- [(set_attr "length" "2,2")
- (set_attr "cc" "set_zn,set_zn")])
-
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
"TARGET_H8300H || TARGET_H8300S"
[(const_int 0)]
- "split_adds_subs (SImode, operands); DONE;")
+ {
+ split_adds_subs (SImode, operands);
+ DONE;
+ })
;; ----------------------------------------------------------------------
;; SUBTRACT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "subqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (minus:QI (match_operand:QI 1 "register_operand" "0")
- (match_operand:QI 2 "register_operand" "r")))]
+(define_expand "sub<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
- "sub.b %X2,%X0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
-(define_expand "subhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (minus:HI (match_operand:HI 1 "general_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
- ""
- "")
+ {
+ if (TARGET_H8300 && <MODE>mode == SImode)
+ operands[2] = force_reg (SImode, operands[2]);
+ })
+
+(define_insn "*subqi3"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
+ "h8300_operands_match_p (operands)"
+ "sub.b %X2,%X0"
+ [(set_attr "length_table" "add")
+ (set_attr "cc" "set_zn")])
(define_insn "*subhi3_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r")
- (minus:HI (match_operand:HI 1 "general_operand" "0,0")
- (match_operand:HI 2 "nonmemory_operand" "r,n")))]
+ (minus:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "h8300_src_operand" "r,n")))]
"TARGET_H8300"
"@
sub.w %T2,%T0
[(set_attr "length" "2,4")
(set_attr "cc" "set_zn,clobber")])
-(define_insn "*subhi3_h8300hs"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (minus:HI (match_operand:HI 1 "general_operand" "0,0")
- (match_operand:HI 2 "nonmemory_operand" "r,n")))]
- "TARGET_H8300H || TARGET_H8300S"
- "@
- sub.w %T2,%T0
- sub.w %T2,%T0"
- [(set_attr "length" "2,4")
- (set_attr "cc" "set_zn,set_zn")])
-
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "")
+(define_insn "*sub<mode>3_h8300hs"
+ [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
+ (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
+ (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+ {
+ if (<MODE>mode == HImode)
+ return "sub.w %T2,%T0";
+ else if (<MODE>mode == SImode)
+ return "sub.l %S2,%S0";
+ gcc_unreachable ();
+ }
+ [(set_attr "length_table" "add")
+ (set_attr "cc" "set_zn")])
(define_insn "*subsi3_h8300"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_H8300"
"sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "6")])
-(define_insn "*subsi3_h8300hs"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "general_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "r,i")))]
- "TARGET_H8300H || TARGET_H8300S"
- "@
- sub.l %S2,%S0
- sub.l %S2,%S0"
- [(set_attr "length" "2,6")
- (set_attr "cc" "set_zn,set_zn")])
\f
;; ----------------------------------------------------------------------
;; MULTIPLY INSTRUCTIONS
;; Note that the H8/300 can only handle umulqihi3.
-(define_insn "mulqihi3"
+(define_expand "mulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" ""))
+ ;; intentionally-mismatched modes
+ (match_operand:QI 2 "reg_or_nibble_operand" "")))]
+ "TARGET_H8300H || TARGET_H8300S"
+ {
+ if (GET_MODE (operands[2]) != VOIDmode)
+ operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
+ })
+
+(define_insn "*mulqihi3_const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+ (match_operand:QI 2 "nibble_operand" "IP4>X")))]
+ "TARGET_H8300SX"
+ "mulxs.b %X2,%T0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "*mulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
[(set_attr "length" "4")
(set_attr "cc" "set_zn")])
-(define_insn "mulhisi3"
+(define_expand "mulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
+ ;; intentionally-mismatched modes
+ (match_operand:HI 2 "reg_or_nibble_operand" "")))]
+ "TARGET_H8300H || TARGET_H8300S"
+ {
+ if (GET_MODE (operands[2]) != VOIDmode)
+ operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
+ })
+
+(define_insn "*mulhisi3_const"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (match_operand:SI 2 "nibble_operand" "IP4>X")))]
+ "TARGET_H8300SX"
+ "mulxs.w %T2,%S0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "*mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
[(set_attr "length" "4")
(set_attr "cc" "set_zn")])
-(define_insn "umulqihi3"
+(define_expand "umulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" ""))
+ ;; intentionally-mismatched modes
+ (match_operand:QI 2 "reg_or_nibble_operand" "")))]
+ "TARGET_H8300H || TARGET_H8300S"
+ {
+ if (GET_MODE (operands[2]) != VOIDmode)
+ operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]);
+ })
+
+(define_insn "*umulqihi3_const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+ (match_operand:QI 2 "nibble_operand" "IP4>X")))]
+ "TARGET_H8300SX"
+ "mulxu.b %X2,%T0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "*umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
""
- "mulxu %X2,%T0"
+ "mulxu.b %X2,%T0"
[(set_attr "length" "2")
(set_attr "cc" "none_0hit")])
-(define_insn "umulhisi3"
+(define_expand "umulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
+ ;; intentionally-mismatched modes
+ (match_operand:HI 2 "reg_or_nibble_operand" "")))]
+ "TARGET_H8300H || TARGET_H8300S"
+ {
+ if (GET_MODE (operands[2]) != VOIDmode)
+ operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]);
+ })
+
+(define_insn "*umulhisi3_const"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (match_operand:SI 2 "nibble_operand" "IP4>X")))]
+ "TARGET_H8300SX"
+ "mulxu.w %T2,%S0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "*umulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
[(set_attr "length" "2")
(set_attr "cc" "none_0hit")])
+;; We could have used mulu.[wl] here, but mulu.[lw] is only available
+;; on a H8SX with a multiplier, whereas muls.w seems to be available
+;; on all H8SX variants.
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
+ "TARGET_H8300SX"
+ { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "smulsi3_highpart"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+ (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (const_int 32))))]
+ "TARGET_H8300SXMUL"
+ "muls/u.l\\t%S2,%S0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "umulsi3_highpart"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (ashiftrt:DI
+ (mult:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+ (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (const_int 32))))]
+ "TARGET_H8300SX"
+ "mulu/u.l\\t%S2,%S0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none_0hit")])
+
;; This is a "bridge" instruction. Combine can't cram enough insns
;; together to crate a MAC instruction directly, but it can create
;; this instruction, which then allows combine to create the real
;;
;; Unfortunately, if combine doesn't create a MAC instruction, this
;; insn must generate reasonably correct code. Egad.
+
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=a")
(mult:SI
;; DIVIDE/MOD INSTRUCTIONS
;; ----------------------------------------------------------------------
+(define_insn "udiv<mode>3"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (udiv:HSI (match_operand:HSI 1 "register_operand" "0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
+ "TARGET_H8300SX"
+ { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
+ [(set_attr "length" "2")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (div:HSI (match_operand:HSI 1 "register_operand" "0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
+ "TARGET_H8300SX"
+ { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
+ [(set_attr "length" "2")])
+
(define_insn "udivmodqi4"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(match_dup 1)
(zero_extend:HI (match_dup 2)))))]
""
- "*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"divxu.b\\t%X2,%T0\";
+ return "divxu.b\\t%X2,%T0";
else
- return \"divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
-}"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
+ return "divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
+}
+ [(set_attr "length" "4")])
(define_insn "divmodqi4"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_dup 1)
(sign_extend:HI (match_dup 2)))))]
"TARGET_H8300H || TARGET_H8300S"
- "*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"divxs.b\\t%X2,%T0\";
+ return "divxs.b\\t%X2,%T0";
else
- return \"divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ return "divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
+}
+ [(set_attr "length" "6")])
(define_insn "udivmodhi4"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_dup 1)
(zero_extend:SI (match_dup 2)))))]
"TARGET_H8300H || TARGET_H8300S"
- "*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"divxu.w\\t%T2,%S0\";
+ return "divxu.w\\t%T2,%S0";
else
- return \"divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
-}"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
+ return "divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
+}
+ [(set_attr "length" "4")])
(define_insn "divmodhi4"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_dup 1)
(sign_extend:SI (match_dup 2)))))]
"TARGET_H8300H || TARGET_H8300S"
- "*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"divxs.w\\t%T2,%S0\";
+ return "divxs.w\\t%T2,%S0";
else
- return \"divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ return "divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
+}
+ [(set_attr "length" "6")])
\f
;; ----------------------------------------------------------------------
;; AND INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "*andqi3_1"
- [(set (match_operand:QI 0 "bit_operand" "=r,U")
+(define_insn "bclrqi_msx"
+ [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
+ (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:QI 2 "single_zero_operand" "Y0")))]
+ "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
+ "bclr\\t%W2,%0"
+ [(set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:HI 0 "bit_register_indirect_operand")
+ (and:HI (match_operand:HI 1 "bit_register_indirect_operand")
+ (match_operand:HI 2 "single_zero_operand")))]
+ "TARGET_H8300SX"
+ [(set (match_dup 0)
+ (and:QI (match_dup 1)
+ (match_dup 2)))]
+ {
+ if (abs (INTVAL (operands[2])) > 0xFF)
+ {
+ operands[0] = adjust_address (operands[0], QImode, 0);
+ operands[1] = adjust_address (operands[1], QImode, 0);
+ operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
+ }
+ else
+ {
+ operands[0] = adjust_address (operands[0], QImode, 1);
+ operands[1] = adjust_address (operands[1], QImode, 1);
+ }
+ })
+
+(define_insn "bclrhi_msx"
+ [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+ (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:HI 2 "single_zero_operand" "Y0")))]
+ "TARGET_H8300SX"
+ "bclr\\t%W2,%0"
+ [(set_attr "length" "8")])
+
+(define_insn "*andqi3_2"
+ [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
+ (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
+ (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
+ "TARGET_H8300SX"
+ "@
+ bclr\\t %W2,%R0
+ and %X2,%X0
+ bfld %2,%1,%R0"
+ [(set_attr "length" "8,*,8")
+ (set_attr "length_table" "*,logicb,*")
+ (set_attr "cc" "none_0hit,set_znv,none_0hit")])
+
+(define_insn "andqi3_1"
+ [(set (match_operand:QI 0 "bit_operand" "=U,r")
(and:QI (match_operand:QI 1 "bit_operand" "%0,0")
- (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
+ (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
"register_operand (operands[0], QImode)
|| single_zero_operand (operands[2], QImode)"
"@
- and %X2,%X0
- bclr %W2,%R0"
+ bclr %W2,%R0
+ and %X2,%X0"
[(set_attr "length" "2,8")
- (set_attr "cc" "set_znv,none_0hit")])
-
-(define_expand "andqi3"
- [(set (match_operand:QI 0 "bit_operand" "")
- (and:QI (match_operand:QI 1 "bit_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (fix_bit_operand (operands, 0, AND))
- DONE;
-}")
+ (set_attr "cc" "none_0hit,set_znv")])
-(define_expand "andhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (and:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
+(define_expand "and<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (and:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
-(define_insn "*andorqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
- (match_operand:QI 3 "single_one_operand" "n"))
- (match_operand:QI 1 "register_operand" "0")))]
- ""
- "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
-
-(define_insn "*andorhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
- (match_operand:HI 3 "single_one_operand" "n"))
- (match_operand:HI 1 "register_operand" "0")))]
- ""
- "*
-{
- operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
- if (INTVAL (operands[3]) > 128)
- {
- operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
- return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\";
- }
- return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
-
-(define_insn "*andorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "single_one_operand" "n"))
- (match_operand:SI 1 "register_operand" "0")))]
- "(INTVAL (operands[3]) & 0xffff) != 0"
- "*
-{
- operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
- if (INTVAL (operands[3]) > 128)
- {
- operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
- return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\";
- }
- return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+(define_insn "*andor<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "=r")
+ (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
+ (match_operand:QHSI 3 "single_one_operand" "n"))
+ (match_operand:QHSI 1 "register_operand" "0")))]
+ "(<MODE>mode == QImode
+ || <MODE>mode == HImode
+ || (<MODE>mode == SImode
+ && (INTVAL (operands[3]) & 0xffff) != 0))"
+ {
+ if (<MODE>mode == QImode)
+ return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
+
+ if (<MODE>mode == HImode)
+ {
+ operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+ if (INTVAL (operands[3]) > 128)
+ {
+ operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+ return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
+ }
+ return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
+ }
+
+ if (<MODE>mode == SImode)
+ {
+ operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+ if (INTVAL (operands[3]) > 128)
+ {
+ operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+ return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
+ }
+ return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
+ }
+
+ gcc_unreachable ();
+
+ }
+ [(set_attr "length" "6")])
(define_insn "*andorsi3_shift_8"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "register_operand" "0")))]
""
"or.b\\t%w2,%x0"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")])
-
-(define_expand "andsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (and:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "")
-
-;; ----------------------------------------------------------------------
-;; OR INSTRUCTIONS
-;; ----------------------------------------------------------------------
-
-(define_insn "*iorqi3_1"
- [(set (match_operand:QI 0 "bit_operand" "=r,U")
- (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
- (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
- "register_operand (operands[0], QImode)
- || single_one_operand (operands[2], QImode)"
- "@
- or\\t%X2,%X0
- bset\\t%V2,%R0"
- [(set_attr "length" "2,8")
- (set_attr "cc" "set_znv,none_0hit")])
-
-(define_expand "iorqi3"
- [(set (match_operand:QI 0 "bit_operand" "")
- (ior:QI (match_operand:QI 1 "bit_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (fix_bit_operand (operands, 1, IOR))
- DONE;
-}")
-
-(define_expand "iorhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (ior:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
- ""
- "")
-
-(define_expand "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ior:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "")
+ [(set_attr "length" "2")])
;; ----------------------------------------------------------------------
-;; XOR INSTRUCTIONS
+;; OR/XOR INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "*xorqi3_1"
- [(set (match_operand:QI 0 "bit_operand" "=r,U")
- (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
- (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
- "register_operand (operands[0], QImode)
+(define_insn "b<code>qi_msx"
+ [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
+ (ors:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:QI 2 "single_one_operand" "Y2")))]
+ "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
+ { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
+ [(set_attr "length" "8")])
+
+(define_insn "b<code>hi_msx"
+ [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+ (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:HI 2 "single_one_operand" "Y2")))]
+ "TARGET_H8300SX"
+ { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
+ [(set_attr "length" "8")])
+
+(define_insn "<code>qi3_1"
+ [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
+ (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
+ (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
+ "TARGET_H8300SX || register_operand (operands[0], QImode)
|| single_one_operand (operands[2], QImode)"
- "@
- xor\\t%X2,%X0
- bnot\\t%V2,%R0"
- [(set_attr "length" "2,8")
- (set_attr "cc" "set_znv,none_0hit")])
-
-(define_expand "xorqi3"
- [(set (match_operand:QI 0 "bit_operand" "")
- (xor:QI (match_operand:QI 1 "bit_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (fix_bit_operand (operands, 1, XOR))
- DONE;
-}")
-
-(define_expand "xorhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (xor:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "nonmemory_operand" "")))]
- ""
- "")
-
-(define_expand "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (xor:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ {
+ if (which_alternative == 0)
+ return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
+ else if (which_alternative == 1)
+ return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
+ gcc_unreachable ();
+ }
+ [(set_attr "length" "8,*")
+ (set_attr "length_table" "*,logicb")
+ (set_attr "cc" "none_0hit,set_znv")])
+
+(define_expand "<code><mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (ors:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
;; ----------------------------------------------------------------------
-(define_insn "*logicalhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operator:HI 3 "bit_operator"
- [(match_operand:HI 1 "register_operand" "%0")
- (match_operand:HI 2 "nonmemory_operand" "rn")]))]
- ""
- "* return output_logical_op (HImode, operands);"
- [(set (attr "length")
- (symbol_ref "compute_logical_op_length (HImode, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
-
-(define_insn "*logicalsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 3 "bit_operator"
- [(match_operand:SI 1 "register_operand" "%0")
- (match_operand:SI 2 "nonmemory_operand" "rn")]))]
- ""
- "* return output_logical_op (SImode, operands);"
+(define_insn "*logical<mode>3"
+ [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:HSI 3 "bit_operator"
+ [(match_operand:HSI 1 "h8300_dst_operand" "%0")
+ (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
+ "h8300_operands_match_p (operands)"
+ { return output_logical_op (<MODE>mode, operands); }
[(set (attr "length")
- (symbol_ref "compute_logical_op_length (SImode, operands)"))
+ (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
(set (attr "cc")
- (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
+ (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
\f
;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "negqi2"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (neg:QI (match_operand:QI 1 "register_operand" "0")))]
+(define_expand "neg<mode>2"
+ [(set (match_operand:QHSIF 0 "register_operand" "")
+ (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
+ ""
+ {
+ enum machine_mode mode = <MODE>mode;
+ if (TARGET_H8300)
+ {
+ if (mode == QImode || mode == SFmode)
+ ;
+ else if (mode == HImode)
+ {
+ emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
+ DONE;
+ }
+ else if (mode == SImode)
+ {
+ emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
+ DONE;
+ }
+ }
+ })
+
+(define_insn "*negqi2"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (neg:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
""
"neg %X0"
- [(set_attr "length" "2")
+ [(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "neghi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (neg:HI (match_operand:HI 1 "register_operand" "")))]
- ""
- "
-{
- if (TARGET_H8300)
- {
- emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
- DONE;
- }
-}")
-
-(define_expand "neghi2_h8300"
+(define_expand "neg<mode>2_h8300"
[(set (match_dup 2)
- (not:HI (match_operand:HI 1 "register_operand" "")))
- (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
- (set (match_operand:HI 0 "register_operand" "")
+ (not:HSI (match_operand:HSI 1 "register_operand" "")))
+ (set (match_dup 2) (plus:HSI (match_dup 2) (const_int 1)))
+ (set (match_operand:HSI 0 "register_operand" "")
(match_dup 2))]
""
- "operands[2] = gen_reg_rtx (HImode);")
+ {
+ operands[2] = gen_reg_rtx (<MODE>mode);
+ })
(define_insn "*neghi2_h8300hs"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (neg:HI (match_operand:HI 1 "register_operand" "0")))]
- "TARGET_H8300H || TARGET_H8300S"
- "neg %T0"
- [(set_attr "length" "2")
+ [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
+ (neg:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+ "neg.w %T0"
+ [(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "negsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (neg:SI (match_operand:SI 1 "register_operand" "")))]
- ""
- "
-{
- if (TARGET_H8300)
- {
- emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
- DONE;
- }
-}")
-
-(define_expand "negsi2_h8300"
- [(set (match_dup 2)
- (not:SI (match_operand:SI 1 "register_operand" "")))
- (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
- (set (match_operand:SI 0 "register_operand" "")
- (match_dup 2))]
- ""
- "operands[2] = gen_reg_rtx (SImode);")
-
(define_insn "*negsi2_h8300hs"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "0")))]
- "TARGET_H8300H || TARGET_H8300S"
- "neg %S0"
- [(set_attr "length" "2")
+ [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
+ (neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+ "neg.l %S0"
+ [(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "negsf2"
- [(set (match_operand:SF 0 "register_operand" "")
- (neg:SF (match_operand:SF 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*negsf2_h8300"
[(set (match_operand:SF 0 "register_operand" "=r")
(neg:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_H8300"
"xor.b\\t#128,%z0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*negsf2_h8300hs"
[(set (match_operand:SF 0 "register_operand" "=r")
(neg:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_H8300H || TARGET_H8300S"
"xor.w\\t#32768,%e0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
\f
;; ----------------------------------------------------------------------
;; ABSOLUTE VALUE INSTRUCTIONS
(abs:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_H8300"
"and.b\\t#127,%z0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*abssf2_h8300hs"
[(set (match_operand:SF 0 "register_operand" "=r")
(abs:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_H8300H || TARGET_H8300S"
"and.w\\t#32767,%e0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
\f
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "one_cmplqi2"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (not:QI (match_operand:QI 1 "register_operand" "0")))]
+(define_expand "one_cmpl<mode>2"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (not:QHSI (match_operand:QHSI 1 "register_operand" "")))]
""
- "not %X0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ "")
-(define_expand "one_cmplhi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (not:HI (match_operand:HI 1 "register_operand" "0")))]
+(define_insn "*one_cmplqi2"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (not:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
""
- "")
+ "not %X0"
+ [(set_attr "length_table" "unary")
+ (set_attr "cc" "set_znv")])
(define_insn "*one_cmplhi2_h8300"
[(set (match_operand:HI 0 "register_operand" "=r")
(not:HI (match_operand:HI 1 "register_operand" "0")))]
"TARGET_H8300"
"not %s0\;not %t0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_insn "*one_cmplhi2_h8300hs"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (not:HI (match_operand:HI 1 "register_operand" "0")))]
- "TARGET_H8300H || TARGET_H8300S"
- "not %T0"
+ [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
+ (not:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+ "not.w %T0"
[(set_attr "cc" "set_znv")
- (set_attr "length" "2")])
-
-(define_expand "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operand:SI 1 "register_operand" "0")))]
- ""
- "")
+ (set_attr "length_table" "unary")])
-(define_insn "*one_complsi2_h8300"
+(define_insn "*one_cmplsi2_h8300"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_operand" "0")))]
"TARGET_H8300"
- "not %w0\;not %x0\;not %y0\;not %z0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "8")])
-
-(define_insn "*one_complsi2_h8300hs"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operand:SI 1 "register_operand" "0")))]
- "TARGET_H8300H || TARGET_H8300S"
- "not %S0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "2")])
-\f
-;; ----------------------------------------------------------------------
-;; JUMP INSTRUCTIONS
-;; ----------------------------------------------------------------------
-
-;; Conditional jump instructions
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+ "not %w0\;not %x0\;not %y0\;not %z0"
+ [(set_attr "length" "8")])
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+(define_insn "*one_cmplsi2_h8300hs"
+ [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
+ (not:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
+ "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
+ "not.l %S0"
+ [(set_attr "cc" "set_znv")
+ (set_attr "length_table" "unary")])
+\f
+;; ----------------------------------------------------------------------
+;; JUMP INSTRUCTIONS
+;; ----------------------------------------------------------------------
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+;; Conditional jump instructions
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchqi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:QI 1 "h8300_dst_operand" "")
+ (match_operand:QI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
""
- "")
+ {
+ h8300_expand_branch (operands);
+ DONE;
+ })
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchhi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:HI 1 "h8300_dst_operand" "")
+ (match_operand:HI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
""
- "")
+ {
+ /* Force operand1 into a register if we're compiling
+ for the H8/300. */
+ if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
+ && TARGET_H8300)
+ operands[2] = force_reg (HImode, operands[2]);
+ h8300_expand_branch (operands);
+ DONE;
+ })
+
+(define_expand "cbranchsi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "h8300_dst_operand" "")
+ (match_operand:SI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_H8300H || TARGET_H8300S"
+ {
+ h8300_expand_branch (operands);
+ DONE;
+ })
(define_insn "branch_true"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "*
{
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
&& (GET_CODE (operands[1]) == GT
}
if (get_attr_length (insn) == 2)
- return \"b%j1 %l0\";
+ return "b%j1 %l0";
else if (get_attr_length (insn) == 4)
- return \"b%j1 %l0:16\";
+ return "b%j1 %l0:16";
else
- return \"b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\";
-}"
+ return "b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
+}
[(set_attr "type" "branch")
(set_attr "cc" "none")])
(define_insn "branch_false"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "*
{
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
&& (GET_CODE (operands[1]) == GT
}
if (get_attr_length (insn) == 2)
- return \"b%k1 %l0\";
+ return "b%k1 %l0";
else if (get_attr_length (insn) == 4)
- return \"b%k1 %l0:16\";
+ return "b%k1 %l0:16";
else
- return \"b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\";
-}"
+ return "b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
+}
[(set_attr "type" "branch")
(set_attr "cc" "none")])
+(define_insn "*brabc"
+ [(set (pc)
+ (if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
+ (const_int 1)
+ (match_operand:QI 2 "immediate_operand" "n"))
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ "TARGET_H8300SX"
+{
+ switch (get_attr_length (insn)
+ - h8300_insn_length_from_table (insn, operands))
+ {
+ case 2:
+ return "bra/bc %2,%R1,%l0";
+ case 4:
+ return "bra/bc %2,%R1,%l0:16";
+ default:
+ return "bra/bs %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
+ }
+}
+ [(set_attr "type" "bitbranch")
+ (set_attr "length_table" "bitbranch")
+ (set_attr "cc" "none")])
+
+(define_insn "*brabs"
+ [(set (pc)
+ (if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
+ (const_int 1)
+ (match_operand:QI 2 "immediate_operand" "n"))
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ "TARGET_H8300SX"
+{
+ switch (get_attr_length (insn)
+ - h8300_insn_length_from_table (insn, operands))
+ {
+ case 2:
+ return "bra/bs %2,%R1,%l0";
+ case 4:
+ return "bra/bs %2,%R1,%l0:16";
+ default:
+ return "bra/bc %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
+ }
+}
+ [(set_attr "type" "bitbranch")
+ (set_attr "length_table" "bitbranch")
+ (set_attr "cc" "none")])
+
;; Unconditional and other jump instructions.
(define_insn "jump"
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
- "*
{
- if (get_attr_length (insn) == 2)
- return \"bra %l0\";
+ if (final_sequence != 0)
+ {
+ if (get_attr_length (insn) == 2)
+ return "bra/s %l0";
+ else
+ {
+ /* The branch isn't short enough to use bra/s. Output the
+ branch and delay slot in their normal order.
+
+ If this is a backward branch, it will now be branching two
+ bytes further than previously thought. The length-based
+ test for bra vs. jump is very conservative though, so the
+ branch will still be within range. */
+ rtx_sequence *seq;
+ int seen;
+
+ seq = final_sequence;
+ final_sequence = 0;
+ final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen);
+ final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen);
+ seq->insn (1)->set_deleted ();
+ return "";
+ }
+ }
+ else if (get_attr_length (insn) == 2)
+ return "bra %l0";
else if (get_attr_length (insn) == 4)
- return \"bra %l0:16\";
+ return "bra %l0:16";
else
- return \"jmp @%l0\";
-}"
+ return "jmp @%l0";
+}
[(set_attr "type" "branch")
+ (set (attr "delay_slot")
+ (if_then_else (match_test "TARGET_H8300SX")
+ (const_string "jump")
+ (const_string "none")))
(set_attr "cc" "none")])
;; This is a define expand, because pointers may be either 16 or 32 bits.
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call"
- [(call (match_operand:QI 0 "call_insn_operand" "or")
- (match_operand:HI 1 "general_operand" "g"))]
+(define_expand "call"
+ [(call (match_operand:QI 0 "call_expander_operand" "")
+ (match_operand 1 "general_operand" ""))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[0], 0), Pmode)
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
+ })
+
+(define_insn "call_insn_<mode>"
+ [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
+ (match_operand:P 1 "general_operand" "g"))]
""
- "*
{
- if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
- && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
- return \"jsr\\t@%0:8\";
+ rtx xoperands[1];
+ xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
+ gcc_assert (GET_MODE (operands[0]) == Pmode);
+ if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%0:8", xoperands);
else
- return \"jsr\\t%0\";
-}"
- [(set_attr "cc" "clobber")
+ output_asm_insn ("jsr\\t%0", xoperands);
+ return "";
+}
+ [(set_attr "type" "call")
(set (attr "length")
(if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
(const_int 2)
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call_value"
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "call_expander_operand" "")
+ (match_operand 2 "general_operand" "")))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[1], 0), Pmode)
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
+ })
+
+(define_insn "call_value_insn_<mode>"
[(set (match_operand 0 "" "=r")
- (call (match_operand:QI 1 "call_insn_operand" "or")
- (match_operand:HI 2 "general_operand" "g")))]
+ (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
+ (match_operand:P 2 "general_operand" "g")))]
""
- "*
{
- if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
- return \"jsr\\t@%1:8\";
+ rtx xoperands[2];
+ gcc_assert (GET_MODE (operands[1]) == Pmode);
+ xoperands[0] = operands[0];
+ xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
+ if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%1:8", xoperands);
else
- return \"jsr\\t%1\";
-}"
- [(set_attr "cc" "clobber")
+ output_asm_insn ("jsr\\t%1", xoperands);
+ return "";
+}
+ [(set_attr "type" "call")
(set (attr "length")
(if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
(const_int 2)
"TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
"")
-(define_insn "stm_h8300s_2_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int -8)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "stm.l\\t%S0-%S1,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "stm_h8300s_2_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -8)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "stm.l\\t%S0-%S1,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_expand "stm_h8300s_2"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")]
- "TARGET_H8300S
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "
-{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_stm_h8300s_2_advanced (operands[0], operands[1]));
- else
- emit_insn (gen_stm_h8300s_2_normal (operands[0], operands[1]));
- DONE;
-}")
-
-(define_insn "stm_h8300s_3_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int -12)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
- (match_operand:SI 2 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "stm.l\\t%S0-%S2,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "stm_h8300s_3_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -12)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
- (match_operand:SI 2 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "stm.l\\t%S0-%S2,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_expand "stm_h8300s_3"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")]
- "TARGET_H8300S
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "
-{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_stm_h8300s_3_advanced (operands[0], operands[1],
- operands[2]));
- else
- emit_insn (gen_stm_h8300s_3_normal (operands[0], operands[1],
- operands[2]));
- DONE;
-}")
-
-(define_insn "stm_h8300s_4_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int -16)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
- (match_operand:SI 2 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
- (match_operand:SI 3 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "stm.l\\t%S0-%S3,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "stm_h8300s_4_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int -16)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
- (match_operand:SI 2 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
- (match_operand:SI 3 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "stm.l\\t%S0-%S3,@-er7"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_expand "stm_h8300s_4"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "register_operand" "")]
- "TARGET_H8300S
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "
+(define_insn "ldm_h8300sx"
+ [(match_parallel 0 "h8300_ldm_parallel"
+ [(set (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "memory_operand" ""))])]
+ "TARGET_H8300S"
{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_stm_h8300s_4_advanced (operands[0], operands[1],
- operands[2], operands[3]));
- else
- emit_insn (gen_stm_h8300s_4_normal (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-}")
-
-(define_insn "ldm_h8300s_2_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 8)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (reg:SI SP_REG))
- (match_operand:SI 1 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "ldm.l\\t@er7+,%S0-%S1"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "ldm_h8300s_2_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int 8)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (reg:HI SP_REG))
- (match_operand:SI 1 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "ldm.l\\t@er7+,%S0-%S1"
+ operands[3] = SET_DEST (XVECEXP (operands[0], 0,
+ XVECLEN (operands[0], 0) - 2));
+ return "ldm.l\t@er7+,%S1-%S3";
+}
[(set_attr "cc" "none")
(set_attr "length" "4")])
-(define_expand "ldm_h8300s_2"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")]
- "TARGET_H8300S
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- "
+(define_insn "stm_h8300sx"
+ [(match_parallel 0 "h8300_stm_parallel"
+ [(set (match_operand:SI 1 "memory_operand" "")
+ (match_operand:SI 2 "register_operand" ""))])]
+ "TARGET_H8300S"
{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_ldm_h8300s_2_advanced (operands[0], operands[1]));
- else
- emit_insn (gen_ldm_h8300s_2_normal (operands[0], operands[1]));
- DONE;
-}")
-
-(define_insn "ldm_h8300s_3_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 12)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (reg:SI SP_REG))
- (match_operand:SI 2 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "ldm.l\\t@er7+,%S0-%S2"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "ldm_h8300s_3_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int 12)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (reg:HI SP_REG))
- (match_operand:SI 2 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "ldm.l\\t@er7+,%S0-%S2"
+ operands[3] = SET_SRC (XVECEXP (operands[0], 0,
+ XVECLEN (operands[0], 0) - 2));
+ return "stm.l\t%S2-%S3,@-er7";
+}
[(set_attr "cc" "none")
(set_attr "length" "4")])
-(define_expand "ldm_h8300s_3"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")]
- "TARGET_H8300S
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- "
+(define_insn "return_h8sx"
+ [(match_parallel 0 "h8300_return_parallel"
+ [(return)
+ (set (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "memory_operand" ""))])]
+ "TARGET_H8300SX"
{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_ldm_h8300s_3_advanced (operands[0], operands[1],
- operands[2]));
+ operands[3] = SET_DEST (XVECEXP (operands[0], 0,
+ XVECLEN (operands[0], 0) - 2));
+ if (h8300_current_function_interrupt_function_p ()
+ || h8300_current_function_monitor_function_p ())
+ return "rte/l\t%S1-%S3";
else
- emit_insn (gen_ldm_h8300s_3_normal (operands[0], operands[1],
- operands[2]));
- DONE;
-}")
-
-(define_insn "ldm_h8300s_4_advanced"
- [(parallel
- [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 16)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 12)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
- (match_operand:SI 2 "register_operand" ""))
- (set (mem:SI (reg:SI SP_REG))
- (match_operand:SI 3 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "ldm.l\\t@er7+,%S0-%S3"
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_insn "ldm_h8300s_4_normal"
- [(parallel
- [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG) (const_int 16)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 12)))
- (match_operand:SI 0 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
- (match_operand:SI 1 "register_operand" ""))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
- (match_operand:SI 2 "register_operand" ""))
- (set (mem:SI (reg:HI SP_REG))
- (match_operand:SI 3 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "ldm.l\\t@er7+,%S0-%S3"
+ return "rts/l\t%S1-%S3";
+}
[(set_attr "cc" "none")
- (set_attr "length" "4")])
-
-(define_expand "ldm_h8300s_4"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "register_operand" "")]
- "TARGET_H8300S && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- "
-{
- if (!TARGET_NORMAL_MODE)
- emit_insn (gen_ldm_h8300s_4_advanced (operands[0], operands[1],
- operands[2], operands[3]));
- else
- emit_insn (gen_ldm_h8300s_4_normal (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-}")
+ (set_attr "can_delay" "no")
+ (set_attr "length" "2")])
(define_expand "return"
[(return)]
(define_insn "*return_1"
[(return)]
"reload_completed"
- "*
{
- if (h8300_current_function_interrupt_function_p ())
- return \"rte\";
+ if (h8300_current_function_interrupt_function_p ()
+ || h8300_current_function_monitor_function_p ())
+ return "rte";
else
- return \"rts\";
-}"
+ return "rts";
+}
[(set_attr "cc" "none")
+ (set_attr "can_delay" "no")
(set_attr "length" "2")])
(define_expand "prologue"
[(const_int 0)]
""
- "h8300_expand_prologue (); DONE;")
+ {
+ h8300_expand_prologue ();
+ DONE;
+ })
(define_expand "epilogue"
[(return)]
""
- "h8300_expand_epilogue ();")
+ {
+ h8300_expand_epilogue ();
+ DONE;
+ })
(define_insn "monitor_prologue"
[(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
""
- "*
{
if (TARGET_H8300)
- return \"subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr\";
+ return "subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr";
+ else if (TARGET_H8300H && TARGET_NORMAL_MODE)
+ return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
else if (TARGET_H8300H)
- return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
+ return "mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
+ else if (TARGET_H8300S && TARGET_NEXR )
+ return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
+ else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
+ return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
+ else if (TARGET_H8300S && TARGET_NORMAL_MODE)
+ return "subs\\t#2,er7\;stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
else if (TARGET_H8300S)
- return \"stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
- abort ();
-}"
- [(set_attr "length" "20")
- (set_attr "cc" "clobber")])
+ return "stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
+ gcc_unreachable ();
+}
+ [(set_attr "length" "20")])
\f
;; ----------------------------------------------------------------------
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
+(define_expand "zero_extendqi<mode>2"
+ [(set (match_operand:HSI 0 "register_operand" "")
+ (zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
""
- "")
+ {
+ if (TARGET_H8300SX)
+ operands[1] = force_reg (QImode, operands[1]);
+ })
(define_insn "*zero_extendqihi2_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r")
"@
mov.b #0,%t0
#"
- [(set_attr "length" "2,10")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "2,10")])
(define_insn "*zero_extendqihi2_h8300hs"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_dup 1))
(set (match_dup 0)
(zero_extend:HI (match_dup 2)))]
- "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
+ {
+ operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
+ })
-(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
- ""
- "")
(define_insn "*zero_extendqisi2_h8300"
[(set (match_operand:SI 0 "register_operand" "=r,r")
"@
mov.b #0,%x0\;sub.w %e0,%e0
mov.b %R1,%w0\;mov.b #0,%x0\;sub.w %e0,%e0"
- [(set_attr "length" "4,8")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "4,8")])
(define_insn "*zero_extendqisi2_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
- "TARGET_H8300H || TARGET_H8300S"
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
"#")
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && reg_overlap_mentioned_p (operands[0], operands[1])
- && reload_completed"
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+ && reg_overlap_mentioned_p (operands[0], operands[1])
+ && reload_completed"
[(set (match_dup 2)
(match_dup 1))
(set (match_dup 3)
(zero_extend:HI (match_dup 2)))
(set (match_dup 0)
(zero_extend:SI (match_dup 3)))]
- "operands[2] = gen_lowpart (QImode, operands[0]);
- operands[3] = gen_lowpart (HImode, operands[0]);")
+ {
+ operands[2] = gen_lowpart (QImode, operands[0]);
+ operands[3] = gen_lowpart (HImode, operands[0]);
+ })
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && !reg_overlap_mentioned_p (operands[0], operands[1])
- && reload_completed"
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+ && !reg_overlap_mentioned_p (operands[0], operands[1])
+ && reload_completed"
[(set (match_dup 0)
(const_int 0))
(set (strict_low_part (match_dup 2))
(match_dup 1))]
- "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
+ {
+ operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
+ })
+
+(define_insn "*zero_extendqisi2_h8sx"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
+ "TARGET_H8300SX"
+ "extu.l\t#2,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
sub.w %e0,%e0
mov.w %f1,%f0\;sub.w %e0,%e0
mov.w %e1,%f0\;sub.w %e0,%e0"
- [(set_attr "length" "2,4,6")
- (set_attr "cc" "clobber,clobber,clobber")])
+ [(set_attr "length" "2,4,6")])
(define_insn "*zero_extendhisi2_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r")
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_expand "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "extendqi<mode>2"
+ [(set (match_operand:HSI 0 "register_operand" "")
+ (sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
""
"")
"@
bld #7,%s0\;subx %t0,%t0
mov.b %R1,%s0\;bld #7,%s0\;subx %t0,%t0"
- [(set_attr "length" "4,8")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "4,8")])
(define_insn "*extendqihi2_h8300hs"
[(set (match_operand:HI 0 "register_operand" "=r")
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_expand "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*extendqisi2_h8300"
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
"TARGET_H8300"
"@
bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0
mov.b %R1,%w0\;bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0"
- [(set_attr "length" "8,12")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "8,12")])
;; The following pattern is needed because without the pattern, the
-;; combiner would split (sign_extend:SI (reg:QI)) into into two 24-bit
+;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
;; shifts, one ashift and one ashiftrt.
(define_insn_and_split "*extendqisi2_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
"#"
"&& reload_completed"
[(set (match_dup 2)
(sign_extend:HI (match_dup 1)))
(set (match_dup 0)
(sign_extend:SI (match_dup 2)))]
- "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+ {
+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ })
+
+(define_insn "*extendqisi2_h8sx"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
+ "TARGET_H8300SX"
+ "exts.l\t#2,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
"@
bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0
mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0"
- [(set_attr "length" "6,10")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "6,10")])
(define_insn "*extendhisi2_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r")
;; ----------------------------------------------------------------------
;;
;; We make some attempt to provide real efficient shifting. One example is
-;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
+;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
;; reg and moving 0 into the former reg.
;;
;; We also try to achieve this in a uniform way. IE: We don't try to achieve
;; give the optimizer more cracks at the code. However, we wish to do things
;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
-;; 16 bit rotates. Also, if we emit complicated rtl, combine may not be able
+;; 16-bit rotates. Also, if we emit complicated rtl, combine may not be able
;; to detect cases it can optimize.
;;
;; For these and other fuzzy reasons, I've decided to go the less pretty but
(ashift:QI (match_operand:QI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (QImode, ASHIFT, operands); DONE;")
+ {
+ if (expand_a_shift (QImode, ASHIFT, operands))
+ DONE;
+ })
(define_expand "ashrqi3"
[(set (match_operand:QI 0 "register_operand" "")
(ashiftrt:QI (match_operand:QI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (QImode, ASHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (QImode, ASHIFTRT, operands))
+ DONE;
+ })
(define_expand "lshrqi3"
[(set (match_operand:QI 0 "register_operand" "")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (QImode, LSHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (QImode, LSHIFTRT, operands))
+ DONE;
+ })
+
+(define_insn ""
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:QI 3 "h8sx_unary_shift_operator"
+ [(match_operand:QI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "")]))]
+ "h8300_operands_match_p (operands)"
+{
+ return output_h8sx_shift (operands, 'b', 'X');
+}
+ [(set_attr "length_table" "unary")
+ (set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (match_operator:QI 3 "h8sx_binary_shift_operator"
+ [(match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
+ ""
+{
+ return output_h8sx_shift (operands, 'b', 'X');
+}
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
(define_insn "*shiftqi"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(match_operator:QI 3 "nshift_operator"
- [ (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
+ [(match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
- "* return output_a_shift (operands);"
+{
+ return output_a_shift (operands);
+}
[(set (attr "length")
(symbol_ref "compute_a_shift_length (insn, operands)"))
(set (attr "cc")
(define_expand "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "")
- (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
+ (ashift:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (HImode, ASHIFT, operands); DONE;")
+ {
+ if (expand_a_shift (HImode, ASHIFT, operands))
+ DONE;
+ })
(define_expand "lshrhi3"
[(set (match_operand:HI 0 "register_operand" "")
- (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
+ (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (HImode, LSHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (HImode, LSHIFTRT, operands))
+ DONE;
+ })
(define_expand "ashrhi3"
[(set (match_operand:HI 0 "register_operand" "")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (HImode, ASHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (HImode, ASHIFTRT, operands))
+ DONE;
+ })
+
+(define_insn ""
+ [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:HI 3 "h8sx_unary_shift_operator"
+ [(match_operand:HI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "")]))]
+ "h8300_operands_match_p (operands)"
+{
+ return output_h8sx_shift (operands, 'w', 'T');
+}
+ [(set_attr "length_table" "unary")
+ (set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (match_operator:HI 3 "h8sx_binary_shift_operator"
+ [(match_operand:HI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
+ ""
+{
+ return output_h8sx_shift (operands, 'w', 'T');
+}
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
(define_insn "*shifthi"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_operator:HI 3 "nshift_operator"
- [ (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
+ [(match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
- "* return output_a_shift (operands);"
+{
+ return output_a_shift (operands);
+}
[(set (attr "length")
(symbol_ref "compute_a_shift_length (insn, operands)"))
(set (attr "cc")
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_operand:SI 1 "general_operand" "")
+ (ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (SImode, ASHIFT, operands); DONE;")
+ {
+ if (expand_a_shift (SImode, ASHIFT, operands))
+ DONE;
+ })
(define_expand "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "")
- (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (SImode, LSHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (SImode, LSHIFTRT, operands))
+ DONE;
+ })
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:SI (match_operand:SI 1 "general_operand" "")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
- "expand_a_shift (SImode, ASHIFTRT, operands); DONE;")
+ {
+ if (expand_a_shift (SImode, ASHIFTRT, operands))
+ DONE;
+ })
+
+(define_insn ""
+ [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:SI 3 "h8sx_unary_shift_operator"
+ [(match_operand:SI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "")]))]
+ "h8300_operands_match_p (operands)"
+{
+ return output_h8sx_shift (operands, 'l', 'S');
+}
+ [(set_attr "length_table" "unary")
+ (set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 3 "h8sx_binary_shift_operator"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
+ ""
+{
+ return output_h8sx_shift (operands, 'l', 'S');
+}
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
(define_insn "*shiftsi"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operator:SI 3 "nshift_operator"
- [ (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
- "* return output_a_shift (operands);"
+{
+ return output_a_shift (operands);
+}
[(set (attr "length")
(symbol_ref "compute_a_shift_length (insn, operands)"))
(set (attr "cc")
;; the shift count dies, then we just use that register.
(define_split
- [(parallel
- [(set (match_operand 0 "register_operand" "")
- (match_operator 2 "nshift_operator"
- [(match_dup 0)
- (match_operand:QI 1 "register_operand" "")]))
- (clobber (match_operand:QI 3 "register_operand" ""))])]
- "flow2_completed
+ [(set (match_operand 0 "register_operand" "")
+ (match_operator 2 "nshift_operator"
+ [(match_dup 0)
+ (match_operand:QI 1 "register_operand" "")]))
+ (clobber (match_operand:QI 3 "register_operand" ""))]
+ "epilogue_completed
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
- [(set (cc0)
- (match_dup 1))
+ [(set (cc0) (compare (match_dup 1) (const_int 0)))
(set (pc)
(if_then_else (le (cc0) (const_int 0))
(label_ref (match_dup 5))
[(set (match_dup 0)
(match_op_dup 2 [(match_dup 0) (const_int 1)]))
(clobber (scratch:QI))])
- (set (match_dup 1)
- (plus:QI (match_dup 1) (const_int -1)))
- (set (cc0)
- (match_dup 1))
+ (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
+ (set (cc0) (compare (match_dup 1) (const_int 0)))
(set (pc)
(if_then_else (ne (cc0) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
- "operands[4] = gen_label_rtx ();
- operands[5] = gen_label_rtx ();")
+ {
+ operands[4] = gen_label_rtx ();
+ operands[5] = gen_label_rtx ();
+ })
(define_split
- [(parallel
- [(set (match_operand 0 "register_operand" "")
- (match_operator 2 "nshift_operator"
- [(match_dup 0)
- (match_operand:QI 1 "register_operand" "")]))
- (clobber (match_operand:QI 3 "register_operand" ""))])]
- "flow2_completed
+ [(set (match_operand 0 "register_operand" "")
+ (match_operator 2 "nshift_operator"
+ [(match_dup 0)
+ (match_operand:QI 1 "register_operand" "")]))
+ (clobber (match_operand:QI 3 "register_operand" ""))]
+ "epilogue_completed
&& !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
[(set (match_dup 3)
(match_dup 1))
- (set (cc0)
- (match_dup 3))
+ (set (cc0) (compare (match_dup 3) (const_int 0)))
(set (pc)
(if_then_else (le (cc0) (const_int 0))
(label_ref (match_dup 5))
[(set (match_dup 0)
(match_op_dup 2 [(match_dup 0) (const_int 1)]))
(clobber (scratch:QI))])
- (set (match_dup 3)
- (plus:QI (match_dup 3) (const_int -1)))
- (set (cc0)
- (match_dup 3))
+ (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
+ (set (cc0) (compare (match_dup 3) (const_int 0)))
(set (pc)
(if_then_else (ne (cc0) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
- "operands[4] = gen_label_rtx ();
- operands[5] = gen_label_rtx ();")
+ {
+ operands[4] = gen_label_rtx ();
+ operands[5] = gen_label_rtx ();
+ })
\f
;; ----------------------------------------------------------------------
;; ROTATIONS
;; ----------------------------------------------------------------------
-(define_expand "rotlqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (rotate:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
-
-(define_insn "*rotlqi3_1"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (rotate:QI (match_operand:QI 1 "register_operand" "0")
- (match_operand:QI 2 "immediate_operand" "")))]
- ""
- "* return output_a_rotate (ROTATE, operands);"
- [(set (attr "length")
- (symbol_ref "compute_a_rotate_length (operands)"))
- (set_attr "cc" "clobber")])
-
-(define_expand "rotlhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (rotate:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
+(define_expand "rotl<mode>3"
+ [(set (match_operand:QHI 0 "register_operand" "")
+ (rotate:QHI (match_operand:QHI 1 "register_operand" "")
+ (match_operand:QI 2 "nonmemory_operand" "")))]
""
- "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
+ {
+ if (expand_a_rotate (operands))
+ DONE;
+ })
-(define_insn "*rotlhi3_1"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (rotate:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "immediate_operand" "")))]
+(define_insn "rotl<mode>3_1"
+ [(set (match_operand:QHI 0 "register_operand" "=r")
+ (rotate:QHI (match_operand:QHI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "")))]
""
- "* return output_a_rotate (ROTATE, operands);"
+{
+ return output_a_rotate (ROTATE, operands);
+}
[(set (attr "length")
- (symbol_ref "compute_a_rotate_length (operands)"))
- (set_attr "cc" "clobber")])
+ (symbol_ref "compute_a_rotate_length (operands)"))])
(define_expand "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(rotate:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
"TARGET_H8300H || TARGET_H8300S"
- "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
+ {
+ if (expand_a_rotate (operands))
+ DONE;
+ })
-(define_insn "*rotlsi3_1"
+(define_insn "rotlsi3_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotate:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "")))]
"TARGET_H8300H || TARGET_H8300S"
- "* return output_a_rotate (ROTATE, operands);"
+{
+ return output_a_rotate (ROTATE, operands);
+}
[(set (attr "length")
- (symbol_ref "compute_a_rotate_length (operands)"))
- (set_attr "cc" "clobber")])
+ (symbol_ref "compute_a_rotate_length (operands)"))])
\f
;; -----------------------------------------------------------------
;; BIT FIELDS
(match_operand:HI 2 "immediate_operand" "n")))]
"TARGET_H8300"
"sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
;;
;; Inverted loads with a 16bit destination.
(match_operand:HI 3 "const_int_operand" "n"))
(const_int 1)
(match_operand:HI 2 "const_int_operand" "n")))]
- "TARGET_H8300
- && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+ "(TARGET_H8300 || TARGET_H8300SX)
+ && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
"sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "8")])
+ [(set_attr "length" "8")])
;;
;; Normal loads with a 32bit destination.
(zero_extract:SI (match_operand:HI 1 "register_operand" "r")
(const_int 1)
(match_operand 2 "const_int_operand" "n")))]
- "TARGET_H8300
- && INTVAL (operands[2]) < 16"
- "* return output_simode_bld (0, operands);"
- [(set_attr "cc" "clobber")
- (set_attr "length" "8")])
+ "TARGET_H8300 && INTVAL (operands[2]) < 16"
+{
+ return output_simode_bld (0, operands);
+}
+ [(set_attr "length" "8")])
(define_insn "*extzv_1_r_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
(const_int 1)
(match_operand 2 "const_int_operand" "n,n")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[2]) < 16"
- "* return output_simode_bld (0, operands);"
+ "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
+{
+ return output_simode_bld (0, operands);
+}
[(set_attr "cc" "set_znv,set_znv")
(set_attr "length" "8,6")])
(match_operand:HI 3 "const_int_operand" "n"))
(const_int 1)
(match_operand 2 "const_int_operand" "n")))]
- "TARGET_H8300
- && INTVAL (operands[2]) < 16
+ "TARGET_H8300 && INTVAL (operands[2]) < 16
&& (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
- "* return output_simode_bld (1, operands);"
- [(set_attr "cc" "clobber")
- (set_attr "length" "8")])
+{
+ return output_simode_bld (1, operands);
+}
+ [(set_attr "length" "8")])
(define_insn "*extzv_1_r_inv_h8300hs"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operand 3 "const_int_operand" "n,n"))
(const_int 1)
(match_operand 2 "const_int_operand" "n,n")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[2]) < 16
- && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
- "* return output_simode_bld (1, operands);"
+ "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16
+ && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+{
+ return output_simode_bld (1, operands);
+}
[(set_attr "cc" "set_znv,set_znv")
(set_attr "length" "8,6")])
(match_operand:HI 1 "general_operand" "")
(match_operand:HI 2 "general_operand" ""))
(match_operand:HI 3 "general_operand" ""))]
- "TARGET_H8300"
- "
-{
- /* We only have single bit bit-field instructions. */
- if (INTVAL (operands[1]) != 1)
- FAIL;
-
- /* For now, we don't allow memory operands. */
- if (GET_CODE (operands[0]) == MEM
- || GET_CODE (operands[3]) == MEM)
- FAIL;
-}")
+ "TARGET_H8300 || TARGET_H8300SX"
+ {
+ if (TARGET_H8300SX)
+ {
+ if (GET_CODE (operands[1]) == CONST_INT
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[1]) <= 8
+ && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
+ && memory_operand (operands[0], GET_MODE (operands[0])))
+ {
+ /* If the source operand is zero, it's better to use AND rather
+ than BFST. Likewise OR if the operand is all ones. */
+ if (GET_CODE (operands[3]) == CONST_INT)
+ {
+ HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
+ if ((INTVAL (operands[3]) & mask) == 0)
+ FAIL;
+ if ((INTVAL (operands[3]) & mask) == mask)
+ FAIL;
+ }
+ if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
+ {
+ if (!can_create_pseudo_p ())
+ FAIL;
+ operands[0] = replace_equiv_address (operands[0], force_reg (Pmode,
+ XEXP (operands[0], 0)));
+ }
+ operands[3] = gen_lowpart (QImode, operands[3]);
+ if (! operands[3])
+ FAIL;
+ if (! register_operand (operands[3], QImode))
+ {
+ if (!can_create_pseudo_p ())
+ FAIL;
+ operands[3] = force_reg (QImode, operands[3]);
+ }
+ emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
+ operands[3], operands[1], operands[2]));
+ DONE;
+ }
+ FAIL;
+ }
+
+ /* We only have single bit bit-field instructions. */
+ if (INTVAL (operands[1]) != 1)
+ FAIL;
+
+ /* For now, we don't allow memory operands. */
+ if (GET_CODE (operands[0]) == MEM
+ || GET_CODE (operands[3]) == MEM)
+ FAIL;
+
+ if (GET_CODE (operands[3]) != REG)
+ operands[3] = force_reg (HImode, operands[3]);
+ })
(define_insn ""
[(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
(match_operand:HI 2 "register_operand" "r"))]
""
"bld #0,%R2\;bst %Z1,%Y0 ; i1"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_expand "extzv"
[(set (match_operand:HI 0 "register_operand" "")
(zero_extract:HI (match_operand:HI 1 "bit_operand" "")
(match_operand:HI 2 "general_operand" "")
(match_operand:HI 3 "general_operand" "")))]
- "TARGET_H8300"
- "
-{
- /* We only have single bit bit-field instructions. */
- if (INTVAL (operands[2]) != 1)
- FAIL;
-
- /* For now, we don't allow memory operands. */
- if (GET_CODE (operands[1]) == MEM)
- FAIL;
-}")
+ "TARGET_H8300 || TARGET_H8300SX"
+ {
+ if (TARGET_H8300SX)
+ {
+ if (GET_CODE (operands[2]) == CONST_INT
+ && GET_CODE (operands[3]) == CONST_INT
+ && INTVAL (operands[2]) <= 8
+ && INTVAL (operands[3]) >= 0
+ && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
+ && memory_operand (operands[1], QImode))
+ {
+ rtx temp;
+
+ /* Optimize the case where we're extracting into a paradoxical
+ subreg. It's only necessary to extend to the inner reg. */
+ if (GET_CODE (operands[0]) == SUBREG
+ && subreg_lowpart_p (operands[0])
+ && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
+ < GET_MODE_SIZE (GET_MODE (operands[0])))
+ && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
+ == MODE_INT))
+ operands[0] = SUBREG_REG (operands[0]);
+
+ if (!can_create_pseudo_p ())
+ temp = gen_lowpart (QImode, operands[0]);
+ else
+ temp = gen_reg_rtx (QImode);
+ if (! temp)
+ FAIL;
+ if (! bit_memory_operand (operands[1], QImode))
+ {
+ if (!can_create_pseudo_p ())
+ FAIL;
+ operands[1] = replace_equiv_address (operands[1],
+ force_reg (Pmode, XEXP (operands[1], 0)));
+ }
+ emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
+ convert_move (operands[0], temp, 1);
+ DONE;
+ }
+ FAIL;
+ }
+
+ /* We only have single bit bit-field instructions. */
+ if (INTVAL (operands[2]) != 1)
+ FAIL;
+
+ /* For now, we don't allow memory operands. */
+ if (GET_CODE (operands[1]) == MEM)
+ FAIL;
+ })
;; BAND, BOR, and BXOR patterns
(define_insn ""
[(set (match_operand:HI 0 "bit_operand" "=Ur")
(match_operator:HI 4 "bit_operator"
- [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
- (const_int 1)
- (match_operand:HI 2 "immediate_operand" "n"))
- (match_operand:HI 3 "bit_operand" "0")]))]
+ [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 2 "immediate_operand" "n"))
+ (match_operand:HI 3 "bit_operand" "0")]))]
""
"bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1"
- [(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
(define_insn ""
[(set (match_operand:HI 0 "bit_operand" "=Ur")
(match_operator:HI 5 "bit_operator"
- [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
- (const_int 1)
- (match_operand:HI 2 "immediate_operand" "n"))
- (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
- (const_int 1)
- (match_operand:HI 4 "immediate_operand" "n"))]))]
+ [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 2 "immediate_operand" "n"))
+ (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 4 "immediate_operand" "n"))]))]
""
"bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3"
- [(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
+
+(define_insn "bfld"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
+ (match_operand:QI 2 "immediate_operand" "n")
+ (match_operand:QI 3 "immediate_operand" "n")))]
+ "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+{
+ operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
+ - (1 << INTVAL (operands[3])));
+ return "bfld %2,%1,%R0";
+}
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "bitfield")])
+
+(define_insn "bfst"
+ [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+ (match_operand:QI 2 "immediate_operand" "n")
+ (match_operand:QI 3 "immediate_operand" "n"))
+ (match_operand:QI 1 "register_operand" "r"))]
+ "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+{
+ operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
+ - (1 << INTVAL (operands[3])));
+ return "bfst %R1,%2,%0";
+}
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "bitfield")])
+
+(define_expand "cstoreqi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:QI 2 "h8300_dst_operand" "")
+ (match_operand:QI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
+ "TARGET_H8300SX"
+ {
+ h8300_expand_store (operands);
+ DONE;
+ })
+
+(define_expand "cstorehi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:HI 2 "h8300_dst_operand" "")
+ (match_operand:HI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
+ "TARGET_H8300SX"
+ {
+ h8300_expand_store (operands);
+ DONE;
+ })
+
+(define_expand "cstoresi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:SI 2 "h8300_dst_operand" "")
+ (match_operand:SI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
+ "TARGET_H8300SX"
+ {
+ h8300_expand_store (operands);
+ DONE;
+ })
+
+(define_insn "*bstzhireg"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
+ "TARGET_H8300SX"
+ "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
+ [(set_attr "cc" "clobber")])
+
+(define_insn_and_split "*cmpstz"
+ [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
+ (const_int 1)
+ (match_operand:QI 1 "immediate_operand" "n,n"))
+ (match_operator:QI 2 "eqne_operator"
+ [(match_operand 3 "h8300_dst_operand" "r,rQ")
+ (match_operand 4 "h8300_src_operand" "I,rQi")]))]
+ "TARGET_H8300SX
+ && (GET_MODE (operands[3]) == GET_MODE (operands[4])
+ || GET_CODE (operands[4]) == CONST_INT)
+ && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
+ && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
+ "#"
+ "reload_completed"
+ [(set (cc0) (match_dup 5))
+ (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
+ (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
+ {
+ operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
+ }
+ [(set_attr "cc" "set_znv,compare")])
+
+(define_insn "*bstz"
+ [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+ (const_int 1)
+ (match_operand:QI 1 "immediate_operand" "n"))
+ (eq:QI (cc0) (const_int 0)))]
+ "TARGET_H8300SX && reload_completed"
+ "bstz %1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "unary")])
+
+(define_insn "*bistz"
+ [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+ (const_int 1)
+ (match_operand:QI 1 "immediate_operand" "n"))
+ (ne:QI (cc0) (const_int 0)))]
+ "TARGET_H8300SX && reload_completed"
+ "bistz %1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "unary")])
+
+(define_insn_and_split "*cmpcondbset"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+ (if_then_else:QI (match_operator 1 "eqne_operator"
+ [(match_operand 2 "h8300_dst_operand" "r,rQ")
+ (match_operand 3 "h8300_src_operand" "I,rQi")])
+ (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+ (match_operand:QI 5 "single_one_operand" "n,n"))
+ (match_dup 4)))]
+ "TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(set (cc0) (match_dup 6))
+ (set (match_dup 0)
+ (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+ (ior:QI (match_dup 4) (match_dup 5))
+ (match_dup 4)))]
+ {
+ operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+ }
+ [(set_attr "cc" "set_znv,compare")])
+
+(define_insn "*condbset"
+ [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+ (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+ (match_operand:QI 1 "single_one_operand" "n"))
+ (match_dup 3)))]
+ "TARGET_H8300SX && reload_completed"
+ "bset/%j2\t%V1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "logicb")])
+
+(define_insn_and_split "*cmpcondbclr"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+ (if_then_else:QI (match_operator 1 "eqne_operator"
+ [(match_operand 2 "h8300_dst_operand" "r,rQ")
+ (match_operand 3 "h8300_src_operand" "I,rQi")])
+ (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+ (match_operand:QI 5 "single_zero_operand" "n,n"))
+ (match_dup 4)))]
+ "TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(set (cc0) (match_dup 6))
+ (set (match_dup 0)
+ (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+ (and:QI (match_dup 4) (match_dup 5))
+ (match_dup 4)))]
+ {
+ operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+ }
+ [(set_attr "cc" "set_znv,compare")])
+
+(define_insn "*condbclr"
+ [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+ (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+ (match_operand:QI 1 "single_zero_operand" "n"))
+ (match_dup 3)))]
+ "TARGET_H8300SX && reload_completed"
+ "bclr/%j2\t%W1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "logicb")])
+
+(define_insn_and_split "*cmpcondbsetreg"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+ (if_then_else:QI (match_operator 1 "eqne_operator"
+ [(match_operand 2 "h8300_dst_operand" "r,rQ")
+ (match_operand 3 "h8300_src_operand" "I,rQi")])
+ (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+ (ashift:QI (const_int 1)
+ (match_operand:QI 5 "register_operand" "r,r")))
+ (match_dup 4)))]
+ "TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(set (cc0) (match_dup 6))
+ (set (match_dup 0)
+ (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+ (ior:QI (match_dup 4)
+ (ashift:QI (const_int 1)
+ (match_operand:QI 5 "register_operand" "r,r")))
+ (match_dup 4)))]
+ {
+ operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+ }
+ [(set_attr "cc" "set_znv,compare")])
+
+(define_insn "*condbsetreg"
+ [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+ (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+ (ashift:QI (const_int 1)
+ (match_operand:QI 1 "register_operand" "r")))
+ (match_dup 3)))]
+ "TARGET_H8300SX && reload_completed"
+ "bset/%j2\t%R1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "logicb")])
+
+(define_insn_and_split "*cmpcondbclrreg"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+ (if_then_else:QI (match_operator 1 "eqne_operator"
+ [(match_operand 2 "h8300_dst_operand" "r,rQ")
+ (match_operand 3 "h8300_src_operand" "I,rQi")])
+ (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+ (ashift:QI (const_int 1)
+ (match_operand:QI 5 "register_operand" "r,r")))
+ (match_dup 4)))]
+ "TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(set (cc0) (match_dup 6))
+ (set (match_dup 0)
+ (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+ (and:QI (match_dup 4)
+ (ashift:QI (const_int 1)
+ (match_operand:QI 5 "register_operand" "r,r")))
+ (match_dup 4)))]
+ {
+ operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+ }
+ [(set_attr "cc" "set_znv,compare")])
+
+(define_insn "*condbclrreg"
+ [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+ (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+ (ashift:QI (const_int 1)
+ (match_operand:QI 1 "register_operand" "r")))
+ (match_dup 3)))]
+ "TARGET_H8300SX && reload_completed"
+ "bclr/%j2\t%R1,%0"
+ [(set_attr "cc" "none_0hit")
+ (set_attr "length_table" "logicb")])
+
\f
;; -----------------------------------------------------------------
;; COMBINE PATTERNS
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n"))
(match_operand:SI 2 "register_operand" "r"))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[1]) < 16"
+ "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
"bld\\t#0,%w2\;bst\\t%Z1,%Y0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_insn "*insv_si_1_n_lshiftrt"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "const_int_operand" "n")))]
"(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[1]) < 16
- && INTVAL (operands[3]) < 16"
+ && INTVAL (operands[1]) < 16
+ && INTVAL (operands[3]) < 16"
"bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_insn "*insv_si_1_n_lshiftrt_16"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "const_int_operand" "n"))
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16)))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[1]) < 16"
+ "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
"rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
(define_insn "*insv_si_8_8"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "register_operand" "r"))]
"TARGET_H8300H || TARGET_H8300S"
"mov.b\\t%w1,%x0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*insv_si_8_8_lshiftrt_8"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 8)))]
"TARGET_H8300H || TARGET_H8300S"
"mov.b\\t%x1,%x0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; extzv:SI
(match_operand:SI 3 "const_int_operand" "n,n")))
(clobber (match_scratch:QI 4 "=X,&r"))]
"(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[2]) <= 15
- && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
+ && INTVAL (operands[2]) <= 15
+ && UINTVAL (operands[3]) == ((HOST_WIDE_INT_M1U << INTVAL (operands[2]))
+ & 0xffff)"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 5)
(clobber (match_dup 4))])
(set (match_dup 0)
(zero_extend:SI (match_dup 5)))]
- "operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+ {
+ operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ })
;; Accept (A >> 30) & 2 and the like.
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "single_one_operand" "n")))]
"(TARGET_H8300H || TARGET_H8300S)
- && exact_log2 (INTVAL (operands[3])) < 16
- && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
- "*
+ && exact_log2 (INTVAL (operands[3])) < 16
+ && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
{
operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
- return \"shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0\";
-}"
- [(set_attr "length" "8")
- (set_attr "cc" "clobber")])
+ return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
+}
+ [(set_attr "length" "8")])
(define_insn_and_split "*andsi3_lshiftrt_9_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 9))
(const_int 4194304)))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(set (match_dup 0)
(match_operand:SI 2 "register_operand" "0")))]
"TARGET_H8300H || TARGET_H8300S"
"add.w\\t%f1,%e0"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "2")])
(define_insn "*addsi3_lshiftrt_16_zexthi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
"TARGET_H8300H || TARGET_H8300S"
"add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
(define_insn_and_split "*addsi3_and_r_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
(const_int 1))
(match_operand:SI 2 "register_operand" "0")))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
- [(set (cc0)
- (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0)))
+ [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (const_int 0))
+ (const_int 0)))
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(plus:SI (match_dup 2)
(const_int 1)))
(match_dup 3)]
- "operands[3] = gen_label_rtx ();")
+ {
+ operands[3] = gen_label_rtx ();
+ })
(define_insn_and_split "*addsi3_and_not_r_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
(const_int 1))
(match_operand:SI 2 "register_operand" "0")))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
- [(set (cc0)
- (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0)))
+ [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (const_int 0))
+ (const_int 0)))
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(plus:SI (match_dup 2)
(const_int 1)))
(match_dup 3)]
- "operands[3] = gen_label_rtx ();")
+ {
+ operands[3] = gen_label_rtx ();
+ })
;; [ix]or:HI
(define_insn "*ixorhi3_zext"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operator:HI 1 "iorxor_operator"
- [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
- (match_operand:HI 3 "register_operand" "0")]))]
+ [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:HI 3 "register_operand" "0")]))]
""
"%c1.b\\t%X2,%s0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; [ix]or:SI
(define_insn "*ixorsi3_zext_qi"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
- [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
- (match_operand:SI 3 "register_operand" "0")]))]
+ [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:SI 3 "register_operand" "0")]))]
""
"%c1.b\\t%X2,%w0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*ixorsi3_zext_hi"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
- [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
- (match_operand:SI 3 "register_operand" "0")]))]
+ [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
+ (match_operand:SI 3 "register_operand" "0")]))]
"TARGET_H8300H || TARGET_H8300S"
"%c1.w\\t%T2,%f0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*ixorsi3_ashift_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
- [(ashift:SI (match_operand:SI 2 "register_operand" "r")
- (const_int 16))
- (match_operand:SI 3 "register_operand" "0")]))]
+ [(ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (match_operand:SI 3 "register_operand" "0")]))]
"TARGET_H8300H || TARGET_H8300S"
"%c1.w\\t%f2,%e0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*ixorsi3_lshiftrt_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
- [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
- (const_int 16))
- (match_operand:SI 3 "register_operand" "0")]))]
+ [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (match_operand:SI 3 "register_operand" "0")]))]
"TARGET_H8300H || TARGET_H8300S"
"%c1.w\\t%e2,%f0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; ior:HI
(match_operand:HI 2 "register_operand" "0")))]
""
"or.b\\t%s1,%t0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*iorhi3_lshiftrt_8"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 2 "register_operand" "0")))]
""
"or.b\\t%t1,%s0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*iorhi3_two_qi"
[(set (match_operand:HI 0 "register_operand" "=r")
(const_int 8))))]
""
"mov.b\\t%s2,%t0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn "*iorhi3_two_qi_mem"
[(set (match_operand:HI 0 "register_operand" "=&r")
(const_int 8))))]
""
"mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "16")])
+ [(set_attr "length" "16")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
(const_int 8))))]
"(TARGET_H8300H || TARGET_H8300S)
- && reload_completed
- && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
+ && reload_completed
+ && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
[(set (match_dup 0)
(match_dup 3))]
- "operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));")
+ {
+ operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
+ })
;; ior:SI
(const_int 16))))]
"TARGET_H8300H || TARGET_H8300S"
"mov.w\\t%f2,%e0"
- [(set_attr "cc" "clobber")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
(define_insn_and_split "*iorsi3_two_qi_zext"
[(set (match_operand:SI 0 "register_operand" "=&r")
(ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
-
(and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
(const_int 8))
(const_int 65280))))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(set (match_dup 3)
(const_int 8))))
(set (match_dup 0)
(zero_extend:SI (match_dup 3)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ })
(define_insn "*iorsi3_e2f"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 16))))]
"TARGET_H8300H || TARGET_H8300S"
"mov.w\\t%e2,%f0"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "2")])
(define_insn_and_split "*iorsi3_two_qi_sext"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
(ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
(const_int 8))))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(set (match_dup 3)
(const_int 8))))
(set (match_dup 0)
(sign_extend:SI (match_dup 3)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
- operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
+ })
(define_insn "*iorsi3_w"
[(set (match_operand:SI 0 "register_operand" "=r,&r")
(zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
"TARGET_H8300H || TARGET_H8300S"
"mov.b\\t%X2,%w0"
- [(set_attr "length" "2,8")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "2,8")])
(define_insn "*iorsi3_ashift_31"
[(set (match_operand:SI 0 "register_operand" "=&r")
(match_operand:SI 3 "single_one_operand" "n"))
(match_operand:SI 4 "register_operand" "0")))]
"(TARGET_H8300H || TARGET_H8300S)
- && (INTVAL (operands[3]) & ~0xffff) == 0"
- "*
+ && (INTVAL (operands[3]) & ~0xffff) == 0"
{
rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
- INTVAL (operands[2]));
rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
operands[2] = srcpos;
operands[3] = dstpos;
- return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
+}
+ [(set_attr "length" "6")])
(define_insn "*iorsi3_and_lshiftrt"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 3 "single_one_operand" "n"))
(match_operand:SI 4 "register_operand" "0")))]
"(TARGET_H8300H || TARGET_H8300S)
- && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
- "*
+ && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
{
rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
+ INTVAL (operands[2]));
rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
operands[2] = srcpos;
operands[3] = dstpos;
- return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
-}"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
+}
+ [(set_attr "length" "6")])
(define_insn "*iorsi3_zero_extract"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 1)
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "register_operand" "0")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && INTVAL (operands[2]) < 16"
+ "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
"bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "6")])
(define_insn "*iorsi3_and_lshiftrt_n_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 30))
(const_int 2))
(match_operand:SI 2 "register_operand" "0")))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
- [(set_attr "length" "8")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "8")])
(define_insn "*iorsi3_and_lshiftrt_9_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 4194304))
(match_operand:SI 2 "register_operand" "0")))
(clobber (match_scratch:HI 3 "=&r"))]
- "(TARGET_H8300H || TARGET_H8300S)"
- "*
+ "TARGET_H8300H || TARGET_H8300S"
{
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return \"shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
+ return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
else
- return \"rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
-}"
- [(set_attr "length" "10")
- (set_attr "cc" "clobber")])
+ return "rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
+}
+ [(set_attr "length" "10")])
;; Used to OR the exponent of a float.
"#")
(define_split
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
- (const_int 23))
- (match_dup 0)))
- (clobber (match_operand:SI 2 "register_operand" ""))])]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 23))
+ (match_dup 0)))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S)
- && flow2_completed
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
- && REGNO (operands[0]) != REGNO (operands[1])"
+ && epilogue_completed
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
+ && REGNO (operands[0]) != REGNO (operands[1])"
[(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
(ior:SI (ashift:SI (match_dup 1)
(const_int 16))
(match_dup 0)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
+ })
(define_split
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
- (const_int 23))
- (match_dup 0)))
- (clobber (match_operand:SI 2 "register_operand" ""))])]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 23))
+ (match_dup 0)))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S)
- && flow2_completed
- && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
- && REGNO (operands[0]) != REGNO (operands[1]))"
+ && epilogue_completed
+ && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
+ && REGNO (operands[0]) != REGNO (operands[1]))"
[(set (match_dup 2)
(match_dup 1))
(parallel [(set (match_dup 3)
(ior:SI (ashift:SI (match_dup 2)
(const_int 16))
(match_dup 0)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
+ })
(define_insn "*iorsi2_and_1_lshiftrt_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 1))))]
"TARGET_H8300H || TARGET_H8300S"
"shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
- [(set_attr "length" "6")
- (set_attr "cc" "clobber")])
+ [(set_attr "length" "6")])
(define_insn_and_split "*iorsi3_ashift_16_ashift_24"
[(set (match_operand:SI 0 "register_operand" "=r")
(const_int 16))
(ashift:SI (match_operand:SI 2 "register_operand" "r")
(const_int 24))))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(set (match_dup 3)
(ashift:SI (match_dup 0)
(const_int 16)))
(clobber (scratch:QI))])]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
- operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
+ })
(define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
[(set (match_operand:SI 0 "register_operand" "=&r")
(const_int 16711680))
(ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
(const_int 24))))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(set (match_dup 3)
(ashift:SI (match_dup 0)
(const_int 16)))
(clobber (scratch:QI))])]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ })
;; Used to add the exponent of a float.
"#")
(define_split
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
- (const_int 8388608))
- (match_dup 0)))
- (clobber (match_operand:SI 2 "register_operand" ""))])]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 8388608))
+ (match_dup 0)))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S)
- && flow2_completed
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
- && REGNO (operands[0]) != REGNO (operands[1])"
+ && epilogue_completed
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
+ && REGNO (operands[0]) != REGNO (operands[1])"
[(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
(plus:SI (mult:SI (match_dup 1)
(const_int 65536))
(match_dup 0)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
+ })
(define_split
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
- (const_int 8388608))
- (match_dup 0)))
- (clobber (match_operand:SI 2 "register_operand" ""))])]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 8388608))
+ (match_dup 0)))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S)
- && flow2_completed
- && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
- && REGNO (operands[0]) != REGNO (operands[1]))"
+ && epilogue_completed
+ && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
+ && REGNO (operands[0]) != REGNO (operands[1]))"
[(set (match_dup 2)
(match_dup 1))
(parallel [(set (match_dup 3)
(plus:SI (mult:SI (match_dup 2)
(const_int 65536))
(match_dup 0)))]
- "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
+ {
+ operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
+ })
;; ashift:SI
[(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
(const_int 7)))]
- "(TARGET_H8300H || TARGET_H8300S)"
+ "TARGET_H8300H || TARGET_H8300S"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 2)
(ashiftrt:SI (match_dup 0)
(const_int 1)))
(clobber (scratch:QI))])]
- "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+ {
+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ })
;; Storing a part of HImode to QImode.
""
"#"
""
- [(set (cc0)
- (match_dup 0))
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
""
"#"
""
- [(set (cc0)
- (match_dup 0))
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
(define_peephole2
- [(parallel
- [(set (match_operand:HI 0 "register_operand" "")
- (lshiftrt:HI (match_dup 0)
- (match_operand:HI 1 "const_int_operand" "")))
- (clobber (match_operand:HI 2 "" ""))])
+ [(parallel [(set (match_operand:HI 0 "register_operand" "")
+ (lshiftrt:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (clobber (match_operand:HI 2 "" ""))])
(set (match_dup 0)
(and:HI (match_dup 0)
(match_operand:HI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:HI (match_dup 0)
(const_int 255)))
- (parallel
- [(set (match_dup 0)
- (lshiftrt:HI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (lshiftrt:HI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
(define_peephole2
- [(parallel
- [(set (match_operand:HI 0 "register_operand" "")
- (ashift:HI (match_dup 0)
- (match_operand:HI 1 "const_int_operand" "")))
- (clobber (match_operand:HI 2 "" ""))])
+ [(parallel [(set (match_operand:HI 0 "register_operand" "")
+ (ashift:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (clobber (match_operand:HI 2 "" ""))])
(set (match_dup 0)
(and:HI (match_dup 0)
(match_operand:HI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:HI (match_dup 0)
(const_int 255)))
- (parallel
- [(set (match_dup 0)
- (ashift:HI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (ashift:HI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (lshiftrt:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))
- (clobber (match_operand:SI 2 "" ""))])
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (lshiftrt:SI (match_dup 0)
+ (match_operand:SI 1 "const_int_operand" "")))
+ (clobber (match_operand:SI 2 "" ""))])
(set (match_dup 0)
(and:SI (match_dup 0)
(match_operand:SI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 255)))
- (parallel
- [(set (match_dup 0)
- (lshiftrt:SI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (lshiftrt:SI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))
- (clobber (match_operand:SI 2 "" ""))])
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (ashift:SI (match_dup 0)
+ (match_operand:SI 1 "const_int_operand" "")))
+ (clobber (match_operand:SI 2 "" ""))])
(set (match_dup 0)
(and:SI (match_dup 0)
(match_operand:SI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 255)))
- (parallel
- [(set (match_dup 0)
- (ashift:SI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (ashift:SI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (lshiftrt:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))
- (clobber (match_operand:SI 2 "" ""))])
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (lshiftrt:SI (match_dup 0)
+ (match_operand:SI 1 "const_int_operand" "")))
+ (clobber (match_operand:SI 2 "" ""))])
(set (match_dup 0)
(and:SI (match_dup 0)
(match_operand:SI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 65535)))
- (parallel
- [(set (match_dup 0)
- (lshiftrt:SI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (lshiftrt:SI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))
- (clobber (match_operand:SI 2 "" ""))])
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (ashift:SI (match_dup 0)
+ (match_operand:SI 1 "const_int_operand" "")))
+ (clobber (match_operand:SI 2 "" ""))])
(set (match_dup 0)
(and:SI (match_dup 0)
(match_operand:SI 3 "const_int_operand" "")))]
[(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 65535)))
- (parallel
- [(set (match_dup 0)
- (ashift:SI (match_dup 0)
- (match_dup 1)))
- (clobber (match_dup 2))])]
+ (parallel [(set (match_dup 0)
+ (ashift:SI (match_dup 0) (match_dup 1)))
+ (clobber (match_dup 2))])]
"")
;; Convert a QImode push into an SImode push so that the
(plus:SI (reg:SI SP_REG) (const_int -4)))
(set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
(match_operand:QI 0 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE"
+ "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
[(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_dup 0))]
- "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ {
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ })
(define_peephole2
[(parallel [(set (reg:HI SP_REG)
(plus:HI (reg:HI SP_REG) (const_int -4)))
(set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
(match_operand:QI 0 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE"
+ "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
[(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
(match_dup 0))]
- "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ {
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ })
;; Convert a HImode push into an SImode push so that the
;; define_peephole2 below can cram multiple pushes into one stm.l.
(plus:SI (reg:SI SP_REG) (const_int -4)))
(set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
(match_operand:HI 0 "register_operand" ""))])]
- "TARGET_H8300S && !TARGET_NORMAL_MODE"
+ "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
[(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_dup 0))]
- "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ {
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ })
(define_peephole2
[(parallel [(set (reg:HI SP_REG)
(plus:HI (reg:HI SP_REG) (const_int -4)))
(set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
(match_operand:HI 0 "register_operand" ""))])]
- "TARGET_H8300S && TARGET_NORMAL_MODE"
+ "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
[(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
(match_dup 0))]
- "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ {
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ })
;; Cram four pushes into stm.l.
(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_operand:SI 3 "register_operand" ""))]
"TARGET_H8300S && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- [(parallel [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (const_int -16)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && REGNO (operands[2]) == REGNO (operands[0]) + 2
+ && REGNO (operands[3]) == REGNO (operands[0]) + 3
+ && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
+ [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
(match_dup 1))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
(match_dup 2))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
- (match_dup 3))])]
+ (match_dup 3))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (const_int -16)))])]
"")
(define_peephole2
(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
(match_operand:SI 3 "register_operand" ""))]
"TARGET_H8300S && TARGET_NORMAL_MODE
- && REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2
- && REGNO (operands[3]) == 3"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG)
- (const_int -16)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && REGNO (operands[2]) == REGNO (operands[0]) + 2
+ && REGNO (operands[3]) == REGNO (operands[0]) + 3
+ && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
+ [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
(match_dup 1))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
(match_dup 2))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
- (match_dup 3))])]
+ (match_dup 3))
+ (set (reg:HI SP_REG)
+ (plus:HI (reg:HI SP_REG)
+ (const_int -16)))])]
"")
;; Cram three pushes into stm.l.
(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_operand:SI 2 "register_operand" ""))]
"TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- [(parallel [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (const_int -12)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && REGNO (operands[2]) == REGNO (operands[0]) + 2
+ && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
+ [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
(match_dup 1))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
- (match_dup 2))])]
+ (match_dup 2))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (const_int -12)))])]
"")
(define_peephole2
(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
(match_operand:SI 2 "register_operand" ""))]
"TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0
- && REGNO (operands[1]) == 1
- && REGNO (operands[2]) == 2)
- || (REGNO (operands[0]) == 4
- && REGNO (operands[1]) == 5
- && REGNO (operands[2]) == 6))"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG)
- (const_int -12)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && REGNO (operands[2]) == REGNO (operands[0]) + 2
+ && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
+ [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
(match_dup 1))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
- (match_dup 2))])]
+ (match_dup 2))
+ (set (reg:HI SP_REG)
+ (plus:HI (reg:HI SP_REG)
+ (const_int -12)))])]
"")
;; Cram two pushes into stm.l.
(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_operand:SI 1 "register_operand" ""))]
"TARGET_H8300S && !TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- [(parallel [(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (const_int -8)))
- (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
+ [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
- (match_dup 1))])]
+ (match_dup 1))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (const_int -8)))])]
"")
(define_peephole2
(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
(match_operand:SI 1 "register_operand" ""))]
"TARGET_H8300S && TARGET_NORMAL_MODE
- && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
- || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
- || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
- [(parallel [(set (reg:HI SP_REG)
- (plus:HI (reg:HI SP_REG)
- (const_int -8)))
- (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
+ && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
+ && REGNO (operands[1]) == REGNO (operands[0]) + 1
+ && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
+ [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
(match_dup 0))
(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
- (match_dup 1))])]
+ (match_dup 1))
+ (set (reg:HI SP_REG)
+ (plus:HI (reg:HI SP_REG)
+ (const_int -8)))])]
"")
;; Turn
(match_operand:HI 2 "register_operand" "")))]
"REG_P (operands[0]) && REG_P (operands[2])
&& REGNO (operands[0]) != REGNO (operands[2])
- && (CONST_OK_FOR_J (INTVAL (operands[1]))
- || CONST_OK_FOR_L (INTVAL (operands[1]))
- || CONST_OK_FOR_N (INTVAL (operands[1])))"
+ && (satisfies_constraint_J (operands[1])
+ || satisfies_constraint_L (operands[1])
+ || satisfies_constraint_N (operands[1]))"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 2 "register_operand" "")))]
"(TARGET_H8300H || TARGET_H8300S)
- && REG_P (operands[0]) && REG_P (operands[2])
- && REGNO (operands[0]) != REGNO (operands[2])
- && (CONST_OK_FOR_L (INTVAL (operands[1]))
- || CONST_OK_FOR_N (INTVAL (operands[1])))"
+ && REG_P (operands[0]) && REG_P (operands[2])
+ && REGNO (operands[0]) != REGNO (operands[2])
+ && (satisfies_constraint_L (operands[1])
+ || satisfies_constraint_N (operands[1]))"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 2 "const_int_operand" "")))]
"(TARGET_H8300H || TARGET_H8300S)
- && REG_P (operands[0]) && REG_P (operands[1])
- && REGNO (operands[0]) != REGNO (operands[1])
- && !CONST_OK_FOR_L (INTVAL (operands[2]))
- && !CONST_OK_FOR_N (INTVAL (operands[2]))
- && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
- || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
- || INTVAL (operands[2]) == 0xffff
- || INTVAL (operands[2]) == 0xfffe)"
+ && REG_P (operands[0]) && REG_P (operands[1])
+ && REGNO (operands[0]) != REGNO (operands[1])
+ && !satisfies_constraint_L (operands[2])
+ && !satisfies_constraint_N (operands[2])
+ && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
+ || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
+ || INTVAL (operands[2]) == 0xffff
+ || INTVAL (operands[2]) == 0xfffe)"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_dup 0)
(match_operand 1 "incdec_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
(unspec:HI [(match_dup 0)
(match_dup 1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(match_operand 1 "incdec_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
(unspec:SI [(match_dup 0)
(match_dup 1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(define_peephole2
[(parallel [(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "register_operand" "")
- (const_int 1)
- (const_int 7)))
+ (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
+ (const_int 1)
+ (const_int 7))
+ (const_int 0)))
(clobber (scratch:QI))])
(set (pc)
(if_then_else (match_operator 1 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
- "(TARGET_H8300H || TARGET_H8300S)"
- [(set (cc0)
- (match_dup 0))
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[3] = ((GET_CODE (operands[1]) == EQ)
- ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
- : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));")
+ {
+ operands[3] = ((GET_CODE (operands[1]) == EQ)
+ ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
+ : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
+ })
;; The next three peephole2's will try to transform
;;
(and:SI (match_dup 2)
(const_int 255)))]
"(TARGET_H8300H || TARGET_H8300S)
- && !reg_overlap_mentioned_p (operands[2], operands[1])
- && REGNO (operands[0]) == REGNO (operands[2])"
+ && !reg_overlap_mentioned_p (operands[2], operands[1])
+ && REGNO (operands[0]) == REGNO (operands[2])"
[(set (match_dup 2)
(const_int 0))
(set (strict_low_part (match_dup 0))
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "general_operand" ""))
+ (match_operand:SI 1 "nonimmediate_operand" ""))
(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 255)))]
"(TARGET_H8300H || TARGET_H8300S)
- && !reg_overlap_mentioned_p (operands[0], operands[1])
- && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
+ && !reg_overlap_mentioned_p (operands[0], operands[1])
+ && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
+ && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
[(set (match_dup 0)
(const_int 0))
(set (strict_low_part (match_dup 2))
(match_dup 3))]
- "operands[2] = gen_lowpart (QImode, operands[0]);
- operands[3] = gen_lowpart (QImode, operands[1]);")
+ {
+ operands[2] = gen_lowpart (QImode, operands[0]);
+ operands[3] = gen_lowpart (QImode, operands[1]);
+ })
(define_peephole2
[(set (match_operand 0 "register_operand" "")
- (match_operand 1 "general_operand" ""))
+ (match_operand 1 "nonimmediate_operand" ""))
(set (match_operand:SI 2 "register_operand" "")
(and:SI (match_dup 2)
(match_operand:SI 3 "const_int_qi_operand" "")))]
"(TARGET_H8300H || TARGET_H8300S)
- && (GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode)
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && REGNO (operands[0]) == REGNO (operands[2])
- && !reg_overlap_mentioned_p (operands[2], operands[1])
- && !(GET_MODE (operands[1]) != QImode
- && GET_CODE (operands[1]) == MEM
- && MEM_VOLATILE_P (operands[1]))"
+ && (GET_MODE (operands[0]) == QImode
+ || GET_MODE (operands[0]) == HImode
+ || GET_MODE (operands[0]) == SImode)
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && REGNO (operands[0]) == REGNO (operands[2])
+ && !reg_overlap_mentioned_p (operands[2], operands[1])
+ && !(GET_MODE (operands[1]) != QImode
+ && GET_CODE (operands[1]) == MEM
+ && !offsettable_memref_p (operands[1]))
+ && !(GET_MODE (operands[1]) != QImode
+ && GET_CODE (operands[1]) == MEM
+ && MEM_VOLATILE_P (operands[1]))"
[(set (match_dup 2)
(const_int 0))
(set (strict_low_part (match_dup 4))
(set (match_dup 2)
(and:SI (match_dup 2)
(match_dup 6)))]
- "operands[4] = gen_lowpart (QImode, operands[0]);
- operands[5] = gen_lowpart (QImode, operands[1]);
- operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));")
+ {
+ operands[4] = gen_lowpart (QImode, operands[0]);
+ operands[5] = gen_lowpart (QImode, operands[1]);
+ operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
+ })
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_dup 0)
(match_operand:SI 2 "const_int_operand" "")))]
"(TARGET_H8300H || TARGET_H8300S)
- && !MEM_VOLATILE_P (operands[1])
- && (INTVAL (operands[2]) & ~0xffff) == 0
- && INTVAL (operands[2]) != 255"
+ && !MEM_VOLATILE_P (operands[1])
+ && offsettable_memref_p (operands[1])
+ && (INTVAL (operands[2]) & ~0xffff) == 0
+ && INTVAL (operands[2]) != 255"
[(set (match_dup 3)
(match_dup 4))
(set (match_dup 0)
(and:SI (match_dup 0)
(match_dup 2)))]
- "operands[3] = gen_lowpart (HImode, operands[0]);
- operands[4] = gen_lowpart (HImode, operands[1]);")
+ {
+ operands[3] = gen_lowpart (HImode, operands[0]);
+ operands[4] = gen_lowpart (HImode, operands[1]);
+ })
+
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+ [(match_scratch:QI 1 "r")
+ (set (cc0)
+ (compare (match_operand:QI 0 "memory_operand" "")
+ (const_int 0)))]
+ ""
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
+(define_peephole2
+ [(match_scratch:HI 1 "r")
+ (set (cc0)
+ (compare (match_operand:HI 0 "memory_operand" "")
+ (const_int 0)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
+(define_peephole2
+ [(match_scratch:SI 1 "r")
+ (set (cc0)
+ (compare (match_operand:SI 0 "memory_operand" "")
+ (const_int 0)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
;; the equivalent with shorter sequences. Here is the summary. Cases
;; dead 1 eq/ne dec.l
;; dead 2 eq/ne dec.l
;;
+;; dead 1 ge/lt shar.l
+;; dead 3 (H8S) ge/lt shar.l
+;;
;; dead 1 geu/ltu shar.l
;; dead 3 (H8S) geu/ltu shar.l
;;
+;; ---- 255 ge/lt mov.b
+;;
;; ---- 255 geu/ltu mov.b
;; Transform
(match_operand:HI 1 "incdec_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])"
+ && INTVAL (operands[1]) != 0
+ && peep2_reg_dead_p (1, operands[0])"
[(set (match_dup 0)
(unspec:HI [(match_dup 0)
(match_dup 4)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = GEN_INT (- INTVAL (operands[1]));")
+ {
+ operands[4] = GEN_INT (- INTVAL (operands[1]));
+ })
+
+;; Transform
+;;
+;; cmp.w #1,r0
+;; bgt .L1
+;;
+;; into
+;;
+;; shar.w r0
+;; bgt .L1
+
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:HI 0 "register_operand" "")
+ (match_operand:HI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtle_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
+ [(parallel [(set (match_dup 0)
+ (ashiftrt:HI (match_dup 0)
+ (match_dup 4)))
+ (clobber (scratch:QI))])
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 2)
+ (label_ref (match_dup 3))
+ (pc)))]
+ {
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ })
;; Transform
;;
(compare (match_operand:HI 0 "register_operand" "")
(match_operand:HI 1 "const_int_operand" "")))
(set (pc)
- (if_then_else (match_operator 2 "gtle_operator"
- [(cc0) (const_int 0)])
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && (INTVAL (operands[1]) == 1
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
|| (TARGET_H8300S && INTVAL (operands[1]) == 3))"
[(parallel [(set (match_dup 0)
(ashiftrt:HI (match_dup 0)
- (match_dup 5)))
+ (match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
- (if_then_else (match_dup 4)
+ (if_then_else (match_dup 5)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[4] = operands[2];
- break;
- }
- operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ {
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
;; Transform
;;
;; cmp.w #255,r0
-;; bhi .L1
+;; bgt .L1
;;
;; into
;;
;; mov.b r0h,r0h
-;; bne .L1
+;; bgt .L1
(define_peephole2
[(set (cc0)
(const_int 255)))
(set (pc)
(if_then_else (match_operator 1 "gtle_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0) (compare (and:HI (match_dup 0)
+ (const_int -256))
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_dup 2))
+ (pc)))]
+ "")
+
+;; Transform
+;;
+;; cmp.w #255,r0
+;; bhi .L1
+;;
+;; into
+;;
+;; mov.b r0h,r0h
+;; bne .L1
+
+(define_peephole2
[(set (cc0)
- (and:HI (match_dup 0)
- (const_int -256)))
+ (compare (match_operand:HI 0 "register_operand" "")
+ (const_int 255)))
+ (set (pc)
+ (if_then_else (match_operator 1 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0) (compare (and:HI (match_dup 0)
+ (const_int -256))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 3)
(label_ref (match_dup 2))
(pc)))]
- "switch (GET_CODE (operands[1]))
- {
- case GTU:
- operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[3] = operands[1];
- break;
- }")
+ {
+ operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
;; the equivalent with shorter sequences. Here is the summary. Cases
;; dead 0x40000000 (H8S) eq/ne rotl.l and dec.l
;; dead 0x80000000 eq/ne rotl.l and dec.l
;;
+;; live 1 ge/lt copy and shar.l
+;; live 3 (H8S) ge/lt copy and shar.l
+;;
;; live 1 geu/ltu copy and shar.l
;; live 3 (H8S) geu/ltu copy and shar.l
;;
+;; dead 1 ge/lt shar.l
+;; dead 3 (H8S) ge/lt shar.l
+;;
;; dead 1 geu/ltu shar.l
;; dead 3 (H8S) geu/ltu shar.l
;;
+;; dead 3 (H8/300H) ge/lt and.b and test
+;; dead 7 ge/lt and.b and test
+;; dead 15 ge/lt and.b and test
+;; dead 31 ge/lt and.b and test
+;; dead 63 ge/lt and.b and test
+;; dead 127 ge/lt and.b and test
+;; dead 255 ge/lt and.b and test
+;;
;; dead 3 (H8/300H) geu/ltu and.b and test
;; dead 7 geu/ltu and.b and test
;; dead 15 geu/ltu and.b and test
;; dead 127 geu/ltu and.b and test
;; dead 255 geu/ltu and.b and test
;;
-;; ---- 65535 geu/ltu mov.w
-
-;; For a small constant, it is cheaper to actually do the subtraction
-;; and then test the register.
+;; ---- 65535 ge/lt mov.w
+;;
+;; ---- 65535 geu/ltu mov.w
+
+;; Transform
+;;
+;; cmp.l #1,er0
+;; beq .L1
+;;
+;; into
+;;
+;; dec.l #1,er0
+;; beq .L1
(define_peephole2
[(set (cc0)
(match_operand:SI 1 "incdec_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])"
+ && INTVAL (operands[1]) != 0
+ && peep2_reg_dead_p (1, operands[0])"
[(set (match_dup 0)
(unspec:SI [(match_dup 0)
(match_dup 4)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = GEN_INT (- INTVAL (operands[1]));")
+ {
+ operands[4] = GEN_INT (- INTVAL (operands[1]));
+ })
+
+;; Transform
+;;
+;; cmp.l #65536,er0
+;; beq .L1
+;;
+;; into
+;;
+;; dec.l #1,e0
+;; beq .L1
(define_peephole2
[(set (cc0)
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && (INTVAL (operands[1]) == -131072
- || INTVAL (operands[1]) == -65536
- || INTVAL (operands[1]) == 65536
- || INTVAL (operands[1]) == 131072)"
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == -131072
+ || INTVAL (operands[1]) == -65536
+ || INTVAL (operands[1]) == 65536
+ || INTVAL (operands[1]) == 131072)"
[(set (match_dup 0)
(plus:SI (match_dup 0)
(match_dup 4)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = GEN_INT (- INTVAL (operands[1]));")
+ {
+ operands[4] = GEN_INT (- INTVAL (operands[1]));
+ })
-;; For certain (in)equality comparisons against a constant, we can
-;; XOR the register with the constant, and test the register against
-;; 0.
+;; Transform
+;;
+;; cmp.l #100,er0
+;; beq .L1
+;;
+;; into
+;;
+;; xor.b #100,er0
+;; mov.l er0,er0
+;; beq .L1
(define_peephole2
[(set (cc0)
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
- || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
- || INTVAL (operands[1]) == 0x0000ffff)
- && INTVAL (operands[1]) != 1
- && INTVAL (operands[1]) != 2"
+ && peep2_reg_dead_p (1, operands[0])
+ && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
+ || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
+ || INTVAL (operands[1]) == 0x0000ffff)
+ && INTVAL (operands[1]) != 0
+ && INTVAL (operands[1]) != 1
+ && INTVAL (operands[1]) != 2"
[(set (match_dup 0)
(xor:SI (match_dup 0)
(match_dup 1)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
"")
+;; Transform
+;;
+;; cmp.l #-100,er0
+;; beq .L1
+;;
+;; into
+;;
+;; xor.b #99,er0
+;; not.l er0
+;; beq .L1
+
(define_peephole2
[(set (cc0)
(compare (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && ((INTVAL (operands[1]) | 0x00ff) == -1
+ && peep2_reg_dead_p (1, operands[0])
+ && ((INTVAL (operands[1]) | 0x00ff) == -1
|| (INTVAL (operands[1]) | 0xff00) == -1)
- && INTVAL (operands[1]) != -1
- && INTVAL (operands[1]) != -2"
+ && INTVAL (operands[1]) != -1
+ && INTVAL (operands[1]) != -2"
[(set (match_dup 0)
(xor:SI (match_dup 0)
(match_dup 4)))
(set (match_dup 0)
(not:SI (match_dup 0)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);")
+ {
+ operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);
+ })
+
+;; Transform
+;;
+;; cmp.l #-2147483648,er0
+;; beq .L1
+;;
+;; into
+;;
+;; rotl.l er0
+;; dec.l #1,er0
+;; beq .L1
(define_peephole2
[(set (cc0)
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && (INTVAL (operands[1]) == -2147483647 - 1
- || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == -2147483647 - 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
[(set (match_dup 0)
(rotate:SI (match_dup 0)
(match_dup 4)))
(unspec:SI [(match_dup 0)
(const_int -1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);")
+ {
+ operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);
+ })
;; Transform
;;
;; cmp.l #1,er0
-;; bhi .L1
+;; bgt .L1
;;
;; into
;;
;; mov.l er0,er1
;; shar.l er1
-;; bne .L1
+;; bgt .L1
;; We avoid this transformation if we see more than one copy of the
;; same compare insn immediately before this one.
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 2 "gtle_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && !peep2_reg_dead_p (1, operands[0])
- && (INTVAL (operands[1]) == 1
+ && !peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
|| (TARGET_H8300S && INTVAL (operands[1]) == 3))
- && !same_cmp_preceding_p (insn)"
+ && !same_cmp_preceding_p (insn)"
[(set (match_dup 4)
(match_dup 0))
(parallel [(set (match_dup 4)
(ashiftrt:SI (match_dup 4)
- (match_dup 6)))
+ (match_dup 5)))
(clobber (scratch:QI))])
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 2)
+ (label_ref (match_dup 3))
+ (pc)))]
+ {
+ operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ })
+
+;; Transform
+;;
+;; cmp.l #1,er0
+;; bhi .L1
+;;
+;; into
+;;
+;; mov.l er0,er1
+;; shar.l er1
+;; bne .L1
+
+;; We avoid this transformation if we see more than one copy of the
+;; same compare insn immediately before this one.
+
+(define_peephole2
+ [(match_scratch:SI 4 "r")
(set (cc0)
- (match_dup 4))
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
(set (pc)
- (if_then_else (match_dup 5)
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && !peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))
+ && !same_cmp_preceding_p (insn)"
+ [(set (match_dup 4)
+ (match_dup 0))
+ (parallel [(set (match_dup 4)
+ (ashiftrt:SI (match_dup 4)
+ (match_dup 5)))
+ (clobber (scratch:QI))])
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 6)
+ (label_ref (match_dup 3))
+ (pc)))]
+ {
+ operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
+
+;; Transform
+;;
+;; cmp.l #1,er0
+;; bgt .L1
+;;
+;; into
+;;
+;; shar.l er0
+;; bgt .L1
+
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtle_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
+ [(parallel [(set (match_dup 0)
+ (ashiftrt:SI (match_dup 0)
+ (match_dup 4)))
+ (clobber (scratch:QI))])
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[5] = operands[2];
- break;
- }
- operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ {
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ })
;; Transform
;;
(compare (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
- (if_then_else (match_operator 2 "gtle_operator"
- [(cc0) (const_int 0)])
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && (INTVAL (operands[1]) == 1
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
|| (TARGET_H8300S && INTVAL (operands[1]) == 3))"
[(parallel [(set (match_dup 0)
(ashiftrt:SI (match_dup 0)
- (match_dup 5)))
+ (match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 5)
+ (label_ref (match_dup 3))
+ (pc)))]
+ {
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
+
+;; Transform
+;;
+;; cmp.l #15,er0
+;; bgt .L1
+;;
+;; into
+;;
+;; and #240,r0l
+;; mov.l er0,er0
+;; bgt .L1
+
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtle_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 3
+ || INTVAL (operands[1]) == 7
+ || INTVAL (operands[1]) == 15
+ || INTVAL (operands[1]) == 31
+ || INTVAL (operands[1]) == 63
+ || INTVAL (operands[1]) == 127
+ || INTVAL (operands[1]) == 255)"
+ [(set (match_dup 0)
+ (and:SI (match_dup 0)
+ (match_dup 4)))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
- (if_then_else (match_dup 4)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[4] = operands[2];
- break;
- }
- operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ {
+ operands[4] = GEN_INT (~INTVAL (operands[1]));
+ })
;; Transform
;;
(compare (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" "")))
(set (pc)
- (if_then_else (match_operator 2 "gtle_operator"
- [(cc0) (const_int 0)])
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && peep2_reg_dead_p (1, operands[0])
- && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
- || INTVAL (operands[1]) == 7
- || INTVAL (operands[1]) == 15
- || INTVAL (operands[1]) == 31
- || INTVAL (operands[1]) == 63
- || INTVAL (operands[1]) == 127
- || INTVAL (operands[1]) == 255)"
+ && peep2_reg_dead_p (1, operands[0])
+ && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
+ || INTVAL (operands[1]) == 7
+ || INTVAL (operands[1]) == 15
+ || INTVAL (operands[1]) == 31
+ || INTVAL (operands[1]) == 63
+ || INTVAL (operands[1]) == 127
+ || INTVAL (operands[1]) == 255)"
[(set (match_dup 0)
(and:SI (match_dup 0)
- (match_dup 5)))
- (set (cc0)
- (match_dup 0))
+ (match_dup 4)))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
- (if_then_else (match_dup 4)
+ (if_then_else (match_dup 5)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[4] = operands[2];
- break;
- }
- operands[5] = GEN_INT (~INTVAL (operands[1]));")
-
-;; Transform A <= 65535 to (A & 0xffff0000) == 0.
+ {
+ operands[4] = GEN_INT (~INTVAL (operands[1]));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
+
+;; Transform
+;;
+;; cmp.l #65535,er0
+;; bgt .L1
+;;
+;; into
+;;
+;; mov.l e0,e0
+;; bgt .L1
(define_peephole2
[(set (cc0)
(const_int 65535)))
(set (pc)
(if_then_else (match_operator 1 "gtle_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0) (compare (and:SI (match_dup 0)
+ (const_int -65536))
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_dup 2))
+ (pc)))]
+ "")
+
+;; Transform
+;;
+;; cmp.l #65535,er0
+;; bhi .L1
+;;
+;; into
+;;
+;; mov.l e0,e0
+;; bne .L1
+
+(define_peephole2
[(set (cc0)
- (and:SI (match_dup 0)
- (const_int -65536)))
+ (compare (match_operand:SI 0 "register_operand" "")
+ (const_int 65535)))
+ (set (pc)
+ (if_then_else (match_operator 1 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0) (compare (and:SI (match_dup 0)
+ (const_int -65536))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 3)
(label_ref (match_dup 2))
(pc)))]
- "switch (GET_CODE (operands[1]))
- {
- case GTU:
- operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[3] = operands[1];
- break;
- }")
-
-;; For constants like -1, -2, 1, 2, it is still cheaper to make a copy
-;; of the register being tested, do the subtraction on the copy, and
-;; then test the copy. We avoid this transformation if we see more
-;; than one copy of the same compare insn.
+ {
+ operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
+ VOIDmode, cc0_rtx, const0_rtx);
+ })
+
+;; Transform
+;;
+;; cmp.l #1,er0
+;; beq .L1
+;;
+;; into
+;;
+;; mov.l er0,er1
+;; dec.l #1,er1
+;; beq .L1
+
+;; We avoid this transformation if we see more than one copy of the
+;; same compare insn.
(define_peephole2
[(match_scratch:SI 4 "r")
(match_operand:SI 1 "incdec_operand" "")))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
- && !peep2_reg_dead_p (1, operands[0])
- && !same_cmp_following_p (insn)"
+ && INTVAL (operands[1]) != 0
+ && !peep2_reg_dead_p (1, operands[0])
+ && !same_cmp_following_p (insn)"
[(set (match_dup 4)
(match_dup 0))
(set (match_dup 4)
(unspec:SI [(match_dup 4)
(match_dup 5)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[5] = GEN_INT (- INTVAL (operands[1]));")
-
+ {
+ operands[5] = GEN_INT (- INTVAL (operands[1]));
+ })
;; Narrow the mode of testing if possible.
(define_peephole2
[(set (match_operand:HI 0 "register_operand" "")
(and:HI (match_dup 0)
(match_operand:HI 1 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 4)
(and:QI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
- operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
+ {
+ operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
+ operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
+ })
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_dup 0)
(match_operand:SI 1 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 4)
(and:QI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
- operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
+ {
+ operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
+ operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
+ })
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_dup 0)
(match_operand:SI 1 "const_int_hi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))]
"peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 4)
(and:HI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
(pc)))]
- "operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
- operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);")
+ {
+ operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
+ operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);
+ })
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(set (match_dup 0)
(xor:SI (match_dup 0)
(match_operand:SI 2 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 4 "eqne_operator"
- [(cc0) (const_int 0)])
+ [(cc0) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"peep2_reg_dead_p (3, operands[0])
(set (match_dup 5)
(xor:QI (match_dup 5)
(match_dup 7)))
- (set (cc0)
- (match_dup 5))
+ (set (cc0) (compare (match_dup 5)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
(label_ref (match_dup 3))
(pc)))]
- "operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
- operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
- operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);")
+ {
+ operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
+ operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
+ operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
;; These triggers right at the end of allocation of locals in the
;; prologue (and possibly at other places).
-;; stack adjustment of -8, generate one push
+;; stack adjustment of -4, generate one push
;;
-;; before : 14 bytes, 22 clocks
-;; after : 8 bytes, 20 clocks
+;; before : 6 bytes, 10 clocks
+;; after : 4 bytes, 10 clocks
(define_peephole2
[(set (reg:SI SP_REG)
(set (mem:SI (reg:SI SP_REG))
(match_operand:SI 0 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) != SP_REG"
+ && REGNO (operands[0]) != SP_REG"
[(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_dup 0))]
"")
(set (mem:SI (reg:SI SP_REG))
(match_operand:SI 0 "register_operand" ""))]
"(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
- && REGNO (operands[0]) != SP_REG"
+ && REGNO (operands[0]) != SP_REG"
[(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(const_int -4)))
(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
(match_dup 0))]
"")
+
+;; Transform
+;;
+;; mov dst,reg
+;; op src,reg
+;; mov reg,dst
+;;
+;; into
+;;
+;; op src,dst
+;;
+;; if "reg" dies at the end of the sequence.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "memory_operand" ""))
+ (set (match_dup 0)
+ (match_operator 2 "h8sx_binary_memory_operator"
+ [(match_dup 0)
+ (match_operand 3 "h8300_src_operand" "")]))
+ (set (match_operand 4 "memory_operand" "")
+ (match_dup 0))]
+ "0 /* Disable because it breaks compiling fp-bit.c. */
+ && TARGET_H8300SX
+ && peep2_reg_dead_p (3, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[3])
+ && !reg_overlap_mentioned_p (operands[0], operands[4])
+ && h8sx_mergeable_memrefs_p (operands[4], operands[1])"
+ [(set (match_dup 4)
+ (match_dup 5))]
+ {
+ operands[5] = shallow_copy_rtx (operands[2]);
+ XEXP (operands[5], 0) = operands[1];
+ })
+
+;; Transform
+;;
+;; mov src,reg
+;; op reg,dst
+;;
+;; into
+;;
+;; op src,dst
+;;
+;; if "reg" dies in the second insn.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "h8300_src_operand" ""))
+ (set (match_operand 2 "h8300_dst_operand" "")
+ (match_operator 3 "h8sx_binary_memory_operator"
+ [(match_operand 4 "h8300_dst_operand" "")
+ (match_dup 0)]))]
+ "0 /* Disable because it breaks compiling fp-bit.c. */
+ && TARGET_H8300SX
+ && peep2_reg_dead_p (2, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[4])"
+ [(set (match_dup 2)
+ (match_dup 5))]
+ {
+ operands[5] = shallow_copy_rtx (operands[3]);
+ XEXP (operands[5], 1) = operands[1];
+ })
+
+;; Transform
+;;
+;; mov dst,reg
+;; op reg
+;; mov reg,dst
+;;
+;; into
+;;
+;; op dst
+;;
+;; if "reg" dies at the end of the sequence.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "memory_operand" ""))
+ (set (match_dup 0)
+ (match_operator 2 "h8sx_unary_memory_operator"
+ [(match_dup 0)]))
+ (set (match_operand 3 "memory_operand" "")
+ (match_dup 0))]
+ "TARGET_H8300SX
+ && peep2_reg_dead_p (3, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[3])
+ && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
+ [(set (match_dup 3)
+ (match_dup 4))]
+ {
+ operands[4] = shallow_copy_rtx (operands[2]);
+ XEXP (operands[4], 0) = operands[1];
+ })
+
+;; Transform
+;;
+;; mov src1,reg
+;; cmp reg,src2
+;;
+;; into
+;;
+;; cmp src1,src2
+;;
+;; if "reg" dies in the comparison.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "h8300_dst_operand" ""))
+ (set (cc0)
+ (compare (match_dup 0)
+ (match_operand 2 "h8300_src_operand" "")))]
+ "TARGET_H8300SX
+ && peep2_reg_dead_p (2, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && operands[2] != const0_rtx"
+ [(set (cc0)
+ (compare (match_dup 1)
+ (match_dup 2)))])
+
+;; Likewise for the second operand.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "h8300_src_operand" ""))
+ (set (cc0)
+ (compare (match_operand 2 "h8300_dst_operand" "")
+ (match_dup 0)))]
+ "TARGET_H8300SX
+ && peep2_reg_dead_p (2, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[2])"
+ [(set (cc0)
+ (compare (match_dup 2)
+ (match_dup 1)))])
+
+;; Combine two moves.
+
+(define_peephole2
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "h8300_src_operand" ""))
+ (set (match_operand 2 "h8300_dst_operand" "")
+ (match_dup 0))]
+ "TARGET_H8300SX
+ && peep2_reg_dead_p (2, operands[0])
+ && !reg_overlap_mentioned_p (operands[0], operands[2])"
+ [(set (match_dup 2)
+ (match_dup 1))])
+
+