none/tests/fdleak_cmsg_supp.supp: Add suppressions for older glibc
[valgrind.git] / none / tests / amd64 / gen_insn_test.pl
blobaa3910462d121024b547dd07164dae6b81d2842d
1 #!/usr/bin/perl
3 use 5.006;
4 use strict;
5 use warnings;
7 our %ArgTypes = (
8 r8 => "reg8_t",
9 r16 => "reg16_t",
10 r32 => "reg32_t",
11 r64 => "reg64_t",
12 mm => "reg64_t",
13 xmm => "reg128_t",
14 m8 => "reg8_t",
15 m16 => "reg16_t",
16 m32 => "reg32_t",
17 m64 => "reg64_t",
18 m128 => "reg128_t",
19 rflags => "reg64_t",
20 st => "reg64_t",
21 fpucw => "reg16_t",
22 fpusw => "reg16_t"
25 our %SubTypeFormats = (
26 sb => "%d",
27 ub => "%u",
28 sw => "%d",
29 uw => "%u",
30 sd => "%d",
31 ud => "%u",
32 sq => "%lld",
33 uq => "%llu",
34 ps => "%.16g",
35 pd => "%.16g"
38 our %SubTypeSuffixes = (
39 sb => "",
40 ub => "U",
41 sw => "",
42 uw => "",
43 sd => "",
44 ud => "",
45 sq => "LL",
46 uq => "ULL",
47 ps => "F",
48 pd => ""
51 our %RegNums = (
52 r9b => 0, r9w => 0, r9d => 0, r9 => 0,
53 r10b => 1, r10w => 1, r10d => 1, r10 => 1,
54 r11b => 2, r11w => 2, r11d => 2, r11 => 2,
55 r12b => 3, r12w => 3, r12d => 3, r12 => 3,
56 al => 4, ax => 4, eax => 4, rax => 4,
57 bl => 5, bx => 5, ebx => 5, rbx => 5,
58 cl => 6, cx => 6, ecx => 6, rcx => 6,
59 dl => 7, dx => 7, edx => 7, rdx => 7,
60 ah => 8,
61 bh => 9,
62 ch => 10,
63 dh => 11,
64 st0 => 0, st1 => 1, st2 => 2, st3 => 3,
65 st4 => 4, st5 => 5, st6 => 6, st7 => 7
68 our %RegTypes = (
69 al => "r8", ah => "r8", ax => "r16", eax => "r32", rax => "r64",
70 bl => "r8", bh => "r8", bx => "r16", ebx => "r32", rbx => "r64",
71 cl => "r8", ch => "r8", cx => "r16", ecx => "r32", rcx => "r64",
72 dl => "r8", dh => "r8", dx => "r16", edx => "r32", rdx => "r64"
75 #our @IntRegs = (
76 # { r8 => "al", r16 => "ax", r32 => "eax", r64 => "rax" },
77 # { r8 => "bl", r16 => "bx", r32 => "ebx", r64 => "rbx" },
78 # { r8 => "cl", r16 => "cx", r32 => "ecx", r64 => "rcx" },
79 # { r8 => "dl", r16 => "dx", r32 => "edx", r64 => "rdx" },
80 # { r8 => "ah" },
81 # { r8 => "bh" },
82 # { r8 => "ch" },
83 # { r8 => "dh" }
84 # );
86 our @IntRegs = (
87 { r8 => "r9b", r16 => "r9w", r32 => "r9d", r64 => "r9" },
88 { r8 => "r10b", r16 => "r10w", r32 => "r10d", r64 => "r10" },
89 { r8 => "r11b", r16 => "r11w", r32 => "r11d", r64 => "r11" },
90 { r8 => "r12b", r16 => "r12w", r32 => "r12d", r64 => "r12" },
91 { r8 => "al", r16 => "ax", r32 => "eax", r64 => "rax" },
92 { r8 => "bl", r16 => "bx", r32 => "ebx", r64 => "rbx" },
93 { r8 => "cl", r16 => "cx", r32 => "ecx", r64 => "rcx" },
94 { r8 => "dl", r16 => "dx", r32 => "edx", r64 => "rdx" },
95 { r8 => "ah" },
96 { r8 => "bh" },
97 { r8 => "ch" },
98 { r8 => "dh" }
101 print <<EOF;
102 #include <math.h>
103 #include <setjmp.h>
104 #include <signal.h>
105 #include <stdio.h>
106 #include <stdlib.h>
108 typedef union {
109 char sb[1];
110 unsigned char ub[1];
111 } reg8_t;
113 typedef union {
114 char sb[2];
115 unsigned char ub[2];
116 short sw[1];
117 unsigned short uw[1];
118 } reg16_t;
120 typedef union {
121 char sb[4];
122 unsigned char ub[4];
123 short sw[2];
124 unsigned short uw[2];
125 int sd[1];
126 unsigned int ud[1];
127 float ps[1];
128 } reg32_t;
130 typedef union {
131 char sb[8];
132 unsigned char ub[8];
133 short sw[4];
134 unsigned short uw[4];
135 int sd[2];
136 unsigned int ud[2];
137 long long int sq[1];
138 unsigned long long int uq[1];
139 float ps[2];
140 double pd[1];
141 } reg64_t __attribute__ ((aligned (8)));
143 typedef union {
144 char sb[16];
145 unsigned char ub[16];
146 short sw[8];
147 unsigned short uw[8];
148 int sd[4];
149 unsigned int ud[4];
150 long long int sq[2];
151 unsigned long long int uq[2];
152 float ps[4];
153 double pd[2];
154 } reg128_t __attribute__ ((aligned (16)));
156 static sigjmp_buf catchpoint;
158 static void handle_sigill(int signum)
160 siglongjmp(catchpoint, 1);
163 __attribute__((unused))
164 static int eq_float(float f1, float f2)
166 /* return f1 == f2 || fabsf(f1 - f2) < fabsf(f1) * 1.5 * powf(2,-12); */
167 return f1 == f2 || fabsf(f1 - f2) < fabsf(f1) * 1.5 / 4096.0;
170 __attribute__((unused))
171 static int eq_double(double d1, double d2)
173 /* return d1 == d2 || fabs(d1 - d2) < fabs(d1) * 1.5 * pow(2,-12); */
174 return d1 == d2 || fabs(d1 - d2) < fabs(d1) * 1.5 / 4096.0;
179 my %tests;
180 my @tests;
182 while (<>)
184 next if /^#/;
186 my $insn;
187 my $presets;
188 my $args;
189 my $results;
191 if (/^(\S+)\s+(?:(\S+(?:\s+\S+)*)\s+:\s+)?((?:\S+\s+)*?)(?:=>\s+(\S+(?:\s+\S+)*))?$/)
193 $insn = $1;
194 $presets = $2 || "";
195 $args = $3 || "";
196 $results = $4 || "";
198 # print STDERR "insn: $insn\n";
199 # print STDERR "presets: $presets\n";
200 # print STDERR "args: $args\n";
201 # print STDERR "results: $results\n";
203 else
205 die "Can't parse test $_";
208 $tests{$insn}++;
210 my $test = "${insn}_$tests{$insn}";
212 push @tests, $test;
214 print qq|static void $test(void)\n|;
215 print qq|\{\n|;
217 my @intregs = @IntRegs;
218 my @mmregs = map { "mm$_" } (6,7,0,1,2,3,4,5);
219 # my @xmmregs = map { "xmm$_" } (4,5,0,1,2,3,6,7);
220 my @xmmregs = map { "xmm$_" } (12,13,8,9,10,11,14,15);
221 my @fpregs = map { "st$_" } (0 .. 7);
223 my @presets;
224 my $presetc = 0;
225 my $rflagsmask;
226 my $rflagsset;
227 my $fpucwmask;
228 my $fpucwset;
229 my $fpuswmask;
230 my $fpuswset;
232 foreach my $preset (split(/\s+/, $presets))
234 if ($preset =~ /^([abcd][lh]|[abcd]x|e[abcd]x|r[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
236 my $name = "preset$presetc";
237 my $type = $RegTypes{$1};
238 my $regnum = $RegNums{$1};
239 my $register = $intregs[$regnum];
240 my $subtype = $2;
241 my @values = split(/,/, $3);
243 die "Register $1 already used" unless defined($register);
245 my $preset = {
246 name => $name,
247 type => $type,
248 subtype => $subtype,
249 register => $register
252 delete($intregs[$regnum]);
254 push @presets, $preset;
256 print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
258 my $valuec = 0;
260 foreach my $value (@values)
262 print qq|,| if $valuec > 0;
263 print qq| $value$SubTypeSuffixes{$subtype}|;
264 $valuec++;
267 print qq| \} \};\n|;
269 $presetc++;
271 elsif ($preset =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
273 my $name = "preset$presetc";
274 my $type = "st";
275 my $regnum = $1;
276 my $register = $fpregs[$regnum];
277 my $subtype = $2;
278 my @values = split(/,/, $3);
280 die "Register st$1 already used" unless defined($register);
282 my $preset = {
283 name => $name,
284 type => $type,
285 subtype => $subtype,
286 register => $register
289 delete($fpregs[$regnum]);
291 push @presets, $preset;
293 print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
295 my $valuec = 0;
297 foreach my $value (@values)
299 print qq|,| if $valuec > 0;
300 print qq| $value$SubTypeSuffixes{$subtype}|;
301 $valuec++;
304 print qq| \} \};\n|;
306 $presetc++;
308 elsif ($preset =~ /^(rflags)\[([^\]]+)\]$/)
310 my $type = $1;
311 my @values = split(/,/, $2);
313 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
314 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
316 $rflagsmask = sprintf "0x%016x", ~$values[0];
317 $rflagsset = sprintf "0x%016x", $values[1];
319 elsif ($preset =~ /^(fpucw)\[([^\]]+)\]$/)
321 my $type = $1;
322 my @values = split(/,/, $2);
324 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
325 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
327 $fpucwmask = sprintf "0x%04x", $values[0] ^ 0xffff;
328 $fpucwset = sprintf "0x%04x", $values[1];
330 elsif ($preset =~ /^(fpusw)\[([^\]]+)\]$/)
332 my $type = $1;
333 my @values = split(/,/, $2);
335 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
336 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
338 $fpuswmask = sprintf "0x%04x", $values[0] ^ 0xffff;
339 $fpuswset = sprintf "0x%04x", $values[1];
341 else
343 die "Can't parse preset $preset";
347 my @args;
348 my $argc = 0;
350 foreach my $arg (split(/\s+/, $args))
352 my $name = "arg$argc";
354 if ($arg =~ /^([abcd]l|[abcd]x|e[abcd]x|r[abcd]x|r8|r16|r32|r64|mm|xmm|m8|m16|m32|m64|m128)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
356 my $type = $RegTypes{$1} || $1;
357 my $regnum = $RegNums{$1};
358 my $register = $intregs[$regnum] if defined($regnum);
359 my $subtype = $2;
360 my @values = split(/,/, $3);
362 die "Register $1 already used" if defined($regnum) && !defined($register);
364 my $arg = {
365 name => $name,
366 type => $type,
367 subtype => $subtype
370 if (defined($register))
372 $arg->{register} = $register;
373 delete($intregs[$regnum]);
376 push @args, $arg;
378 print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
380 my $valuec = 0;
382 foreach my $value (@values)
384 print qq|,| if $valuec > 0;
385 print qq| $value$SubTypeSuffixes{$subtype}|;
386 $valuec++;
389 print qq| \} \};\n|;
391 elsif ($arg =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
393 my $type = "st";
394 my $regnum = $1;
395 my $register = $fpregs[$regnum] if defined($regnum);
396 my $subtype = $2;
397 my @values = split(/,/, $3);
399 die "Register st$1 already used" if defined($regnum) && !defined($register);
401 my $arg = {
402 name => $name,
403 type => $type,
404 subtype => $subtype
407 if (defined($register))
409 $arg->{register} = $register;
410 delete($fpregs[$regnum]);
413 push @args, $arg;
415 print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
417 my $valuec = 0;
419 foreach my $value (@values)
421 print qq|,| if $valuec > 0;
422 print qq| $value$SubTypeSuffixes{$subtype}|;
423 $valuec++;
426 print qq| \} \};\n|;
428 elsif ($arg =~ /^(imm8|imm16|imm32|imm64)\[([^\]]+)\]$/)
430 my $type = $1;
431 my $value = $2;
433 my $arg = {
434 type => $type,
435 value => $value
438 push @args, $arg;
440 else
442 die "Can't parse argument $arg";
445 $argc++;
448 foreach my $arg (@presets, @args)
450 if ($arg->{type} =~ /^(r8|r16|r32|r64|m8|m16|m32)$/)
452 while (!exists($arg->{register}) || !defined($arg->{register}))
454 $arg->{register} = shift @intregs;
457 $arg->{register} = $arg->{register}->{$arg->{type}};
459 elsif ($arg->{type} =~ /^(mm|m64)$/)
461 $arg->{register} = shift @mmregs;
463 elsif ($arg->{type} =~ /^(xmm|m128)$/)
465 $arg->{register} = shift @xmmregs;
467 elsif ($arg->{type} =~ /^st$/)
469 while (!exists($arg->{register}) || !defined($arg->{register}))
471 $arg->{register} = shift @fpregs;
476 my @results;
477 my $resultc = 0;
479 foreach my $result (split(/\s+/, $results))
481 my $name = "result$resultc";
483 if ($result =~ /^(\d+)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
485 my $index = $1;
486 my $type = $args[$index]->{type};
487 my $subtype = $2;
488 my @values = split(/,/, $3);
490 die "Argument $index not specified" unless exists($args[$index]);
492 my $result = {
493 name => $name,
494 type => $type,
495 subtype => $subtype,
496 arg => $args[$index],
497 register => $args[$index]->{register},
498 values => [ @values ]
501 push @results, $result;
503 print qq| $ArgTypes{$type} $name|;
504 print qq| = arg$index| if $type =~ /^m(8|16|32|64|128)$/;
505 print qq|;\n|;
507 $args[$index]->{result} = $result;
509 elsif ($result =~ /^([abcd][lh]|[abcd]x|e[abcd]x|r[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
511 my $register = $1;
512 my $type = $RegTypes{$register};
513 my $subtype = $2;
514 my @values = split(/,/, $3);
516 my $result = {
517 name => $name,
518 type => $type,
519 subtype => $subtype,
520 register => $register,
521 values => [ @values ]
524 push @results, $result;
526 print qq| $ArgTypes{$type} $name;\n|;
528 elsif ($result =~ /^(st[0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
530 my $register = $1;
531 my $type = "st";
532 my $subtype = $2;
533 my @values = split(/,/, $3);
535 my $result = {
536 name => $name,
537 type => $type,
538 subtype => $subtype,
539 register => $register,
540 values => [ @values ]
543 push @results, $result;
545 print qq| $ArgTypes{$type} $name;\n|;
547 elsif ($result =~ /^rflags\[([^\]]+)\]$/)
549 my @values = split(/,/, $1);
551 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
552 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
554 my $result = {
555 name => $name,
556 type => "rflags",
557 subtype => "uq",
558 values => [ map { sprintf "0x%016x", $_ } @values ]
561 push @results, $result;
563 print qq| $ArgTypes{rflags} $name;\n|;
565 if (!defined($rflagsmask) && !defined($rflagsset))
567 $rflagsmask = sprintf "0x%016x", ~$values[0];
568 $rflagsset = sprintf "0x%016x", $values[0] & ~$values[1];
571 elsif ($result =~ /^fpucw\[([^\]]+)\]$/)
573 my @values = split(/,/, $1);
575 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
576 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
578 my $result = {
579 name => $name,
580 type => "fpucw",
581 subtype => "ud",
582 values => [ map { sprintf "0x%04x", $_ } @values ]
585 push @results, $result;
587 print qq| $ArgTypes{fpucw} $name;\n|;
589 if (!defined($fpucwmask) && !defined($fpucwset))
591 $fpucwmask = sprintf "0x%04x", $values[0] ^ 0xffff;
592 $fpucwset = sprintf "0x%04x", $values[0] & ~$values[1];
595 elsif ($result =~ /^fpusw\[([^\]]+)\]$/)
597 my @values = split(/,/, $1);
599 $values[0] = oct($values[0]) if $values[0] =~ /^0/;
600 $values[1] = oct($values[1]) if $values[1] =~ /^0/;
602 my $result = {
603 name => $name,
604 type => "fpusw",
605 subtype => "ud",
606 values => [ map { sprintf "0x%04x", $_ } @values ]
609 push @results, $result;
611 print qq| $ArgTypes{fpusw} $name;\n|;
613 if (!defined($fpuswmask) && !defined($fpuswset))
615 $fpuswmask = sprintf "0x%04x", $values[0] ^ 0xffff;
616 $fpuswset = sprintf "0x%04x", $values[0] & ~$values[1];
619 else
621 die "Can't parse result $result";
624 $resultc++;
627 my $argnum = 0;
629 foreach my $result (@results)
631 if ($result->{type} eq "xmm")
633 $result->{argnuml} = $argnum++;
634 $result->{argnumh} = $argnum++;
636 else
638 $result->{argnum} = $argnum++;
642 foreach my $arg (@presets, @args)
644 if (defined($arg->{name}))
646 if ($arg->{type} eq "xmm")
648 $arg->{argnuml} = $argnum++;
649 $arg->{argnumh} = $argnum++;
651 else
653 $arg->{argnum} = $argnum++;
658 my $stateargnum = $argnum++;
660 print qq| char state\[108\];\n|;
661 print qq|\n|;
662 print qq| if (sigsetjmp(catchpoint, 1) == 0)\n|;
663 print qq| \{\n|;
664 print qq| asm\(\n|;
665 # print qq| \"fsave %$stateargnum\\n\"\n|;
666 print qq| \"ffree %%st(7)\\n\"\n|;
667 print qq| \"ffree %%st(6)\\n\"\n|;
668 print qq| \"ffree %%st(5)\\n\"\n|;
669 print qq| \"ffree %%st(4)\\n\"\n|;
671 my @fpargs;
673 foreach my $arg (@presets, @args)
675 if ($arg->{type} eq "r8")
677 print qq| \"movb %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
679 elsif ($arg->{type} eq "r16")
681 print qq| \"movw %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
683 elsif ($arg->{type} eq "r32")
685 print qq| \"movl %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
687 elsif ($arg->{type} eq "r64")
689 print qq| \"movq %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
691 elsif ($arg->{type} eq "mm")
693 print qq| \"movq %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
695 elsif ($arg->{type} eq "xmm")
697 print qq| \"movlps %$arg->{argnuml}, %%$arg->{register}\\n\"\n|;
698 print qq| \"movhps %$arg->{argnumh}, %%$arg->{register}\\n\"\n|;
700 elsif ($arg->{type} eq "st")
702 $fpargs[$RegNums{$arg->{register}}] = $arg;
706 foreach my $arg (reverse @fpargs)
708 if (defined($arg))
710 if ($arg->{subtype} eq "ps")
712 print qq| \"flds %$arg->{argnum}\\n\"\n|;
714 elsif ($arg->{subtype} eq "pd")
716 print qq| \"fldl %$arg->{argnum}\\n\"\n|;
719 else
721 print qq| \"fldz\\n\"\n|;
725 if (defined($rflagsmask) || defined($rflagsset))
727 print qq| \"pushfq\\n\"\n|;
728 print qq| \"andq \$$rflagsmask, (%%rsp)\\n\"\n| if defined($rflagsmask);
729 print qq| \"orq \$$rflagsset, (%%rsp)\\n\"\n| if defined($rflagsset);
730 print qq| \"popfq\\n\"\n|;
733 if (defined($fpucwmask) || defined($fpucwset))
735 print qq| \"subq \$2, %%rsp\\n\"\n|;
736 print qq| \"fstcw (%%rsp)\\n\"\n|;
737 print qq| \"andw \$$fpucwmask, (%%rsp)\\n\"\n| if defined($fpucwmask);
738 print qq| \"orw \$$fpucwset, (%%rsp)\\n\"\n| if defined($fpucwset);
739 print qq| \"fldcw (%%rsp)\\n\"\n|;
740 print qq| \"addq \$2, %%rsp\\n\"\n|;
743 print qq| \"$insn|;
745 my $prefix = " ";
747 foreach my $arg (@args)
749 next if $arg->{type} eq "rflags";
751 if ($arg->{type} =~ /^(r8|r16|r32|r64|mm|xmm)$/)
753 print qq|$prefix%%$arg->{register}|;
755 elsif ($arg->{type} =~ /^st$/)
757 my $register = $arg->{register};
759 $register =~ s/st(\d+)/st\($1\)/;
761 print qq|$prefix%%$register|;
763 elsif ($arg->{type} =~ /^(m(8|16|32|64|128))$/)
765 if (exists($arg->{result}))
767 print qq|$prefix%$arg->{result}->{argnum}|;
769 else
771 print qq|$prefix%$arg->{argnum}|;
774 elsif ($arg->{type} =~ /^imm(8|16|32|64)$/)
776 print qq|$prefix\$$arg->{value}|;
779 $prefix = ", ";
782 print qq|\\n\"\n|;
784 my @fpresults;
786 foreach my $result (@results)
788 if ($result->{type} eq "r8")
790 print qq| \"movb %%$result->{register}, %$result->{argnum}\\n\"\n|;
792 elsif ($result->{type} eq "r16")
794 print qq| \"movw %%$result->{register}, %$result->{argnum}\\n\"\n|;
796 elsif ($result->{type} eq "r32")
798 print qq| \"movl %%$result->{register}, %$result->{argnum}\\n\"\n|;
800 elsif ($result->{type} eq "r64")
802 print qq| \"movq %%$result->{register}, %$result->{argnum}\\n\"\n|;
804 elsif ($result->{type} eq "mm")
806 print qq| \"movq %%$result->{register}, %$result->{argnum}\\n\"\n|;
808 elsif ($result->{type} eq "xmm")
810 print qq| \"movlps %%$result->{register}, %$result->{argnuml}\\n\"\n|;
811 print qq| \"movhps %%$result->{register}, %$result->{argnumh}\\n\"\n|;
813 elsif ($result->{type} eq "st")
815 $fpresults[$RegNums{$result->{register}}] = $result;
817 elsif ($result->{type} eq "rflags")
819 print qq| \"pushfq\\n\"\n|;
820 print qq| \"popq %$result->{argnum}\\n\"\n|;
822 elsif ($result->{type} eq "fpucw")
824 print qq| \"fstcw %$result->{argnum}\\n\"\n|;
826 elsif ($result->{type} eq "fpusw")
828 print qq| \"fstsw %$result->{argnum}\\n\"\n|;
832 foreach my $result (@fpresults)
834 if (defined($result))
836 if ($result->{subtype} eq "ps")
838 print qq| \"fstps %$result->{argnum}\\n\"\n|;
840 elsif ($result->{subtype} eq "pd")
842 print qq| \"fstpl %$result->{argnum}\\n\"\n|;
845 else
847 print qq| \"fincstp\\n\"\n|;
851 # print qq| \"frstor %$stateargnum\\n\"\n|;
852 print qq| \"cld\\n\"\n|;
854 print qq| :|;
856 $prefix = " ";
858 foreach my $result (@results)
860 if ($result->{type} eq "xmm")
862 print qq|$prefix\"=m\" \($result->{name}.uq[0]\), \"=m\" \($result->{name}.uq[1]\)|;
864 else
866 print qq|$prefix\"=m\" \($result->{name}\)|;
869 $prefix = ", ";
872 print qq|\n|;
874 $prefix = " : ";
876 foreach my $arg (@presets, @args)
878 if (defined($arg->{name}))
880 if ($arg->{type} eq "xmm")
882 print qq|$prefix\"m\" \($arg->{name}.uq[0]\), \"m\" \($arg->{name}.uq[1]\)|;
884 else
886 print qq|$prefix\"m\" \($arg->{name}\)|;
889 $prefix = ", ";
893 print qq|$prefix\"m\" \(state[0]\)\n|;
895 $prefix = " : ";
896 my %clobber_added;
898 foreach my $arg (@presets, @results, @args)
900 if ($arg->{register} && $arg->{type} ne "st")
902 my $register = $arg->{register};
904 $register =~ s/^(r[0-9]+)[bwd]$/$1/;
905 if (!$clobber_added{$register}++)
907 print qq|$prefix\"$register\"|;
908 $prefix = ", ";
913 print qq|\n|;
915 print qq| \);\n|;
916 print qq|\n|;
918 if (@results)
920 print qq| if \(|;
922 $prefix = "";
924 foreach my $result (@results)
926 my $type = $result->{type};
927 my $subtype = $result->{subtype};
928 my $suffix = $SubTypeSuffixes{$subtype};
929 my @values = @{$result->{values}};
931 if ($type eq "rflags")
933 print qq|${prefix}\($result->{name}.uq[0] & $values[0]UL\) == $values[1]UL|;
935 elsif ($type =~ /^fpu[cs]w$/)
937 print qq|${prefix}\($result->{name}.uw[0] & $values[0]\) == $values[1]|;
939 else
941 foreach my $value (0 .. $#values)
943 if ($subtype eq "ps")
945 print qq|${prefix}eq_float($result->{name}.$subtype\[$value\], $values[$value]$suffix)|;
947 elsif ($subtype eq "pd")
949 print qq|${prefix}eq_double($result->{name}.$subtype\[$value\], $values[$value]$suffix)|;
951 else
953 print qq|${prefix}$result->{name}.$subtype\[$value\] == $values[$value]$suffix|;
956 $prefix = " && ";
960 $prefix = " &&\n ";
963 print qq| \)\n|;
964 print qq| \{\n|;
965 print qq| printf("$test ... ok\\n");\n|;
966 print qq| \}\n|;
967 print qq| else\n|;
968 print qq| \{\n|;
969 print qq| printf("$test ... not ok\\n");\n|;
971 foreach my $result (@results)
973 my $type = $result->{type};
974 my $subtype = $result->{subtype};
975 my $suffix = $SubTypeSuffixes{$subtype};
976 my @values = @{$result->{values}};
978 if ($type eq "rflags")
980 print qq| printf(" rflags & 0x%lx = 0x%lx (expected 0x%lx)\\n", $values[0]UL, $result->{name}.ud\[0\] & $values[0]UL, $values[1]UL);\n|;
982 elsif ($type =~ /^fpu[cs]w$/)
984 print qq| printf(" $type & 0x%x = 0x%x (expected 0x%x)\\n", $values[0], $result->{name}.uw\[0\] & $values[0], $values[1]);\n|;
986 else
988 foreach my $value (0 .. $#values)
990 print qq| printf(" $result->{name}.$subtype\[$value\] = $SubTypeFormats{$subtype} (expected $SubTypeFormats{$subtype})\\n", $result->{name}.$subtype\[$value\], $values[$value]$suffix);\n|;
995 print qq| \}\n|;
997 else
999 print qq| printf("$test ... ok\\n");\n|;
1002 print qq| \}\n|;
1003 print qq| else\n|;
1004 print qq| \{\n|;
1005 print qq| printf("$test ... failed\\n");\n|;
1006 print qq| \}\n|;
1007 print qq|\n|;
1008 print qq| return;\n|;
1009 print qq|\}\n|;
1010 print qq|\n|;
1013 print qq|int main(int argc, char **argv)\n|;
1014 print qq|\{\n|;
1015 print qq| signal(SIGILL, handle_sigill);\n|;
1016 print qq|\n|;
1018 foreach my $test (@tests)
1020 print qq| $test();\n|;
1023 print qq|\n|;
1024 print qq| exit(0);\n|;
1025 print qq|\}\n|;
1027 exit 0;