1
2
3
4
5 package x86
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/objabi"
10 "testing"
11 )
12
13 type oclassTest struct {
14 arg *obj.Addr
15 want int
16 }
17
18
19 var (
20 oclassTestsAMD64 []*oclassTest
21 oclassTests386 []*oclassTest
22 )
23
24 func init() {
25
26
27 var ctxt obj.Link
28 instinit(&ctxt)
29
30 regAddr := func(reg int16) *obj.Addr {
31 return &obj.Addr{Type: obj.TYPE_REG, Reg: reg}
32 }
33 immAddr := func(v int64) *obj.Addr {
34 return &obj.Addr{Type: obj.TYPE_CONST, Offset: v}
35 }
36 regListAddr := func(regFrom, regTo int16) *obj.Addr {
37 return &obj.Addr{Type: obj.TYPE_REGLIST, Offset: EncodeRegisterRange(regFrom, regTo)}
38 }
39 memAddr := func(base, index int16) *obj.Addr {
40 return &obj.Addr{Type: obj.TYPE_MEM, Reg: base, Index: index}
41 }
42
43
44
45
46
47
48 oclassTestsCommon := []*oclassTest{
49 {&obj.Addr{Type: obj.TYPE_NONE}, Ynone},
50 {&obj.Addr{Type: obj.TYPE_BRANCH}, Ybr},
51 {&obj.Addr{Type: obj.TYPE_TEXTSIZE}, Ytextsize},
52
53 {&obj.Addr{Type: obj.TYPE_INDIR, Name: obj.NAME_EXTERN}, Yindir},
54 {&obj.Addr{Type: obj.TYPE_INDIR, Name: obj.NAME_GOTREF}, Yindir},
55
56 {&obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_AUTO}, Yiauto},
57 {&obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_PARAM}, Yiauto},
58 {&obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_EXTERN}, Yiauto},
59 {&obj.Addr{Type: obj.TYPE_ADDR, Sym: &obj.LSym{Name: "runtime.duff"}}, Yi32},
60 {&obj.Addr{Type: obj.TYPE_ADDR, Offset: 4}, Yu7},
61 {&obj.Addr{Type: obj.TYPE_ADDR, Offset: 255}, Yu8},
62
63 {immAddr(0), Yi0},
64 {immAddr(1), Yi1},
65 {immAddr(2), Yu2},
66 {immAddr(3), Yu2},
67 {immAddr(4), Yu7},
68 {immAddr(86), Yu7},
69 {immAddr(127), Yu7},
70 {immAddr(128), Yu8},
71 {immAddr(200), Yu8},
72 {immAddr(255), Yu8},
73 {immAddr(-1), Yi8},
74 {immAddr(-100), Yi8},
75 {immAddr(-128), Yi8},
76
77 {regAddr(REG_AL), Yal},
78 {regAddr(REG_AX), Yax},
79 {regAddr(REG_DL), Yrb},
80 {regAddr(REG_DH), Yrb},
81 {regAddr(REG_BH), Yrb},
82 {regAddr(REG_CL), Ycl},
83 {regAddr(REG_CX), Ycx},
84 {regAddr(REG_DX), Yrx},
85 {regAddr(REG_BX), Yrx},
86 {regAddr(REG_F0), Yf0},
87 {regAddr(REG_F3), Yrf},
88 {regAddr(REG_F7), Yrf},
89 {regAddr(REG_M0), Ymr},
90 {regAddr(REG_M3), Ymr},
91 {regAddr(REG_M7), Ymr},
92 {regAddr(REG_X0), Yxr0},
93 {regAddr(REG_X6), Yxr},
94 {regAddr(REG_X13), Yxr},
95 {regAddr(REG_X20), YxrEvex},
96 {regAddr(REG_X31), YxrEvex},
97 {regAddr(REG_Y0), Yyr},
98 {regAddr(REG_Y6), Yyr},
99 {regAddr(REG_Y13), Yyr},
100 {regAddr(REG_Y20), YyrEvex},
101 {regAddr(REG_Y31), YyrEvex},
102 {regAddr(REG_Z0), Yzr},
103 {regAddr(REG_Z6), Yzr},
104 {regAddr(REG_K0), Yk0},
105 {regAddr(REG_K5), Yknot0},
106 {regAddr(REG_K7), Yknot0},
107 {regAddr(REG_CS), Ycs},
108 {regAddr(REG_SS), Yss},
109 {regAddr(REG_DS), Yds},
110 {regAddr(REG_ES), Yes},
111 {regAddr(REG_FS), Yfs},
112 {regAddr(REG_GS), Ygs},
113 {regAddr(REG_TLS), Ytls},
114 {regAddr(REG_GDTR), Ygdtr},
115 {regAddr(REG_IDTR), Yidtr},
116 {regAddr(REG_LDTR), Yldtr},
117 {regAddr(REG_MSW), Ymsw},
118 {regAddr(REG_TASK), Ytask},
119 {regAddr(REG_CR0), Ycr0},
120 {regAddr(REG_CR5), Ycr5},
121 {regAddr(REG_CR8), Ycr8},
122 {regAddr(REG_DR0), Ydr0},
123 {regAddr(REG_DR5), Ydr5},
124 {regAddr(REG_DR7), Ydr7},
125 {regAddr(REG_TR0), Ytr0},
126 {regAddr(REG_TR5), Ytr5},
127 {regAddr(REG_TR7), Ytr7},
128
129 {regListAddr(REG_X0, REG_X3), YxrEvexMulti4},
130 {regListAddr(REG_X4, REG_X7), YxrEvexMulti4},
131 {regListAddr(REG_Y0, REG_Y3), YyrEvexMulti4},
132 {regListAddr(REG_Y4, REG_Y7), YyrEvexMulti4},
133 {regListAddr(REG_Z0, REG_Z3), YzrMulti4},
134 {regListAddr(REG_Z4, REG_Z7), YzrMulti4},
135
136 {memAddr(REG_AL, REG_NONE), Ym},
137 {memAddr(REG_AL, REG_SI), Ym},
138 {memAddr(REG_SI, REG_CX), Ym},
139 {memAddr(REG_DI, REG_X0), Yxvm},
140 {memAddr(REG_DI, REG_X7), Yxvm},
141 {memAddr(REG_DI, REG_Y0), Yyvm},
142 {memAddr(REG_DI, REG_Y7), Yyvm},
143 {memAddr(REG_DI, REG_Z0), Yzvm},
144 {memAddr(REG_DI, REG_Z7), Yzvm},
145 }
146
147 oclassTestsAMD64 = []*oclassTest{
148 {immAddr(-200), Ys32},
149 {immAddr(500), Ys32},
150 {immAddr(0x7FFFFFFF), Ys32},
151 {immAddr(0x7FFFFFFF + 1), Yi32},
152 {immAddr(0xFFFFFFFF), Yi32},
153 {immAddr(0xFFFFFFFF + 1), Yi64},
154
155 {regAddr(REG_BPB), Yrb},
156 {regAddr(REG_SIB), Yrb},
157 {regAddr(REG_DIB), Yrb},
158 {regAddr(REG_R8B), Yrb},
159 {regAddr(REG_R12B), Yrb},
160 {regAddr(REG_R8), Yrl},
161 {regAddr(REG_R13), Yrl},
162 {regAddr(REG_R15), Yrl},
163 {regAddr(REG_SP), Yrl},
164 {regAddr(REG_SI), Yrl},
165 {regAddr(REG_DI), Yrl},
166 {regAddr(REG_Z13), Yzr},
167 {regAddr(REG_Z20), Yzr},
168 {regAddr(REG_Z31), Yzr},
169
170 {regListAddr(REG_X10, REG_X13), YxrEvexMulti4},
171 {regListAddr(REG_X24, REG_X27), YxrEvexMulti4},
172 {regListAddr(REG_Y10, REG_Y13), YyrEvexMulti4},
173 {regListAddr(REG_Y24, REG_Y27), YyrEvexMulti4},
174 {regListAddr(REG_Z10, REG_Z13), YzrMulti4},
175 {regListAddr(REG_Z24, REG_Z27), YzrMulti4},
176
177 {memAddr(REG_DI, REG_X20), YxvmEvex},
178 {memAddr(REG_DI, REG_X27), YxvmEvex},
179 {memAddr(REG_DI, REG_Y20), YyvmEvex},
180 {memAddr(REG_DI, REG_Y27), YyvmEvex},
181 {memAddr(REG_DI, REG_Z20), Yzvm},
182 {memAddr(REG_DI, REG_Z27), Yzvm},
183 }
184
185 oclassTests386 = []*oclassTest{
186 {&obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_EXTERN, Sym: &obj.LSym{}}, Yi32},
187
188 {immAddr(-200), Yi32},
189
190 {regAddr(REG_SP), Yrl32},
191 {regAddr(REG_SI), Yrl32},
192 {regAddr(REG_DI), Yrl32},
193 }
194
195
196 oclassTestsAMD64 = append(oclassTestsAMD64, oclassTestsCommon...)
197 oclassTests386 = append(oclassTests386, oclassTestsCommon...)
198 }
199
200 func TestOclass(t *testing.T) {
201 runTest := func(t *testing.T, ctxt *obj.Link, tests []*oclassTest) {
202 var p obj.Prog
203 for _, test := range tests {
204 have := oclass(ctxt, &p, test.arg)
205 if have != test.want {
206 t.Errorf("oclass(%q):\nhave: %d\nwant: %d",
207 obj.Dconv(&p, test.arg), have, test.want)
208 }
209 }
210 }
211
212
213
214 t.Run("linux/AMD64", func(t *testing.T) {
215 ctxtAMD64 := obj.Linknew(&Linkamd64)
216 ctxtAMD64.Headtype = objabi.Hlinux
217 runTest(t, ctxtAMD64, oclassTestsAMD64)
218 })
219
220 t.Run("linux/386", func(t *testing.T) {
221 ctxt386 := obj.Linknew(&Link386)
222 ctxt386.Headtype = objabi.Hlinux
223 runTest(t, ctxt386, oclassTests386)
224 })
225 }
226
227 func TestRegisterListEncDec(t *testing.T) {
228 tests := []struct {
229 printed string
230 reg0 int16
231 reg1 int16
232 }{
233 {"[R10-R13]", REG_R10, REG_R13},
234 {"[X0-AX]", REG_X0, REG_AX},
235
236 {"[X0-X3]", REG_X0, REG_X3},
237 {"[X21-X24]", REG_X21, REG_X24},
238
239 {"[Y0-Y3]", REG_Y0, REG_Y3},
240 {"[Y21-Y24]", REG_Y21, REG_Y24},
241
242 {"[Z0-Z3]", REG_Z0, REG_Z3},
243 {"[Z21-Z24]", REG_Z21, REG_Z24},
244 }
245
246 for _, test := range tests {
247 enc := EncodeRegisterRange(test.reg0, test.reg1)
248 reg0, reg1 := decodeRegisterRange(enc)
249
250 if int16(reg0) != test.reg0 {
251 t.Errorf("%s reg0 mismatch: have %d, want %d",
252 test.printed, reg0, test.reg0)
253 }
254 if int16(reg1) != test.reg1 {
255 t.Errorf("%s reg1 mismatch: have %d, want %d",
256 test.printed, reg1, test.reg1)
257 }
258 wantPrinted := test.printed
259 if rlconv(enc) != wantPrinted {
260 t.Errorf("%s string mismatch: have %s, want %s",
261 test.printed, rlconv(enc), wantPrinted)
262 }
263 }
264 }
265
266 func TestRegIndex(t *testing.T) {
267 tests := []struct {
268 regFrom int
269 regTo int
270 }{
271 {REG_AL, REG_R15B},
272 {REG_AX, REG_R15},
273 {REG_M0, REG_M7},
274 {REG_K0, REG_K7},
275 {REG_X0, REG_X31},
276 {REG_Y0, REG_Y31},
277 {REG_Z0, REG_Z31},
278 }
279
280 for _, test := range tests {
281 for index, reg := 0, test.regFrom; reg <= test.regTo; index, reg = index+1, reg+1 {
282 have := regIndex(int16(reg))
283 want := index
284 if have != want {
285 regName := rconv(int(reg))
286 t.Errorf("regIndex(%s):\nhave: %d\nwant: %d",
287 regName, have, want)
288 }
289 }
290 }
291 }
292
View as plain text