Skip to content

Commit e0dcc96

Browse files
authored
implement code gen for fabs() (#21609)
1 parent 965c7b0 commit e0dcc96

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1814,7 +1814,7 @@ void assignaddrc(code* c)
18141814
{ /* Convert to SP relative address instead of BP */
18151815
offset += cgstate.EBPtoESP; // add difference in offset
18161816
ins = setField(ins,9,5,31); // set Rn to SP
1817-
assert(0); // offset is ignored
1817+
//assert(0); // offset is ignored
18181818
}
18191819
c.Iop = ins;
18201820

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,10 @@ struct INSTR
875875
*/
876876
static uint fcvt_float(uint ftype, uint opcode, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,opcode,Vn & 31,Vd & 31); }
877877

878+
/* FABS fpreg,fpreg https://www.scs.stanford.edu/~zyedidia/arm64/fabs_float.html
879+
*/
880+
static uint fabs_float(uint ftype, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,1,Vn & 31,Vd & 31); }
881+
878882
/* FNEG fpreg,fpreg https://www.scs.stanford.edu/~zyedidia/arm64/fneg_float.html
879883
*/
880884
static uint fneg_float(uint ftype, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,2,Vn & 31,Vd & 31); }

0 commit comments

Comments
 (0)