mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
load 128 bit floating point constants from global (#21279)
This commit is contained in:
parent
ddb917f8e8
commit
4aa543a2a2
3 changed files with 76 additions and 5 deletions
|
@ -313,6 +313,7 @@ static if (0)
|
||||||
configv.vasm = vasm;
|
configv.vasm = vasm;
|
||||||
configv.verbose = verbose;
|
configv.verbose = verbose;
|
||||||
|
|
||||||
|
go.AArch64 = arm;
|
||||||
if (optimize)
|
if (optimize)
|
||||||
go_flag(go, cast(char*)"-o".ptr);
|
go_flag(go, cast(char*)"-o".ptr);
|
||||||
|
|
||||||
|
|
|
@ -1144,7 +1144,7 @@ int el_countCommas(const(elem)* e)
|
||||||
* Convert floating point constant to a read-only symbol.
|
* Convert floating point constant to a read-only symbol.
|
||||||
* Needed iff floating point code can't load immediate constants.
|
* Needed iff floating point code can't load immediate constants.
|
||||||
*/
|
*/
|
||||||
@trusted
|
private @trusted
|
||||||
elem* el_convfloat(ref GlobalOptimizer go, elem* e)
|
elem* el_convfloat(ref GlobalOptimizer go, elem* e)
|
||||||
{
|
{
|
||||||
//printf("el_convfloat()\n"); elem_print(e);
|
//printf("el_convfloat()\n"); elem_print(e);
|
||||||
|
@ -1232,12 +1232,75 @@ elem* el_convfloat(ref GlobalOptimizer go, elem* e)
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
* Convert AArch64 128 bit floating point constant to a read-only symbol.
|
||||||
|
* Params:
|
||||||
|
* go = optimizer state
|
||||||
|
* e = floating point constant
|
||||||
|
* Returns:
|
||||||
|
* read-only constant variable
|
||||||
|
*/
|
||||||
|
private @trusted
|
||||||
|
elem* el_convreal(ref GlobalOptimizer go, elem* e)
|
||||||
|
{
|
||||||
|
//printf("el_convfloat()\n"); elem_print(e);
|
||||||
|
ubyte[32] buffer = void;
|
||||||
|
|
||||||
|
tym_t ty = e.Ety;
|
||||||
|
int sz = tysize(ty);
|
||||||
|
assert(sz <= buffer.length);
|
||||||
|
void* p;
|
||||||
|
switch (tybasic(ty))
|
||||||
|
{
|
||||||
|
case TYldouble:
|
||||||
|
case TYildouble:
|
||||||
|
/* The size, alignment, and padding of long doubles may be different
|
||||||
|
* from host to target
|
||||||
|
*/
|
||||||
|
p = buffer.ptr;
|
||||||
|
// TODO AArch64 these are supposed to be 128 bit floats, not 80 bit
|
||||||
|
memset(buffer.ptr, 0, sz); // ensure padding is 0
|
||||||
|
memcpy(buffer.ptr, &e.Vldouble, 10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYcldouble:
|
||||||
|
p = buffer.ptr;
|
||||||
|
memset(buffer.ptr, 0, sz);
|
||||||
|
memcpy(buffer.ptr, &e.Vcldouble.re, 10);
|
||||||
|
memcpy(buffer.ptr + tysize(TYldouble), &e.Vcldouble.im, 10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return e; // not necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (0)
|
||||||
|
{
|
||||||
|
printf("%gL+%gLi\n", cast(double)e.Vcldouble.re, cast(double)e.Vcldouble.im);
|
||||||
|
printf("el_convfloat() %g %g sz=%d\n", e.Vcdouble.re, e.Vcdouble.im, sz);
|
||||||
|
printf("el_convfloat(): sz = %d\n", sz);
|
||||||
|
ushort* p = cast(ushort*)&e.Vcldouble;
|
||||||
|
for (int i = 0; i < sz/2; i++) printf("%04x ", p[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol* s = out_readonly_sym(ty, p, sz);
|
||||||
|
el_free(e);
|
||||||
|
|
||||||
|
elem* ep = el_ptr(s);
|
||||||
|
elem* ec = el_una(OPind, ty, ep);
|
||||||
|
|
||||||
|
go.changes++;
|
||||||
|
//printf("s: %s %d:x%x\n", s.Sident, s.Sseg, s.Soffset);
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
* Convert vector constant to a read-only symbol.
|
* Convert vector constant to a read-only symbol.
|
||||||
* Needed iff vector code can't load immediate constants.
|
* Needed iff vector code can't load immediate constants.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
private @trusted
|
||||||
elem* el_convxmm(ref GlobalOptimizer go, elem* e)
|
elem* el_convxmm(ref GlobalOptimizer go, elem* e)
|
||||||
{
|
{
|
||||||
// Do not convert if the constants can be loaded with the special XMM instructions
|
// Do not convert if the constants can be loaded with the special XMM instructions
|
||||||
|
@ -1272,7 +1335,7 @@ elem* el_convxmm(ref GlobalOptimizer go, elem* e)
|
||||||
* stored in the static data segment.
|
* stored in the static data segment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
private @trusted
|
||||||
elem* el_convstring(elem* e)
|
elem* el_convstring(elem* e)
|
||||||
{
|
{
|
||||||
//printf("el_convstring()\n");
|
//printf("el_convstring()\n");
|
||||||
|
@ -1386,6 +1449,7 @@ void shrinkLongDoubleConstantIfPossible(elem* e)
|
||||||
/*************************
|
/*************************
|
||||||
* Run through a tree converting it to CODGEN.
|
* Run through a tree converting it to CODGEN.
|
||||||
*/
|
*/
|
||||||
|
public
|
||||||
@trusted
|
@trusted
|
||||||
elem* el_convert(ref GlobalOptimizer go, elem* e)
|
elem* el_convert(ref GlobalOptimizer go, elem* e)
|
||||||
{
|
{
|
||||||
|
@ -1400,8 +1464,13 @@ elem* el_convert(ref GlobalOptimizer go, elem* e)
|
||||||
case OPconst:
|
case OPconst:
|
||||||
if (tyvector(e.Ety))
|
if (tyvector(e.Ety))
|
||||||
e = el_convxmm(go, e);
|
e = el_convxmm(go, e);
|
||||||
else if (tyfloating(e.Ety) && config.inline8087)
|
else if (tyfloating(e.Ety))
|
||||||
e = el_convfloat(go, e);
|
{
|
||||||
|
if (config.inline8087)
|
||||||
|
e = el_convfloat(go, e);
|
||||||
|
else if (go.AArch64)
|
||||||
|
e = el_convreal(go, e);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPstring:
|
case OPstring:
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct DefNode
|
||||||
*/
|
*/
|
||||||
struct GlobalOptimizer
|
struct GlobalOptimizer
|
||||||
{
|
{
|
||||||
|
bool AArch64; // AArch64 is the target
|
||||||
mftype mfoptim;
|
mftype mfoptim;
|
||||||
uint changes; // # of optimizations performed
|
uint changes; // # of optimizations performed
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue