@@ -2054,7 +2054,40 @@ void cdabs(ref CGstate cg, ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
20542054 const sz = _tysize[tyml];
20552055 if (tyfloating(tyml))
20562056 {
2057- assert (0 ); // TODO AArch64
2057+ regm_t retregs = pretregs & INSTR .FLOATREGS ;
2058+ if (retregs == 0 ) /* if no return regs speced */
2059+ /* (like if wanted flags only) */
2060+ retregs = INSTR .FLOATREGS ; // give us some
2061+ codelem(cgstate,cdb,e.E1 ,retregs,false );
2062+ getregs(cdb,retregs); // retregs will be destroyed
2063+
2064+ const Vn = findreg(retregs);
2065+
2066+ if (sz == 16 ) // 128 bit float
2067+ {
2068+ /* Generate:
2069+ FMOV Xn,Vn.d[1] // upper 64 bits
2070+ EOR Xn,Xn,#0x8000_0000_0000_0000 // toggle sign bit
2071+ FMOV Vn.d[1],Xn // store upper 64 bits
2072+ */
2073+ // Alloc Xn
2074+ regm_t retregsx = cg.allregs;
2075+ const Xn = allocreg(cdb,retregsx,TYllong); // scratch register Xn
2076+ // https://www.scs.stanford.edu/~zyedidia/arm64/fmov_float_gen.html
2077+ cdb.gen1(INSTR .fmov_float_gen(1 ,2 ,1 ,6 ,Vn,Xn)); // Top half of 128-bit to 64-bit
2078+ uint N, immr, imms;
2079+ assert (encodeNImmrImms(0x8000_0000_0000_0000,N,immr,imms));
2080+ uint sf = 1 , opc = 2 ;
2081+ cdb.gen1(INSTR .log_imm(sf,opc,N,immr,imms,Xn,Xn)); // https://www.scs.stanford.edu/~zyedidia/arm64/eor_log_imm.html
2082+ cdb.gen1(INSTR .fmov_float_gen(1 ,2 ,1 ,7 ,Xn,Vn)); // 64-bit to top half of 128-bit
2083+ }
2084+ else
2085+ {
2086+ const ftype = INSTR .szToFtype(sz);
2087+ cdb.gen1(INSTR .fabs_float(ftype, Vn, Vn));
2088+ }
2089+ fixresult(cdb,e,retregs,pretregs);
2090+ return ;
20582091 }
20592092
20602093 const posregs = cgstate.allregs;
0 commit comments