...

Source file src/pkg/cmd/compile/internal/ppc64/ggen.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package ppc64
     6	
     7	import (
     8		"cmd/compile/internal/gc"
     9		"cmd/internal/obj"
    10		"cmd/internal/obj/ppc64"
    11	)
    12	
    13	func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
    14		if cnt == 0 {
    15			return p
    16		}
    17		if cnt < int64(4*gc.Widthptr) {
    18			for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
    19				p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
    20			}
    21		} else if cnt <= int64(128*gc.Widthptr) {
    22			p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
    23			p.Reg = ppc64.REGSP
    24			p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
    25			p.To.Name = obj.NAME_EXTERN
    26			p.To.Sym = gc.Duffzero
    27			p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
    28		} else {
    29			p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
    30			p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
    31			p.Reg = ppc64.REGSP
    32			p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
    33			p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
    34			p.Reg = ppc64.REGRT1
    35			p = pp.Appendpp(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(gc.Widthptr))
    36			p1 := p
    37			p = pp.Appendpp(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
    38			p = pp.Appendpp(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
    39			gc.Patch(p, p1)
    40		}
    41	
    42		return p
    43	}
    44	
    45	func zeroAuto(pp *gc.Progs, n *gc.Node) {
    46		// Note: this code must not clobber any registers.
    47		sym := n.Sym.Linksym()
    48		size := n.Type.Size()
    49		for i := int64(0); i < size; i += 8 {
    50			p := pp.Prog(ppc64.AMOVD)
    51			p.From.Type = obj.TYPE_REG
    52			p.From.Reg = ppc64.REGZERO
    53			p.To.Type = obj.TYPE_MEM
    54			p.To.Name = obj.NAME_AUTO
    55			p.To.Reg = ppc64.REGSP
    56			p.To.Offset = n.Xoffset + i
    57			p.To.Sym = sym
    58		}
    59	}
    60	
    61	func ginsnop(pp *gc.Progs) *obj.Prog {
    62		p := pp.Prog(ppc64.AOR)
    63		p.From.Type = obj.TYPE_REG
    64		p.From.Reg = ppc64.REG_R0
    65		p.To.Type = obj.TYPE_REG
    66		p.To.Reg = ppc64.REG_R0
    67		return p
    68	}
    69	
    70	func ginsnopdefer(pp *gc.Progs) *obj.Prog {
    71		// On PPC64 two nops are required in the defer case.
    72		//
    73		// (see gc/cgen.go, gc/plive.go -- copy of comment below)
    74		//
    75		// On ppc64, when compiling Go into position
    76		// independent code on ppc64le we insert an
    77		// instruction to reload the TOC pointer from the
    78		// stack as well. See the long comment near
    79		// jmpdefer in runtime/asm_ppc64.s for why.
    80		// If the MOVD is not needed, insert a hardware NOP
    81		// so that the same number of instructions are used
    82		// on ppc64 in both shared and non-shared modes.
    83	
    84		ginsnop(pp)
    85		if gc.Ctxt.Flag_shared {
    86			p := pp.Prog(ppc64.AMOVD)
    87			p.From.Type = obj.TYPE_MEM
    88			p.From.Offset = 24
    89			p.From.Reg = ppc64.REGSP
    90			p.To.Type = obj.TYPE_REG
    91			p.To.Reg = ppc64.REG_R2
    92			return p
    93		}
    94		return ginsnop(pp)
    95	}
    96	

View as plain text