From fd8b00b58c004c9582012e557eb05c364c0c68d9 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Mon, 3 Feb 2025 17:54:14 -0800 Subject: [PATCH] convert Freg numbers in instr.d --- compiler/src/dmd/backend/arm/cod4.d | 28 ++++++++-------- compiler/src/dmd/backend/arm/instr.d | 48 ++++++++++++++++------------ 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/compiler/src/dmd/backend/arm/cod4.d b/compiler/src/dmd/backend/arm/cod4.d index c2e444e3f66..766860a6014 100644 --- a/compiler/src/dmd/backend/arm/cod4.d +++ b/compiler/src/dmd/backend/arm/cod4.d @@ -1279,28 +1279,28 @@ else switch (e.Eoper) { case OPd_s16: - cdb.gen1(INSTR.fcvtzs(0,ftype,V1 & 31,Rd)); // fcvtzs Rd,V1 + cdb.gen1(INSTR.fcvtzs(0,ftype,V1,Rd)); // fcvtzs Rd,V1 cdb.gen1(INSTR.sxth_sbfm(0,Rd,Rd)); // sxth Rd,Rd break; case OPd_s32: - cdb.gen1(INSTR.fcvtzs(0,1,V1 & 31,Rd)); // fcvtzs Rd,V1 + cdb.gen1(INSTR.fcvtzs(0,1,V1,Rd)); // fcvtzs Rd,V1 break; case OPd_s64: cdb.gen1(INSTR.fcvtzs_asisdmisc(1,V1,V1)); // fcvtzs V1,V1 - cdb.gen1(INSTR.fmov_float_gen(1,1,0,6,V1 & 31,Rd)); // fmov Rd,V1 + cdb.gen1(INSTR.fmov_float_gen(1,1,0,6,V1,Rd)); // fmov Rd,V1 break; case OPd_u16: - cdb.gen1(INSTR.fcvtzu(0,ftype,V1 & 31,Rd)); // fcvtzu Rd,V1 + cdb.gen1(INSTR.fcvtzu(0,ftype,V1,Rd)); // fcvtzu Rd,V1 uint N,immr,imms; assert(encodeNImmrImms(0xFFFF,N,immr,imms)); cdb.gen1(INSTR.log_imm(0,0,0,immr,imms,Rd,Rd)); // and Rd,Rd,#0xFFFF break; case OPd_u32: - cdb.gen1(INSTR.fcvtzu(0,1,V1 & 31,Rd)); // fcvtzu Rd,V1 + cdb.gen1(INSTR.fcvtzu(0,1,V1,Rd)); // fcvtzu Rd,V1 break; case OPd_u64: cdb.gen1(INSTR.fcvtzu_asisdmisc(1,V1,V1)); // fcvtzu V1,V1 - cdb.gen1(INSTR.fmov_float_gen(1,1,0,6,V1 & 31,Rd)); // fmov Rd,V1 + cdb.gen1(INSTR.fmov_float_gen(1,1,0,6,V1,Rd)); // fmov Rd,V1 break; default: assert(0); @@ -1322,38 +1322,38 @@ else static if (1) { regm_t retregs = mCX; // hack because no floating support in rest of code - reg_t Rd = CX; + reg_t Vd = CX; } else { regm_t retregs = FLOATREGS; const tym = tybasic(e.Ety); - reg_t Rd = allocreg(cdb,retregs,tym); // destination integer register + reg_t Vd = 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 + cdb.gen1(INSTR.scvtf_float_int(0,1,Vd,R1)); // scvtf d31,w0 break; case OPs32_d: - cdb.gen1(INSTR.scvtf_float_int(0,1,Rd,R1)); // scvtf d31,w0 + cdb.gen1(INSTR.scvtf_float_int(0,1,Vd,R1)); // scvtf d31,w0 break; case OPs64_d: - cdb.gen1(INSTR.scvtf_float_int(1,1,Rd,R1)); // scvtf d31,x0 + cdb.gen1(INSTR.scvtf_float_int(1,1,Vd,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 + cdb.gen1(INSTR.ucvtf_float_int(0,1,Vd,R1)); // ucvtf d31,w0 break; case OPu32_d: - cdb.gen1(INSTR.ucvtf_float_int(0,1,Rd,R1)); // ucvtf d31,w0 + cdb.gen1(INSTR.ucvtf_float_int(0,1,Vd,R1)); // ucvtf d31,w0 break; case OPu64_d: - cdb.gen1(INSTR.ucvtf_float_int(1,1,Rd,R1)); // ucvtf d31,x0 + cdb.gen1(INSTR.ucvtf_float_int(1,1,Vd,R1)); // ucvtf d31,x0 break; default: assert(0); diff --git a/compiler/src/dmd/backend/arm/instr.d b/compiler/src/dmd/backend/arm/instr.d index 554449190bf..24be9eefa38 100644 --- a/compiler/src/dmd/backend/arm/instr.d +++ b/compiler/src/dmd/backend/arm/instr.d @@ -39,7 +39,7 @@ struct INSTR { pure nothrow: - /* Even though the floating point registers are V0..31, we call them 32-63 so they fit + /* Even though the floating point registers are 0..31, we call them V32..V63 so they fit * into regm_t. Remember to and them with 31 to generate an instruction */ enum FLOATREGS = 0xFFFF_FFFF_0000_0000; @@ -550,6 +550,7 @@ struct INSTR */ static uint asisdmisc(uint U, uint size, uint opcode, reg_t Rn, reg_t Rd) { + assert(Rn < 32 && Rd < 32); uint ins = (1 << 30) | (U << 29) | (0x1E << 24) | @@ -565,12 +566,12 @@ struct INSTR /* FCVTZS , https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzs_advsimd_int.html * Scalar single-precision and double-precision */ - static uint fcvtzs_asisdmisc(uint sz, reg_t Rn, reg_t Rd) { return asisdmisc(0, 2|sz, 0x1B, Rn, Rd); } + static uint fcvtzs_asisdmisc(uint sz, reg_t Vn, reg_t Vd) { return asisdmisc(0, 2|sz, 0x1B, Vn & 31, Vd & 31); } /* FCVTZU , https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzu_advsimd_int.html * Scalar single-precision and double-precision */ - static uint fcvtzu_asisdmisc(uint sz, reg_t Rn, reg_t Rd) { return asisdmisc(1, 2|sz, 0x1B, Rn, Rd); } + static uint fcvtzu_asisdmisc(uint sz, reg_t Vn, reg_t Vd) { return asisdmisc(1, 2|sz, 0x1B, Vn & 31, Vd & 31); } /* Advanced SIMD scalar pairwise @@ -592,6 +593,7 @@ struct INSTR */ static uint asimdmisc(uint Q, uint U, uint size, uint opcode, reg_t Rn, reg_t Rd) { + assert(Rn < 32 && Rd < 32); uint ins = (0 << 31) | (Q << 30) | (U << 29) | @@ -608,23 +610,24 @@ struct INSTR /* CNT ., . * https://www.scs.stanford.edu/~zyedidia/arm64/cnt_advsimd.html */ - static uint cnt_advsimd(uint Q, uint size, reg_t Rn, reg_t Rd) { return asimdmisc(Q, 0, size, 5, Rn, Rd); } + static uint cnt_advsimd(uint Q, uint size, reg_t Vn, reg_t Vd) { return asimdmisc(Q, 0, size, 5, Vn & 31, Vd & 31); } /* FCVTZS .,. https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzs_advsimd_int.html * Vector single-precision and double-precision */ - static uint fcvtzs_asimdmisc(uint Q, uint sz, reg_t Rn, reg_t Rd) { return asimdmisc(Q, 0, 2|sz, 0x1B, Rn, Rd); } + static uint fcvtzs_asimdmisc(uint Q, uint sz, reg_t Vn, reg_t Vd) { return asimdmisc(Q, 0, 2|sz, 0x1B, Vn & 31, Vd & 31); } /* FCVTZU .,. https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzu_advsimd_int.html * Vector single-precision and double-precision */ - static uint fcvtzu_asimdmisc(uint Q, uint sz, reg_t Rn, reg_t Rd) { return asimdmisc(Q, 1, 2|sz, 0x1B, Rn, Rd); } + static uint fcvtzu_asimdmisc(uint Q, uint sz, reg_t Vn, reg_t Vd) { return asimdmisc(Q, 1, 2|sz, 0x1B, Vn & 31, Vd & 31); } /* Advanced SIMD across lanes * https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#asimdall */ static uint asimdall(uint Q, uint U, uint size, uint opcode, reg_t Rn, reg_t Rd) { + assert(Rn < 32 && Rd < 32); uint ins = (0 << 31) | (Q << 30) | (U << 29) | @@ -640,11 +643,11 @@ struct INSTR /* ADDV , . https://www.scs.stanford.edu/~zyedidia/arm64/addv_advsimd.html */ - static uint addv_advsimd(uint Q, uint size, reg_t Rn, reg_t Rd) { return asimdall(Q, 0, size, 0x1B, Rn, Rd); } + static uint addv_advsimd(uint Q, uint size, reg_t Vn, reg_t Vd) { return asimdall(Q, 0, size, 0x1B, Vn & 31, Vd & 31); } /* UADDLV , . https://www.scs.stanford.edu/~zyedidia/arm64/uaddlv_advsimd.html */ - static uint uaddlv_advsimd(uint Q, uint size, reg_t Rn, reg_t Rd) { return asimdall(Q, 1, size, 3, Rn, Rd); } + static uint uaddlv_advsimd(uint Q, uint size, reg_t Vn, reg_t Vd) { return asimdall(Q, 1, size, 3, Vn & 31, Vd & 31); } /* Advanced SIMD three different * Advanced SIMD three same @@ -655,7 +658,7 @@ struct INSTR */ // FMOV Rd, Rn https://www.scs.stanford.edu/~zyedidia/arm64/fmov_float.html - static uint fmov(uint ftype, uint Rn, uint Rd) { return floatdp1(0,0,ftype,0,Rn,Rd); } + static uint fmov(uint ftype, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,0,Vn & 31,Vd & 31); } /* Advanced SIMD shift by immediate * Advanced SIMD vector x indexed element @@ -671,6 +674,7 @@ struct INSTR */ static uint float2int(uint sf, uint S, uint ftype, uint rmode, uint opcode, reg_t Rn, reg_t Rd) { + assert(Rn < 32 && Rd < 32); return (sf << 31) | (S << 29) | (0x1E << 24) | (ftype << 22) | (1 << 21) | (rmode << 19) | (opcode << 16) | (Rn << 5) | Rd; } @@ -678,52 +682,56 @@ struct INSTR */ static uint fmov_float_gen(uint sf, uint ftype, uint rmode, uint opcode, reg_t Rn, reg_t Rd) { + if (opcode == 7) + Rd &= 31; + else if (opcode == 6) + Rn &= 31; return float2int(sf, 0, ftype, rmode, opcode, Rn, Rd); } /* FCVTNS (scalar) https://www.scs.stanford.edu/~zyedidia/arm64/fcvtns_float.html */ - static uint fcvtns(uint sf, uint ftype, reg_t Rn, reg_t Rd) + static uint fcvtns(uint sf, uint ftype, reg_t Vn, reg_t Rd) { - return float2int(sf, 0, ftype, 0, 0, Rn, Rd); + return float2int(sf, 0, ftype, 0, 0, Vn & 31, Rd); } /* FCVTNU (scalar) https://www.scs.stanford.edu/~zyedidia/arm64/fcvtnu_float.html */ - static uint fcvtnu(uint sf, uint ftype, reg_t Rn, reg_t Rd) + static uint fcvtnu(uint sf, uint ftype, reg_t Vn, reg_t Rd) { - return float2int(sf, 0, ftype, 0, 1, Rn, Rd); + return float2int(sf, 0, ftype, 0, 1, Vn & 31, Rd); } /* FCVTZS (scalar, integer) https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzs_float_int.html */ - static uint fcvtzs(uint sf, uint ftype, reg_t Rn, reg_t Rd) { return float2int(sf, 0, ftype, 3, 0, Rn, Rd); } + static uint fcvtzs(uint sf, uint ftype, reg_t Vn, reg_t Rd) { return float2int(sf, 0, ftype, 3, 0, Vn & 31, Rd); } /* FCVTZU (scalar, integer) https://www.scs.stanford.edu/~zyedidia/arm64/fcvtzu_float_int.html */ - 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 Vn, reg_t Rd) { return float2int(sf, 0, ftype, 3, 1, Vn & 31, 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); } + static uint scvtf_float_int(uint sf, uint ftype, reg_t Rn, reg_t Vd) { return float2int(sf,0,ftype,0,2,Rn,Vd & 31); } /* 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); } + static uint ucvtf_float_int(uint sf, uint ftype, reg_t Rn, reg_t Vd) { return float2int(sf,0,ftype,0,3,Rn,Vd & 31); } /* Floating-point data-processing (1 source) * https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp1 */ - static uint floatdp1(uint M, uint S, uint ftype, uint opcode, uint Rn, uint Rd) + static uint floatdp1(uint M, uint S, uint ftype, uint opcode, reg_t Rn, reg_t Rd) { - assert(Rn < 32 && Rd < 32); // remember to convert R32-63 to 0-31 + assert(Rn < 32 && Rd < 32); // remember to convert V32..V63 to R0..R31 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); } + static uint fcvt_float(uint ftype, uint opcode, reg_t Vn, reg_t Vd) { return floatdp1(0,0,ftype,opcode,Vn & 31,Vd & 31); } /* Floating-point compare * Floating-point immediate