aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2011-11-29 16:36:43 -0500
committerDJ Delorie <dj@gcc.gnu.org>2011-11-29 16:36:43 -0500
commit85b8555ed3c45855b237b0f3a044eefb9382255c (patch)
tree65c814557c3c0e61f746e922c96ca834174464c4 /libgcc
parentc360c0fb8a1dd8ef61d986671d02071075d2c0b9 (diff)
downloadgcc-85b8555ed3c45855b237b0f3a044eefb9382255c.zip
gcc-85b8555ed3c45855b237b0f3a044eefb9382255c.tar.gz
gcc-85b8555ed3c45855b237b0f3a044eefb9382255c.tar.bz2
.
* 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
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog5
-rw-r--r--libgcc/config.host3
-rw-r--r--libgcc/config/rl78/cmpsi2.S122
-rw-r--r--libgcc/config/rl78/lib2div.c81
-rw-r--r--libgcc/config/rl78/lib2mul.c49
-rw-r--r--libgcc/config/rl78/lib2shift.c113
-rw-r--r--libgcc/config/rl78/lshrsi3.S131
-rw-r--r--libgcc/config/rl78/mulsi3.S235
-rw-r--r--libgcc/config/rl78/rl78-divmod.h118
-rw-r--r--libgcc/config/rl78/rl78-mul.h43
-rw-r--r--libgcc/config/rl78/t-rl7828
-rw-r--r--libgcc/config/rl78/trampoline.S139
12 files changed, 1067 insertions, 0 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index aca72b0..bf07e10 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -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
diff --git a/libgcc/config.host b/libgcc/config.host
index 961c69f..f15282c 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -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"
diff --git a/libgcc/config/rl78/cmpsi2.S b/libgcc/config/rl78/cmpsi2.S
new file mode 100644
index 0000000..14fa3cf
--- /dev/null
+++ b/libgcc/config/rl78/cmpsi2.S
@@ -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
+ \ No newline at end of file
diff --git a/libgcc/config/rl78/lib2div.c b/libgcc/config/rl78/lib2div.c
new file mode 100644
index 0000000..679f26d
--- /dev/null
+++ b/libgcc/config/rl78/lib2div.c
@@ -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"
diff --git a/libgcc/config/rl78/lib2mul.c b/libgcc/config/rl78/lib2mul.c
new file mode 100644
index 0000000..123690b
--- /dev/null
+++ b/libgcc/config/rl78/lib2mul.c
@@ -0,0 +1,49 @@
+/* libgcc routines for RL78
+ Copyright (C) 2005, 2009, 2011
+ Free Software Foundation, Inc.
+ Contributed by Red Hat.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+typedef unsigned int uint32_type __attribute__ ((mode (SI)));
+typedef unsigned int uint16_type __attribute__ ((mode (HI)));
+typedef unsigned int uint08_type __attribute__ ((mode (QI)));
+
+#define C3B(a,b,c) a##b##c
+#define C3(a,b,c) C3B(a,b,c)
+
+
+#define UINT_TYPE uint16_type
+#define BITS_MINUS_1 15
+#define NAME_MODE hi
+
+/*#include "rl78-mul.h"*/
+
+#undef UINT_TYPE
+#undef BITS_MINUS_1
+#undef NAME_MODE
+
+#define UINT_TYPE uint08_type
+#define BITS_MINUS_1 7
+#define NAME_MODE qi
+
+#include "rl78-mul.h"
diff --git a/libgcc/config/rl78/lib2shift.c b/libgcc/config/rl78/lib2shift.c
new file mode 100644
index 0000000..c9db85e
--- /dev/null
+++ b/libgcc/config/rl78/lib2shift.c
@@ -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;
+}
diff --git a/libgcc/config/rl78/lshrsi3.S b/libgcc/config/rl78/lshrsi3.S
new file mode 100644
index 0000000..8422284
--- /dev/null
+++ b/libgcc/config/rl78/lshrsi3.S
@@ -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
diff --git a/libgcc/config/rl78/mulsi3.S b/libgcc/config/rl78/mulsi3.S
new file mode 100644
index 0000000..0bca43a
--- /dev/null
+++ b/libgcc/config/rl78/mulsi3.S
@@ -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
diff --git a/libgcc/config/rl78/rl78-divmod.h b/libgcc/config/rl78/rl78-divmod.h
new file mode 100644
index 0000000..8ea5e1e
--- /dev/null
+++ b/libgcc/config/rl78/rl78-divmod.h
@@ -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);
+}
diff --git a/libgcc/config/rl78/rl78-mul.h b/libgcc/config/rl78/rl78-mul.h
new file mode 100644
index 0000000..fc2cd6c
--- /dev/null
+++ b/libgcc/config/rl78/rl78-mul.h
@@ -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;
+}
diff --git a/libgcc/config/rl78/t-rl78 b/libgcc/config/rl78/t-rl78
new file mode 100644
index 0000000..d1a82a2
--- /dev/null
+++ b/libgcc/config/rl78/t-rl78
@@ -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
diff --git a/libgcc/config/rl78/trampoline.S b/libgcc/config/rl78/trampoline.S
new file mode 100644
index 0000000..ef3aa6c
--- /dev/null
+++ b/libgcc/config/rl78/trampoline.S
@@ -0,0 +1,139 @@
+/* libgcc routines for RL78
+ Copyright (C) 2011
+ Free Software Foundation, Inc.
+ Contributed by Red Hat.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* RL78 Trampoline support
+
+ Since the RL78's RAM is not in the first 64k, we cannot "just" use a
+ function pointer to point to a trampoline on the stack. So, we
+ create N fixed trampolines that read from an array, and allocate
+ them as needed.
+
+*/
+
+r8 = 0xffef0
+r10 = 0xffef2
+r14 = 0xffef6
+
+ .data
+ .p2align 1
+trampoline_array:
+
+ .macro stub n
+
+ .text
+trampoline_\n:
+ .type trampoline_\n, @function
+ movw ax, !trampoline_chain_\n
+ movw r14, ax
+ movw ax, !trampoline_addr_\n
+ br ax
+ .size trampoline_\n, .-trampoline_\n
+
+ .data
+trampoline_frame_\n:
+ .short 0
+trampoline_stub_\n:
+ .short trampoline_\n
+trampoline_chain_\n:
+ .short 0
+trampoline_addr_\n:
+ .short 0
+
+#define TO_FRAME 0
+#define TO_STUB 2
+#define TO_CHAIN 4
+#define TO_ADDR 6
+#define TO_SIZE 8
+
+ .endm
+
+ stub 0
+ stub 1
+ stub 2
+ stub 3
+ stub 4
+ stub 5
+
+trampoline_array_end:
+
+/* Given the function pointer in R8 and the static chain
+ pointer in R10, allocate a trampoline and return its address in
+ R8. */
+
+ .text
+ .global ___trampoline_init
+ .type ___trampoline_init, @function
+___trampoline_init:
+
+ movw hl, #trampoline_array
+1:
+ movw ax, [hl + TO_ADDR]
+ cmpw ax, #0
+ bz $2f
+
+ movw ax, hl
+ addw ax, #TO_SIZE
+ movw hl, ax
+ cmpw ax, #trampoline_array_end
+ bnz $1b
+ brk ; no more slots?
+
+2: movw ax, r8
+ movw [hl + TO_ADDR], ax
+ movw ax, r10
+ movw [hl + TO_CHAIN], ax
+ movw ax, sp
+ movw [hl + TO_FRAME], ax
+
+ movw ax, [hl + TO_STUB]
+ movw r8, ax
+
+ ret
+ .size ___trampoline_init, . - ___trampoline_init
+
+ .global ___trampoline_uninit
+ .type ___trampoline_uninit, @function
+___trampoline_uninit:
+ movw hl, #trampoline_array
+ movw ax, sp
+ movw bc, ax
+1:
+ movw ax, [hl + TO_FRAME]
+ cmpw ax, bc
+ bc $2f
+
+ clrw ax
+ movw [hl + TO_ADDR], ax
+
+2:
+ movw ax, hl
+ addw ax, #TO_SIZE
+ movw hl, ax
+ cmpw ax, #trampoline_array_end
+ bnz $1b
+
+ ret
+ .size ___trampoline_uninit, . - ___trampoline_uninit