Skip to content

Commit 82141da

Browse files
authored
get tstresult() to work with 128 bit floats (dlang#21306)
1 parent 018656e commit 82141da

4 files changed

Lines changed: 89 additions & 15 deletions

File tree

compiler/src/dmd/backend/arm/cod1.d

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,8 +1231,27 @@ void tstresult(ref CodeBuilder cdb, regm_t regm, tym_t tym, bool saveflag)
12311231

12321232
if (tyfloating(tym))
12331233
{
1234-
const ftype = INSTR.szToFtype(sz);
1235-
cdb.gen1(INSTR.fcmp_float(ftype,0,reg)); // FCMP Vn,#0.0
1234+
assert(reg & 32);
1235+
if (tym == TYldouble || tym == TYildouble)
1236+
{
1237+
/*
1238+
fmov q0,reg
1239+
movi v1.2d,#0 // https://www.scs.stanford.edu/~zyedidia/arm64/movi_advsimd.html
1240+
bl __netf2
1241+
cmp w0,#0
1242+
*/
1243+
if (reg != 32)
1244+
cdb.gen1(INSTR.mov_orr_advsimd_reg(1,reg,32)); // MOV v0,reg
1245+
cdb.gen1(INSTR.movi_advsimd(1,1,0xE,0,1)); // MOVI V1.2D,0
1246+
regm_t dummy;
1247+
callclib(cdb,null,CLIB_A.netf2,dummy,saveflag ? mask(reg) : 0); // __netf2(v0,v1)
1248+
gentstreg(cdb,0,0); // CMP W0,#0
1249+
}
1250+
else
1251+
{
1252+
const ftype = INSTR.szToFtype(sz);
1253+
cdb.gen1(INSTR.fcmp_float(ftype,0,reg)); // FCMP Vn,#0.0
1254+
}
12361255
}
12371256
else
12381257
gentstreg(cdb,reg,sz == 8); // CMP reg,#0
@@ -1322,6 +1341,7 @@ enum CLIB_A
13221341
{
13231342
realToDouble,
13241343
doubleToReal,
1344+
netf2,
13251345
}
13261346

13271347
private
@@ -1378,6 +1398,14 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
13781398
break;
13791399
}
13801400

1401+
case CLIB_A.netf2:
1402+
{
1403+
string name = "__netf2";
1404+
s = symboly(name, mask(32));
1405+
cinfo.retregs = mask(32);
1406+
break;
1407+
}
1408+
13811409
default:
13821410
assert(0);
13831411
}
@@ -1408,11 +1436,13 @@ void getClibInfo(uint clib, Symbol** ps, ClibInfo** pinfo, objfmt_t objfmt, exef
14081436
}
14091437

14101438
/********************************
1411-
* Generate code sequence to call C runtime library support routine.
1412-
* clib = CLIB_A.xxxx
1413-
* keepmask = mask of registers not to destroy. Currently can
1414-
* handle only 1. Should use a temporary rather than
1415-
* push/pop for speed.
1439+
* Generate code sequence to call compiler's runtime library support routine.
1440+
* Params:
1441+
* cdb = code sink
1442+
* e = elem being tested (null if none)
1443+
* clib = CLIB_A.xxxx (function to call)
1444+
* pretregs = register(s) to return result in
1445+
* keepmask = mask of registers not to destroy. Saves/restores them
14161446
*/
14171447

14181448
@trusted
@@ -1449,7 +1479,8 @@ void callclib(ref CodeBuilder cdb, elem* e, uint clib, ref regm_t pretregs, regm
14491479
cgstate.calledafunc = 1;
14501480

14511481
cdb.append(cdbpop);
1452-
fixresult(cdb, e, cinfo.retregs, pretregs);
1482+
if (e)
1483+
fixresult(cdb, e, cinfo.retregs, pretregs);
14531484
}
14541485

14551486

compiler/src/dmd/backend/arm/disasmarm.d

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ void disassemble(uint c) @trusted
295295
const(char)[] p6 = "";
296296
const(char)[] p7 = "";
297297
const(char)[] url = "";
298+
const(char)[] url2 = "";
298299

299300
string[4] addsubTab = [ "add", "adds", "sub", "subs" ];
300301
string[16] condstring =
@@ -2004,6 +2005,28 @@ void disassemble(uint c) @trusted
20042005
else
20052006

20062007
// Advanced SIMD modified immediate https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdimm
2008+
if (field(ins,31,31) == 0 && field(ins,28,19) == 0x1E0 && field(ins,10,10) == 1)
2009+
{
2010+
url = "asimdimm";
2011+
2012+
uint Q = field(ins,30,30);
2013+
uint op = field(ins,29,29);
2014+
uint abcdefgh = (field(ins,18,16) << 5) | field(ins,9,5);
2015+
uint cmode = field(ins,15,12);
2016+
uint o2 = field(ins,11,11);
2017+
uint Rd = field(ins,4,0);
2018+
2019+
if (Q == 1 && op == 1 && cmode == 0xE)
2020+
{
2021+
url2 = "movi_advsimd";
2022+
p1 = "movi"; // https://www.scs.stanford.edu/~zyedidia/arm64/movi_advsimd.html
2023+
// TODO AArch64 implement https://www.scs.stanford.edu/~zyedidia/arm64/shared_pseudocode.html#impl-shared.AdvSIMDExpandImm.3
2024+
uint n = snprintf(buf.ptr, cast(uint)buf.length, "v%d.2d,#0x%x", Rd, abcdefgh);
2025+
p2 = buf[0 .. n];
2026+
}
2027+
}
2028+
else
2029+
20072030
// Advanced SIMD shift by immediate https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdshf
20082031
// Advanced SIMD vector x indexed element https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdelem
20092032
// Cryptographic three-register, imm2 https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#crypto3_imm2
@@ -2442,8 +2465,17 @@ void disassemble(uint c) @trusted
24422465
{
24432466
for (; plen < 29; ++plen)
24442467
put(' ');
2445-
puts(" // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#");
2446-
puts(url);
2468+
puts(" // https://www.scs.stanford.edu/~zyedidia/arm64/");
2469+
if (url2)
2470+
{
2471+
puts(url2);
2472+
puts(".html");
2473+
}
2474+
else
2475+
{
2476+
puts("encodingindex.html#");
2477+
puts(url);
2478+
}
24472479
}
24482480
}
24492481
}
@@ -2949,8 +2981,9 @@ unittest
29492981
unittest
29502982
{
29512983
int line64 = __LINE__;
2952-
string[81] cases64 = // 64 bit code gen
2984+
string[82] cases64 = // 64 bit code gen
29532985
[
2986+
"6F 00 E4 01 movi v1.2d,#0x0",
29542987
"4E BE 1F C0 mov v0.16b,v30.16b",
29552988
"D4 20 00 20 brk #1",
29562989
"D6 3F 00 00 blr x0",

compiler/src/dmd/backend/arm/instr.d

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,18 @@ struct INSTR
707707
static uint mov_orr_advsimd_reg(uint Q, reg_t Vn, reg_t Vd) { return orr_advsimd_reg(Q,Vn,Vn,Vd); }
708708

709709
/* Advanced SIMD modified immediate
710-
* http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdimm
710+
* https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdimm
711711
*/
712+
static uint asimdimm(uint Q, uint op, uint cmode, uint o2, uint abcdefgh, reg_t Rd)
713+
{
714+
return (0 << 31) | (Q << 30) | (op << 29) | (0x1E0 << 19) | ((abcdefgh & 0xE0) << (16 - 5)) |
715+
(cmode << 12) | (o2 << 11) | (1 << 10) | ((abcdefgh & 0x1F) << 5) | (Rd & 31);
716+
}
712717

713-
// FMOV Rd, Rn https://www.scs.stanford.edu/~zyedidia/arm64/fmov_float.html
714-
static uint fmov(uint ftype, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,0,Vn & 31,Vd & 31); }
718+
/* MOVI <Vd>.2D, #<imm> etc.
719+
* http://www.scs.stanford.edu/~zyedidia/arm64/movi_advsimd.html
720+
*/
721+
static uint movi_advsimd(uint Q, uint op, uint cmode, uint abcdefgh, reg_t Rd) { return asimdimm(Q,op,cmode,0,abcdefgh,Rd); }
715722

716723
/* Advanced SIMD shift by immediate
717724
* Advanced SIMD vector x indexed element
@@ -785,6 +792,9 @@ struct INSTR
785792
return (M << 31) | (S << 29) | (0x1E << 24) | (ftype << 22) | (1 << 21) | (opcode << 15) | (0x10 << 10) | (Rn << 5) | Rd;
786793
}
787794

795+
// FMOV Rd, Rn https://www.scs.stanford.edu/~zyedidia/arm64/fmov_float.html
796+
static uint fmov(uint ftype, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,0,Vn & 31,Vd & 31); }
797+
788798
/* FCVT fpreg,fpreg https://www.scs.stanford.edu/~zyedidia/arm64/fcvt_float.html
789799
*/
790800
static uint fcvt_float(uint ftype, uint opcode, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,opcode,Vn & 31,Vd & 31); }

compiler/src/dmd/backend/x86/cod3.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ void cod3_stackadj(ref CodeBuilder cdb, int nbytes)
555555
Rd;
556556
cdb.gen1(ins);
557557
assert(imm12 < (1 << 12)); // only 12 bits allowed
558-
assert((imm12 & 0xF) == 0); // 16 byte aligned
558+
// assert((imm12 & 0xF) == 0); // 16 byte aligned
559559
return;
560560
}
561561
uint grex = I64 ? REX_W << 16 : 0;

0 commit comments

Comments
 (0)