Browse Source

math: move x87-family remainder functions to C with inline asm

master
Alexander Monakov 6 years ago
committed by Rich Felker
parent
commit
b173e4262f
  1. 12
      src/math/i386/remainder.c
  2. 14
      src/math/i386/remainder.s
  3. 12
      src/math/i386/remainderf.c
  4. 14
      src/math/i386/remainderf.s
  5. 9
      src/math/i386/remainderl.c
  6. 11
      src/math/i386/remainderl.s
  7. 9
      src/math/x86_64/remainderl.c
  8. 11
      src/math/x86_64/remainderl.s

12
src/math/i386/remainder.c

@ -0,0 +1,12 @@
#include <math.h>
double remainder(double x, double y)
{
unsigned short fpsr;
// fprem1 does not introduce excess precision into x
do __asm__ ("fprem1; fnstsw %%ax" : "+t"(x), "=a"(fpsr) : "u"(y));
while (fpsr & 0x400);
return x;
}
weak_alias(remainder, drem);

14
src/math/i386/remainder.s

@ -1,14 +0,0 @@
.global remainder
.type remainder,@function
remainder:
.weak drem
.type drem,@function
drem:
fldl 12(%esp)
fldl 4(%esp)
1: fprem1
fnstsw %ax
sahf
jp 1b
fstp %st(1)
ret

12
src/math/i386/remainderf.c

@ -0,0 +1,12 @@
#include <math.h>
float remainderf(float x, float y)
{
unsigned short fpsr;
// fprem1 does not introduce excess precision into x
do __asm__ ("fprem1; fnstsw %%ax" : "+t"(x), "=a"(fpsr) : "u"(y));
while (fpsr & 0x400);
return x;
}
weak_alias(remainderf, dremf);

14
src/math/i386/remainderf.s

@ -1,14 +0,0 @@
.global remainderf
.type remainderf,@function
remainderf:
.weak dremf
.type dremf,@function
dremf:
flds 8(%esp)
flds 4(%esp)
1: fprem1
fnstsw %ax
sahf
jp 1b
fstp %st(1)
ret

9
src/math/i386/remainderl.c

@ -0,0 +1,9 @@
#include <math.h>
long double remainderl(long double x, long double y)
{
unsigned short fpsr;
do __asm__ ("fprem1; fnstsw %%ax" : "+t"(x), "=a"(fpsr) : "u"(y));
while (fpsr & 0x400);
return x;
}

11
src/math/i386/remainderl.s

@ -1,11 +0,0 @@
.global remainderl
.type remainderl,@function
remainderl:
fldt 16(%esp)
fldt 4(%esp)
1: fprem1
fnstsw %ax
sahf
jp 1b
fstp %st(1)
ret

9
src/math/x86_64/remainderl.c

@ -0,0 +1,9 @@
#include <math.h>
long double remainderl(long double x, long double y)
{
unsigned short fpsr;
do __asm__ ("fprem1; fnstsw %%ax" : "+t"(x), "=a"(fpsr) : "u"(y));
while (fpsr & 0x400);
return x;
}

11
src/math/x86_64/remainderl.s

@ -1,11 +0,0 @@
.global remainderl
.type remainderl,@function
remainderl:
fldt 24(%rsp)
fldt 8(%rsp)
1: fprem1
fnstsw %ax
testb $4,%ah
jnz 1b
fstp %st(1)
ret
Loading…
Cancel
Save