Bug in romdiv_11u6x.c, solution but why?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Bug in romdiv_11u6x.c, solution but why?

316 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cappo85 on Tue Jul 14 06:45:41 MST 2015
Hi to all,

I use lpcopen_2_06_keil_iar_manley_11u68 in IAR EWARM, int file romdiv_11u6x.c this routines:

__value_in_regs IDIV_RETURN_T __aeabi_idivmod(int numerator, int denominator)
{
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
return pROMDiv->sidivmod(numerator, denominator);
}

/* Redirector of unsigned 32 bit integer divider with reminder to ROM routine */
__value_in_regs UIDIV_RETURN_T __aeabi_uidivmod(unsigned numerator, unsigned denominator)
{
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
        return pROMDiv->uidivmod(numerator, denominator);
}

don't works.
I think that the problem is __value_in_regs, so I have change code as follows:

solution 1
__value_in_regs UIDIV_RETURN_T __aeabi_uidivmod1(unsigned numerator, unsigned denominator)
{
        UIDIV_RETURN_T result;
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
        result = (pROMDiv->uidivmod(numerator, denominator));
return result;
}

or

UIDIV_RETURN_T __aeabi_uidivmod3(unsigned numerator, unsigned denominator)
{
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
        return (pROMDiv->uidivmod)(numerator, denominator);
}

and works perfectly.

I have an idea but I'd like to have more information from you....
In the original case the function that must return more than argument return a result of a function that can't return more than an argument. So in solution 1 declaring variable result I reserve registers and when "pROMDiv->uidivmod" return there are register where return the values. But in routine 2  isn't so.... and why it works....Why????

Best Regards
Riccardo Capponi
Labels (1)
0 Kudos
1 Reply

288 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cappo85 on Tue Jul 14 07:58:06 MST 2015
Hi to all,

the solution is here:

ARM Information Center

"A C++ function cannot return a __value_in_regs structure if the structure requires copy constructing."

in case:
__value_in_regs IDIV_RETURN_T __aeabi_idivmod(int numerator, int denominator)
{
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
return pROMDiv->sidivmod(numerator, denominator);
}

function __aeabi_idivmod can try to return a function that require a copy, where the result is in stack and not in resgister, so the core use the register and destroy the information and DOESN'T WORKS.

in case :
__value_in_regs UIDIV_RETURN_T __aeabi_uidivmod1(unsigned numerator, unsigned denominator)
{
UIDIV_RETURN_T result;
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
result = (pROMDiv->uidivmod(numerator, denominator));
return result;
}
function (pROMDiv->uidivmod(numerator, denominator)) return values in stack and copy in to result and then __aeabi_uidivmod1 return result in register.

in case:

UIDIV_RETURN_T __aeabi_uidivmod3(unsigned numerator, unsigned denominator)
{
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
return (pROMDiv->uidivmod)(numerator, denominator);
}

function __aeabi_uidivmod3 that return a values in stack, return the value form a  (pROMDiv->uidivmod)(numerator, denominator); that returns value in stack!!!!

In attach you can find the correct file.

Best Regards
Riccardo Capponi
0 Kudos