Skip to content

Commit 4aa543a

Browse files
authored
load 128 bit floating point constants from global (dlang#21279)
1 parent ddb917f commit 4aa543a

3 files changed

Lines changed: 76 additions & 5 deletions

File tree

compiler/src/dmd/backend/backconfig.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ static if (0)
313313
configv.vasm = vasm;
314314
configv.verbose = verbose;
315315

316+
go.AArch64 = arm;
316317
if (optimize)
317318
go_flag(go, cast(char*)"-o".ptr);
318319

compiler/src/dmd/backend/elem.d

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ int el_countCommas(const(elem)* e)
11441144
* Convert floating point constant to a read-only symbol.
11451145
* Needed iff floating point code can't load immediate constants.
11461146
*/
1147-
@trusted
1147+
private @trusted
11481148
elem* el_convfloat(ref GlobalOptimizer go, elem* e)
11491149
{
11501150
//printf("el_convfloat()\n"); elem_print(e);
@@ -1232,12 +1232,75 @@ elem* el_convfloat(ref GlobalOptimizer go, elem* e)
12321232
return e;
12331233
}
12341234

1235+
/************************************
1236+
* Convert AArch64 128 bit floating point constant to a read-only symbol.
1237+
* Params:
1238+
* go = optimizer state
1239+
* e = floating point constant
1240+
* Returns:
1241+
* read-only constant variable
1242+
*/
1243+
private @trusted
1244+
elem* el_convreal(ref GlobalOptimizer go, elem* e)
1245+
{
1246+
//printf("el_convfloat()\n"); elem_print(e);
1247+
ubyte[32] buffer = void;
1248+
1249+
tym_t ty = e.Ety;
1250+
int sz = tysize(ty);
1251+
assert(sz <= buffer.length);
1252+
void* p;
1253+
switch (tybasic(ty))
1254+
{
1255+
case TYldouble:
1256+
case TYildouble:
1257+
/* The size, alignment, and padding of long doubles may be different
1258+
* from host to target
1259+
*/
1260+
p = buffer.ptr;
1261+
// TODO AArch64 these are supposed to be 128 bit floats, not 80 bit
1262+
memset(buffer.ptr, 0, sz); // ensure padding is 0
1263+
memcpy(buffer.ptr, &e.Vldouble, 10);
1264+
break;
1265+
1266+
case TYcldouble:
1267+
p = buffer.ptr;
1268+
memset(buffer.ptr, 0, sz);
1269+
memcpy(buffer.ptr, &e.Vcldouble.re, 10);
1270+
memcpy(buffer.ptr + tysize(TYldouble), &e.Vcldouble.im, 10);
1271+
break;
1272+
1273+
default:
1274+
return e; // not necessary
1275+
}
1276+
1277+
static if (0)
1278+
{
1279+
printf("%gL+%gLi\n", cast(double)e.Vcldouble.re, cast(double)e.Vcldouble.im);
1280+
printf("el_convfloat() %g %g sz=%d\n", e.Vcdouble.re, e.Vcdouble.im, sz);
1281+
printf("el_convfloat(): sz = %d\n", sz);
1282+
ushort* p = cast(ushort*)&e.Vcldouble;
1283+
for (int i = 0; i < sz/2; i++) printf("%04x ", p[i]);
1284+
printf("\n");
1285+
}
1286+
1287+
Symbol* s = out_readonly_sym(ty, p, sz);
1288+
el_free(e);
1289+
1290+
elem* ep = el_ptr(s);
1291+
elem* ec = el_una(OPind, ty, ep);
1292+
1293+
go.changes++;
1294+
//printf("s: %s %d:x%x\n", s.Sident, s.Sseg, s.Soffset);
1295+
return ec;
1296+
}
1297+
12351298
/************************************
12361299
* Convert vector constant to a read-only symbol.
12371300
* Needed iff vector code can't load immediate constants.
12381301
*/
12391302

1240-
@trusted
1303+
private @trusted
12411304
elem* el_convxmm(ref GlobalOptimizer go, elem* e)
12421305
{
12431306
// 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)
12721335
* stored in the static data segment.
12731336
*/
12741337

1275-
@trusted
1338+
private @trusted
12761339
elem* el_convstring(elem* e)
12771340
{
12781341
//printf("el_convstring()\n");
@@ -1386,6 +1449,7 @@ void shrinkLongDoubleConstantIfPossible(elem* e)
13861449
/*************************
13871450
* Run through a tree converting it to CODGEN.
13881451
*/
1452+
public
13891453
@trusted
13901454
elem* el_convert(ref GlobalOptimizer go, elem* e)
13911455
{
@@ -1400,8 +1464,13 @@ elem* el_convert(ref GlobalOptimizer go, elem* e)
14001464
case OPconst:
14011465
if (tyvector(e.Ety))
14021466
e = el_convxmm(go, e);
1403-
else if (tyfloating(e.Ety) && config.inline8087)
1404-
e = el_convfloat(go, e);
1467+
else if (tyfloating(e.Ety))
1468+
{
1469+
if (config.inline8087)
1470+
e = el_convfloat(go, e);
1471+
else if (go.AArch64)
1472+
e = el_convreal(go, e);
1473+
}
14051474
break;
14061475

14071476
case OPstring:

compiler/src/dmd/backend/goh.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct DefNode
7474
*/
7575
struct GlobalOptimizer
7676
{
77+
bool AArch64; // AArch64 is the target
7778
mftype mfoptim;
7879
uint changes; // # of optimizations performed
7980

0 commit comments

Comments
 (0)