Git init
[external/liboil.git] / testsuite / instruction / check-instructions.pl
1 #!/usr/bin/perl -w
2 # vi: set ts=4:
3 #
4
5 $debug = 0;
6 $pedantic = 0;
7
8 sub get_flags
9 {
10         my @list = @insns;
11         my $exts = {};
12         my $s;
13
14         $debug && print "function: $func\n";
15         foreach $insn (@list) {
16                 #$debug && print "checking instruction \"$insn\"\n";
17                 $insn =~ m/^(\w+)\s+(.*)$/;
18                 $opcode = $1;
19                 $regs = $2;
20                 if (grep { /^$opcode$/ } @normal_list) {
21                         $debug && print "  $opcode: normal\n";
22                 }elsif (grep { /^$opcode$/ } @cmov_list) {
23                         #$exts->{"cmov"} = 1;
24                         $debug && print "  $opcode: cmov\n";
25                 }elsif (grep { /^$opcode$/ } @mmxsse_list) {
26                         if (grep { /\%xmm/ } $regs) {
27                                 $exts->{"sse2"} = 1;
28                                 $debug && print "  $opcode: sse2\n";
29                         } else {
30                                 $exts->{"mmx"} = 1;
31                                 $debug && print "  $opcode: mmx\n";
32                         }
33                 }elsif (grep { /^$opcode$/ } @mmx_list) {
34                         $exts->{"mmx"} = 1;
35                         $debug && print "  $opcode: mmx\n";
36                 }elsif (grep { /^$opcode$/ } @mmx_ext_list) {
37                         $exts->{"mmxext"} = 1;
38                         $debug && print "  $opcode: mmxext\n";
39                 }elsif (grep { /^$opcode$/ } @_3dnow_list) {
40                         $exts->{"3dnow"} = 1;
41                         $debug && print "  $opcode: 3dnow\n";
42                 }elsif (grep { /^$opcode$/ } @_3dnow_ext_list) {
43                         $exts->{"3dnowext"} = 1;
44                         $debug && print "  $opcode: 3dnowext\n";
45                 }elsif (grep { /^$opcode$/ } @sse_list) {
46                         $exts->{"sse"} = 1;
47                         $debug && print "  $opcode: sse\n";
48                 }elsif (grep { /^$opcode$/ } @sse2_list) {
49                         $exts->{"sse2"} = 1;
50                         $debug && print "  $opcode: sse2\n";
51                 }elsif (grep { /^$opcode$/ } @sse3_list) {
52                         $exts->{"sse3"} = 1;
53                         $debug && print "  $opcode: sse3\n";
54                 }elsif (grep { /^$opcode$/ } @ssse3_list) {
55                         $exts->{"ssse3"} = 1;
56                         $debug && print "  $opcode: ssse3\n";
57                 }else {
58                         print "FIXME:\t\"$opcode\",\n";
59                         $error = 1;
60                 }
61         }
62         if (!$pedantic) {
63         if ($exts->{"sse3"}) {
64             $exts->{"sse2"} = 1;
65         }
66         if ($exts->{"sse2"}) {
67             $exts->{"sse"} = 1;
68             $exts->{"mmxext"} = 1;
69         }
70     }
71         $s = join(" ",sort(keys(%$exts)));
72         $funcs->{"$func"} = $s;
73         $debug && print "  FLAGS: $s\n";
74 }
75
76 sub check
77 {
78         foreach $insn (@normal_list) {
79                 if (grep { /^$insn$/ } @mmx_list) {
80                         print "FIXME: $insn is in mmx_list\n";
81                         $error = 1;
82                 } elsif (grep { /^$insn$/ } @mmx_ext_list) {
83                         print "FIXME: $insn is in mmx_ext_list\n";
84                         $error = 1;
85                 } elsif (grep { /^$insn$/ } @_3dnow_list) {
86                         print "FIXME: $insn is in _3dnow_list\n";
87                         $error = 1;
88                 } elsif (grep { /^$insn$/ } @_3dnow_ext_list) {
89                         print "FIXME: $insn is in _3dnow_ext_list\n";
90                         $error = 1;
91                 } elsif (grep { /^$insn$/ } @sse_list) {
92                         print "FIXME: $insn is in sse_list\n";
93                         $error = 1;
94                 } elsif (grep { /^$insn$/ } @sse2_list) {
95                         print "FIXME: $insn is in sse2_list\n";
96                         $error = 1;
97                 }
98         }
99 }
100
101 # this list is not complete
102 @normal_list = (
103         "add", 
104         "addl", 
105         "and", 
106         "andl", 
107         "bswap",
108         "call", 
109         "cld", 
110         "cltd", 
111         "cmp", 
112         "cmpb", 
113         "cmpl", 
114         "cwtl", 
115         "dec", 
116         "decl", 
117         "fabs", 
118         "fadd", 
119         "faddl", 
120         "faddp", 
121         "fadds", 
122         "fchs",
123         "fcom",
124         "fcomp",
125         "fcompp",
126         "fdiv",
127         "fdivl",
128         "fdivr",
129         "fdivrl", 
130         "fdivrs",
131         "fdivs",
132         "fiaddl",
133         "fimull",
134         "fild", 
135         "fildl", 
136         "fildll", 
137         "fistp", 
138         "fistpl", 
139         "fistpll", 
140         "fld",
141         "fld1",
142         "fldcw", 
143         "fldl", 
144         "flds", 
145         "fldt",
146         "fldz", 
147         "fmul", 
148         "fmull", 
149         "fmulp", 
150         "fmuls", 
151         "fnstcw", 
152         "fnstsw", 
153         "frndint",
154         "fsqrt", 
155         "fstl", 
156         "fstp", 
157         "fstpl", 
158         "fstps", 
159         "fstpt",
160         "fsts", 
161         "fsub", 
162         "fsubl", 
163         "fsubp", 
164         "fsubr", 
165         "fsubrl", 
166         "fsubrp", 
167         "fsubrs",
168         "fsubs",
169         "fucom", 
170         "fucomi", 
171         "fucomp", 
172         "fucompp", 
173         "fxch", 
174         "idiv",
175         "imul", 
176         "imulb",
177         "inc", 
178         "incl", 
179         "ja", 
180         "jae", 
181         "jb",
182         "jbe", 
183         "je", 
184         "jg", 
185         "jge", 
186         "jl", 
187         "jle", 
188         "jmp", 
189         "jne", 
190         "jns", 
191         "jp", 
192         "js", 
193         "lea", 
194         "leave", 
195         "mov", 
196         "movb", 
197         "movl", 
198         "movsbl", 
199         "movsbw", 
200         "movswl", 
201         "movsww", 
202         "movw",
203         "movzbl", 
204         "movzbw", 
205         "movzwl", 
206         "mul",
207         "mulb", 
208         "neg", 
209         "nop", 
210         "not", 
211         "or", 
212         "pop", 
213         "push", 
214         "pushl", 
215         "rep",
216         "repz", 
217         "ret", 
218         "rol", 
219         "ror", 
220         "sahf", 
221         "sar", 
222         "sarl", 
223         "setl",
224         "shl", 
225         "shll",
226         "shr", 
227         "shrl", 
228         "sub", 
229         "subl", 
230         "test", 
231         "testb", 
232         "testl", 
233         "xchg",
234         "xor", 
235 );
236
237 @cmov_list = (
238         "cmova",
239         "cmovae",
240         "cmovb",
241         "cmovg", 
242         "cmovge", 
243         "cmovl",
244         "cmovle", 
245         "cmovbe",
246         "fcmovbe",
247         "fcmovnbe",
248 );
249
250 # verified
251 @mmx_list = (
252         "emms",
253 );
254
255 # verified
256 @_3dnow_list = (
257         "femms",
258         "pavgusb",
259         "pf2id",
260         "pfacc",
261         "pfadd",
262         "pfcmpeq",
263         "pfcmpge",
264         "pfcmpgt",
265         "pfmax",
266         "pfmin",
267         "pfmul",
268         "pfrcp",
269         "pfrcpit1",
270         "pfrcpit2",
271         "pfrsqit1",
272         "pfrsqrt",
273         "pfsub",
274         "pfsubr",
275         "pi2fd",
276         "pmulhrw",
277         "prefetch",
278         "prefetchw"
279 );
280
281 # verified
282 @_3dnow_ext_list = (
283         "pf2iw",
284         "pfnacc",
285         "pfpnacc",
286         "pi2fw",
287         "pswapd"
288 );
289
290 # verified
291 @mmx_ext_list = (
292         "maskmovq",
293         "movntq",
294         "pavgb",
295         "pavgw",
296         "pextrw",
297         "pinsrw",
298         "pmaxsw",
299         "pmaxub",
300         "pminsw",
301         "pminub",
302         "pmovmskb",
303         "pmulhuw",
304         "prefetchnta",
305         "prefetch0",
306         "prefetch1",
307         "prefetch2",
308         "psadbw",
309         "pshufw",
310         "sfence"
311 );
312
313 # verified
314 @sse_list = (
315         "addps",
316         "addss",
317         "andnps",
318         "andps",
319         "cmpps",
320         "cmpss",
321         "comiss",
322         "cvtpi2ps",
323         "cvtps2pi",
324         "cvtsi2ss",
325         "cvtss2si",
326         "cvttps2pi",
327         "cvttss2si",
328         "divps",
329         "divss",
330         "fxrstor",
331         "fxsave",
332         "ldmxcsr",
333         "maxps",
334         "maxss",
335         "minps",
336         "minss",
337         "movaps",
338         "movhlps",
339         "movhps",
340         "movlhps",
341         "movlps",
342         "movmskps",
343         "movss",
344         "movups",
345         "mulps",
346         "mulss",
347         "orps",
348         "rcpps",
349         "rcpss",
350         "rsqrtps",
351         "rsqrtss",
352         "shufps",
353         "sqrtps",
354         "sqrtss",
355         "stmxcsr",
356         "subps",
357         "subss",
358         "ucomiss",
359         "unpckhps",
360         "unpcklps",
361         "xorps"
362 );
363
364 @mmxsse_list = (
365         "movd",
366         "movq",
367         "packssdw",
368         "packsswb",
369         "packuswb",
370         "paddb",
371         "paddd",
372         "paddsb",
373         "paddsw",
374         "paddusb",
375         "paddusw",
376         "paddw",
377         "pand",
378         "pandn",
379         "pcmpeqb",
380         "pcmpeqd",
381         "pcmpeqw",
382         "pcmpgtb",
383         "pcmpgtd",
384         "pcmpgtw",
385         "pmaddwd",
386         "pmulhw",
387         "pmullw",
388         "pmulhuw",
389         "por",
390         "pslld",
391         "psllq",
392         "psllw",
393         "psrad",
394         "psraw",
395         "psrld",
396         "psrlq",
397         "psrlw",
398         "psubb",
399         "psubd",
400         "psubsb",
401         "psubsw",
402         "psubusb",
403         "psubusw",
404         "psubw",
405         "punpckhbw",
406         "punpckhdq",
407         "punpckhwd",
408         "punpcklbw",
409         "punpckldq",
410         "punpcklwd",
411         "pxor",
412 );
413
414 # verified
415 @sse2_list = (
416         "addpd",
417         "addsd",
418         "andnpd",
419         "andpd",
420         "cmppd",
421         "cmpsd",
422         "comisd",
423         "cvtpi2pd",
424         "cvtpd2pi",
425         "cvtsi2sd",
426         "cvtsd2si",
427         "cvttpd2pi",
428         "cvttsd2si",
429         "cvtpd2ps",
430         "cvtps2pd",
431         "cvtsd2ss",
432         "cvtss2sd",
433         "cvtps2dq",
434         "cvttpd2dq",
435         "cvtdq2pd",
436         "cvtps2dq",
437         "cvttps2dq",
438         "cvtdq2ps",
439         "divpd",
440         "divsd",
441         "maxpd",
442         "maxsd",
443         "minpd",
444         "minsd",
445         "movapd",
446         "movhpd",
447         "movlpd",
448         "movmskpd",
449         "movsd",
450         "movupd",
451         "mulpd",
452         "mulsd",
453         "orpd",
454         "shufpd",
455         "sqrtpd",
456         "sqrtsd",
457         "subpd",
458         "subsd",
459         "ucomisd",
460         "unpckhpd",
461         "unpcklpd",
462         "xorpd",
463         #"movd",
464         "movdqa",
465         "movdqu",
466         "movq2dq",
467         "movdq2q",
468         #"movq",
469         #"packssdw",
470         #"packsswb",
471         #"packuswb",
472         "paddq",
473         "padd",
474         "padds",
475         "paddus",
476         #"pand",
477         #"pandn",
478         "pavgb",
479         "pavgw",
480         "pcmpeq",
481         "pcmpgt",
482         "pextrw",
483         "pinsrw",
484         #"pmaddwd",
485         "pmaxsw",
486         "pmaxub",
487         "pminsw",
488         "pminub",
489         "pmovmskb",
490         "pmulhuw",
491         #"pmulhw",
492         #"pmullw",
493         "pmuludq",
494         #"por",
495         "psadbw",
496         "pshuflw",
497         "pshufhw",
498         "pshufd",
499         "pslldq",
500         "psll",
501         "psra",
502         "psrldq",
503         "psrl",
504         "psubq",
505         "psub",
506         "psubs",
507         "psubus",
508         "punpckh",
509         "punpckhqdq",
510         "punpckl",
511         "punpcklqdq",
512         #"pxor",
513         "maskmovdqu",
514         "movntpd",
515         "movntdq",
516         "movnti",
517         "pause",
518         "lfence",
519         "mfence",
520 );
521
522 @sse3_list = (
523         "addsubpd",
524         "addsubps",
525         "haddpd",
526         "haddps",
527         "hsubpd",
528         "hsubps",
529         "lddqu",
530         "movddup",
531         "movshdup",
532         "movsldup",
533         "fisttp"
534 );
535
536 @ssse3_list = (
537         "psignb",
538         "psignw",
539         "psignd",
540         "pabsb",
541         "pabsw",
542         "pabsd",
543         "palignr",
544         "pshufb",
545         "pmulhrsw",
546         "pmaddubsw",
547         "phsubw",
548         "phsubd",
549         "phsubsw",
550         "phaddw",
551         "phaddd",
552         "phaddsw"
553 );
554
555 #@clflush_list = (
556 #       "clflush",
557 #);
558
559 $funcs = {};
560
561 $ARGV=shift @ARGV;
562 @output=`objdump -j .text -dr $ARGV`;
563
564 check();
565
566 $error = 0;
567 @insns = ();
568 while($_=shift @output){
569         chomp;
570         if(m/^0[0-9a-fA-F]+\s<[\.\w@]+>:$/){
571                 $f = $_;
572                 $f =~ s/^0[0-9a-fA-F]+\s<([\.\w]+)>:$/$1/;
573
574                 if (@insns) {
575                         get_flags ();
576                 }
577
578                 $func = $f;
579
580                 @insns = ();
581                 $debug && print "$func:\n";
582
583         } elsif(m/^[\s0-9a-f]+:\s[\s0-9a-f]{20}\s+([\w]+\s.*)$/){
584                 push @insns, $1;
585                 #print "  $1\n";
586         } elsif(m/^[\s0-9a-f]+:\s[\s0-9a-f]{2,20}\s$/){
587                 # ignore
588         } elsif (m/^$/) {
589         } elsif (m/^Disassembly of section/) {
590         } elsif (m/\sfile format\s/) {
591         } else {
592                 print "FIXME: $_\n";
593                 $error = 1;
594         }
595 }
596
597 @source = `./list-impls`;
598 while ($_ = shift @source) {
599         chomp;
600         if (m/^([\w\.]+):\s*([\w\s*]*)/) {
601                 $func = $1;
602                 $flags = $2;
603
604                 $xflags = $funcs->{$func};
605                 if (1) {
606                         if ($flags ne $xflags) {
607                                 print "$func: \"$flags\" should be \"$xflags\"\n";
608                         }
609                 } else {
610                         print "FIXME: function \"$func\" has no disassembly\n";
611                         $error = 1;
612                 }
613         } else {
614                 print "FIXME: bad match: $_\n";
615         }
616 }
617
618 exit $error;
619
620