diff options
Diffstat (limited to 'libgcc')
36 files changed, 2489 insertions, 81 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 2f415bfc80a..5f503617658 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,36 @@ +2013-09-17 Jacek Caban <jacek@codeweavers.com> + + * config/i386/gthr-win32.c: CreateSemaphoreW instead of + CreateSemaphoreA. + * config/i386/gthr-win32.h: Likewise. + +2013-09-16 DJ Delorie <dj@redhat.com> + + * config/rl78/vregs.h: Add G10 register definitions. + * config/rl78/lib2mul.c: Enable for RL78/G10. + * config/rl78/lib2div.c: Likewise. + * config/rl78/lshrsi3.S: Use vregs.h. + * config/rl78/cmpsi2.S: Likewise. + * config/rl78/trampoline.S: Likewise. + * config/rl78/mulsi2.S: Likewise. Disable for RL78/G10. + +2013-09-14 DJ Delorie <dj@redhat.com> + Nick Clifton <nickc@redhat.com> + + * config/rl78/mulsi3.S: Remove a few unneeded moves and branches. + * config/rl78/vregs.h: New. + * config/rl78/signbit.S: New file. Implements signbit function. + * config/rl78/divmodsi.S: New. + * config/rl78/divmodhi.S: New. + * config/rl78/divmodqi.S: New. + * config/rl78/t-rl78: Build them here... + * config/rl78/lib2div.c: ...but not here. + +2013-09-12 DJ Delorie <dj@redhat.com> + + * config.host (msp*-*-elf): New. + * config/msp430/: New port. + 2013-08-18 Iain Sandoe <iain@codesourcery.com> PR gcov-profile/58127 diff --git a/libgcc/config.host b/libgcc/config.host index 187391e9a2e..1fa3a654131 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -831,6 +831,9 @@ moxie-*-rtems*) # Don't use default. extra_parts= ;; +msp430*-*-elf) + tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430" + ;; pdp11-*-*) tmake_file="pdp11/t-pdp11 t-fdpbit" ;; diff --git a/libgcc/config/i386/gthr-win32.c b/libgcc/config/i386/gthr-win32.c index f6f661a0217..f3230317929 100644 --- a/libgcc/config/i386/gthr-win32.c +++ b/libgcc/config/i386/gthr-win32.c @@ -147,7 +147,7 @@ void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { mutex->counter = -1; - mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } void @@ -195,7 +195,7 @@ __gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) mutex->counter = -1; mutex->depth = 0; mutex->owner = 0; - mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } int diff --git a/libgcc/config/i386/gthr-win32.h b/libgcc/config/i386/gthr-win32.h index d2e729a00f6..1e437fc6498 100644 --- a/libgcc/config/i386/gthr-win32.h +++ b/libgcc/config/i386/gthr-win32.h @@ -635,7 +635,7 @@ static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { __mutex->counter = -1; - __mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline void @@ -697,7 +697,7 @@ __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) __mutex->counter = -1; __mutex->depth = 0; __mutex->owner = 0; - __mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline int diff --git a/libgcc/config/msp430/cmpd.c b/libgcc/config/msp430/cmpd.c new file mode 100644 index 00000000000..03e690dff53 --- /dev/null +++ b/libgcc/config/msp430/cmpd.c @@ -0,0 +1,19 @@ +/* Public domain. */ +int +__mspabi_cmpf (float x, float y) +{ + if (x < y) + return -1; + if (x > y) + return 1; + return 0; +} +int +__mspabi_cmpd (double x, double y) +{ + if (x < y) + return -1; + if (x > y) + return 1; + return 0; +} diff --git a/libgcc/config/msp430/cmpsi2.S b/libgcc/config/msp430/cmpsi2.S new file mode 100644 index 00000000000..e8e5b3935a4 --- /dev/null +++ b/libgcc/config/msp430/cmpsi2.S @@ -0,0 +1,98 @@ +; Copyright (C) 2012, 2013 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/>. + +#ifdef __MSP430X_LARGE__ +#define ret_ RETA +#else +#define ret_ RET +#endif + + .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. + + ;; Note - this code is also used by the __ucmpsi2 routine below. + + .global __cmpsi2 + .type __cmpsi2, @function +__cmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + cmp.w r13, r15 + jeq .L_compare_low + jge .L_less_than +.L_greater_than: + mov.w #2, r12 + ret_ +.L_less_than: + mov.w #0, r12 + ret_ + +.L_compare_low: + cmp.w r12, r14 + jl .L_greater_than + jne .L_less_than + mov.w #1, r12 + 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. + +;;; Note - this function branches into the __cmpsi2 code above. + + .global __ucmpsi2 + .type __ucmpsi2, @function +__ucmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + tst r13 + jn .L_top_bit_set_in_A + tst r15 +;;; If the top bit of B is set, but A's is clear we know that A < B. + jn .L_less_than +;;; Neither A nor B has their top bit set so we can use the __cmpsi2 routine. +;;; Note we use Jc rather than BR as that saves two bytes. The TST insn always +;;; sets the C bit. + jc __cmpsi2 + +.L_top_bit_set_in_A: + tst r15 +;;; If both A and B have their top bit set we can use the __cmpsi2 routine. + jn __cmpsi2 +;;; Otherwise A has its top bit set and B does not so A > B. + jc .L_greater_than + + .size __ucmpsi2, . - __ucmpsi2 diff --git a/libgcc/config/msp430/epilogue.S b/libgcc/config/msp430/epilogue.S new file mode 100644 index 00000000000..2e86decafc1 --- /dev/null +++ b/libgcc/config/msp430/epilogue.S @@ -0,0 +1,51 @@ +; Copyright (C) 2012, 2013 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/>. + + .text + + .global __mspabi_func_epilog_7 + .global __mspabi_func_epilog_6 + .global __mspabi_func_epilog_5 + .global __mspabi_func_epilog_4 + .global __mspabi_func_epilog_3 + .global __mspabi_func_epilog_2 + .global __mspabi_func_epilog_1 + +__mspabi_func_epilog_7: + POP R4 +__mspabi_func_epilog_6: + POP R5 +__mspabi_func_epilog_5: + POP R6 +__mspabi_func_epilog_4: + POP R7 +__mspabi_func_epilog_3: + POP R8 +__mspabi_func_epilog_2: + POP R9 +__mspabi_func_epilog_1: + POP R10 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/floathidf.c b/libgcc/config/msp430/floathidf.c new file mode 100644 index 00000000000..304731d518b --- /dev/null +++ b/libgcc/config/msp430/floathidf.c @@ -0,0 +1,8 @@ +/* Public domain. */ +extern double __floatsidf (long); + +double +__floathidf (int u) +{ + return __floatsidf ((long)u); +} diff --git a/libgcc/config/msp430/floathisf.c b/libgcc/config/msp430/floathisf.c new file mode 100644 index 00000000000..64e5d805d21 --- /dev/null +++ b/libgcc/config/msp430/floathisf.c @@ -0,0 +1,11 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef float SFtype __attribute__ ((mode (SF))); + +extern SFtype __floatsisf (unsigned long); + +SFtype +__floathisf (HItype u) +{ + return __floatsisf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/floatunhidf.c b/libgcc/config/msp430/floatunhidf.c new file mode 100644 index 00000000000..f13b5507692 --- /dev/null +++ b/libgcc/config/msp430/floatunhidf.c @@ -0,0 +1,12 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef float DFtype __attribute__ ((mode (DF))); + +extern DFtype __floatunsidf (unsigned long); + +DFtype +__floatunhidf (UHItype u) +{ + return __floatunsidf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/floatunhisf.c b/libgcc/config/msp430/floatunhisf.c new file mode 100644 index 00000000000..ea920bd853a --- /dev/null +++ b/libgcc/config/msp430/floatunhisf.c @@ -0,0 +1,12 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef float SFtype __attribute__ ((mode (SF))); + +extern SFtype __floatunsisf (unsigned long); + +SFtype +__floatunhisf (UHItype u) +{ + return __floatunsisf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/lib2bitcountHI.c b/libgcc/config/msp430/lib2bitcountHI.c new file mode 100644 index 00000000000..f0291ad60b0 --- /dev/null +++ b/libgcc/config/msp430/lib2bitcountHI.c @@ -0,0 +1,50 @@ +/* libgcc routines for MSP430 + Copyright (C) 2012 + 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) + +/* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in + msp430.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/msp430/lib2divHI.c b/libgcc/config/msp430/lib2divHI.c new file mode 100644 index 00000000000..e70ed400513 --- /dev/null +++ b/libgcc/config/msp430/lib2divHI.c @@ -0,0 +1,43 @@ +/* HI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + 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 uint16_type +#define SINT_TYPE sint16_type +#define BITS_MINUS_1 15 +#define NAME_MODE hi + +#include "msp430-divmod.h" diff --git a/libgcc/config/msp430/lib2divQI.c b/libgcc/config/msp430/lib2divQI.c new file mode 100644 index 00000000000..fe341fc2fdc --- /dev/null +++ b/libgcc/config/msp430/lib2divQI.c @@ -0,0 +1,44 @@ +/* QI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + 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 uint08_type +#define SINT_TYPE sint08_type +#define BITS_MINUS_1 7 +#define NAME_MODE qi + +#include "msp430-divmod.h" + diff --git a/libgcc/config/msp430/lib2divSI.c b/libgcc/config/msp430/lib2divSI.c new file mode 100644 index 00000000000..bc1dacaf51f --- /dev/null +++ b/libgcc/config/msp430/lib2divSI.c @@ -0,0 +1,43 @@ +/* SI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + 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 "msp430-divmod.h" diff --git a/libgcc/config/msp430/lib2mul.c b/libgcc/config/msp430/lib2mul.c new file mode 100644 index 00000000000..9f68f4c5e67 --- /dev/null +++ b/libgcc/config/msp430/lib2mul.c @@ -0,0 +1,59 @@ +/* libgcc routines for MSP430 + 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 "msp430-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 "msp430-mul.h" + +#undef UINT_TYPE +#undef BITS_MINUS_1 +#undef NAME_MODE + +#define UINT_TYPE uint32_type +#define BITS_MINUS_1 31 +#define NAME_MODE si + +#include "msp430-mul.h" diff --git a/libgcc/config/msp430/lib2shift.c b/libgcc/config/msp430/lib2shift.c new file mode 100644 index 00000000000..53d7eaec682 --- /dev/null +++ b/libgcc/config/msp430/lib2shift.c @@ -0,0 +1,113 @@ +/* Shift functions for the GCC support library for the MSP430 + 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/msp430/mpy.c b/libgcc/config/msp430/mpy.c new file mode 100644 index 00000000000..57cffd0ba2a --- /dev/null +++ b/libgcc/config/msp430/mpy.c @@ -0,0 +1,15 @@ +/* Public domain. */ +extern int __mulhi3 (int, int); + +int +__mulhi3 (int x, int y) +{ + volatile int rv = 0; + + while (y > 0) + { + rv += x; + y --; + } + return rv; +} diff --git a/libgcc/config/msp430/msp430-divmod.h b/libgcc/config/msp430/msp430-divmod.h new file mode 100644 index 00000000000..206c7516c3e --- /dev/null +++ b/libgcc/config/msp430/msp430-divmod.h @@ -0,0 +1,118 @@ +/* libgcc routines for MSP430 + 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/msp430/msp430-mul.h b/libgcc/config/msp430/msp430-mul.h new file mode 100644 index 00000000000..fc2cd6c6ebb --- /dev/null +++ b/libgcc/config/msp430/msp430-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/msp430/slli.S b/libgcc/config/msp430/slli.S new file mode 100644 index 00000000000..48ed15d3ec3 --- /dev/null +++ b/libgcc/config/msp430/slli.S @@ -0,0 +1,108 @@ +; Copyright (C) 2012, 2013 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/>. + + .text + +/* Logical Left Shift - R12 -> R12 */ + + .macro _slli n + .global __mspabi_slli_\n +__mspabi_slli_\n: + ADD.W R12,R12 + .endm + + _slli 15 + _slli 14 + _slli 13 + _slli 12 + _slli 11 + _slli 10 + _slli 9 + _slli 8 + _slli 7 + _slli 6 + _slli 5 + _slli 4 + _slli 3 + _slli 2 + _slli 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + ADD.W R12,R12 + .global __mspabi_slli +__mspabi_slli: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Left Shift - R12:R13 -> R12:R13 */ + + .macro _slll n + .global __mspabi_slll_\n +__mspabi_slll_\n: + ADD.W R12,R12 + ADDC.W R13,R13 + .endm + + _slll 15 + _slll 14 + _slll 13 + _slll 12 + _slll 11 + _slll 10 + _slll 9 + _slll 8 + _slll 7 + _slll 6 + _slll 5 + _slll 4 + _slll 3 + _slll 2 + _slll 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + ADD.W R12,R12 + ADDC.W R13,R13 + .global __mspabi_slll +__mspabi_slll: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + diff --git a/libgcc/config/msp430/srai.S b/libgcc/config/msp430/srai.S new file mode 100644 index 00000000000..8f841229fde --- /dev/null +++ b/libgcc/config/msp430/srai.S @@ -0,0 +1,106 @@ +; Copyright (C) 2012, 2013 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/>. + + .text + + .macro _srai n + .global __mspabi_srai_\n +__mspabi_srai_\n: + RRA.W R12 + .endm + +/* Logical Right Shift - R12 -> R12 */ + _srai 15 + _srai 14 + _srai 13 + _srai 12 + _srai 11 + _srai 10 + _srai 9 + _srai 8 + _srai 7 + _srai 6 + _srai 5 + _srai 4 + _srai 3 + _srai 2 + _srai 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + RRA.W R12,R12 + .global __mspabi_srai +__mspabi_srai: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Right Shift - R12:R13 -> R12:R13 */ + + .macro _sral n + .global __mspabi_sral_\n +__mspabi_sral_\n: + RRA.W R13 + RRC.W R12 + .endm + + _sral 15 + _sral 14 + _sral 13 + _sral 12 + _sral 11 + _sral 10 + _sral 9 + _sral 8 + _sral 7 + _sral 6 + _sral 5 + _sral 4 + _sral 3 + _sral 2 + _sral 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + RRA.W R13 + RRC.W R12 + .global __mspabi_sral +__mspabi_sral: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/srli.S b/libgcc/config/msp430/srli.S new file mode 100644 index 00000000000..3ec33df343f --- /dev/null +++ b/libgcc/config/msp430/srli.S @@ -0,0 +1,110 @@ +; Copyright (C) 2012, 2013 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/>. + + .text + + .macro _srli n + .global __mspabi_srli_\n +__mspabi_srli_\n: + CLRC + RRC.W R12 + .endm + +/* Logical Right Shift - R12 -> R12 */ + _srli 15 + _srli 14 + _srli 13 + _srli 12 + _srli 11 + _srli 10 + _srli 9 + _srli 8 + _srli 7 + _srli 6 + _srli 5 + _srli 4 + _srli 3 + _srli 2 + _srli 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + CLRC + RRC.W R12,R12 + .global __mspabi_srli +__mspabi_srli: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Right Shift - R12:R13 -> R12:R13 */ + + .macro _srll n + .global __mspabi_srll_\n +__mspabi_srll_\n: + CLRC + RRC.W R13 + RRC.W R12 + .endm + + _srll 15 + _srll 14 + _srll 13 + _srll 12 + _srll 11 + _srll 10 + _srll 9 + _srll 8 + _srll 7 + _srll 6 + _srll 5 + _srll 4 + _srll 3 + _srll 2 + _srll 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + CLRC + RRC.W R13 + RRC.W R12 + .global __mspabi_srll +__mspabi_srll: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/t-msp430 b/libgcc/config/msp430/t-msp430 new file mode 100644 index 00000000000..a4d4158e199 --- /dev/null +++ b/libgcc/config/msp430/t-msp430 @@ -0,0 +1,48 @@ +# Makefile fragment for building LIBGCC for the TI MSP430 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/>. + +# Note - we have separate versions of the lib2div<mode> files +# as the functions are quite large and we do not want to pull +# in unneeded division routines. + +LIB2ADD = \ + $(srcdir)/config/msp430/lib2divQI.c \ + $(srcdir)/config/msp430/lib2divHI.c \ + $(srcdir)/config/msp430/lib2divSI.c \ + $(srcdir)/config/msp430/lib2bitcountHI.c \ + $(srcdir)/config/msp430/lib2mul.c \ + $(srcdir)/config/msp430/lib2shift.c \ + $(srcdir)/config/msp430/epilogue.S \ + $(srcdir)/config/msp430/mpy.c \ + $(srcdir)/config/msp430/slli.S \ + $(srcdir)/config/msp430/srai.S \ + $(srcdir)/config/msp430/srli.S \ + $(srcdir)/config/msp430/cmpsi2.S \ + $(srcdir)/config/msp430/floatunhisf.c \ + $(srcdir)/config/msp430/floatunhidf.c \ + $(srcdir)/config/msp430/floathidf.c \ + $(srcdir)/config/msp430/floathisf.c \ + $(srcdir)/config/msp430/cmpd.c + +HOST_LIBGCC2_CFLAGS += -Os -ffunction-sections -fdata-sections + +# Local Variables: +# mode: Makefile +# End: diff --git a/libgcc/config/rl78/cmpsi2.S b/libgcc/config/rl78/cmpsi2.S index d815793daba..7fdc76a03f6 100644 --- a/libgcc/config/rl78/cmpsi2.S +++ b/libgcc/config/rl78/cmpsi2.S @@ -21,8 +21,7 @@ ; <http://www.gnu.org/licenses/>. -; clobberable -r8 = 0xffef0 +#include "vregs.h" .text diff --git a/libgcc/config/rl78/divmodhi.S b/libgcc/config/rl78/divmodhi.S new file mode 100644 index 00000000000..4e0a1237b28 --- /dev/null +++ b/libgcc/config/rl78/divmodhi.S @@ -0,0 +1,337 @@ +/* HImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 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/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r10 + den = r12 + bit = r14 + .else + num = r8 + quot = r10 + den = r12 + bit = r14 + .endif + + quotB0 = quot + quotB1 = quot+1 + + numB0 = num + numB1 = num+1 + + denB0 = den + denB1 = den+1 + + bitB0 = bit + bitB1 = bit+1 + +#if 1 +#define bit bc +#define bitB0 c +#define bitB1 b +#endif + +num_lt_den\which: + .if \need_result + movw r8, #0 + .else + movw ax, [sp+8] + movw r8, ax + .endif + ret + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 8[sp] /% 10[sp] + + movw hl, sp + movw ax, [hl+10] ; denH + cmpw ax, [hl+8] ; numH + bh $num_lt_den\which + + ;; (quot,rem) = 16[sp] /% 20[sp] + + ;; copy numerator + movw ax, [hl+8] + movw num, ax + + ;; copy denomonator + movw ax, [hl+10] + movw den, ax + + movw ax, den + cmpw ax, #0 + bnz $den_not_zero\which + movw num, #0 + ret + +den_not_zero\which: + .if \need_result + ;; zero out quot + movw quot, #0 + .endif + + ;; initialize bit to 1 + movw bit, #1 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + +shift_den_bit\which: + movw ax, den + mov1 cy,a.7 + bc $enter_main_loop\which + cmpw ax, num + bh $enter_main_loop\which + + ;; den <<= 1 +; movw ax, den ; already has it from the cmpw above + shlw ax, 1 + movw den, ax + + ;; bit <<= 1 + .if \need_result +#ifdef bit + shlw bit, 1 +#else + movw ax, bit + shlw ax, 1 + movw bit, ax +#endif + .else + ;; if we don't need to compute the quotent, we don't need an + ;; actual bit *mask*, we just need to keep track of which bit + inc bitB0 + .endif + + br $shift_den_bit\which + +main_loop\which: + + ;; if (num >= den) (cmp den > num) + movw ax, den + cmpw ax, num + bh $next_loop\which + + ;; num -= den + movw ax, num + subw ax, den + movw num, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + .endif + +next_loop\which: + + ;; den >>= 1 + movw ax, den + shrw ax, 1 + movw den, ax + + .if \need_result + ;; bit >>= 1 + movw ax, bit + shrw ax, 1 + movw bit, ax + .else + dec bitB0 + .endif + +enter_main_loop\which: + .if \need_result + movw ax, bit + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop\which + +main_loop_done\which: + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivhi3 + .type ___udivhi3,@function +___udivhi3: + ;; r8 = 4[sp] / 6[sp] + call $!generic_div + ret + .size ___udivhi3, . - ___udivhi3 + + + .global ___umodhi3 + .type ___umodhi3,@function +___umodhi3: + ;; r8 = 4[sp] % 6[sp] + call $!generic_mod + ret + .size ___umodhi3, . - ___umodhi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + movw ax, #0 + subw ax, [hl] + movw [hl], ax + .endm + + .global ___divhi3 + .type ___divhi3,@function +___divhi3: + ;; r8 = 4[sp] / 6[sp] + movw de, #0 + mov a, [sp+5] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+7] + mov1 cy, a.7 + bc $div_signed_den + call $!generic_div + ret + +div_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+7] + mov1 cy, a.7 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+6] + movw ax, sp + addw ax, #6 + neg_ax + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +div_skip_restore_den: + ret + .size ___divhi3, . - ___divhi3 + + + .global ___modhi3 + .type ___modhi3,@function +___modhi3: + ;; r8 = 4[sp] % 6[sp] + movw de, #0 + mov a, [sp+5] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [sp+7] + mov1 cy, a.7 + bc $mod_signed_den + call $!generic_mod + ret + +mod_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+7] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+6] + movw ax, sp + addw ax, #6 + neg_ax +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + movw ax, #r8 + neg_ax + ;; Also restore numerator + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +mod_skip_restore_den: + ret + .size ___modhi3, . - ___modhi3 + +#endif diff --git a/libgcc/config/rl78/divmodqi.S b/libgcc/config/rl78/divmodqi.S new file mode 100644 index 00000000000..62d6f776143 --- /dev/null +++ b/libgcc/config/rl78/divmodqi.S @@ -0,0 +1,310 @@ +/* QImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 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/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r10 + den = r12 + bit = r14 + .else + num = r8 + quot = r10 + den = r12 + bit = r14 + .endif + +#if 1 +#define bit b +#define den c +#define bitden bc +#endif + +num_lt_den\which: + .if \need_result + mov r8, #0 + .else + mov a, [hl+4] + mov r8, a + .endif + ret + +num_eq_den\which: + .if \need_result + mov r8, #1 + .else + mov r8, #0 + .endif + ret + +den_is_zero\which: + mov r8, #0xff + ret + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 4[hl] /% 6[hl] + + mov a, [hl+4] ; num + cmp a, [hl+6] ; den + bz $num_eq_den\which + bnh $num_lt_den\which + + ;; copy numerator +; mov a, [hl+4] ; already there from above + mov num, a + + ;; copy denomonator + mov a, [hl+6] + mov den, a + + cmp0 den + bz $den_is_zero\which + +den_not_zero\which: + .if \need_result + ;; zero out quot + mov quot, #0 + .endif + + ;; initialize bit to 1 + mov bit, #1 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + +shift_den_bit\which: + .macro sdb_one\which + mov a, den + mov1 cy,a.7 + bc $enter_main_loop\which + cmp a, num + bh $enter_main_loop\which + + ;; den <<= 1 +; mov a, den ; already has it from the cmpw above + shl a, 1 + mov den, a + + ;; bit <<= 1 + shl bit, 1 + .endm + + sdb_one\which + sdb_one\which + + br $shift_den_bit\which + +main_loop\which: + + ;; if (num >= den) (cmp den > num) + mov a, den + cmp a, num + bh $next_loop\which + + ;; num -= den + mov a, num + sub a, den + mov num, a + + .if \need_result + ;; res |= bit + mov a, quot + or a, bit + mov quot, a + .endif + +next_loop\which: + + ;; den, bit >>= 1 + movw ax, bitden + shrw ax, 1 + movw bitden, ax + +enter_main_loop\which: + cmp0 bit + bnz $main_loop\which + +main_loop_done\which: + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivqi3 + .type ___udivqi3,@function +___udivqi3: + ;; r8 = 4[sp] / 6[sp] + movw hl, sp + br $!generic_div + .size ___udivqi3, . - ___udivqi3 + + + .global ___umodqi3 + .type ___umodqi3,@function +___umodqi3: + ;; r8 = 4[sp] % 6[sp] + movw hl, sp + br $!generic_mod + .size ___umodqi3, . - ___umodqi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + mov a, #0 + sub a, [hl] + mov [hl], a + .endm + + .global ___divqi3 + .type ___divqi3,@function +___divqi3: + ;; r8 = 4[sp] / 6[sp] + movw hl, sp + movw de, #0 + mov a, [sp+4] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+6] + mov1 cy, a.7 + bc $div_signed_den + br $!generic_div + +div_signed_num: + ;; neg [sp+4] + mov a, #0 + sub a, [hl+4] + mov [hl+4], a + mov d, #1 + mov a, [sp+6] + mov1 cy, a.6 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+6] + mov a, #0 + sub a, [hl+6] + mov [hl+6], a + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +div_skip_restore_den: + ret + .size ___divqi3, . - ___divqi3 + + + .global ___modqi3 + .type ___modqi3,@function +___modqi3: + ;; r8 = 4[sp] % 6[sp] + movw hl, sp + movw de, #0 + mov a, [hl+4] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [hl+6] + mov1 cy, a.7 + bc $mod_signed_den + br $!generic_mod + +mod_signed_num: + ;; neg [sp+4] + mov a, #0 + sub a, [hl+4] + mov [hl+4], a + mov d, #1 + mov a, [hl+6] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+6] + mov a, #0 + sub a, [hl+6] + mov [hl+6], a + mov e, #1 +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + mov a, #0 + sub a, r8 + mov r8, a + ;; Also restore numerator + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +mod_skip_restore_den: + ret + .size ___modqi3, . - ___modqi3 + +#endif diff --git a/libgcc/config/rl78/divmodsi.S b/libgcc/config/rl78/divmodsi.S new file mode 100644 index 00000000000..e22b5ba56e8 --- /dev/null +++ b/libgcc/config/rl78/divmodsi.S @@ -0,0 +1,521 @@ +/* SImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 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/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r12 + den = r16 + bit = r20 + .else + num = r8 + quot = r12 + den = r16 + bit = r20 + .endif + + quotH = quot+2 + quotL = quot + quotB0 = quot + quotB1 = quot+1 + quotB2 = quot+2 + quotB3 = quot+3 + + numH = num+2 + numL = num + numB0 = num + numB1 = num+1 + numB2 = num+2 + numB3 = num+3 + +#define denH bc + denL = den + denB0 = den + denB1 = den+1 +#define denB2 c +#define denB3 b + + bitH = bit+2 + bitL = bit + bitB0 = bit + bitB1 = bit+1 + bitB2 = bit+2 + bitB3 = bit+3 + +num_lt_den\which: + .if \need_result + movw r8, #0 + movw r10, #0 + .else + movw ax, [sp+8] + movw r8, ax + movw ax, [sp+10] + movw r10, ax + .endif + ret + +shift_den_bit16\which: + movw ax, denL + movw denH, ax + movw denL, #0 + .if \need_result + movw ax, bitL + movw bitH, ax + movw bitL, #0 + .else + mov a, bit + add a, #16 + mov bit, a + .endif + br $shift_den_bit\which + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 8[sp] /% 12[sp] + + movw hl, sp + movw ax, [hl+14] ; denH + cmpw ax, [hl+10] ; numH + movw ax, [hl+12] ; denL + sknz + cmpw ax, [hl+8] ; numL + bh $num_lt_den\which + + sel rb2 + push ax ; denL +; push bc ; denH + push de ; bitL + push hl ; bitH - stored in BC + sel rb0 + + ;; (quot,rem) = 16[sp] /% 20[sp] + + ;; copy numerator + movw ax, [hl+8] + movw numL, ax + movw ax, [hl+10] + movw numH, ax + + ;; copy denomonator + movw ax, [hl+12] + movw denL, ax + movw ax, [hl+14] + movw denH, ax + + movw ax, denL + or a, denB2 + or a, denB3 ; not x + cmpw ax, #0 + bnz $den_not_zero\which + movw numL, #0 + movw numH, #0 + ret + +den_not_zero\which: + .if \need_result + ;; zero out quot + movw quotL, #0 + movw quotH, #0 + .endif + + ;; initialize bit to 1 + movw bitL, #1 + movw bitH, #0 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + + .if 1 + ;; see if we can short-circuit a bunch of shifts + movw ax, denH + cmpw ax, #0 + bnz $shift_den_bit\which + movw ax, denL + cmpw ax, numH + bnh $shift_den_bit16\which + .endif + +shift_den_bit\which: + movw ax, denH + mov1 cy,a.7 + bc $enter_main_loop\which + cmpw ax, numH + movw ax, denL ; we re-use this below + sknz + cmpw ax, numL + bh $enter_main_loop\which + + ;; den <<= 1 +; movw ax, denL ; already has it from the cmpw above + shlw ax, 1 + movw denL, ax +; movw ax, denH + rolwc denH, 1 +; movw denH, ax + + ;; bit <<= 1 + .if \need_result + movw ax, bitL + shlw ax, 1 + movw bitL, ax + movw ax, bitH + rolwc ax, 1 + movw bitH, ax + .else + ;; if we don't need to compute the quotent, we don't need an + ;; actual bit *mask*, we just need to keep track of which bit + inc bitB0 + .endif + + br $shift_den_bit\which + + ;; while (bit) +main_loop\which: + + ;; if (num >= den) (cmp den > num) + movw ax, numH + cmpw ax, denH + movw ax, numL + sknz + cmpw ax, denL + skz + bnh $next_loop\which + + ;; num -= den +; movw ax, numL ; already has it from the cmpw above + subw ax, denL + movw numL, ax + movw ax, numH + sknc + decw ax + subw ax, denH + movw numH, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + mov a, quotB2 + or a, bitB2 + mov quotB2, a + mov a, quotB3 + or a, bitB3 + mov quotB3, a + .endif + +next_loop\which: + + ;; den >>= 1 + movw ax, denH + shrw ax, 1 + movw denH, ax + mov a, denB1 + rorc a, 1 + mov denB1, a + mov a, denB0 + rorc a, 1 + mov denB0, a + + ;; bit >>= 1 + .if \need_result + movw ax, bitH + shrw ax, 1 + movw bitH, ax + mov a, bitB1 + rorc a, 1 + mov bitB1, a + mov a, bitB0 + rorc a, 1 + mov bitB0, a + .else + dec bitB0 + .endif + +enter_main_loop\which: + .if \need_result + movw ax, bitH + cmpw ax, #0 + bnz $main_loop\which + .else + cmp bitB0, #15 + bh $main_loop\which + .endif + ;; bit is HImode now; check others + movw ax, numH ; numerator + cmpw ax, #0 + bnz $bit_high_set\which + movw ax, denH ; denominator + cmpw ax, #0 + bz $switch_to_himode\which +bit_high_set\which: + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop\which + +switch_to_himode\which: + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bz $main_loop_done_himode\which + + ;; From here on in, r22, r14, and r18 are all zero + ;; while (bit) +main_loop_himode\which: + + ;; if (num >= den) (cmp den > num) + movw ax, denL + cmpw ax, numL + bh $next_loop_himode\which + + ;; num -= den + movw ax, numL + subw ax, denL + movw numL, ax + movw ax, numH + sknc + decw ax + subw ax, denH + movw numH, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + .endif + +next_loop_himode\which: + + ;; den >>= 1 + movw ax, denL + shrw ax, 1 + movw denL, ax + + .if \need_result + ;; bit >>= 1 + movw ax, bitL + shrw ax, 1 + movw bitL, ax + .else + dec bitB0 + .endif + + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop_himode\which + +main_loop_done_himode\which: + sel rb2 + pop hl ; bitH - stored in BC + pop de ; bitL +; pop bc ; denH + pop ax ; denL + sel rb0 + + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivsi3 + .type ___udivsi3,@function +___udivsi3: + ;; r8 = 4[sp] / 8[sp] + call $!generic_div + ret + .size ___udivsi3, . - ___udivsi3 + + + .global ___umodsi3 + .type ___umodsi3,@function +___umodsi3: + ;; r8 = 4[sp] % 8[sp] + call $!generic_mod + ret + .size ___umodsi3, . - ___umodsi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + movw ax, #0 + subw ax, [hl] + movw [hl], ax + movw ax, #0 + sknc + decw ax + subw ax, [hl+2] + movw [hl+2], ax + .endm + + .global ___divsi3 + .type ___divsi3,@function +___divsi3: + ;; r8 = 4[sp] / 8[sp] + movw de, #0 + mov a, [sp+7] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+11] + mov1 cy, a.7 + bc $div_signed_den + call $!generic_div + ret + +div_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+11] + mov1 cy, a.7 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+8] + movw ax, sp + addw ax, #8 + neg_ax + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + ;; We have to restore the denominator [sp+8] + movw ax, sp + addw ax, #8 + neg_ax +div_skip_restore_den: + ret + .size ___divsi3, . - ___divsi3 + + + .global ___modsi3 + .type ___modsi3,@function +___modsi3: + ;; r8 = 4[sp] % 8[sp] + movw de, #0 + mov a, [sp+7] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [sp+11] + mov1 cy, a.7 + bc $mod_signed_den + call $!generic_mod + ret + +mod_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+11] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+8] + movw ax, sp + addw ax, #8 + neg_ax + mov e, #1 +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + movw ax, #r8 + neg_ax + ;; We have to restore [sp+4] as well. + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + .if 1 + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #8 + neg_ax +mod_skip_restore_den: + .endif + ret + .size ___modsi3, . - ___modsi3 + +#endif diff --git a/libgcc/config/rl78/lib2div.c b/libgcc/config/rl78/lib2div.c index d9dcf4c2745..b37f55a94ac 100644 --- a/libgcc/config/rl78/lib2div.c +++ b/libgcc/config/rl78/lib2div.c @@ -34,6 +34,8 @@ typedef int word_type __attribute__ ((mode (__word__))); #define C3B(a,b,c) a##b##c #define C3(a,b,c) C3B(a,b,c) +#ifdef __RL78_G10__ + #define UINT_TYPE uint32_type #define SINT_TYPE sint32_type #define BITS_MINUS_1 31 @@ -65,6 +67,8 @@ typedef int word_type __attribute__ ((mode (__word__))); #include "rl78-divmod.h" +#endif + /* 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. */ diff --git a/libgcc/config/rl78/lib2mul.c b/libgcc/config/rl78/lib2mul.c index 6460f9e69db..fee50817722 100644 --- a/libgcc/config/rl78/lib2mul.c +++ b/libgcc/config/rl78/lib2mul.c @@ -30,12 +30,25 @@ 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) +#ifdef __RL78_G10__ + +#define UINT_TYPE uint32_type +#define BITS_MINUS_1 31 +#define NAME_MODE si + +#include "rl78-mul.h" + +#undef UINT_TYPE +#undef BITS_MINUS_1 +#undef NAME_MODE #define UINT_TYPE uint16_type #define BITS_MINUS_1 15 #define NAME_MODE hi -/*#include "rl78-mul.h"*/ +#include "rl78-mul.h" + +#endif #undef UINT_TYPE #undef BITS_MINUS_1 diff --git a/libgcc/config/rl78/lshrsi3.S b/libgcc/config/rl78/lshrsi3.S index 1ee7325143f..8bd997897aa 100644 --- a/libgcc/config/rl78/lshrsi3.S +++ b/libgcc/config/rl78/lshrsi3.S @@ -20,22 +20,7 @@ ; 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 +#include "vregs.h" .text .global ___lshrsi3 diff --git a/libgcc/config/rl78/mulsi3.S b/libgcc/config/rl78/mulsi3.S index 4ce343c1420..1ce45ba3402 100644 --- a/libgcc/config/rl78/mulsi3.S +++ b/libgcc/config/rl78/mulsi3.S @@ -22,35 +22,12 @@ ;; 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 +#include "vregs.h" + +; the G10 only has one register bank, so cannot use these optimized +; versions. Use the C version instead. + +#ifndef __RL78_G10__ ;---------------------------------------------------------------------- @@ -70,10 +47,6 @@ ___mulsi3: ;; 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 @@ -83,37 +56,37 @@ ___mulsi3: movw r8, ax movw r16, ax - movw ax, [hl+6] + movw ax, [sp+14] cmpw ax, #0 bz $1f cmpw ax, #0xffff bnz $2f - movw ax, [hl] + movw ax, [sp+8] sel rb1 subw ax, r_0 sel rb0 br $1f 2: movw bc, ax - movw ax, [hl] + movw ax, [sp+8] cmpw ax, #0 skz call !.Lmul_hi 1: - movw ax, [hl+2] + movw ax, [sp+10] cmpw ax, #0 bz $1f cmpw ax, #0xffff bnz $2f - movw ax, [hl+4] + movw ax, [sp+12] sel rb1 subw ax, r_0 sel rb0 br $1f 2: movw bc, ax - movw ax, [hl+4] + movw ax, [sp+12] cmpw ax, #0 skz call !.Lmul_hi @@ -130,9 +103,9 @@ ___mulsi3: ;; 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 ax, [sp+8] movw r10, ax ; BC.1 - movw ax, [hl+4] + movw ax, [sp+12] cmpw ax, r10 bc $.Lmul_hisi_top @@ -191,6 +164,13 @@ ___mulsi3: ;---------------------------------------------------------------------- + .global ___mulhi3 +___mulhi3: + movw r8, #0 + movw ax, [sp+6] + movw bc, ax + movw ax, [sp+4] + ;; R8 += AX * BC .Lmul_hi: cmpw ax, bc @@ -219,17 +199,4 @@ ___mulsi3: .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 +#endif diff --git a/libgcc/config/rl78/signbit.S b/libgcc/config/rl78/signbit.S new file mode 100644 index 00000000000..afd0f07eb47 --- /dev/null +++ b/libgcc/config/rl78/signbit.S @@ -0,0 +1,67 @@ +; Copyright (C) 2012,2013 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/>. + +#include "vregs.h" + +;; int signbitf (float X) +;; int signbit (double X) +;; int signbitl (long double X) +;; +;; `signbit' returns a nonzero value if the value of X has its sign +;; bit set. +;; +;; This is not the same as `x < 0.0', because IEEE 754 floating point +;; allows zero to be signed. The comparison `-0.0 < 0.0' is false, +;; but `signbit (-0.0)' will return a nonzero value. + +;---------------------------------------------------------------------- + + .text + + .global _signbit +_signbit: + .global _signbitf +_signbitf: + ;; X is at [sp+4] + ;; result is in R8..R9 + + movw r8, #0 + mov a, [sp+7] + mov1 cy, a.7 + sknc + movw r8, #1 + ret + .size _signbit, . - _signbit + .size _signbitf, . - _signbitf + + .global _signbitl +_signbitl: + ;; X is at [sp+4] + ;; result is in R8..R9 + + movw r8, #0 + mov a, [sp+11] + mov1 cy, a.7 + sknc + movw r8, #1 + ret + .size _signbitl, . - _signbitl diff --git a/libgcc/config/rl78/t-rl78 b/libgcc/config/rl78/t-rl78 index da7f7bb9bf7..d3260aa23d2 100644 --- a/libgcc/config/rl78/t-rl78 +++ b/libgcc/config/rl78/t-rl78 @@ -25,4 +25,8 @@ LIB2ADD = \ $(srcdir)/config/rl78/lib2shift.c \ $(srcdir)/config/rl78/lshrsi3.S \ $(srcdir)/config/rl78/mulsi3.S \ + $(srcdir)/config/rl78/divmodsi.S \ + $(srcdir)/config/rl78/divmodhi.S \ + $(srcdir)/config/rl78/divmodqi.S \ + $(srcdir)/config/rl78/signbit.S \ $(srcdir)/config/rl78/cmpsi2.S diff --git a/libgcc/config/rl78/trampoline.S b/libgcc/config/rl78/trampoline.S index b15b0d361e2..59d429eb589 100644 --- a/libgcc/config/rl78/trampoline.S +++ b/libgcc/config/rl78/trampoline.S @@ -32,9 +32,7 @@ */ -r8 = 0xffef0 -r10 = 0xffef2 -r14 = 0xffef6 +#include "vregs.h" .data .p2align 1 diff --git a/libgcc/config/rl78/vregs.h b/libgcc/config/rl78/vregs.h new file mode 100644 index 00000000000..fa488fabcb1 --- /dev/null +++ b/libgcc/config/rl78/vregs.h @@ -0,0 +1,56 @@ + +; 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 + +#ifdef __RL78_G10__ + +; clobberable +r8 = 0xffec8 +r9 = 0xffec9 +r10 = 0xffeca +r11 = 0xffecb +r12 = 0xffecc +r13 = 0xffecd +r14 = 0xffece +r15 = 0xffecf +; preserved +r16 = 0xffed0 +r17 = 0xffed1 +r18 = 0xffed2 +r19 = 0xffed3 +r20 = 0xffed4 +r21 = 0xffed5 +r22 = 0xffed6 +r23 = 0xffed7 + +#else + +; 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 + +#endif |