;; Machine description for Moxie
|
;; Machine description for Moxie
|
;; Copyright (C) 2009 Free Software Foundation, Inc.
|
;; Copyright (C) 2009 Free Software Foundation, Inc.
|
;; Contributed by Anthony Green
|
;; Contributed by Anthony Green
|
|
|
;; This file is part of GCC.
|
;; This file is part of GCC.
|
|
|
;; GCC is free software; you can redistribute it and/or modify it
|
;; GCC is free software; you can redistribute it and/or modify it
|
;; under the terms of the GNU General Public License as published
|
;; under the terms of the GNU General Public License as published
|
;; by the Free Software Foundation; either version 3, or (at your
|
;; by the Free Software Foundation; either version 3, or (at your
|
;; option) any later version.
|
;; option) any later version.
|
|
|
;; GCC is distributed in the hope that it will be useful, but WITHOUT
|
;; GCC is distributed in the hope that it will be useful, but WITHOUT
|
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
;; License for more details.
|
;; License for more details.
|
|
|
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
;; along with GCC; see the file COPYING3. If not see
|
;; along with GCC; see the file COPYING3. If not see
|
;; .
|
;; .
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Moxie specific constraints, predicates and attributes
|
;; Moxie specific constraints, predicates and attributes
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(include "constraints.md")
|
(include "constraints.md")
|
(include "predicates.md")
|
(include "predicates.md")
|
|
|
; Most instructions are two bytes long.
|
; Most instructions are two bytes long.
|
(define_attr "length" "" (const_int 2))
|
(define_attr "length" "" (const_int 2))
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; nop instruction
|
;; nop instruction
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_insn "nop"
|
(define_insn "nop"
|
[(const_int 0)]
|
[(const_int 0)]
|
""
|
""
|
"nop")
|
"nop")
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Arithmetic instructions
|
;; Arithmetic instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_insn "addsi3"
|
(define_insn "addsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
(plus:SI
|
(plus:SI
|
(match_operand:SI 1 "register_operand" "0,0,0")
|
(match_operand:SI 1 "register_operand" "0,0,0")
|
(match_operand:SI 2 "moxie_add_operand" "I,N,r")))]
|
(match_operand:SI 2 "moxie_add_operand" "I,N,r")))]
|
""
|
""
|
"@
|
"@
|
inc %0, %2
|
inc %0, %2
|
dec %0, -%2
|
dec %0, -%2
|
add.l %0, %2")
|
add.l %0, %2")
|
|
|
(define_insn "subsi3"
|
(define_insn "subsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(minus:SI
|
(minus:SI
|
(match_operand:SI 1 "register_operand" "0,0")
|
(match_operand:SI 1 "register_operand" "0,0")
|
(match_operand:SI 2 "moxie_sub_operand" "I,r")))]
|
(match_operand:SI 2 "moxie_sub_operand" "I,r")))]
|
""
|
""
|
"@
|
"@
|
dec %0, %2
|
dec %0, %2
|
sub.l %0, %2")
|
sub.l %0, %2")
|
|
|
(define_insn "mulsi3"
|
(define_insn "mulsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mult:SI
|
(mult:SI
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"mul.l %0, %2")
|
"mul.l %0, %2")
|
|
|
(define_insn "divsi3"
|
(define_insn "divsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(div:SI
|
(div:SI
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"div.l %0, %2")
|
"div.l %0, %2")
|
|
|
(define_insn "udivsi3"
|
(define_insn "udivsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(udiv:SI
|
(udiv:SI
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"udiv.l %0, %2")
|
"udiv.l %0, %2")
|
|
|
(define_insn "modsi3"
|
(define_insn "modsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mod:SI
|
(mod:SI
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"mod.l %0, %2")
|
"mod.l %0, %2")
|
|
|
(define_insn "umodsi3"
|
(define_insn "umodsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(umod:SI
|
(umod:SI
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"umod.l %0, %2")
|
"umod.l %0, %2")
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Unary arithmetic instructions
|
;; Unary arithmetic instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_insn "negsi2"
|
(define_insn "negsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))]
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"neg %0, %1")
|
"neg %0, %1")
|
|
|
(define_insn "one_cmplsi2"
|
(define_insn "one_cmplsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(not:SI (match_operand:SI 1 "register_operand" "r")))]
|
(not:SI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"not %0, %1")
|
"not %0, %1")
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Logical operators
|
;; Logical operators
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_insn "andsi3"
|
(define_insn "andsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(and:SI (match_operand:SI 1 "register_operand" "0")
|
(and:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "and %0, %2";
|
return "and %0, %2";
|
})
|
})
|
|
|
(define_insn "xorsi3"
|
(define_insn "xorsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(xor:SI (match_operand:SI 1 "register_operand" "0")
|
(xor:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "xor %0, %2";
|
return "xor %0, %2";
|
})
|
})
|
|
|
(define_insn "iorsi3"
|
(define_insn "iorsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ior:SI (match_operand:SI 1 "register_operand" "0")
|
(ior:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "or %0, %2";
|
return "or %0, %2";
|
})
|
})
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Shifters
|
;; Shifters
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_insn "ashlsi3"
|
(define_insn "ashlsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashift:SI (match_operand:SI 1 "register_operand" "0")
|
(ashift:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "ashl %0, %2";
|
return "ashl %0, %2";
|
})
|
})
|
|
|
(define_insn "ashrsi3"
|
(define_insn "ashrsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "ashr %0, %2";
|
return "ashr %0, %2";
|
})
|
})
|
|
|
(define_insn "lshrsi3"
|
(define_insn "lshrsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
|
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
{
|
{
|
return "lshr %0, %2";
|
return "lshr %0, %2";
|
})
|
})
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Move instructions
|
;; Move instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
;; SImode
|
;; SImode
|
|
|
;; Push a register onto the stack
|
;; Push a register onto the stack
|
(define_insn "movsi_push"
|
(define_insn "movsi_push"
|
[(set:SI (mem:SI (pre_dec:SI (reg:SI 1)))
|
[(set:SI (mem:SI (pre_dec:SI (reg:SI 1)))
|
(match_operand:SI 0 "register_operand" "r"))]
|
(match_operand:SI 0 "register_operand" "r"))]
|
""
|
""
|
"push $sp, %0")
|
"push $sp, %0")
|
|
|
;; Pop a register from the stack
|
;; Pop a register from the stack
|
(define_insn "movsi_pop"
|
(define_insn "movsi_pop"
|
[(set:SI (match_operand:SI 1 "register_operand" "=r")
|
[(set:SI (match_operand:SI 1 "register_operand" "=r")
|
(mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))]
|
(mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))]
|
""
|
""
|
"pop %0, %1")
|
"pop %0, %1")
|
|
|
(define_expand "movsi"
|
(define_expand "movsi"
|
[(set (match_operand:SI 0 "general_operand" "")
|
[(set (match_operand:SI 0 "general_operand" "")
|
(match_operand:SI 1 "general_operand" ""))]
|
(match_operand:SI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* If this is a store, force the value into a register. */
|
/* If this is a store, force the value into a register. */
|
if (! (reload_in_progress || reload_completed))
|
if (! (reload_in_progress || reload_completed))
|
{
|
{
|
if (MEM_P (operands[0]))
|
if (MEM_P (operands[0]))
|
{
|
{
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[1] = force_reg (SImode, operands[1]);
|
if (MEM_P (XEXP (operands[0], 0)))
|
if (MEM_P (XEXP (operands[0], 0)))
|
operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
|
operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
|
}
|
}
|
else
|
else
|
if (MEM_P (operands[1])
|
if (MEM_P (operands[1])
|
&& MEM_P (XEXP (operands[1], 0)))
|
&& MEM_P (XEXP (operands[1], 0)))
|
operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
|
operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "*movsi"
|
(define_insn "*movsi"
|
[(set (match_operand:SI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
[(set (match_operand:SI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
(match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
(match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
"register_operand (operands[0], SImode)
|
"register_operand (operands[0], SImode)
|
|| register_operand (operands[1], SImode)"
|
|| register_operand (operands[1], SImode)"
|
"@
|
"@
|
xor %0, %0
|
xor %0, %0
|
mov %0, %1
|
mov %0, %1
|
ldi.l %0, %1
|
ldi.l %0, %1
|
st.l %0, %1
|
st.l %0, %1
|
sta.l %0, %1
|
sta.l %0, %1
|
ld.l %0, %1
|
ld.l %0, %1
|
lda.l %0, %1
|
lda.l %0, %1
|
sto.l %0, %1
|
sto.l %0, %1
|
ldo.l %0, %1"
|
ldo.l %0, %1"
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
|
|
(define_expand "movqi"
|
(define_expand "movqi"
|
[(set (match_operand:QI 0 "general_operand" "")
|
[(set (match_operand:QI 0 "general_operand" "")
|
(match_operand:QI 1 "general_operand" ""))]
|
(match_operand:QI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* If this is a store, force the value into a register. */
|
/* If this is a store, force the value into a register. */
|
if (MEM_P (operands[0]))
|
if (MEM_P (operands[0]))
|
operands[1] = force_reg (QImode, operands[1]);
|
operands[1] = force_reg (QImode, operands[1]);
|
}")
|
}")
|
|
|
(define_insn "*movqi"
|
(define_insn "*movqi"
|
[(set (match_operand:QI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
[(set (match_operand:QI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
(match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
(match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
"register_operand (operands[0], QImode)
|
"register_operand (operands[0], QImode)
|
|| register_operand (operands[1], QImode)"
|
|| register_operand (operands[1], QImode)"
|
"@
|
"@
|
xor %0, %0
|
xor %0, %0
|
mov %0, %1
|
mov %0, %1
|
ldi.b %0, %1
|
ldi.b %0, %1
|
st.b %0, %1
|
st.b %0, %1
|
sta.b %0, %1
|
sta.b %0, %1
|
ld.b %0, %1
|
ld.b %0, %1
|
lda.b %0, %1
|
lda.b %0, %1
|
sto.b %0, %1
|
sto.b %0, %1
|
ldo.b %0, %1"
|
ldo.b %0, %1"
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
|
|
(define_expand "movhi"
|
(define_expand "movhi"
|
[(set (match_operand:HI 0 "general_operand" "")
|
[(set (match_operand:HI 0 "general_operand" "")
|
(match_operand:HI 1 "general_operand" ""))]
|
(match_operand:HI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* If this is a store, force the value into a register. */
|
/* If this is a store, force the value into a register. */
|
if (MEM_P (operands[0]))
|
if (MEM_P (operands[0]))
|
operands[1] = force_reg (HImode, operands[1]);
|
operands[1] = force_reg (HImode, operands[1]);
|
}")
|
}")
|
|
|
(define_insn "*movhi"
|
(define_insn "*movhi"
|
[(set (match_operand:HI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
[(set (match_operand:HI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
|
(match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
(match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
|
"(register_operand (operands[0], HImode)
|
"(register_operand (operands[0], HImode)
|
|| register_operand (operands[1], HImode))"
|
|| register_operand (operands[1], HImode))"
|
"@
|
"@
|
xor %0, %0
|
xor %0, %0
|
mov %0, %1
|
mov %0, %1
|
ldi.s %0, %1
|
ldi.s %0, %1
|
st.s %0, %1
|
st.s %0, %1
|
sta.s %0, %1
|
sta.s %0, %1
|
ld.s %0, %1
|
ld.s %0, %1
|
lda.s %0, %1
|
lda.s %0, %1
|
sto.s %0, %1
|
sto.s %0, %1
|
ldo.s %0, %1"
|
ldo.s %0, %1"
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Compare instructions
|
;; Compare instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_constants
|
(define_constants
|
[(CC_REG 11)])
|
[(CC_REG 11)])
|
|
|
(define_expand "cbranchsi4"
|
(define_expand "cbranchsi4"
|
[(set (reg:CC CC_REG)
|
[(set (reg:CC CC_REG)
|
(compare:CC
|
(compare:CC
|
(match_operand:SI 1 "general_operand" "")
|
(match_operand:SI 1 "general_operand" "")
|
(match_operand:SI 2 "general_operand" "")))
|
(match_operand:SI 2 "general_operand" "")))
|
(set (pc)
|
(set (pc)
|
(if_then_else (match_operator:CC 0 "comparison_operator"
|
(if_then_else (match_operator:CC 0 "comparison_operator"
|
[(reg:CC CC_REG) (const_int 0)])
|
[(reg:CC CC_REG) (const_int 0)])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"
|
"
|
/* Force the compare operands into registers. */
|
/* Force the compare operands into registers. */
|
if (GET_CODE (operands[1]) != REG)
|
if (GET_CODE (operands[1]) != REG)
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[1] = force_reg (SImode, operands[1]);
|
if (GET_CODE (operands[2]) != REG)
|
if (GET_CODE (operands[2]) != REG)
|
operands[2] = force_reg (SImode, operands[2]);
|
operands[2] = force_reg (SImode, operands[2]);
|
")
|
")
|
|
|
(define_insn "*cmpsi"
|
(define_insn "*cmpsi"
|
[(set (reg:CC CC_REG)
|
[(set (reg:CC CC_REG)
|
(compare
|
(compare
|
(match_operand:SI 0 "register_operand" "r")
|
(match_operand:SI 0 "register_operand" "r")
|
(match_operand:SI 1 "register_operand" "r")))]
|
(match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"cmp %0, %1")
|
"cmp %0, %1")
|
|
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Branch instructions
|
;; Branch instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
|
(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
|
(define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu")
|
(define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu")
|
(gt "gt") (gtu "gtu") (ge "ge") (le "le")
|
(gt "gt") (gtu "gtu") (ge "ge") (le "le")
|
(geu "geu") (leu "leu") ])
|
(geu "geu") (leu "leu") ])
|
(define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu")
|
(define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu")
|
(gt "le") (gtu "leu") (ge "lt") (le "gt")
|
(gt "le") (gtu "leu") (ge "lt") (le "gt")
|
(geu "ltu") (leu "gtu") ])
|
(geu "ltu") (leu "gtu") ])
|
|
|
(define_insn "*b"
|
(define_insn "*b"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else (cond (reg:CC CC_REG)
|
(if_then_else (cond (reg:CC CC_REG)
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
{
|
{
|
if (get_attr_length (insn) == 2)
|
if (get_attr_length (insn) == 2)
|
return "b %l0";
|
return "b %l0";
|
else
|
else
|
return "b .+6\n\tjmpa %l0";
|
return "b .+6\n\tjmpa %l0";
|
}
|
}
|
[(set (attr "length")
|
[(set (attr "length")
|
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022))
|
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022))
|
(const_int 2) (const_int 8)))])
|
(const_int 2) (const_int 8)))])
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Call and Jump instructions
|
;; Call and Jump instructions
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_expand "call"
|
(define_expand "call"
|
[(call (match_operand:QI 0 "memory_operand" "")
|
[(call (match_operand:QI 0 "memory_operand" "")
|
(match_operand 1 "general_operand" ""))]
|
(match_operand 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
})
|
})
|
|
|
(define_insn "*call"
|
(define_insn "*call"
|
[(call (mem:QI (match_operand:SI
|
[(call (mem:QI (match_operand:SI
|
0 "nonmemory_operand" "i,r"))
|
0 "nonmemory_operand" "i,r"))
|
(match_operand 1 "" ""))]
|
(match_operand 1 "" ""))]
|
""
|
""
|
"@
|
"@
|
jsra %0
|
jsra %0
|
jsr %0"
|
jsr %0"
|
[(set_attr "length" "6,2")])
|
[(set_attr "length" "6,2")])
|
|
|
(define_expand "call_value"
|
(define_expand "call_value"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (match_operand:QI 1 "memory_operand" "")
|
(call (match_operand:QI 1 "memory_operand" "")
|
(match_operand 2 "" "")))]
|
(match_operand 2 "" "")))]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
})
|
})
|
|
|
(define_insn "*call_value"
|
(define_insn "*call_value"
|
[(set (match_operand 0 "register_operand" "=r")
|
[(set (match_operand 0 "register_operand" "=r")
|
(call (mem:QI (match_operand:SI
|
(call (mem:QI (match_operand:SI
|
1 "immediate_operand" "i"))
|
1 "immediate_operand" "i"))
|
(match_operand 2 "" "")))]
|
(match_operand 2 "" "")))]
|
""
|
""
|
"jsra %1"
|
"jsra %1"
|
[(set_attr "length" "6")])
|
[(set_attr "length" "6")])
|
|
|
(define_insn "*call_value_indirect"
|
(define_insn "*call_value_indirect"
|
[(set (match_operand 0 "register_operand" "=r")
|
[(set (match_operand 0 "register_operand" "=r")
|
(call (mem:QI (match_operand:SI
|
(call (mem:QI (match_operand:SI
|
1 "register_operand" "r"))
|
1 "register_operand" "r"))
|
(match_operand 2 "" "")))]
|
(match_operand 2 "" "")))]
|
""
|
""
|
"jsr %1")
|
"jsr %1")
|
|
|
(define_insn "indirect_jump"
|
(define_insn "indirect_jump"
|
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
|
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
|
""
|
""
|
"jmp %0")
|
"jmp %0")
|
|
|
(define_insn "jump"
|
(define_insn "jump"
|
[(set (pc)
|
[(set (pc)
|
(label_ref (match_operand 0 "" "")))]
|
(label_ref (match_operand 0 "" "")))]
|
""
|
""
|
"jmpa %l0"
|
"jmpa %l0"
|
[(set_attr "length" "6")])
|
[(set_attr "length" "6")])
|
|
|
|
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
;; Prologue & Epilogue
|
;; Prologue & Epilogue
|
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
|
|
(define_expand "prologue"
|
(define_expand "prologue"
|
[(clobber (const_int 0))]
|
[(clobber (const_int 0))]
|
""
|
""
|
"
|
"
|
{
|
{
|
moxie_expand_prologue ();
|
moxie_expand_prologue ();
|
DONE;
|
DONE;
|
}
|
}
|
")
|
")
|
|
|
(define_expand "epilogue"
|
(define_expand "epilogue"
|
[(return)]
|
[(return)]
|
""
|
""
|
"
|
"
|
{
|
{
|
moxie_expand_epilogue ();
|
moxie_expand_epilogue ();
|
DONE;
|
DONE;
|
}
|
}
|
")
|
")
|
|
|
(define_insn "returner"
|
(define_insn "returner"
|
[(return)]
|
[(return)]
|
"reload_completed"
|
"reload_completed"
|
"ret")
|
"ret")
|
|
|