1
2
3
4
5 package amd64
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/x86"
13 "internal/buildcfg"
14 )
15
16
17 var isPlan9 = buildcfg.GOOS == "plan9"
18
19
20
21 const (
22 dzBlocks = 16
23 dzBlockLen = 4
24 dzBlockSize = 23
25 dzMovSize = 5
26 dzLeaqSize = 4
27 dzClearStep = 16
28
29 dzClearLen = dzClearStep * dzBlockLen
30 dzSize = dzBlocks * dzBlockSize
31 )
32
33
34
35 func dzOff(b int64) int64 {
36 off := int64(dzSize)
37 off -= b / dzClearLen * dzBlockSize
38 tailLen := b % dzClearLen
39 if tailLen >= dzClearStep {
40 off -= dzLeaqSize + dzMovSize*(tailLen/dzClearStep)
41 }
42 return off
43 }
44
45
46
47 func dzDI(b int64) int64 {
48 tailLen := b % dzClearLen
49 if tailLen < dzClearStep {
50 return 0
51 }
52 tailSteps := tailLen / dzClearStep
53 return -dzClearStep * (dzBlockLen - tailSteps)
54 }
55
56 func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
57 const (
58 r13 = 1 << iota
59 )
60
61 if cnt == 0 {
62 return p
63 }
64
65 if cnt == 8 {
66 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_SP, off)
67 } else if !isPlan9 && cnt <= int64(8*types.RegSize) {
68 for i := int64(0); i < cnt/16; i++ {
69 p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
70 }
71
72 if cnt%16 != 0 {
73 p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
74 }
75 } else if !isPlan9 && (cnt <= int64(128*types.RegSize)) {
76
77
78 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_DI, 0, obj.TYPE_REG, x86.REG_R12, 0)
79
80 p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
81 p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
82 p.To.Sym = ir.Syms.Duffzero
83 if cnt%16 != 0 {
84 p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
85 }
86
87 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R12, 0, obj.TYPE_REG, x86.REG_DI, 0)
88
89 } else {
90
91
92
93
94
95
96
97
98
99 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_DI, 0, obj.TYPE_REG, x86.REG_R12, 0)
100 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_REG, x86.REG_R13, 0)
101 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_CX, 0, obj.TYPE_REG, x86.REG_R15, 0)
102
103
104 p = pp.Append(p, x86.AXORL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_REG, x86.REG_AX, 0)
105 p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
106 p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
107 p = pp.Append(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
108 p = pp.Append(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
109
110
111 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R12, 0, obj.TYPE_REG, x86.REG_DI, 0)
112 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R13, 0, obj.TYPE_REG, x86.REG_AX, 0)
113 p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R15, 0, obj.TYPE_REG, x86.REG_CX, 0)
114
115
116 *state &= ^uint32(r13)
117 }
118
119 return p
120 }
121
122 func ginsnop(pp *objw.Progs) *obj.Prog {
123
124
125
126
127
128
129 p := pp.Prog(x86.AXCHGL)
130 p.From.Type = obj.TYPE_REG
131 p.From.Reg = x86.REG_AX
132 p.To.Type = obj.TYPE_REG
133 p.To.Reg = x86.REG_AX
134 return p
135 }
136
View as plain text