more of AArch64 cdcvt implemented (#20814)

This commit is contained in:
Walter Bright 2025-02-02 22:35:54 -08:00 committed by GitHub
parent 6e249f01dd
commit e132fb4d3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 87 additions and 12 deletions

View file

@ -1264,8 +1264,10 @@ void cdcnvt(ref CGstate cg, ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
case OPd_u64: // fcvtzu d31,d31 // fmov x0,d31 case OPd_u64: // fcvtzu d31,d31 // fmov x0,d31
L2: L2:
regm_t retregs1 = ALLREGS; //INSTR.FLOATREGS; regm_t retregs1 = ALLREGS; //INSTR.FLOATREGS;
retregs1 = mCX; // hack because no floating support in rest of code static if (1)
// codelem(cgstate,cdb,e.E1,retregs1,false); 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 const reg_t V1 = findreg(retregs1); // source floating point register
regm_t retregs = pretregs & cg.allregs; regm_t retregs = pretregs & cg.allregs;
@ -1307,6 +1309,59 @@ retregs1 = mCX; // hack because no floating support in rest of code
fixresult(cdb,e,retregs,pretregs); fixresult(cdb,e,retregs,pretregs);
break; break;
case OPs16_d: // sxth w0,w0 // scvtf d31,w0
case OPs32_d: // scvtf d31,w0
case OPs64_d: // scvtf d31,x0
case OPu16_d: // and w0,w0,#0xFFFF // ucvtf d31,w0
case OPu32_d: // ucvtf d31,w0
case OPu64_d: // ucvtf d31,x0
regm_t retregs1 = ALLREGS;
codelem(cgstate,cdb,e.E1,retregs1,false);
reg_t R1 = findreg(retregs1);
static if (1)
{
regm_t retregs = mCX; // hack because no floating support in rest of code
reg_t Rd = CX;
}
else
{
regm_t retregs = FLOATREGS;
const tym = tybasic(e.Ety);
reg_t Rd = allocreg(cdb,retregs,tym); // destination integer register
}
switch (e.Eoper)
{
case OPs16_d:
cdb.gen1(INSTR.sxth_sbfm(0,R1,R1)); // sxth w0,w0
cdb.gen1(INSTR.scvtf_float_int(0,1,Rd,R1)); // scvtf d31,w0
break;
case OPs32_d:
cdb.gen1(INSTR.scvtf_float_int(0,1,Rd,R1)); // scvtf d31,w0
break;
case OPs64_d:
cdb.gen1(INSTR.scvtf_float_int(1,1,Rd,R1)); // scvtf d31,x0
break;
case OPu16_d:
/* not executed because OPu16_d was converted to OPu16_32 then OP32_d */
uint N,immr,imms;
assert(encodeNImmrImms(0xFFFF,N,immr,imms));
cdb.gen1(INSTR.log_imm(0,0,0,immr,imms,R1,R1)); // and w0,w0,#0xFFFF
cdb.gen1(INSTR.ucvtf_float_int(0,1,Rd,R1)); // ucvtf d31,w0
break;
case OPu32_d:
cdb.gen1(INSTR.ucvtf_float_int(0,1,Rd,R1)); // ucvtf d31,w0
break;
case OPu64_d:
cdb.gen1(INSTR.ucvtf_float_int(1,1,Rd,R1)); // ucvtf d31,x0
break;
default:
assert(0);
}
fixresult(cdb,e,retregs,pretregs);
break;
default: default:
assert(0); assert(0);
} }
@ -1456,7 +1511,7 @@ void cdshtlng(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
{ {
uint N,immr,imms; uint N,immr,imms;
assert(encodeNImmrImms(0xFFFF,N,immr,imms)); assert(encodeNImmrImms(0xFFFF,N,immr,imms));
uint ins = INSTR.log_imm(0,0,N,immr,imms,reg,reg); // AND Xreg,Xreg,#0xFFFF uint ins = INSTR.log_imm(0,0,0,immr,imms,reg,reg); // AND Xreg,Xreg,#0xFFFF
cdb.gen1(ins); cdb.gen1(ins);
} }
else else
@ -1497,7 +1552,7 @@ void cdshtlng(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
{ {
uint N,immr,imms; uint N,immr,imms;
assert(encodeNImmrImms(0xFFFF,N,immr,imms)); assert(encodeNImmrImms(0xFFFF,N,immr,imms));
uint ins = INSTR.log_imm(0,0,N,immr,imms,reg,reg); // AND reg,reg,#0xFFFF uint ins = INSTR.log_imm(0,0,0,immr,imms,reg,reg); // AND reg,reg,#0xFFFF
cdb.gen1(ins); cdb.gen1(ins);
} }
else else

View file

@ -1979,6 +1979,12 @@ void disassemble(uint c) @trusted
p2 = fregString(rbuf[4 .. 8],"sd h"[ftype],Rd); p2 = fregString(rbuf[4 .. 8],"sd h"[ftype],Rd);
p3 = regString(sf,Rn); p3 = regString(sf,Rn);
} }
else if (S == 0 && rmode == 0 && (opcode & ~1) == 2)
{
p1 = opcode & 1 ? "ucvtf" : "scvtf";
p2 = fregString(rbuf[4 .. 8],"sd h"[ftype],Rd);
p3 = regString(sf,Rn);
}
} }
} }
else else
@ -2803,8 +2809,10 @@ unittest
unittest unittest
{ {
int line64 = __LINE__; int line64 = __LINE__;
string[73] cases64 = // 64 bit code gen string[75] cases64 = // 64 bit code gen
[ [
"1E 62 00 1F scvtf d31,w0",
"1E 63 00 1F ucvtf d31,w0",
"5E E1 BB FE fcvtzs d30,d31", "5E E1 BB FE fcvtzs d30,d31",
"5E A1 BB FF fcvtzs s31,s31", "5E A1 BB FF fcvtzs s31,s31",
"1E 78 03 E0 fcvtzs w0,d31", "1E 78 03 E0 fcvtzs w0,d31",

View file

@ -703,6 +703,15 @@ struct INSTR
*/ */
static uint fcvtzu(uint sf, uint ftype, reg_t Rn, reg_t Rd) { return float2int(sf, 0, ftype, 3, 1, Rn, Rd); } static uint fcvtzu(uint sf, uint ftype, reg_t Rn, reg_t Rd) { return float2int(sf, 0, ftype, 3, 1, Rn, Rd); }
/* SCVTF (scalar, integer) https://www.scs.stanford.edu/~zyedidia/arm64/scvtf_float_int.html
*/
static uint scvtf_float_int(uint sf, uint ftype, reg_t Rn, reg_t Rd) { return float2int(sf,0,ftype,0,2,Rn,Rd); }
/* UCVTF (scalar, integer) https://www.scs.stanford.edu/~zyedidia/arm64/ucvtf_float_int.html
*/
static uint ucvtf_float_int(uint sf, uint ftype, reg_t Rn, reg_t Rd) { return float2int(sf,0,ftype,0,3,Rn,Rd); }
/* Floating-point data-processing (1 source) /* Floating-point data-processing (1 source)
* https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp1 * https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp1
*/ */

View file

@ -5207,6 +5207,9 @@ private elem* elu64_d(elem* e, Goal goal)
if (!pu || (*pu).Eoper == OPconst) if (!pu || (*pu).Eoper == OPconst)
return evalu8(e, goal); return evalu8(e, goal);
if (config.target_cpu == TARGET_AArch64)
return e;
elem* u = *pu; elem* u = *pu;
if (config.fpxmmregs && I64 && (ty == TYfloat || ty == TYdouble)) if (config.fpxmmregs && I64 && (ty == TYfloat || ty == TYdouble))
{ {

View file

@ -518,15 +518,15 @@ private elem* initializeParamsWithArgs(elem* eargs, SYMIDX sistart, SYMIDX siend
auto s2 = nextSymbol(si); auto s2 = nextSymbol(si);
if (!s2) if (!s2)
{ {
for (size_t m = args.length; m; --m) for (size_t m = args.length; m; --m)
{ {
elem* ex = args[m - 1]; elem* ex = args[m - 1];
printf("arg[%d]\n", cast(int) m); printf("arg[%d]\n", cast(int) m);
elem_print(ex); elem_print(ex);
} }
printf("function: %s\n", funcsym_p.Sident.ptr); printf("function: %s\n", funcsym_p.Sident.ptr);
printf("szs: %d sze: %d\n", cast(int)szs, cast(int)sze); printf("szs: %d sze: %d\n", cast(int)szs, cast(int)sze);
printf("detected slice with %s\n", s.Sident.ptr); printf("detected slice with %s\n", s.Sident.ptr);
symbol_print(*s); elem_print(e); assert(0); symbol_print(*s); elem_print(e); assert(0);
} }