@@ -233,9 +233,13 @@ math_emulate(struct trapframe *info, ksiginfo_t *ksi) {
233233 fpush ();
234234 ST (0 ) = CONSTZ ;
235235 return (0 );
236+ case 0x1f0 : /* f2xm1 */
237+ f2xm1 (PST (0 ), & tmp );
238+ real_to_real (& tmp , & ST (0 ));
239+ return (0 );
236240 case 0x1f1 : /* fyl2x */
237- fyl2x (PST (0 ),PST (1 ),& tmp );
238- real_to_real (& tmp ,& ST (0 ));
241+ fyl2x (PST (0 ), PST (1 ), & tmp );
242+ real_to_real (& tmp , & ST (0 ));
239243 fpop ();
240244 return (0 );
241245 case 0x1fc : /* frndint */
@@ -273,10 +277,18 @@ math_emulate(struct trapframe *info, ksiginfo_t *ksi) {
273277 case 0x1e2 : case 0x1e3 : case 0x1e5 :
274278 case 0x1e6 : case 0x1e7 :
275279 case 0x1ef :
276- case 0x1f0 : /* case 0x1f1: */ case 0x1f2 : case 0x1f3 :
277- case 0x1f4 : case 0x1f5 : case 0x1f6 : case 0x1f7 :
278- case 0x1f8 : case 0x1f9 : case 0x1fa : case 0x1fb :
279- case 0x1fe : case 0x1ff :
280+ case 0x1f2 : /* fptan */
281+ case 0x1f3 : /* fpatan */
282+ case 0x1f4 : /* fxtract */
283+ case 0x1f5 : /* fprem1 */
284+ case 0x1f6 : /* fdecstp */
285+ case 0x1f7 : /* fincstp */
286+ case 0x1f8 : /* fprem */
287+ case 0x1f9 : /* fyl2xp1 */
288+ case 0x1fa : /* fsqrt */
289+ case 0x1fb : /* fsincos */
290+ case 0x1fe : /* fsin */
291+ case 0x1ff : /* fcos */
280292 uprintf ("math_emulate: 0x%04x not implemented\n" , code + 0xd800 );
281293 math_abort (info , ksi , SIGILL , ILL_ILLOPC );
282294 }
@@ -1626,7 +1638,6 @@ void temp_to_short(const temp_real * a, short_real * b)
16261638/* printf("DEBUG: temp_to_short() result: 0x%08lX\n", *b); */
16271639}
16281640
1629-
16301641void temp_to_long (const temp_real * a , long_real * b )
16311642{
16321643/* printf("DEBUG: temp_to_long() input: exponent=0x%04X, significand=0x%08lX %08lX\n",
@@ -1869,6 +1880,15 @@ void int_to_real(const temp_int * a, temp_real * b)
18691880
18701881/* logarithm functions */
18711882
1883+ void f2xm1 (const temp_real * x , temp_real * result )
1884+ {
1885+ temp_real exp2_x , one ;
1886+
1887+ f2exp (x , & exp2_x ); /* exp2_x = 2^x */
1888+ real_to_real (& CONST1 , & one ); /* one = 1.0 */
1889+ fsub (& exp2_x , & one , result ); /* result = 2^x - 1 */
1890+ }
1891+
18721892void fyl2x (const temp_real * a , const temp_real * b , temp_real * c )
18731893{
18741894 temp_real log2_a ;
@@ -1880,30 +1900,49 @@ void fyl2x(const temp_real *a, const temp_real *b, temp_real *c)
18801900void flog2 (const temp_real * a , temp_real * result ) {
18811901 temp_real ln_a , ln2 ;
18821902
1883- fln (a , & ln_a ); // ln(x)
1884- long_to_temp (( const long_real * ) & CONSTLN2 , & ln2 );
1903+ fln (a , & ln_a ); /* ln(x) */
1904+ real_to_real ( & CONSTLN2 , & ln2 );
18851905 fdiv (& ln_a , & ln2 , result );
18861906}
18871907
18881908#define MAX_ITER 50
1889- void fexp (const temp_real * x , temp_real * result ) {
1890- temp_real term , sum , factor ;
1909+ void fexp (const temp_real * x , temp_real * result )
1910+ {
1911+ temp_real term , sum ;
18911912 int i ;
1913+ temp_int ti ;
1914+ temp_real real_i ;
1915+ temp_real x_copy = * x ;
18921916
1893- factor = * x ; // x^1
1894- long_to_temp ((const long_real * )& CONST1 , & sum );
1895- term = factor ;
1917+ real_to_real (& CONST1 , & sum ); /* sum = 1 */
1918+ real_to_real (& x_copy , & term ); /* term = x */
18961919
1897- for (i = 2 ; i < MAX_ITER ; i ++ ) {
1898- fmul (& term , & factor , & term ); // term = x^i / i!
1899- fdiv (& term , (const temp_real * )& i , & term ); // div i!
1920+ fadd (& sum , & term , & sum ); /* sum += x */
19001921
1901- fadd (& sum , & term , & sum );
1922+ for (i = 2 ; i < MAX_ITER ; i ++ )
1923+ {
1924+ ti .a = (signed short )i ;
1925+ ti .b = 0 ;
1926+ ti .sign = 0 ;
1927+ int_to_real (& ti , & real_i );
1928+
1929+ fmul (& term , & x_copy , & term ); /* term = term * x */
1930+ fdiv (& term , & real_i , & term ); /* term = term / i */
1931+ fadd (& sum , & term , & sum ); /* sum += term */
19021932 }
19031933
19041934 * result = sum ;
19051935}
19061936
1937+ void f2exp (const temp_real * x , temp_real * result )
1938+ {
1939+ temp_real ln2 , scaled ;
1940+
1941+ real_to_real (& CONSTLN2 , & ln2 ); /* ln2 = ln(2) */
1942+ fmul (x , & ln2 , & scaled ); /* scaled = x * ln(2) */
1943+ fexp (& scaled , result ); /* result = e^(x * ln(2)) = 2^x */
1944+ }
1945+
19071946void fln (const temp_real * x , temp_real * result )
19081947{
19091948 temp_real guess ;
@@ -1912,30 +1951,27 @@ void fln(const temp_real *x, temp_real *result)
19121951 temp_real diff ;
19131952 temp_real one ;
19141953
1915- long_to_temp (( const long_real * )& CONST1 , & one );
1954+ real_to_real (( temp_real * )& CONST1 , & one );
19161955
19171956 if (x -> exponent == 0 && x -> a == 0 && x -> b == 0 ) {
1918- long_to_temp (( const long_real * ) & NEG_INF , result );
1957+ real_to_real ( & NEG_INF , result );
19191958 return ;
19201959 }
19211960
19221961 guess = * x ;
19231962 fsub (& guess , & one , & guess );
19241963
19251964 while (iter < MAX_ITER ) {
1926- // f(guess) = e^guess - x
19271965 fexp (& guess , & f );
19281966 fsub (& f , x , & f );
19291967
1930- // f'(guess) = e^guess
1931- fexp (& guess , & f_prime ); // f_prime = e^guess
1968+ fexp (& guess , & f_prime ); /* f_prime = e^guess */
19321969
1933- // New guess = guess - f / f_prime
1934- fdiv (& f , & f_prime , & new_guess ); // new_guess = f / f_prime
1935- fsub (& guess , & new_guess , & new_guess ); // new_guess = guess - f / f_prime
1970+ fdiv (& f , & f_prime , & new_guess ); /* new_guess = f / f_prime */
1971+ fsub (& guess , & new_guess , & new_guess ); /* new_guess = guess - f / f_prime */
19361972
1937- fsub (& guess , & new_guess , & diff ); // diff = guess - new_guess
1938- diff .exponent &= 0x7fff ; // fabs(diff)
1973+ fsub (& guess , & new_guess , & diff ); /* diff = guess - new_guess */
1974+ diff .exponent &= 0x7fff ; /* fabs(diff) */
19391975
19401976 if (diff .exponent == 0 && diff .a == 0 && diff .b == 0 )
19411977 break ;
0 commit comments