@@ -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
11481148elem* 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
12411304elem* 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
12761339elem* 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
13901454elem* 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:
0 commit comments