diff --git a/compiler/src/dmd/backend/arm/cod1.d b/compiler/src/dmd/backend/arm/cod1.d index 7c36b4cef3..338ad941b9 100644 --- a/compiler/src/dmd/backend/arm/cod1.d +++ b/compiler/src/dmd/backend/arm/cod1.d @@ -56,7 +56,9 @@ nothrow: */ void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr) { - if (reg & 32) // if floating point register + cs.Iop = INSTR.nop; + assert(reg != NOREG); + if (mask(reg) & INSTR.FLOATREGS) // if floating point store { if (cs.reg != NOREG) { @@ -120,7 +122,10 @@ void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr) */ void storeToEA(ref code cs, reg_t reg, uint sz) { - if (reg & 32) // if floating point store + //debug printf("storeToEA(reg: %d, sz: %d)\n", reg, sz); + cs.Iop = INSTR.nop; + assert(reg != NOREG); + if (mask(reg) & INSTR.FLOATREGS) // if floating point store { if (cs.reg != NOREG) { @@ -1071,7 +1076,7 @@ void getlvalue(ref CodeBuilder cdb,ref code pcs,elem* e,regm_t keepmsk,RM rm = R * such variables. */ if (tyxmmreg(ty) && !(s.Sregm & XMMREGS) || - !tyxmmreg(ty) && (s.Sregm & XMMREGS)) + !tyxmmreg(ty) && (s.Sregm & XMMREGS)) // TODO AArch64 cgreg_unregister(s.Sregm); if ( diff --git a/compiler/src/dmd/backend/arm/cod3.d b/compiler/src/dmd/backend/arm/cod3.d index 688204fb92..9f1206f631 100644 --- a/compiler/src/dmd/backend/arm/cod3.d +++ b/compiler/src/dmd/backend/arm/cod3.d @@ -30,6 +30,7 @@ import dmd.backend.cc; import dmd.backend.cdef; import dmd.backend.cgcse; import dmd.backend.code; +import dmd.backend.arm.cod1 : loadFromEA, storeToEA; import dmd.backend.arm.disasmarm : encodeHFD; import dmd.backend.x86.cgcod : disassemble; import dmd.backend.x86.code_x86; @@ -207,9 +208,90 @@ COND conditionCode(elem* e) // cod3_ptrchk // cod3_useBP // cse_simple -// gen_storecse -// gen_testcse -// gen_loadcse + +/************************** + * Store `reg` to the common subexpression save area in index `slot`. + * Params: + * cdb = where to write code to + * tym = type of value that's in `reg` + * reg = register to save + * slot = index into common subexpression save area + */ +@trusted +void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot) +{ + //printf("gen_storecse() tym: %s reg: %d slot: %d\n", tym_str(tym), reg, cast(int)slot); + // MOV slot[BP],reg + if (tyvector(tym)) // TODO AArch64 + { + assert(0); + //const aligned = tyvector(tym) ? STACKALIGN >= 16 : true; + //const op = xmmstore(tym, aligned); + //cdb.genc1(op,modregxrm(2, reg - XMM0, BPRM),FL.cs,cast(targ_size_t)slot); + //return; + } + code cs; + cs.IFL1 = FL.cs; + cs.Iflags = CFoff; + cs.reg = NOREG; + cs.index = NOREG; + cs.base = 29; // SP? BPRM? TODO AArch64 + cs.Sextend = 0; + cs.IEV1.Vsym = null; + cs.IEV1.Voffset = slot; + storeToEA(cs, reg, tysize(tym)); + assert(cs.Iop); + cdb.gen(&cs); +} + +@trusted +void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot) +{ + printf("gen_testcse()\n"); + // CMP slot[BP],0 +static if (0) +{ + /* Since on the AArch64 this would have to allocate a register, + that should probably be done by the caller TODO AArch64 + */ + assert(0); + cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM), + FL.cs,cast(targ_uns)slot, FL.const_,cast(targ_uns) 0); + if ((I64 || I32) && sz == 2) + cdb.last().Iflags |= CFopsize; + if (I64 && sz == 8) + code_orrex(cdb.last(), REX_W); +} +} + +@trusted +void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot) +{ + //printf("gen_loadcse() tym: %s reg: %d slot: %d\n", tym_str(tym), reg, cast(int)slot); + // MOV reg,slot[BP] + if (tyvector(tym)) // TODO AArch64 + { + assert(0); + //const aligned = tyvector(tym) ? STACKALIGN >= 16 : true; + //const op = xmmload(tym, aligned); + //cdb.genc1(op,modregxrm(2, reg - XMM0, BPRM),FL.cs,cast(targ_size_t)slot); + //return; + } + code cs; + cs.IFL1 = FL.cs; + cs.Iflags = CFoff; + cs.reg = NOREG; + cs.index = NOREG; + cs.base = 29; // SP? BPRM? TODO AArch64 + cs.Sextend = 0; + cs.IEV1.Vsym = null; + cs.IEV1.Voffset = slot; + uint szr = tysize(tym); + uint szw = szr == 8 ? 8 : 4; + loadFromEA(cs, reg, szw, szr); + cdb.gen(&cs); +} + // cdframeptr // cdgot // load_localgot @@ -1143,6 +1225,7 @@ void assignaddrc(code* c) ulong offset; reg_t Rn, Rt; uint base = cgstate.EBPtoESP; + code* csave = c; for (; c; c = code_next(c)) { @@ -1230,7 +1313,7 @@ void assignaddrc(code* c) s = c.IEV1.Vsym; uint sz = 8; uint ins = c.Iop; -// if (c.IFL1 != FL.unde) + if (0 && c.IFL1 != FL.unde) { printf("FL: %s ", fl_str(c.IFL1)); disassemble(ins); @@ -1431,10 +1514,16 @@ printf("offset: %lld localsize: %lld REGSIZE*2: %d\n", offset, localsize, REGSIZ break; default: - printf("FL: %s\n", fl_str(c.IFL1)); + if (0) printf("FL: %s\n", fl_str(c.IFL1)); assert(0); } } + static if (0) + for (c = csave; c; c = code_next(c)) + { + printf("Iop %08x ", c.Iop); + disassemble(c.Iop); + } } /************************** diff --git a/compiler/src/dmd/backend/arm/cod4.d b/compiler/src/dmd/backend/arm/cod4.d index e884338087..4d0a7c6e71 100644 --- a/compiler/src/dmd/backend/arm/cod4.d +++ b/compiler/src/dmd/backend/arm/cod4.d @@ -55,8 +55,8 @@ nothrow: @trusted void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs) { - printf("cdeq(e = %p, pretregs = %s)\n",e,regm_str(pretregs)); - elem_print(e); + //printf("cdeq(e = %p, pretregs = %s)\n",e,regm_str(pretregs)); + //elem_print(e); reg_t reg; code cs; @@ -362,7 +362,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs) scodelem(cgstate,cdb,e.E2,retregs,0,true); // get rvalue getlvalue(cdb,cs,e1,retregs); // get lvalue reg_t reg1; - if (cs.reg) + if (cs.reg != NOREG) reg1 = cs.reg; else { diff --git a/compiler/src/dmd/backend/arm/instr.d b/compiler/src/dmd/backend/arm/instr.d index ab542391de..1469689a1b 100644 --- a/compiler/src/dmd/backend/arm/instr.d +++ b/compiler/src/dmd/backend/arm/instr.d @@ -1173,7 +1173,7 @@ struct INSTR // STRH Rt,[Xn,#offset] uint size = 1; uint imm12 = offset & 0xFFF; - return ldst_pos(0, 0, 0, imm12, Rn, Rt); + return ldst_pos(1, 0, 0, imm12, Rn, Rt); } /* STR (immediate) Unsigned offset diff --git a/compiler/src/dmd/backend/x86/cgcod.d b/compiler/src/dmd/backend/x86/cgcod.d index 20a02b9f43..c449de65df 100644 --- a/compiler/src/dmd/backend/x86/cgcod.d +++ b/compiler/src/dmd/backend/x86/cgcod.d @@ -2095,7 +2095,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs) uint byte_,sz; //printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs)); - elem_debug(e); + //elem_debug(e); debug { @@ -2203,7 +2203,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs) cse.flags |= CSEload; if (pretregs == mPSW) // if result in CCs only { - if (config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety))) + if (0 && config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety))) // TODO AArch64 { retregs = XMMREGS; reg = allocreg(cdb,retregs,tym); diff --git a/compiler/src/dmd/backend/x86/cod3.d b/compiler/src/dmd/backend/x86/cod3.d index 464ad3350b..678ab1c3a0 100644 --- a/compiler/src/dmd/backend/x86/cod3.d +++ b/compiler/src/dmd/backend/x86/cod3.d @@ -2686,6 +2686,10 @@ bool cse_simple(code* c, elem* e) @trusted void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot) { + if (cgstate.AArch64) + return dmd.backend.arm.cod3.gen_storecse(cdb,tym,reg,slot); + + //printf("gen_storecse()\n"); // MOV slot[BP],reg if (isXMMreg(reg) && config.fpxmmregs) // watch out for ES { @@ -2708,6 +2712,10 @@ void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot) @trusted void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot) { + if (cgstate.AArch64) + return dmd.backend.arm.cod3.gen_testcse(cdb,tym,sz,slot); + + //printf("gen_testcse()\n"); // CMP slot[BP],0 cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM), FL.cs,cast(targ_uns)slot, FL.const_,cast(targ_uns) 0); @@ -2720,6 +2728,10 @@ void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot) @trusted void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot) { + if (cgstate.AArch64) + return dmd.backend.arm.cod3.gen_loadcse(cdb,tym,reg,slot); + + //printf("gen_loadcse()\n"); // MOV reg,slot[BP] if (isXMMreg(reg) && config.fpxmmregs) { @@ -3973,7 +3985,7 @@ private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topo void prolog_genvarargs(ref CGstate cg, ref CodeBuilder cdb, Symbol* sv) { if (cg.AArch64) - return dmd.backend.arm.cod3.prolog_genvarargs(cg, cdb, sv); + return dmd.backend.arm.cod3.prolog_genvarargs(cg, cdb, sv); /* Generate code to move any arguments passed in registers into * the stack variable __va_argsave,