From: Nathael Pajani Date: Thu, 17 Apr 2014 09:13:07 +0000 (+0200) Subject: There are more than the division routines in ROM. Prepare for inclusion of the other... X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=1d7ed1f65e339c4c111f14d55bc0ba7220b2f62e;p=soft%2Flpc122x%2Fcore There are more than the division routines in ROM. Prepare for inclusion of the other ones. --- diff --git a/core/bootstrap.c b/core/bootstrap.c index 8b414b3..c59bba2 100644 --- a/core/bootstrap.c +++ b/core/bootstrap.c @@ -129,7 +129,7 @@ void *vector_table[] __attribute__ ((section(".vectors"))) = { }; -extern void rom_div_helpers_init(void); +extern void rom_helpers_init(void); /* * This is the entry point of the programm * It does the set up of the memory and then starts the main. @@ -149,7 +149,7 @@ void Reset_Handler(void) { *dst++ = 0; /* Initialize rom based division helpers */ - rom_div_helpers_init(); + rom_helpers_init(); /* Start main programm */ main(); } diff --git a/core/rom_helpers.c b/core/rom_helpers.c new file mode 100644 index 0000000..ec823ea --- /dev/null +++ b/core/rom_helpers.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * core/rom_helpers.c + * + * + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + * + *************************************************************************** */ + +#include + +/*******************************************************************************/ +/* Integer division using ROM based division routines */ +/*******************************************************************************/ + +struct idiv_return { + int quotient; + int remainder; +}; +struct uidiv_return { + unsigned quotient; + unsigned remainder; +}; + +struct lpc_rom_div_helpers { + /* Signed integer division */ + int (*rom_sidiv)(int numerator, int denominator); + /* Unsigned integer division */ + unsigned (*rom_uidiv)(unsigned numerator, unsigned denominator); + /* Signed integer division with remainder */ + struct idiv_return (*rom_sidivmod)(int numerator, int denominator); + /* Unsigned integer division with remainder */ + struct uidiv_return (*rom_uidivmod)(unsigned numerator, unsigned denominator); +}; + +static struct lpc_rom_div_helpers* rom_div_helpers; + +/* Division (/) */ +int __aeabi_idiv(int numerator, int denominator) +{ + return rom_div_helpers->rom_sidiv(numerator, denominator); +} +unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator) +{ + return rom_div_helpers->rom_uidiv(numerator, denominator); +} + +/* Modulo (%) */ +void __aeabi_idivmod(int numerator, int denominator) +{ + struct idiv_return result = rom_div_helpers->rom_sidivmod(numerator, denominator); + register uint32_t r0 asm("r0") = result.quotient; + register uint32_t r1 asm("r1") = result.remainder; + asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1)); +} +void __aeabi_uidivmod(unsigned numerator, unsigned denominator) +{ + struct uidiv_return result = rom_div_helpers->rom_uidivmod(numerator, denominator); + register uint32_t r0 asm("r0") = result.quotient; + register uint32_t r1 asm("r1") = result.remainder; + asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1)); +} + + +/*******************************************************************************/ +/* Rom based routines initialisation */ +/*******************************************************************************/ +#define LPC_122x_DIVROM_LOC (0x1FFC0000) + +void rom_helpers_init(void) +{ + rom_div_helpers = *((struct lpc_rom_div_helpers**)LPC_122x_DIVROM_LOC); +} + diff --git a/core/uidiv.c b/core/uidiv.c deleted file mode 100644 index b484b96..0000000 --- a/core/uidiv.c +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** - * core/uidiv.c - * - * - * - * This program 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 2 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - *************************************************************************** */ - -#include - -/*******************************************************************************/ -/* Integer division using ROM based division routines */ -/*******************************************************************************/ - -struct idiv_return { - int quotient; - int remainder; -}; -struct uidiv_return { - unsigned quotient; - unsigned remainder; -}; - -struct lpc_rom_div_helpers { - /* Signed integer division */ - int (*rom_sidiv)(int numerator, int denominator); - /* Unsigned integer division */ - unsigned (*rom_uidiv)(unsigned numerator, unsigned denominator); - /* Signed integer division with remainder */ - struct idiv_return (*rom_sidivmod)(int numerator, int denominator); - /* Unsigned integer division with remainder */ - struct uidiv_return (*rom_uidivmod)(unsigned numerator, unsigned denominator); -}; - -#define LPC_122x_DIVROM_LOC (0x1FFC0000) -static struct lpc_rom_div_helpers* rom_div_helpers; - -void rom_div_helpers_init(void) -{ - rom_div_helpers = *((struct lpc_rom_div_helpers**)LPC_122x_DIVROM_LOC); -} - -/* Division (/) */ -int __aeabi_idiv(int numerator, int denominator) -{ - return rom_div_helpers->rom_sidiv(numerator, denominator); -} -unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator) -{ - return rom_div_helpers->rom_uidiv(numerator, denominator); -} - -/* Modulo (%) */ -void __aeabi_idivmod(int numerator, int denominator) -{ - struct idiv_return result = rom_div_helpers->rom_sidivmod(numerator, denominator); - register uint32_t r0 asm("r0") = result.quotient; - register uint32_t r1 asm("r1") = result.remainder; - asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1)); -} -void __aeabi_uidivmod(unsigned numerator, unsigned denominator) -{ - struct uidiv_return result = rom_div_helpers->rom_uidivmod(numerator, denominator); - register uint32_t r0 asm("r0") = result.quotient; - register uint32_t r1 asm("r1") = result.remainder; - asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1)); -} -