Skip to content

Commit 4bf6ced

Browse files
WalterBrightthewilsonator
authored andcommitted
support += for complex floats
1 parent 952f7e0 commit 4bf6ced

File tree

2 files changed

+81
-20
lines changed

2 files changed

+81
-20
lines changed

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

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,7 @@ void fixresult(ref CodeBuilder cdb, elem* e, regm_t retregs, ref regm_t outretre
13711371
regm_t forccs = outretregs & mPSW;
13721372
regm_t forregs = outretregs & (INSTR.ALLREGS | INSTR.FLOATREGS);
13731373
tym_t tym = tybasic(e.Ety);
1374+
bool isPair = isRegisterPair(true, tym, 0);
13741375

13751376
if (tym == TYstruct)
13761377
{
@@ -1388,8 +1389,32 @@ void fixresult(ref CodeBuilder cdb, elem* e, regm_t retregs, ref regm_t outretre
13881389
outretregs = retregs;
13891390
else if (forregs) // if return the result in registers
13901391
{
1391-
bool opsflag = false;
1392-
if (tyfloating(tym))
1392+
if (isPair)
1393+
{
1394+
sz /= 2;
1395+
reg_t msreg = findreg(retregs & INSTR.MSW);
1396+
reg_t lsreg = findreg(retregs & INSTR.LSW);
1397+
1398+
allocreg(cdb, outretregs, tym); // allocate return regs
1399+
reg_t msrreg = findreg(outretregs & INSTR.MSW);
1400+
reg_t lsrreg = findreg(outretregs & INSTR.LSW);
1401+
1402+
// should fix genmovreg() to do this work
1403+
if (tyfloating(tym))
1404+
{
1405+
const uint ftype = INSTR.szToFtype(sz);
1406+
assert((msreg & lsreg & msrreg & lsrreg) & 32); // ensure all fp registers
1407+
cdb.gen1(INSTR.fmov(ftype,msreg,msrreg)); // FMOV msrreg,msreg
1408+
cdb.gen1(INSTR.fmov(ftype,lsreg,lsrreg)); // FMOV lsrreg,lsreg
1409+
}
1410+
else
1411+
{
1412+
assert(((msreg | lsreg | msrreg | lsrreg) & 32) == 0); // ensure all gp registers
1413+
cdb.gen1(INSTR.mov_register(sz == 8,msreg,msrreg)); // MOV msrreg,msreg
1414+
cdb.gen1(INSTR.mov_register(sz == 8,lsreg,lsrreg)); // MOV lsrreg,lsreg
1415+
}
1416+
}
1417+
else if (tyfloating(tym))
13931418
{
13941419
assert(outretregs & INSTR.FLOATREGS);
13951420
reg_t Vn = findreg(retregs);
@@ -1405,25 +1430,13 @@ void fixresult(ref CodeBuilder cdb, elem* e, regm_t retregs, ref regm_t outretre
14051430
cdb.gen1(INSTR.fmov(ftype,Vn,Vd)); // FMOV Vd,Vn
14061431
}
14071432
}
1408-
else if (sz > REGSIZE)
1409-
{
1410-
reg_t msreg = findreg(retregs & INSTR.MSW);
1411-
reg_t lsreg = findreg(retregs & INSTR.LSW);
1412-
1413-
allocreg(cdb, outretregs, tym); // allocate return regs
1414-
reg_t msrreg = findreg(outretregs & INSTR.MSW);
1415-
reg_t lsrreg = findreg(outretregs & INSTR.LSW);
1416-
1417-
cdb.gen1(INSTR.mov_register(sz == 8,msreg,msrreg)); // MOV msrreg,msreg
1418-
cdb.gen1(INSTR.mov_register(sz == 8,lsreg,lsrreg)); // MOV lsrreg,lsreg
1419-
}
14201433
else
14211434
{
14221435
reg_t reg = findreg(retregs & INSTR.ALLREGS);
14231436
reg_t rreg = allocreg(cdb, outretregs, tym); // allocate return regs
14241437
cdb.gen1(INSTR.mov_register(sz == 8,reg,rreg)); // MOV rreg,reg
14251438
}
1426-
cssave(e,retregs | outretregs,opsflag);
1439+
cssave(e,retregs | outretregs,false);
14271440
// Commented out due to Bugzilla 8840
14281441
//forregs = 0; // don't care about result in reg cuz real result is in rreg
14291442
retregs = outretregs & ~mPSW;

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

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,9 @@ void floatOpAss(ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
592592
if (isregvar(e1,varregm,varreg) && // if lvalue is register variable
593593
doinreg(e1.Vsym,e2) // and we can compute directly into it
594594
)
595-
{ regvar = true;
595+
{
596+
assert(!isPair); // TODO AArch64
597+
regvar = true;
596598
retregs = varregm;
597599
reg = varreg; // evaluate directly in target register
598600
getregs(cdb,retregs); // destroy these regs
@@ -605,12 +607,58 @@ void floatOpAss(ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
605607
retregs = pretregs & INSTR.FLOATREGS & ~rretregs;
606608
if (!retregs)
607609
retregs = INSTR.FLOATREGS & ~rretregs;
608-
reg = allocreg(cdb,retregs,ty1);
609-
loadFromEA(cs,reg,sz1,sz1);
610+
allocreg(cdb,retregs,ty1);
611+
reg = findreg(isPair ? retregs & INSTR.LSW : retregs);
612+
if (isPair)
613+
loadFromEA(cs,reg,sz1 / 2,sz1 / 2);
614+
else
615+
loadFromEA(cs,reg,sz1,sz1);
610616
cdb.gen(&cs);
611617
}
612618

613-
if (sz1 == 16) // 128 bit float
619+
if (isPair)
620+
{
621+
sz1 /= 2;
622+
rreg = findreg(rretregs & INSTR.LSW);
623+
reg_t Rd = reg, Rn = rreg, Rm = reg; // reg = rreg + reg
624+
const uint ftype = INSTR.szToFtype(sz1);
625+
switch (e.Eoper)
626+
{
627+
// FADD/FSUB (extended register)
628+
// http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp2
629+
case OPaddass:
630+
cdb.gen1(INSTR.fadd_float(ftype,Rn,Rm,Rd)); // FADD Rd,Rn,Rm
631+
if (!regvar)
632+
{
633+
storeToEA(cs,reg,sz1);
634+
cdb.gen(&cs);
635+
}
636+
637+
reg = findreg(retregs & INSTR.MSW);
638+
rreg = findreg(rretregs & INSTR.MSW);
639+
if (cs.reg == NOREG)
640+
cs.IEV1.Voffset += sz1;
641+
else
642+
cs.reg = reg;
643+
loadFromEA(cs,reg,sz1,sz1);
644+
cdb.gen(&cs);
645+
Rd = reg, Rn = rreg, Rm = reg; // reg = rreg + reg
646+
cdb.gen1(INSTR.fadd_float(ftype,Rn,Rm,Rd)); // FADD Rd,Rn,Rm
647+
break;
648+
649+
case OPminass:
650+
cdb.gen1(INSTR.fsub_float(ftype,Rn,Rm,Rd)); // FSUB Rd,Rn,Rm
651+
break;
652+
653+
case OPmulass:
654+
case OPdivass:
655+
assert(0); // TODO AArch64
656+
657+
default:
658+
assert(0);
659+
}
660+
}
661+
else if (sz1 == 16) // 128 bit float
614662
{
615663
CLIB_A clib;
616664
switch (e.Eoper)
@@ -631,7 +679,7 @@ void floatOpAss(ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
631679
}
632680
else
633681
{
634-
reg_t Rd = reg, Rn = rreg, Rm = reg;
682+
const reg_t Rd = reg, Rn = rreg, Rm = reg;
635683
uint ftype = INSTR.szToFtype(sz1);
636684
switch (e.Eoper)
637685
{

0 commit comments

Comments
 (0)