Skip to content

Commit

Permalink
refactor longdouble.d (dlang#16680)
Browse files Browse the repository at this point in the history
* refactor longdouble.d

* reduce duplicative code

* fix error
  • Loading branch information
0-v-0 authored and thewilsonator committed Oct 7, 2024
1 parent b88637c commit aeb08cb
Showing 1 changed file with 62 additions and 82 deletions.
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

0 comments on commit aeb08cb

Please sign in to comment.