Fix math.nbtheory linkage to asm

Don't use extern for templated functions. If the function argument is
const, it gets a different mangling. So define a private function for
each floatint point length and call it from template.
This commit is contained in:
Eugen Wissner 2018-05-08 17:45:51 +02:00
parent 6ed2992862
commit 2ec750ca05
3 changed files with 60 additions and 51 deletions

View File

@ -2,10 +2,10 @@
// fabsf. // fabsf.
.globl _D5tanya4math8nbtheory10__T3absTfZ3absFNaNbNiNffZf .globl _D5tanya4math8nbtheory4fabsFNaNbNiNffZf
.type _D5tanya4math8nbtheory10__T3absTfZ3absFNaNbNiNffZf, @function .type _D5tanya4math8nbtheory4fabsFNaNbNiNffZf, @function
_D5tanya4math8nbtheory10__T3absTfZ3absFNaNbNiNffZf: _D5tanya4math8nbtheory4fabsFNaNbNiNffZf:
mov $0x7fffffff, %eax mov $0x7fffffff, %eax
movq %rax, %xmm1 movq %rax, %xmm1
andpd %xmm1, %xmm0 andpd %xmm1, %xmm0
@ -13,10 +13,10 @@ _D5tanya4math8nbtheory10__T3absTfZ3absFNaNbNiNffZf:
// fabs. // fabs.
.globl _D5tanya4math8nbtheory10__T3absTdZ3absFNaNbNiNfdZd .globl _D5tanya4math8nbtheory4fabsFNaNbNiNfdZd
.type _D5tanya4math8nbtheory10__T3absTdZ3absFNaNbNiNfdZd, @function .type _D5tanya4math8nbtheory4fabsFNaNbNiNfdZd, @function
_D5tanya4math8nbtheory10__T3absTdZ3absFNaNbNiNfdZd: _D5tanya4math8nbtheory4fabsFNaNbNiNfdZd:
mov $0x7fffffffffffffff, %rax mov $0x7fffffffffffffff, %rax
movq %rax, %xmm1 movq %rax, %xmm1
andpd %xmm1, %xmm0 andpd %xmm1, %xmm0
@ -24,12 +24,12 @@ _D5tanya4math8nbtheory10__T3absTdZ3absFNaNbNiNfdZd:
// fabsl. // fabsl.
.globl _D5tanya4math8nbtheory10__T3absTeZ3absFNaNbNiNfeZe .globl _D5tanya4math8nbtheory4fabsFNaNbNiNfeZe
.type _D5tanya4math8nbtheory10__T3absTeZ3absFNaNbNiNfeZe, @function .type _D5tanya4math8nbtheory4fabsFNaNbNiNfeZe, @function
// Load the parameter from the stack onto FP stack, execute 'fabs' instruction // Load the parameter from the stack onto FP stack, execute 'fabs' instruction
// The result is returned in ST0. // The result is returned in ST0.
_D5tanya4math8nbtheory10__T3absTeZ3absFNaNbNiNfeZe: _D5tanya4math8nbtheory4fabsFNaNbNiNfeZe:
fldt 0x8(%rsp) fldt 0x8(%rsp)
fabs fabs
ret ret

View File

@ -1,22 +1,29 @@
.text .text
// logl. // logf.
.globl _D5tanya4math8nbtheory9__T2lnTeZ2lnFNaNbNiNfeZe .globl _D5tanya4math8nbtheory4logfFNaNbNiNffZf
.type _D5tanya4math8nbtheory9__T2lnTeZ2lnFNaNbNiNfeZe, @function .type _D5tanya4math8nbtheory4logfFNaNbNiNffZf, @function
_D5tanya4math8nbtheory4logfFNaNbNiNffZf:
movss %xmm0, -4(%rsp) // Put the argument onto the stack
_D5tanya4math8nbtheory9__T2lnTeZ2lnFNaNbNiNfeZe:
fldln2 // Put lb(e) onto the FPU stack fldln2 // Put lb(e) onto the FPU stack
fldt 8(%rsp) // Put the argument onto the FPU stack flds -4(%rsp) // Put a float onto the FPU stack
fyl2x // %st1 * lb(%st0) fyl2x // %st1 * lb(%st0)
// The result is on the FPU stack, but returned in %xmm0
fstps -4(%rsp)
movss -4(%rsp), %xmm0
ret ret
// log. // log.
.globl _D5tanya4math8nbtheory9__T2lnTdZ2lnFNaNbNiNfdZd .globl _D5tanya4math8nbtheory3logFNaNbNiNfdZd
.type _D5tanya4math8nbtheory9__T2lnTdZ2lnFNaNbNiNfdZd, @function .type _D5tanya4math8nbtheory3logFNaNbNiNfdZd, @function
_D5tanya4math8nbtheory9__T2lnTdZ2lnFNaNbNiNfdZd: _D5tanya4math8nbtheory3logFNaNbNiNfdZd:
movsd %xmm0, -8(%rsp) // Put the argument onto the stack movsd %xmm0, -8(%rsp) // Put the argument onto the stack
fldln2 // Put lb(e) onto the FPU stack fldln2 // Put lb(e) onto the FPU stack
@ -30,19 +37,12 @@ _D5tanya4math8nbtheory9__T2lnTdZ2lnFNaNbNiNfdZd:
ret ret
// logf. // logl.
.globl _D5tanya4math8nbtheory9__T2lnTfZ2lnFNaNbNiNffZf .globl _D5tanya4math8nbtheory4loglFNaNbNiNfeZe
.type _D5tanya4math8nbtheory9__T2lnTfZ2lnFNaNbNiNffZf, @function .type _D5tanya4math8nbtheory4loglFNaNbNiNfeZe, @function
_D5tanya4math8nbtheory9__T2lnTfZ2lnFNaNbNiNffZf:
movss %xmm0, -4(%rsp) // Put the argument onto the stack
_D5tanya4math8nbtheory4loglFNaNbNiNfeZe:
fldln2 // Put lb(e) onto the FPU stack fldln2 // Put lb(e) onto the FPU stack
flds -4(%rsp) // Put a float onto the FPU stack fldt 8(%rsp) // Put the argument onto the FPU stack
fyl2x // %st1 * lb(%st0) fyl2x // %st1 * lb(%st0)
// The result is on the FPU stack, but returned in %xmm0
fstps -4(%rsp)
movss -4(%rsp), %xmm0
ret ret

View File

@ -16,9 +16,17 @@ module tanya.math.nbtheory;
import tanya.math.mp; import tanya.math.mp;
import tanya.meta.trait; import tanya.meta.trait;
import tanya.meta.transform;
version (TanyaNative) version (TanyaNative)
{ {
private extern float fabs(float) @nogc nothrow pure @safe;
private extern double fabs(double) @nogc nothrow pure @safe;
private extern real fabs(real) @nogc nothrow pure @safe;
private extern double log(double) @nogc nothrow pure @safe;
private extern float logf(float) @nogc nothrow pure @safe;
private extern real logl(real) @nogc nothrow pure @safe;
} }
else else
{ {
@ -35,7 +43,7 @@ else
* *
* Returns: Absolute value of $(D_PARAM x). * Returns: Absolute value of $(D_PARAM x).
*/ */
T abs(T)(T x) Unqual!T abs(T)(T x)
if (isIntegral!T) if (isIntegral!T)
{ {
static if (isSigned!T) static if (isSigned!T)
@ -60,24 +68,11 @@ if (isIntegral!T)
static assert(is(typeof(u.abs) == uint)); static assert(is(typeof(u.abs) == uint));
} }
version (D_Ddoc) /// ditto
Unqual!T abs(T)(T x)
if (isFloatingPoint!T)
{ {
/// ditto return fabs(x);
T abs(T)(T x)
if (isFloatingPoint!T);
}
else version (TanyaNative)
{
extern T abs(T)(T number) @nogc nothrow pure @safe
if (isFloatingPoint!T);
}
else
{
T abs(T)(T x)
if (isFloatingPoint!T)
{
return fabs(cast(real) x);
}
} }
/// ///
@ -122,17 +117,31 @@ version (D_Ddoc)
* *
* Returns: Natural logarithm of $(D_PARAM x). * Returns: Natural logarithm of $(D_PARAM x).
*/ */
T ln(T)(T x) Unqual!T ln(T)(T x)
if (isFloatingPoint!T); if (isFloatingPoint!T);
} }
else version (TanyaNative) else version (TanyaNative)
{ {
extern T ln(T)(T x) @nogc nothrow pure @safe Unqual!T ln(T)(T x) @nogc nothrow pure @safe
if (isFloatingPoint!T); if (isFloatingPoint!T)
{
static if (is(Unqual!T == float))
{
return logf(x);
}
else static if (is(Unqual!T == double))
{
return log(x);
}
else
{
return logl(x);
}
}
} }
else else
{ {
T ln(T)(T x) Unqual!T ln(T)(T x)
if (isFloatingPoint!T) if (isFloatingPoint!T)
{ {
return log(x); return log(x);