wie wärs denn damit?
s32 sin32fixed(s32 wink_bogen) {
register s32 akku asm ("r9") = wink_bogen;
register s32 potenz asm ("r10") = 0;
register s32 square asm("r6") = 0;
register s32 ii asm("r8") = 0;
register s32 dummy_lo asm("r5") = 0;
const s32 nenn_fkt_sgn [5] = {0xeaaaaaab, // (1/3!)*(2^31) dann 2er
Komplement
0x01111111, // (1/5!)*(2^31-1)
0xFFF97F98, // (1/7!)*(2^31) dann 2er
Komplement
0x0000171e, // (1/9!)*(2^31-1)
0xffffffca};// (1/11!)*(2^31) dann 2er
Komplement
// Konstantentabelle enthält Vorzeichen und Faktoren der
Winkelpotenzen
// also -1/3!, +1/5!, -1/7!, +1/9!, -1/11!
potenz=akku;
asm ("smull r5,r6,r9,r9" : "=r"(dummy_lo),"=r"(square) :
"r"(akku),"r"(akku));
square<<=1; // normiere
// wink_bogen^2 ist in r6, potenz in r10 ist zunaechst wink_bogen
akku>>=1; // da die Summation in der Schleife in einer anderen Norm
erfolgt, muss entsprechend vorgeteilt werden
if (akku&0x40000000) akku|=0x80000000; // Vorzeichenerweiterung
else akku&=0x7fffffff;
for (ii=0; ii<5; ii++) {
// multipliziere potenz mit wink_bogen^2
asm ("smull r5,r10,r10,r6" : "=r"(dummy_lo),"=r"(potenz) :
"1"(potenz),"r"(square));
potenz<<=1; // normiere jeweils
dummy_lo=0; // damit sich das nicht reinaddiert
asm ("smlal r5,r9,r10,%[rn]" : "=r"(dummy_lo),"=r"(akku) :
"0"(dummy_lo),"1"(akku),"r"(potenz),[rn]"r"(nenn_fkt_sgn[ii]));
}
akku<<=1; // normiere Endergebnis, weil das in der Schleife nicht
passiert
return akku; // gib Ergebnis zurück
}