Source file src/pkg/cmd/compile/internal/amd64/ggen.go
1
2
3
4
5 package amd64
6
7 import (
8 "cmd/compile/internal/gc"
9 "cmd/internal/obj"
10 "cmd/internal/obj/x86"
11 "cmd/internal/objabi"
12 )
13
14
15 var isPlan9 = objabi.GOOS == "plan9"
16
17
18
19 const (
20 dzBlocks = 16
21 dzBlockLen = 4
22 dzBlockSize = 19
23 dzMovSize = 4
24 dzLeaqSize = 4
25 dzClearStep = 16
26
27 dzClearLen = dzClearStep * dzBlockLen
28 dzSize = dzBlocks * dzBlockSize
29 )
30
31
32
33 func dzOff(b int64) int64 {
34 off := int64(dzSize)
35 off -= b / dzClearLen * dzBlockSize
36 tailLen := b % dzClearLen
37 if tailLen >= dzClearStep {
38 off -= dzLeaqSize + dzMovSize*(tailLen/dzClearStep)
39 }
40 return off
41 }
42
43
44
45 func dzDI(b int64) int64 {
46 tailLen := b % dzClearLen
47 if tailLen < dzClearStep {
48 return 0
49 }
50 tailSteps := tailLen / dzClearStep
51 return -dzClearStep * (dzBlockLen - tailSteps)
52 }
53
54 func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
55 const (
56 ax = 1 << iota
57 x0
58 )
59
60 if cnt == 0 {
61 return p
62 }
63
64 if cnt%int64(gc.Widthreg) != 0 {
65
66 if cnt%int64(gc.Widthptr) != 0 {
67 gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
68 }
69 if *state&ax == 0 {
70 p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
71 *state |= ax
72 }
73 p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
74 off += int64(gc.Widthptr)
75 cnt -= int64(gc.Widthptr)
76 }
77
78 if cnt == 8 {
79 if *state&ax == 0 {
80 p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
81 *state |= ax
82 }
83 p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
84 } else if !isPlan9 && cnt <= int64(8*gc.Widthreg) {
85 if *state&x0 == 0 {
86 p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
87 *state |= x0
88 }
89
90 for i := int64(0); i < cnt/16; i++ {
91 p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
92 }
93
94 if cnt%16 != 0 {
95 p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
96 }
97 } else if !gc.Nacl && !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
98 if *state&x0 == 0 {
99 p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
100 *state |= x0
101 }
102 p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
103 p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
104 p.To.Sym = gc.Duffzero
105
106 if cnt%16 != 0 {
107 p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
108 }
109 } else {
110 if *state&ax == 0 {
111 p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
112 *state |= ax
113 }
114
115 p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
116 p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
117 p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
118 p = pp.Appendpp(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
119 }
120
121 return p
122 }
123
124 func zeroAuto(pp *gc.Progs, n *gc.Node) {
125
126 op := x86.AMOVQ
127 if gc.Widthptr == 4 {
128 op = x86.AMOVL
129 }
130 sym := n.Sym.Linksym()
131 size := n.Type.Size()
132 for i := int64(0); i < size; i += int64(gc.Widthptr) {
133 p := pp.Prog(op)
134 p.From.Type = obj.TYPE_CONST
135 p.From.Offset = 0
136 p.To.Type = obj.TYPE_MEM
137 p.To.Name = obj.NAME_AUTO
138 p.To.Reg = x86.REG_SP
139 p.To.Offset = n.Xoffset + i
140 p.To.Sym = sym
141 }
142 }
143
144 func ginsnop(pp *gc.Progs) *obj.Prog {
145
146
147
148
149
150
151 p := pp.Prog(x86.AXCHGL)
152 p.From.Type = obj.TYPE_REG
153 p.From.Reg = x86.REG_AX
154 p.To.Type = obj.TYPE_REG
155 p.To.Reg = x86.REG_AX
156 return p
157 }
158
View as plain text