]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/arm64/ggen.go
internal/buildcfg: move build configuration out of cmd/internal/objabi
[gostls13.git] / src / cmd / compile / internal / arm64 / 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 arm64
6
7 import (
8         "cmd/compile/internal/ir"
9         "cmd/compile/internal/objw"
10         "cmd/compile/internal/types"
11         "cmd/internal/obj"
12         "cmd/internal/obj/arm64"
13         "internal/buildcfg"
14 )
15
16 var darwin = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios"
17
18 func padframe(frame int64) int64 {
19         // arm64 requires that the frame size (not counting saved FP&LR)
20         // be 16 bytes aligned. If not, pad it.
21         if frame%16 != 0 {
22                 frame += 16 - (frame % 16)
23         }
24         return frame
25 }
26
27 func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
28         if cnt == 0 {
29                 return p
30         }
31         if cnt < int64(4*types.PtrSize) {
32                 for i := int64(0); i < cnt; i += int64(types.PtrSize) {
33                         p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
34                 }
35         } else if cnt <= int64(128*types.PtrSize) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
36                 if cnt%(2*int64(types.PtrSize)) != 0 {
37                         p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
38                         off += int64(types.PtrSize)
39                         cnt -= int64(types.PtrSize)
40                 }
41                 p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REG_R20, 0)
42                 p = pp.Append(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REG_R20, 0)
43                 p.Reg = arm64.REG_R20
44                 p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
45                 p.To.Name = obj.NAME_EXTERN
46                 p.To.Sym = ir.Syms.Duffzero
47                 p.To.Offset = 4 * (64 - cnt/(2*int64(types.PtrSize)))
48         } else {
49                 // Not using REGTMP, so this is async preemptible (async preemption clobbers REGTMP).
50                 // We are at the function entry, where no register is live, so it is okay to clobber
51                 // other registers
52                 const rtmp = arm64.REG_R20
53                 p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
54                 p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
55                 p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
56                 p.Reg = arm64.REGRT1
57                 p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
58                 p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
59                 p.Reg = arm64.REGRT1
60                 p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(types.PtrSize))
61                 p.Scond = arm64.C_XPRE
62                 p1 := p
63                 p = pp.Append(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
64                 p.Reg = arm64.REGRT2
65                 p = pp.Append(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
66                 p.To.SetTarget(p1)
67         }
68
69         return p
70 }
71
72 func ginsnop(pp *objw.Progs) *obj.Prog {
73         p := pp.Prog(arm64.AHINT)
74         p.From.Type = obj.TYPE_CONST
75         return p
76 }