URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [rl78/] [rl78.md] - Rev 709
Compare with Previous | Blame | View Log
;; Machine Description for Renesas RL78 processors
;; Copyright (C) 2011 Free Software Foundation, Inc.
;; Contributed by Red Hat.
;; This file is part of GCC.
;; 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 3, or (at your option)
;; any later version.
;; GCC 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 GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_constants
[
(AX_REG 0)
(X_REG 0)
(A_REG 1)
(BC_REG 2)
(C_REG 2)
(B_REG 3)
(DE_REG 4)
(E_REG 4)
(D_REG 5)
(HL_REG 6)
(L_REG 6)
(H_REG 7)
(FP_REG 22)
(SP_REG 32)
(CC_REG 33)
(ES_REG 35)
(CS_REG 36)
(UNS_PROLOG 1)
(UNS_EPILOG 1)
(UNS_RETI 2)
(UNS_RETB 3)
(UNS_SET_RB 10)
(UNS_TRAMPOLINE_INIT 20)
(UNS_TRAMPOLINE_UNINIT 21)
(UNS_NONLOCAL_GOTO 22)
])
(define_insn "nop"
[(const_int 0)]
""
"nop"
)
(define_mode_iterator QHI [QI HI])
(include "predicates.md")
(include "constraints.md")
(include "rl78-expand.md")
(include "rl78-virt.md")
(include "rl78-real.md")
;; Function Prologue/Epilogue Instructions
(define_expand "prologue"
[(const_int 0)]
""
"rl78_expand_prologue (); DONE;"
)
(define_expand "epilogue"
[(const_int 0)]
""
"rl78_expand_epilogue (); DONE;"
)
(define_expand "sibcall_epilogue"
[(return)]
""
"FAIL;"
)
(define_insn "rl78_return"
[(return)]
""
"ret"
)
(define_insn "interrupt_return"
[(unspec_volatile [(return)] UNS_RETI) ]
""
"reti"
)
(define_insn "brk_interrupt_return"
[(unspec_volatile [(return)] UNS_RETB) ]
""
"retb"
)
(define_expand "eh_return"
[(match_operand:HI 0 "" "")]
""
"rl78_expand_eh_epilogue (operands[0]);
emit_barrier ();
DONE;"
)
;; These are used only by prologue/epilogue so it's "safe" to pass
;; virtual registers.
(define_insn "push"
[(set (reg:HI SP_REG)
(plus:HI (reg:HI SP_REG)
(const_int -2)))
(set (mem:HI (reg:HI SP_REG))
(match_operand:HI 0 "register_operand" "ABDT,vZint"))]
""
"@
push\t%v0
push\t%v0 ; %0"
)
(define_insn "pop"
[(set (match_operand:HI 0 "register_operand" "=ABDT,vZint")
(mem:HI (reg:HI SP_REG)))
(set (reg:HI SP_REG)
(plus:HI (reg:HI SP_REG)
(const_int 2)))]
""
"@
pop\t%v0
pop\t%v0 ; %0"
)
(define_insn "sel_rb"
[(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)]
""
"sel\trb%u0"
)
(define_insn "trampoline_init"
[(set (match_operand 0 "register_operand" "=Z08W")
(unspec_volatile [(match_operand 1 "register_operand" "Z08W")
(match_operand 2 "register_operand" "Z10W")
] UNS_TRAMPOLINE_INIT))
]
""
"call !!___trampoline_init ; %0 <= %1 %2"
)
(define_insn "trampoline_uninit"
[(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT)
]
""
"call !!___trampoline_uninit"
)
;; GCC restores $fp *before* using it to access values on the *old*
;; frame. So, we do it ourselves, to ensure this is not the case.
;; Note that while %1 is usually a label_ref, we allow for a
;; non-immediate as well.
(define_expand "nonlocal_goto"
[(set (pc)
(unspec_volatile [(match_operand 0 "" "") ;; fp (ignore)
(match_operand 1 "" "vi") ;; target
(match_operand 2 "" "vi") ;; sp
(match_operand 3 "" "vi") ;; ?
] UNS_NONLOCAL_GOTO))
]
""
"emit_jump_insn (gen_nonlocal_goto_insn (operands[0], operands[1], operands[2], operands[3]));
emit_barrier ();
DONE;"
)
(define_insn "nonlocal_goto_insn"
[(set (pc)
(unspec_volatile [(match_operand 0 "" "") ;; fp (ignore)
(match_operand 1 "" "vi") ;; target
(match_operand 2 "" "vi") ;; sp
(match_operand 3 "" "vi") ;; ?
] UNS_NONLOCAL_GOTO))
]
""
"; nonlocal goto
movw ax, %3
movw r22, ax
movw ax, %2
movw sp, ax
movw ax, %1
br ax
"
)
;;======================================================================
;;
;; "macro" insns - cases where inline chunks of code are more
;; efficient than anything else.
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "=&v")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "vi")
(match_operand 2 "nonmemory_operand" "vi")))
]
""
"if (!nonmemory_operand (operands[1], SImode))
operands[1] = force_reg (SImode, operands[1]);
if (!nonmemory_operand (operands[1], SImode))
operands[2] = force_reg (SImode, operands[2]);"
)
(define_insn "addsi3_internal"
[(set (match_operand:SI 0 "register_operand" "=&v")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "vi")
(match_operand:SI 2 "nonmemory_operand" "vi")))
]
""
"; addSI macro %0 = %1 + %2
movw ax, %h1
addw ax, %h2
movw %h0, ax
movw ax,%H1
sknc
incw ax
addw ax,%H2
movw %H0,ax
; end of addSI macro"
[(set_attr "valloc" "macax")]
)
(define_expand "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=&v")
(mult:SI (match_operand:SI 1 "nonmemory_operand" "vi")
(match_operand:SI 2 "nonmemory_operand" "vi")))
]
"! RL78_MUL_NONE"
""
)
;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it
;; because we're only using the lower 16 bits (which is the upper 16
;; bits of the result).
(define_insn "mulsi3_rl78"
[(set (match_operand:SI 0 "register_operand" "=&v")
(mult:SI (match_operand:SI 1 "nonmemory_operand" "vi")
(match_operand:SI 2 "nonmemory_operand" "vi")))
]
"RL78_MUL_RL78"
"; mulsi macro %0 = %1 * %2
movw ax, %h1
movw bc, %h2
MULHU ; bcax = bc * ax
movw %h0, ax
movw ax, bc
movw 0xffff0, ax
movw ax, %H1
movw bc, %h2
MACHU ; MACR += bc * ax
movw ax, %h1
movw bc, %H2
MACHU ; MACR += bc * ax
movw ax, 0xffff0
movw %H0, ax
; end of mulsi macro"
[(set_attr "valloc" "macax")]
)
;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH.
;; 0xFFFF4 is MDBL. 0xFFFF6 is MDBH.
;; 0xF00E0 is MDCL. 0xF00E2 is MDCH.
;; 0xF00E8 is MDUC.
;; Warning: this matches the documentation, not the silicon.
(define_insn "mulsi3_g13"
[(set (match_operand:SI 0 "register_operand" "=&v")
(mult:SI (match_operand:SI 1 "nonmemory_operand" "vi")
(match_operand:SI 2 "nonmemory_operand" "vi")))
]
"RL78_MUL_G13"
"; mulsi macro %0 = %1 * %2
mov a, #0x00
mov !0xf00e8, a ; MDUC
movw ax, %h1
movw 0xffff0, ax ; MDAL
movw ax, %h2
movw 0xffff2, ax ; MDAH
nop ; mdb = mdal * mdah
movw ax, 0xffff4 ; MDBL
movw %h0, ax
mov a, #0x40
mov !0xf00e8, a ; MDUC
movw ax, 0xffff6 ; MDBH
movw !0xf00e0, ax ; MDCL
movw ax, #0
movw !0xf00e2, ax ; MDCL
movw ax, %H1
movw 0xffff0, ax ; MDAL
movw ax, %h2
movw 0xffff2, ax ; MDAH
nop ; mdc += mdal * mdah
mov a, #0x40
mov !0xf00e8, a ; MDUC
movw ax, %h1
movw 0xffff0, ax ; MDAL
movw ax, %H2
movw 0xffff2, ax ; MDAH
nop ; mdc += mdal * mdah
movw ax, !0xf00e0 ; MDCL
movw %H0, ax
; end of mulsi macro"
[(set_attr "valloc" "macax")]
)