@@ -41,7 +41,7 @@ import dmd.backend.oper;
4141import dmd.backend.ty;
4242import dmd.backend.evalu8 : el_toldoubled;
4343import dmd.backend.x86.xmm;
44- import dmd.backend.arm.cod1 : getlvalue, loadFromEA, storeToEA;
44+ import dmd.backend.arm.cod1 : getlvalue, loadFromEA, storeToEA, CLIB_A ,callclib ;
4545import dmd.backend.arm.cod2 : tyToExtend;
4646import dmd.backend.arm.cod3 : COND , conditionCode, gentstreg;
4747import dmd.backend.arm.instr;
@@ -462,6 +462,7 @@ void floatOpAss(ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
462462
463463 if (e.Eoper == OPnegass)
464464 {
465+ assert (sz1 <= 8 ); // not for 128 bit operands
465466 bool regvar;
466467 getlvalue(cdb,cs,e1,0 );
467468 if (cs.reg == NOREG )
@@ -538,30 +539,52 @@ void floatOpAss(ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
538539 cdb.gen(&cs);
539540 }
540541
541- reg_t Rd = reg, Rn = rreg, Rm = reg;
542- uint ftype = INSTR .szToFtype(sz1);
543- switch (e.Eoper)
542+ if (sz1 == 16 ) // 128 bit float
544543 {
545- // FADD/FSUB (extended register)
546- // http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_ext
547- case OPaddass:
548- cdb.gen1(INSTR .fadd_float(ftype,Rm,Rn,Rd)); // FADD Rd,Rn,Rm
549- break ;
544+ CLIB_A clib;
545+ switch (e.Eoper)
546+ {
547+ case OPaddass: clib = CLIB_A .add; break ;
548+ case OPminass: clib = CLIB_A .min; break ;
549+ case OPmulass: clib = CLIB_A .mul; break ;
550+ case OPdivass: clib = CLIB_A .div; break ;
551+ default : assert (0 );
552+ }
553+ regm_t idxregs; // save index registers so we can do the storeToEA() later
554+ if (cs.base != NOREG )
555+ idxregs |= mask(cs.base);
556+ if (cs.index != NOREG )
557+ idxregs |= mask(cs.index);
558+ regm_t dummy;
559+ callclib(cdb,null ,clib,dummy,idxregs);
560+ }
561+ else
562+ {
563+ reg_t Rd = reg, Rn = rreg, Rm = reg;
564+ uint ftype = INSTR .szToFtype(sz1);
565+ switch (e.Eoper)
566+ {
567+ // FADD/FSUB (extended register)
568+ // http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp2
569+ case OPaddass:
570+ cdb.gen1(INSTR .fadd_float(ftype,Rm,Rn,Rd)); // FADD Rd,Rn,Rm
571+ break ;
550572
551- case OPminass:
552- cdb.gen1(INSTR .fsub_float(ftype,Rm,Rn,Rd)); // FSUB Rd,Rn,Rm
553- break ;
573+ case OPminass:
574+ cdb.gen1(INSTR .fsub_float(ftype,Rm,Rn,Rd)); // FSUB Rd,Rn,Rm
575+ break ;
554576
555- case OPmulass:
556- cdb.gen1(INSTR .fmul_float(ftype,Rm,Rn,Rd)); // FMUL Rd,Rn,Rm
557- break ;
577+ case OPmulass:
578+ cdb.gen1(INSTR .fmul_float(ftype,Rm,Rn,Rd)); // FMUL Rd,Rn,Rm
579+ break ;
558580
559- case OPdivass:
560- cdb.gen1(INSTR .fdiv_float(ftype,Rm,Rn,Rd)); // FDIV Rd,Rn,Rm
561- break ;
581+ case OPdivass:
582+ cdb.gen1(INSTR .fdiv_float(ftype,Rm,Rn,Rd)); // FDIV Rd,Rn,Rm
583+ break ;
562584
563- default :
564- assert (0 );
585+ default :
586+ assert (0 );
587+ }
565588 }
566589
567590 if (! regvar)
0 commit comments