* 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:
DJ Delorie 2011-11-29 16:36:43 -05:00 committed by DJ Delorie
parent c360c0fb8a
commit 85b8555ed3
38 changed files with 6095 additions and 8 deletions

View File

@ -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.

View File

@ -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
View File

@ -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.

View File

@ -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.

View File

@ -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 '.'.

View File

@ -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 \

View File

@ -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

View File

@ -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"

View 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"))

View 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
View 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);
}

View 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);"
)

View 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

View 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);

View 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"
)

View 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

File diff suppressed because it is too large Load Diff

462
gcc/config/rl78/rl78.h Normal file
View 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
View 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
View 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
View 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) $<

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View 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"

View 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"

View 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;
}

View 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
View 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

View 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);
}

View 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
View 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

View 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