* configure.ac (rl78-*-*) New case. * configure: Regenerate. * MAINTAINERS: Add myself as RL78 maintainer. libgcc * config.host (rl78-*-elf): New case. * config/rl78: New directory for the Renesas RL78. gcc * config.gcc (rl78-*-elf): New case. * doc/extend.texi: Add RL78 documentation. * doc/invoke.texi: Likewise. * doc/md.texi: Likewise. * doc/contrib.texi: Add RL78. * doc/install.texi: Add rl78-*-elf. * config/rl78: New directory for the Renesas RL78. contrib * config-list.mk (LIST): Add rl78-elf. From-SVN: r181819
This commit is contained in:
parent
c360c0fb8a
commit
85b8555ed3
|
@ -1,3 +1,9 @@
|
||||||
|
2011-11-29 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* configure.ac (rl78-*-*) New case.
|
||||||
|
* configure: Regenerate.
|
||||||
|
* MAINTAINERS: Add myself as RL78 maintainer.
|
||||||
|
|
||||||
2011-11-21 Eric Botcazou <ebotcazou@libertysurf.fr>
|
2011-11-21 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||||
|
|
||||||
* MAINTAINERS: Add self as co-maintainer of the Ada front end.
|
* MAINTAINERS: Add self as co-maintainer of the Ada front end.
|
||||||
|
|
|
@ -87,6 +87,7 @@ moxie port Anthony Green green@moxielogic.com
|
||||||
pdp11 port Paul Koning ni1d@arrl.net
|
pdp11 port Paul Koning ni1d@arrl.net
|
||||||
picochip port Hariharan Sandanagobalane hariharan@picochip.com
|
picochip port Hariharan Sandanagobalane hariharan@picochip.com
|
||||||
picochip port Daniel Towner dant@picochip.com
|
picochip port Daniel Towner dant@picochip.com
|
||||||
|
rl78 port DJ Delorie dj@redhat.com
|
||||||
rs6000 port Geoff Keating geoffk@geoffk.org
|
rs6000 port Geoff Keating geoffk@geoffk.org
|
||||||
rs6000 port David Edelsohn dje.gcc@gmail.com
|
rs6000 port David Edelsohn dje.gcc@gmail.com
|
||||||
rs6000 vector extns Aldy Hernandez aldyh@redhat.com
|
rs6000 vector extns Aldy Hernandez aldyh@redhat.com
|
||||||
|
|
|
@ -3092,6 +3092,10 @@ case "${target}" in
|
||||||
powerpc-*-aix* | rs6000-*-aix*)
|
powerpc-*-aix* | rs6000-*-aix*)
|
||||||
noconfigdirs="$noconfigdirs target-libssp"
|
noconfigdirs="$noconfigdirs target-libssp"
|
||||||
;;
|
;;
|
||||||
|
rl78-*-*)
|
||||||
|
# Dereferencing -1 is a compile-time error
|
||||||
|
noconfigdirs="$noconfigdirs target-libssp"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Disable libstdc++-v3 for some systems.
|
# Disable libstdc++-v3 for some systems.
|
||||||
|
|
|
@ -518,6 +518,12 @@ case "${target}" in
|
||||||
powerpc-*-aix* | rs6000-*-aix*)
|
powerpc-*-aix* | rs6000-*-aix*)
|
||||||
noconfigdirs="$noconfigdirs target-libssp"
|
noconfigdirs="$noconfigdirs target-libssp"
|
||||||
;;
|
;;
|
||||||
|
rl78-*-*)
|
||||||
|
# libssp uses a misaligned load to trigger a fault, but the RL78
|
||||||
|
# doesn't fault for those - instead, it gives a build-time error
|
||||||
|
# for explicit misaligned loads.
|
||||||
|
noconfigdirs="$noconfigdirs target-libssp"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Disable libstdc++-v3 for some systems.
|
# Disable libstdc++-v3 for some systems.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2011-11-29 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* config-list.mk (LIST): Add rl78-elf.
|
||||||
|
|
||||||
2011-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
2011-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||||
|
|
||||||
* make_sunver.pl: Convert '?' in glob patterns to '.'.
|
* make_sunver.pl: Convert '?' in glob patterns to '.'.
|
||||||
|
|
|
@ -53,7 +53,7 @@ LIST = alpha-linux-gnu alpha-freebsd6 alpha-netbsd alpha-openbsd \
|
||||||
powerpc-wrs-vxworks powerpc-wrs-vxworksae powerpc-lynxos powerpcle-elf \
|
powerpc-wrs-vxworks powerpc-wrs-vxworksae powerpc-lynxos powerpcle-elf \
|
||||||
powerpcle-eabisim powerpcle-eabi rs6000-ibm-aix4.3 rs6000-ibm-aix5.1.0 \
|
powerpcle-eabisim powerpcle-eabi rs6000-ibm-aix4.3 rs6000-ibm-aix5.1.0 \
|
||||||
rs6000-ibm-aix5.2.0 rs6000-ibm-aix5.3.0 rs6000-ibm-aix6.0 \
|
rs6000-ibm-aix5.2.0 rs6000-ibm-aix5.3.0 rs6000-ibm-aix6.0 \
|
||||||
rx-elf s390-linux-gnu s390x-linux-gnu s390x-ibm-tpf sh-elf \
|
rl78-elf rx-elf s390-linux-gnu s390x-linux-gnu s390x-ibm-tpf sh-elf \
|
||||||
shle-linux sh-netbsdelf sh-superh-elf sh5el-netbsd sh64-netbsd sh64-linux \
|
shle-linux sh-netbsdelf sh-superh-elf sh5el-netbsd sh64-netbsd sh64-linux \
|
||||||
sh64-elfOPT-with-newlib sh-rtems sh-wrs-vxworks sparc-elf \
|
sh64-elfOPT-with-newlib sh-rtems sh-wrs-vxworks sparc-elf \
|
||||||
sparc-leon-elf sparc-rtems sparc-linux-gnu \
|
sparc-leon-elf sparc-rtems sparc-linux-gnu \
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2011-11-29 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* config.gcc (rl78-*-elf): New case.
|
||||||
|
* doc/extend.texi: Add RL78 documentation.
|
||||||
|
* doc/invoke.texi: Likewise.
|
||||||
|
* doc/md.texi: Likewise.
|
||||||
|
* doc/contrib.texi: Add RL78.
|
||||||
|
* doc/install.texi: Add rl78-*-elf.
|
||||||
|
* config/rl78: New directory for the Renesas RL78.
|
||||||
|
|
||||||
2011-11-29 Jakub Jelinek <jakub@redhat.com>
|
2011-11-29 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/51247
|
PR tree-optimization/51247
|
||||||
|
|
|
@ -2115,6 +2115,13 @@ rs6000-ibm-aix[6789].* | powerpc-ibm-aix[6789].*)
|
||||||
use_gcc_stdint=wrap
|
use_gcc_stdint=wrap
|
||||||
extra_headers=altivec.h
|
extra_headers=altivec.h
|
||||||
;;
|
;;
|
||||||
|
rl78-*-elf*)
|
||||||
|
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
||||||
|
target_has_targetm_common=no
|
||||||
|
c_target_objs="rl78-c.o"
|
||||||
|
cxx_target_objs="rl78-c.o"
|
||||||
|
tmake_file="${tmake_file} rl78/t-rl78"
|
||||||
|
;;
|
||||||
rx-*-elf*)
|
rx-*-elf*)
|
||||||
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
||||||
tmake_file="${tmake_file} rx/t-rx"
|
tmake_file="${tmake_file} rx/t-rx"
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
; Constraints in use:
|
||||||
|
|
||||||
|
; core:
|
||||||
|
; V X g i m n o p r s < >
|
||||||
|
; 0..9
|
||||||
|
; I..Q - integers
|
||||||
|
; Int8 = 0..255
|
||||||
|
; Int3 = 1..7
|
||||||
|
; J = -255..0
|
||||||
|
; K = 1
|
||||||
|
; L = -1
|
||||||
|
; M = 0
|
||||||
|
; N = 2
|
||||||
|
; O = -2
|
||||||
|
; P = 1..15
|
||||||
|
|
||||||
|
; E..H - float constants
|
||||||
|
|
||||||
|
; RL78-specific
|
||||||
|
; a x b c d e h l w - 8-bit regs
|
||||||
|
; A B D T S - 16-bit regs
|
||||||
|
; R = all regular registers (A-L)
|
||||||
|
; Y - any valid memory
|
||||||
|
; Wxx - various memory addressing modes
|
||||||
|
; Qxx - conditionals
|
||||||
|
; v = virtual registers
|
||||||
|
; Zxx = specific virtual registers
|
||||||
|
|
||||||
|
(define_constraint "Int8"
|
||||||
|
"Integer constant in the range 0 @dots{} 255."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 0, 255)")))
|
||||||
|
|
||||||
|
(define_constraint "Int3"
|
||||||
|
"Integer constant in the range 1 @dots{} 7."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 1, 7)")))
|
||||||
|
|
||||||
|
(define_constraint "J"
|
||||||
|
"Integer constant in the range -255 @dots{} 0"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, -255, 0)")))
|
||||||
|
|
||||||
|
(define_constraint "K"
|
||||||
|
"Integer constant 1."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 1, 1)")))
|
||||||
|
|
||||||
|
(define_constraint "L"
|
||||||
|
"Integer constant -1."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, -1, -1)")))
|
||||||
|
|
||||||
|
(define_constraint "M"
|
||||||
|
"Integer constant 0."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 0, 0)")))
|
||||||
|
|
||||||
|
(define_constraint "N"
|
||||||
|
"Integer constant 2."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 2, 2)")))
|
||||||
|
|
||||||
|
(define_constraint "O"
|
||||||
|
"Integer constant -2."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, -2, -2)")))
|
||||||
|
|
||||||
|
(define_constraint "P"
|
||||||
|
"Integer constant 1..15"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (ival, 1, 15)")))
|
||||||
|
|
||||||
|
(define_register_constraint "R" "QI_REGS"
|
||||||
|
"@code{A} through @code{L} registers.")
|
||||||
|
|
||||||
|
(define_register_constraint "a" "AREG"
|
||||||
|
"The @code{A} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "x" "XREG"
|
||||||
|
"The @code{X} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "b" "BREG"
|
||||||
|
"The @code{B} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "c" "CREG"
|
||||||
|
"The @code{C} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "d" "DREG"
|
||||||
|
"The @code{D} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "e" "EREG"
|
||||||
|
"The @code{E} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "h" "HREG"
|
||||||
|
"The @code{H} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "l" "LREG"
|
||||||
|
"The @code{L} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "w" "PSWREG"
|
||||||
|
"The @code{PSW} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "A" "AXREG"
|
||||||
|
"The @code{AX} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "B" "BCREG"
|
||||||
|
"The @code{BC} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "D" "DEREG"
|
||||||
|
"The @code{DE} register.")
|
||||||
|
|
||||||
|
; because H + L = T, assuming A=1.
|
||||||
|
(define_register_constraint "T" "HLREG"
|
||||||
|
"The @code{HL} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "S" "SPREG"
|
||||||
|
"The @code{SP} register.")
|
||||||
|
|
||||||
|
(define_register_constraint "v" "V_REGS"
|
||||||
|
"The virtual registers.")
|
||||||
|
|
||||||
|
(define_register_constraint "Z08W" "R8W_REGS"
|
||||||
|
"The R8 register, HImode.")
|
||||||
|
|
||||||
|
(define_register_constraint "Z10W" "R10W_REGS"
|
||||||
|
"The R10 register, HImode.")
|
||||||
|
|
||||||
|
(define_register_constraint "Zint" "INT_REGS"
|
||||||
|
"The interrupt registers.")
|
||||||
|
|
||||||
|
; All the memory addressing schemes the RL78 supports
|
||||||
|
; of the form W {register} {bytes of offset}
|
||||||
|
; or W {register} {register}
|
||||||
|
|
||||||
|
; absolute address
|
||||||
|
(define_memory_constraint "Wab"
|
||||||
|
"[addr]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(ior (match_test "CONSTANT_P (XEXP (op, 0))")
|
||||||
|
(match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wbc"
|
||||||
|
"word16[BC]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(ior
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) == BC_REG"))
|
||||||
|
(and (match_code "plus" "0")
|
||||||
|
(and (and (match_code "reg" "00")
|
||||||
|
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == BC_REG"))
|
||||||
|
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wde"
|
||||||
|
"[DE]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) == DE_REG")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wca"
|
||||||
|
"[AX..HL] for calls"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) <= HL_REG")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wcv"
|
||||||
|
"[AX..HL,r8-r23] for calls"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) < 24")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wd2"
|
||||||
|
"word16[DE]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(ior
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) == DE_REG"))
|
||||||
|
(and (match_code "plus" "0")
|
||||||
|
(and (and (match_code "reg" "00")
|
||||||
|
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == DE_REG"))
|
||||||
|
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Whl"
|
||||||
|
"[HL]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) == HL_REG")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wh1"
|
||||||
|
"byte8[HL]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(and (match_code "plus" "0")
|
||||||
|
(and (and (match_code "reg" "00")
|
||||||
|
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG"))
|
||||||
|
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Whb"
|
||||||
|
"[HL+B]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_test "rl78_hl_b_c_addr_p (XEXP (op, 0))"))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Ws1"
|
||||||
|
"word8[SP]"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(ior
|
||||||
|
(and (match_code "reg" "0")
|
||||||
|
(match_test "REGNO (XEXP (op, 0)) == SP_REG"))
|
||||||
|
(and (match_code "plus" "0")
|
||||||
|
(and (and (match_code "reg" "00")
|
||||||
|
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))
|
||||||
|
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Wfr"
|
||||||
|
"ES/CS far pointer"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_test "rl78_far_p (op)"))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_memory_constraint "Y"
|
||||||
|
"any near legitimate memory access"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_test "!rl78_far_p (op) && rl78_as_legitimate_address (VOIDmode, XEXP (op, 0), true, ADDR_SPACE_GENERIC)"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(define_memory_constraint "Qbi"
|
||||||
|
"built-in compare types"
|
||||||
|
(match_code "eq,ne,gtu,ltu,geu,leu"))
|
||||||
|
|
||||||
|
(define_memory_constraint "Qsc"
|
||||||
|
"synthetic compares"
|
||||||
|
(match_code "gt,lt,ge,le"))
|
|
@ -0,0 +1,60 @@
|
||||||
|
;; 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_predicate "rl78_any_operand"
|
||||||
|
(ior (match_operand 0 "general_operand")
|
||||||
|
(match_code "mem,const_int,const_double,reg"))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_predicate "rl78_nonfar_operand"
|
||||||
|
(and (match_operand 0 "general_operand")
|
||||||
|
(not (match_test "rl78_far_p (op)")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_predicate "rl78_nonfar_nonimm_operand"
|
||||||
|
(and (match_operand 0 "nonimmediate_operand")
|
||||||
|
(not (match_test "rl78_far_p (op)")))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_predicate "ubyte_operand"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (INTVAL (op), 0, 255)")))
|
||||||
|
|
||||||
|
(define_predicate "rl78_24_operand"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "INTVAL (op) == 2 || INTVAL (op) == 4")))
|
||||||
|
|
||||||
|
(define_predicate "uword_operand"
|
||||||
|
(ior (match_code "const")
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "IN_RANGE (INTVAL (op), 0, 65536)"))))
|
||||||
|
|
||||||
|
(define_predicate "rl78_cmp_operator_real"
|
||||||
|
(match_code "eq,ne,gtu,ltu,geu,leu"))
|
||||||
|
(define_predicate "rl78_cmp_operator"
|
||||||
|
(match_code "eq,ne,gtu,ltu,geu,leu,gt,lt,ge,le"))
|
||||||
|
|
||||||
|
(define_predicate "rl78_ax_operand"
|
||||||
|
(and (match_code "reg")
|
||||||
|
(match_test "REGNO (op) == AX_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER")))
|
||||||
|
|
||||||
|
(define_predicate "rl78_addw_operand"
|
||||||
|
(and (match_code "reg")
|
||||||
|
(match_test "REGNO (op) == AX_REG || REGNO (op) == SP_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER")))
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* RL78 C-specific support
|
||||||
|
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
Contributed by Red Hat, Inc.
|
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "coretypes.h"
|
||||||
|
#include "tm.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "c-family/c-pragma.h"
|
||||||
|
#include "c-family/c-common.h"
|
||||||
|
#include "diagnostic-core.h"
|
||||||
|
#include "cpplib.h"
|
||||||
|
#include "hard-reg-set.h"
|
||||||
|
#include "output.h"
|
||||||
|
#include "rl78-protos.h"
|
||||||
|
#include "function.h"
|
||||||
|
#define MAX_RECOG_OPERANDS 10
|
||||||
|
#include "reload.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
/* Implements REGISTER_TARGET_PRAGMAS. */
|
||||||
|
void
|
||||||
|
rl78_register_pragmas (void)
|
||||||
|
{
|
||||||
|
c_register_addr_space ("__far", ADDR_SPACE_FAR);
|
||||||
|
}
|
|
@ -0,0 +1,256 @@
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
;;---------- Moving ------------------------
|
||||||
|
|
||||||
|
(define_expand "movqi"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand")
|
||||||
|
(match_operand:QI 1 "general_operand"))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (MEM_P (operand0) && MEM_P (operand1))
|
||||||
|
operands[1] = copy_to_mode_reg (QImode, operand1);
|
||||||
|
if (rl78_far_p (operand0) && rl78_far_p (operand1))
|
||||||
|
operands[1] = copy_to_mode_reg (QImode, operand1);
|
||||||
|
|
||||||
|
/* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)),
|
||||||
|
but it does. Since this makes no sense, reject it here. */
|
||||||
|
if (GET_CODE (operand1) == SUBREG
|
||||||
|
&& GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF)
|
||||||
|
FAIL;
|
||||||
|
|
||||||
|
if (CONST_INT_P (operand1) && ! IN_RANGE (INTVAL (operand1), (-1 << 8) + 1, (1 << 8) - 1))
|
||||||
|
gcc_unreachable();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "movhi"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand")
|
||||||
|
(match_operand:HI 1 "general_operand"))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (MEM_P (operand0) && MEM_P (operand1))
|
||||||
|
operands[1] = copy_to_mode_reg (HImode, operand1);
|
||||||
|
if (rl78_far_p (operand0) && rl78_far_p (operand1))
|
||||||
|
operands[1] = copy_to_mode_reg (HImode, operand1);
|
||||||
|
|
||||||
|
/* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)),
|
||||||
|
but it does. Since this makes no sense, reject it here. */
|
||||||
|
if (GET_CODE (operand1) == SUBREG
|
||||||
|
&& GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF)
|
||||||
|
FAIL;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "movsi"
|
||||||
|
[(set (match_operand:SI 0 "nonimmediate_operand")
|
||||||
|
(match_operand:SI 1 "general_operand"))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
rl78_expand_movsi (operands);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Conversions ------------------------
|
||||||
|
|
||||||
|
(define_expand "zero_extendqihi2"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand")
|
||||||
|
(zero_extend:HI (match_operand:QI 1 "general_operand")))]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_2 (operands, gen_zero_extendqihi2))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "extendqihi2"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand")
|
||||||
|
(sign_extend:HI (match_operand:QI 1 "general_operand")))]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_2 (operands, gen_extendqihi2))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Arithmetic ------------------------
|
||||||
|
|
||||||
|
(define_expand "add<mode>3"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(plus:QHI (match_operand:QHI 1 "general_operand")
|
||||||
|
(match_operand:QHI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_add<mode>3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "sub<mode>3"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(minus:QHI (match_operand:QHI 1 "general_operand")
|
||||||
|
(match_operand:QHI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_sub<mode>3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "neg<mode>2"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(minus:QHI (const_int 0)
|
||||||
|
(match_operand:QHI 1 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_2 (operands, gen_neg<mode>2))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "umulqihi3"
|
||||||
|
[(set (match_operand:HI 0 "register_operand")
|
||||||
|
(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand"))
|
||||||
|
(zero_extend:HI (match_operand:QI 2 "register_operand"))))]
|
||||||
|
""
|
||||||
|
""
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "andqi3"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand")
|
||||||
|
(and:QI (match_operand:QI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_andqi3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "iorqi3"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand")
|
||||||
|
(ior:QI (match_operand:QI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_iorqi3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "xorqi3"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand")
|
||||||
|
(xor:QI (match_operand:QI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_xorqi3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "one_cmplqi2"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand")
|
||||||
|
(xor:QI (match_operand:QI 1 "general_operand")
|
||||||
|
(const_int 255)))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_2 (operands, gen_one_cmplqi2))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Shifts ------------------------
|
||||||
|
|
||||||
|
(define_expand "ashl<mode>3"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(ashift:QHI (match_operand:QHI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_ashl<mode>3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "ashr<mode>3"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(ashiftrt:QHI (match_operand:QHI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_ashr<mode>3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "lshr<mode>3"
|
||||||
|
[(set (match_operand:QHI 0 "nonimmediate_operand")
|
||||||
|
(lshiftrt:QHI (match_operand:QHI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (rl78_force_nonfar_3 (operands, gen_lshr<mode>3))
|
||||||
|
DONE;"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "ashrsi3"
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(ashiftrt:SI (match_operand:SI 1 "register_operand")
|
||||||
|
(match_operand:SI 2 "immediate_operand")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"if (GET_CODE (operands[2]) != CONST_INT)
|
||||||
|
FAIL;"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Branching ------------------------
|
||||||
|
|
||||||
|
(define_expand "indirect_jump"
|
||||||
|
[(set (pc)
|
||||||
|
(match_operand:HI 0 "nonimmediate_operand"))]
|
||||||
|
""
|
||||||
|
""
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "call"
|
||||||
|
[(call (match_operand:HI 0 "memory_operand")
|
||||||
|
(match_operand 1 ""))]
|
||||||
|
""
|
||||||
|
""
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "call_value"
|
||||||
|
[(set (match_operand 0 "register_operand")
|
||||||
|
(call (match_operand:HI 1 "memory_operand")
|
||||||
|
(match_operand 2 "")))]
|
||||||
|
""
|
||||||
|
""
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "cbranchqi4"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator"
|
||||||
|
[(match_operand:QI 1 "general_operand")
|
||||||
|
(match_operand:QI 2 "general_operand")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
"rl78_expand_compare (operands);"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_expand "cbranchhi4"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator"
|
||||||
|
[(match_operand:HI 1 "general_operand")
|
||||||
|
(match_operand:HI 2 "general_operand")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
"rl78_expand_compare (operands);"
|
||||||
|
)
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* GCC option-handling definitions for the Renesas RL78 processor.
|
||||||
|
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
#ifndef RL78_OPTS_H
|
||||||
|
#define RL78_OPTS_H
|
||||||
|
|
||||||
|
enum rl78_mul_types
|
||||||
|
{
|
||||||
|
MUL_NONE,
|
||||||
|
MUL_RL78,
|
||||||
|
MUL_G13
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* Prototypes 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/>. */
|
||||||
|
|
||||||
|
void rl78_emit_eh_epilogue (rtx);
|
||||||
|
void rl78_expand_compare (rtx *);
|
||||||
|
void rl78_expand_movsi (rtx *);
|
||||||
|
int rl78_force_nonfar_2 (rtx *, rtx (*gen)(rtx,rtx));
|
||||||
|
int rl78_force_nonfar_3 (rtx *, rtx (*gen)(rtx,rtx,rtx));
|
||||||
|
void rl78_expand_eh_epilogue (rtx);
|
||||||
|
void rl78_expand_epilogue (void);
|
||||||
|
void rl78_expand_prologue (void);
|
||||||
|
int rl78_far_p (rtx x);
|
||||||
|
int rl78_hard_regno_mode_ok (int, enum machine_mode);
|
||||||
|
int rl78_hard_regno_nregs (int, enum machine_mode);
|
||||||
|
bool rl78_hl_b_c_addr_p (rtx);
|
||||||
|
int rl78_initial_elimination_offset (int, int);
|
||||||
|
bool rl78_as_legitimate_address (enum machine_mode, rtx,
|
||||||
|
bool, addr_space_t);
|
||||||
|
int rl78_legitimize_reload_address (rtx *, enum machine_mode, int,int, int);
|
||||||
|
enum reg_class rl78_mode_code_base_reg_class (enum machine_mode, addr_space_t, int, int);
|
||||||
|
bool rl78_peep_movhi_p (rtx *);
|
||||||
|
bool rl78_real_insns_ok (void);
|
||||||
|
void rl78_register_pragmas (void);
|
||||||
|
bool rl78_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_space_t, int, int);
|
||||||
|
void rl78_setup_peep_movhi (rtx *);
|
||||||
|
bool rl78_virt_insns_ok (void);
|
|
@ -0,0 +1,339 @@
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
;; The insns in this file correspond to the actual opcodes the RL78
|
||||||
|
;; can issue with real registers. All insns in here should be
|
||||||
|
;; conditional on rl78_real_insns_ok() returning true, and should
|
||||||
|
;; allow virtual registers in their predicates - the reorg pass that
|
||||||
|
;; allocates physical registers uses the constraints to select
|
||||||
|
;; registers, but insns with virtual registers MUST match one of these
|
||||||
|
;; patterns - other than the constraints - so that the operand info is
|
||||||
|
;; properly set up for the alloc pass.
|
||||||
|
|
||||||
|
;;---------- Moving ------------------------
|
||||||
|
|
||||||
|
(define_insn "movqi_es"
|
||||||
|
[(set (reg:QI ES_REG)
|
||||||
|
(match_operand:QI 0 "register_operand" "a"))]
|
||||||
|
""
|
||||||
|
"mov\tes, %0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "movqi_cs"
|
||||||
|
[(set (reg:QI CS_REG)
|
||||||
|
(match_operand:QI 0 "register_operand" "a"))]
|
||||||
|
""
|
||||||
|
"mov\tcs, %0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*movqi_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx")
|
||||||
|
(match_operand 1 "general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R"))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
; mov\t%0, %1
|
||||||
|
oneb\t%0
|
||||||
|
clrb\t%0
|
||||||
|
mov\t%0, %1
|
||||||
|
mov\t%0, %1
|
||||||
|
mov\t%0, %1
|
||||||
|
mov\t%0, %1
|
||||||
|
mov\t%0, %S1"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*movhi_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
|
||||||
|
(match_operand:HI 1 "general_operand" " 0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
; movw\t%0, %1
|
||||||
|
onew\t%0
|
||||||
|
clrw\t%0
|
||||||
|
movw\t%0, %1
|
||||||
|
movw\t%0, %1
|
||||||
|
movw\t%0, %1
|
||||||
|
movw\t%0, %S1
|
||||||
|
movw\t%0, %1
|
||||||
|
movw\t%0, %1"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Conversions ------------------------
|
||||||
|
|
||||||
|
(define_insn "*zero_extendqihi2_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=rv,A")
|
||||||
|
(zero_extend:HI (match_operand:QI 1 "general_operand" "0,a")))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
mov\t%Q0, #0
|
||||||
|
mov\tx, a \;mov\ta, #0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*extendqihi2_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=A,A")
|
||||||
|
(sign_extend:HI (match_operand:QI 1 "general_operand" "x,a")))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shlw\t%0, 8 \;sarw\t%0, 8
|
||||||
|
sarw\t%0, 8"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Arithmetic ------------------------
|
||||||
|
|
||||||
|
(define_insn "*addqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl")
|
||||||
|
(plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "K,L,RWhlWh1i,a")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
inc\t%0
|
||||||
|
dec\t%0
|
||||||
|
add\t%0, %2
|
||||||
|
add\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*addhi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
|
||||||
|
(plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0,S")
|
||||||
|
(match_operand:HI 2 "general_operand" "K,L,N,O,RWh1WhlWabiv,Int8,J,Ri")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
incw\t%0
|
||||||
|
decw\t%0
|
||||||
|
incw\t%0 \;incw\t%0
|
||||||
|
decw\t%0 \;decw\t%0
|
||||||
|
addw\t%0, %p2
|
||||||
|
addw\t%0, %2
|
||||||
|
subw\t%0, %m2
|
||||||
|
movw\t%0, %1 \;addw\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*addqihi3a_real"
|
||||||
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||||
|
(plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%r"))
|
||||||
|
(match_operand:HI 2 "register_operand" "r")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"add\t%q0, %q1 \;addc\t%Q0, #0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*subqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=a,R,v")
|
||||||
|
(minus:QI (match_operand:QI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "RiWabWhbWh1Whl,a,i")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"sub\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*subhi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=A,S")
|
||||||
|
(minus:HI (match_operand:HI 1 "general_operand" "0,0")
|
||||||
|
(match_operand:HI 2 "general_operand" "iBDTWabWh1v,i")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"subw\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*umulhi3_shift_real"
|
||||||
|
[(set (match_operand:HI 0 "register_operand" "=A,A")
|
||||||
|
(mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "0,0")
|
||||||
|
(match_operand:HI 2 "rl78_24_operand" "N,i")))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shlw\t%0, 1
|
||||||
|
shlw\t%0, 2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*umulqihi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=A")
|
||||||
|
(mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%a"))
|
||||||
|
(zero_extend:HI (match_operand:QI 2 "general_operand" "x"))))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"mulu\t%2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*andqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
|
||||||
|
(and:QI (match_operand:QI 1 "general_operand" "%0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"and\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*iorqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
|
||||||
|
(ior:QI (match_operand:QI 1 "general_operand" "%0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"or\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*xorqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
|
||||||
|
(xor:QI (match_operand:QI 1 "general_operand" "%0,0,0")
|
||||||
|
(match_operand 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"xor\t%0, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Shifts ------------------------
|
||||||
|
|
||||||
|
(define_insn "*ashlqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
|
||||||
|
(ashift:QI (match_operand:QI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shl\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*ashlhi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
|
||||||
|
(ashift:HI (match_operand:HI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "P,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shlw\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;----------
|
||||||
|
|
||||||
|
(define_insn "*ashrqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
|
||||||
|
(ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
sar\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: sar\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: sar\t%0, 1\;dec %2 \;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*ashrhi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
|
||||||
|
(ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "P,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
sarw\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: sarw\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: sarw\t%0, 1\;dec %2\;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;----------
|
||||||
|
|
||||||
|
(define_insn "*lshrqi3_real"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
|
||||||
|
(lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shr\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: shr\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: shr\t%0, 1\;dec %2\;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*lshrhi3_real"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
|
||||||
|
(lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0,0")
|
||||||
|
(match_operand:QI 2 "general_operand" "P,bc,dehl")))
|
||||||
|
]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
shrw\t%0, %u2
|
||||||
|
cmp0 %2\; bz $2f\; 1: shrw\t%0, 1 \;dec %2 \;bnz $1b\;2:
|
||||||
|
inc %2\;dec %2\;bz $2f\;1: shrw\t%0, 1\;dec %2\;bnz $1b\;2:"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Branching ------------------------
|
||||||
|
|
||||||
|
(define_insn "*indirect_jump_real"
|
||||||
|
[(set (pc)
|
||||||
|
(match_operand:HI 0 "nonimmediate_operand" "A"))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"br\t%0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "jump"
|
||||||
|
[(set (pc)
|
||||||
|
(label_ref (match_operand 0 "" "")))]
|
||||||
|
""
|
||||||
|
;; $rel8, $!rel16, !abs16, !!abs20
|
||||||
|
"br\t!!%0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*call_real"
|
||||||
|
[(call (match_operand:HI 0 "memory_operand" "Wab,Wca")
|
||||||
|
(match_operand 1 "" ""))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
call\t!!%A0
|
||||||
|
call\t%A0"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*call_value_real"
|
||||||
|
[(set (match_operand 0 "register_operand" "=v,v")
|
||||||
|
(call (match_operand:HI 1 "memory_operand" "Wab,Wca")
|
||||||
|
(match_operand 2 "" "")))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
call\t!!%A1
|
||||||
|
call\t%A1"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*cbranchqi4_real"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator_real"
|
||||||
|
[(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl")
|
||||||
|
(match_operand:QI 2 "general_operand" "M, irWhlWh1Whb,i,a")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"@
|
||||||
|
cmp0\t%1 \;sk%c0 \;br\t!!%3
|
||||||
|
cmp\t%1, %2 \;sk%c0 \;br\t!!%3
|
||||||
|
cmp\t%1, %2 \;sk%c0 \;br\t!!%3
|
||||||
|
cmp\t%1, %2 \;sk%c0 \;br\t!!%3"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*cbranchhi4_real"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator_real"
|
||||||
|
[(match_operand:HI 1 "general_operand" "A")
|
||||||
|
(match_operand:HI 2 "general_operand" "iBDTWhlWh1")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
"rl78_real_insns_ok ()"
|
||||||
|
"cmpw\t%1, %2 \;sk%c0 \;br\t!!%3"
|
||||||
|
)
|
|
@ -0,0 +1,259 @@
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
;; In this MD file, we define those insn patterns that involve
|
||||||
|
;; registers, where such registers are virtual until allocated to a
|
||||||
|
;; physical register. All of these insns need to be conditional on
|
||||||
|
;; rl78_virt_insns_ok () being true.
|
||||||
|
|
||||||
|
;; This tells the physical register allocator what method to use to
|
||||||
|
;; allocate registers. Basically, this defines the template of the
|
||||||
|
;; instruction - op1 is of the form "a = op(b)", op2 is "a = b op c"
|
||||||
|
;; etc.
|
||||||
|
|
||||||
|
(define_attr "valloc" "op1,op2,ro1,cmp,umul,macax"
|
||||||
|
(const_string "op2"))
|
||||||
|
|
||||||
|
;;---------- Moving ------------------------
|
||||||
|
|
||||||
|
(define_insn "*movqi_virt"
|
||||||
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,Wfr")
|
||||||
|
(match_operand 1 "general_operand" "vInt8JY,Wfr,vInt8J"))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.mov %0, %1"
|
||||||
|
[(set_attr "valloc" "op1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*movhi_virt"
|
||||||
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=vYS,v,Wfr")
|
||||||
|
(match_operand:HI 1 "general_operand" "viYS,Wfr,v"))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.movw %0, %1"
|
||||||
|
[(set_attr "valloc" "op1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Conversions ------------------------
|
||||||
|
|
||||||
|
(define_insn "*zero_extendqihi2_virt"
|
||||||
|
[(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(zero_extend:HI (match_operand:QI 1 "general_operand" "vim")))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.zero_extend\t%0, %1"
|
||||||
|
[(set_attr "valloc" "op1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*extendqihi2_virt"
|
||||||
|
[(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(sign_extend:HI (match_operand:QI 1 "general_operand" "vim")))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.sign_extend\t%0, %1"
|
||||||
|
[(set_attr "valloc" "op1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Arithmetic ------------------------
|
||||||
|
|
||||||
|
(define_insn "*add<mode>3_virt"
|
||||||
|
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vY,S")
|
||||||
|
(plus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "viY,0")
|
||||||
|
(match_operand:QHI 2 "general_operand" "vim,i")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.add\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*sub<mode>3_virt"
|
||||||
|
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm,S")
|
||||||
|
(minus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim,0")
|
||||||
|
(match_operand:QHI 2 "general_operand" "vim,i")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.sub\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*umulhi3_shift_virt"
|
||||||
|
[(set (match_operand:HI 0 "register_operand" "=vm")
|
||||||
|
(mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "%vim")
|
||||||
|
(match_operand:HI 2 "rl78_24_operand" "Ni")))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.mulu\t%0, %1, %2"
|
||||||
|
[(set_attr "valloc" "umul")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*umulqihi3_virt"
|
||||||
|
[(set (match_operand:HI 0 "register_operand" "=vm")
|
||||||
|
(mult:HI (zero_extend:HI (match_operand:QI 1 "rl78_nonfar_operand" "%vim"))
|
||||||
|
(zero_extend:HI (match_operand:QI 2 "general_operand" "vim"))))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.mulu\t%0, %2"
|
||||||
|
[(set_attr "valloc" "umul")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*andqi3_virt"
|
||||||
|
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(and:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.and\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*iorqi3_virt"
|
||||||
|
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(ior:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.or\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*xor3_virt"
|
||||||
|
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=v,vm,m")
|
||||||
|
(xor:QI (match_operand:QI 1 "rl78_nonfar_operand" "%0,vm,vm")
|
||||||
|
(match_operand 2 "general_operand" "i,vm,vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.xor\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Shifts ------------------------
|
||||||
|
|
||||||
|
(define_insn "*ashl<mode>3_virt"
|
||||||
|
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(ashift:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.shl\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*ashr<mode>3_virt"
|
||||||
|
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(ashiftrt:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.sar\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*lshr<mode>3_virt"
|
||||||
|
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm")
|
||||||
|
(lshiftrt:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")))
|
||||||
|
]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.shr\t%0, %1, %2"
|
||||||
|
)
|
||||||
|
|
||||||
|
;; really a macro
|
||||||
|
(define_insn "*ashrsi3_virt"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=v,v,v")
|
||||||
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,v,0")
|
||||||
|
(match_operand:SI 2 "immediate_operand" "M,K,i")))
|
||||||
|
]
|
||||||
|
""
|
||||||
|
"@
|
||||||
|
; ashrsi %0, 0
|
||||||
|
movw\tax,%H1\;sarw\tax,1\;movw\t%H0,ax\;mov\ta,%Q1\;rorc\ta,1\;mov\t%Q0,a\;mov\ta,%q1\;rorc\ta,1\;mov\t%q0,a
|
||||||
|
mov\tb,%2\;1:\;movw\tax,%H1\;sarw\tax,1\;movw\t%H0,ax\;mov\ta,%Q1\;rorc\ta,1\;mov\t%Q0,a\;mov\ta,%q1\;rorc\ta,1\;mov\t%q0,a\;dec\tb\;bnz $1b"
|
||||||
|
[(set_attr "valloc" "macax")]
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Branching ------------------------
|
||||||
|
|
||||||
|
(define_insn "*indirect_jump_virt"
|
||||||
|
[(set (pc)
|
||||||
|
(match_operand:HI 0 "nonimmediate_operand" "vm"))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.br\t%0"
|
||||||
|
[(set_attr "valloc" "ro1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*call_virt"
|
||||||
|
[(call (match_operand:HI 0 "memory_operand" "Wab,Wcv")
|
||||||
|
(match_operand 1 "" ""))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.call\t%0"
|
||||||
|
[(set_attr "valloc" "ro1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*call_value_virt"
|
||||||
|
[(set (match_operand 0 "register_operand" "=v,v")
|
||||||
|
(call (match_operand:HI 1 "memory_operand" "Wab,Wcv")
|
||||||
|
(match_operand 2 "" "")))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.call\t%1"
|
||||||
|
[(set_attr "valloc" "op1")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*cbranchqi4_virt"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator_real"
|
||||||
|
[(match_operand:QI 1 "general_operand" "vim")
|
||||||
|
(match_operand:QI 2 "general_operand" "vim")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.cmp\t%1, %2\\n\tv.b%c0\t%3"
|
||||||
|
[(set_attr "valloc" "cmp")]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "*cbranchhi4_virt"
|
||||||
|
[(set (pc) (if_then_else
|
||||||
|
(match_operator 0 "rl78_cmp_operator_real"
|
||||||
|
[(match_operand:HI 1 "general_operand" "vim")
|
||||||
|
(match_operand:HI 2 "general_operand" "vim")])
|
||||||
|
(label_ref (match_operand 3 "" ""))
|
||||||
|
(pc)))]
|
||||||
|
"rl78_virt_insns_ok ()"
|
||||||
|
"v.cmpw\t%1, %2\\n\tv.b%c0\t%3"
|
||||||
|
[(set_attr "valloc" "cmp")]
|
||||||
|
)
|
||||||
|
|
||||||
|
;;---------- Peepholes ------------------------
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:QI 0 "" "")
|
||||||
|
(match_operand:QI 1 "" ""))
|
||||||
|
(set (match_operand:QI 2 "" "")
|
||||||
|
(match_operand:QI 3 "" ""))]
|
||||||
|
"rl78_peep_movhi_p (operands)"
|
||||||
|
[(set (match_dup 4)
|
||||||
|
(match_dup 5))]
|
||||||
|
"rl78_setup_peep_movhi (operands);"
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (reg:QI A_REG)
|
||||||
|
(match_operand:QI 1 "" ""))
|
||||||
|
(set (match_operand:QI 0 "" "")
|
||||||
|
(reg:QI A_REG))
|
||||||
|
(set (reg:QI A_REG)
|
||||||
|
(match_operand:QI 3 "" ""))
|
||||||
|
(set (match_operand:QI 2 "" "")
|
||||||
|
(reg:QI A_REG))
|
||||||
|
]
|
||||||
|
"rl78_peep_movhi_p (operands)"
|
||||||
|
[(set (reg:HI AX_REG)
|
||||||
|
(match_dup 5))
|
||||||
|
(set (match_dup 4)
|
||||||
|
(reg:HI AX_REG))
|
||||||
|
]
|
||||||
|
"rl78_setup_peep_movhi (operands);"
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,462 @@
|
||||||
|
/* GCC backend definitions for the Renesas RL78 processor.
|
||||||
|
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 RL78_MUL_NONE (rl78_mul_type == MUL_NONE)
|
||||||
|
#define RL78_MUL_RL78 (rl78_mul_type == MUL_RL78)
|
||||||
|
#define RL78_MUL_G13 (rl78_mul_type == MUL_G13)
|
||||||
|
|
||||||
|
#define TARGET_CPU_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
builtin_define ("__RL78__"); \
|
||||||
|
builtin_assert ("cpu=RL78"); \
|
||||||
|
if (RL78_MUL_RL78) \
|
||||||
|
builtin_define ("__RL78_MUL_RL78__"); \
|
||||||
|
if (RL78_MUL_G13) \
|
||||||
|
builtin_define ("__RL78_MUL_G13__"); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#undef STARTFILE_SPEC
|
||||||
|
#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s"
|
||||||
|
|
||||||
|
#undef ENDFILE_SPEC
|
||||||
|
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
|
||||||
|
|
||||||
|
#undef LIB_SPEC
|
||||||
|
#define LIB_SPEC " \
|
||||||
|
--start-group \
|
||||||
|
-lc \
|
||||||
|
-lsim \
|
||||||
|
%{fprofile-arcs|fprofile-generate|coverage:-lgcov} \
|
||||||
|
--end-group \
|
||||||
|
%{!T*: %{msim:%Trl78-sim.ld}%{!msim:%Trl78.ld}} \
|
||||||
|
"
|
||||||
|
|
||||||
|
|
||||||
|
#define BITS_BIG_ENDIAN 0
|
||||||
|
#define BYTES_BIG_ENDIAN 0
|
||||||
|
#define WORDS_BIG_ENDIAN 0
|
||||||
|
|
||||||
|
#ifdef IN_LIBGCC2
|
||||||
|
/* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */
|
||||||
|
#define UNITS_PER_WORD 4
|
||||||
|
/* We have a problem with libgcc2. It only defines two versions of
|
||||||
|
each function, one for "int" and one for "long long". Ie it assumes
|
||||||
|
that "sizeof (int) == sizeof (long)". For the RL78 this is not true
|
||||||
|
and we need a third set of functions. We explicitly define
|
||||||
|
LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting
|
||||||
|
to get the SI and DI versions from the libgcc2.c sources, and we
|
||||||
|
provide our own set of HI functions, which is why this
|
||||||
|
definition is surrounded by #ifndef..#endif. */
|
||||||
|
#ifndef LIBGCC2_UNITS_PER_WORD
|
||||||
|
#define LIBGCC2_UNITS_PER_WORD 4
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* Actual width of a word, in units (bytes). */
|
||||||
|
#define UNITS_PER_WORD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHORT_TYPE_SIZE 16
|
||||||
|
#define INT_TYPE_SIZE 16
|
||||||
|
#define LONG_TYPE_SIZE 32
|
||||||
|
#define LONG_LONG_TYPE_SIZE 64
|
||||||
|
|
||||||
|
#define FLOAT_TYPE_SIZE 32
|
||||||
|
#define DOUBLE_TYPE_SIZE 32 /*64*/
|
||||||
|
#define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/
|
||||||
|
|
||||||
|
#define LIBGCC2_HAS_DF_MODE 1
|
||||||
|
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
|
||||||
|
|
||||||
|
#define DEFAULT_SIGNED_CHAR 0
|
||||||
|
|
||||||
|
#define STRICT_ALIGNMENT 1
|
||||||
|
#define FUNCTION_BOUNDARY 8
|
||||||
|
#define BIGGEST_ALIGNMENT 16
|
||||||
|
#define STACK_BOUNDARY 16
|
||||||
|
#define PARM_BOUNDARY 16
|
||||||
|
|
||||||
|
#define STACK_GROWS_DOWNWARD 1
|
||||||
|
#define FRAME_GROWS_DOWNWARD 1
|
||||||
|
#define FIRST_PARM_OFFSET(FNDECL) 0
|
||||||
|
|
||||||
|
#define MAX_REGS_PER_ADDRESS 1
|
||||||
|
|
||||||
|
#define Pmode HImode
|
||||||
|
#define POINTER_SIZE 16
|
||||||
|
#undef SIZE_TYPE
|
||||||
|
#define SIZE_TYPE "unsigned int"
|
||||||
|
#undef PTRDIFF_TYPE
|
||||||
|
#define PTRDIFF_TYPE "int"
|
||||||
|
#undef WCHAR_TYPE
|
||||||
|
#define WCHAR_TYPE "long int"
|
||||||
|
#undef WCHAR_TYPE_SIZE
|
||||||
|
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||||
|
#define POINTERS_EXTEND_UNSIGNED 1
|
||||||
|
#define FUNCTION_MODE HImode
|
||||||
|
#define CASE_VECTOR_MODE Pmode
|
||||||
|
#define WORD_REGISTER_OPERATIONS 0
|
||||||
|
#define HAS_LONG_COND_BRANCH 0
|
||||||
|
#define HAS_LONG_UNCOND_BRANCH 0
|
||||||
|
|
||||||
|
#define MOVE_MAX 2
|
||||||
|
#define STARTING_FRAME_OFFSET 0
|
||||||
|
|
||||||
|
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
|
||||||
|
|
||||||
|
#define ADDR_SPACE_FAR 1
|
||||||
|
|
||||||
|
#define HAVE_PRE_DECCREMENT 0
|
||||||
|
#define HAVE_POST_INCREMENT 0
|
||||||
|
|
||||||
|
#define MOVE_RATIO(SPEED) ((SPEED) ? 24 : 16)
|
||||||
|
#define SLOW_BYTE_ACCESS 0
|
||||||
|
|
||||||
|
#define STORE_FLAG_VALUE 1
|
||||||
|
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
|
||||||
|
#define SHORT_IMMEDIATES_SIGN_EXTEND 0
|
||||||
|
|
||||||
|
|
||||||
|
/* The RL78 has four register banks. Normal operation uses RB0 as
|
||||||
|
real registers, RB1 and RB2 as "virtual" registers (because we know
|
||||||
|
they'll be there, and not used as variables), and RB3 is reserved
|
||||||
|
for interrupt handlers. The virtual registers are accessed as
|
||||||
|
SADDRs:
|
||||||
|
|
||||||
|
FFEE0-FFEE7 RB0
|
||||||
|
FFEE8-FFEEF RB1
|
||||||
|
FFEF0-FFEF7 RB2
|
||||||
|
FFEF8-FFEFF RB3
|
||||||
|
*/
|
||||||
|
#define REGISTER_NAMES \
|
||||||
|
{ \
|
||||||
|
"x", "a", "c", "b", "e", "d", "l", "h", \
|
||||||
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
|
||||||
|
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
|
||||||
|
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
|
||||||
|
"sp", "ap", "psw", "es", "cs" \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADDITIONAL_REGISTER_NAMES \
|
||||||
|
{ \
|
||||||
|
{ "ax", 0 }, \
|
||||||
|
{ "bc", 2 }, \
|
||||||
|
{ "de", 4 }, \
|
||||||
|
{ "hl", 6 }, \
|
||||||
|
{ "rp0", 0 }, \
|
||||||
|
{ "rp1", 2 }, \
|
||||||
|
{ "rp2", 4 }, \
|
||||||
|
{ "rp3", 6 }, \
|
||||||
|
{ "r0", 0 }, \
|
||||||
|
{ "r1", 1 }, \
|
||||||
|
{ "r2", 2 }, \
|
||||||
|
{ "r3", 3 }, \
|
||||||
|
{ "r4", 4 }, \
|
||||||
|
{ "r5", 5 }, \
|
||||||
|
{ "r6", 6 }, \
|
||||||
|
{ "r7", 7 }, \
|
||||||
|
}
|
||||||
|
|
||||||
|
enum reg_class
|
||||||
|
{
|
||||||
|
NO_REGS, /* No registers in set. */
|
||||||
|
XREG,
|
||||||
|
AREG,
|
||||||
|
AXREG,
|
||||||
|
CREG,
|
||||||
|
BREG,
|
||||||
|
BCREG,
|
||||||
|
EREG,
|
||||||
|
DREG,
|
||||||
|
DEREG,
|
||||||
|
LREG,
|
||||||
|
HREG,
|
||||||
|
HLREG,
|
||||||
|
IDX_REGS,
|
||||||
|
QI_REGS,
|
||||||
|
SPREG,
|
||||||
|
R8W_REGS,
|
||||||
|
R10W_REGS,
|
||||||
|
INT_REGS,
|
||||||
|
V_REGS, /* Virtual registers. */
|
||||||
|
GR_REGS, /* Integer registers. */
|
||||||
|
PSWREG,
|
||||||
|
ALL_REGS, /* All registers. */
|
||||||
|
LIM_REG_CLASSES /* Max value + 1. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REG_CLASS_NAMES \
|
||||||
|
{ \
|
||||||
|
"NO_REGS", \
|
||||||
|
"XREG", \
|
||||||
|
"AREG", \
|
||||||
|
"AXREG", \
|
||||||
|
"CREG", \
|
||||||
|
"BREG", \
|
||||||
|
"BCREG", \
|
||||||
|
"EREG", \
|
||||||
|
"DREG", \
|
||||||
|
"DEREG", \
|
||||||
|
"LREG", \
|
||||||
|
"HREG", \
|
||||||
|
"HLREG", \
|
||||||
|
"IDX_REGS", \
|
||||||
|
"QI_REGS", \
|
||||||
|
"SPREG", \
|
||||||
|
"R8W_REGS", \
|
||||||
|
"R10W_REGS", \
|
||||||
|
"INT_REGS", \
|
||||||
|
"V_REGS", \
|
||||||
|
"GR_REGS", \
|
||||||
|
"PSWREG", \
|
||||||
|
"ALL_REGS" \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REG_CLASS_CONTENTS \
|
||||||
|
{ \
|
||||||
|
{ 0x00000000, 0x00000000 }, /* No registers, */ \
|
||||||
|
{ 0x00000001, 0x00000000 }, \
|
||||||
|
{ 0x00000002, 0x00000000 }, \
|
||||||
|
{ 0x00000003, 0x00000000 }, \
|
||||||
|
{ 0x00000004, 0x00000000 }, \
|
||||||
|
{ 0x00000008, 0x00000000 }, \
|
||||||
|
{ 0x0000000c, 0x00000000 }, \
|
||||||
|
{ 0x00000010, 0x00000000 }, \
|
||||||
|
{ 0x00000020, 0x00000000 }, \
|
||||||
|
{ 0x00000030, 0x00000000 }, \
|
||||||
|
{ 0x00000040, 0x00000000 }, \
|
||||||
|
{ 0x00000080, 0x00000000 }, \
|
||||||
|
{ 0x000000c0, 0x00000000 }, \
|
||||||
|
{ 0x0000000c, 0x00000000 }, /* B and C - index regs. */ \
|
||||||
|
{ 0x000000ff, 0x00000000 }, /* all real registers. */ \
|
||||||
|
{ 0x00000000, 0x00000001 }, /* SP */ \
|
||||||
|
{ 0x00000300, 0x00000000 }, /* R8 - HImode */ \
|
||||||
|
{ 0x00000c00, 0x00000000 }, /* R10 - HImode */ \
|
||||||
|
{ 0xff000000, 0x00000000 }, /* INT - HImode */ \
|
||||||
|
{ 0x007fff00, 0x00000000 }, /* Virtual registers. */ \
|
||||||
|
{ 0xff7fffff, 0x00000002 }, /* General registers. */ \
|
||||||
|
{ 0x04000000, 0x00000004 }, /* PSW. */ \
|
||||||
|
{ 0xff7fffff, 0x0000001f } /* All registers. */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SMALL_REGISTER_CLASSES 1
|
||||||
|
#define N_REG_CLASSES (int) LIM_REG_CLASSES
|
||||||
|
#define CLASS_MAX_NREGS(CLASS, MODE) ((GET_MODE_SIZE (MODE) \
|
||||||
|
+ UNITS_PER_WORD - 1) \
|
||||||
|
/ UNITS_PER_WORD)
|
||||||
|
|
||||||
|
#define GENERAL_REGS GR_REGS
|
||||||
|
#define BASE_REG_CLASS V_REGS
|
||||||
|
#define INDEX_REG_CLASS V_REGS
|
||||||
|
|
||||||
|
#define FIRST_PSEUDO_REGISTER 37
|
||||||
|
|
||||||
|
#define REGNO_REG_CLASS(REGNO) ((REGNO) < FIRST_PSEUDO_REGISTER \
|
||||||
|
? GR_REGS : NO_REGS)
|
||||||
|
|
||||||
|
#define FRAME_POINTER_REGNUM 22
|
||||||
|
#define STACK_POINTER_REGNUM 32
|
||||||
|
#define ARG_POINTER_REGNUM 33
|
||||||
|
#define CC_REGNUM 34
|
||||||
|
#define FUNC_RETURN_REGNUM 8
|
||||||
|
#define STATIC_CHAIN_REGNUM 14
|
||||||
|
|
||||||
|
/* Trampolines are implemented with a separate data stack. The memory
|
||||||
|
on stack only holds the function pointer for the chosen stub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TRAMPOLINE_SIZE 4
|
||||||
|
#define TRAMPOLINE_ALIGNMENT 16
|
||||||
|
|
||||||
|
#define ELIMINABLE_REGS \
|
||||||
|
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
|
||||||
|
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
|
||||||
|
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
|
||||||
|
|
||||||
|
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||||
|
(OFFSET) = rl78_initial_elimination_offset ((FROM), (TO))
|
||||||
|
|
||||||
|
|
||||||
|
#define FUNCTION_ARG_REGNO_P(N) 0
|
||||||
|
#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8)
|
||||||
|
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||||
|
|
||||||
|
#define FIXED_REGISTERS \
|
||||||
|
{ \
|
||||||
|
1,1,1,1, 1,1,1,1, \
|
||||||
|
0,0,0,0, 0,0,0,0, \
|
||||||
|
0,0,0,0, 0,0,1,1, \
|
||||||
|
1,1,1,1, 1,1,1,1, \
|
||||||
|
0, 1, 0, 1, 1 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CALL_USED_REGISTERS \
|
||||||
|
{ \
|
||||||
|
1,1,1,1, 1,1,1,1, \
|
||||||
|
1,1,1,1, 1,1,1,1, \
|
||||||
|
0,0,0,0, 0,0,1,1, \
|
||||||
|
1,1,1,1, 1,1,1,1, \
|
||||||
|
0, 1, 1, 1, 1 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIBCALL_VALUE(MODE) \
|
||||||
|
gen_rtx_REG ((MODE), \
|
||||||
|
FUNC_RETURN_REGNUM)
|
||||||
|
|
||||||
|
/* Order of allocation of registers. */
|
||||||
|
|
||||||
|
#define REG_ALLOC_ORDER \
|
||||||
|
{ 8, 9, 10, 11, 12, 13, 14, 15, \
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23, \
|
||||||
|
0, 1, 6, 7, 2, 3, 4, 5, \
|
||||||
|
24, 25, 26, 27, 28, 29, 30, 31, \
|
||||||
|
32, 33, 34 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REGNO_IN_RANGE(REGNO, MIN, MAX) \
|
||||||
|
(IN_RANGE ((REGNO), (MIN), (MAX)) \
|
||||||
|
|| (reg_renumber != NULL \
|
||||||
|
&& reg_renumber[(REGNO)] >= (MIN) \
|
||||||
|
&& reg_renumber[(REGNO)] <= (MAX)))
|
||||||
|
|
||||||
|
#ifdef REG_OK_STRICT
|
||||||
|
#define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 23)
|
||||||
|
#else
|
||||||
|
#define REGNO_OK_FOR_BASE_P(regno) 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REGNO_OK_FOR_INDEX_P(regno) REGNO_OK_FOR_BASE_P (regno)
|
||||||
|
|
||||||
|
#define REGNO_MODE_CODE_OK_FOR_BASE_P(regno, mode, address_space, outer_code, index_code) \
|
||||||
|
rl78_regno_mode_code_ok_for_base_p (regno, mode, address_space, outer_code, index_code)
|
||||||
|
|
||||||
|
#define MODE_CODE_BASE_REG_CLASS(mode, address_space, outer_code, index_code) \
|
||||||
|
rl78_mode_code_base_reg_class (mode, address_space, outer_code, index_code)
|
||||||
|
|
||||||
|
#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
|
||||||
|
((COUNT) == 0 \
|
||||||
|
? gen_rtx_MEM (Pmode, gen_rtx_PLUS (HImode, arg_pointer_rtx, GEN_INT (-4))) \
|
||||||
|
: NULL_RTX)
|
||||||
|
|
||||||
|
#define INCOMING_RETURN_ADDR_RTX gen_rtx_MEM (Pmode, stack_pointer_rtx)
|
||||||
|
|
||||||
|
#define ACCUMULATE_OUTGOING_ARGS 1
|
||||||
|
|
||||||
|
typedef unsigned int CUMULATIVE_ARGS;
|
||||||
|
|
||||||
|
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
|
||||||
|
(CUM) = 0
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
#define NO_PROFILE_COUNTERS 1
|
||||||
|
#define PROFILE_BEFORE_PROLOGUE 1
|
||||||
|
|
||||||
|
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||||
|
fprintf (FILE, "\tbsr\t__mcount\n");
|
||||||
|
|
||||||
|
|
||||||
|
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||||
|
rl78_hard_regno_nregs (REGNO, MODE)
|
||||||
|
|
||||||
|
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||||
|
rl78_hard_regno_mode_ok (REGNO, MODE)
|
||||||
|
|
||||||
|
#define MODES_TIEABLE_P(MODE1, MODE2) \
|
||||||
|
( ( GET_MODE_CLASS (MODE1) == MODE_FLOAT \
|
||||||
|
|| GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \
|
||||||
|
== ( GET_MODE_CLASS (MODE2) == MODE_FLOAT \
|
||||||
|
|| GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
|
||||||
|
|
||||||
|
|
||||||
|
#define TEXT_SECTION_ASM_OP ".text"
|
||||||
|
#define DATA_SECTION_ASM_OP ".data"
|
||||||
|
#define BSS_SECTION_ASM_OP ".bss"
|
||||||
|
#define CTORS_SECTION_ASM_OP ".section \".ctors\",\"a\""
|
||||||
|
#define DTORS_SECTION_ASM_OP ".section \".dtors\",\"a\""
|
||||||
|
|
||||||
|
#define ASM_COMMENT_START " ;"
|
||||||
|
#define ASM_APP_ON ""
|
||||||
|
#define ASM_APP_OFF ""
|
||||||
|
#define LOCAL_LABEL_PREFIX ".L"
|
||||||
|
#undef USER_LABEL_PREFIX
|
||||||
|
#define USER_LABEL_PREFIX "_"
|
||||||
|
|
||||||
|
#define GLOBAL_ASM_OP "\t.global\t"
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||||
|
fprintf (FILE, "\t.long .L%d\n", VALUE)
|
||||||
|
|
||||||
|
/* This is how to output an element of a case-vector that is relative.
|
||||||
|
Note: The local label referenced by the "3b" below is emitted by
|
||||||
|
the tablejump insn. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
|
||||||
|
fprintf (FILE, "\t.long .L%d - 1b\n", VALUE)
|
||||||
|
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_ALIGN(STREAM, LOG) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if ((LOG) == 0) \
|
||||||
|
break; \
|
||||||
|
fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* For PIC put jump tables into the text section so that the offsets that
|
||||||
|
they contain are always computed between two same-section symbols. */
|
||||||
|
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
|
||||||
|
|
||||||
|
/* This is a version of REG_P that also returns TRUE for SUBREGs. */
|
||||||
|
#define RL78_REG_P(rtl) (REG_P (rtl) || GET_CODE (rtl) == SUBREG)
|
||||||
|
|
||||||
|
/* Like REG_P except that this macro is true for SET expressions. */
|
||||||
|
#define SET_P(rtl) (GET_CODE (rtl) == SET)
|
||||||
|
|
||||||
|
#undef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||||
|
|
||||||
|
#undef DWARF2_ADDR_SIZE
|
||||||
|
#define DWARF2_ADDR_SIZE 4
|
||||||
|
|
||||||
|
#define DWARF2_ASM_LINE_DEBUG_INFO 1
|
||||||
|
|
||||||
|
#define EXIT_IGNORE_STACK 0
|
||||||
|
#define INCOMING_FRAME_SP_OFFSET 4
|
||||||
|
|
||||||
|
|
||||||
|
#define BRANCH_COST(SPEED,PREDICT) 1
|
||||||
|
#define REGISTER_MOVE_COST(MODE,FROM,TO) 2
|
||||||
|
|
||||||
|
#define EH_RETURN_DATA_REGNO(N) (N < 2 ? (8+(N)*2) : INVALID_REGNUM)
|
||||||
|
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (HImode, 20)
|
||||||
|
|
||||||
|
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4
|
||||||
|
|
||||||
|
/* NOTE: defined but zero means dwarf2 debugging, but sjlj EH. */
|
||||||
|
#define DWARF2_UNWIND_INFO 0
|
||||||
|
/*#define DONT_USE_BUILTIN_SETJMP 1*/
|
||||||
|
#undef DONT_USE_BUILTIN_SETJMP
|
||||||
|
#define JMP_BUF_SIZE (8*3+8)
|
||||||
|
|
||||||
|
#define REGISTER_TARGET_PRAGMAS() rl78_register_pragmas()
|
|
@ -0,0 +1,320 @@
|
||||||
|
;; 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 "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")]
|
||||||
|
)
|
|
@ -0,0 +1,43 @@
|
||||||
|
; Command line options for the Renesas RL78 port of GCC.
|
||||||
|
; 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/>.
|
||||||
|
;---------------------------------------------------
|
||||||
|
|
||||||
|
HeaderInclude
|
||||||
|
config/rl78/rl78-opts.h
|
||||||
|
|
||||||
|
msim
|
||||||
|
Target
|
||||||
|
Use the simulator runtime.
|
||||||
|
|
||||||
|
mmul=
|
||||||
|
Target RejectNegative Joined Var(rl78_mul_type) Report Tolower Enum(rl78_mul_types) Init(MUL_NONE)
|
||||||
|
Select hardware or software multiplication support.
|
||||||
|
|
||||||
|
Enum
|
||||||
|
Name(rl78_mul_types) Type(enum rl78_mul_types)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(rl78_mul_types) String(none) Value(MUL_NONE)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(rl78_mul_types) String(rl78) Value(MUL_RL78)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(rl78_mul_types) String(g13) Value(MUL_G13)
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Makefile fragment for building GCC for the Renesas RL78 target.
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
rl78-c.o: $(srcdir)/config/rl78/rl78-c.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H)
|
||||||
|
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
|
@ -220,7 +220,7 @@ Mo DeJong for GCJ and libgcj bug fixes.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
DJ Delorie for the DJGPP port, build and libiberty maintenance,
|
DJ Delorie for the DJGPP port, build and libiberty maintenance,
|
||||||
various bug fixes, and the M32C and MeP ports.
|
various bug fixes, and the M32C, MeP, and RL78 ports.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Arnaud Desitter for helping to debug GNU Fortran.
|
Arnaud Desitter for helping to debug GNU Fortran.
|
||||||
|
|
|
@ -1220,11 +1220,12 @@ Fixed-point types are supported by the DWARF2 debug information format.
|
||||||
|
|
||||||
As an extension, the GNU C compiler supports named address spaces as
|
As an extension, the GNU C compiler supports named address spaces as
|
||||||
defined in the N1275 draft of ISO/IEC DTR 18037. Support for named
|
defined in the N1275 draft of ISO/IEC DTR 18037. Support for named
|
||||||
address spaces in GCC will evolve as the draft technical report changes.
|
address spaces in GCC will evolve as the draft technical report
|
||||||
Calling conventions for any target might also change. At present, only
|
changes. Calling conventions for any target might also change. At
|
||||||
the SPU and M32C targets support other address spaces. On the SPU target, for
|
present, only the SPU, M32C, and RL78 targets support other address
|
||||||
example, variables may be declared as belonging to another address space
|
spaces. On the SPU target, for example, variables may be declared as
|
||||||
by qualifying the type with the @code{__ea} address space identifier:
|
belonging to another address space by qualifying the type with the
|
||||||
|
@code{__ea} address space identifier:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
extern int __ea i;
|
extern int __ea i;
|
||||||
|
@ -1244,6 +1245,11 @@ qualified with @code{__far} are accessed using 32-bit addresses in
|
||||||
order to access memory beyond the first 64k bytes. If @code{__far} is
|
order to access memory beyond the first 64k bytes. If @code{__far} is
|
||||||
used with the M32CM or M32C cpu variants, it has no effect.
|
used with the M32CM or M32C cpu variants, it has no effect.
|
||||||
|
|
||||||
|
On the RL78 target, variables qualified with @code{__far} are accessed
|
||||||
|
with 32-bit pointers (20-bit addresses) rather than the default 16-bit
|
||||||
|
addresses. Non-far variables are assumed to appear in the topmost 64
|
||||||
|
kB of the address space.
|
||||||
|
|
||||||
@node Zero Length
|
@node Zero Length
|
||||||
@section Arrays of Length Zero
|
@section Arrays of Length Zero
|
||||||
@cindex arrays of length zero
|
@cindex arrays of length zero
|
||||||
|
@ -2553,7 +2559,7 @@ This attribute is ignored for R8C target.
|
||||||
@item interrupt
|
@item interrupt
|
||||||
@cindex interrupt handler functions
|
@cindex interrupt handler functions
|
||||||
Use this attribute on the ARM, AVR, Epiphany, M32C, M32R/D, m68k, MeP, MIPS,
|
Use this attribute on the ARM, AVR, Epiphany, M32C, M32R/D, m68k, MeP, MIPS,
|
||||||
RX and Xstormy16 ports to indicate that the specified function is an
|
RL78, RX and Xstormy16 ports to indicate that the specified function is an
|
||||||
interrupt handler. The compiler will generate function entry and exit
|
interrupt handler. The compiler will generate function entry and exit
|
||||||
sequences suitable for use in an interrupt handler when this attribute
|
sequences suitable for use in an interrupt handler when this attribute
|
||||||
is present.
|
is present.
|
||||||
|
@ -2611,6 +2617,10 @@ void __attribute__ ((interrupt, use_shadow_register_set,
|
||||||
use_debug_exception_return)) v7 ();
|
use_debug_exception_return)) v7 ();
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
|
On RL78, use @code{brk_interrupt} instead of @code{interrupt} for
|
||||||
|
handlers intended to be used with the @code{BRK} opcode (i.e. those
|
||||||
|
that must end with @code{RETB} instead of @code{RETI}).
|
||||||
|
|
||||||
@item ifunc ("@var{resolver}")
|
@item ifunc ("@var{resolver}")
|
||||||
@cindex @code{ifunc} attribute
|
@cindex @code{ifunc} attribute
|
||||||
The @code{ifunc} attribute is used to mark a function as an indirect
|
The @code{ifunc} attribute is used to mark a function as an indirect
|
||||||
|
|
|
@ -4137,6 +4137,13 @@ the PSIM simulator.
|
||||||
@heading @anchor{powerpcle-x-eabi}powerpcle-*-eabi
|
@heading @anchor{powerpcle-x-eabi}powerpcle-*-eabi
|
||||||
Embedded PowerPC system in little endian mode.
|
Embedded PowerPC system in little endian mode.
|
||||||
|
|
||||||
|
@html
|
||||||
|
<hr />
|
||||||
|
@end html
|
||||||
|
@heading @anchor{rl78-x-elf}rl78-*-elf
|
||||||
|
The Renesas RL78 processor.
|
||||||
|
This configuration is intended for embedded systems.
|
||||||
|
|
||||||
@html
|
@html
|
||||||
<hr />
|
<hr />
|
||||||
@end html
|
@end html
|
||||||
|
|
|
@ -778,6 +778,9 @@ Objective-C and Objective-C++ Dialects}.
|
||||||
@emph{PowerPC Options}
|
@emph{PowerPC Options}
|
||||||
See RS/6000 and PowerPC Options.
|
See RS/6000 and PowerPC Options.
|
||||||
|
|
||||||
|
@emph{RL78 Options}
|
||||||
|
@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=rl78}
|
||||||
|
|
||||||
@emph{RS/6000 and PowerPC Options}
|
@emph{RS/6000 and PowerPC Options}
|
||||||
@gccoptlist{-mcpu=@var{cpu-type} @gol
|
@gccoptlist{-mcpu=@var{cpu-type} @gol
|
||||||
-mtune=@var{cpu-type} @gol
|
-mtune=@var{cpu-type} @gol
|
||||||
|
@ -10303,6 +10306,7 @@ platform.
|
||||||
* PDP-11 Options::
|
* PDP-11 Options::
|
||||||
* picoChip Options::
|
* picoChip Options::
|
||||||
* PowerPC Options::
|
* PowerPC Options::
|
||||||
|
* RL78 Options::
|
||||||
* RS/6000 and PowerPC Options::
|
* RS/6000 and PowerPC Options::
|
||||||
* RX Options::
|
* RX Options::
|
||||||
* S/390 and zSeries Options::
|
* S/390 and zSeries Options::
|
||||||
|
@ -15931,6 +15935,29 @@ the warning to be turned off.
|
||||||
|
|
||||||
These are listed under @xref{RS/6000 and PowerPC Options}.
|
These are listed under @xref{RS/6000 and PowerPC Options}.
|
||||||
|
|
||||||
|
@node RL78 Options
|
||||||
|
@subsection RL78 Options
|
||||||
|
@cindex RL78 Options
|
||||||
|
|
||||||
|
@table @gcctabopt
|
||||||
|
|
||||||
|
@item -msim
|
||||||
|
@opindex msim
|
||||||
|
Links in additional target libraries to support operation within a
|
||||||
|
simulator.
|
||||||
|
|
||||||
|
@item -mmul=none
|
||||||
|
@itemx -mmul=g13
|
||||||
|
@itemx -mmul=rl78
|
||||||
|
@opindex mmul
|
||||||
|
Specifies the type of hardware multiplication support to be used. The
|
||||||
|
default is @code{none}, which uses software multiplication functions.
|
||||||
|
The @code{g13} option is for the hardware multiply/divide peripheral
|
||||||
|
only on the RL78/G13 targets. The @code{rl78} option is for the
|
||||||
|
standard hardware multiplication defined in the RL78 software manual.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
@node RS/6000 and PowerPC Options
|
@node RS/6000 and PowerPC Options
|
||||||
@subsection IBM RS/6000 and PowerPC Options
|
@subsection IBM RS/6000 and PowerPC Options
|
||||||
@cindex RS/6000 and PowerPC Options
|
@cindex RS/6000 and PowerPC Options
|
||||||
|
|
|
@ -2979,6 +2979,96 @@ A memory reference that is encoded within the opcode.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item RL78---@file{config/rl78/constraints.md}
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item Int3
|
||||||
|
An integer constant in the range 1 @dots{} 7.
|
||||||
|
@item Int8
|
||||||
|
An integer constant in the range 0 @dots{} 255.
|
||||||
|
@item J
|
||||||
|
An integer constant in the range @minus{}255 @dots{} 0
|
||||||
|
@item K
|
||||||
|
The integer constant 1.
|
||||||
|
@item L
|
||||||
|
The integer constant -1.
|
||||||
|
@item M
|
||||||
|
The integer constant 0.
|
||||||
|
@item N
|
||||||
|
The integer constant 2.
|
||||||
|
@item O
|
||||||
|
The integer constant -2.
|
||||||
|
@item P
|
||||||
|
An integer constant in the range 1 @dots{} 15.
|
||||||
|
@item Qbi
|
||||||
|
The built-in compare types--eq, ne, gtu, ltu, geu, and leu.
|
||||||
|
@item Qsc
|
||||||
|
The synthetic compare types--gt, lt, ge, and le.
|
||||||
|
@item Wab
|
||||||
|
A memory reference with an absolute address.
|
||||||
|
@item Wbc
|
||||||
|
A memory reference using @code{BC} as a base register, with an optional offset.
|
||||||
|
@item Wca
|
||||||
|
A memory reference using @code{AX}, @code{BC}, @code{DE}, or @code{HL} for the address, for calls.
|
||||||
|
@item Wcv
|
||||||
|
A memory reference using any 16-bit register pair for the address, for calls.
|
||||||
|
@item Wd2
|
||||||
|
A memory reference using @code{DE} as a base register, with an optional offset.
|
||||||
|
@item Wde
|
||||||
|
A memory reference using @code{DE} as a base register, without any offset.
|
||||||
|
@item Wfr
|
||||||
|
Any memory reference to an address in the far address space.
|
||||||
|
@item Wh1
|
||||||
|
A memory reference using @code{HL} as a base register, with an optional one-byte offset.
|
||||||
|
@item Whb
|
||||||
|
A memory reference using @code{HL} as a base register, with @code{B} or @code{C} as the index register.
|
||||||
|
@item Whl
|
||||||
|
A memory reference using @code{HL} as a base register, without any offset.
|
||||||
|
@item Ws1
|
||||||
|
A memory reference using @code{SP} as a base register, with an optional one-byte offset.
|
||||||
|
@item Y
|
||||||
|
Any memory reference to an address in the near address space.
|
||||||
|
@item A
|
||||||
|
The @code{AX} register.
|
||||||
|
@item B
|
||||||
|
The @code{BC} register.
|
||||||
|
@item D
|
||||||
|
The @code{DE} register.
|
||||||
|
@item R
|
||||||
|
@code{A} through @code{L} registers.
|
||||||
|
@item S
|
||||||
|
The @code{SP} register.
|
||||||
|
@item T
|
||||||
|
The @code{HL} register.
|
||||||
|
@item Z08W
|
||||||
|
The 16-bit @code{R8} register.
|
||||||
|
@item Z10W
|
||||||
|
The 16-bit @code{R10} register.
|
||||||
|
@item Zint
|
||||||
|
The registers reserved for interrupts (@code{R24} to @code{R31}).
|
||||||
|
@item a
|
||||||
|
The @code{A} register.
|
||||||
|
@item b
|
||||||
|
The @code{B} register.
|
||||||
|
@item c
|
||||||
|
The @code{C} register.
|
||||||
|
@item d
|
||||||
|
The @code{D} register.
|
||||||
|
@item e
|
||||||
|
The @code{E} register.
|
||||||
|
@item h
|
||||||
|
The @code{H} register.
|
||||||
|
@item l
|
||||||
|
The @code{L} register.
|
||||||
|
@item v
|
||||||
|
The virtual registers.
|
||||||
|
@item w
|
||||||
|
The @code{PSW} register.
|
||||||
|
@item x
|
||||||
|
The @code{X} register.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
@item RX---@file{config/rx/constraints.md}
|
@item RX---@file{config/rx/constraints.md}
|
||||||
@table @code
|
@table @code
|
||||||
@item Q
|
@item Q
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2011-11-29 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* config.host (rl78-*-elf): New case.
|
||||||
|
* config/rl78: New directory for the Renesas RL78.
|
||||||
|
|
||||||
2011-11-29 Bernd Schmidt <bernds@codesourcery.com>
|
2011-11-29 Bernd Schmidt <bernds@codesourcery.com>
|
||||||
|
|
||||||
* config.host (tic6x-*-uclinux): Append to extra_parts. Fix
|
* config.host (tic6x-*-uclinux): Append to extra_parts. Fix
|
||||||
|
|
|
@ -916,6 +916,9 @@ rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
|
||||||
md_unwind_header=rs6000/aix-unwind.h
|
md_unwind_header=rs6000/aix-unwind.h
|
||||||
tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-ibm-ldouble rs6000/t-slibgcc-aix"
|
tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-ibm-ldouble rs6000/t-slibgcc-aix"
|
||||||
;;
|
;;
|
||||||
|
rl78-*-elf)
|
||||||
|
tmake_file="$tm_file t-fdpbit rl78/t-rl78"
|
||||||
|
;;
|
||||||
rx-*-elf)
|
rx-*-elf)
|
||||||
tmake_file="rx/t-rx t-fdpbit"
|
tmake_file="rx/t-rx t-fdpbit"
|
||||||
tm_file="$tm_file rx/rx-abi.h rx/rx-lib.h"
|
tm_file="$tm_file rx/rx-abi.h rx/rx-lib.h"
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
; Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
; Contributed by Red Hat.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
; permissions described in the GCC Runtime Library Exception, version
|
||||||
|
; 3.1, as published by the Free Software Foundation.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License and
|
||||||
|
; a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
; clobberable
|
||||||
|
r8 = 0xffef0
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
;; int __cmpsi2 (signed long A, signed long B)
|
||||||
|
;;
|
||||||
|
;; Performs a signed comparison of A and B.
|
||||||
|
;; If A is less than B it returns 0. If A is greater
|
||||||
|
;; than B it returns 2. If they are equal it returns 1.
|
||||||
|
|
||||||
|
.global ___cmpsi2
|
||||||
|
.type ___cmpsi2, @function
|
||||||
|
___cmpsi2:
|
||||||
|
;; A is at [sp+4]
|
||||||
|
;; B is at [sp+8]
|
||||||
|
;; Result put in R8
|
||||||
|
|
||||||
|
;; Initialise default return value.
|
||||||
|
onew bc
|
||||||
|
|
||||||
|
;; Compare the high words.
|
||||||
|
movw ax, [sp + 10]
|
||||||
|
movw de, ax
|
||||||
|
movw ax, [sp + 6]
|
||||||
|
cmpw ax, de
|
||||||
|
skz
|
||||||
|
br !!.Lconvert_to_signed
|
||||||
|
|
||||||
|
.Lcompare_bottom_words:
|
||||||
|
;; The top words are equal - compare the bottom words.
|
||||||
|
;; Note - code from __ucmpsi2 branches into here.
|
||||||
|
movw ax, [sp + 8]
|
||||||
|
movw de, ax
|
||||||
|
movw ax, [sp + 4]
|
||||||
|
cmpw ax, de
|
||||||
|
sknz
|
||||||
|
br !!.Lless_than_or_greater_than
|
||||||
|
;; The words are equal - return 1.
|
||||||
|
;; Note - we could branch to the return code at the end of the
|
||||||
|
;; function but a branch instruction takes 4 bytes, and the
|
||||||
|
;; return sequence itself is only 4 bytes long...
|
||||||
|
movw ax, bc
|
||||||
|
movw r8, ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.Lconvert_to_signed:
|
||||||
|
;; The top words are different. Unfortunately the comparison
|
||||||
|
;; is always unsigned, so to get a signed result we XOR the CY
|
||||||
|
;; flag with the top bits of AX and DE.
|
||||||
|
xor1 cy, a.7
|
||||||
|
mov a, d
|
||||||
|
xor1 cy, a.7
|
||||||
|
;; Fall through.
|
||||||
|
|
||||||
|
.Lless_than_or_greater_than:
|
||||||
|
;; We now have a signed less than/greater than result in CY.
|
||||||
|
;; Return 0 for less than, 2 for greater than.
|
||||||
|
;; Note - code from __ucmpsi2 branches into here.
|
||||||
|
incw bc
|
||||||
|
sknc
|
||||||
|
clrw bc
|
||||||
|
|
||||||
|
;; Get the result value, currently in BC, into r8
|
||||||
|
movw ax, bc
|
||||||
|
movw r8, ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.size ___cmpsi2, . - ___cmpsi2
|
||||||
|
|
||||||
|
|
||||||
|
;; int __ucmpsi2 (unsigned long A, unsigned long B)
|
||||||
|
;;
|
||||||
|
;; Performs an unsigned comparison of A and B.
|
||||||
|
;; If A is less than B it returns 0. If A is greater
|
||||||
|
;; than B it returns 2. If they are equal it returns 1.
|
||||||
|
|
||||||
|
.global ___ucmpsi2
|
||||||
|
.type ___ucmpsi2, @function
|
||||||
|
___ucmpsi2:
|
||||||
|
;; A is at [sp+4]
|
||||||
|
;; B is at [sp+8]
|
||||||
|
;; Result put in R8..R9
|
||||||
|
|
||||||
|
;; Initialise default return value.
|
||||||
|
onew bc
|
||||||
|
|
||||||
|
;; Compare the high words.
|
||||||
|
movw ax, [sp + 10]
|
||||||
|
movw de, ax
|
||||||
|
movw ax, [sp + 6]
|
||||||
|
cmpw ax, de
|
||||||
|
skz
|
||||||
|
;; Note: These branches go into the __cmpsi2 code!
|
||||||
|
br !!.Lless_than_or_greater_than
|
||||||
|
br !!.Lcompare_bottom_words
|
||||||
|
|
||||||
|
.size ___ucmpsi2, . - ___ucmpsi2
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* libgcc routines for RL78
|
||||||
|
Copyright (C) 2005, 2009, 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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
typedef int sint32_type __attribute__ ((mode (SI)));
|
||||||
|
typedef unsigned int uint32_type __attribute__ ((mode (SI)));
|
||||||
|
typedef int sint16_type __attribute__ ((mode (HI)));
|
||||||
|
typedef unsigned int uint16_type __attribute__ ((mode (HI)));
|
||||||
|
typedef int sint08_type __attribute__ ((mode (QI)));
|
||||||
|
typedef unsigned int uint08_type __attribute__ ((mode (QI)));
|
||||||
|
typedef int word_type __attribute__ ((mode (__word__)));
|
||||||
|
|
||||||
|
#define C3B(a,b,c) a##b##c
|
||||||
|
#define C3(a,b,c) C3B(a,b,c)
|
||||||
|
|
||||||
|
#define UINT_TYPE uint32_type
|
||||||
|
#define SINT_TYPE sint32_type
|
||||||
|
#define BITS_MINUS_1 31
|
||||||
|
#define NAME_MODE si
|
||||||
|
|
||||||
|
#include "rl78-divmod.h"
|
||||||
|
|
||||||
|
#undef UINT_TYPE
|
||||||
|
#undef SINT_TYPE
|
||||||
|
#undef BITS_MINUS_1
|
||||||
|
#undef NAME_MODE
|
||||||
|
|
||||||
|
#define UINT_TYPE uint16_type
|
||||||
|
#define SINT_TYPE sint16_type
|
||||||
|
#define BITS_MINUS_1 15
|
||||||
|
#define NAME_MODE hi
|
||||||
|
|
||||||
|
#include "rl78-divmod.h"
|
||||||
|
|
||||||
|
#undef UINT_TYPE
|
||||||
|
#undef SINT_TYPE
|
||||||
|
#undef BITS_MINUS_1
|
||||||
|
#undef NAME_MODE
|
||||||
|
|
||||||
|
#define UINT_TYPE uint08_type
|
||||||
|
#define SINT_TYPE sint08_type
|
||||||
|
#define BITS_MINUS_1 7
|
||||||
|
#define NAME_MODE qi
|
||||||
|
|
||||||
|
#include "rl78-divmod.h"
|
||||||
|
|
||||||
|
/* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in
|
||||||
|
m32c.h for why we are creating extra versions of some of the
|
||||||
|
functions defined in libgcc2.c. */
|
||||||
|
|
||||||
|
#define LIBGCC2_UNITS_PER_WORD 2
|
||||||
|
|
||||||
|
#define L_clzsi2
|
||||||
|
#define L_ctzsi2
|
||||||
|
#define L_ffssi2
|
||||||
|
#define L_paritysi2
|
||||||
|
#define L_popcountsi2
|
||||||
|
|
||||||
|
#include "libgcc2.c"
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* libgcc routines for RL78
|
||||||
|
Copyright (C) 2005, 2009, 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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
typedef unsigned int uint32_type __attribute__ ((mode (SI)));
|
||||||
|
typedef unsigned int uint16_type __attribute__ ((mode (HI)));
|
||||||
|
typedef unsigned int uint08_type __attribute__ ((mode (QI)));
|
||||||
|
|
||||||
|
#define C3B(a,b,c) a##b##c
|
||||||
|
#define C3(a,b,c) C3B(a,b,c)
|
||||||
|
|
||||||
|
|
||||||
|
#define UINT_TYPE uint16_type
|
||||||
|
#define BITS_MINUS_1 15
|
||||||
|
#define NAME_MODE hi
|
||||||
|
|
||||||
|
/*#include "rl78-mul.h"*/
|
||||||
|
|
||||||
|
#undef UINT_TYPE
|
||||||
|
#undef BITS_MINUS_1
|
||||||
|
#undef NAME_MODE
|
||||||
|
|
||||||
|
#define UINT_TYPE uint08_type
|
||||||
|
#define BITS_MINUS_1 7
|
||||||
|
#define NAME_MODE qi
|
||||||
|
|
||||||
|
#include "rl78-mul.h"
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* Shift functions for the GCC support library for the 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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
typedef int sint32_type __attribute__ ((mode (SI)));
|
||||||
|
typedef unsigned int uint32_type __attribute__ ((mode (SI)));
|
||||||
|
typedef int sint16_type __attribute__ ((mode (HI)));
|
||||||
|
typedef unsigned int uint16_type __attribute__ ((mode (HI)));
|
||||||
|
|
||||||
|
uint32_type __ashlsi3 (uint32_type in, char bit);
|
||||||
|
sint32_type __ashrsi3 (sint32_type in, char bit);
|
||||||
|
int __clrsbhi2 (sint16_type x);
|
||||||
|
extern int __clrsbsi2 (sint32_type x);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_type u;
|
||||||
|
uint16_type h[2];
|
||||||
|
} u;
|
||||||
|
} dd;
|
||||||
|
|
||||||
|
uint32_type
|
||||||
|
__ashlsi3 (uint32_type in, char bit)
|
||||||
|
{
|
||||||
|
uint16_type h, l;
|
||||||
|
dd d;
|
||||||
|
|
||||||
|
if (bit > 32)
|
||||||
|
return 0;
|
||||||
|
if (bit < 0)
|
||||||
|
return in;
|
||||||
|
|
||||||
|
d.u.u = in;
|
||||||
|
h = d.u.h[1];
|
||||||
|
l = d.u.h[0];
|
||||||
|
|
||||||
|
if (bit > 15)
|
||||||
|
{
|
||||||
|
h = l;
|
||||||
|
l = 0;
|
||||||
|
bit -= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bit)
|
||||||
|
{
|
||||||
|
h = (h << 1) | (l >> 15);
|
||||||
|
l <<= 1;
|
||||||
|
bit --;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.u.h[1] = h;
|
||||||
|
d.u.h[0] = l;
|
||||||
|
return d.u.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32_type
|
||||||
|
__ashrsi3 (sint32_type in, char bit)
|
||||||
|
{
|
||||||
|
sint16_type h;
|
||||||
|
uint16_type l;
|
||||||
|
dd d;
|
||||||
|
|
||||||
|
if (bit > 32)
|
||||||
|
return 0;
|
||||||
|
if (bit < 0)
|
||||||
|
return in;
|
||||||
|
|
||||||
|
d.u.u = in;
|
||||||
|
h = d.u.h[1];
|
||||||
|
l = d.u.h[0];
|
||||||
|
|
||||||
|
while (bit)
|
||||||
|
{
|
||||||
|
l = (h << 15) | (l >> 1);
|
||||||
|
h >>= 1;
|
||||||
|
bit --;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.u.h[1] = h;
|
||||||
|
d.u.h[0] = l;
|
||||||
|
return d.u.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__clrsbhi2 (sint16_type x)
|
||||||
|
{
|
||||||
|
if (x == 0)
|
||||||
|
return 15;
|
||||||
|
return __clrsbsi2 ((sint32_type) x) - 16;
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
; Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
; Contributed by Red Hat.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
; permissions described in the GCC Runtime Library Exception, version
|
||||||
|
; 3.1, as published by the Free Software Foundation.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License and
|
||||||
|
; a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
r8 = 0xffef0
|
||||||
|
r16 = 0xffee8
|
||||||
|
r9 = 0xffef1
|
||||||
|
r17 = 0xffee9
|
||||||
|
r10 = 0xffef2
|
||||||
|
r18 = 0xffeea
|
||||||
|
r11 = 0xffef3
|
||||||
|
r19 = 0xffeeb
|
||||||
|
r12 = 0xffef4
|
||||||
|
r20 = 0xffeec
|
||||||
|
r13 = 0xffef5
|
||||||
|
r21 = 0xffeed
|
||||||
|
r14 = 0xffef6
|
||||||
|
r22 = 0xffeee
|
||||||
|
r15 = 0xffef7
|
||||||
|
r23 = 0xffeef
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global ___lshrsi3
|
||||||
|
.type ___lshrsi3, @function
|
||||||
|
___lshrsi3:
|
||||||
|
|
||||||
|
;; input:
|
||||||
|
;;
|
||||||
|
;; [zero]
|
||||||
|
;; [count] <= $sp+8
|
||||||
|
;; [in MSB]
|
||||||
|
;; [in]
|
||||||
|
;; [in]
|
||||||
|
;; [in LSB] <- $sp+4
|
||||||
|
|
||||||
|
;; output:
|
||||||
|
;;
|
||||||
|
;; [r8..r11] result
|
||||||
|
|
||||||
|
;; registers:
|
||||||
|
;;
|
||||||
|
;; AX - temp for shift/rotate
|
||||||
|
;; B - count
|
||||||
|
|
||||||
|
mov a, [sp+8] ; A now contains the count
|
||||||
|
|
||||||
|
cmp a, #0x20
|
||||||
|
bc $.Lcount_is_normal
|
||||||
|
|
||||||
|
;; count is out of bounds, just return zero.
|
||||||
|
movw r8, #0
|
||||||
|
movw r10, #0
|
||||||
|
ret
|
||||||
|
|
||||||
|
.Lcount_is_normal:
|
||||||
|
cmp0 a
|
||||||
|
bnz $.Lcount_is_nonzero
|
||||||
|
|
||||||
|
;; count is zero, just copy IN to OUT
|
||||||
|
movw ax, [sp+4]
|
||||||
|
movw r8, ax
|
||||||
|
movw ax, [sp+6]
|
||||||
|
movw r10, ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.Lcount_is_nonzero:
|
||||||
|
mov b, a ; B now contains the count also
|
||||||
|
bf a.4, $.Lcount_lt_16
|
||||||
|
|
||||||
|
;; count >= 16, shift 16 at a time.
|
||||||
|
movw r10, #0
|
||||||
|
movw ax, [sp+6]
|
||||||
|
movw r8, ax
|
||||||
|
mov a, b
|
||||||
|
and a, #0x0f
|
||||||
|
sknz
|
||||||
|
ret
|
||||||
|
|
||||||
|
mov b, a ; B now contains the remaining count
|
||||||
|
inc b
|
||||||
|
br $.Lloop_top
|
||||||
|
|
||||||
|
.Lcount_lt_16:
|
||||||
|
;; count is nonzero. Do one
|
||||||
|
movw ax, [sp+6]
|
||||||
|
shrw ax,1
|
||||||
|
movw r10, ax
|
||||||
|
mov a, [sp+5]
|
||||||
|
rorc a,1
|
||||||
|
mov r9, a
|
||||||
|
mov a, [sp+4]
|
||||||
|
rorc a,1
|
||||||
|
mov r8, a
|
||||||
|
|
||||||
|
;; we did one shift above; do as many more as we need now.
|
||||||
|
.Lloop_top:
|
||||||
|
dec b
|
||||||
|
sknz
|
||||||
|
ret
|
||||||
|
|
||||||
|
movw ax, r10
|
||||||
|
shrw ax,1
|
||||||
|
movw r10, ax
|
||||||
|
mov a, r9
|
||||||
|
rorc a,1
|
||||||
|
mov r9, a
|
||||||
|
mov a, r8
|
||||||
|
rorc a,1
|
||||||
|
mov r8, a
|
||||||
|
|
||||||
|
br $.Lloop_top
|
||||||
|
|
||||||
|
.size ___lshrsi3, .-___lshrsi3
|
|
@ -0,0 +1,235 @@
|
||||||
|
; Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
; Contributed by Red Hat.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; This file 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.
|
||||||
|
;
|
||||||
|
; Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
; permissions described in the GCC Runtime Library Exception, version
|
||||||
|
; 3.1, as published by the Free Software Foundation.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License and
|
||||||
|
; a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; 32x32=32 multiply
|
||||||
|
|
||||||
|
; real
|
||||||
|
; GAS defines r0..r7 as aliases for real registers; we want the saddr
|
||||||
|
; forms here.
|
||||||
|
r_0 = 0xffef8
|
||||||
|
r_1 = 0xffef9
|
||||||
|
r_2 = 0xffefa
|
||||||
|
r_3 = 0xffefb
|
||||||
|
r_4 = 0xffefc
|
||||||
|
r_5 = 0xffefd
|
||||||
|
r_6 = 0xffefe
|
||||||
|
r_7 = 0xffeff
|
||||||
|
; clobberable
|
||||||
|
r8 = 0xffef0
|
||||||
|
r9 = 0xffef1
|
||||||
|
r10 = 0xffef2
|
||||||
|
r11 = 0xffef3
|
||||||
|
r12 = 0xffef4
|
||||||
|
r13 = 0xffef5
|
||||||
|
r14 = 0xffef6
|
||||||
|
r15 = 0xffef7
|
||||||
|
; preserved
|
||||||
|
r16 = 0xffee8
|
||||||
|
r17 = 0xffee9
|
||||||
|
r18 = 0xffeea
|
||||||
|
r19 = 0xffeeb
|
||||||
|
r20 = 0xffeec
|
||||||
|
r21 = 0xffeed
|
||||||
|
r22 = 0xffeee
|
||||||
|
r23 = 0xffeef
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; Register use:
|
||||||
|
; RB0 RB1 RB2
|
||||||
|
; AX op2L res32L res32H
|
||||||
|
; BC op2H (resH) op1
|
||||||
|
; DE count (resL-tmp)
|
||||||
|
; HL [sp+4]
|
||||||
|
|
||||||
|
.text
|
||||||
|
nop
|
||||||
|
.global ___mulsi3 ; (USI a, USI b)
|
||||||
|
___mulsi3:
|
||||||
|
;; A is at [sp+4]
|
||||||
|
;; B is at [sp+8]
|
||||||
|
;; result is in R8..R11
|
||||||
|
|
||||||
|
movw ax, sp
|
||||||
|
addw ax, #4
|
||||||
|
movw hl, ax
|
||||||
|
|
||||||
|
sel rb2
|
||||||
|
push ax
|
||||||
|
push bc
|
||||||
|
sel rb0
|
||||||
|
|
||||||
|
clrw ax
|
||||||
|
movw r8, ax
|
||||||
|
movw r16, ax
|
||||||
|
|
||||||
|
movw ax, [hl+6]
|
||||||
|
cmpw ax, #0
|
||||||
|
bz $1f
|
||||||
|
cmpw ax, #0xffff
|
||||||
|
bnz $2f
|
||||||
|
movw ax, [hl]
|
||||||
|
sel rb1
|
||||||
|
subw ax, r_0
|
||||||
|
sel rb0
|
||||||
|
br $1f
|
||||||
|
2:
|
||||||
|
movw bc, ax
|
||||||
|
movw ax, [hl]
|
||||||
|
cmpw ax, #0
|
||||||
|
skz
|
||||||
|
call !.Lmul_hi
|
||||||
|
1:
|
||||||
|
|
||||||
|
movw ax, [hl+2]
|
||||||
|
cmpw ax, #0
|
||||||
|
bz $1f
|
||||||
|
cmpw ax, #0xffff
|
||||||
|
bnz $2f
|
||||||
|
movw ax, [hl+4]
|
||||||
|
sel rb1
|
||||||
|
subw ax, r_0
|
||||||
|
sel rb0
|
||||||
|
br $1f
|
||||||
|
2:
|
||||||
|
movw bc, ax
|
||||||
|
movw ax, [hl+4]
|
||||||
|
cmpw ax, #0
|
||||||
|
skz
|
||||||
|
call !.Lmul_hi
|
||||||
|
1:
|
||||||
|
|
||||||
|
movw ax, r8
|
||||||
|
movw r16, ax
|
||||||
|
clrw ax
|
||||||
|
movw r8, ax
|
||||||
|
|
||||||
|
;; now do R16:R8 += op1L * op2L
|
||||||
|
|
||||||
|
;; op1 is in AX.0 (needs to shrw)
|
||||||
|
;; op2 is in BC.2 and BC.1 (bc can shlw/rolcw)
|
||||||
|
;; res is in AX.2 and AX.1 (needs to addw)
|
||||||
|
|
||||||
|
movw ax, [hl]
|
||||||
|
movw r10, ax ; BC.1
|
||||||
|
movw ax, [hl+4]
|
||||||
|
|
||||||
|
cmpw ax, r10
|
||||||
|
bc $.Lmul_hisi_top
|
||||||
|
movw bc, r10
|
||||||
|
movw r10, ax
|
||||||
|
movw ax, bc
|
||||||
|
|
||||||
|
|
||||||
|
.Lmul_hisi_top:
|
||||||
|
movw bc, #0
|
||||||
|
|
||||||
|
.Lmul_hisi_loop:
|
||||||
|
shrw ax, 1
|
||||||
|
bnc $.Lmul_hisi_no_add
|
||||||
|
sel rb1
|
||||||
|
addw ax, bc
|
||||||
|
sel rb2
|
||||||
|
sknc
|
||||||
|
incw ax
|
||||||
|
addw ax, r_2
|
||||||
|
.Lmul_hisi_no_add:
|
||||||
|
sel rb1
|
||||||
|
shlw bc, 1
|
||||||
|
sel rb0
|
||||||
|
rolwc bc, 1
|
||||||
|
cmpw ax, #0
|
||||||
|
bz $.Lmul_hisi_done
|
||||||
|
|
||||||
|
shrw ax, 1
|
||||||
|
bnc $.Lmul_hisi_no_add2
|
||||||
|
sel rb1
|
||||||
|
addw ax, bc
|
||||||
|
sel rb2
|
||||||
|
sknc
|
||||||
|
incw ax
|
||||||
|
addw ax, r_2
|
||||||
|
.Lmul_hisi_no_add2:
|
||||||
|
sel rb1
|
||||||
|
shlw bc, 1
|
||||||
|
sel rb0
|
||||||
|
rolwc bc, 1
|
||||||
|
cmpw ax, #0
|
||||||
|
bnz $.Lmul_hisi_loop
|
||||||
|
|
||||||
|
.Lmul_hisi_done:
|
||||||
|
|
||||||
|
movw ax, r16
|
||||||
|
movw r10, ax
|
||||||
|
|
||||||
|
sel rb2
|
||||||
|
pop bc
|
||||||
|
pop ax
|
||||||
|
sel rb0
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------
|
||||||
|
|
||||||
|
;; R8 += AX * BC
|
||||||
|
.Lmul_hi:
|
||||||
|
cmpw ax, bc
|
||||||
|
skc
|
||||||
|
xchw ax, bc
|
||||||
|
br $.Lmul_hi_loop
|
||||||
|
|
||||||
|
.Lmul_hi_top:
|
||||||
|
sel rb1
|
||||||
|
addw ax, r_2
|
||||||
|
sel rb0
|
||||||
|
.Lmul_hi_no_add:
|
||||||
|
shlw bc, 1
|
||||||
|
.Lmul_hi_loop:
|
||||||
|
shrw ax, 1
|
||||||
|
bc $.Lmul_hi_top
|
||||||
|
cmpw ax, #0
|
||||||
|
bz $.Lmul_hi_done
|
||||||
|
|
||||||
|
shlw bc, 1
|
||||||
|
shrw ax, 1
|
||||||
|
bc $.Lmul_hi_top
|
||||||
|
cmpw ax, #0
|
||||||
|
bnz $.Lmul_hi_no_add
|
||||||
|
|
||||||
|
.Lmul_hi_done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------
|
||||||
|
|
||||||
|
.global ___mulhi3
|
||||||
|
___mulhi3:
|
||||||
|
sel rb1
|
||||||
|
clrw ax
|
||||||
|
sel rb0
|
||||||
|
movw ax, sp
|
||||||
|
addw ax, #4
|
||||||
|
movw hl, ax
|
||||||
|
movw ax, [hl+2]
|
||||||
|
movw bc, ax
|
||||||
|
movw ax, [hl]
|
||||||
|
br $.Lmul_hi
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* libgcc routines for RL78
|
||||||
|
Copyright (C) 2005, 2009, 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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
UINT_TYPE C3(udivmod,NAME_MODE,4) (UINT_TYPE, UINT_TYPE, word_type);
|
||||||
|
SINT_TYPE C3(__div,NAME_MODE,3) (SINT_TYPE, SINT_TYPE);
|
||||||
|
SINT_TYPE C3(__mod,NAME_MODE,3) (SINT_TYPE, SINT_TYPE);
|
||||||
|
UINT_TYPE C3(__udiv,NAME_MODE,3) (UINT_TYPE, UINT_TYPE);
|
||||||
|
UINT_TYPE C3(__umod,NAME_MODE,3) (UINT_TYPE, UINT_TYPE);
|
||||||
|
|
||||||
|
UINT_TYPE
|
||||||
|
C3(udivmod,NAME_MODE,4) (UINT_TYPE num, UINT_TYPE den, word_type modwanted)
|
||||||
|
{
|
||||||
|
UINT_TYPE bit = 1;
|
||||||
|
UINT_TYPE res = 0;
|
||||||
|
|
||||||
|
while (den < num && bit && !(den & (1L << BITS_MINUS_1)))
|
||||||
|
{
|
||||||
|
den <<= 1;
|
||||||
|
bit <<= 1;
|
||||||
|
}
|
||||||
|
while (bit)
|
||||||
|
{
|
||||||
|
if (num >= den)
|
||||||
|
{
|
||||||
|
num -= den;
|
||||||
|
res |= bit;
|
||||||
|
}
|
||||||
|
bit >>= 1;
|
||||||
|
den >>= 1;
|
||||||
|
}
|
||||||
|
if (modwanted)
|
||||||
|
return num;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SINT_TYPE
|
||||||
|
C3(__div,NAME_MODE,3) (SINT_TYPE a, SINT_TYPE b)
|
||||||
|
{
|
||||||
|
word_type neg = 0;
|
||||||
|
SINT_TYPE res;
|
||||||
|
|
||||||
|
if (a < 0)
|
||||||
|
{
|
||||||
|
a = -a;
|
||||||
|
neg = !neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b < 0)
|
||||||
|
{
|
||||||
|
b = -b;
|
||||||
|
neg = !neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = C3(udivmod,NAME_MODE,4) (a, b, 0);
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
res = -res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SINT_TYPE
|
||||||
|
C3(__mod,NAME_MODE,3) (SINT_TYPE a, SINT_TYPE b)
|
||||||
|
{
|
||||||
|
word_type neg = 0;
|
||||||
|
SINT_TYPE res;
|
||||||
|
|
||||||
|
if (a < 0)
|
||||||
|
{
|
||||||
|
a = -a;
|
||||||
|
neg = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b < 0)
|
||||||
|
b = -b;
|
||||||
|
|
||||||
|
res = C3(udivmod,NAME_MODE,4) (a, b, 1);
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
res = -res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT_TYPE
|
||||||
|
C3(__udiv,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b)
|
||||||
|
{
|
||||||
|
return C3(udivmod,NAME_MODE,4) (a, b, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT_TYPE
|
||||||
|
C3(__umod,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b)
|
||||||
|
{
|
||||||
|
return C3(udivmod,NAME_MODE,4) (a, b, 1);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* libgcc routines for RL78
|
||||||
|
Copyright (C) 2005, 2009, 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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
UINT_TYPE C3(__mul,NAME_MODE,3) (UINT_TYPE, UINT_TYPE);
|
||||||
|
UINT_TYPE
|
||||||
|
C3(__mul,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b)
|
||||||
|
{
|
||||||
|
UINT_TYPE rv = 0;
|
||||||
|
|
||||||
|
char bit;
|
||||||
|
|
||||||
|
for (bit=0; b && bit<sizeof(UINT_TYPE)*8; bit++)
|
||||||
|
{
|
||||||
|
if (b & 1)
|
||||||
|
rv += a;
|
||||||
|
a <<= 1;
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Makefile fragment for building LIBGCC for the Renesas RL78 target.
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
LIB2ADD = \
|
||||||
|
$(srcdir)/config/rl78/trampoline.S \
|
||||||
|
$(srcdir)/config/rl78/lib2div.c \
|
||||||
|
$(srcdir)/config/rl78/lib2mul.c \
|
||||||
|
$(srcdir)/config/rl78/lib2shift.c \
|
||||||
|
$(srcdir)/config/rl78/lshrsi3.S \
|
||||||
|
$(srcdir)/config/rl78/mulsi3.S \
|
||||||
|
$(srcdir)/config/rl78/cmpsi2.S
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* libgcc routines for RL78
|
||||||
|
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.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* RL78 Trampoline support
|
||||||
|
|
||||||
|
Since the RL78's RAM is not in the first 64k, we cannot "just" use a
|
||||||
|
function pointer to point to a trampoline on the stack. So, we
|
||||||
|
create N fixed trampolines that read from an array, and allocate
|
||||||
|
them as needed.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
r8 = 0xffef0
|
||||||
|
r10 = 0xffef2
|
||||||
|
r14 = 0xffef6
|
||||||
|
|
||||||
|
.data
|
||||||
|
.p2align 1
|
||||||
|
trampoline_array:
|
||||||
|
|
||||||
|
.macro stub n
|
||||||
|
|
||||||
|
.text
|
||||||
|
trampoline_\n:
|
||||||
|
.type trampoline_\n, @function
|
||||||
|
movw ax, !trampoline_chain_\n
|
||||||
|
movw r14, ax
|
||||||
|
movw ax, !trampoline_addr_\n
|
||||||
|
br ax
|
||||||
|
.size trampoline_\n, .-trampoline_\n
|
||||||
|
|
||||||
|
.data
|
||||||
|
trampoline_frame_\n:
|
||||||
|
.short 0
|
||||||
|
trampoline_stub_\n:
|
||||||
|
.short trampoline_\n
|
||||||
|
trampoline_chain_\n:
|
||||||
|
.short 0
|
||||||
|
trampoline_addr_\n:
|
||||||
|
.short 0
|
||||||
|
|
||||||
|
#define TO_FRAME 0
|
||||||
|
#define TO_STUB 2
|
||||||
|
#define TO_CHAIN 4
|
||||||
|
#define TO_ADDR 6
|
||||||
|
#define TO_SIZE 8
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
stub 0
|
||||||
|
stub 1
|
||||||
|
stub 2
|
||||||
|
stub 3
|
||||||
|
stub 4
|
||||||
|
stub 5
|
||||||
|
|
||||||
|
trampoline_array_end:
|
||||||
|
|
||||||
|
/* Given the function pointer in R8 and the static chain
|
||||||
|
pointer in R10, allocate a trampoline and return its address in
|
||||||
|
R8. */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global ___trampoline_init
|
||||||
|
.type ___trampoline_init, @function
|
||||||
|
___trampoline_init:
|
||||||
|
|
||||||
|
movw hl, #trampoline_array
|
||||||
|
1:
|
||||||
|
movw ax, [hl + TO_ADDR]
|
||||||
|
cmpw ax, #0
|
||||||
|
bz $2f
|
||||||
|
|
||||||
|
movw ax, hl
|
||||||
|
addw ax, #TO_SIZE
|
||||||
|
movw hl, ax
|
||||||
|
cmpw ax, #trampoline_array_end
|
||||||
|
bnz $1b
|
||||||
|
brk ; no more slots?
|
||||||
|
|
||||||
|
2: movw ax, r8
|
||||||
|
movw [hl + TO_ADDR], ax
|
||||||
|
movw ax, r10
|
||||||
|
movw [hl + TO_CHAIN], ax
|
||||||
|
movw ax, sp
|
||||||
|
movw [hl + TO_FRAME], ax
|
||||||
|
|
||||||
|
movw ax, [hl + TO_STUB]
|
||||||
|
movw r8, ax
|
||||||
|
|
||||||
|
ret
|
||||||
|
.size ___trampoline_init, . - ___trampoline_init
|
||||||
|
|
||||||
|
.global ___trampoline_uninit
|
||||||
|
.type ___trampoline_uninit, @function
|
||||||
|
___trampoline_uninit:
|
||||||
|
movw hl, #trampoline_array
|
||||||
|
movw ax, sp
|
||||||
|
movw bc, ax
|
||||||
|
1:
|
||||||
|
movw ax, [hl + TO_FRAME]
|
||||||
|
cmpw ax, bc
|
||||||
|
bc $2f
|
||||||
|
|
||||||
|
clrw ax
|
||||||
|
movw [hl + TO_ADDR], ax
|
||||||
|
|
||||||
|
2:
|
||||||
|
movw ax, hl
|
||||||
|
addw ax, #TO_SIZE
|
||||||
|
movw hl, ax
|
||||||
|
cmpw ax, #trampoline_array_end
|
||||||
|
bnz $1b
|
||||||
|
|
||||||
|
ret
|
||||||
|
.size ___trampoline_uninit, . - ___trampoline_uninit
|
Loading…
Reference in New Issue