private static ref obj.Prog zerorange(ref gc.Progs pp, ref obj.Prog p, long off, long cnt, ref uint r0) { if (cnt == 0L) { return(p); } if (r0 == 0L.Value) { p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_CONST, 0L, 0L, obj.TYPE_REG, arm.REG_R0, 0L); r0.Value = 1L; } if (cnt < int64(4L * gc.Widthptr)) { { var i = int64(0L); while (i < cnt) { p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0L, obj.TYPE_MEM, arm.REGSP, 4L + off + i); i += int64(gc.Widthptr); } } } else if (!gc.Nacl && (cnt <= int64(128L * gc.Widthptr))) { p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0L, 4L + off, obj.TYPE_REG, arm.REG_R1, 0L); p.Reg = arm.REGSP; p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0L, 0L, obj.TYPE_MEM, 0L, 0L); p.To.Name = obj.NAME_EXTERN; p.To.Sym = gc.Duffzero; p.To.Offset = 4L * (128L - cnt / int64(gc.Widthptr)); } else { p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0L, 4L + off, obj.TYPE_REG, arm.REG_R1, 0L); p.Reg = arm.REGSP; p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0L, cnt, obj.TYPE_REG, arm.REG_R2, 0L); p.Reg = arm.REG_R1; p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0L, obj.TYPE_MEM, arm.REG_R1, 4L); var p1 = p; p.Scond |= arm.C_PBIT; p = pp.Appendpp(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0L, obj.TYPE_NONE, 0L, 0L); p.Reg = arm.REG_R2; p = pp.Appendpp(p, arm.ABNE, obj.TYPE_NONE, 0L, 0L, obj.TYPE_BRANCH, 0L, 0L); gc.Patch(p, p1); } return(p); }
private static ref obj.Prog zerorange(ref gc.Progs pp, ref obj.Prog p, long off, long cnt, ref uint state) { const long ax = 1L << (int)(iota); const var x0 = 0; if (cnt == 0L) { return(p); } if (cnt % int64(gc.Widthreg) != 0L) { // should only happen with nacl if (cnt % int64(gc.Widthptr) != 0L) { gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt); } if (state & ax == 0L.Value) { p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0L, 0L, obj.TYPE_REG, x86.REG_AX, 0L); state.Value |= ax; } p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0L, obj.TYPE_MEM, x86.REG_SP, off); off += int64(gc.Widthptr); cnt -= int64(gc.Widthptr); } if (cnt == 8L) { if (state & ax == 0L.Value) { p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0L, 0L, obj.TYPE_REG, x86.REG_AX, 0L); state.Value |= ax; } p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0L, obj.TYPE_MEM, x86.REG_SP, off); } else if (!isPlan9 && cnt <= int64(8L * gc.Widthreg)) { if (state & x0 == 0L.Value) { p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0L, obj.TYPE_REG, x86.REG_X0, 0L); state.Value |= x0; } for (var i = int64(0L); i < cnt / 16L; i++) { p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0L, obj.TYPE_MEM, x86.REG_SP, off + i * 16L); } if (cnt % 16L != 0L) { p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0L, obj.TYPE_MEM, x86.REG_SP, off + cnt - int64(16L)); } } else if (!gc.Nacl && !isPlan9 && (cnt <= int64(128L * gc.Widthreg))) { if (state & x0 == 0L.Value) { p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0L, obj.TYPE_REG, x86.REG_X0, 0L); state.Value |= x0; } p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off + dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0L); p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0L, 0L, obj.TYPE_ADDR, 0L, dzOff(cnt)); p.To.Sym = gc.Duffzero; if (cnt % 16L != 0L) { p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0L, obj.TYPE_MEM, x86.REG_DI, -int64(8L)); } } else { if (state & ax == 0L.Value) { p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0L, 0L, obj.TYPE_REG, x86.REG_AX, 0L); state.Value |= ax; } p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0L, cnt / int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0L); p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0L); p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0L, 0L, obj.TYPE_NONE, 0L, 0L); p = pp.Appendpp(p, x86.ASTOSQ, obj.TYPE_NONE, 0L, 0L, obj.TYPE_NONE, 0L, 0L); } return(p); }