1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#!/usr/bin/perl
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse 5.006;
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse strict;
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse warnings;
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour %ArgTypes = (
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 r8 => "reg8_t",
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 r16 => "reg16_t",
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 r32 => "reg32_t",
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mm => "reg64_t",
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 xmm => "reg128_t",
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 m8 => "reg8_t",
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 m16 => "reg16_t",
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 m32 => "reg32_t",
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 m64 => "reg64_t",
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 m128 => "reg128_t",
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 eflags => "reg32_t",
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 st => "reg64_t",
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 fpucw => "reg16_t",
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 fpusw => "reg16_t"
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 );
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour %SubTypeFormats = (
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sb => "%d",
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ub => "%u",
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sw => "%d",
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       uw => "%u",
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sd => "%ld",
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ud => "%lu",
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sq => "%lld",
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       uq => "%llu",
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ps => "%.16g",
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       pd => "%.16g"
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       );
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour %SubTypeSuffixes = (
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        sb => "",
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ub => "U",
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        sw => "",
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        uw => "",
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        sd => "L",
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ud => "UL",
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        sq => "LL",
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        uq => "ULL",
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ps => "F",
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        pd => ""
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        );
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour %RegNums = (
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                al => 0, ax => 0, eax => 0,
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                bl => 1, bx => 1, ebx => 1,
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                cl => 2, cx => 2, ecx => 2,
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                dl => 3, dx => 3, edx => 3,
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ah => 4,
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                bh => 5,
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ch => 6,
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                dh => 7,
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                st0 => 0, st1 => 1, st2 => 2, st3 => 3,
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                st4 => 4, st5 => 5, st6 => 6, st7 => 7
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                );
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour %RegTypes = (
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 al => "r8", ah => "r8", ax => "r16", eax => "r32",
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 bl => "r8", bh => "r8", bx => "r16", ebx => "r32",
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 cl => "r8", ch => "r8", cx => "r16", ecx => "r32",
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 dl => "r8", dh => "r8", dx => "r16", edx => "r32"
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 );
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownour @IntRegs = (
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "al", r16 => "ax", r32 => "eax" },
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "bl", r16 => "bx", r32 => "ebx" },
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "cl", r16 => "cx", r32 => "ecx" },
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "dl", r16 => "dx", r32 => "edx" },
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "ah" },
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "bh" },
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "ch" },
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                { r8 => "dh" }
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                );
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint <<EOF;
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <math.h>
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <setjmp.h>
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <signal.h>
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef union {
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char sb[1];
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned char ub[1];
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} reg8_t;
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef union {
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char sb[2];
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned char ub[2];
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  short sw[1];
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned short uw[1];
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} reg16_t;
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef union {
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char sb[4];
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned char ub[4];
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  short sw[2];
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned short uw[2];
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long int sd[1];
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned long int ud[1];
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  float ps[1];
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} reg32_t;
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef union {
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char sb[8];
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned char ub[8];
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  short sw[4];
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned short uw[4];
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long int sd[2];
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned long int ud[2];
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long long int sq[1];
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned long long int uq[1];
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  float ps[2];
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  double pd[1];
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} reg64_t __attribute__ ((aligned (8)));
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef union {
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char sb[16];
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned char ub[16];
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  short sw[8];
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned short uw[8];
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long int sd[4];
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned long int ud[4];
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long long int sq[2];
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned long long int uq[2];
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  float ps[4];
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  double pd[2];
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} reg128_t __attribute__ ((aligned (16)));
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic sigjmp_buf catchpoint;
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handle_sigill(int signum)
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   siglongjmp(catchpoint, 1);
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int eq_float(float f1, float f2)
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return f1 == f2 || fabsf(f1 - f2) < fabsf(f1) * 1.5 * pow(2,-12);
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int eq_double(double d1, double d2)
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return d1 == d2 || fabs(d1 - d2) < fabs(d1) * 1.5 * pow(2,-12);
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEOF
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %tests;
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @tests;
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownwhile (<>)
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    next if /^#/;
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $insn;
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $presets;
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $args;
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $results;
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (/^(\S+)\s+(?:(\S+(?:\s+\S+)*)\s+:\s+)?((?:\S+\s+)*?)(?:=>\s+(\S+(?:\s+\S+)*))?$/)
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $insn = $1;
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $presets = $2 || "";
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $args = $3 || "";
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $results = $4 || "";
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#        print STDERR "insn: $insn\n";
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#        print STDERR "presets: $presets\n";
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#        print STDERR "args: $args\n";
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#        print STDERR "results: $results\n";
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    else
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        die "Can't parse test $_";
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $tests{$insn}++;
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $test = "${insn}_$tests{$insn}";
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    push @tests, $test;
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|static void $test(void)\n|;
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\{\n|;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @intregs = @IntRegs;
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @mmregs  = map { "mm$_" }  (6,7,0,1,2,3,4,5);
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @xmmregs = map { "xmm$_" } (4,5,0,1,2,3,6,7);
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @fpregs  = map { "st$_" }  (0 .. 7);
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @presets;
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $presetc = 0;
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $eflagsmask;
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $eflagsset;
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $fpucwmask;
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $fpucwset;
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $fpuswmask;
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $fpuswset;
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $preset (split(/\s+/, $presets))
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($preset =~ /^([abcd][lh]|[abcd]x|e[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $name = "preset$presetc";
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $RegTypes{$1};
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $regnum = $RegNums{$1};
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $intregs[$regnum];
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Register $1 already used" unless defined($register);
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $preset = {
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype,
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                register => $register
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            delete($intregs[$regnum]);
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @presets, $preset;
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $valuec = 0;
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            foreach my $value (@values)
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|,| if $valuec > 0;
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq| $value$SubTypeSuffixes{$subtype}|;
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valuec++;
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq| \} \};\n|;
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $presetc++;
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($preset =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $name = "preset$presetc";
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = "st";
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $regnum = $1;
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $fpregs[$regnum];
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Register st$1 already used" unless defined($register);
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $preset = {
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype,
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                register => $register
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            delete($fpregs[$regnum]);
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @presets, $preset;
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $valuec = 0;
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            foreach my $value (@values)
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|,| if $valuec > 0;
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq| $value$SubTypeSuffixes{$subtype}|;
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valuec++;
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq| \} \};\n|;
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $presetc++;
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($preset =~ /^(eflags)\[([^\]]+)\]$/)
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $1;
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $2);
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $eflagsmask = sprintf "0x%08x", $values[0] ^ 0xffffffff;
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $eflagsset = sprintf "0x%08x", $values[1];
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($preset =~ /^(fpucw)\[([^\]]+)\]$/)
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $1;
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $2);
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpucwmask = sprintf "0x%04x", $values[0] ^ 0xffff;
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpucwset = sprintf "0x%04x", $values[1];
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($preset =~ /^(fpusw)\[([^\]]+)\]$/)
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $1;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $2);
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpuswmask = sprintf "0x%04x", $values[0] ^ 0xffff;
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpuswset = sprintf "0x%04x", $values[1];
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Can't parse preset $preset";
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @args;
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $argc = 0;
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (split(/\s+/, $args))
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        my $name = "arg$argc";
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg =~ /^([abcd]l|[abcd]x|e[abcd]x|r8|r16|r32|mm|xmm|m8|m16|m32|m64|m128)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $RegTypes{$1} || $1;
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $regnum = $RegNums{$1};
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $intregs[$regnum] if defined($regnum);
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Register $1 already used" if defined($regnum) && !defined($register);
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $arg = {
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (defined($register))
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $arg->{register} = $register;
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                delete($intregs[$regnum]);
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @args, $arg;
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $valuec = 0;
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            foreach my $value (@values)
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|,| if $valuec > 0;
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq| $value$SubTypeSuffixes{$subtype}|;
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valuec++;
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq| \} \};\n|;
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = "st";
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $regnum = $1;
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $fpregs[$regnum] if defined($regnum);
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Register st$1 already used" if defined($regnum) && !defined($register);
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $arg = {
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (defined($register))
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $arg->{register} = $register;
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                delete($fpregs[$regnum]);
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @args, $arg;
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $valuec = 0;
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            foreach my $value (@values)
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|,| if $valuec > 0;
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq| $value$SubTypeSuffixes{$subtype}|;
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valuec++;
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq| \} \};\n|;
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg =~ /^(imm8|imm16|imm32)\[([^\]]+)\]$/)
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $1;
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $value = $2;
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $arg = {
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                value => $value
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @args, $arg;
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Can't parse argument $arg";
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $argc++;
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@presets, @args)
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg->{type} =~ /^(r8|r16|r32|m8|m16|m32)$/)
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            while (!exists($arg->{register}) || !defined($arg->{register}))
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $arg->{register} = shift @intregs;
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $arg->{register} = $arg->{register}->{$arg->{type}};
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^(mm|m64)$/)
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $arg->{register} = shift @mmregs;
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^(xmm|m128)$/)
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $arg->{register} = shift @xmmregs;
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^st$/)
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            while (!exists($arg->{register}) || !defined($arg->{register}))
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $arg->{register} = shift @fpregs;
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @results;
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $resultc = 0;
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $result (split(/\s+/, $results))
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        my $name = "result$resultc";
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($result =~ /^(\d+)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $index = $1;
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $args[$index]->{type};
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Argument $index not specified" unless exists($args[$index]);
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype,
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                arg => $args[$index],
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                register => $args[$index]->{register},
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ @values ]
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name|;
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq| = arg$index| if $type =~ /^m(8|16|32|64|128)$/;
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|;\n|;
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $args[$index]->{result} = $result;
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result =~ /^([abcd][lh]|[abcd]x|e[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $1;
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $RegTypes{$register};
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype,
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                register => $register,
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ @values ]
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name;\n|;
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result =~ /^(st[0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $1;
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = "st";
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $2;
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $3);
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => $type,
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => $subtype,
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                register => $register,
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ @values ]
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{$type} $name;\n|;
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result =~ /^eflags\[([^\]]+)\]$/)
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $1);
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => "eflags",
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => "ud",
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ map { sprintf "0x%08x", $_ } @values ]
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{eflags} $name;\n|;
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (!defined($eflagsmask) && !defined($eflagsset))
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $eflagsmask = sprintf "0x%08x", $values[0] ^ 0xffffffff;
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $eflagsset = sprintf "0x%08x", $values[0] & ~$values[1];
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result =~ /^fpucw\[([^\]]+)\]$/)
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $1);
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => "fpucw",
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => "ud",
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ map { sprintf "0x%04x", $_ } @values ]
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{fpucw} $name;\n|;
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (!defined($fpucwmask) && !defined($fpucwset))
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $fpucwmask = sprintf "0x%04x", $values[0] ^ 0xffff;
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $fpucwset = sprintf "0x%04x", $values[0] & ~$values[1];
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result =~ /^fpusw\[([^\]]+)\]$/)
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = split(/,/, $1);
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[0] = oct($values[0]) if $values[0] =~ /^0/;
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $values[1] = oct($values[1]) if $values[1] =~ /^0/;
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $result = {
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                name => $name,
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                type => "fpusw",
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                subtype => "ud",
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                values => [ map { sprintf "0x%04x", $_ } @values ]
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            };
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push @results, $result;
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|   $ArgTypes{fpusw} $name;\n|;
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (!defined($fpuswmask) && !defined($fpuswset))
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $fpuswmask = sprintf "0x%04x", $values[0] ^ 0xffff;
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $fpuswset = sprintf "0x%04x", $values[0] & ~$values[1];
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Can't parse result $result";
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $resultc++;
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $argnum = 0;
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $result (@results)
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        if ($result->{type} eq "xmm")
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        {
610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $result->{argnuml} = $argnum++;
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $result->{argnumh} = $argnum++;
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        }
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        else
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $result->{argnum} = $argnum++;
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@presets, @args)
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (defined($arg->{name}))
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if ($arg->{type} eq "xmm")
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            {
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                $arg->{argnuml} = $argnum++;
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                $arg->{argnumh} = $argnum++;
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            {
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                $arg->{argnum} = $argnum++;
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $stateargnum = $argnum++;
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   char state\[108\];\n|;
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   if (sigsetjmp(catchpoint, 1) == 0)\n|;
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   \{\n|;
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|      asm\(\n|;
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|         \"fsave %$stateargnum\\n\"\n|;
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @fpargs;
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@presets, @args)
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg->{type} eq "r8")
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movb %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} eq "r16")
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movw %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} eq "r32")
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movl %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} eq "mm")
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movq %$arg->{argnum}, %%$arg->{register}\\n\"\n|;
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} eq "xmm")
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            print qq|         \"movlps %$arg->{argnuml}, %%$arg->{register}\\n\"\n|;
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            print qq|         \"movhps %$arg->{argnumh}, %%$arg->{register}\\n\"\n|;
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} eq "st")
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpargs[$RegNums{$arg->{register}}] = $arg;
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (reverse @fpargs)
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (defined($arg))
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ($arg->{subtype} eq "ps")
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         \"flds %$arg->{argnum}\\n\"\n|;
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            elsif ($arg->{subtype} eq "pd")
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         \"fldl %$arg->{argnum}\\n\"\n|;
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"fldz\\n\"\n|;
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined($eflagsmask) || defined($eflagsset))
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"pushfl\\n\"\n|;
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"andl \$$eflagsmask, (%%esp)\\n\"\n| if defined($eflagsmask);
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"orl \$$eflagsset, (%%esp)\\n\"\n| if defined($eflagsset);
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"popfl\\n\"\n|;
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined($fpucwmask) || defined($fpucwset))
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"subl \$2, %%esp\\n\"\n|;
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"fstcw (%%esp)\\n\"\n|;
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"andw \$$fpucwmask, (%%esp)\\n\"\n| if defined($fpucwmask);
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"orw \$$fpucwset, (%%esp)\\n\"\n| if defined($fpucwset);
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"fldcw (%%esp)\\n\"\n|;
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         \"addl \$2, %%esp\\n\"\n|;
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|         \"$insn|;
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $prefix = " ";
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@args)
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        next if $arg->{type} eq "eflags";
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg->{type} =~ /^(r8|r16|r32|mm|xmm)$/)
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|$prefix%%$arg->{register}|;
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^st$/)
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $register = $arg->{register};
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $register =~ s/st(\d+)/st\($1\)/;
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|$prefix%%$register|;
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^(m(8|16|32|64|128))$/)
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (exists($arg->{result}))
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|$prefix%$arg->{result}->{argnum}|;
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|$prefix%$arg->{argnum}|;
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($arg->{type} =~ /^imm(8|16|32)$/)
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|$prefix\$$arg->{value}|;
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $prefix = ", ";
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\\n\"\n|;
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @fpresults;
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $result (@results)
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($result->{type} eq "r8")
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movb %%$result->{register}, %$result->{argnum}\\n\"\n|;
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "r16")
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movw %%$result->{register}, %$result->{argnum}\\n\"\n|;
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "r32")
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movl %%$result->{register}, %$result->{argnum}\\n\"\n|;
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "mm")
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"movq %%$result->{register}, %$result->{argnum}\\n\"\n|;
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "xmm")
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            print qq|         \"movlps %%$result->{register}, %$result->{argnuml}\\n\"\n|;
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            print qq|         \"movhps %%$result->{register}, %$result->{argnumh}\\n\"\n|;
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "st")
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $fpresults[$RegNums{$result->{register}}] = $result;
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "eflags")
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"pushfl\\n\"\n|;
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"popl %$result->{argnum}\\n\"\n|;
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "fpucw")
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"fstcw %$result->{argnum}\\n\"\n|;
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        elsif ($result->{type} eq "fpusw")
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"fstsw %$result->{argnum}\\n\"\n|;
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $result (@fpresults)
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (defined($result))
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ($result->{subtype} eq "ps")
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         \"fstps %$result->{argnum}\\n\"\n|;
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            elsif ($result->{subtype} eq "pd")
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         \"fstpl %$result->{argnum}\\n\"\n|;
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|         \"fincstp\\n\"\n|;
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|         \"frstor %$stateargnum\\n\"\n|;
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|         \"cld\\n\"\n|;
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|         :|;
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $prefix = " ";
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $result (@results)
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        if ($result->{type} eq "xmm")
826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        {
827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            print qq|$prefix\"=m\" \($result->{name}.uq[0]\), \"=m\" \($result->{name}.uq[1]\)|;
828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        }
829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        else
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|$prefix\"=m\" \($result->{name}\)|;
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
833b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        $prefix = ", ";
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $prefix = "         : ";
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@presets, @args)
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (defined($arg->{name}))
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if ($arg->{type} eq "xmm")
846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            {
847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                print qq|$prefix\"m\" \($arg->{name}.uq[0]\), \"m\" \($arg->{name}.uq[1]\)|;
848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else
850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            {
851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                print qq|$prefix\"m\" \($arg->{name}\)|;
852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prefix = ", ";
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|$prefix\"m\" \(state[0]\)\n|;
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $prefix = "         : ";
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $arg (@presets, @args)
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg->{register} && $arg->{type} ne "st")
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print qq|$prefix\"$arg->{register}\"|;
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prefix = ", ";
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|      \);\n|;
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (@results)
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      if \(|;
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $prefix = "";
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        foreach my $result (@results)
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $result->{type};
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $result->{subtype};
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $suffix = $SubTypeSuffixes{$subtype};
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = @{$result->{values}};
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ($type eq "eflags")
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|${prefix}\($result->{name}.ud[0] & $values[0]UL\) == $values[1]UL|;
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            elsif ($type =~ /^fpu[cs]w$/)
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|${prefix}\($result->{name}.uw[0] & $values[0]\) == $values[1]|;
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                foreach my $value (0 .. $#values)
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                {
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    if ($subtype eq "ps")
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    {
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        print qq|${prefix}eq_float($result->{name}.$subtype\[$value\], $values[$value]$suffix)|;
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    }
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    elsif ($subtype eq "pd")
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    {
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        print qq|${prefix}eq_double($result->{name}.$subtype\[$value\], $values[$value]$suffix)|;
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    }
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    else
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    {
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        print qq|${prefix}$result->{name}.$subtype\[$value\] == $values[$value]$suffix|;
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    }
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    $prefix = " && ";
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                }
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prefix = " &&\n          ";
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq| \)\n|;
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      \{\n|;
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         printf("$test ... ok\\n");\n|;
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      \}\n|;
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      else\n|;
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      \{\n|;
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|         printf("$test ... not ok\\n");\n|;
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        foreach my $result (@results)
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        {
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $type = $result->{type};
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $subtype = $result->{subtype};
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $suffix = $SubTypeSuffixes{$subtype};
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my @values = @{$result->{values}};
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ($type eq "eflags")
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         printf("  eflags & 0x%lx = 0x%lx (expected 0x%lx)\\n", $values[0]UL, $result->{name}.ud\[0\] & $values[0]UL, $values[1]UL);\n|;
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            elsif ($type =~ /^fpu[cs]w$/)
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                print qq|         printf("  $type & 0x%x = 0x%x (expected 0x%x)\\n", $values[0], $result->{name}.uw\[0\] & $values[0], $values[1]);\n|;
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            {
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                foreach my $value (0 .. $#values)
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                {
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    print qq|         printf("  $result->{name}.$subtype\[$value\] = $SubTypeFormats{$subtype} (expected $SubTypeFormats{$subtype})\\n", $result->{name}.$subtype\[$value\], $values[$value]$suffix);\n|;
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                }
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      \}\n|;
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    else
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print qq|      printf("$test ... ok\\n");\n|;
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   \}\n|;
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   else\n|;
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   \{\n|;
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|      printf("$test ... failed\\n");\n|;
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   \}\n|;
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   return;\n|;
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\}\n|;
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|\n|;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|int main(int argc, char **argv)\n|;
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|\{\n|;
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|   signal(SIGILL, handle_sigill);\n|;
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|\n|;
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownforeach my $test (@tests)
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print qq|   $test();\n|;
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|\n|;
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|   exit(0);\n|;
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint qq|\}\n|;
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownexit 0;
986