slaanesh
Certified Guru
I was having a look at the vidhrdw/vector.c and found that there already is some inline ASM for multiply instructions.
This works well as it seems ARM has a nice multiply command to do this easily.
Here's the equivalent 'C' code if there is no ASM version:
CODE
#ifndef vec_mult
INLINE int vec_mult(int parm1, int parm2)
{
int temp,result;
temp = abs(parm1);
result = (temp&0x0000ffff) * (parm2&0x0000ffff);
result >>= 16;
result += (temp&0x0000ffff) * (parm2>>16 );
result += (temp>>16 ) * (parm2&0x0000ffff);
result >>= 16;
result += (temp>>16 ) * (parm2>>16 );
if( parm1 < 0 )
return(-result);
else
return( result);
}
#endif
But we do have some ASM; here it is:
CODE
#define vec_mult _vec_mult
INLINE int _vec_mult(int x, int y)
{
int res_hi, res_lo;
__asm__ __volatile__
("smull\t%1,%0,%2,%3"
: "=r"(res_hi), "=r"(res_lo)
: "r"(x), "r"(y)
);
return res_hi;
}
I was wondering if we could do the same thing for divide?
I realize that the ARM doesn't have native DIVIDE functionality, but perhaps an ASM guru could whip up the equivalent ASM from this 'C' code?
The vector case looks specific and it seems to be doing some sanity and bounds checking, however a generic version may also be handy for other areas of code with lots of divide maths.
Anyone interested?
Here's the vector divide code:
CODE
#ifndef vec_div
INLINE int vec_div(int parm1, int parm2)
{
if( (parm2>>12) )
{
parm1 = (parm1<<4) / (parm2>>12);
if( parm1 > 0x00010000 )
return( 0x00010000 );
if( parm1 < -0x00010000 )
return( -0x00010000 );
return( parm1 );
}
return( 0x00010000 );
}
#endif
This works well as it seems ARM has a nice multiply command to do this easily.
Here's the equivalent 'C' code if there is no ASM version:
CODE
#ifndef vec_mult
INLINE int vec_mult(int parm1, int parm2)
{
int temp,result;
temp = abs(parm1);
result = (temp&0x0000ffff) * (parm2&0x0000ffff);
result >>= 16;
result += (temp&0x0000ffff) * (parm2>>16 );
result += (temp>>16 ) * (parm2&0x0000ffff);
result >>= 16;
result += (temp>>16 ) * (parm2>>16 );
if( parm1 < 0 )
return(-result);
else
return( result);
}
#endif
But we do have some ASM; here it is:
CODE
#define vec_mult _vec_mult
INLINE int _vec_mult(int x, int y)
{
int res_hi, res_lo;
__asm__ __volatile__
("smull\t%1,%0,%2,%3"
: "=r"(res_hi), "=r"(res_lo)
: "r"(x), "r"(y)
);
return res_hi;
}
I was wondering if we could do the same thing for divide?
I realize that the ARM doesn't have native DIVIDE functionality, but perhaps an ASM guru could whip up the equivalent ASM from this 'C' code?
The vector case looks specific and it seems to be doing some sanity and bounds checking, however a generic version may also be handy for other areas of code with lots of divide maths.
Anyone interested?
Here's the vector divide code:
CODE
#ifndef vec_div
INLINE int vec_div(int parm1, int parm2)
{
if( (parm2>>12) )
{
parm1 = (parm1<<4) / (parm2>>12);
if( parm1 > 0x00010000 )
return( 0x00010000 );
if( parm1 < -0x00010000 )
return( -0x00010000 );
return( parm1 );
}
return( 0x00010000 );
}
#endif