.
* 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
38 changed files with 6095 additions and 8 deletions
|
@ -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>
|
||||
|
||||
* 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
|
||||
picochip port Hariharan Sandanagobalane hariharan@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 David Edelsohn dje.gcc@gmail.com
|
||||
rs6000 vector extns Aldy Hernandez aldyh@redhat.com
|
||||
|
|
4
configure
vendored
4
configure
vendored
|
@ -3092,6 +3092,10 @@ case "${target}" in
|
|||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
noconfigdirs="$noconfigdirs target-libssp"
|
||||
;;
|
||||
rl78-*-*)
|
||||
# Dereferencing -1 is a compile-time error
|
||||
noconfigdirs="$noconfigdirs target-libssp"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Disable libstdc++-v3 for some systems.
|
||||
|
|
|
@ -518,6 +518,12 @@ case "${target}" in
|
|||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
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
|
||||
|
||||
# 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>
|
||||
|
||||
* 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 \
|
||||
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 \
|
||||
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 \
|
||||
sh64-elfOPT-with-newlib sh-rtems sh-wrs-vxworks sparc-elf \
|
||||
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>
|
||||
|
||||
PR tree-optimization/51247
|
||||
|
|
|
@ -2115,6 +2115,13 @@ rs6000-ibm-aix[6789].* | powerpc-ibm-aix[6789].*)
|
|||
use_gcc_stdint=wrap
|
||||
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*)
|
||||
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
||||
tmake_file="${tmake_file} rx/t-rx"
|
||||
|
|
266
gcc/config/rl78/constraints.md
Normal file
266
gcc/config/rl78/constraints.md
Normal file
|
@ -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"))
|
60
gcc/config/rl78/predicates.md
Normal file
60
gcc/config/rl78/predicates.md
Normal file
|
@ -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")))
|
43
gcc/config/rl78/rl78-c.c
Normal file
43
gcc/config/rl78/rl78-c.c
Normal file
|
@ -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);
|
||||
}
|
256
gcc/config/rl78/rl78-expand.md
Normal file
256
gcc/config/rl78/rl78-expand.md
Normal file
|
@ -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);"
|
||||
)
|
30
gcc/config/rl78/rl78-opts.h
Normal file
30
gcc/config/rl78/rl78-opts.h
Normal file
|
@ -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
|
43
gcc/config/rl78/rl78-protos.h
Normal file
43
gcc/config/rl78/rl78-protos.h
Normal file
|
@ -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);
|
339
gcc/config/rl78/rl78-real.md
Normal file
339
gcc/config/rl78/rl78-real.md
Normal file
|
@ -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"
|
||||
)
|
259
gcc/config/rl78/rl78-virt.md
Normal file
259
gcc/config/rl78/rl78-virt.md
Normal file
|
@ -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);"
|
||||
)
|
2705
gcc/config/rl78/rl78.c
Normal file
2705
gcc/config/rl78/rl78.c
Normal file
File diff suppressed because it is too large
Load diff
462
gcc/config/rl78/rl78.h
Normal file
462
gcc/config/rl78/rl78.h
Normal file
|
@ -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()
|
320
gcc/config/rl78/rl78.md
Normal file
320
gcc/config/rl78/rl78.md
Normal file
|
@ -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")]
|
||||
)
|
43
gcc/config/rl78/rl78.opt
Normal file
43
gcc/config/rl78/rl78.opt
Normal file
|
@ -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)
|
22
gcc/config/rl78/t-rl78
Normal file
22
gcc/config/rl78/t-rl78
Normal file
|
@ -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
|
||||
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
|
||||
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
|
||||
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.
|
||||
Calling conventions for any target might also change. At present, only
|
||||
the SPU and M32C targets support other address spaces. On the SPU target, for
|
||||
example, variables may be declared as belonging to another address space
|
||||
by qualifying the type with the @code{__ea} address space identifier:
|
||||
address spaces in GCC will evolve as the draft technical report
|
||||
changes. Calling conventions for any target might also change. At
|
||||
present, only the SPU, M32C, and RL78 targets support other address
|
||||
spaces. On the SPU target, for example, variables may be declared as
|
||||
belonging to another address space by qualifying the type with the
|
||||
@code{__ea} address space identifier:
|
||||
|
||||
@smallexample
|
||||
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
|
||||
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
|
||||
@section Arrays of Length Zero
|
||||
@cindex arrays of length zero
|
||||
|
@ -2553,7 +2559,7 @@ This attribute is ignored for R8C target.
|
|||
@item interrupt
|
||||
@cindex interrupt handler functions
|
||||
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
|
||||
sequences suitable for use in an interrupt handler when this attribute
|
||||
is present.
|
||||
|
@ -2611,6 +2617,10 @@ void __attribute__ ((interrupt, use_shadow_register_set,
|
|||
use_debug_exception_return)) v7 ();
|
||||
@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}")
|
||||
@cindex @code{ifunc} attribute
|
||||
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
|
||||
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
|
||||
<hr />
|
||||
@end html
|
||||
|
|
|
@ -778,6 +778,9 @@ Objective-C and Objective-C++ Dialects}.
|
|||
@emph{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}
|
||||
@gccoptlist{-mcpu=@var{cpu-type} @gol
|
||||
-mtune=@var{cpu-type} @gol
|
||||
|
@ -10303,6 +10306,7 @@ platform.
|
|||
* PDP-11 Options::
|
||||
* picoChip Options::
|
||||
* PowerPC Options::
|
||||
* RL78 Options::
|
||||
* RS/6000 and PowerPC Options::
|
||||
* RX 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}.
|
||||
|
||||
@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
|
||||
@subsection IBM 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
|
||||
|
||||
@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}
|
||||
@table @code
|
||||
@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>
|
||||
|
||||
* 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
|
||||
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)
|
||||
tmake_file="rx/t-rx t-fdpbit"
|
||||
tm_file="$tm_file rx/rx-abi.h rx/rx-lib.h"
|
||||
|
|
122
libgcc/config/rl78/cmpsi2.S
Normal file
122
libgcc/config/rl78/cmpsi2.S
Normal file
|
@ -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
|
||||
|
81
libgcc/config/rl78/lib2div.c
Normal file
81
libgcc/config/rl78/lib2div.c
Normal file
|
@ -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"
|
49
libgcc/config/rl78/lib2mul.c
Normal file
49
libgcc/config/rl78/lib2mul.c
Normal file
|
@ -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"
|
113
libgcc/config/rl78/lib2shift.c
Normal file
113
libgcc/config/rl78/lib2shift.c
Normal file
|
@ -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;
|
||||
}
|
131
libgcc/config/rl78/lshrsi3.S
Normal file
131
libgcc/config/rl78/lshrsi3.S
Normal file
|
@ -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
|
235
libgcc/config/rl78/mulsi3.S
Normal file
235
libgcc/config/rl78/mulsi3.S
Normal file
|
@ -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
|
118
libgcc/config/rl78/rl78-divmod.h
Normal file
118
libgcc/config/rl78/rl78-divmod.h
Normal file
|
@ -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);
|
||||
}
|
43
libgcc/config/rl78/rl78-mul.h
Normal file
43
libgcc/config/rl78/rl78-mul.h
Normal file
|
@ -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;
|
||||
}
|
28
libgcc/config/rl78/t-rl78
Normal file
28
libgcc/config/rl78/t-rl78
Normal file
|
@ -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
|
139
libgcc/config/rl78/trampoline.S
Normal file
139
libgcc/config/rl78/trampoline.S
Normal file
|
@ -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…
Add table
Reference in a new issue