]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/asm/internal/asm/operand_test.go
[dev.ssa] Merge remote-tracking branch 'origin/master' into mergebranch
[gostls13.git] / src / cmd / asm / internal / asm / operand_test.go
1 // Copyright 2015 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 asm
6
7 import (
8         "os"
9         "testing"
10
11         "cmd/asm/internal/arch"
12         "cmd/asm/internal/lex"
13         "cmd/internal/obj"
14 )
15
16 // A simple in-out test: Do we print what we parse?
17
18 func setArch(goarch string) (*arch.Arch, *obj.Link) {
19         os.Setenv("GOOS", "linux") // obj can handle this OS for all architectures.
20         architecture := arch.Set(goarch)
21         if architecture == nil {
22                 panic("asm: unrecognized architecture " + goarch)
23         }
24         return architecture, obj.Linknew(architecture.LinkArch)
25 }
26
27 func newParser(goarch string) *Parser {
28         architecture, ctxt := setArch(goarch)
29         return NewParser(ctxt, architecture, nil)
30 }
31
32 func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
33         for _, test := range tests {
34                 parser.start(lex.Tokenize(test.input))
35                 addr := obj.Addr{}
36                 parser.operand(&addr)
37                 result := obj.Dconv(&emptyProg, &addr)
38                 if result != test.output {
39                         t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)
40                 }
41         }
42 }
43
44 func TestAMD64OperandParser(t *testing.T) {
45         parser := newParser("amd64")
46         testOperandParser(t, parser, amd64OperandTests)
47 }
48
49 func Test386OperandParser(t *testing.T) {
50         parser := newParser("386")
51         testOperandParser(t, parser, x86OperandTests)
52 }
53
54 func TestARMOperandParser(t *testing.T) {
55         parser := newParser("arm")
56         testOperandParser(t, parser, armOperandTests)
57 }
58 func TestARM64OperandParser(t *testing.T) {
59         parser := newParser("arm64")
60         testOperandParser(t, parser, arm64OperandTests)
61 }
62
63 func TestPPC64OperandParser(t *testing.T) {
64         parser := newParser("ppc64")
65         testOperandParser(t, parser, ppc64OperandTests)
66 }
67
68 func TestMIPS64OperandParser(t *testing.T) {
69         parser := newParser("mips64")
70         testOperandParser(t, parser, mips64OperandTests)
71 }
72
73 type operandTest struct {
74         input, output string
75 }
76
77 // Examples collected by scanning all the assembly in the standard repo.
78
79 var amd64OperandTests = []operandTest{
80         {"$(-1.0)", "$(-1.0)"},
81         {"$(0.0)", "$(0.0)"},
82         {"$(0x2000000+116)", "$33554548"},
83         {"$(0x3F<<7)", "$8064"},
84         {"$(112+8)", "$120"},
85         {"$(1<<63)", "$-9223372036854775808"},
86         {"$-1", "$-1"},
87         {"$0", "$0"},
88         {"$0-0", "$0"},
89         {"$0-16", "$-16"},
90         {"$0x000FFFFFFFFFFFFF", "$4503599627370495"},
91         {"$0x01", "$1"},
92         {"$0x02", "$2"},
93         {"$0x04", "$4"},
94         {"$0x3FE", "$1022"},
95         {"$0x7fffffe00000", "$140737486258176"},
96         {"$0xfffffffffffff001", "$-4095"},
97         {"$1", "$1"},
98         {"$1.0", "$(1.0)"},
99         {"$10", "$10"},
100         {"$1000", "$1000"},
101         {"$1000000", "$1000000"},
102         {"$1000000000", "$1000000000"},
103         {"$__tsan_func_enter(SB)", "$__tsan_func_enter(SB)"},
104         {"$main(SB)", "$main(SB)"},
105         {"$masks<>(SB)", "$masks<>(SB)"},
106         {"$setg_gcc<>(SB)", "$setg_gcc<>(SB)"},
107         {"$shifts<>(SB)", "$shifts<>(SB)"},
108         {"$~(1<<63)", "$9223372036854775807"},
109         {"$~0x3F", "$-64"},
110         {"$~15", "$-16"},
111         {"(((8)&0xf)*4)(SP)", "32(SP)"},
112         {"(((8-14)&0xf)*4)(SP)", "40(SP)"},
113         {"(6+8)(AX)", "14(AX)"},
114         {"(8*4)(BP)", "32(BP)"},
115         {"(AX)", "(AX)"},
116         {"(AX)(CX*8)", "(AX)(CX*8)"},
117         {"(BP)(CX*4)", "(BP)(CX*4)"},
118         {"(BP)(DX*4)", "(BP)(DX*4)"},
119         {"(BP)(R8*4)", "(BP)(R8*4)"},
120         {"(BX)", "(BX)"},
121         {"(DI)", "(DI)"},
122         {"(DI)(BX*1)", "(DI)(BX*1)"},
123         {"(DX)", "(DX)"},
124         {"(R9)", "(R9)"},
125         {"(R9)(BX*8)", "(R9)(BX*8)"},
126         {"(SI)", "(SI)"},
127         {"(SI)(BX*1)", "(SI)(BX*1)"},
128         {"(SI)(DX*1)", "(SI)(DX*1)"},
129         {"(SP)", "(SP)"},
130         {"(SP)(AX*4)", "(SP)(AX*4)"},
131         {"32(SP)(BX*2)", "32(SP)(BX*2)"},
132         {"32323(SP)(R8*4)", "32323(SP)(R8*4)"},
133         {"+3(PC)", "3(PC)"},
134         {"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
135         {"-3(PC)", "-3(PC)"},
136         {"-64(SI)(BX*1)", "-64(SI)(BX*1)"},
137         {"-96(SI)(BX*1)", "-96(SI)(BX*1)"},
138         {"AL", "AL"},
139         {"AX", "AX"},
140         {"BP", "BP"},
141         {"BX", "BX"},
142         {"CX", "CX"},
143         {"DI", "DI"},
144         {"DX", "DX"},
145         {"R10", "R10"},
146         {"R10", "R10"},
147         {"R11", "R11"},
148         {"R12", "R12"},
149         {"R13", "R13"},
150         {"R14", "R14"},
151         {"R15", "R15"},
152         {"R8", "R8"},
153         {"R9", "R9"},
154         {"SI", "SI"},
155         {"SP", "SP"},
156         {"X0", "X0"},
157         {"X1", "X1"},
158         {"X10", "X10"},
159         {"X11", "X11"},
160         {"X12", "X12"},
161         {"X13", "X13"},
162         {"X14", "X14"},
163         {"X15", "X15"},
164         {"X2", "X2"},
165         {"X3", "X3"},
166         {"X4", "X4"},
167         {"X5", "X5"},
168         {"X6", "X6"},
169         {"X7", "X7"},
170         {"X8", "X8"},
171         {"X9", "X9"},
172         {"_expand_key_128<>(SB)", "_expand_key_128<>(SB)"},
173         {"_seek<>(SB)", "_seek<>(SB)"},
174         {"a2+16(FP)", "a2+16(FP)"},
175         {"addr2+24(FP)", "addr2+24(FP)"},
176         {"asmcgocall<>(SB)", "asmcgocall<>(SB)"},
177         {"b+24(FP)", "b+24(FP)"},
178         {"b_len+32(FP)", "b_len+32(FP)"},
179         {"racecall<>(SB)", "racecall<>(SB)"},
180         {"rcv_name+20(FP)", "rcv_name+20(FP)"},
181         {"retoffset+28(FP)", "retoffset+28(FP)"},
182         {"runtime·_GetStdHandle(SB)", "runtime._GetStdHandle(SB)"},
183         {"sync\u2215atomic·AddInt64(SB)", "sync/atomic.AddInt64(SB)"},
184         {"timeout+20(FP)", "timeout+20(FP)"},
185         {"ts+16(FP)", "ts+16(FP)"},
186         {"x+24(FP)", "x+24(FP)"},
187         {"x·y(SB)", "x.y(SB)"},
188         {"x·y(SP)", "x.y(SP)"},
189         {"x·y+8(SB)", "x.y+8(SB)"},
190         {"x·y+8(SP)", "x.y+8(SP)"},
191         {"y+56(FP)", "y+56(FP)"},
192         {"·AddUint32(SB)", "\"\".AddUint32(SB)"},
193         {"·callReflect(SB)", "\"\".callReflect(SB)"},
194         {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
195 }
196
197 var x86OperandTests = []operandTest{
198         {"$(2.928932188134524e-01)", "$(0.29289321881345243)"},
199         {"$-1", "$-1"},
200         {"$0", "$0"},
201         {"$0x00000000", "$0"},
202         {"$runtime·badmcall(SB)", "$runtime.badmcall(SB)"},
203         {"$setg_gcc<>(SB)", "$setg_gcc<>(SB)"},
204         {"$~15", "$-16"},
205         {"(-64*1024+104)(SP)", "-65432(SP)"},
206         {"(0*4)(BP)", "(BP)"},
207         {"(1*4)(DI)", "4(DI)"},
208         {"(4*4)(BP)", "16(BP)"},
209         {"(AX)", "(AX)"},
210         {"(BP)(CX*4)", "(BP)(CX*4)"},
211         {"(BP*8)", "0(BP*8)"},
212         {"(BX)", "(BX)"},
213         {"(SP)", "(SP)"},
214         {"*AX", "AX"}, // TODO: Should make * illegal here; a simple alias for JMP AX.
215         {"*runtime·_GetStdHandle(SB)", "*runtime._GetStdHandle(SB)"},
216         {"-(4+12)(DI)", "-16(DI)"},
217         {"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
218         {"-96(DI)(BX*1)", "-96(DI)(BX*1)"},
219         {"0(AX)", "(AX)"},
220         {"0(BP)", "(BP)"},
221         {"0(BX)", "(BX)"},
222         {"4(AX)", "4(AX)"},
223         {"AL", "AL"},
224         {"AX", "AX"},
225         {"BP", "BP"},
226         {"BX", "BX"},
227         {"CX", "CX"},
228         {"DI", "DI"},
229         {"DX", "DX"},
230         {"F0", "F0"},
231         {"GS", "GS"},
232         {"SI", "SI"},
233         {"SP", "SP"},
234         {"X0", "X0"},
235         {"X1", "X1"},
236         {"X2", "X2"},
237         {"X3", "X3"},
238         {"X4", "X4"},
239         {"X5", "X5"},
240         {"X6", "X6"},
241         {"X7", "X7"},
242         {"asmcgocall<>(SB)", "asmcgocall<>(SB)"},
243         {"ax+4(FP)", "ax+4(FP)"},
244         {"ptime-12(SP)", "ptime-12(SP)"},
245         {"runtime·_NtWaitForSingleObject(SB)", "runtime._NtWaitForSingleObject(SB)"},
246         {"s(FP)", "s(FP)"},
247         {"sec+4(FP)", "sec+4(FP)"},
248         {"shifts<>(SB)(CX*8)", "shifts<>(SB)(CX*8)"},
249         {"x+4(FP)", "x+4(FP)"},
250         {"·AddUint32(SB)", "\"\".AddUint32(SB)"},
251         {"·reflectcall(SB)", "\"\".reflectcall(SB)"},
252         {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
253 }
254
255 var armOperandTests = []operandTest{
256         {"$0", "$0"},
257         {"$256", "$256"},
258         {"(R0)", "(R0)"},
259         {"(R11)", "(R11)"},
260         {"(g)", "(g)"},
261         {"-12(R4)", "-12(R4)"},
262         {"0(PC)", "0(PC)"},
263         {"1024", "1024"},
264         {"12(R(1))", "12(R1)"},
265         {"12(R13)", "12(R13)"},
266         {"R0", "R0"},
267         {"R0->(32-1)", "R0->31"},
268         {"R0<<R1", "R0<<R1"},
269         {"R0>>R(1)", "R0>>R1"},
270         {"R0@>(32-1)", "R0@>31"},
271         {"R1", "R1"},
272         {"R11", "R11"},
273         {"R12", "R12"},
274         {"R13", "R13"},
275         {"R14", "R14"},
276         {"R15", "R15"},
277         {"R1<<2(R3)", "R1<<2(R3)"},
278         {"R(1)<<2(R(3))", "R1<<2(R3)"},
279         {"R2", "R2"},
280         {"R3", "R3"},
281         {"R4", "R4"},
282         {"R(4)", "R4"},
283         {"R5", "R5"},
284         {"R6", "R6"},
285         {"R7", "R7"},
286         {"R8", "R8"},
287         {"[R0,R1,g,R15]", "[R0,R1,g,R15]"},
288         {"[R0-R7]", "[R0,R1,R2,R3,R4,R5,R6,R7]"},
289         {"[R(0)-R(7)]", "[R0,R1,R2,R3,R4,R5,R6,R7]"},
290         {"[R0]", "[R0]"},
291         {"[R1-R12]", "[R1,R2,R3,R4,R5,R6,R7,R8,R9,g,R11,R12]"},
292         {"armCAS64(SB)", "armCAS64(SB)"},
293         {"asmcgocall<>(SB)", "asmcgocall<>(SB)"},
294         {"c+28(FP)", "c+28(FP)"},
295         {"g", "g"},
296         {"gosave<>(SB)", "gosave<>(SB)"},
297         {"retlo+12(FP)", "retlo+12(FP)"},
298         {"runtime·_sfloat2(SB)", "runtime._sfloat2(SB)"},
299         {"·AddUint32(SB)", "\"\".AddUint32(SB)"},
300         {"(R1, R3)", "(R1, R3)"},
301         {"[R0,R1,g,R15", ""}, // Issue 11764 - asm hung parsing ']' missing register lists.
302         {"[):[o-FP", ""},     // Issue 12469 - there was no infinite loop for ARM; these are just sanity checks.
303         {"[):[R0-FP", ""},
304         {"(", ""}, // Issue 12466 - backed up before beginning of line.
305 }
306
307 var ppc64OperandTests = []operandTest{
308         {"$((1<<63)-1)", "$9223372036854775807"},
309         {"$(-64*1024)", "$-65536"},
310         {"$(1024 * 8)", "$8192"},
311         {"$-1", "$-1"},
312         {"$-24(R4)", "$-24(R4)"},
313         {"$0", "$0"},
314         {"$0(R1)", "$(R1)"},
315         {"$0.5", "$(0.5)"},
316         {"$0x7000", "$28672"},
317         {"$0x88888eef", "$2290650863"},
318         {"$1", "$1"},
319         {"$_main<>(SB)", "$_main<>(SB)"},
320         {"$argframe(FP)", "$argframe(FP)"},
321         {"$runtime·tlsg(SB)", "$runtime.tlsg(SB)"},
322         {"$~3", "$-4"},
323         {"(-288-3*8)(R1)", "-312(R1)"},
324         {"(16)(R7)", "16(R7)"},
325         {"(8)(g)", "8(g)"},
326         {"(CTR)", "(CTR)"},
327         {"(R0)", "(R0)"},
328         {"(R3)", "(R3)"},
329         {"(R4)", "(R4)"},
330         {"(R5)", "(R5)"},
331         {"(R5)(R6*1)", "(R5)(R6*1)"},
332         {"(R5+R6)", "(R5)(R6*1)"}, // Old syntax.
333         {"-1(R4)", "-1(R4)"},
334         {"-1(R5)", "-1(R5)"},
335         {"6(PC)", "6(PC)"},
336         {"CR7", "CR7"},
337         {"CTR", "CTR"},
338         {"F14", "F14"},
339         {"F15", "F15"},
340         {"F16", "F16"},
341         {"F17", "F17"},
342         {"F18", "F18"},
343         {"F19", "F19"},
344         {"F20", "F20"},
345         {"F21", "F21"},
346         {"F22", "F22"},
347         {"F23", "F23"},
348         {"F24", "F24"},
349         {"F25", "F25"},
350         {"F26", "F26"},
351         {"F27", "F27"},
352         {"F28", "F28"},
353         {"F29", "F29"},
354         {"F30", "F30"},
355         {"F31", "F31"},
356         {"LR", "LR"},
357         {"R0", "R0"},
358         {"R1", "R1"},
359         {"R11", "R11"},
360         {"R12", "R12"},
361         {"R13", "R13"},
362         {"R14", "R14"},
363         {"R15", "R15"},
364         {"R16", "R16"},
365         {"R17", "R17"},
366         {"R18", "R18"},
367         {"R19", "R19"},
368         {"R2", "R2"},
369         {"R20", "R20"},
370         {"R21", "R21"},
371         {"R22", "R22"},
372         {"R23", "R23"},
373         {"R24", "R24"},
374         {"R25", "R25"},
375         {"R26", "R26"},
376         {"R27", "R27"},
377         {"R28", "R28"},
378         {"R29", "R29"},
379         {"R3", "R3"},
380         {"R31", "R31"},
381         {"R4", "R4"},
382         {"R5", "R5"},
383         {"R6", "R6"},
384         {"R7", "R7"},
385         {"R8", "R8"},
386         {"R9", "R9"},
387         {"SPR(269)", "SPR(269)"},
388         {"a(FP)", "a(FP)"},
389         {"g", "g"},
390         {"ret+8(FP)", "ret+8(FP)"},
391         {"runtime·abort(SB)", "runtime.abort(SB)"},
392         {"·AddUint32(SB)", "\"\".AddUint32(SB)"},
393         {"·trunc(SB)", "\"\".trunc(SB)"},
394         {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
395 }
396
397 var arm64OperandTests = []operandTest{
398         {"$0", "$0"},
399         {"$0.5", "$(0.5)"},
400         {"0(R26)", "(R26)"},
401         {"0(RSP)", "(RSP)"},
402         {"$1", "$1"},
403         {"$-1", "$-1"},
404         {"$1000", "$1000"},
405         {"$1000000000", "$1000000000"},
406         {"$0x7fff3c000", "$34358935552"},
407         {"$1234", "$1234"},
408         {"$~15", "$-16"},
409         {"$16", "$16"},
410         {"-16(RSP)", "-16(RSP)"},
411         {"16(RSP)", "16(RSP)"},
412         {"1(R1)", "1(R1)"},
413         {"-1(R4)", "-1(R4)"},
414         {"18740(R5)", "18740(R5)"},
415         {"$2", "$2"},
416         {"$-24(R4)", "$-24(R4)"},
417         {"-24(RSP)", "-24(RSP)"},
418         {"$24(RSP)", "$24(RSP)"},
419         {"-32(RSP)", "-32(RSP)"},
420         {"$48", "$48"},
421         {"$(-64*1024)(R7)", "$-65536(R7)"},
422         {"$(8-1)", "$7"},
423         {"a+0(FP)", "a(FP)"},
424         {"a1+8(FP)", "a1+8(FP)"},
425         {"·AddInt32(SB)", `"".AddInt32(SB)`},
426         {"runtime·divWVW(SB)", "runtime.divWVW(SB)"},
427         {"$argframe+0(FP)", "$argframe(FP)"},
428         {"$asmcgocall<>(SB)", "$asmcgocall<>(SB)"},
429         {"EQ", "EQ"},
430         {"F29", "F29"},
431         {"F3", "F3"},
432         {"F30", "F30"},
433         {"g", "g"},
434         {"LR", "R30"},
435         {"(LR)", "(R30)"},
436         {"R0", "R0"},
437         {"R10", "R10"},
438         {"R11", "R11"},
439         {"$4503601774854144.0", "$(4503601774854144.0)"},
440         {"$runtime·badsystemstack(SB)", "$runtime.badsystemstack(SB)"},
441         {"ZR", "ZR"},
442         {"(ZR)", "(ZR)"},
443         {"(R29, RSP)", "(R29, RSP)"},
444         {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
445 }
446
447 var mips64OperandTests = []operandTest{
448         {"$((1<<63)-1)", "$9223372036854775807"},
449         {"$(-64*1024)", "$-65536"},
450         {"$(1024 * 8)", "$8192"},
451         {"$-1", "$-1"},
452         {"$-24(R4)", "$-24(R4)"},
453         {"$0", "$0"},
454         {"$0(R1)", "$(R1)"},
455         {"$0.5", "$(0.5)"},
456         {"$0x7000", "$28672"},
457         {"$0x88888eef", "$2290650863"},
458         {"$1", "$1"},
459         {"$_main<>(SB)", "$_main<>(SB)"},
460         {"$argframe(FP)", "$argframe(FP)"},
461         {"$~3", "$-4"},
462         {"(-288-3*8)(R1)", "-312(R1)"},
463         {"(16)(R7)", "16(R7)"},
464         {"(8)(g)", "8(g)"},
465         {"(R0)", "(R0)"},
466         {"(R3)", "(R3)"},
467         {"(R4)", "(R4)"},
468         {"(R5)", "(R5)"},
469         {"-1(R4)", "-1(R4)"},
470         {"-1(R5)", "-1(R5)"},
471         {"6(PC)", "6(PC)"},
472         {"F14", "F14"},
473         {"F15", "F15"},
474         {"F16", "F16"},
475         {"F17", "F17"},
476         {"F18", "F18"},
477         {"F19", "F19"},
478         {"F20", "F20"},
479         {"F21", "F21"},
480         {"F22", "F22"},
481         {"F23", "F23"},
482         {"F24", "F24"},
483         {"F25", "F25"},
484         {"F26", "F26"},
485         {"F27", "F27"},
486         {"F28", "F28"},
487         {"F29", "F29"},
488         {"F30", "F30"},
489         {"F31", "F31"},
490         {"R0", "R0"},
491         {"R1", "R1"},
492         {"R11", "R11"},
493         {"R12", "R12"},
494         {"R13", "R13"},
495         {"R14", "R14"},
496         {"R15", "R15"},
497         {"R16", "R16"},
498         {"R17", "R17"},
499         {"R18", "R18"},
500         {"R19", "R19"},
501         {"R2", "R2"},
502         {"R20", "R20"},
503         {"R21", "R21"},
504         {"R22", "R22"},
505         {"R23", "R23"},
506         {"R24", "R24"},
507         {"R25", "R25"},
508         {"R26", "R26"},
509         {"R27", "R27"},
510         {"R28", "R28"},
511         {"R29", "R29"},
512         {"R3", "R3"},
513         {"R31", "R31"},
514         {"R4", "R4"},
515         {"R5", "R5"},
516         {"R6", "R6"},
517         {"R7", "R7"},
518         {"R8", "R8"},
519         {"R9", "R9"},
520         {"LO", "LO"},
521         {"a(FP)", "a(FP)"},
522         {"g", "g"},
523         {"ret+8(FP)", "ret+8(FP)"},
524         {"runtime·abort(SB)", "runtime.abort(SB)"},
525         {"·AddUint32(SB)", "\"\".AddUint32(SB)"},
526         {"·trunc(SB)", "\"\".trunc(SB)"},
527         {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
528 }