diff --git a/compiler/src/dmd/backend/arm/cod4.d b/compiler/src/dmd/backend/arm/cod4.d index f79c546af94..c2e444e3f66 100644 --- a/compiler/src/dmd/backend/arm/cod4.d +++ b/compiler/src/dmd/backend/arm/cod4.d @@ -1362,6 +1362,43 @@ else fixresult(cdb,e,retregs,pretregs); break; + case OPd_f: // fcvt d31,s31 + case OPf_d: // fcvt s31,d31 + regm_t retregs1 = ALLREGS; //INSTR.FLOATREGS; +static if (1) + retregs1 = mCX; // hack because no floating support in rest of code +else + codelem(cgstate,cdb,e.E1,retregs1,false); + const reg_t V1 = findreg(retregs1); // source floating point register + +static if (1) +{ + regm_t retregs = mDX; +} +else +{ + regm_t retregs = pretregs & INSTR.FLOATREGS; + if (retregs == 0) + retregs = INSTR.FLOATREGS & cgstate.allregs; +} + const tym = tybasic(e.Ety); + reg_t Vd = allocreg(cdb,retregs,tym); // destination integer register + + switch (e.Eoper) + { + case OPd_f: // fcvt s31,d31 + cdb.gen1(INSTR.fcvt_float(1,4,V1,Vd)); + break; + case OPf_d: // fcvt d31,s31 + cdb.gen1(INSTR.fcvt_float(0,5,V1,Vd)); + break; + default: + assert(0); + } + + fixresult(cdb,e,retregs,pretregs); + break; + default: assert(0); } diff --git a/compiler/src/dmd/backend/arm/disasmarm.d b/compiler/src/dmd/backend/arm/disasmarm.d index fc7ae68c3bf..447c287fc6e 100644 --- a/compiler/src/dmd/backend/arm/disasmarm.d +++ b/compiler/src/dmd/backend/arm/disasmarm.d @@ -1994,7 +1994,7 @@ void disassemble(uint c) @trusted field(ins,21,21) == 1 && field(ins,14,10) == 0x10) { - url = "floatdpl"; + url = "floatdp1"; uint M = field(ins,31,31); uint S = field(ins,29,29); diff --git a/compiler/src/dmd/backend/arm/instr.d b/compiler/src/dmd/backend/arm/instr.d index 2bf68fb6495..554449190bf 100644 --- a/compiler/src/dmd/backend/arm/instr.d +++ b/compiler/src/dmd/backend/arm/instr.d @@ -718,9 +718,13 @@ struct INSTR static uint floatdp1(uint M, uint S, uint ftype, uint opcode, uint Rn, uint Rd) { assert(Rn < 32 && Rd < 32); // remember to convert R32-63 to 0-31 - return (M << 31) | (S << 29) | (0x1E << 24) | (ftype << 22) | (1 << 21) | (0x10 << 10) | (Rn << 5) | Rd; + return (M << 31) | (S << 29) | (0x1E << 24) | (ftype << 22) | (1 << 21) | (opcode << 15) | (0x10 << 10) | (Rn << 5) | Rd; } + /* FCVT fpreg,fpreg https://www.scs.stanford.edu/~zyedidia/arm64/fcvt_float.html + */ + static uint fcvt_float(uint ftype, uint opcode, reg_t Rn, reg_t Rd) { return floatdp1(0,0,ftype,opcode,Rn,Rd); } + /* Floating-point compare * Floating-point immediate * Floating-point condistional compare