add loads of floating point constants

This commit is contained in:
Walter Bright 2025-02-17 20:55:02 -08:00 committed by The Dlang Bot
parent b5e0bee399
commit 56f35fd4df
5 changed files with 57 additions and 7 deletions

View file

@ -37,6 +37,7 @@ import dmd.backend.ty;
import dmd.backend.type;
import dmd.backend.arm.cod3 : COND, genBranch, conditionCode, gentstreg;
import dmd.backend.arm.instr;
import dmd.backend.arm.cod3 : loadFloatRegConst;
import dmd.backend.x86.cod1 : cdisscaledindex, ssindex_array;
import dmd.backend.cg : segfl, stackfl;
@ -2172,8 +2173,6 @@ private void movParams(ref CodeBuilder cdb, elem* e, uint stackalign, uint funca
*/
@trusted
void loaddata(ref CodeBuilder cdb, elem* e, ref regm_t outretregs)
{
static if (1)
{
reg_t reg;
reg_t nreg;
@ -2216,7 +2215,7 @@ static if (1)
forregs = outretregs & (cgstate.allregs | INSTR.FLOATREGS); // XMMREGS ?
if (e.Eoper == OPconst)
{
if (tyvector(tym) && forregs & XMMREGS)
if (0 && tyvector(tym) && forregs & XMMREGS) // TODO
{
assert(!flags);
const xreg = allocreg(cdb, forregs, tym); // allocate registers
@ -2225,6 +2224,16 @@ static if (1)
return;
}
if (tyfloating(tym))
{
const vreg = allocreg(cdb, forregs, tym); // allocate floating point register
float value = e.Vfloat;
if (sz == 8)
value = e.Vdouble;
loadFloatRegConst(cdb,vreg,value,sz);
return;
}
targ_size_t value = e.Vint;
if (sz == 8)
value = cast(targ_size_t)e.Vullong;
@ -2414,4 +2423,3 @@ static if (1)
return;
}
}
}

View file

@ -30,6 +30,7 @@ import dmd.backend.cc;
import dmd.backend.cdef;
import dmd.backend.cgcse;
import dmd.backend.code;
import dmd.backend.arm.disasmarm : encodeHFD;
import dmd.backend.x86.cgcod : disassemble;
import dmd.backend.x86.code_x86;
import dmd.backend.x86.cod3;
@ -218,7 +219,6 @@ COND conditionCode(elem* e)
// genmovreg
// genmulimm
// genshift
// movregconst
/**************************
* Generate a jump instruction.
@ -695,6 +695,45 @@ void genmovreg(ref CodeBuilder cdb, reg_t to, reg_t from, tym_t ty = TYMAX)
}
}
/*************************************
* Load constant floating point value into vreg.
* Params:
* cdb = code sink for generated output
* vreg = target floating point register
* value = value to move into register
* sz = 4 for float, 8 for double
*/
@trusted
void loadFloatRegConst(ref CodeBuilder cdb, reg_t vreg, double value, uint sz)
{
assert(vreg & 32);
ubyte imm8;
if (encodeHFD(value, imm8))
{
uint ftype = INSTR.szToFtype(sz);
cdb.gen1(INSTR.fmov_float_imm(ftype,imm8,vreg)); // FMOV <Vd>,#<imm8>
}
else if (sz == 4)
{
float f = value;
uint i = *cast(uint*)&f;
regm_t retregs = ALLREGS; // TODO cg.allregs?
reg_t reg = allocreg(cdb, retregs, TYfloat);
movregconst(cdb,reg,i,0); // MOV reg,i
cdb.gen1(INSTR.fmov_float_gen(0,0,0,7,reg,vreg)); // FMOV Sd,Wn
}
else if (sz == 8)
{
ulong i = *cast(ulong*)&value;
regm_t retregs = ALLREGS; // TODO cg.allregs?
reg_t reg = allocreg(cdb, retregs, TYdouble);
movregconst(cdb,reg,i,64); // MOV reg,i
cdb.gen1(INSTR.fmov_float_gen(1,1,0,7,reg,vreg)); // FMOV Dd,Xn
}
else
assert(0);
//cgstate.regimmed_set(vreg,value); // TODO
}
/******************************
* Move constant value into reg.
@ -846,7 +885,7 @@ void movregconst(ref CodeBuilder cdb,reg_t reg,targ_size_t value,regm_t flags)
done:
if (flags & mPSW)
gentstreg(cdb,reg,(flags & 64) != 0);
printf("set reg %d to %lld\n", reg, value);
//printf("set reg %d to %lld\n", reg, value);
cgstate.regimmed_set(reg,value);
}

View file

@ -2760,6 +2760,7 @@ unittest
* Returns:
* true for success
*/
public
bool encodeHFD(double d, out ubyte imm8)
{
float f = d;

View file

@ -100,7 +100,8 @@ void out_config_init(
}
cfg.fulltypes = CVNONE;
cfg.fpxmmregs = false;
cfg.inline8087 = 1;
if (!arm)
cfg.inline8087 = 1;
cfg.memmodel = 0;
cfg.flags |= CFGuchar; // make sure TYchar is unsigned
cfg.exe = exefmt;

View file

@ -1147,6 +1147,7 @@ int el_countCommas(const(elem)* e)
@trusted
elem* el_convfloat(ref GlobalOptimizer go, elem* e)
{
//printf("el_convfloat()\n"); elem_print(e);
ubyte[32] buffer = void;
assert(config.inline8087);