Пример #1
0
                    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;
                            }
                        }
                    }
Пример #2
0
                    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);
                            }
                        }
                    }
Пример #3
0
                    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;
                    }
Пример #4
0
                    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);
                    }
Пример #5
0
                    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;
                    }
Пример #6
0
                    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);
                    }
Пример #7
0
                    private static void ginsnop(ref gc.Progs pp)
                    {
                        var p = pp.Prog(arm64.AHINT);

                        p.From.Type = obj.TYPE_CONST;
                    }
Пример #8
0
                    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);
                    }