diff options
Diffstat (limited to 'libgcc/config/mep')
-rw-r--r-- | libgcc/config/mep/lib2funcs.c | 139 | ||||
-rw-r--r-- | libgcc/config/mep/t-mep | 5 | ||||
-rw-r--r-- | libgcc/config/mep/tramp.c | 103 |
3 files changed, 247 insertions, 0 deletions
diff --git a/libgcc/config/mep/lib2funcs.c b/libgcc/config/mep/lib2funcs.c new file mode 100644 index 0000000..1dbf57d --- /dev/null +++ b/libgcc/config/mep/lib2funcs.c @@ -0,0 +1,139 @@ +/* libgcc routines for MeP. + Copyright 2001, 2002, 2009 Free Software Foundation, Inc + +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 of the License, 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/>. */ + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef int word_type __attribute__ ((mode (__word__))); + +USItype +__mulsi3 (USItype a, USItype b) +{ + USItype c = 0; + + while (a != 0) + { + if (a & 1) + c += b; + a >>= 1; + b <<= 1; + } + + return c; +} + + + +USItype +udivmodsi4(USItype num, USItype den, word_type modwanted) +{ + USItype bit = 1; + USItype res = 0; + + while (den < num && bit && !(den & (1L<<31))) + { + den <<=1; + bit <<=1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>=1; + den >>=1; + } + if (modwanted) return num; + return res; +} + + + +SItype +__divsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} + + + +SItype +__modsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} + + + + +SItype +__udivsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 0); +} + + + +SItype +__umodsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 1); +} diff --git a/libgcc/config/mep/t-mep b/libgcc/config/mep/t-mep index d1fb094..fb3a0d6 100644 --- a/libgcc/config/mep/t-mep +++ b/libgcc/config/mep/t-mep @@ -7,5 +7,10 @@ LIB1ASMFUNCS = _mep_profile \ _mep_bb_trace \ _mep_bb_increment +# multiply and divide routines +LIB2ADD = \ + $(srcdir)/config/mep/lib2funcs.c \ + $(srcdir)/config/mep/tramp.c + # Use -O0 instead of -O2 so we don't get complex relocations CRTSTUFF_CFLAGS += -O0 diff --git a/libgcc/config/mep/tramp.c b/libgcc/config/mep/tramp.c new file mode 100644 index 0000000..bf484ca --- /dev/null +++ b/libgcc/config/mep/tramp.c @@ -0,0 +1,103 @@ +/* Trampoline support for MeP + Copyright (C) 2004, 2007 Free Software Foundation, Inc. + Contributed by Red Hat Inc. + +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 of the License, 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/>. */ + +/* + 7a0a ldc $10,$pc + c0ae000a lw $0,10($10) + caae000e lw $10,14($10) + 10ae jmp $10 + 00000000 static chain + 00000000 function address +*/ + +static inline int +cache_config_register(void) { + int rv; + asm ("ldc\t%0, $ccfg" : "=r" (rv)); + return rv; +} + +#define ICACHE_SIZE ((cache_config_register() >> 16) & 0x7f) +#define DCACHE_SIZE (cache_config_register() & 0x7f) + +#define ICACHE_DATA_BASE 0x00300000 +#define ICACHE_TAG_BASE 0x00310000 +#define DCACHE_DATA_BASE 0x00320000 +#define DCACHE_TAG_BASE 0x00330000 + +static inline void +flush_dcache (int addr) +{ + asm volatile ("cache\t0, (%0)" : : "r" (addr)); +} + +void +__mep_trampoline_helper (unsigned long *tramp, + int function_address, + int static_chain); + +void +__mep_trampoline_helper (unsigned long *tramp, + int function_address, + int static_chain) +{ + int dsize, isize; + +#ifdef __LITTLE_ENDIAN__ + tramp[0] = 0xc0ae7a0a; + tramp[1] = 0xcaae000a; + tramp[2] = 0x10ae000e; +#else + tramp[0] = 0x7a0ac0ae; + tramp[1] = 0x000acaae; + tramp[2] = 0x000e10ae; +#endif + tramp[3] = static_chain; + tramp[4] = function_address; + + dsize = DCACHE_SIZE; + isize = ICACHE_SIZE; + + if (dsize) + { + flush_dcache ((int)tramp); + flush_dcache ((int)tramp+16); + } + + if (isize) + { + int imask = (isize * 1024) - 1; + int tmask = ~imask; + unsigned int i; + volatile unsigned int *tags; + + imask &= 0xffe0; + + for (i=(unsigned int)tramp; i<(unsigned int)tramp+20; i+=16) + { + tags = (unsigned int *)(ICACHE_TAG_BASE + (i & imask)); + if ((*tags & tmask) == (i & tmask)) + *tags &= ~1; + } + } +} |