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