mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 12:40:11 +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.verbose = verbose;
|
||||
|
||||
go.AArch64 = arm;
|
||||
if (optimize)
|
||||
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.
|
||||
* Needed iff floating point code can't load immediate constants.
|
||||
*/
|
||||
@trusted
|
||||
private @trusted
|
||||
elem* el_convfloat(ref GlobalOptimizer go, elem* e)
|
||||
{
|
||||
//printf("el_convfloat()\n"); elem_print(e);
|
||||
|
@ -1232,12 +1232,75 @@ elem* el_convfloat(ref GlobalOptimizer go, elem* 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.
|
||||
* Needed iff vector code can't load immediate constants.
|
||||
*/
|
||||
|
||||
@trusted
|
||||
private @trusted
|
||||
elem* el_convxmm(ref GlobalOptimizer go, elem* e)
|
||||
{
|
||||
// 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.
|
||||
*/
|
||||
|
||||
@trusted
|
||||
private @trusted
|
||||
elem* el_convstring(elem* e)
|
||||
{
|
||||
//printf("el_convstring()\n");
|
||||
|
@ -1386,6 +1449,7 @@ void shrinkLongDoubleConstantIfPossible(elem* e)
|
|||
/*************************
|
||||
* Run through a tree converting it to CODGEN.
|
||||
*/
|
||||
public
|
||||
@trusted
|
||||
elem* el_convert(ref GlobalOptimizer go, elem* e)
|
||||
{
|
||||
|
@ -1400,8 +1464,13 @@ elem* el_convert(ref GlobalOptimizer go, elem* e)
|
|||
case OPconst:
|
||||
if (tyvector(e.Ety))
|
||||
e = el_convxmm(go, e);
|
||||
else if (tyfloating(e.Ety) && config.inline8087)
|
||||
e = el_convfloat(go, e);
|
||||
else if (tyfloating(e.Ety))
|
||||
{
|
||||
if (config.inline8087)
|
||||
e = el_convfloat(go, e);
|
||||
else if (go.AArch64)
|
||||
e = el_convreal(go, e);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPstring:
|
||||
|
|
|
@ -74,6 +74,7 @@ struct DefNode
|
|||
*/
|
||||
struct GlobalOptimizer
|
||||
{
|
||||
bool AArch64; // AArch64 is the target
|
||||
mftype mfoptim;
|
||||
uint changes; // # of optimizations performed
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue