Commit f82eca4d by Steve Chamberlain

New File.

From-SVN: r3630
parent 43517f90
;;- Machine description for the Hitachi H8/300 for the GNU C compiler
;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
;; This file is part of GNU CC.
;; GNU CC 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)
;; any later version.
;; GNU CC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
;; The original PO technology requires these to be ordered by speed,
;; so that assigner will pick the fastest.
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
(define_attr "type" "branch,return,call,arith,move,float,multi"
(const_string "arith"))
;; The size of instructions in bytes.
(define_attr "length" ""
(cond [(eq_attr "type" "branch")
(if_then_else (and (ge (minus (pc) (match_dup 0))
(const_int -128))
(le (minus (pc) (match_dup 0))
(const_int 128)))
(const_int 2)
(const_int 6))
(eq_attr "type" "move") (const_int 4)
(eq_attr "type" "return") (const_int 2)
(eq_attr "type" "float") (const_int 12)
(eq_attr "type" "call") (const_int 4)]
(const_int 200)))
(define_attr "cc" "none,clobber,none_0hit,set,compare,whoops"
(const_string "whoops"))
;; ----------------------------------------------------------------------
;; move instructions
;; ----------------------------------------------------------------------
;; movhi
(define_insn ""
[(set (match_operand:HI 0 "push_operand" "=<")
(match_operand:HI 1 "register_operand" "ra"))]
""
"mov.w %T1,%T0"
[(set_attr "type" "move")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r,o,<"))
(match_operand:HI 1 "general_operand_src" "I,r,io,r,r"))]
""
"@
sub.w %T0,%T0
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "type" "move")
(set_attr "length" "2,2,4,4,2")
(set_attr "cc" "set")])
(define_insn ""
[(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,ra,o,<")
(match_operand:HI 1 "general_operand_src" "I,ra,ion,ra,ra"))]
""
"@
sub.w %T0,%T0
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "type" "move")
(set_attr "length" "2,2,4,4,2")
(set_attr "cc" "set")])
(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);
}")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=&ra")
(plus:HI (match_operand:HI 1 "general_operand_src" "g")
(match_operand:HI 2 "register_operand" "ra")))]
""
"mov.w %T1,%T0\;add.w %T2,%T0"
[(set_attr "type" "arith")
(set_attr "length" "6")
(set_attr "cc" "set")])
;; movqi
(define_insn ""
[(set (match_operand:QI 0 "push_operand" "=<")
(match_operand:QI 1 "register_operand" "r"))]
""
"mov.w %T1,%T0"
[(set_attr "type" "move")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "movstrictqi"
[(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<"))
(match_operand:QI 1 "general_operand_src" "I,r,io,r,r"))]
""
"@
sub.b %X0,%X0
mov.b %X1,%X0
mov.b %X1,%X0
mov.b %X1,%X0
mov.b %X1,%X0"
[(set_attr "type" "move")
(set_attr "length" "2,2,4,4,2")
(set_attr "cc" "set")])
(define_insn ""
[(set (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<")
(match_operand:QI 1 "general_operand_src" "I,r,io,r,r"))]
""
"@
sub.b %X0,%X0
mov.b %X1,%X0
mov.b %X1,%X0
mov.b %X1,%X0
mov.b %X1,%X0"
[(set_attr "type" "move")
(set_attr "length" "2,2,4,4,2")
(set_attr "cc" "set")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand_dst" "")
(match_operand:QI 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);
}")
;; movsi
(define_insn ""
[(set (match_operand:SI 0 "general_operand_dst" "=l,l,l,o,<")
(match_operand:SI 1 "general_operand_src" "I,l,ion,l,l"))]
""
"*
{
int rn = -1;
switch (which_alternative)
{
case 0:
return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
case 1:
return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
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
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\";
}
}"
[(set_attr "type" "move")
(set_attr "length" "4,4,8,8,4")
(set_attr "cc" "clobber")])
(define_insn ""
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "register_operand" "l"))]
""
"mov.w %f1,%T0\;mov.w %e1,%T0"
[(set_attr "type" "move")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand_dst" "")
(match_operand:SI 1 "general_operand_src" ""))]
""
"if (domovsi (operands)) DONE;")
(define_insn ""
[(set (match_operand:SF 0 "general_operand_dst" "=l,l,l,o,<")
(match_operand:SF 1 "general_operand_src" "I,l,ion,l,l"))]
""
"*
{
/* This is a copy of the movsi stuff. */
int rn = -1;
switch (which_alternative)
{
case 0:
return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
case 1:
return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
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
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\";
}
}"
[(set_attr "type" "move")
(set_attr "length" "4,4,8,8,4")
(set_attr "cc" "clobber")])
(define_insn ""
[(set (match_operand:SF 0 "push_operand" "=<")
(match_operand:SF 1 "register_operand" "l"))]
""
"mov.w %f1,%T0\;mov.w %e1,%T0"
[(set_attr "type" "move")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_expand "movsf"
[(set (match_operand:SF 0 "general_operand_dst" "")
(match_operand:SF 1 "general_operand_src" ""))]
""
"if (domovsi (operands)) DONE;")
;; Block move
(define_expand "movstrhi"
[(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
(mem:BLK (match_operand:BLK 1 "general_operand" "")))
(use (match_operand:HI 2 "general_operand" ""))
(use (match_operand:HI 3 "immediate_operand" ""))
(clobber (match_dup 3))
])]
""
"
{
rtx src_ptr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
enum machine_mode mode = INTVAL (operands[3]) >=2 ? HImode : QImode;
rtx tmpreg = gen_reg_rtx (mode);
rtx increment = mode == QImode ? const1_rtx : const2_rtx;
rtx length = operands[2];
rtx label = gen_label_rtx ();
rtx end_src_ptr = gen_reg_rtx (Pmode);
emit_insn (gen_rtx (SET, VOIDmode, end_src_ptr,
gen_rtx (PLUS, Pmode, src_ptr, length)));
emit_label (label);
emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr));
emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg);
emit_insn (gen_rtx (SET, VOIDmode, src_ptr,
gen_rtx (PLUS, Pmode, src_ptr, increment)));
emit_insn (gen_rtx (SET, VOIDmode, dst_ptr,
gen_rtx (PLUS, Pmode, dst_ptr, increment)));
emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
gen_rtx (COMPARE, HImode, src_ptr, end_src_ptr)));
emit_jump_insn (gen_bne (label));
DONE;
}
")
;; ----------------------------------------------------------------------
;; Test instructions
;; ----------------------------------------------------------------------
(define_insn "tstqi"
[(set (cc0)
(match_operand:QI 0 "register_operand" "ra"))]
""
"cmp.b #0,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "tsthi"
[(set (cc0)
(match_operand:HI 0 "register_operand" "ra"))]
""
"mov.w %T0,%T0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "cmphi"
[(set (cc0)
(compare:HI (match_operand:HI 0 "register_operand" "ra")
(match_operand:HI 1 "register_operand" "ra")))]
""
"cmp.w %T1,%T0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "compare")])
(define_insn "cmpqi"
[(set (cc0)
(compare:QI (match_operand:QI 0 "register_operand" "ra")
(match_operand:QI 1 "nonmemory_operand" "rai")))]
""
"cmp.b %X1,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "compare")])
;; ----------------------------------------------------------------------
;; Add instructions
;; ----------------------------------------------------------------------
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,ra,r,ra")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:HI 2 "nonmemory_operand" "K,M,L,N,n,ra")))]
""
"@
adds %T2,%T0
adds #2,%T0\;adds %C2,%T0
subs %M2,%T0
subs #2,%T0\;subs %M2,%T0
add.b %s2,%s0\;addx %t2,%t0
add.w %T2,%T0"
[(set_attr "type" "multi,multi,multi,multi,multi,arith")
(set_attr "length" "2,4,2,4,4,2")
(set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set")])
(define_expand "addhi3"
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))]
""
"
{
if (operands[0] != operands[1])
emit_move_insn (operands[0], operands[1]);
}")
(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" "ri")))]
""
"add.b %X2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=l,l")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0")
(match_operand:SI 2 "nonmemory_operand" "l,n")))
(clobber (match_operand:HI 3 "register_operand" "=&l,l"))]
""
"@
add %w2,%w0\;addx %x2,%x0\;addx %y2,%y0\;addx %z2,%z0
add.w %f2,%f0\;addx %y2,%y0\;addx %z2,%z0"
[(set_attr "type" "multi")
(set_attr "length" "8,6")
(set_attr "cc" "clobber")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=l,l")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0")
(match_operand:SI 2 "nonmemory_operand" "n,r")))]
""
"@
add %w2,%w0\;addx %x2,%x0\;addx %y2,%y0\;addx %z2,%z0
add.w %f2,%f0\;addx %y2,%y0\;addx %z2,%z0"
[(set_attr "type" "arith")
(set_attr "length" "8,6")
(set_attr "cc" "clobber")])
(define_expand "addsi3"
[(set (match_dup 3) (match_operand:SI 1 "register_operand" ""))
(set (match_dup 3)
(plus:SI (match_dup 3)
(match_operand:SI 2 "nonmemory_operand" "")))
(set (match_operand:SI 0 "register_operand" "") (match_dup 3))]
""
"
{
operands[3] = gen_rtx (REG, SImode, 0);
}")
;; ----------------------------------------------------------------------;
;; Subtract instructions
;; ----------------------------------------------------------------------
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,r")
(minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
(match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))]
""
"@
subs %T2,%T0
subs #2,%T0\;subs %E2,%T0
sub.w %T2,%T0
add.b %E2,%s0\;addx %F2,%t0 ; -%0"
[(set_attr "type" "multi")
(set_attr "length" "2,4,2,4")
(set_attr "cc" "none_0hit,none_0hit,set,clobber")])
(define_insn "subqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(minus:QI (match_operand:QI 1 "register_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "r,i")))]
""
"@
sub.b %X2,%X0
add.b %G2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_expand "subhi3"
[(set (match_operand:HI 0 "register_operand" "")
(minus:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))]
""
"
{
if (operands[0] != operands[1])
emit_move_insn (operands[0], operands[1]);
}")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=l")
(minus:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "l")))]
""
"sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0"
[(set_attr "type" "arith")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_expand "subsi3"
[(set (match_dup 3) (match_operand:SI 1 "register_operand" ""))
(set (match_dup 3)
(minus:SI (match_dup 3)
(match_operand:SI 2 "nonmemory_operand" "")))
(set (match_operand:SI 0 "register_operand" "") (match_dup 3))]
""
"operands[3] = gen_rtx (REG, SImode, 0);")
;; ----------------------------------------------------------------------
;; Multiply instruction
;; ----------------------------------------------------------------------
(define_insn "umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "register_operand" "r")))]
""
"mulxu %X2,%T0"
[(set_attr "type" "multi")
(set_attr "length" "2")
(set_attr "cc" "none_0hit")])
;; ----------------------------------------------------------------------
;; Divide instructions
;; ----------------------------------------------------------------------
(define_insn "udivqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(udiv:QI (match_operand:HI 1 "general_operand" "0")
(match_operand:QI 2 "register_operand" "r")))]
""
"divxu %X2,%T0"
[(set_attr "type" "multi")
(set_attr "length" "2")
(set_attr "cc" "clobber")])
(define_insn "divqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(div:QI (match_operand:HI 1 "general_operand" "0")
(match_operand:QI 2 "register_operand" "r")))]
""
"divxu %X2,%T0"
[(set_attr "type" "multi")
(set_attr "length" "2")
(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
;; And instructions
;; ----------------------------------------------------------------------
(define_insn "andqi3"
[(set (match_operand:QI 0 "general_operand" "=r")
(and:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rn")))]
""
"and %X2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (match_operand:HI 1 "register_operand" "%0")
(match_operand:HI 2 "general_operand" "ri")))]
""
"and %s2,%s0\;and %t2,%t0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
;; Or instructions
;; ----------------------------------------------------------------------
(define_insn "iorqi3"
[(set (match_operand:QI 0 "general_operand" "=r,U")
(ior:QI (match_operand:QI 1 "general_operand" "%0,0")
(match_operand:QI 2 "general_operand" "rn,P")))]
""
"@
or %X2,%X0
bset %V2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2,4")
(set_attr "cc" "set,none_0hit")])
(define_insn "iorhi3"
[(set (match_operand:HI 0 "general_operand" "=r,r")
(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
(match_operand:HI 2 "general_operand" "J,ri")))]
""
"@
or %s2,%s0
or %s2,%s0\;or %t2,%t0"
[(set_attr "type" "multi")
(set_attr "length" "2,4")
(set_attr "cc" "clobber,clobber")])
;; ----------------------------------------------------------------------
;; Xor instructions
;; ----------------------------------------------------------------------
(define_insn "xorqi3"
[(set (match_operand:QI 0 "general_operand" "=r")
(xor:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "nonmemory_operand" "ri")))]
""
"xor %X2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "xorhi3"
[(set (match_operand:HI 0 "general_operand" "=r")
(xor:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "nonmemory_operand" "ri")))]
""
"xor %s2,%s0\;xor %t2,%t0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
;; Negation instructions
;; ----------------------------------------------------------------------
(define_insn "negqi2"
[(set (match_operand:QI 0 "register_operand" "=r")
(neg:QI (match_operand:QI 1 "general_operand" "0")))]
""
"neg %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_expand "neghi2"
[(set (match_dup 2)
(not:HI (match_operand:HI 1 "register_operand" "r")))
(set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
(set (match_operand:HI 0 "register_operand" "=r")
(match_dup 2))]
""
"operands[2] = gen_reg_rtx (HImode);")
(define_expand "negsi2"
[(set (match_dup 2)
(not:SI (match_operand:SI 1 "register_operand" "r")))
(set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
(set (match_operand:SI 0 "register_operand" "=r")
(match_dup 2))]
""
"operands[2] = gen_reg_rtx (SImode);")
;; ----------------------------------------------------------------------
;; Not instructions
;; ----------------------------------------------------------------------
(define_insn "one_cmplqi2"
[(set (match_operand:QI 0 "register_operand" "=r")
(not:QI (match_operand:QI 1 "general_operand" "0")))]
""
"not %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "one_cmplhi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(not:HI (match_operand:HI 1 "general_operand" "0")))]
""
"not %s0\;not %t0"
[(set_attr "type" "arith")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "general_operand" "0")))]
""
"not %w0\;not %x0\;not %y0\;not %z0"
[(set_attr "type" "arith")
(set_attr "length" "8")
(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
;; Conditional branches
;; ----------------------------------------------------------------------
(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)))]
""
"")
(define_expand "bgt"
[(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"")
(define_expand "bgtu"
[(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"")
(define_expand "beq"
[(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"")
(define_expand "bne"
[(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"")
(define_insn ""
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"*
{
if (get_attr_length (insn) == 2)
return \"b%j1 %l0\";
else
return \"b%k1 %L0\;jmp @%l0\;%L0:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "none")])
(define_insn ""
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"*
{
if (get_attr_length (insn) == 2)
return \"b%k1 %l0\";
else
return \"b%j1 %L0\;jmp @%l0\;%L0:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "none")])
;; ----------------------------------------------------------------------
;; Unconditional branches
;; ----------------------------------------------------------------------
(define_insn "jump"
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
"*
{
if (get_attr_length (insn) == 2)
return \"bra %l0\";
else
return \"jmp @%l0\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "none")])
(define_insn "tablejump"
[(set (pc) (match_operand:HI 0 "register_operand" ""))
(use (label_ref (match_operand 1 "" "")))]
""
"jmp @%0"
[(set_attr "type" "branch")
(set_attr "cc" "none")
(set_attr "length" "2")])
;; Call subroutine with no return value.
(define_insn "call"
[(call (match_operand:QI 0 "memory_operand" "o")
(match_operand:HI 1 "general_operand" "g"))]
""
"jsr %0"
[(set_attr "type" "call")
(set_attr "cc" "clobber")
(set_attr "length" "4")])
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
(define_insn "call_value"
[(set (match_operand 0 "" "=r")
(call (match_operand:QI 1 "memory_operand" "o")
(match_operand:HI 2 "general_operand" "g")))]
""
"jsr %1"
[(set_attr "type" "call")
(set_attr "cc" "clobber")
(set_attr "length" "4")])
(define_insn "nop"
[(const_int 0)]
""
"nop"
[(set_attr "type" "multi")
(set_attr "cc" "none")
(set_attr "length" "2")])
(define_insn "indirect_jump"
[(set (pc) (match_operand:HI 0 "register_operand" "r"))]
""
"jmp @%0"
[(set_attr "type" "branch")
(set_attr "cc" "none")
(set_attr "length" "2")])
;; -----------------------------------------------------------------
;; Shifts
;; -----------------------------------------------------------------
;; All H8 shifts go one bit at a time, here they are defined with names
;; so can use them in the expands..
;; QI BIT SHIFTS
(define_insn "ashlqi3_one"
[(set (match_operand:QI 0 "register_operand" "=r")
(ashift:QI (match_operand:QI 1 "register_operand" "0")
(const_int 1)))]
""
"shal %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "ashrqi3_one"
[(set (match_operand:QI 0 "register_operand" "=r")
(ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
(const_int 1)))]
""
"shar %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_insn "lshrqi3_one"
[(set (match_operand:QI 0 "register_operand" "=r")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
(const_int 1)))]
""
"shlr %X0"
[(set_attr "type" "arith")
(set_attr "length" "2")
(set_attr "cc" "set")])
(define_expand "ashlqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(ashift:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "rn")))]
""
"
{
if (can_shift (ASHIFT, operands, gen_ashlqi3_one, 4, 0))
DONE;
else
FAIL;
}")
(define_expand "ashrqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "rn")))]
""
"
{
if (can_shift (ASHIFTRT, operands, gen_ashrqi3_one, 4, 0))
DONE;
else
FAIL;
}")
(define_expand "lshrqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "rn")))]
""
"
{
if (can_shift (LSHIFTRT, operands, gen_lshrqi3_one, 4, 0))
DONE;
else
FAIL;
}")
;; HI BIT SHIFTS
(define_insn "ashlhi3_one"
[(set (match_operand:HI 0 "register_operand" "=r")
(ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 1)))]
""
"add.w %T1,%T0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "set")])
(define_insn "ashlhi3_eight"
[(set (match_operand:HI 0 "register_operand" "=r")
(ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 8)))]
""
"mov.b %s1,%t0\;mov.b #0,%s0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_expand "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "")
(ashift:HI
(match_operand:HI 1 "general_operand_src" "")
(match_operand:HI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (ASHIFT, operands, gen_ashlhi3_one, 4, gen_ashlhi3_eight))
DONE;
else
FAIL;
}")
(define_insn "lshrhi3_one"
[(set (match_operand:HI 0 "register_operand" "=r")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
(const_int 1)))]
""
"shlr %t0\;rotxr %s0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_insn "lshlhi3_eight"
[(set (match_operand:HI 0 "register_operand" "=r")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
(const_int 8)))]
""
"mov.b %t1,%s0\;mov.b #0,%t0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_expand "lshrhi3"
[(set (match_operand:HI 0 "register_operand" "")
(lshiftrt:HI
(match_operand:HI 1 "general_operand_src" "")
(match_operand:HI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (LSHIFTRT, operands, gen_lshrhi3_one, 4, gen_lshlhi3_eight))
DONE;
else
FAIL;
}")
(define_insn "ashrhi3_one"
[(set (match_operand:HI 0 "register_operand" "=r")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
(const_int 1)))]
""
"shar %t0\;rotxr %s0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
; signed shift right by 8 bits
; fetch the carry bit from the top, copy the byte right, subtract the
; top byte from itself - carry.
(define_insn "ashrhi3_eight"
[(set (match_operand:HI 0 "register_operand" "=r")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
(const_int 8)))]
""
"bld #7,%t0\;mov.b %t0,%s0\;subx %t0,%t0"
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_expand "ashrhi3"
[(set (match_operand:HI 0 "register_operand" "")
(ashiftrt:HI
(match_operand:HI 1 "general_operand_src" "")
(match_operand:HI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (ASHIFTRT, operands, gen_ashrhi3_one, 4, gen_ashrhi3_eight))
DONE;
else
FAIL;
}")
;; SI BIT SHIFTS
(define_insn "ashlsi3_one"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1)))]
""
"add.w %f1,%f0\;addx %y1,%y0\;addx %z1,%z0"
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI
(match_operand:SI 1 "general_operand_src" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (ASHIFT, operands, gen_ashlsi3_one, 1, 0))
DONE;
else
FAIL;
}")
(define_insn "lshrsi3_one"
[(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1)))]
""
"shlr %z0\;rotxr %y0\;rotxr %x0\;rotxr %w0"
[(set_attr "type" "multi")
(set_attr "length" "8")
(set_attr "cc" "clobber")])
(define_expand "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI
(match_operand:SI 1 "general_operand_src" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (LSHIFTRT, operands, gen_lshrsi3_one, 1, 0))
DONE;
else
FAIL;
}")
(define_insn "ashrsi3_one"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1)))]
""
"shar %z0\;rotxr %y0\;rotxr %x0\;rotxr %w0"
[(set_attr "type" "multi")
(set_attr "length" "16")
(set_attr "cc" "clobber")])
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI
(match_operand:SI 1 "general_operand_src" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (can_shift (ASHIFTRT, operands, gen_ashrsi3_one, 1, 0))
DONE;
else
FAIL;
}")
;; ----------------------------------------------------------------------
;; BIT FIELDS
;; ----------------------------------------------------------------------
(define_insn ""
[(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
(const_int 1)
(match_operand:HI 2 "general_operand" "g"))
(match_operand:HI 3 "general_operand" "r"))]
""
"bld #0,%3l\;bst %Z2,%0%Y1"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_expand "insv"
[(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
(match_operand:HI 1 "general_operand" "g")
(match_operand:HI 2 "general_operand" "g"))
(match_operand:HI 3 "general_operand" "r"))]
""
"if (INTVAL (operands[1]) != 1) FAIL;")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=&r")
(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
(const_int 1)
(match_operand:HI 3 "general_operand" "g")))]
""
"sub.w %T0,%T0\;bld %Z3,%T1%Y1\;rotxl %T0l"
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(sign_extract:HI (match_operand:HI 1 "register_operand" "r")
(const_int 1)
(match_operand:HI 3 "general_operand" "g")))]
""
"bld %Z3,%1%Y1\;sub.x %0l,%0l\;mov.b %0l,%0h"
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_expand "extzv"
[(set (match_operand:HI 0 "register_operand" "")
(zero_extract:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "general_operand" "")
(match_operand:HI 3 "general_operand" "")))]
""
"if (INTVAL (operands[2]) != 1) FAIL;")
(define_expand "extv"
[(set (match_operand:HI 0 "register_operand" "")
(sign_extract:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "general_operand" "")
(match_operand:HI 3 "immediate_operand" "")))]
""
"if (INTVAL (operands[2]) != 1) FAIL;")
;; ----------------------------------------------------------------------
;; Conversions
;; ----------------------------------------------------------------------
(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(zero_extend:HI
(match_operand:QI 1 "general_operand" "g")))]
""
"mov.b %X1,%s0\;mov.b #0,%t0"
[(set_attr "type" "multi")
(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(sign_extend:HI
(match_operand:QI 1 "register_operand" "r")))]
""
"*
{
if (REGNO (operands[1]) != REGNO (operands[0]))
return \"mov.b %X1,%s0\;bld #7,%s0\;subx %t0,%t0\";
else
return \"bld #7,%s0\;subx %t0,%t0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "6")
(set_attr "cc" "clobber")])
(define_insn "extendhisi2_one"
[(set (match_operand:SI 0 "register_operand" "=l")
(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
""
"mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0"
[(set_attr "length" "10")
(set_attr "cc" "clobber")])
(define_expand "extendhisi2"
[(set (reg:HI 1) (match_operand:HI 1 "general_operand" ""))
(set (reg:SI 0) (sign_extend:SI (reg:HI 1)))
(set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))]
""
"")
;; ----------------------------------------------------------------------
;; peepholes
;; ----------------------------------------------------------------------
;; notice a move which could be predecremented
(define_peephole
[(set (match_operand:HI 1 "register_operand" "")
(plus:HI (match_dup 1) (const_int -1)))
(set (mem:HI (match_dup 1))
(match_operand:HI 0 "register_operand" ""))]
"REGNO (operands[1]) != REGNO (operands[0])"
"mov.w %T0,@-%T1"
[(set_attr "length" "2")
(set_attr "cc" "set")])
(define_peephole
[(set (match_operand:HI 1 "register_operand" "")
(plus:HI (match_dup 1) (const_int -1)))
(set (mem:QI (match_dup 1))
(match_operand:QI 0 "register_operand" ""))]
"REGNO (operands[1]) != REGNO (operands[0])"
"mov.b %X0,@-%T1"
[(set_attr "length" "2")
(set_attr "cc" "set")])
;; notice a move which could be post incremented
(define_peephole
[(set (match_operand:HI 0 "register_operand" "")
(mem:HI (match_operand:HI 1 "register_operand" "")))
(set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))]
"REGNO (operands[1]) != REGNO (operands[0])"
"mov.w @%T1+,%T0"
[(set_attr "length" "2")
(set_attr "cc" "set")])
(define_peephole
[(set (match_operand:QI 0 "register_operand" "")
(mem:QI (match_operand:HI 1 "register_operand" "")))
(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
"REGNO (operands[1]) != REGNO (operands[0])"
"mov.b @%T1+,%X0"
[(set_attr "length" "2")
(set_attr "cc" "set")])
;; notice when two byte moves in a row could be a word move
(define_peephole
[(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
(match_operand:HI 2 "immediate_operand" "n")))
(match_operand:QI 0 "register_operand" "r"))
(set (mem:QI (plus:HI (match_dup 1)
(match_operand:HI 4 "immediate_operand" "n")))
(match_operand:QI 3 "register_operand" "r"))]
"(INTVAL (operands[2]) == INTVAL (operands[4]) + 1)
&& (REGNO (operands[0]) + 1 == REGNO (operands[3]))"
"mov.w %T0,@(%u4,%T1)"
[(set_attr "length" "6")
(set_attr "cc" "set")])
(define_peephole
[(set (match_operand:QI 0 "register_operand" "=r")
(mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
(match_operand:HI 2 "immediate_operand" "n"))))
(set (match_operand:QI 3 "register_operand" "=r")
(mem:QI (plus:HI (match_dup 1)
(match_operand:HI 4 "immediate_operand" "n"))))]
"(INTVAL (operands[2]) == INTVAL (operands[4]) + 1)
&& (REGNO (operands[0]) + 1 == REGNO (operands[3]))"
"mov.w @(%u4,%T1),%T0"
[(set_attr "length" "6")
(set_attr "cc" "set")])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment