OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [rl78/] [rl78.md] - Rev 749

Go to most recent revision | 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")]
  )

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.