private static void zeroAuto(ref gc.Progs pp, ref gc.Node n) { // Note: this code must not clobber any registers. var sym = n.Sym.Linksym(); var size = n.Type.Size(); var p = pp.Prog(arm.AMOVW); p.From.Type = obj.TYPE_CONST; p.From.Offset = 0L; p.To.Type = obj.TYPE_REG; p.To.Reg = arm.REGTMP; { var i = int64(0L); while (i < size) { p = pp.Prog(arm.AMOVW); p.From.Type = obj.TYPE_REG; p.From.Reg = arm.REGTMP; p.To.Type = obj.TYPE_MEM; p.To.Name = obj.NAME_AUTO; p.To.Reg = arm.REGSP; p.To.Offset = n.Xoffset + i; p.To.Sym = sym; i += 4L; } } }
private static void zeroAuto(ref gc.Progs pp, ref gc.Node n) { // Note: this code must not clobber any registers. var op = x86.AMOVQ; if (gc.Widthptr == 4L) { op = x86.AMOVL; } var sym = n.Sym.Linksym(); var size = n.Type.Size(); { var i = int64(0L); while (i < size) { var p = pp.Prog(op); p.From.Type = obj.TYPE_CONST; p.From.Offset = 0L; p.To.Type = obj.TYPE_MEM; p.To.Name = obj.NAME_AUTO; p.To.Reg = x86.REG_SP; p.To.Offset = n.Xoffset + i; p.To.Sym = sym; i += int64(gc.Widthptr); } } }
private static void ginsnop(ref gc.Progs pp) { var p = pp.Prog(arm.AAND); p.From.Type = obj.TYPE_REG; p.From.Reg = arm.REG_R0; p.To.Type = obj.TYPE_REG; p.To.Reg = arm.REG_R0; p.Scond = arm.C_SCOND_EQ; }
private static ref obj.Prog zerorange(ref gc.Progs pp, ref obj.Prog p, long off, long cnt, ref uint _) { if (cnt == 0L) { return(p); } if (cnt < int64(4L * gc.Widthptr)) { { var i = int64(0L); while (i < cnt) { p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0L, obj.TYPE_MEM, arm64.REGSP, 8L + off + i); i += int64(gc.Widthptr); } } } else if (cnt <= int64(128L * gc.Widthptr) && !darwin) { // darwin ld64 cannot handle BR26 reloc with non-zero addend if (cnt % (2L * int64(gc.Widthptr)) != 0L) { p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0L, obj.TYPE_MEM, arm64.REGSP, 8L + off); off += int64(gc.Widthptr); cnt -= int64(gc.Widthptr); } p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0L, obj.TYPE_REG, arm64.REGRT1, 0L); p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0L, 8L + off, obj.TYPE_REG, arm64.REGRT1, 0L); p.Reg = arm64.REGRT1; 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 * (64L - cnt / (2L * int64(gc.Widthptr))); } else { p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0L, 8L + off - 8L, obj.TYPE_REG, arm64.REGTMP, 0L); p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0L, obj.TYPE_REG, arm64.REGRT1, 0L); p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0L, obj.TYPE_REG, arm64.REGRT1, 0L); p.Reg = arm64.REGRT1; p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0L, cnt, obj.TYPE_REG, arm64.REGTMP, 0L); p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0L, obj.TYPE_REG, arm64.REGRT2, 0L); p.Reg = arm64.REGRT1; p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0L, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr)); p.Scond = arm64.C_XPRE; var p1 = p; p = pp.Appendpp(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0L, obj.TYPE_NONE, 0L, 0L); p.Reg = arm64.REGRT2; p = pp.Appendpp(p, arm64.ABNE, obj.TYPE_NONE, 0L, 0L, obj.TYPE_BRANCH, 0L, 0L); gc.Patch(p, p1); } return(p); }
private static void ginsnop(ref gc.Progs pp) { // This is actually not the x86 NOP anymore, // but at the point where it gets used, AX is dead // so it's okay if we lose the high bits. var p = pp.Prog(x86.AXCHGL); p.From.Type = obj.TYPE_REG; p.From.Reg = x86.REG_AX; p.To.Type = obj.TYPE_REG; p.To.Reg = x86.REG_AX; }
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 void ginsnop(ref gc.Progs pp) { var p = pp.Prog(arm64.AHINT); p.From.Type = obj.TYPE_CONST; }
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); }