Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor longdouble.d #16680

Merged
merged 3 commits into from
Jul 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 62 additions & 82 deletions compiler/src/dmd/root/longdouble.d
Original file line number Diff line number Diff line change
Expand Up @@ -170,25 +170,23 @@ nothrow @nogc pure:
T opCast(T)() const @trusted
{
static if (is(T == bool)) return mantissa != 0 || (exp_sign & 0x7fff) != 0;
else static if (is(T == byte)) return cast(T)ld_read(&this);
else static if (is(T == ubyte)) return cast(T)ld_read(&this);
else static if (is(T == short)) return cast(T)ld_read(&this);
else static if (is(T == ushort)) return cast(T)ld_read(&this);
else static if (is(T == int)) return cast(T)ld_read(&this);
else static if (is(T == uint)) return cast(T)ld_read(&this);
else static if (is(T == float)) return cast(T)ld_read(&this);
else static if (is(T == double)) return cast(T)ld_read(&this);
else static if (is(T == byte) || is(T == ubyte) ||
is(T == short) || is(T == ushort) ||
is(T == int) || is(T == uint))
return cast(T)ld_read(&this);
else static if (is(T == float) || is(T == double))
return cast(T)ld_read(&this);
else static if (is(T == long)) return ld_readll(&this);
else static if (is(T == ulong)) return ld_readull(&this);
else static if (is(T == real))
{
// convert to front end real if built with dmd
if (real.sizeof > 8)
static if (real.sizeof > 8)
return *cast(real*)&this;
else
return ld_read(&this);
}
else static assert(false, "usupported type");
else static assert(false, "unsupported type");
}
}

Expand Down Expand Up @@ -217,24 +215,18 @@ version(LDC)

extern(D):
private:
string fld_arg (string arg)() { return `__asm("fldt $0", "*m,~{st}", &` ~ arg ~ `);`; }
string fstp_arg (string arg)() { return `__asm("fstpt $0", "=*m,~{st}", &` ~ arg ~ `);`; }
string fld_parg (string arg)() { return `__asm("fldt $0", "*m,~{st}", ` ~ arg ~ `);`; }
string fstp_parg(string arg)() { return `__asm("fstpt $0", "=*m,~{st}", ` ~ arg ~ `);`; }
enum fld_arg(string arg) = `__asm("fldt $0", "*m,~{st}", &` ~ arg ~ `);`;
enum fstp_arg(string arg) = `__asm("fstpt $0", "=*m,~{st}", &` ~ arg ~ `);`;
enum fld_parg(string arg) = `__asm("fldt $0", "*m,~{st}", ` ~ arg ~ `);`;
enum fstp_parg(string arg) = `__asm("fstpt $0", "=*m,~{st}", ` ~ arg ~ `);`;
}
else version(D_InlineAsm_X86_64)
{
// longdouble_soft passed by reference
extern(D):
private:
string fld_arg(string arg)()
{
return "asm nothrow @nogc pure @trusted { mov RAX, " ~ arg ~ "; fld real ptr [RAX]; }";
}
string fstp_arg(string arg)()
{
return "asm nothrow @nogc pure @trusted { mov RAX, " ~ arg ~ "; fstp real ptr [RAX]; }";
}
enum fld_arg(string arg) = "asm nothrow @nogc pure @trusted { mov RAX, " ~ arg ~ "; fld real ptr [RAX]; }";
enum fstp_arg(string arg) = "asm nothrow @nogc pure @trusted { mov RAX, " ~ arg ~ "; fstp real ptr [RAX]; }";
alias fld_parg = fld_arg;
alias fstp_parg = fstp_arg;
}
Expand All @@ -243,30 +235,18 @@ else version(D_InlineAsm_X86)
// longdouble_soft passed by value
extern(D):
private:
string fld_arg(string arg)()
{
return "asm nothrow @nogc pure @trusted { lea EAX, " ~ arg ~ "; fld real ptr [EAX]; }";
}
string fstp_arg(string arg)()
{
return "asm nothrow @nogc pure @trusted { lea EAX, " ~ arg ~ "; fstp real ptr [EAX]; }";
}
string fld_parg(string arg)()
{
return "asm nothrow @nogc pure @trusted { mov EAX, " ~ arg ~ "; fld real ptr [EAX]; }";
}
string fstp_parg(string arg)()
{
return "asm nothrow @nogc pure @trusted { mov EAX, " ~ arg ~ "; fstp real ptr [EAX]; }";
}
enum fld_arg(string arg) = "asm nothrow @nogc pure @trusted { lea EAX, " ~ arg ~ "; fld real ptr [EAX]; }";
enum fstp_arg(string arg) = "asm nothrow @nogc pure @trusted { lea EAX, " ~ arg ~ "; fstp real ptr [EAX]; }";
enum fld_parg(string arg) = "asm nothrow @nogc pure @trusted { mov EAX, " ~ arg ~ "; fld real ptr [EAX]; }";
enum fstp_parg(string arg) = "asm nothrow @nogc pure @trusted { mov EAX, " ~ arg ~ "; fstp real ptr [EAX]; }";
}

double ld_read(const longdouble_soft* pthis)
{
double res;
version(AsmX86)
{
mixin(fld_parg!("pthis"));
mixin(fld_parg!"pthis");
asm nothrow @nogc pure @trusted
{
fstp res;
Expand Down Expand Up @@ -320,7 +300,7 @@ void ld_set(longdouble_soft* pthis, double d)
{
fld d;
}
mixin(fstp_parg!("pthis"));
mixin(fstp_parg!"pthis");
}
}

Expand All @@ -332,7 +312,7 @@ void ld_setll(longdouble_soft* pthis, long d)
{
fild qword ptr d;
}
mixin(fstp_parg!("pthis"));
mixin(fstp_parg!"pthis");
}
}

Expand All @@ -342,13 +322,13 @@ void ld_setull(longdouble_soft* pthis, ulong d)
version(AsmX86)
{
auto pTwoPow63 = &twoPow63;
mixin(fld_parg!("pTwoPow63"));
mixin(fld_parg!"pTwoPow63");
asm nothrow @nogc pure @trusted
{
fild qword ptr d;
faddp;
}
mixin(fstp_parg!("pthis"));
mixin(fstp_parg!"pthis");
}
}

Expand All @@ -361,13 +341,13 @@ longdouble_soft ldexpl(longdouble_soft ld, int exp)
{
fild dword ptr exp;
}
mixin(fld_arg!("ld"));
mixin(fld_arg!"ld");
asm nothrow @nogc pure @trusted
{
fscale; // ST(0) = ST(0) * (2**ST(1))
fstp ST(1);
}
mixin(fstp_arg!("ld"));
mixin(fstp_arg!"ld");
}
return ld;
}
Expand All @@ -377,13 +357,13 @@ longdouble_soft ld_add(longdouble_soft ld1, longdouble_soft ld2)
{
version(AsmX86)
{
mixin(fld_arg!("ld1"));
mixin(fld_arg!("ld2"));
mixin(fld_arg!"ld1");
mixin(fld_arg!"ld2");
asm nothrow @nogc pure @trusted
{
fadd;
}
mixin(fstp_arg!("ld1"));
mixin(fstp_arg!"ld1");
}
return ld1;
}
Expand All @@ -392,13 +372,13 @@ longdouble_soft ld_sub(longdouble_soft ld1, longdouble_soft ld2)
{
version(AsmX86)
{
mixin(fld_arg!("ld1"));
mixin(fld_arg!("ld2"));
mixin(fld_arg!"ld1");
mixin(fld_arg!"ld2");
asm nothrow @nogc pure @trusted
{
fsub;
}
mixin(fstp_arg!("ld1"));
mixin(fstp_arg!"ld1");
}
return ld1;
}
Expand All @@ -407,13 +387,13 @@ longdouble_soft ld_mul(longdouble_soft ld1, longdouble_soft ld2)
{
version(AsmX86)
{
mixin(fld_arg!("ld1"));
mixin(fld_arg!("ld2"));
mixin(fld_arg!"ld1");
mixin(fld_arg!"ld2");
asm nothrow @nogc pure @trusted
{
fmul;
}
mixin(fstp_arg!("ld1"));
mixin(fstp_arg!"ld1");
}
return ld1;
}
Expand All @@ -422,13 +402,13 @@ longdouble_soft ld_div(longdouble_soft ld1, longdouble_soft ld2)
{
version(AsmX86)
{
mixin(fld_arg!("ld1"));
mixin(fld_arg!("ld2"));
mixin(fld_arg!"ld1");
mixin(fld_arg!"ld2");
asm nothrow @nogc pure @trusted
{
fdiv;
}
mixin(fstp_arg!("ld1"));
mixin(fstp_arg!"ld1");
}
return ld1;
}
Expand All @@ -439,8 +419,8 @@ bool ld_cmpb(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -460,8 +440,8 @@ bool ld_cmpbe(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -481,8 +461,8 @@ bool ld_cmpa(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -502,8 +482,8 @@ bool ld_cmpae(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -523,8 +503,8 @@ bool ld_cmpe(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -544,8 +524,8 @@ bool ld_cmpne(longdouble_soft x, longdouble_soft y)
bool res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand All @@ -566,8 +546,8 @@ int ld_cmp(longdouble_soft x, longdouble_soft y)
int res;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
fucomip ST(1);
Expand Down Expand Up @@ -600,12 +580,12 @@ longdouble_soft sqrtl(longdouble_soft ld)
{
version(AsmX86)
{
mixin(fld_arg!("ld"));
mixin(fld_arg!"ld");
asm nothrow @nogc pure @trusted
{
fsqrt;
}
mixin(fstp_arg!("ld"));
mixin(fstp_arg!"ld");
}
return ld;
}
Expand All @@ -616,39 +596,39 @@ longdouble_soft sinl (longdouble_soft ld)
{
version(AsmX86)
{
mixin(fld_arg!("ld"));
mixin(fld_arg!"ld");
asm nothrow @nogc pure @trusted
{
fsin; // exact for |x|<=PI/4
}
mixin(fstp_arg!("ld"));
mixin(fstp_arg!"ld");
}
return ld;
}
longdouble_soft cosl (longdouble_soft ld)
{
version(AsmX86)
{
mixin(fld_arg!("ld"));
mixin(fld_arg!"ld");
asm nothrow @nogc pure @trusted
{
fcos; // exact for |x|<=PI/4
}
mixin(fstp_arg!("ld"));
mixin(fstp_arg!"ld");
}
return ld;
}
longdouble_soft tanl (longdouble_soft ld)
{
version(AsmX86)
{
mixin(fld_arg!("ld"));
mixin(fld_arg!"ld");
asm nothrow @nogc pure @trusted
{
fptan;
fstp ST(0); // always 1
}
mixin(fstp_arg!("ld"));
mixin(fstp_arg!"ld");
}
return ld;
}
Expand All @@ -663,8 +643,8 @@ longdouble_soft ld_mod(longdouble_soft x, longdouble_soft y)
short sw;
version(AsmX86)
{
mixin(fld_arg!("y"));
mixin(fld_arg!("x"));
mixin(fld_arg!"y");
mixin(fld_arg!"x");
asm nothrow @nogc pure @trusted
{
FM1: // We don't use fprem1 because for some inexplicable
Expand All @@ -677,7 +657,7 @@ longdouble_soft ld_mod(longdouble_soft x, longdouble_soft y)
jp FM1; // continue till ST < ST1
fstp ST(1); // leave remainder on stack
}
mixin(fstp_arg!("x"));
mixin(fstp_arg!"x");
}
return x;
}
Expand Down
Loading