diff options
author | DJ Delorie <dj@redhat.com> | 2011-11-29 16:36:43 -0500 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2011-11-29 16:36:43 -0500 |
commit | 85b8555ed3c45855b237b0f3a044eefb9382255c (patch) | |
tree | 65c814557c3c0e61f746e922c96ca834174464c4 /libgcc | |
parent | c360c0fb8a1dd8ef61d986671d02071075d2c0b9 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | libgcc/config.host | 3 | ||||
-rw-r--r-- | libgcc/config/rl78/cmpsi2.S | 122 | ||||
-rw-r--r-- | libgcc/config/rl78/lib2div.c | 81 | ||||
-rw-r--r-- | libgcc/config/rl78/lib2mul.c | 49 | ||||
-rw-r--r-- | libgcc/config/rl78/lib2shift.c | 113 | ||||
-rw-r--r-- | libgcc/config/rl78/lshrsi3.S | 131 | ||||
-rw-r--r-- | libgcc/config/rl78/mulsi3.S | 235 | ||||
-rw-r--r-- | libgcc/config/rl78/rl78-divmod.h | 118 | ||||
-rw-r--r-- | libgcc/config/rl78/rl78-mul.h | 43 | ||||
-rw-r--r-- | libgcc/config/rl78/t-rl78 | 28 | ||||
-rw-r--r-- | libgcc/config/rl78/trampoline.S | 139 |
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 |