File Coverage

blib/lib/Asm/X86.pm
Criterion Covered Total %
statement 932 937 99.4
branch 875 906 96.5
condition 909 993 91.5
subroutine 74 74 100.0
pod 55 55 100.0
total 2845 2965 95.9


line stmt bran cond sub pod time code
1             package Asm::X86;
2              
3 10     10   630748 use warnings;
  10         91  
  10         1193  
4             require Exporter;
5              
6             @ISA = (Exporter);
7             @EXPORT = qw();
8             @EXPORT_OK = qw(
9             @regs8_intel @regs16_intel @segregs_intel @regs32_intel @regs64_intel @regs_mm_intel
10             @regs_intel @regs_fpu_intel @regs_opmask_intel
11             @regs8_att @regs16_att @segregs_att @regs32_att @regs64_att @regs_mm_att
12             @regs_att @regs_fpu_att @regs_opmask_att
13              
14             @instr_intel @instr_att @instr
15              
16             is_reg_intel is_reg8_intel is_reg16_intel is_reg32_intel
17             is_reg64_intel is_reg_mm_intel is_segreg_intel is_reg_fpu_intel
18             is_reg_opmask_intel
19             is_reg_att is_reg8_att is_reg16_att is_reg32_att
20             is_reg64_att is_reg_mm_att is_segreg_att is_reg_fpu_att
21             is_reg_opmask_att
22             is_reg is_reg8 is_reg16 is_reg32 is_reg64 is_reg_mm is_segreg is_reg_fpu
23             is_reg_opmask
24              
25             is_instr_intel is_instr_att is_instr
26              
27             is_valid_16bit_addr_intel is_valid_32bit_addr_intel is_valid_64bit_addr_intel is_valid_addr_intel
28             is_valid_16bit_addr_att is_valid_32bit_addr_att is_valid_64bit_addr_att is_valid_addr_att
29             is_valid_16bit_addr is_valid_32bit_addr is_valid_64bit_addr is_valid_addr
30              
31             conv_att_addr_to_intel conv_intel_addr_to_att
32             conv_att_instr_to_intel conv_intel_instr_to_att
33              
34             is_addressable32_intel is_addressable32_att is_addressable32
35             is_r32_in64_intel is_r32_in64_att is_r32_in64
36             is_att_suffixed_instr is_att_suffixed_instr_fpu add_att_suffix_instr
37             );
38              
39 10     10   68 use strict;
  10         14  
  10         352058  
40              
41             =head1 NAME
42              
43             Asm::X86 - List of instructions and registers of x86-compatible processors, validating and converting instructions and memory references.
44              
45             =head1 VERSION
46              
47             Version 0.61
48              
49             =cut
50              
51             our $VERSION = '0.61';
52              
53             =head1 DESCRIPTION
54              
55             This module provides the user with the ability to check whether a given
56             string represents an x86 processor register or instruction. It also provides
57             lists of registers and instructions and allows to check if a given
58             expression is a valid addressing mode. Other subroutines include converting
59             between AT&T and Intel syntaxes.
60              
61             =head1 SYNOPSIS
62              
63             use Asm::X86 qw(@instr is_instr);
64              
65             print "YES" if is_instr ("MOV");
66              
67             =head1 EXPORT
68              
69             Nothing is exported by default.
70              
71             The following functions are exported on request:
72             is_reg_intel
73             is_reg8_intel
74             is_reg16_intel
75             is_reg32_intel
76             is_reg64_intel
77             is_reg_mm_intel
78             is_segreg_intel
79             is_reg_fpu_intel
80             is_reg_opmask_intel
81             is_addressable32_intel
82             is_r32_in64_intel
83              
84             is_reg_att
85             is_reg8_att
86             is_reg16_att
87             is_reg32_att
88             is_reg64_att
89             is_reg_mm_att
90             is_segreg_att
91             is_reg_fpu_att
92             is_reg_opmask_att
93             is_addressable32_att
94             is_r32_in64_att
95              
96             is_reg
97             is_reg8
98             is_reg16
99             is_reg32
100             is_reg64
101             is_reg_mm
102             is_segreg
103             is_reg_fpu
104             is_reg_opmask
105             is_addressable32
106             is_r32_in64
107              
108             is_instr_intel
109             is_instr_att
110             is_instr
111              
112             is_valid_16bit_addr_intel
113             is_valid_32bit_addr_intel
114             is_valid_64bit_addr_intel
115             is_valid_addr_intel
116              
117             is_valid_16bit_addr_att
118             is_valid_32bit_addr_att
119             is_valid_64bit_addr_att
120             is_valid_addr_att
121              
122             is_valid_16bit_addr
123             is_valid_32bit_addr
124             is_valid_64bit_addr
125             is_valid_addr
126              
127             conv_att_addr_to_intel
128             conv_att_instr_to_intel
129             conv_intel_addr_to_att
130             conv_intel_instr_to_att
131              
132             is_att_suffixed_instr
133             is_att_suffixed_instr_fpu
134             add_att_suffix_instr
135              
136             These check if the given string parameter belongs to the specified
137             class of registers or instructions or is a vaild addressing mode.
138             The "convert*" functions can be used to convert the given instruction
139             (including the operands)/addressing mode between AT&T and Intel syntaxes.
140             The "_intel" and "_att" suffixes mean the Intel and AT&T syntaxes,
141             respectively.
142             No suffix means either Intel or AT&T.
143             All subroutines work best given input after any pre-processing, i.e. after
144             all macros, constants, etc. have been replaced by the real values.
145              
146             The following arrays are exported on request:
147             @regs8_intel
148             @regs16_intel
149             @segregs_intel
150             @regs32_intel
151             @regs64_intel
152             @regs_mm_intel
153             @regs_fpu_intel
154             @regs_opmask_intel
155             @regs_intel
156              
157             @regs8_att
158             @regs16_att
159             @segregs_att
160             @regs32_att
161             @regs64_att
162             @regs_mm_att
163             @regs_fpu_att
164             @regs_opmask_att
165             @regs_att
166              
167             @instr_intel
168             @instr_att
169             @instr
170              
171             These contain all register and instruction mnemonic names as lower-case strings.
172             The "_intel" and "_att" suffixes mean the Intel and AT&T syntaxes, respectively.
173             No suffix means either Intel or AT&T.
174              
175             =head1 DATA
176              
177             =cut
178              
179             # =head2 _add_percent
180             #
181             # PRIVATE SUBROUTINE.
182             # Add a percent character ('%') in front of each element in the array given as a parameter.
183             # Returns the new array.
184             #
185             # =cut
186              
187             sub _add_percent(@) {
188              
189 100     100   307 my @result = ();
190 100         154 foreach (@_) {
191 2440         3251 push @result, "%$_";
192             }
193 100         522 return @result;
194             }
195              
196             # =head2 _remove_duplicates
197             #
198             # PRIVATE SUBROUTINE.
199             # Returns an array of the provided arguments with duplicate entries removed.
200             #
201             # =cut
202             #
203             sub _remove_duplicates(@) {
204              
205             # Use a hash to remove the duplicates:
206 36     36   81 my %new_hash;
207 36         83 foreach (@_) {
208 75597         101316 $new_hash{$_} = 1;
209             }
210 36         12108 return keys %new_hash;
211             }
212              
213             # =head2 _nopluses
214             #
215             # PRIVATE SUBROUTINE.
216             # Removes unnecessary '+' characters from the beginning of the given string.
217             # Returns the resulting string (or '+' if it was empty).
218             #
219             # =cut
220             #
221             sub _nopluses($) {
222              
223 669     669   951 my $elem = shift;
224 669         1703 $elem =~ s/^\s*\++//o;
225 669 100       1640 $elem = '+' if $elem eq '';
226 669         1358 return $elem;
227             }
228              
229             # =head2 _is_in_array
230             #
231             # PRIVATE SUBROUTINE.
232             # Checks if the given element (1st parameter) is a simple word and is present
233             # in the array (passed by reference as the 2nd parameter),
234             # case-insensitive.
235             # Returns 1 if yes.
236             #
237             # =cut
238             #
239             sub _is_in_array($@) {
240              
241 2050146     2050146   3135374 my $elem = shift;
242 2050146         2363663 my $arr = shift;
243 2050146 100       5289427 return 0 unless $elem =~ /^\w+$/o;
244 2043576         3305294 foreach (@$arr) {
245 113068448 100       267333679 return 1 if /^$elem$/i;
246             }
247 837668         3305641 return 0;
248             }
249              
250             # =head2 _is_in_array_att
251             #
252             # PRIVATE SUBROUTINE.
253             # Checks if the given element (1st parameter) is a simple word beginning
254             # with '%' and is present in the array (passed by reference as the 2nd
255             # parameter), case-insensitive.
256             # Returns 1 if yes.
257             #
258             # =cut
259             #
260             sub _is_in_array_att($@) {
261              
262 44011     44011   62665 my $elem = shift;
263 44011         52871 my $arr = shift;
264 44011 100       161124 return 0 unless $elem =~ /^\%\w+$/o;
265 31154         57192 foreach (@$arr) {
266 746286 100       1905733 return 1 if /^$elem$/i;
267             }
268 15283         72160 return 0;
269             }
270              
271              
272             sub add_att_suffix_instr(@);
273              
274             =head2 @regs8_intel
275              
276             A list of 8-bit registers (as strings) in Intel syntax.
277              
278             =cut
279              
280             our @regs8_intel = (
281             'al', 'bl', 'cl', 'dl', 'r8b', 'r9b', 'r10b', 'r11b',
282             'r12b', 'r13b', 'r14b', 'r15b', 'sil', 'dil', 'spl', 'bpl',
283             'ah', 'bh', 'ch', 'dh'
284             );
285              
286             =head2 @regs8_att
287              
288             A list of 8-bit registers (as strings) in AT&T syntax.
289              
290             =cut
291              
292             our @regs8_att = _add_percent @regs8_intel;
293              
294             =head2 @segregs_intel
295              
296             A list of segment registers (as strings) in Intel syntax.
297              
298             =cut
299              
300             our @segregs_intel = ( 'cs', 'ds', 'es', 'fs', 'gs', 'ss' );
301              
302             =head2 @segregs_att
303              
304             A list of segment registers (as strings) in AT&T syntax.
305              
306             =cut
307              
308             our @segregs_att = _add_percent @segregs_intel;
309              
310             =head2 @regs16_intel
311              
312             A list of 16-bit registers (as strings), including the segment registers, in Intel syntax.
313              
314             =cut
315              
316             our @regs16_intel = (
317             'ax', 'bx', 'cx', 'dx', 'r8w', 'r9w', 'r10w', 'r11w',
318             'r12w', 'r13w', 'r14w', 'r15w', 'si', 'di', 'sp', 'bp',
319             @segregs_intel
320             );
321              
322             =head2 @regs16_att
323              
324             A list of 16-bit registers (as strings), including the segment registers, in AT&T syntax.
325              
326             =cut
327              
328             our @regs16_att = _add_percent @regs16_intel;
329              
330             my @addressable32 = ('eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'esp', 'ebp');
331              
332             my @addressable32_att = _add_percent @addressable32;
333              
334             my @r32_in64 = (
335             'r8d', 'r8l', 'r9d', 'r9l', 'r10d', 'r10l', 'r11d', 'r11l',
336             'r12d', 'r12l', 'r13d', 'r13l', 'r14d', 'r14l', 'r15d', 'r15l',
337             );
338              
339             my @r32_in64_att = _add_percent @r32_in64;
340              
341             =head2 @regs32_intel
342              
343             A list of 32-bit registers (as strings) in Intel syntax.
344              
345             =cut
346              
347             our @regs32_intel = (
348             @addressable32,
349             'cr0', 'cr2', 'cr3', 'cr4', 'cr8',
350             'dr0', 'dr1', 'dr2', 'dr3', 'dr6', 'dr7',
351             @r32_in64
352             );
353              
354             =head2 @regs32_att
355              
356             A list of 32-bit registers (as strings) in AT&T syntax.
357              
358             =cut
359              
360             our @regs32_att = _add_percent @regs32_intel;
361              
362             =head2 @regs_fpu_intel
363              
364             A list of FPU registers (as strings) in Intel syntax.
365              
366             =cut
367              
368             our @regs_fpu_intel = ('st0', 'st1', 'st2', 'st3', 'st4', 'st5', 'st6', 'st7');
369              
370             =head2 @regs_fpu_att
371              
372             A list of FPU registers (as strings) in AT&T syntax.
373              
374             =cut
375              
376             our @regs_fpu_att = _add_percent @regs_fpu_intel;
377              
378             =head2 @regs64_intel
379              
380             A list of 64-bit registers (as strings) in Intel syntax.
381              
382             =cut
383              
384             our @regs64_intel = (
385             'rax', 'rbx', 'rcx', 'rdx', 'r8', 'r9', 'r10', 'r11',
386             'r12', 'r13', 'r14', 'r15', 'rsi', 'rdi', 'rsp', 'rbp', 'rip'
387             );
388              
389             =head2 @regs64_att
390              
391             A list of 64-bit registers (as strings) in AT&T syntax.
392              
393             =cut
394              
395             our @regs64_att = _add_percent @regs64_intel;
396              
397             =head2 @regs_mm_intel
398              
399             A list of multimedia (MMX/3DNow!/SSEn) registers (as strings) in Intel syntax.
400              
401             =cut
402              
403             our @regs_mm_intel = (
404             'mm0', 'mm1', 'mm2', 'mm3', 'mm4', 'mm5', 'mm6', 'mm7',
405             'xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5', 'xmm6', 'xmm7',
406             'xmm8', 'xmm9', 'xmm10', 'xmm11', 'xmm12', 'xmm13', 'xmm14', 'xmm15',
407             'xmm16', 'xmm17', 'xmm18', 'xmm19', 'xmm20', 'xmm21', 'xmm22', 'xmm23',
408             'xmm24', 'xmm25', 'xmm26', 'xmm27', 'xmm28', 'xmm29', 'xmm30', 'xmm31',
409             'ymm0', 'ymm1', 'ymm2', 'ymm3', 'ymm4', 'ymm5', 'ymm6', 'ymm7',
410             'ymm8', 'ymm9', 'ymm10', 'ymm11', 'ymm12', 'ymm13', 'ymm14', 'ymm15',
411             'ymm16', 'ymm17', 'ymm18', 'ymm19', 'ymm20', 'ymm21', 'ymm22', 'ymm23',
412             'ymm24', 'ymm25', 'ymm26', 'ymm27', 'ymm28', 'ymm29', 'ymm30', 'ymm31',
413             'zmm0', 'zmm1', 'zmm2', 'zmm3', 'zmm4', 'zmm5', 'zmm6', 'zmm7',
414             'zmm8', 'zmm9', 'zmm10', 'zmm11', 'zmm12', 'zmm13', 'zmm14', 'zmm15',
415             'zmm16', 'zmm17', 'zmm18', 'zmm19', 'zmm20', 'zmm21', 'zmm22', 'zmm23',
416             'zmm24', 'zmm25', 'zmm26', 'zmm27', 'zmm28', 'zmm29', 'zmm30', 'zmm31'
417             );
418              
419              
420             =head2 @regs_mm_att
421              
422             A list of multimedia (MMX/3DNow!/SSEn) registers (as strings) in AT&T syntax.
423              
424             =cut
425              
426             our @regs_mm_att = _add_percent @regs_mm_intel;
427              
428             =head2 @regs_opmask_intel
429              
430             A list of opmask registers (as strings) in Intel syntax.
431              
432             =cut
433              
434             our @regs_opmask_intel = ('k0', 'k1', 'k2', 'k3', 'k4', 'k5', 'k6', 'k7');
435              
436              
437             =head2 @regs_opmask_att
438              
439             A list of opmask registers (as strings) in AT&T syntax.
440              
441             =cut
442              
443             our @regs_opmask_att = _add_percent @regs_opmask_intel;
444              
445             =head2 @regs_intel
446              
447             A list of all x86 registers (as strings) in Intel syntax.
448              
449             =cut
450              
451             our @regs_intel = ( @regs8_intel, @regs16_intel, @regs32_intel,
452             @regs64_intel, @regs_mm_intel, @regs_fpu_intel,
453             @regs_opmask_intel );
454              
455             =head2 @regs_att
456              
457             A list of all x86 registers (as strings) in AT&T syntax.
458              
459             =cut
460              
461             our @regs_att = ( @regs8_att, @regs16_att, @regs32_att,
462             @regs64_att, @regs_mm_att, @regs_fpu_att,
463             @regs_opmask_att );
464              
465              
466             =head2 @instr_intel
467              
468             A list of all x86 instructions (as strings) in Intel syntax.
469              
470             =cut
471              
472             our @instr_intel = (
473             'aaa', 'aad', 'aam', 'aas', 'adc', 'adcx', 'add', 'addpd', 'addps', 'addsd', 'addss', 'addsubpd',
474             'addsubps', 'adox', 'aesdec', 'aesdeclast', 'aesenc', 'aesenclast', 'aesimc', 'aeskeygenassist',
475             'and', 'andn', 'andnpd', 'andnps', 'andpd', 'andps', 'arpl', 'bb0_reset',
476             'bb1_reset', 'bextr', 'blcfill', 'blci', 'blcic', 'blcmsk', 'blcs',
477             'blendpd', 'blendps', 'blendvpd', 'blendvps', 'blsfill', 'blsi', 'blsic', 'blsmsk', 'blsr',
478             'bnd', 'bndcl', 'bndcn', 'bndcu', 'bndldx', 'bndmk', 'bndmov', 'bndstx',
479             'bound', 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts', 'bzhi', 'call', 'cbw',
480             'cdq', 'cdqe', 'clac', 'clc', 'cld', 'cldemote', 'clflush', 'clflushopt',
481             'clgi', 'cli', 'clrssbsy','clts', 'clzero',
482             'clwb', 'cmc', 'cmova', 'cmovae', 'cmovb', 'cmovbe', 'cmovc', 'cmove', 'cmovg', 'cmovge',
483             'cmovl', 'cmovle', 'cmovna', 'cmovnae', 'cmovnb', 'cmovnbe', 'cmovnc',
484             'cmovne', 'cmovng', 'cmovnge', 'cmovnl', 'cmovnle', 'cmovno', 'cmovnp',
485             'cmovns', 'cmovnz', 'cmovo', 'cmovp', 'cmovpe', 'cmovpo', 'cmovs', 'cmovz',
486             'cmp', 'cmpeqpd', 'cmpeqps', 'cmpeqsd', 'cmpeqss', 'cmplepd', 'cmpleps', 'cmplesd', 'cmpless',
487             'cmpltpd', 'cmpltps', 'cmpltsd', 'cmpltss', 'cmpneqpd', 'cmpneqps', 'cmpneqsd', 'cmpneqss',
488             'cmpnlepd', 'cmpnleps', 'cmpnlesd', 'cmpnless', 'cmpnltpd', 'cmpnltps', 'cmpnltsd',
489             'cmpnltss', 'cmpordpd', 'cmpordps', 'cmpordsd', 'cmpordss', 'cmppd', 'cmpps', 'cmpsb',
490             'cmpsd', 'cmpsq', 'cmpss', 'cmpsw', 'cmpunordpd', 'cmpunordps', 'cmpunordsd', 'cmpunordss',
491             'cmpxchg', 'cmpxchg16b', 'cmpxchg486', 'cmpxchg8b', 'comeqpd', 'comeqps', 'comeqsd',
492             'comeqss', 'comfalsepd', 'comfalseps', 'comfalsesd', 'comfalsess', 'comisd', 'comiss',
493             'comlepd', 'comleps', 'comlesd', 'comless', 'comltpd', 'comltps', 'comltsd', 'comltss',
494             'comneqpd', 'comneqps', 'comneqsd', 'comneqss', 'comnlepd', 'comnleps', 'comnlesd', 'comnless',
495             'comnltpd', 'comnltps', 'comnltsd', 'comnltss', 'comordpd', 'comordps', 'comordsd',
496             'comordss', 'compd', 'comps', 'comsd', 'comss', 'comtruepd', 'comtrueps', 'comtruesd',
497             'comtruess', 'comueqpd', 'comueqps', 'comueqsd', 'comueqss', 'comulepd', 'comuleps', 'comulesd',
498             'comuless', 'comultpd', 'comultps', 'comultsd', 'comultss', 'comuneqpd', 'comuneqps', 'comuneqsd',
499             'comuneqss', 'comunlepd', 'comunleps', 'comunlesd', 'comunless', 'comunltpd', 'comunltps',
500             'comunltsd', 'comunltss', 'comunordpd', 'comunordps', 'comunordsd', 'comunordss', 'cpuid',
501             'cpu_read', 'cpu_write', 'cqo', 'crc32', 'cvtdq2pd', 'cvtdq2ps', 'cvtpd2dq', 'cvtpd2pi',
502             'cvtpd2ps', 'cvtph2ps', 'cvtpi2pd', 'cvtpi2ps', 'cvtps2dq', 'cvtps2pd', 'cvtps2ph',
503             'cvtps2pi', 'cvtsd2si', 'cvtsd2ss', 'cvtsi2sd', 'cvtsi2ss', 'cvtss2sd', 'cvtss2si', 'cvttpd2dq',
504             'cvttpd2pi', 'cvttps2dq', 'cvttps2pi', 'cvttsd2si', 'cvttss2si', 'cwd', 'cwde', 'daa', 'das',
505             'dec', 'div', 'divpd', 'divps', 'divsd', 'divss', 'dmint', 'dppd',
506             'dpps', 'emms', 'endbr32', 'endbr64', 'encls', 'enclu', 'enclv', 'enqcmd', 'enqcmds', 'enter',
507             'equ', 'extractps', 'extrq', 'f2xm1', 'fabs', 'fadd', 'faddp', 'fbld', 'fbstp', 'fchs', 'fclex',
508             'fcmovb', 'fcmovbe', 'fcmove', 'fcmovnb', 'fcmovnbe', 'fcmovne', 'fcmovnu', 'fcmovu', 'fcom',
509             'fcomi', 'fcomip', 'fcomp', 'fcompp', 'fcos', 'fdecstp', 'fdisi', 'fdiv', 'fdivp', 'fdivr',
510             'fdivrp', 'femms', 'feni', 'ffree', 'ffreep', 'fiadd', 'ficom', 'ficomp', 'fidiv', 'fidivr',
511             'fild', 'fimul', 'fincstp', 'finit', 'fist', 'fistp', 'fisttp', 'fisub', 'fisubr', 'fld',
512             'fld1', 'fldcw', 'fldenv', 'fldenvd', 'fldenvw', 'fldl2e', 'fldl2t', 'fldlg2', 'fldln2', 'fldpi', 'fldz', 'fmaddpd',
513             'fmaddps', 'fmaddsd', 'fmaddss', 'fmsubpd', 'fmsubps', 'fmsubsd', 'fmsubss', 'fmul', 'fmulp',
514             'fnclex', 'fndisi','fneni', 'fninit', 'fnmaddpd', 'fnmaddps', 'fnmaddsd', 'fnmaddss', 'fnmsubpd',
515             'fnmsubps', 'fnmsubsd', 'fnmsubss', 'fnop', 'fnsave', 'fnsaved', 'fnsavew', 'fnstcw',
516             'fnstenv', 'fnstenvd', 'fnstenvw', 'fnstsw', 'fpatan',
517             'fprem', 'fprem1', 'fptan', 'frczpd', 'frczps', 'frczsd', 'frczss', 'frndint',
518             'frstor', 'frstord', 'frstorw', 'frstpm', 'fsave', 'fsaved', 'fsavew',
519             'fscale', 'fsetpm', 'fsin', 'fsincos', 'fsqrt', 'fst', 'fstcw', 'fstenv', 'fstenvd', 'fstenvw', 'fstp', 'fstsw',
520             'fsub', 'fsubp', 'fsubr', 'fsubrp', 'ftst', 'fucom', 'fucomi', 'fucomip', 'fucomp', 'fucompp',
521             'fwait', 'fxam', 'fxch', 'fxrstor', 'fxrstor64', 'fxsave', 'fxsave64',
522             'fxtract', 'fyl2x', 'fyl2xp1', 'getsec', 'gf2p8affineinvqb', 'gf2p8affineqb', 'gf2p8mulb', 'haddpd',
523             'haddps', 'hint_nop0', 'hint_nop1', 'hint_nop10', 'hint_nop11', 'hint_nop12', 'hint_nop13',
524             'hint_nop14','hint_nop15', 'hint_nop16', 'hint_nop17', 'hint_nop18', 'hint_nop19', 'hint_nop2',
525             'hint_nop20', 'hint_nop21', 'hint_nop22', 'hint_nop23', 'hint_nop24', 'hint_nop25', 'hint_nop26',
526             'hint_nop27', 'hint_nop28', 'hint_nop29', 'hint_nop3', 'hint_nop30', 'hint_nop31', 'hint_nop32',
527             'hint_nop33', 'hint_nop34', 'hint_nop35', 'hint_nop36', 'hint_nop37', 'hint_nop38', 'hint_nop39',
528             'hint_nop4', 'hint_nop40', 'hint_nop41', 'hint_nop42', 'hint_nop43', 'hint_nop44', 'hint_nop45',
529             'hint_nop46', 'hint_nop47', 'hint_nop48', 'hint_nop49', 'hint_nop5', 'hint_nop50', 'hint_nop51',
530             'hint_nop52', 'hint_nop53', 'hint_nop54', 'hint_nop55', 'hint_nop56', 'hint_nop57', 'hint_nop58',
531             'hint_nop59', 'hint_nop6', 'hint_nop60', 'hint_nop61', 'hint_nop62', 'hint_nop63', 'hint_nop7',
532             'hint_nop8', 'hint_nop9', 'hlt', 'hsubpd', 'hsubps', 'ibts', 'icebp', 'idiv', 'imul', 'in',
533             'inc', 'incsspd', 'incsspq', 'incbin', 'insb', 'insd', 'insertps', 'insertq', 'insw', 'int', 'int01', 'int03',
534             'int1', 'int3', 'into', 'invd', 'invept', 'invlpg', 'invlpga', 'invlpgb', 'invpcid', 'invvpid', 'iret', 'iretd',
535             'iretq', 'iretw', 'ja', 'jae', 'jb', 'jbe', 'jc', 'jcxz', 'je', 'jecxz', 'jg', 'jge', 'jl',
536             'jle', 'jmp', 'jmpe', 'jna', 'jnae', 'jnb', 'jnbe', 'jnc', 'jne', 'jng', 'jnge', 'jnl',
537             'jnle', 'jno', 'jnp', 'jns', 'jnz', 'jo', 'jp', 'jpe', 'jpo', 'jrcxz', 'js', 'jz',
538             'kadd', 'kaddb', 'kaddd', 'kaddq', 'kaddw', 'kand', 'kandb', 'kandd', 'kandn', 'kandnb', 'kandnd', 'kandnq',
539             'kandnw', 'kandq', 'kandw', 'kmov', 'kmovb', 'kmovd', 'kmovq','kmovw', 'knot', 'knotb', 'knotd',
540             'knotq', 'knotw', 'kor', 'korb', 'kord', 'korq', 'kortest', 'kortestb', 'kortestd', 'kortestq','kortestw',
541             'korw', 'kshiftl', 'kshiftlb', 'kshiftld', 'kshiftlq','kshiftlw', 'kshiftr', 'kshiftrb', 'kshiftrd',
542             'kshiftrq', 'kshiftrw', 'ktest', 'ktestb', 'ktestd', 'ktestq', 'ktestw',
543             'kunpck', 'kunpckbw', 'kunpckdq', 'kunpckwd', 'kxnor', 'kxnorb', 'kxnord', 'kxnorq', 'kxnorw',
544             'kxor', 'kxorb', 'kxord', 'kxorq', 'kxorw',
545             'lahf', 'lar', 'lddqu', 'ldmxcsr', 'lds', 'ldtilecfg', 'lea', 'leave', 'les', 'lfence', 'lfs', 'lgdt',
546             'lgs', 'lidt', 'lldt', 'llwpcb', 'lmsw', 'loadall', 'loadall286', 'loadall386', 'lock', 'lodsb', 'lodsd',
547             'lodsq', 'lodsw', 'loop', 'loopd', 'loope', 'looped', 'loopeq', 'loopew', 'loopne', 'loopned',
548             'loopneq', 'loopnew', 'loopnz', 'loopnzd', 'loopnzq', 'loopnzw', 'loopq', 'loopw', 'loopz',
549             'loopzd', 'loopzq', 'loopzw', 'lsl', 'lss', 'ltr', 'lwpins', 'lwpval', 'lzcnt', 'maskmovdqu',
550             'maskmovq', 'maxpd', 'maxps', 'maxsd', 'maxss', 'mcommit', 'mfence', 'minpd', 'minps', 'minsd',
551             'minss', 'monitor', 'monitorx', 'montmul', 'mov', 'movapd',
552             'movaps', 'movbe', 'movd', 'movddup', 'movdir64b', 'movdiri', 'movdq2q',
553             'movdqa', 'movdqu', 'movhlps', 'movhpd', 'movhps', 'movlhps', 'movlpd', 'movlps', 'movmskpd',
554             'movmskps', 'movntdq', 'movntdqa', 'movnti', 'movntpd', 'movntps', 'movntq', 'movntsd',
555             'movntss', 'movq', 'movq2dq', 'movsb', 'movsd', 'movshdup', 'movsldup', 'movsq', 'movss',
556             'movsw', 'movsx', 'movsxd', 'movupd', 'movups', 'movzx', 'mpsadbw', 'mul', 'mulpd', 'mulps',
557             'mulsd', 'mulss', 'mulx', 'mwait', 'mwaitx', 'neg',
558             'nop', 'not', 'or', 'orpd', 'orps', 'out', 'outsb', 'outsd',
559             'outsw', 'pabsb', 'pabsd', 'pabsw', 'packssdw', 'packsswb', 'packusdw', 'packuswb', 'paddb',
560             'paddd', 'paddq', 'paddsb', 'paddsiw', 'paddsw', 'paddusb', 'paddusw', 'paddw', 'palignr',
561             'pand', 'pandn', 'pause', 'paveb', 'pavgb', 'pavgusb', 'pavgw', 'pblendvb', 'pblendw',
562             'pclmulhqhqdq', 'pclmulhqhdq', 'pclmulhqlqdq', 'pclmullqhqdq', 'pclmullqhdq', 'pclmullqlqdq', 'pclmulqdq', 'pcmov',
563             'pcmpeqb', 'pcmpeqd', 'pcmpeqq', 'pcmpeqw', 'pcmpestri', 'pcmpestrm', 'pcmpgtb', 'pcmpgtd',
564             'pcmpgtq', 'pcmpgtw', 'pcmpistri', 'pcmpistrm', 'pcomb', 'pcomd', 'pcomeqb', 'pcomeqd',
565             'pcomeqq', 'pcomequb', 'pcomequd', 'pcomequq', 'pcomequw', 'pcomeqw', 'pcomfalseb',
566             'pcomfalsed', 'pcomfalseq', 'pcomfalseub', 'pcomfalseud', 'pcomfalseuq', 'pcomfalseuw',
567             'pcomfalsew', 'pcomgeb', 'pcomged', 'pcomgeq', 'pcomgeub', 'pcomgeud', 'pcomgeuq', 'pcomgeuw',
568             'pcomgew', 'pcomgtb', 'pcomgtd', 'pcomgtq', 'pcomgtub', 'pcomgtud', 'pcomgtuq', 'pcomgtuw',
569             'pcomgtw', 'pcomleb', 'pcomled', 'pcomleq', 'pcomleub', 'pcomleud', 'pcomleuq', 'pcomleuw',
570             'pcomlew', 'pcomltb', 'pcomltd', 'pcomltq', 'pcomltub', 'pcomltud', 'pcomltuq', 'pcomltuw',
571             'pcomltw', 'pcommit', 'pcomneqb', 'pcomneqd', 'pcomneqq', 'pcomnequb', 'pcomnequd', 'pcomnequq',
572             'pcomnequw', 'pcomneqw', 'pcomq', 'pcomtrueb', 'pcomtrued', 'pcomtrueq', 'pcomtrueub',
573             'pcomtrueud', 'pcomtrueuq', 'pcomtrueuw', 'pcomtruew', 'pcomub', 'pcomud', 'pcomuq', 'pcomuw',
574             'pcomw', 'pconfig', 'pdep', 'pdistib', 'permpd', 'permps', 'pext', 'pextrb',
575             'pextrd', 'pextrq', 'pextrw', 'pf2id',
576             'pf2iw', 'pfacc', 'pfadd', 'pfcmpeq', 'pfcmpge', 'pfcmpgt', 'pfmax', 'pfmin', 'pfmul',
577             'pfnacc', 'pfpnacc', 'pfrcp', 'pfrcpit1', 'pfrcpit2', 'pfrcpv', 'pfrsqit1', 'pfrsqrt',
578             'pfrsqrtv', 'pfsub', 'pfsubr', 'phaddbd', 'phaddbq', 'phaddbw', 'phaddd', 'phadddq', 'phaddsw',
579             'phaddubd', 'phaddubq', 'phaddubw', 'phaddudq', 'phadduwd', 'phadduwq', 'phaddw', 'phaddwd',
580             'phaddwq', 'phminposuw', 'phsubbw', 'phsubd', 'phsubdq', 'phsubsw', 'phsubw', 'phsubwd',
581             'pi2fd', 'pi2fw', 'pinsrb', 'pinsrd', 'pinsrq', 'pinsrw', 'pmachriw', 'pmacsdd', 'pmacsdqh',
582             'pmacsdql', 'pmacssdd', 'pmacssdqh', 'pmacssdql', 'pmacsswd', 'pmacssww', 'pmacswd',
583             'pmacsww', 'pmadcsswd', 'pmadcswd', 'pmaddubsw', 'pmaddwd', 'pmagw', 'pmaxsb', 'pmaxsd',
584             'pmaxsw', 'pmaxub', 'pmaxud', 'pmaxuw', 'pminsb', 'pminsd', 'pminsw', 'pminub', 'pminud',
585             'pminuw', 'pmovmskb', 'pmovsxbd', 'pmovsxbq', 'pmovsxbw', 'pmovsxdq', 'pmovsxwd', 'pmovsxwq',
586             'pmovzxbd', 'pmovzxbq', 'pmovzxbw', 'pmovzxdq', 'pmovzxwd', 'pmovzxwq', 'pmuldq', 'pmulhriw',
587             'pmulhrsw', 'pmulhrwa', 'pmulhrw', 'pmulhrwc', 'pmulhuw', 'pmulhw', 'pmulld', 'pmullw', 'pmuludq',
588             'pmvgezb', 'pmvlzb', 'pmvnzb', 'pmvzb', 'pop', 'popd', 'popa', 'popad', 'popaw', 'popcnt', 'popf',
589             'popfd', 'popfq', 'popfw', 'popq', 'popw', 'por', 'pperm', 'prefetch', 'prefetchnta', 'prefetcht0',
590             'prefetcht1', 'prefetcht2', 'prefetchw', 'prefetchwt1', 'protb', 'protd', 'protq', 'protw', 'psadbw',
591             'pshab', 'pshad', 'pshaq', 'pshaw', 'pshlb', 'pshld', 'pshlq', 'pshlw', 'pshufb', 'pshufd',
592             'pshufhw', 'pshuflw', 'pshufw', 'psignb', 'psignd', 'psignw', 'pslld', 'pslldq', 'psllq',
593             'psllw', 'psmash', 'psrad', 'psraw', 'psrld', 'psrldq', 'psrlq', 'psrlw', 'psubb', 'psubd', 'psubq',
594             'psubsb', 'psubsiw', 'psubsw', 'psubusb', 'psubusw', 'psubw', 'pswapd', 'ptest', 'ptwrite', 'punpckhbw',
595             'punpckhdq', 'punpckhqdq', 'punpckhwd', 'punpcklbw', 'punpckldq', 'punpcklqdq', 'punpcklwd',
596             'push', 'pusha', 'pushad', 'pushaw', 'pushd', 'pushf', 'pushfd', 'pushfq', 'pushfw', 'pushq',
597             'pushw', 'pvalidate', 'pxor', 'rcl', 'rcpps', 'rcpss', 'rcr', 'rdfsbase', 'rdgsbase', 'rdm', 'rdmsr',
598             'rdmsrq', 'rdpid', 'rdpkru', 'rdpmc', 'rdpru', 'rdrand', 'rdseed', 'rdsspd', 'rdsspq', 'rdshr',
599             'rdtsc', 'rdtscp', 'rep', 'repe', 'repne', 'repnz',
600             'repz', 'ret', 'retd', 'retf', 'retfd', 'retfq', 'retfw', 'retn', 'retnd', 'retnq', 'retnw', 'retq', 'retw',
601             'rmpadjust', 'rmpupdate', 'rol', 'ror', 'rorx', 'roundpd', 'roundps', 'roundsd', 'roundss', 'rsdc', 'rsldt', 'rsm',
602             'rsqrtps', 'rsqrtss', 'rstorssp', 'rsts', 'sahf', 'sal', 'salc', 'sar',
603             'sarx', 'saveprevssp', 'sbb', 'scasb', 'scasd', 'scasq',
604             'scasw', 'serialize', 'seta', 'setae', 'setalc', 'setb', 'setbe', 'setc', 'sete', 'setg', 'setge', 'setl',
605             'setle', 'setna', 'setnae', 'setnb', 'setnbe', 'setnc', 'setne', 'setng', 'setnge',
606             'setnl', 'setnle', 'setno', 'setnp', 'setns', 'setnz', 'seto', 'setp', 'setpe', 'setpo',
607             'sets', 'setssbsy', 'setz', 'sfence', 'sgdt', 'sha1msg1',
608             'sha1msg2', 'sha1nexte', 'sha1rnds4', 'sha256msg1', 'sha256msg2', 'sha256rnds2',
609             'shl', 'shld', 'shlx', 'shr', 'shrd', 'shrx', 'shufpd', 'shufps', 'sidt',
610             'skinit', 'sldt', 'slwpcb', 'smi', 'smint', 'smintold', 'smsw', 'sqrtpd', 'sqrtps', 'sqrtsd',
611             'sqrtss', 'stac', 'stc', 'std', 'stgi', 'sti', 'stmxcsr', 'stosb', 'stosd', 'stosq', 'stosw',
612             'str', 'sttilecfg', 'sub',
613             'subpd', 'subps', 'subsd', 'subss', 'svdc', 'svldt', 'svts', 'swapgs', 'syscall', 'sysenter',
614             'sysexit', 'sysexitq', 'sysret', 'sysretq', 't1mskc', 'tdpbf16ps', 'tdpbssd', 'tdpbsud', 'tdpbusd', 'tdpbuud',
615             'test', 'tileloadd', 'tileloaddt1', 'tilerelease', 'tilestored', 'tilezero', 'tlbsync', 'tpause', 'tzcnt', 'tzmsk',
616             'ucomisd', 'ucomiss', 'ud0', 'ud1', 'ud2', 'ud2a', 'ud2b', 'umonitor', 'umov',
617             'umwait', 'unpckhpd', 'unpckhps', 'unpcklpd', 'unpcklps', 'useavx256', 'useavx512',
618             'v4dpwssd', 'v4dpwssds', 'v4fmaddps', 'v4fmaddss', 'v4fnmaddps', 'v4fnmaddss',
619             'vaddpd', 'vaddps', 'vaddsd', 'vaddss', 'vaddsubpd', 'vaddsubps', 'vaesdec',
620             'vaesdeclast', 'vaesenc', 'vaesenclast', 'vaesimc', 'vaeskeygenassist', 'valignd',
621             'valignq', 'vandnpd', 'vandnps', 'vandpd', 'vandps', 'vblendmpd',
622             'vblendmps', 'vblendpd', 'vblendps',
623             'vblendvpd', 'vblendvps', 'vbroadcastf128', 'vbroadcastf32x2', 'vbroadcastf32x4',
624             'vbroadcastf32x8', 'vbroadcastf64x2', 'vbroadcastf64x4', 'vbroadcasti128', 'vbroadcasti32x2',
625             'vbroadcasti32x4', 'vbroadcasti32x8', 'vbroadcasti64x2',
626             'vbroadcasti64x4', 'vbroadcastsd', 'vbroadcastss', 'vcmpeqpd',
627             'vcmpeqps', 'vcmpeqsd', 'vcmpeqss', 'vcmpeq_oqpd', 'vcmpeq_oqps', 'vcmpeq_oqsd', 'vcmpeq_oqss',
628             'vcmpeq_ospd', 'vcmpeq_osps', 'vcmpeq_ossd',
629             'vcmpeq_osss', 'vcmpeq_uqpd', 'vcmpeq_uqps',
630             'vcmpeq_uqsd', 'vcmpeq_uqss', 'vcmpeq_uspd',
631             'vcmpeq_usps', 'vcmpeq_ussd', 'vcmpeq_usss', 'vcmpfalsepd', 'vcmpfalseps', 'vcmpfalsesd',
632             'vcmpfalsess', 'vcmpfalse_oqpd', 'vcmpfalse_oqps', 'vcmpfalse_oqsd', 'vcmpfalse_oqss',
633             'vcmpfalse_ospd', 'vcmpfalse_osps', 'vcmpfalse_ossd', 'vcmpfalse_osss',
634             'vcmpgepd', 'vcmpgeps', 'vcmpgesd', 'vcmpgess', 'vcmpge_oqpd', 'vcmpge_oqps', 'vcmpge_oqsd',
635             'vcmpge_oqss', 'vcmpge_ospd', 'vcmpge_osps', 'vcmpge_ossd',
636             'vcmpge_osss', 'vcmpgtpd', 'vcmpgtps', 'vcmpgtsd', 'vcmpgtss', 'vcmpgt_oqpd', 'vcmpgt_oqps',
637             'vcmpgt_oqsd', 'vcmpgt_oqss', 'vcmpgt_ospd', 'vcmpgt_osps',
638             'vcmpgt_ossd', 'vcmpgt_osss', 'vpcmpleb', 'vcmplepd', 'vcmpleps', 'vcmplesd', 'vcmpless',
639             'vpcmpleub', 'vpcmpleuw', 'vpcmplew', 'vcmple_oqpd',
640             'vcmple_oqps', 'vcmple_oqsd', 'vcmple_oqss', 'vcmple_ospd',
641             'vcmple_osps', 'vcmple_ossd', 'vcmple_osss', 'vpcmpltb', 'vcmpltpd', 'vcmpltps', 'vcmpltsd',
642             'vcmpltss', 'vpcmpltub', 'vpcmpltuw', 'vpcmpltw',
643             'vcmplt_oqpd', 'vcmplt_oqps', 'vcmplt_oqsd', 'vcmplt_oqss',
644             'vcmplt_ospd', 'vcmplt_osps', 'vcmplt_ossd', 'vcmplt_osss', 'vpcmpneqb', 'vcmpneqpd', 'vcmpneqps',
645             'vcmpneqsd', 'vcmpneqss', 'vpcmpnequb', 'vpcmpnequw', 'vpcmpneqw', 'vcmpneq_oqpd',
646             'vcmpneq_oqps', 'vcmpneq_oqsd', 'vcmpneq_oqss',
647             'vcmpneq_ospd', 'vcmpneq_osps', 'vcmpneq_ossd', 'vcmpneq_osss',
648             'vcmpneq_uqpd', 'vcmpneq_uqps', 'vcmpneq_uqsd', 'vcmpneq_uqss', 'vcmpneq_uspd', 'vcmpneq_usps',
649             'vcmpneq_ussd', 'vcmpneq_usss', 'vcmpngepd', 'vcmpngeps', 'vcmpngesd', 'vcmpngess', 'vcmpnge_uqpd',
650             'vcmpnge_uqps', 'vcmpnge_uqsd', 'vcmpnge_uqss',
651             'vcmpnge_uspd', 'vcmpnge_usps', 'vcmpnge_ussd', 'vcmpnge_usss',
652             'vcmpngtpd', 'vcmpngtps', 'vcmpngtsd', 'vcmpngtss',
653             'vcmpngt_uqpd', 'vcmpngt_uqps', 'vcmpngt_uqsd', 'vcmpngt_uqss',
654             'vcmpngt_uspd', 'vcmpngt_usps', 'vcmpngt_ussd', 'vcmpngt_usss', 'vpcmpnleb', 'vcmpnlepd', 'vcmpnleps',
655             'vcmpnlesd', 'vcmpnless', 'vpcmpnleub', 'vpcmpnleuw', 'vpcmpnlew',
656             'vcmpnle_uqpd', 'vcmpnle_uqps', 'vcmpnle_uqsd', 'vcmpnle_uqss',
657             'vcmpnle_uspd', 'vcmpnle_usps', 'vcmpnle_ussd', 'vcmpnle_usss',
658             'vpcmpnltb', 'vcmpnltpd', 'vcmpnltps', 'vcmpnltsd', 'vcmpnltss', 'vpcmpnltub',
659             'vpcmpnltuw', 'vpcmpnltw', 'vcmpnlt_uqpd', 'vcmpnlt_uqps', 'vcmpnlt_uqsd',
660             'vcmpnlt_uqss', 'vcmpnlt_uspd', 'vcmpnlt_usps', 'vcmpnlt_ussd', 'vcmpnlt_usss',
661             'vcmpordpd', 'vcmpordps', 'vcmpordsd', 'vcmpordss', 'vcmpord_qpd', 'vcmpord_qps',
662             'vcmpord_qsd', 'vcmpord_qss', 'vcmpord_spd', 'vcmpord_sps',
663             'vcmpord_ssd', 'vcmpord_sss', 'vcmppd', 'vcmpps', 'vcmpsd', 'vcmpss', 'vcmptruepd', 'vcmptrueps',
664             'vcmptruesd', 'vcmptruess', 'vcmptrue_uqpd', 'vcmptrue_uqps', 'vcmptrue_uqsd', 'vcmptrue_uqss',
665             'vcmptrue_uspd', 'vcmptrue_usps', 'vcmptrue_ussd', 'vcmptrue_usss',
666             'vcmpunordpd', 'vcmpunordps', 'vcmpunordsd', 'vcmpunordss', 'vcmpunord_qpd', 'vcmpunord_qps',
667             'vcmpunord_qsd', 'vcmpunord_qss', 'vcmpunord_spd', 'vcmpunord_sps', 'vcmpunord_ssd',
668             'vcmpunord_sss', 'vcomisd', 'vcomiss', 'vcompresspd',
669             'vcompressps', 'vcvtdq2pd', 'vcvtdq2ps', 'vcvtpd2dq', 'vcvtne2ps2bf16',
670             'vcvtpd2ps', 'vcvtpd2qq', 'vcvtpd2udq', 'vcvtpd2uqq', 'vcvtph2ps', 'vcvtps2dq', 'vcvtps2pd', 'vcvtps2ph',
671             'vcvtps2qq', 'vcvtps2udq', 'vcvtps2uqq', 'vcvtqq2pd', 'vcvtqq2ps','vcvtsd2si', 'vcvtsd2ss', 'vcvtsd2usi',
672             'vcvtsi2sd', 'vcvtsi2ss', 'vcvtss2sd', 'vcvtss2si', 'vcvtss2usi', 'vcvttpd2dq',
673             'vcvttpd2qq', 'vcvttpd2udq', 'vcvttpd2uqq', 'vcvttps2dq', 'vcvttps2qq',
674             'vcvttps2uqq', 'vcvttps2udq', 'vcvttsd2si', 'vcvttsd2usi', 'vcvttss2si', 'vcvttss2usi',
675             'vcvtudq2pd', 'vcvtudq2ps', 'vcvtuqq2pd', 'vcvtuqq2ps','vcvtusi2sd', 'vcvtusi2ss', 'vdbpsadbw',
676             'vdivpd', 'vdivps', 'vdivsd', 'vdivss', 'vdpbf16ps', 'vdppd', 'vdpps', 'verr', 'verw', 'vexp2pd',
677             'vexp2ps', 'vexpandpd', 'vexpandps',
678             'vextractf128', 'vextractf32x4', 'vextractf32x8', 'vextractf64x2',
679             'vextractf64x4', 'vextracti128', 'vextracti32x4', 'vextracti32x8', 'vextracti64x2',
680             'vextracti64x4', 'vextractps', 'vfixupimmpd', 'vfixupimmps', 'vfixupimmsd', 'vfixupimmss',
681             'vfmadd123pd', 'vfmadd123ps', 'vfmadd123sd', 'vfmadd123ss',
682             'vfmadd132pd', 'vfmadd132ps', 'vfmadd132sd', 'vfmadd132ss', 'vfmadd213pd', 'vfmadd213ps',
683             'vfmadd213sd', 'vfmadd213ss', 'vfmadd231pd', 'vfmadd231ps', 'vfmadd231sd', 'vfmadd231ss',
684             'vfmadd312pd', 'vfmadd312ps', 'vfmadd312sd', 'vfmadd312ss', 'vfmadd321pd', 'vfmadd321ps',
685             'vfmadd321sd', 'vfmadd321ss', 'vfmaddpd', 'vfmaddps', 'vfmaddsd', 'vfmaddss', 'vfmaddsub123pd',
686             'vfmaddsub123ps', 'vfmaddsub132pd', 'vfmaddsub132ps', 'vfmaddsub213pd', 'vfmaddsub213ps',
687             'vfmaddsub231pd', 'vfmaddsub231ps', 'vfmaddsub312pd', 'vfmaddsub312ps', 'vfmaddsub321pd',
688             'vfmaddsub321ps', 'vfmaddsubpd', 'vfmaddsubps', 'vfmsub123pd', 'vfmsub123ps',
689             'vfmsub123sd', 'vfmsub123ss', 'vfmsub132pd', 'vfmsub132ps', 'vfmsub132sd',
690             'vfmsub132ss', 'vfmsub213pd', 'vfmsub213ps', 'vfmsub213sd', 'vfmsub213ss',
691             'vfmsub231pd', 'vfmsub231ps', 'vfmsub231sd', 'vfmsub231ss', 'vfmsub312pd',
692             'vfmsub312ps', 'vfmsub312sd', 'vfmsub312ss', 'vfmsub321pd', 'vfmsub321ps',
693             'vfmsub321sd', 'vfmsub321ss', 'vfmsubadd123pd', 'vfmsubadd123ps', 'vfmsubadd132pd',
694             'vfmsubadd132ps', 'vfmsubadd213pd', 'vfmsubadd213ps', 'vfmsubadd231pd', 'vfmsubadd231ps',
695             'vfmsubadd312pd', 'vfmsubadd312ps', 'vfmsubadd321pd', 'vfmsubadd321ps', 'vfmsubaddpd',
696             'vfmsubaddps', 'vfmsubpd', 'vfmsubps', 'vfmsubsd', 'vfmsubss', 'vfnmadd123pd', 'vfnmadd123ps',
697             'vfnmadd123sd', 'vfnmadd123ss', 'vfnmadd132pd', 'vfnmadd132ps', 'vfnmadd132sd', 'vfnmadd132ss',
698             'vfnmadd213pd', 'vfnmadd213ps', 'vfnmadd213sd', 'vfnmadd213ss', 'vfnmadd231pd',
699             'vfnmadd231ps', 'vfnmadd231sd', 'vfnmadd231ss', 'vfnmadd312pd', 'vfnmadd312ps',
700             'vfnmadd312sd', 'vfnmadd312ss', 'vfnmadd321pd', 'vfnmadd321ps', 'vfnmadd321sd',
701             'vfnmadd321ss', 'vfnmaddpd', 'vfnmaddps', 'vfnmaddsd', 'vfnmaddss', 'vfnmsub123pd',
702             'vfnmsub123ps', 'vfnmsub123sd', 'vfnmsub123ss', 'vfnmsub132pd', 'vfnmsub132ps',
703             'vfnmsub132sd', 'vfnmsub132ss', 'vfnmsub213pd', 'vfnmsub213ps', 'vfnmsub213sd',
704             'vfnmsub213ss', 'vfnmsub231pd', 'vfnmsub231ps', 'vfnmsub231sd', 'vfnmsub231ss',
705             'vfnmsub312pd', 'vfnmsub312ps', 'vfnmsub312sd', 'vfnmsub312ss', 'vfnmsub321pd',
706             'vfnmsub321ps', 'vfnmsub321sd', 'vfnmsub321ss', 'vfnmsubpd', 'vfnmsubps', 'vfnmsubsd',
707             'vfnmsubss', 'vfpclasspd', 'vfpclassps', 'vfpclasssd', 'vfpclassss', 'vfrczpd',
708             'vfrczps', 'vfrczsd', 'vfrczss', 'vgatherdpd', 'vgatherdps',
709             'vgatherpf0dpd', 'vgatherpf0dps', 'vgatherpf0qpd', 'vgatherpf0qps',
710             'vgatherpf1dpd', 'vgatherpf1dps', 'vgatherpf1qpd', 'vgatherpf1qps',
711             'vgatherqpd', 'vgatherqps', 'vgetexppd', 'vgetexpps', 'vgetexpsd', 'vgetexpss',
712             'vgetmantpd', 'vgetmantps', 'vgetmantsd', 'vgetmantss', 'vgf2p8affineinvqb',
713             'vgf2p8affineqb', 'vgf2p8mulb', 'vhaddpd', 'vhaddps', 'vhsubpd',
714             'vhsubps', 'vinsertf128', 'vinsertf32x4', 'vinsertf32x8',
715             'vinsertf64x2', 'vinsertf64x4', 'vinserti128', 'vinserti32x4', 'vinserti32x8', 'vinserti64x2',
716             'vinserti64x4', 'vinsertps', 'vlddqu', 'vldmxcsr', 'vldqqu', 'vmaskmovdqu',
717             'vmaskmovpd', 'vmaskmovps', 'vmaxpd', 'vmaxps', 'vmaxsd', 'vmaxss', 'vmcall', 'vmclear', 'vmfunc',
718             'vminpd', 'vminps', 'vminsd', 'vminss', 'vmlaunch', 'vmload', 'vmmcall', 'vmovapd', 'vmovaps',
719             'vmovd', 'vmovddup', 'vmovdqa', 'vmovdqa32',
720             'vmovdqa64', 'vmovdqu', 'vmovdqu16', 'vmovdqu32',
721             'vmovdqu64', 'vmovdqu8', 'vmovhlps', 'vmovhpd', 'vmovhps', 'vmovlhps',
722             'vmovlpd', 'vmovlps', 'vmovmskpd', 'vmovmskps', 'vmovntdq', 'vmovntdqa', 'vmovntpd',
723             'vmovntps', 'vmovntqq', 'vmovq', 'vmovqqa', 'vmovqqu', 'vmovsd', 'vmovshdup', 'vmovsldup',
724             'vmovss', 'vmovupd', 'vmovups', 'vmpsadbw', 'vmptrld', 'vmptrst', 'vmread', 'vmresume',
725             'vmrun', 'vmsave', 'vmulpd', 'vmulps', 'vmulsd', 'vmulss', 'vmwrite', 'vmxoff', 'vmxon',
726             'vorpd', 'vorps', 'vp2intersectd', 'vp4dpwssd', 'vp4dpwssds', 'vpabsb', 'vpabsd',
727             'vpabsq', 'vpabsw', 'vpackssdw', 'vpacksswb', 'vpackusdw',
728             'vpackuswb', 'vpaddb', 'vpaddd', 'vpaddq', 'vpaddsb', 'vpaddsw', 'vpaddusb',
729             'vpaddusw', 'vpaddw', 'vpalignr', 'vpand', 'vpandd', 'vpandn', 'vpandnd',
730             'vpandnq', 'vpandq', 'vpavgb', 'vpavgw', 'vpblendd', 'vpblendmb', 'vpblendmd', 'vpblendmq',
731             'vpblendmw', 'vpblendvb', 'vpblendw', 'vpbroadcastb', 'vpbroadcastd', 'vpbroadcastmb2q',
732             'vpbroadcastmw2d', 'vpbroadcastq', 'vpbroadcastw',
733             'vpclmulhqhqdq', 'vpclmulhqhdq', 'vpclmulhqlqdq', 'vpclmullqhqdq', 'vpclmullqhdq', 'vpclmullqlqdq',
734             'vpclmulqdq', 'vpcmov', 'vpcmpb', 'vpcmpd', 'vpcmpeqb', 'vpcmpeqd', 'vpcmpeqq', 'vpcmpequb', 'vpcmpequd',
735             'vpcmpequq', 'vpcmpequw', 'vpcmpeqw', 'vpcmpestri',
736             'vpcmpestrm', 'vpcmpgeb', 'vpcmpged', 'vpcmpgeq', 'vpcmpgeub', 'vpcmpgeud', 'vpcmpgeuq', 'vpcmpgeuw', 'vpcmpgew',
737             'vpcmpgtb', 'vpcmpgtd', 'vpcmpgtq', 'vpcmpgtub', 'vpcmpgtud', 'vpcmpgtuq', 'vpcmpgtuw',
738             'vpcmpgtw', 'vpcmpistri', 'vpcmpistrm',
739             'vpcmpled', 'vpcmpleq', 'vpcmpleud', 'vpcmpleuq', 'vpcmpltd', 'vpcmpltq',
740             'vpcmpltud', 'vpcmpltuq', 'vpcmpneqd', 'vpcmpneqq', 'vpcmpnequd', 'vpcmpnequq',
741             'vpcmpngtb', 'vpcmpngtd', 'vpcmpngtq', 'vpcmpngtub', 'vpcmpngtud', 'vpcmpngtuq',
742             'vpcmpngtuw', 'vpcmpngtw',
743             'vpcmpnled', 'vpcmpnleq', 'vpcmpnleud', 'vpcmpnleuq', 'vpcmpnltd', 'vpcmpnltq',
744             'vpcmpnltud', 'vpcmpnltuq', 'vpcmpq', 'vpcmpub', 'vpcmpud',
745             'vpcmpuq', 'vpcmpuw', 'vpcmpw', 'vpcomb', 'vpcomd',
746             'vpcomeqb', 'vpcomeqd', 'vpcomeqq', 'vpcomequb', 'vpcomequd', 'vpcomequq',
747             'vpcomequw', 'vpcomeqw', 'vpcomfalseb', 'vpcomfalsed', 'vpcomfalseq', 'vpcomfalseub',
748             'vpcomfalseud', 'vpcomfalseuq', 'vpcomfalseuw', 'vpcomfalsew', 'vpcomgeb', 'vpcomged',
749             'vpcomgeq', 'vpcomgeub', 'vpcomgeud', 'vpcomgeuq', 'vpcomgeuw', 'vpcomgew', 'vpcomgtb',
750             'vpcomgtd', 'vpcomgtq', 'vpcomgtub', 'vpcomgtud', 'vpcomgtuq', 'vpcomgtuw', 'vpcomgtw',
751             'vpcomleb', 'vpcomled', 'vpcomleq', 'vpcomleub', 'vpcomleud', 'vpcomleuq', 'vpcomleuw',
752             'vpcomlew', 'vpcomltb', 'vpcomltd', 'vpcomltq', 'vpcomltub', 'vpcomltud', 'vpcomltuq',
753             'vpcomltuw', 'vpcomltw', 'vpcomneqb', 'vpcomneqd', 'vpcomneqq', 'vpcomnequb', 'vpcomnequd',
754             'vpcomnequq', 'vpcomnequw', 'vpcomneqw', 'vpcompressb', 'vpcompressd', 'vpcompressq',
755             'vpcompressw', 'vpcomq', 'vpcomtrueb', 'vpcomtrued', 'vpcomtrueq',
756             'vpcomtrueub', 'vpcomtrueud', 'vpcomtrueuq', 'vpcomtrueuw', 'vpcomtruew',
757             'vpcomub', 'vpcomud', 'vpcomuq', 'vpcomuw', 'vpcomw', 'vpconflictd', 'vpconflictq',
758             'vpdpbusd', 'vpdpbusds', 'vpdpwssd', 'vpdpwssds', 'vperm2f128', 'vperm2i128',
759             'vpermb', 'vpermd', 'vpermi2b', 'vpermi2d', 'vpermi2pd', 'vpermi2w', 'vpermi2ps',
760             'vpermi2q', 'vpermil2pd', 'vpermil2ps', 'vpermilmo2pd',
761             'vpermilmo2ps', 'vpermilmz2pd', 'vpermilmz2ps', 'vpermilpd', 'vpermilps', 'vpermpd',
762             'vpermps', 'vpermq', 'vpermt2b', 'vpermt2d', 'vpermt2pd', 'vpermt2ps', 'vpermt2q', 'vpermt2w',
763             'vpermw', 'vpexpandb', 'vpexpandd', 'vpexpandq', 'vpexpandw', 'vpermiltd2pd', 'vpermiltd2ps', 'vpextrb',
764             'vpextrd', 'vpextrq', 'vpextrw', 'vpgatherdd', 'vpgatherdq', 'vpgatherqd', 'vpgatherqq',
765             'vphaddbd', 'vphaddbq', 'vphaddbw', 'vphaddd',
766             'vphadddq', 'vphaddsw', 'vphaddubd', 'vphaddubq', 'vphaddubw', 'vphaddubwd', 'vphaddudq',
767             'vphadduwd', 'vphadduwq', 'vphaddw', 'vphaddwd', 'vphaddwq', 'vphminposuw',
768             'vphsubbw', 'vphsubd', 'vphsubdq', 'vphsubsw', 'vphsubw', 'vphsubwd', 'vpinsrb',
769             'vpinsrd', 'vpinsrq', 'vpinsrw', 'vplzcntd',
770             'vplzcntq', 'vpmacsdd', 'vpmacsdqh', 'vpmacsdql', 'vpmacssdd',
771             'vpmacssdqh', 'vpmacssdql', 'vpmacsswd', 'vpmacssww', 'vpmacswd', 'vpmacsww',
772             'vpmadcsswd', 'vpmadcswd', 'vpmadd52huq',
773             'vpmadd52luq', 'vpmaddubsw', 'vpmaddwd', 'vpmaskmovd', 'vpmaskmovq',
774             'vpmaxsb', 'vpmaxsd', 'vpmaxsq', 'vpmaxsw',
775             'vpmaxub', 'vpmaxud', 'vpmaxuq', 'vpmaxuw', 'vpminsb', 'vpminsd',
776             'vpminsq', 'vpminsw', 'vpminub', 'vpminud', 'vpminuq',
777             'vpminuw', 'vpmovb2m', 'vpmovd2m', 'vpmovdb', 'vpmovdw', 'vpmovm2b',
778             'vpmovm2d', 'vpmovm2q', 'vpmovm2w', 'vpmovmskb', 'vpmovq2m', 'vpmovqb',
779             'vpmovqd', 'vpmovqw', 'vpmovsdb', 'vpmovsdw', 'vpmovsqb', 'vpmovsqd',
780             'vpmovsqw', 'vpmovswb', 'vpmovsxbd', 'vpmovsxbq', 'vpmovsxbw', 'vpmovsxdq',
781             'vpmovsxwd', 'vpmovsxwq', 'vpmovusdb', 'vpmovusdw', 'vpmovusqb', 'vpmovusqd',
782             'vpmovusqw', 'vpmovuswb', 'vpmovw2m', 'vpmovwb', 'vpmovzxbd', 'vpmovzxbq', 'vpmovzxbw', 'vpmovzxdq',
783             'vpmovzxwd', 'vpmovzxwq', 'vpmuldq', 'vpmulhrsw', 'vpmulhuw', 'vpmulhw', 'vpmulld', 'vpmullq',
784             'vpmullw', 'vpmultishiftqb', 'vpmuludq', 'vpopcntb', 'vpopcntd', 'vpopcntq', 'vpopcntw',
785             'vpor', 'vpord', 'vporq', 'vpperm', 'vprold',
786             'vprolq', 'vprolvd', 'vprolvq', 'vprord', 'vprorq', 'vprorvd',
787             'vprorvq','vprotb', 'vprotd', 'vprotq', 'vprotw',
788             'vpsadbw', 'vpscatterdd', 'vpscatterdq', 'vpscatterqd',
789             'vpscatterqq', 'vpshab', 'vpshad', 'vpshaq', 'vpshaw', 'vpshlb', 'vpshld',
790             'vpshldd', 'vpshldq', 'vpshldvd', 'vpshldvq', 'vpshldvw', 'vpshldw', 'vpshlq',
791             'vpshlw', 'vpshrdd', 'vpshrdq', 'vpshrdvd', 'vpshrdvq', 'vpshrdvw', 'vpshrdw',
792             'vpshufb', 'vpshufbitqmb', 'vpshufd', 'vpshufhw', 'vpshuflw', 'vpsignb', 'vpsignd', 'vpsignw',
793             'vpslld', 'vpslldq', 'vpsllq', 'vpsllvd', 'vpsllvq', 'vpsllvw', 'vpsllw', 'vpsrad', 'vpsraq', 'vpsravd',
794             'vpsravq', 'vpsravw', 'vpsraw', 'vpsrld', 'vpsrldq', 'vpsrlq', 'vpsrlvd', 'vpsrlvq', 'vpsrlvw', 'vpsrlw',
795             'vpsubb', 'vpsubd', 'vpsubq', 'vpsubsb', 'vpsubsw', 'vpsubusb',
796             'vpsubusw', 'vpsubw', 'vpternlogd',
797             'vpternlogq', 'vptest', 'vptestmb', 'vptestmd', 'vptestmq', 'vptestmw', 'vptestnmb', 'vptestnmd',
798             'vptestnmq', 'vptestnmw', 'vpunpckhbw', 'vpunpckhdq', 'vpunpckhqdq', 'vpunpckhwd',
799             'vpunpcklbw', 'vpunpckldq', 'vpunpcklqdq', 'vpunpcklwd', 'vpxor', 'vpxord',
800             'vpxorq', 'vrangepd', 'vrangeps', 'vrangesd', 'vrangess',
801             'vrcp14pd', 'vrcp14ps', 'vrcp14sd', 'vrcp14ss', 'vrcp28pd',
802             'vrcp28ps', 'vrcp28sd', 'vrcp28ss', 'vrcpps', 'vrcpss', 'vreducepd',
803             'vreduceps', 'vreducesd', 'vreducess', 'vrndscalepd', 'vrndscaleps', 'vrndscalesd', 'vrndscaless',
804             'vroundpd', 'vroundps', 'vroundsd', 'vroundss', 'vrsqrt14pd',
805             'vrsqrt14ps', 'vrsqrt14sd', 'vrsqrt14ss', 'vrsqrt28pd', 'vrsqrt28ps',
806             'vrsqrt28sd', 'vrsqrt28ss','vrsqrtps', 'vrsqrtss', 'vscalefpd', 'vscalefps',
807             'vscalefsd', 'vscalefss', 'vscatterdpd', 'vscatterdps', 'vscatterpf0dpd',
808             'vscatterpf0dps', 'vscatterpf0qpd', 'vscatterpf0qps', 'vscatterpf1dpd',
809             'vscatterpf1dps', 'vscatterpf1qpd', 'vscatterpf1qps', 'vscatterqpd',
810             'vscatterqps', 'vshuff32x4', 'vshuff64x2', 'vshufi32x4', 'vshufi64x2','vshufpd',
811             'vshufps', 'vsqrtpd', 'vsqrtps', 'vsqrtsd', 'vsqrtss', 'vstmxcsr', 'vsubpd',
812             'vsubps', 'vsubsd', 'vsubss', 'vtestpd', 'vtestps', 'vucomisd', 'vucomiss', 'vunpckhpd',
813             'vunpckhps', 'vunpcklpd', 'vunpcklps', 'vxorpd', 'vxorps', 'vzeroall', 'vzeroupper',
814             'wait', 'wbinvd', 'wbnoinvd', 'wrfsbase', 'wrgsbase', 'wrmsr', 'wrmsrq', 'wrpkru',
815             'wrssd', 'wrssq', 'wrussd', 'wrussq', 'wrshr', 'xabort',
816             'xacquire', 'xadd', 'xbegin', 'xbts', 'xchg', 'xcryptcbc', 'xcryptcfb',
817             'xcryptctr', 'xcryptecb', 'xcryptofb', 'xend', 'xgetbv', 'xlat', 'xlatb', 'xor', 'xorpd',
818             'xorps', 'xrelease', 'xresldtrk', 'xrstor', 'xrstor64', 'xrstors', 'xrstors64', 'xsave', 'xsave64',
819             'xsavec', 'xsavec64', 'xsaveopt', 'xsaveopt64', 'xsaves', 'xsaves64',
820             'xsetbv', 'xsha1', 'xsha256', 'xstore', 'xsusldtrk', 'xtest'
821             );
822              
823             # non-FPU instructions with suffixes in AT&T syntax
824             my @att_suff_instr = (
825             'mov' , 'and' , 'or' , 'not', 'xor', 'neg', 'cmp', 'add' ,
826             'sub' , 'push', 'test', 'lea', 'pop', 'inc', 'dec', 'idiv',
827             'imul', 'sbb' , 'sal' , 'shl', 'sar', 'shr'
828             );
829              
830             # NOTE: no fi* instructions here
831             my @att_suff_instr_fpu = (
832             'fadd', 'faddp', 'fbld', 'fbstp',
833             'fcom', 'fcomp', 'fcompp',
834             'fcomi', 'fcomip', 'fdiv', 'fdivr', 'fdivp', 'fdivrp',
835             'fld', 'fmul', 'fmulp', 'fndisi',
836             'fst', 'fstp', 'fsub', 'fsubr', 'fsubp', 'fsubrp',
837             'fucom', 'fucomp', 'fucompp', 'fucomi', 'fucomip'
838             );
839              
840             =head2 @instr_att
841              
842             A list of all x86 instructions (as strings) in AT&T syntax.
843              
844             =cut
845              
846             our @instr_att = add_att_suffix_instr @instr_intel;
847              
848             =head2 @instr
849              
850             A list of all x86 instructions (as strings) in Intel and AT&T syntax.
851              
852             =cut
853              
854             # concatenating the lists can create unnecessary duplicate entries, so remove them
855             our @instr = _remove_duplicates (@instr_intel, @instr_att);
856              
857             =head1 FUNCTIONS
858              
859             =head2 is_reg_intel
860              
861             Checks if the given string parameter is a valid x86 register (any size) in Intel syntax.
862             Returns 1 if yes.
863              
864             =cut
865              
866             sub is_reg_intel($) {
867 897425     897425 1 1948308 return _is_in_array (shift, \@regs_intel);
868             }
869              
870             =head2 is_reg_att
871              
872             Checks if the given string parameter is a valid x86 register (any size) in AT&T syntax.
873             Returns 1 if yes.
874              
875             =cut
876              
877             sub is_reg_att($) {
878 12841     12841 1 140564 return _is_in_array_att (shift, \@regs_att);
879             }
880              
881             =head2 is_reg
882              
883             Checks if the given string parameter is a valid x86 register (any size).
884             Returns 1 if yes.
885              
886             =cut
887              
888             sub is_reg($) {
889 2377     2377 1 4669 my $elem = shift;
890 2377         4078 return is_reg_intel ($elem) | is_reg_att ($elem);
891             }
892              
893             =head2 is_reg8_intel
894              
895             Checks if the given string parameter is a valid x86 8-bit register in Intel syntax.
896             Returns 1 if yes.
897              
898             =cut
899              
900             sub is_reg8_intel($) {
901 1470     1470 1 3887 return _is_in_array (shift, \@regs8_intel);
902             }
903              
904             =head2 is_reg8_att
905              
906             Checks if the given string parameter is a valid x86 8-bit register in AT&T syntax.
907             Returns 1 if yes.
908              
909             =cut
910              
911             sub is_reg8_att($) {
912 1470     1470 1 3611 return _is_in_array_att (shift, \@regs8_att);
913             }
914              
915             =head2 is_reg8
916              
917             Checks if the given string parameter is a valid x86 8-bit register.
918             Returns 1 if yes.
919              
920             =cut
921              
922             sub is_reg8($) {
923 877     877 1 1809 my $elem = shift;
924 877         1773 return is_reg8_intel ($elem) | is_reg8_att ($elem);
925             }
926              
927             =head2 is_reg16_intel
928              
929             Checks if the given string parameter is a valid x86 16-bit register in Intel syntax.
930             Returns 1 if yes.
931              
932             =cut
933              
934             sub is_reg16_intel($) {
935 7246     7246 1 15186 return _is_in_array (shift, \@regs16_intel);
936             }
937              
938             =head2 is_reg16_att
939              
940             Checks if the given string parameter is a valid x86 16-bit register in AT&T syntax.
941             Returns 1 if yes.
942              
943             =cut
944              
945             sub is_reg16_att($) {
946 2955     2955 1 6784 return _is_in_array_att (shift, \@regs16_att);
947             }
948              
949             =head2 is_reg16
950              
951             Checks if the given string parameter is a valid x86 16-bit register.
952             Returns 1 if yes.
953              
954             =cut
955              
956             sub is_reg16($) {
957 825     825 1 1514 my $elem = shift;
958 825         1748 return is_reg16_intel ($elem) | is_reg16_att ($elem);
959             }
960              
961             =head2 is_segreg_intel
962              
963             Checks if the given string parameter is a valid x86 segment register in Intel syntax.
964             Returns 1 if yes.
965              
966             =cut
967              
968             sub is_segreg_intel($) {
969 207127     207127 1 575470 return _is_in_array (shift, \@segregs_intel);
970             }
971              
972             =head2 is_segreg_att
973              
974             Checks if the given string parameter is a valid x86 segment register in AT&T syntax.
975             Returns 1 if yes.
976              
977             =cut
978              
979             sub is_segreg_att($) {
980 4732     4732 1 14501 return _is_in_array_att (shift, \@segregs_att);
981             }
982              
983             =head2 is_segreg
984              
985             Checks if the given string parameter is a valid x86 segment register.
986             Returns 1 if yes.
987              
988             =cut
989              
990             sub is_segreg($) {
991 547     547 1 1114 my $elem = shift;
992 547         1161 return is_segreg_intel ($elem) | is_segreg_att ($elem);
993             }
994              
995             =head2 is_reg32_intel
996              
997             Checks if the given string parameter is a valid x86 32-bit register in Intel syntax.
998             Returns 1 if yes.
999              
1000             =cut
1001              
1002             sub is_reg32_intel($) {
1003 1373     1373 1 3607 return _is_in_array (shift, \@regs32_intel);
1004             }
1005              
1006             =head2 is_reg32_att
1007              
1008             Checks if the given string parameter is a valid x86 32-bit register in AT&T syntax.
1009             Returns 1 if yes.
1010              
1011             =cut
1012              
1013             sub is_reg32_att($) {
1014 1373     1373 1 3382 return _is_in_array_att (shift, \@regs32_att);
1015             }
1016              
1017             =head2 is_reg32
1018              
1019             Checks if the given string parameter is a valid x86 32-bit register.
1020             Returns 1 if yes.
1021              
1022             =cut
1023              
1024             sub is_reg32($) {
1025 780     780 1 1529 my $elem = shift;
1026 780         1846 return is_reg32_intel ($elem) | is_reg32_att ($elem);
1027             }
1028              
1029             =head2 is_addressable32_intel
1030              
1031             Checks if the given string parameter is a valid x86 32-bit register which can be used
1032             for addressing in Intel syntax.
1033             Returns 1 if yes.
1034              
1035             =cut
1036              
1037             sub is_addressable32_intel($) {
1038 391961     391961 1 760474 return _is_in_array (shift, \@addressable32);
1039             }
1040              
1041             =head2 is_addressable32_att
1042              
1043             Checks if the given string parameter is a valid x86 32-bit register which can be used
1044             for addressing in AT&T syntax.
1045             Returns 1 if yes.
1046              
1047             =cut
1048              
1049             sub is_addressable32_att($) {
1050 6848     6848 1 13764 return _is_in_array_att (shift, \@addressable32_att);
1051             }
1052              
1053             =head2 is_addressable32
1054              
1055             Checks if the given string parameter is a valid x86 32-bit register which can be used
1056             for addressing.
1057             Returns 1 if yes.
1058              
1059             =cut
1060              
1061             sub is_addressable32($) {
1062 519     519 1 1170 my $elem = shift;
1063 519         1153 return is_addressable32_intel ($elem) | is_addressable32_att ($elem);
1064             }
1065              
1066             =head2 is_r32_in64_intel
1067              
1068             Checks if the given string parameter is a valid x86 32-bit register which can only be used
1069             in 64-bit mode (that is, checks if the given string parameter is a 32-bit
1070             subregister of a 64-bit register).
1071             Returns 1 if yes.
1072              
1073             =cut
1074              
1075             sub is_r32_in64_intel($) {
1076 123701     123701 1 224790 return _is_in_array (shift, \@r32_in64);
1077             }
1078              
1079             =head2 is_r32_in64_att
1080              
1081             Checks if the given string parameter is a valid x86 32-bit register in Intel syntax
1082             which can only be used in 64-bit mode (that is, checks if the given string
1083             parameter is a 32-bit subregister of a 64-bit register).
1084             Returns 1 if yes.
1085              
1086             =cut
1087              
1088             sub is_r32_in64_att($) {
1089 3633     3633 1 7789 return _is_in_array_att (shift, \@r32_in64_att);
1090             }
1091              
1092             =head2 is_r32_in64
1093              
1094             Checks if the given string parameter is a valid x86 32-bit register in AT&T syntax
1095             which can only be used in 64-bit mode (that is, checks if the given string
1096             parameter is a 32-bit subregister of a 64-bit register).
1097             Returns 1 if yes.
1098              
1099             =cut
1100              
1101             sub is_r32_in64($) {
1102 519     519 1 1092 my $elem = shift;
1103 519         1097 return is_r32_in64_intel ($elem) | is_r32_in64_att ($elem);
1104             }
1105              
1106             =head2 is_reg64_intel
1107              
1108             Checks if the given string parameter is a valid x86 64-bit register in Intel syntax.
1109             Returns 1 if yes.
1110              
1111             =cut
1112              
1113             sub is_reg64_intel($) {
1114 367641     367641 1 655535 return _is_in_array (shift, \@regs64_intel);
1115             }
1116              
1117             =head2 is_reg64_att
1118              
1119             Checks if the given string parameter is a valid x86 64-bit register in AT&T syntax.
1120             Returns 1 if yes.
1121              
1122             =cut
1123              
1124             sub is_reg64_att($) {
1125 6601     6601 1 14709 return _is_in_array_att (shift, \@regs64_att);
1126             }
1127              
1128             =head2 is_reg64
1129              
1130             Checks if the given string parameter is a valid x86 64-bit register.
1131             Returns 1 if yes.
1132              
1133             =cut
1134              
1135             sub is_reg64($) {
1136 712     712 1 1510 my $elem = shift;
1137 712         1585 return is_reg64_intel ($elem) | is_reg64_att ($elem);
1138             }
1139              
1140             =head2 is_reg_mm_intel
1141              
1142             Checks if the given string parameter is a valid x86 multimedia (MMX/3DNow!/SSEn)
1143             register in Intel syntax.
1144             Returns 1 if yes.
1145              
1146             =cut
1147              
1148             sub is_reg_mm_intel($) {
1149 1186     1186 1 3479 return _is_in_array (shift, \@regs_mm_intel);
1150             }
1151              
1152             =head2 is_reg_mm_att
1153              
1154             Checks if the given string parameter is a valid x86 multimedia (MMX/3DNow!/SSEn)
1155             register in AT&T syntax.
1156             Returns 1 if yes.
1157              
1158             =cut
1159              
1160             sub is_reg_mm_att($) {
1161 1186     1186 1 3109 return _is_in_array_att (shift, \@regs_mm_att);
1162             }
1163              
1164             =head2 is_reg_mm
1165              
1166             Checks if the given string parameter is a valid x86 multimedia (MMX/3DNow!/SSEn) register.
1167             Returns 1 if yes.
1168              
1169             =cut
1170              
1171             sub is_reg_mm($) {
1172 593     593 1 1292 my $elem = shift;
1173 593         1475 return is_reg_mm_intel ($elem) | is_reg_mm_att ($elem);
1174             }
1175              
1176             =head2 is_reg_fpu_intel
1177              
1178             Checks if the given string parameter is a valid x86 FPU register in Intel syntax.
1179             Returns 1 if yes.
1180              
1181             =cut
1182              
1183             sub is_reg_fpu_intel($) {
1184 1186     1186 1 3247 return _is_in_array (shift, \@regs_fpu_intel);
1185             }
1186              
1187             =head2 is_reg_fpu_att
1188              
1189             Checks if the given string parameter is a valid x86 FPU register in AT&T syntax.
1190             Returns 1 if yes.
1191              
1192             =cut
1193              
1194             sub is_reg_fpu_att($) {
1195 1186     1186 1 2907 return _is_in_array_att (shift, \@regs_fpu_att);
1196             }
1197              
1198             =head2 is_reg_fpu
1199              
1200             Checks if the given string parameter is a valid x86 FPU register.
1201             Returns 1 if yes.
1202              
1203             =cut
1204              
1205             sub is_reg_fpu($) {
1206 593     593 1 1312 my $elem = shift;
1207 593         1200 return is_reg_fpu_intel ($elem) | is_reg_fpu_att ($elem);
1208             }
1209              
1210             =head2 is_reg_opmask_intel
1211              
1212             Checks if the given string parameter is a valid x86 opmask register in Intel syntax.
1213             Returns 1 if yes.
1214              
1215             =cut
1216              
1217             sub is_reg_opmask_intel($) {
1218 1186     1186 1 3363 return _is_in_array (shift, \@regs_opmask_intel);
1219             }
1220              
1221             =head2 is_reg_opmask_att
1222              
1223             Checks if the given string parameter is a valid x86 opmask register in AT&T syntax.
1224             Returns 1 if yes.
1225              
1226             =cut
1227              
1228             sub is_reg_opmask_att($) {
1229 1186     1186 1 3085 return _is_in_array_att (shift, \@regs_opmask_att);
1230             }
1231              
1232             =head2 is_reg_opmask
1233              
1234             Checks if the given string parameter is a valid x86 opmask register.
1235             Returns 1 if yes.
1236              
1237             =cut
1238              
1239             sub is_reg_opmask($) {
1240 593     593 1 1311 my $elem = shift;
1241 593         1360 return is_reg_opmask_intel ($elem) | is_reg_opmask_att ($elem);
1242             }
1243              
1244             =head2 is_instr_intel
1245              
1246             Checks if the given string parameter is a valid x86 instruction in Intel syntax.
1247             Returns 1 if yes.
1248              
1249             =cut
1250              
1251             sub is_instr_intel($) {
1252 357     357 1 28281 return _is_in_array (shift, \@instr_intel);
1253             }
1254              
1255             =head2 is_instr_att
1256              
1257             Checks if the given string parameter is a valid x86 instruction in AT&T syntax.
1258             Returns 1 if yes.
1259              
1260             =cut
1261              
1262             sub is_instr_att($) {
1263 373     373 1 32746 return _is_in_array (shift, \@instr_att);
1264             }
1265              
1266             =head2 is_instr
1267              
1268             Checks if the given string parameter is a valid x86 instruction in any syntax.
1269             Returns 1 if yes.
1270              
1271             =cut
1272              
1273             sub is_instr($) {
1274 324     324 1 27022 my $elem = shift;
1275 324         706 return is_instr_intel ($elem) | is_instr_att ($elem);
1276             }
1277              
1278             ##############################################################################
1279              
1280             # =head2 _is_valid_16bit_addr_reg_intel
1281             #
1282             # PRIVATE SUBROUTINE.
1283             # Checks if the given register can be used in x86 16-bit addressing
1284             # mode in Intel syntax.
1285             # Returns 1 if yes.
1286             #
1287             # =cut
1288             #
1289             sub _is_valid_16bit_addr_reg_intel($) {
1290              
1291 27738     27738   50832 my $reg = shift;
1292 27738 100 100     184089 return 1 if $reg =~ /^bx$/io || $reg =~ /^bp$/io
      100        
      100        
1293             || $reg =~ /^si$/io || $reg =~ /^di$/io;
1294 8894         58372 return 0;
1295             }
1296              
1297             # =head2 _is_same_type_16bit_addr_reg_intel
1298             #
1299             # PRIVATE SUBROUTINE.
1300             # Checks if the 2 given registers cannot be used in x86 16-bit addressing
1301             # mode in Intel syntax at the same time because they're of the same type.
1302             # Returns 1 if yes.
1303             #
1304             # =cut
1305             #
1306             sub _is_same_type_16bit_addr_reg_intel($$) {
1307              
1308 1825     1825   3449 my $reg1 = shift;
1309 1825         3120 my $reg2 = shift;
1310 1825 100 100     18132 return 1 if ($reg1 =~ /^b.$/io && $reg2 =~ /^b.$/io)
      100        
      100        
1311             || ($reg1 =~ /^.i$/io && $reg2 =~ /^.i$/io);
1312 913         2792 return 0;
1313             }
1314              
1315             # =head2 _validate_16bit_addr_parts_intel
1316             #
1317             # PRIVATE SUBROUTINE.
1318             # Checks if the given address components give a valid x86 32-bit addressing
1319             # mode in Intel syntax.
1320             # Returns 1 if yes.
1321             #
1322             # =cut
1323             #
1324             sub _validate_16bit_addr_parts_intel($$$$$$$) {
1325              
1326 14403     14403   30127 my $segreg = shift;
1327 14403         26436 my $reg1_sign = shift;
1328 14403         21450 my $reg1 = shift;
1329 14403         23309 my $reg2_sign = shift;
1330 14403         22050 my $reg2 = shift;
1331 14403         23219 my $disp_sign = shift;
1332 14403         20904 my $disp = shift;
1333              
1334 14403 100 100     39880 return 0 if defined $segreg && ! is_segreg_intel($segreg);
1335 14359 100 66     45329 return 0 if defined $reg1 && is_reg_intel($reg1)
      100        
1336             && (! _is_valid_16bit_addr_reg_intel ($reg1));
1337 11262 100 100     32261 return 0 if defined $reg2 && is_reg_intel($reg2)
      100        
1338             && (! _is_valid_16bit_addr_reg_intel ($reg2));
1339 7985 100 100     24093 return 0 if defined $disp && is_reg_intel($disp)
      100        
1340             && (! _is_valid_16bit_addr_reg_intel ($disp));
1341              
1342 5465 100 33     23786 return 0 if defined $reg1 && defined $reg1_sign
      66        
      100        
1343             && is_reg_intel($reg1) && $reg1_sign =~ /-/o;
1344 4738 100 66     18662 return 0 if defined $reg2 && defined $reg2_sign
      100        
      100        
1345             && is_reg_intel($reg2) && $reg2_sign =~ /-/o;
1346 3418 100 66     13813 return 0 if defined $disp && defined $disp_sign
      100        
      100        
1347             && is_reg_intel($disp) && $disp_sign =~ /-/o;
1348 2350 50 66     13457 return 0 if defined $reg1 && defined $reg2 && defined $disp
      100        
      100        
      100        
      66        
1349             && is_reg_intel($reg1) && is_reg_intel($reg2) && is_reg_intel($disp);
1350              
1351 2350 100 66     7196 if ( defined $reg1 && is_reg16_intel($reg1) ) {
1352              
1353 1581 50 33     6320 return 0 if defined $reg1_sign && $reg1_sign =~ /-/o;
1354             # must be one of predefined registers
1355 1581 50       3595 if ( _is_valid_16bit_addr_reg_intel ($reg1) ) {
1356              
1357 1581 100 100     4582 if ( defined $reg2 && is_reg16_intel($reg2) ) {
    100 100        
1358              
1359 769 100       2200 return 0 if _is_same_type_16bit_addr_reg_intel ($reg1, $reg2);
1360 385 50 33     1801 return 0 if defined $reg2_sign && $reg2_sign =~ /-/o;
1361 385 50 66     1224 return 0 if defined $disp && is_reg_intel($disp);
1362              
1363             # must be one of predefined registers
1364 385 50       1160 return 1 if _is_valid_16bit_addr_reg_intel ($reg2)
1365             #&& $reg2 !~ /\b$reg1\b/i # already checked
1366             ;
1367 0         0 return 0;
1368              
1369             } elsif ( defined $disp && is_reg16_intel($disp) ) {
1370              
1371 576 100       1803 return 0 if _is_same_type_16bit_addr_reg_intel ($reg1, $disp);
1372 288 50 33     1390 return 0 if defined $disp_sign && $disp_sign =~ /-/o;
1373              
1374             # must be one of predefined registers
1375 288 50       637 return 1 if _is_valid_16bit_addr_reg_intel ($disp)
1376             #&& $disp !~ /\b$reg1\b/i # already checked
1377             #&& ! is_reg_intel($reg2) # already checked
1378             ;
1379 0         0 return 0;
1380             } else {
1381             # variable/number/constant is OK
1382 236         1489 return 1;
1383             }
1384             }
1385 0         0 return 0;
1386             } else {
1387 769 100 100     2415 if ( defined $reg2 && is_reg16_intel($reg2) ) {
1388              
1389 642 50 33     2980 return 0 if defined $reg2_sign && $reg2_sign =~ /-/o;
1390             # must be one of predefined registers
1391 642 50       1357 if ( _is_valid_16bit_addr_reg_intel ($reg2) )
1392             {
1393 642 100 100     1790 if ( defined $disp && is_reg16_intel($disp) ) {
1394              
1395 480 100       1210 return 0 if _is_same_type_16bit_addr_reg_intel ($disp, $reg2);
1396 240 50 33     1106 return 0 if defined $disp_sign && $disp_sign =~ /-/o;
1397              
1398             # must be one of predefined registers
1399 240 50       529 return 1 if _is_valid_16bit_addr_reg_intel ($disp)
1400             #&& $disp !~ /\b$reg2\b/i # already checked
1401             ;
1402 0         0 return 0;
1403             } else {
1404             # variable/number/constant is OK
1405 162         972 return 1;
1406             }
1407             }
1408 0         0 return 0;
1409             } else {
1410 127 50 66     813 return 0 if defined $disp && defined $disp_sign
      100        
      66        
1411             && is_reg16_intel($disp) && $disp_sign =~ /-/o;
1412             # variable/number/constant is OK
1413 127         1551 return 1;
1414             }
1415             }
1416             }
1417              
1418             =head2 is_valid_16bit_addr_intel
1419              
1420             Checks if the given string parameter (must contain the square braces)
1421             is a valid x86 16-bit addressing mode in Intel syntax.
1422             Works best after any pre-processing of the input, i.e. after all macros,
1423             constants, etc. have been replaced by the real values.
1424             Returns 1 if yes.
1425              
1426             =cut
1427              
1428             sub is_valid_16bit_addr_intel($) {
1429              
1430 23912     23912 1 15694952 my $elem = shift;
1431 23912 100 100     488556 if ( $elem =~ /^(\w+):\s*\[\s*([\+\-]*)\s*(\w+)\s*\]$/o
    100 100        
    100 100        
    100          
    100          
    100          
1432             || $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-]*)\s*(\w+)\s*\]$/o ) {
1433              
1434 202         601 return _validate_16bit_addr_parts_intel ($1, $2, $3, undef, undef, undef, undef);
1435             }
1436             elsif ( $elem =~ /^(\w+):\s*\[\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o
1437             || $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o ) {
1438              
1439 1569         4681 return _validate_16bit_addr_parts_intel ($1, $2, $3, $4, $5, undef, undef);
1440             }
1441             elsif ( $elem =~ /^(\w+):\s*\[\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o
1442             || $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o ) {
1443              
1444 7833         21988 return _validate_16bit_addr_parts_intel ($1, $2, $3, $4, $5, $6, $7);
1445             }
1446             elsif ( $elem =~ /^\[\s*([\+\-]*)\s*(\w+)\s*\]$/o ) {
1447              
1448 100         427 return _validate_16bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, undef);
1449             }
1450             elsif ( $elem =~ /^\[\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o ) {
1451              
1452 790         2450 return _validate_16bit_addr_parts_intel (undef, $1, $2, $3, $4, undef, undef);
1453             }
1454             elsif ( $elem =~ /^\[\s*([\+\-]*)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*([\+\-]+)\s*(\w+)\s*\]$/o ) {
1455              
1456 3909         11893 return _validate_16bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, $6);
1457             }
1458 9509         43099 return 0;
1459             }
1460              
1461             # =head2 _is_valid_16bit_addr_reg_att
1462             #
1463             # PRIVATE SUBROUTINE.
1464             # Checks if the given register can be used in x86 16-bit addressing
1465             # mode in AT&T syntax.
1466             # Returns 1 if yes.
1467             #
1468             # =cut
1469             #
1470             sub _is_valid_16bit_addr_reg_att($) {
1471              
1472 1462     1462   2614 my $reg = shift;
1473 1462 100 100     8768 return 1 if $reg =~ /^%bx$/io || $reg =~ /^%bp$/io
      100        
      100        
1474             || $reg =~ /^%si$/io || $reg =~ /^%di$/io;
1475 186         1181 return 0;
1476             }
1477              
1478             # =head2 _is_same_type_16bit_addr_reg_att
1479             #
1480             # PRIVATE SUBROUTINE.
1481             # Checks if the 2 given registers cannot be used in x86 16-bit addressing
1482             # mode in AT&T syntax at the same time because they're of the same type.
1483             # Returns 1 if yes.
1484             #
1485             # =cut
1486             #
1487             sub _is_same_type_16bit_addr_reg_att($$) {
1488              
1489 129     129   208 my $reg1 = shift;
1490 129         184 my $reg2 = shift;
1491 129 100 100     1082 return 1 if ($reg1 =~ /^%b.$/io && $reg2 =~ /^%b.$/io)
      100        
      100        
1492             || ($reg1 =~ /^%.i$/io && $reg2 =~ /^%.i$/io);
1493 65         142 return 0;
1494             }
1495              
1496             # =head2 _validate_16bit_addr_parts_att
1497             #
1498             # PRIVATE SUBROUTINE.
1499             # Checks if the given address components give a valid x86 32-bit addressing
1500             # mode in AT&T syntax.
1501             # Returns 1 if yes.
1502             #
1503             # =cut
1504             #
1505             sub _validate_16bit_addr_parts_att($$$$$$$$) {
1506              
1507 1088     1088   2145 my $segreg = shift;
1508 1088         1755 my $basereg_sign = shift;
1509 1088         2054 my $basereg = shift;
1510 1088         1472 my $indexreg_sign = shift;
1511 1088         1730 my $indexreg = shift;
1512 1088         1437 my $scale = shift;
1513 1088         1611 my $disp_sign = shift;
1514 1088         1562 my $disp = shift;
1515              
1516 1088 100 100     3420 return 0 if defined $segreg && ! is_segreg_att($segreg);
1517 1067 100       2296 if ( defined $basereg ) {
1518 946 100 100     3394 return 0 if $basereg =~ /%/o && ! is_reg16_att($basereg);
1519 785 100 100     2015 return 0 if is_reg_att($basereg) && ! _is_valid_16bit_addr_reg_att ($basereg);
1520 663 100 100     1796 return 0 if defined $disp && ! is_reg_att($basereg); # disallow 'var(var)'
1521             }
1522 766 100       1640 if ( defined $indexreg ) {
1523 656 100 100     2234 return 0 if $indexreg =~ /%/o && ! is_reg16_att($indexreg);
1524 470 100 100     1039 return 0 if is_reg_att($indexreg) && ! _is_valid_16bit_addr_reg_att ($indexreg);
1525 418 50 66     1102 if ( ! defined $basereg && ! defined $scale ) {
1526             # just one value inside - check for "(,1)
1527 61 100 100     294 return 0 if $indexreg ne '1' || is_reg_att($disp);
1528             }
1529             }
1530 477 100 100     1084 return 0 if defined $disp && is_reg_att($disp);
1531 259 50 33     576 return 0 if defined $scale && $scale ne '1';
1532 259 100 100     718 if ( defined $basereg && defined $indexreg ) {
1533              
1534 141 100 100     247 return 0 if ! _is_valid_16bit_addr_reg_att($basereg)
1535             || ! _is_valid_16bit_addr_reg_att($indexreg);
1536 129 100       266 return 0 if _is_same_type_16bit_addr_reg_att ($basereg, $indexreg);
1537             }
1538 183 0 66     581 return 0 if defined $basereg && defined $basereg_sign
      33        
      33        
1539             && is_reg_att($basereg) && $basereg_sign =~ /-/o;
1540 183 0 66     445 return 0 if defined $indexreg && defined $indexreg_sign
      33        
      33        
1541             && is_reg_att($indexreg) && $indexreg_sign =~ /-/o;
1542              
1543 183         828 return 1;
1544             }
1545              
1546             =head2 is_valid_16bit_addr_att
1547              
1548             Checks if the given string parameter (must contain the parentheses)
1549             is a valid x86 16-bit addressing mode in AT&T syntax.
1550             Works best after any pre-processing of the input, i.e. after all macros,
1551             constants, etc. have been replaced by the real values.
1552             Returns 1 if yes.
1553              
1554             =cut
1555              
1556             sub is_valid_16bit_addr_att($) {
1557              
1558 1850     1850 1 1856990 my $elem = shift;
1559 1850 100       37999 if ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*\)$/o ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1560              
1561 34         124 return _validate_16bit_addr_parts_att ($1, undef, $2, undef, undef, undef, undef, undef);
1562             }
1563             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/ ) {
1564              
1565 52         179 return _validate_16bit_addr_parts_att ($1, undef, $2, undef, $3, undef, undef, undef);
1566             }
1567             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1568              
1569 16         90 return _validate_16bit_addr_parts_att ($1, undef, $2, undef, $3, $4, undef, undef);
1570             }
1571             elsif ( $elem =~ /^([%\w]+):\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1572              
1573             # '(, index, scale)' not in 16-bit addresses
1574 5         27 return 0;
1575             }
1576             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1577              
1578 99         334 return _validate_16bit_addr_parts_att ($1, undef, $4, undef, undef, undef, $2, $3);
1579             }
1580             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1581              
1582 212         743 return _validate_16bit_addr_parts_att ($1, undef, $4, undef, $5, undef, $2, $3);
1583             }
1584             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1585              
1586 72         232 return _validate_16bit_addr_parts_att ($1, undef, $4, undef, $5, $6, $2, $3);
1587             }
1588             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1589              
1590             # 'disp(, index, scale)' not in 16-bit addresses
1591 12         62 return 0;
1592             }
1593             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1594              
1595 60         190 return _validate_16bit_addr_parts_att ($1, undef, undef, undef, $4, undef, $2, $3);
1596             }
1597             elsif ( $elem =~ /^\(\s*([%\w]+)\s*\)$/o ) {
1598              
1599 30         113 return _validate_16bit_addr_parts_att (undef, undef, $1, undef, undef, undef, undef, undef);
1600             }
1601             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1602              
1603 55         242 return _validate_16bit_addr_parts_att (undef, undef, $1, undef, $2, undef, undef, undef);
1604             }
1605             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1606              
1607 18         102 return _validate_16bit_addr_parts_att (undef, undef, $1, undef, $2, $3, undef, undef);
1608             }
1609             elsif ( $elem =~ /^\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1610              
1611             # '(, index, scale)' not in 16-bit addresses
1612 5         30 return 0;
1613             }
1614             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1615              
1616 94         293 return _validate_16bit_addr_parts_att (undef, undef, $3, undef, undef, undef, $1, $2);
1617             }
1618             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1619              
1620 211         728 return _validate_16bit_addr_parts_att (undef, undef, $3, undef, $4, undef, $1, $2);
1621             }
1622             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1623              
1624 73         255 return _validate_16bit_addr_parts_att (undef, undef, $3, undef, $4, $5, $1, $2);
1625             }
1626             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1627              
1628             # 'disp(, index, scale)' not in 16-bit addresses
1629 12         63 return 0;
1630             }
1631             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1632              
1633 62         209 return _validate_16bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
1634             }
1635 728         3164 return 0;
1636             }
1637              
1638             =head2 is_valid_16bit_addr
1639              
1640             Checks if the given string parameter (must contain the parentheses)
1641             is a valid x86 16-bit addressing mode in AT&T or Intel syntax.
1642             Works best after any pre-processing of the input, i.e. after all macros,
1643             constants, etc. have been replaced by the real values.
1644             Returns 1 if yes.
1645              
1646             =cut
1647              
1648             sub is_valid_16bit_addr($) {
1649              
1650 4     4 1 15 my $elem = shift;
1651 4         14 return is_valid_16bit_addr_intel ($elem)
1652             | is_valid_16bit_addr_att ($elem);
1653             }
1654              
1655             # =head2 _validate_32bit_addr_parts_intel
1656             #
1657             # PRIVATE SUBROUTINE.
1658             # Checks if the given address components give a valid x86 32-bit addressing
1659             # mode in Intel syntax.
1660             # Returns 1 if yes.
1661             #
1662             # =cut
1663             sub _validate_32bit_addr_parts_intel($$$$$$$$) {
1664              
1665 154412     154412   334929 my $segreg = shift;
1666 154412         270827 my $base_reg_sign = shift;
1667 154412         230741 my $base_reg = shift;
1668 154412         265545 my $index_reg_sign = shift;
1669 154412         256347 my $index_reg = shift;
1670 154412         235979 my $scale = shift;
1671 154412         221155 my $disp_sign = shift;
1672 154412         237170 my $disp = shift;
1673              
1674 154412 100 100     433529 return 0 if defined $segreg && ! is_segreg_intel($segreg);
1675 151960 100 100     467957 return 0 if defined $base_reg && is_reg_intel($base_reg) && ! is_addressable32_intel($base_reg);
      100        
1676 117634 100 100     365975 return 0 if defined $index_reg && is_reg_intel($index_reg) && ! is_addressable32_intel($index_reg);
      100        
1677 66427 100 100     186896 return 0 if defined $scale && is_reg_intel($scale) && ! is_addressable32_intel($scale);
      100        
1678 39478 100 100     116030 return 0 if defined $disp && is_reg_intel($disp) && ! is_addressable32_intel($disp);
      100        
1679              
1680 12280 100 100     54638 return 0 if defined $index_reg && defined $scale
      100        
      100        
1681             && is_reg_intel($index_reg) && is_reg_intel($scale);
1682 11404 100 66     45924 return 0 if defined $base_reg && defined $base_reg_sign
      100        
      100        
1683             && is_reg_intel($base_reg) && $base_reg_sign =~ /-/o;
1684 9819 100 66     41161 return 0 if defined $index_reg && defined $index_reg_sign
      100        
      100        
1685             && is_reg_intel($index_reg) && $index_reg_sign =~ /-/o;
1686 8688 100 66     35917 return 0 if defined $scale && defined $index_reg_sign
      100        
      100        
1687             && is_reg_intel($scale) && $index_reg_sign =~ /-/o;
1688 7698 100 66     32664 return 0 if defined $disp && defined $disp_sign
      100        
      100        
1689             && is_reg_intel($disp) && $disp_sign =~ /-/o;
1690              
1691 6711 100 100     25439 if ( defined $index_reg && defined $scale ) {
1692              
1693 6192 100 100     24349 return 0 if $index_reg =~ /\besp\b/io && $scale =~ /\b\d+\b/o && $scale != 1;
      100        
1694 6039 100 100     21239 return 0 if $scale =~ /\besp\b/io && $index_reg =~ /\b\d+\b/o && $index_reg != 1;
      100        
1695 5886 100 100     10918 return 0 if is_reg_intel($index_reg) && $scale =~ /\b\d+\b/o && $scale != 1
      100        
      100        
      100        
      100        
1696             && $scale != 2 && $scale != 4 && $scale != 8;
1697 5733 100 100     13155 return 0 if is_reg_intel($scale) && $index_reg =~ /\b\d+\b/o && $index_reg != 1
      100        
      100        
      100        
      100        
1698             && $index_reg != 2 && $index_reg != 4 && $index_reg != 8;
1699             }
1700 6099 100 100     31236 return 0 if defined $base_reg && defined $index_reg && defined $disp
      100        
      100        
      100        
      100        
1701             && is_reg_intel($base_reg) && is_reg_intel($index_reg) && is_reg_intel($disp);
1702 6027 100 100     29481 return 0 if defined $base_reg && defined $scale && defined $disp
      100        
      100        
      100        
      100        
1703             && is_reg_intel($base_reg) && is_reg_intel($scale) && is_reg_intel($disp);
1704              
1705 5991         46174 return 1;
1706             }
1707              
1708             =head2 is_valid_32bit_addr_intel
1709              
1710             Checks if the given string parameter (must contain the square braces)
1711             is a valid x86 32-bit addressing mode in Intel syntax.
1712             Works best after any pre-processing of the input, i.e. after all macros,
1713             constants, etc. have been replaced by the real values.
1714             Returns 1 if yes.
1715              
1716             =cut
1717              
1718             sub is_valid_32bit_addr_intel($) {
1719              
1720 154447     154447 1 85403343 my $elem = shift;
1721             # [seg:base+index*scale+disp]
1722 154447 100 100     3927573 if ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1723             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
1724              
1725 27308         88668 return _validate_32bit_addr_parts_intel ($1, $2, $3, $4, $5, $6, $7, $8);
1726             }
1727             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
1728             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
1729              
1730 27308         96995 return _validate_32bit_addr_parts_intel ($1, $2, $3, $6, $7, $8, $4, $5);
1731             }
1732             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
1733             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
1734              
1735 26088         83062 return _validate_32bit_addr_parts_intel ($1, $5, $6, $2, $3, $4, $7, $8);
1736             }
1737             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
1738             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
1739              
1740 4168         14140 return _validate_32bit_addr_parts_intel ($1, undef, undef, $2, $3, $4, $5, $6);
1741             }
1742             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
1743             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
1744              
1745 8749         29162 return _validate_32bit_addr_parts_intel ($1, $2, $3, $4, $5, undef, $6, $7);
1746             }
1747             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
1748             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
1749              
1750 4440         15313 return _validate_32bit_addr_parts_intel ($1, $2, $3, $4, $5, $6, undef, undef);
1751             }
1752             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o
1753             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o) {
1754              
1755 174         571 return _validate_32bit_addr_parts_intel ($1, $2, $3, undef, undef, undef, undef, undef);
1756             }
1757             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
1758             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
1759              
1760 256         962 return _validate_32bit_addr_parts_intel ($1, undef, undef, $2, $3, $4, undef, undef);
1761             }
1762             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o
1763             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o) {
1764              
1765 5251         17559 return _validate_32bit_addr_parts_intel ($1, $2, $3, undef, undef, undef, $4, $5);
1766             }
1767             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
1768              
1769 13428         47102 return _validate_32bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, $6, $7);
1770             }
1771             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
1772              
1773 13427         47836 return _validate_32bit_addr_parts_intel (undef, $1, $2, $5, $6, $7, $3, $4);
1774             }
1775             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
1776              
1777 12828         47694 return _validate_32bit_addr_parts_intel (undef, $4, $5, $1, $2, $3, $6, $7);
1778             }
1779             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
1780              
1781 2033         7385 return _validate_32bit_addr_parts_intel (undef, undef, undef, $1, $2, $3, $4, $5);
1782             }
1783             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
1784              
1785 4043         13233 return _validate_32bit_addr_parts_intel (undef, $1, $2, $3, $4, undef, $5, $6);
1786             }
1787             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
1788              
1789 2164         7912 return _validate_32bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, undef, undef);
1790             }
1791             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o ) {
1792              
1793 83         274 return _validate_32bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, undef, undef);
1794             }
1795             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
1796              
1797 122         494 return _validate_32bit_addr_parts_intel (undef, undef, undef, $1, $2, $3, undef, undef);
1798             }
1799             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o ) {
1800              
1801 2542         8883 return _validate_32bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, $3, $4);
1802             }
1803 35         185 return 0;
1804             }
1805              
1806             # =head2 _validate_32bit_addr_parts_att
1807             #
1808             # PRIVATE SUBROUTINE.
1809             # Checks if the given address components give a valid x86 32-bit addressing
1810             # mode in AT&T syntax.
1811             # Returns 1 if yes.
1812             #
1813             # =cut
1814             sub _validate_32bit_addr_parts_att($$$$$$$$) {
1815              
1816 3076     3076   5676 my $segreg = shift;
1817 3076         4240 my $base_reg_sign = shift;
1818 3076         5223 my $base_reg = shift;
1819 3076         4002 my $index_reg_sign = shift;
1820 3076         4506 my $index_reg = shift;
1821 3076         4323 my $scale = shift;
1822 3076         4363 my $disp_sign = shift;
1823 3076         4881 my $disp = shift;
1824              
1825 3076 100 100     8934 return 0 if defined $segreg && ! is_segreg_att ($segreg);
1826 3033 100 100     11149 if ( defined $index_reg && ! defined $base_reg && ! defined $scale ) {
      100        
1827             # just one value inside - check for "(,1)
1828 215 100 100     690 return 1 if $index_reg eq '1' && ! is_reg_att($disp);
1829             }
1830 3028 100 100     8738 return 0 if defined $index_reg && (! is_reg_att($index_reg)
      100        
1831             || ! is_addressable32_att($index_reg) || $index_reg =~ /^%esp$/io);
1832 1800 100 66     4540 return 0 if defined $scale && ! is_reg_att($scale) && $scale != 1
      100        
      100        
      100        
      100        
1833             && $scale != 2 && $scale != 4 && $scale != 8;
1834 1784 100 100     4845 return 0 if defined $disp && is_reg_att($disp);
1835 1433 100 100     5813 if ( defined $base_reg && ! defined $index_reg && ! defined $scale ) {
      66        
1836             # just one value inside - allow '(var)' and 'var(%reg)', disallow 'var(var)'
1837 727 100 100     2420 return 0 if ( (defined $disp || $base_reg =~ /%/o)
      100        
      100        
      100        
      100        
      100        
      33        
      66        
1838             && ! is_addressable32_att($base_reg)
1839             && $base_reg !~ /^%bx$/io && $base_reg !~ /^%bp$/io
1840             && $base_reg !~ /^%si$/io && $base_reg !~ /^%di$/io)
1841             || (defined $base_reg_sign && $base_reg_sign =~ /-/o);
1842             } else {
1843             # more than one part - must be a 32-bit register
1844 706 100 100     1817 return 0 if defined $base_reg && ! is_addressable32_att($base_reg);
1845             }
1846 271         1622 return 1;
1847             }
1848              
1849             =head2 is_valid_32bit_addr_att
1850              
1851             Checks if the given string parameter (must contain the parentheses)
1852             is a valid x86 32-bit addressing mode in AT&T syntax.
1853             Works best after any pre-processing of the input, i.e. after all macros,
1854             constants, etc. have been replaced by the real values.
1855             Returns 1 if yes.
1856              
1857             =cut
1858              
1859             sub is_valid_32bit_addr_att($) {
1860              
1861 11296     11296 1 5948270 my $elem = shift;
1862 11296 100       292757 if ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*\)$/o ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1863              
1864 27         115 return _validate_32bit_addr_parts_att ($1, undef, $2, undef, undef, undef, undef, undef);
1865             }
1866             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1867              
1868 48         191 return _validate_32bit_addr_parts_att ($1, undef, $2, undef, $3, undef, undef, undef);
1869             }
1870             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1871              
1872 52         201 return _validate_32bit_addr_parts_att ($1, undef, $2, undef, $3, $4, undef, undef);
1873             }
1874             elsif ( $elem =~ /^([%\w]+):\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1875              
1876 28         104 return _validate_32bit_addr_parts_att ($1, undef, undef, undef, $2, $3, undef, undef);
1877             }
1878             elsif ( $elem =~ /^([%\w]+):\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1879              
1880 17         82 return _validate_32bit_addr_parts_att ($1, undef, undef, undef, $2, undef, undef, undef);
1881             }
1882             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1883              
1884 464         1389 return _validate_32bit_addr_parts_att ($1, undef, $4, undef, undef, undef, $2, $3);
1885             }
1886             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1887              
1888 221         743 return _validate_32bit_addr_parts_att ($1, undef, $4, undef, $5, undef, $2, $3);
1889             }
1890             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1891              
1892 393         1325 return _validate_32bit_addr_parts_att ($1, undef, $4, undef, $5, $6, $2, $3);
1893             }
1894             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1895              
1896 203         628 return _validate_32bit_addr_parts_att ($1, undef, undef, undef, $4, $5, $2, $3);
1897             }
1898             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1899              
1900 96         349 return _validate_32bit_addr_parts_att ($1, undef, undef, undef, $4, undef, $2, $3);
1901             }
1902             elsif ( $elem =~ /^\(\s*([%\w]+)\s*\)$/o ) {
1903              
1904 28         138 return _validate_32bit_addr_parts_att (undef, undef, $1, undef, undef, undef, undef, undef);
1905             }
1906             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1907              
1908 51         161 return _validate_32bit_addr_parts_att (undef, undef, $1, undef, $2, undef, undef, undef);
1909             }
1910             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1911              
1912 51         186 return _validate_32bit_addr_parts_att (undef, undef, $1, undef, $2, $3, undef, undef);
1913             }
1914             elsif ( $elem =~ /^\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1915              
1916 27         120 return _validate_32bit_addr_parts_att (undef, undef, undef, undef, $1, $2, undef, undef);
1917             }
1918             elsif ( $elem =~ /^\(\s*,\s*([%\w]+)\s*\)$/o ) {
1919              
1920 17         70 return _validate_32bit_addr_parts_att (undef, undef, undef, undef, $1, undef, undef, undef);
1921             }
1922             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1923              
1924 459         1365 return _validate_32bit_addr_parts_att (undef, undef, $3, undef, undef, undef, $1, $2);
1925             }
1926             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
1927              
1928 217         793 return _validate_32bit_addr_parts_att (undef, undef, $3, undef, $4, undef, $1, $2);
1929             }
1930             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1931              
1932 385         1264 return _validate_32bit_addr_parts_att (undef, undef, $3, undef, $4, $5, $1, $2);
1933             }
1934             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
1935              
1936 200         645 return _validate_32bit_addr_parts_att (undef, undef, undef, undef, $3, $4, $1, $2);
1937             }
1938             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1939              
1940 92         362 return _validate_32bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
1941             }
1942 8220         35726 return 0;
1943             }
1944              
1945             =head2 is_valid_32bit_addr
1946              
1947             Checks if the given string parameter (must contain the parentheses)
1948             is a valid x86 32-bit addressing mode in AT&T or Intel syntax.
1949             Works best after any pre-processing of the input, i.e. after all macros,
1950             constants, etc. have been replaced by the real values.
1951             Returns 1 if yes.
1952              
1953             =cut
1954              
1955             sub is_valid_32bit_addr($) {
1956              
1957 4     4 1 13 my $elem = shift;
1958 4         16 return is_valid_32bit_addr_intel ($elem)
1959             | is_valid_32bit_addr_att ($elem);
1960             }
1961              
1962             # =head2 _is_valid_64bit_addr_reg_att
1963             #
1964             # PRIVATE SUBROUTINE.
1965             # Checks if the given register can be used in x86 64-bit addressing
1966             # mode in Intel syntax.
1967             # Returns 1 if yes.
1968             #
1969             # =cut
1970             #
1971             sub _is_valid_64bit_addr_reg_intel($) {
1972              
1973 242259     242259   383504 my $reg = shift;
1974 242259 100 100     427533 return 1 if is_reg64_intel($reg) || is_r32_in64_intel($reg) || is_addressable32_intel($reg);
      100        
1975 118182         750925 return 0;
1976             }
1977              
1978             # =head2 _validate_64bit_addr_parts_intel
1979             #
1980             # PRIVATE SUBROUTINE.
1981             # Checks if the given address components give a valid x86 64-bit addressing
1982             # mode in Intel syntax.
1983             # Returns 1 if yes.
1984             #
1985             # =cut
1986             sub _validate_64bit_addr_parts_intel($$$$$$$$) {
1987              
1988 137817     137817   285079 my $segreg = shift;
1989 137817         250863 my $base_reg_sign = shift;
1990 137817         213052 my $base_reg = shift;
1991 137817         264158 my $index_reg_sign = shift;
1992 137817         203641 my $index_reg = shift;
1993 137817         195150 my $scale = shift;
1994 137817         190851 my $disp_sign = shift;
1995 137817         192410 my $disp = shift;
1996 137817         194933 my $was64 = 0;
1997 137817         168613 my $nregs = 0;
1998              
1999 137817 100 100     404245 return 0 if defined $segreg && ! is_segreg_intel($segreg);
2000 135409 100 100     419703 if ( defined $base_reg && is_reg_intel($base_reg) ) {
2001              
2002 90372 100       202169 return 0 if ! _is_valid_64bit_addr_reg_intel($base_reg);
2003 61329         103692 $nregs++;
2004 61329 100       114128 $was64++ if is_reg64_intel($base_reg);
2005             }
2006 106366 100 100     348066 if ( defined $index_reg && is_reg_intel($index_reg) ) {
2007              
2008 77825 100       180664 return 0 if ! _is_valid_64bit_addr_reg_intel($index_reg);
2009 34496         62268 $nregs++;
2010 34496 100       72971 $was64++ if is_reg64_intel($index_reg);
2011             }
2012 63037 100 100     195608 if ( defined $scale && is_reg_intel($scale) ) {
2013              
2014 41911 100       95732 return 0 if ! _is_valid_64bit_addr_reg_intel($scale);
2015 19108         31827 $nregs++;
2016 19108 100       30459 $was64++ if is_reg64_intel($scale);
2017             }
2018 40234 100 100     111924 if ( defined $disp && is_reg_intel($disp) ) {
2019              
2020 32151 100       71764 return 0 if ! _is_valid_64bit_addr_reg_intel($disp);
2021 9144         15350 $nregs++;
2022 9144 100       16706 $was64++ if is_reg64_intel($disp);
2023             }
2024 17227 100 100     83919 return 0 if $was64 != 0 && $was64 != $nregs;
2025              
2026 13720 100 100     55183 return 0 if defined $index_reg && defined $scale
      100        
      100        
2027             && is_reg_intel($index_reg) && is_reg_intel($scale);
2028 12844 100 66     49097 return 0 if defined $base_reg && defined $base_reg_sign
      100        
      100        
2029             && is_reg_intel($base_reg) && $base_reg_sign =~ /-/o;
2030 10902 100 66     48098 return 0 if defined $index_reg && defined $index_reg_sign
      100        
      100        
2031             && is_reg_intel($index_reg) && $index_reg_sign =~ /-/o;
2032 9771 100 66     40124 return 0 if defined $scale && defined $index_reg_sign
      100        
      100        
2033             && is_reg_intel($scale) && $index_reg_sign =~ /-/o;
2034 8781 100 66     43300 return 0 if defined $disp && defined $disp_sign
      100        
      100        
2035             && is_reg_intel($disp) && $disp_sign =~ /-/o;
2036 7573 100 100     29380 if ( defined $index_reg && defined $scale ) {
2037 7129 100 100     42995 return 0 if ( $index_reg =~ /\brsp\b/io || $index_reg =~ /\brip\b/io )
      100        
      100        
2038             && $scale =~ /\b\d+\b/o && $scale != 1;
2039 6823 100 100     38883 return 0 if ( $scale =~ /\brsp\b/io || $scale =~ /\brip\b/io )
      100        
      100        
2040             && $index_reg =~ /\b\d+\b/o && $index_reg != 1;
2041 6517 100 100     13225 return 0 if is_reg_intel($index_reg) && $scale =~ /\b\d+\b/o && $scale != 1
      100        
      100        
      100        
      100        
2042             && $scale != 2 && $scale != 4 && $scale != 8;
2043 6364 100 100     16002 return 0 if is_reg_intel($scale) && $index_reg =~ /\b\d+\b/o && $index_reg != 1
      100        
      100        
      100        
      100        
2044             && $index_reg != 2 && $index_reg != 4 && $index_reg != 8;
2045             }
2046 6655 100 100     37810 return 0 if defined $base_reg && defined $index_reg && defined $disp
      100        
      100        
      100        
      100        
2047             && is_reg_intel($base_reg) && is_reg_intel($index_reg) && is_reg_intel($disp);
2048 6583 100 100     34613 return 0 if defined $base_reg && defined $scale && defined $disp
      100        
      100        
      100        
      100        
2049             && is_reg_intel($base_reg) && is_reg_intel($scale) && is_reg_intel($disp);
2050              
2051 6547         48860 return 1;
2052             }
2053              
2054             =head2 is_valid_64bit_addr_intel
2055              
2056             Checks if the given string parameter (must contain the square braces)
2057             is a valid x86 64-bit addressing mode in Intel syntax.
2058             Works best after any pre-processing of the input, i.e. after all macros,
2059             constants, etc. have been replaced by the real values.
2060             Returns 1 if yes.
2061              
2062             =cut
2063              
2064             sub is_valid_64bit_addr_intel($) {
2065              
2066 137852     137852 1 79077445 my $elem = shift;
2067             # [seg:base+index*scale+disp]
2068 137852 100 100     3512871 if ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2069             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
2070              
2071 24164         84541 return _validate_64bit_addr_parts_intel ($1, $2, $3, $4, $5, $6, $7, $8);
2072             }
2073             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
2074             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
2075              
2076 24164         92821 return _validate_64bit_addr_parts_intel ($1, $2, $3, $6, $7, $8, $4, $5);
2077             }
2078             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
2079             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
2080              
2081 23160         79252 return _validate_64bit_addr_parts_intel ($1, $5, $6, $2, $3, $4, $7, $8);
2082             }
2083             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
2084             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
2085              
2086 3896         12963 return _validate_64bit_addr_parts_intel ($1, undef, undef, $2, $3, $4, $5, $6);
2087             }
2088             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o
2089             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o) {
2090              
2091 8193         28537 return _validate_64bit_addr_parts_intel ($1, $2, $3, $4, $5, undef, $6, $7);
2092             }
2093             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
2094             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
2095              
2096 4096         14268 return _validate_64bit_addr_parts_intel ($1, $2, $3, $4, $5, $6, undef, undef);
2097             }
2098             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o
2099             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o) {
2100              
2101 152         503 return _validate_64bit_addr_parts_intel ($1, $2, $3, undef, undef, undef, undef, undef);
2102             }
2103             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o
2104             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o) {
2105              
2106 288         993 return _validate_64bit_addr_parts_intel ($1, undef, undef, $2, $3, $4, undef, undef);
2107             }
2108             elsif ( $elem =~ /^\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o
2109             || $elem =~ /^(\w+)\s*:\s*\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o) {
2110              
2111 4551         14333 return _validate_64bit_addr_parts_intel ($1, $2, $3, undef, undef, undef, $4, $5);
2112             }
2113             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
2114              
2115 11856         44478 return _validate_64bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, $6, $7);
2116             }
2117             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
2118              
2119 11855         41781 return _validate_64bit_addr_parts_intel (undef, $1, $2, $5, $6, $7, $3, $4);
2120             }
2121             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
2122              
2123 11364         40540 return _validate_64bit_addr_parts_intel (undef, $4, $5, $1, $2, $3, $6, $7);
2124             }
2125             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
2126              
2127 1897         6642 return _validate_64bit_addr_parts_intel (undef, undef, undef, $1, $2, $3, $4, $5);
2128             }
2129             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]$/o ) {
2130              
2131 3765         13440 return _validate_64bit_addr_parts_intel (undef, $1, $2, $3, $4, undef, $5, $6);
2132             }
2133             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
2134              
2135 1992         7372 return _validate_64bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, undef, undef);
2136             }
2137             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\]/o ) {
2138              
2139 75         283 return _validate_64bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, undef, undef);
2140             }
2141             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]$/o ) {
2142              
2143 138         491 return _validate_64bit_addr_parts_intel (undef, undef, undef, $1, $2, $3, undef, undef);
2144             }
2145             elsif ( $elem =~ /^\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*\]$/o ) {
2146              
2147 2211         7520 return _validate_64bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, $3, $4);
2148             }
2149 35         181 return 0;
2150             }
2151              
2152             # =head2 _is_valid_64bit_addr_reg_att
2153             #
2154             # PRIVATE SUBROUTINE.
2155             # Checks if the given register can be used in x86 64-bit addressing
2156             # mode in AT&T syntax.
2157             # Returns 1 if yes.
2158             #
2159             # =cut
2160             #
2161             sub _is_valid_64bit_addr_reg_att($) {
2162              
2163 3843     3843   6706 my $reg = shift;
2164 3843 100 100     6771 return 1 if is_reg64_att($reg) || is_r32_in64_att($reg) || is_addressable32_att($reg);
      100        
2165 2281         14100 return 0;
2166             }
2167              
2168             # =head2 _validate_64bit_addr_parts_att
2169             #
2170             # PRIVATE SUBROUTINE.
2171             # Checks if the given address components give a valid x86 64-bit addressing
2172             # mode in AT&T syntax.
2173             # Returns 1 if yes.
2174             #
2175             # =cut
2176             sub _validate_64bit_addr_parts_att($$$$$$$$) {
2177              
2178 3006     3006   5806 my $segreg = shift;
2179 3006         4093 my $base_reg_sign = shift;
2180 3006         5211 my $base_reg = shift;
2181 3006         4176 my $index_reg_sign = shift;
2182 3006         5319 my $index_reg = shift;
2183 3006         4811 my $scale = shift;
2184 3006         4586 my $disp_sign = shift;
2185 3006         4386 my $disp = shift;
2186 3006         3698 my $was64 = 0;
2187 3006         4075 my $nregs = 0;
2188              
2189 3006 100 100     9352 return 0 if defined $segreg && ! is_segreg_att($segreg);
2190 2949 100       6126 if ( defined $base_reg ) {
2191              
2192 2301 50 66     6781 if ( ! defined $index_reg && ! defined $scale ) {
2193             # just one value inside - allow '(var)',
2194             # disallow 'var(var)', allow 'var(%reg)'
2195 851 50 100     3414 return 0 if ( (defined $disp || $base_reg =~ /%/o)
      66        
      66        
      33        
      66        
2196             && (! _is_valid_64bit_addr_reg_att($base_reg) || $base_reg =~ /^%rip$/io))
2197             || (defined $base_reg_sign && $base_reg_sign =~ /-/o);
2198             }
2199 1494 100 100     3608 return 0 if is_reg_att($base_reg)
      100        
2200             && (! _is_valid_64bit_addr_reg_att($base_reg) || $base_reg =~ /^%rip$/io);
2201 963         1626 $nregs++;
2202 963 100       1782 $was64++ if is_reg64_att($base_reg);
2203             }
2204 1611 100       3308 if ( defined $index_reg ) {
2205              
2206 1567 100 100     4123 if ( ! defined $base_reg && ! defined $scale ) {
2207             # just one value inside - check for "(,1)
2208 214 100 100     763 return 1 if $index_reg eq '1' && ! is_reg_att($disp);
2209             }
2210 1562 100       3187 return 0 if ! _is_valid_64bit_addr_reg_att($index_reg);
2211 587 100 100     2818 return 0 if $index_reg =~ /^%rsp$/io || $index_reg =~ /^%rip$/io;
2212 490         673 $nregs++;
2213 490 100       818 $was64++ if is_reg64_att($index_reg);
2214             }
2215 534 100 100     1630 return 0 if defined $disp && is_reg_att($disp);
2216 495 100 100     2295 return 0 if $was64 != 0 && $was64 != $nregs;
2217              
2218 328 50 100     1011 return 0 if defined $index_reg && defined $scale
      66        
      66        
2219             && is_reg_att($index_reg) && is_reg_att($scale);
2220 328 0 66     1053 return 0 if defined $base_reg && defined $base_reg_sign
      33        
      33        
2221             && is_reg_att($base_reg) && $base_reg_sign =~ /-/o;
2222 328 0 66     1043 return 0 if defined $index_reg && defined $index_reg_sign
      33        
      33        
2223             && is_reg_att($index_reg) && $index_reg_sign =~ /-/o;
2224 328 0 66     844 return 0 if defined $scale && defined $index_reg_sign
      33        
      33        
2225             && is_reg_att($scale) && $index_reg_sign =~ /-/o;
2226 328 50 66     1010 return 0 if defined $disp && defined $disp_sign
      66        
      33        
2227             && is_reg_att($disp) && $disp_sign =~ /-/o;
2228 328 100 66     713 return 0 if defined $scale && (is_reg_att($scale)
      100        
2229             || ($scale != 1 && $scale != 2 && $scale != 4 && $scale != 8));
2230 312 50 100     1246 return 0 if defined $base_reg && defined $index_reg && defined $disp
      100        
      66        
      66        
      33        
2231             && is_reg_att($base_reg) && is_reg_att($index_reg) && is_reg_att($disp);
2232 312 50 100     1230 return 0 if defined $base_reg && defined $scale && defined $disp
      100        
      66        
      66        
      33        
2233             && is_reg_att($base_reg) && is_reg_att($scale) && is_reg_att($disp);
2234              
2235 312         1683 return 1;
2236             }
2237              
2238             =head2 is_valid_64bit_addr_att
2239              
2240             Checks if the given string parameter (must contain the parentheses)
2241             is a valid x86 64-bit addressing mode in AT&T syntax.
2242             Works best after any pre-processing of the input, i.e. after all macros,
2243             constants, etc. have been replaced by the real values.
2244             Returns 1 if yes.
2245              
2246             =cut
2247              
2248             sub is_valid_64bit_addr_att($) {
2249              
2250 10078     10078 1 5446751 my $elem = shift;
2251 10078 100       255461 if ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*\)$/o ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2252              
2253 29         112 return _validate_64bit_addr_parts_att ($1, undef, $2, undef, undef, undef, undef, undef);
2254             }
2255             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
2256              
2257 53         238 return _validate_64bit_addr_parts_att ($1, undef, $2, undef, $3, undef, undef, undef);
2258             }
2259             elsif ( $elem =~ /^([%\w]+):\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2260              
2261 68         262 return _validate_64bit_addr_parts_att ($1, undef, $2, undef, $3, $4, undef, undef);
2262             }
2263             elsif ( $elem =~ /^([%\w]+):\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2264              
2265 30         146 return _validate_64bit_addr_parts_att ($1, undef, undef, undef, $2, $3, undef, undef);
2266             }
2267             elsif ( $elem =~ /^([%\w]+):\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
2268              
2269 19         80 return _validate_64bit_addr_parts_att ($1, undef, undef, undef, $2, undef, undef, undef);
2270             }
2271             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
2272              
2273 405         1166 return _validate_64bit_addr_parts_att ($1, undef, $4, undef, undef, undef, $2, $3);
2274             }
2275             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
2276              
2277 224         834 return _validate_64bit_addr_parts_att ($1, undef, $4, undef, $5, undef, $2, $3);
2278             }
2279             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2280              
2281 405         1497 return _validate_64bit_addr_parts_att ($1, undef, $4, undef, $5, $6, $2, $3);
2282             }
2283             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2284              
2285 191         652 return _validate_64bit_addr_parts_att ($1, undef, undef, undef, $4, $5, $2, $3);
2286             }
2287             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
2288              
2289 97         385 return _validate_64bit_addr_parts_att ($1, undef, undef, undef, $4, undef, $2, $3);
2290             }
2291             elsif ( $elem =~ /^\(\s*([%\w]+)\s*\)$/o ) {
2292              
2293 27         131 return _validate_64bit_addr_parts_att (undef, undef, $1, undef, undef, undef, undef, undef);
2294             }
2295             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
2296              
2297 55         226 return _validate_64bit_addr_parts_att (undef, undef, $1, undef, $2, undef, undef, undef);
2298             }
2299             elsif ( $elem =~ /^\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2300              
2301 66         297 return _validate_64bit_addr_parts_att (undef, undef, $1, undef, $2, $3, undef, undef);
2302             }
2303             elsif ( $elem =~ /^\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2304              
2305 29         107 return _validate_64bit_addr_parts_att (undef, undef, undef, undef, $1, $2, undef, undef);
2306             }
2307             elsif ( $elem =~ /^\(\s*,\s*([%\w]+)\s*\)$/o ) {
2308              
2309 19         84 return _validate_64bit_addr_parts_att (undef, undef, undef, undef, $1, undef, undef, undef);
2310             }
2311             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
2312              
2313 400         1206 return _validate_64bit_addr_parts_att (undef, undef, $3, undef, undef, undef, $1, $2);
2314             }
2315             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*\)$/o ) {
2316              
2317 217         767 return _validate_64bit_addr_parts_att (undef, undef, $3, undef, $4, undef, $1, $2);
2318             }
2319             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2320              
2321 394         1406 return _validate_64bit_addr_parts_att (undef, undef, $3, undef, $4, $5, $1, $2);
2322             }
2323             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*,\s*(\d+)\s*\)$/o ) {
2324              
2325 188         595 return _validate_64bit_addr_parts_att (undef, undef, undef, undef, $3, $4, $1, $2);
2326             }
2327             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
2328              
2329 90         369 return _validate_64bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
2330             }
2331 7072         30263 return 0;
2332             }
2333              
2334             =head2 is_valid_64bit_addr
2335              
2336             Checks if the given string parameter (must contain the parentheses)
2337             is a valid x86 64-bit addressing mode in AT&T or Intel syntax.
2338             Works best after any pre-processing of the input, i.e. after all macros,
2339             constants, etc. have been replaced by the real values.
2340             Returns 1 if yes.
2341              
2342             =cut
2343              
2344             sub is_valid_64bit_addr($) {
2345              
2346 4     4 1 14 my $elem = shift;
2347 4         15 return is_valid_64bit_addr_intel ($elem)
2348             | is_valid_64bit_addr_att ($elem);
2349             }
2350              
2351             =head2 is_valid_addr_intel
2352              
2353             Checks if the given string parameter (must contain the square braces)
2354             is a valid x86 addressing mode in Intel syntax.
2355             Works best after any pre-processing of the input, i.e. after all macros,
2356             constants, etc. have been replaced by the real values.
2357             Returns 1 if yes.
2358              
2359             =cut
2360              
2361             sub is_valid_addr_intel($) {
2362              
2363 33     33 1 12111 my $elem = shift;
2364 33         92 return is_valid_16bit_addr_intel ($elem)
2365             | is_valid_32bit_addr_intel ($elem)
2366             | is_valid_64bit_addr_intel ($elem);
2367             }
2368              
2369             =head2 is_valid_addr_att
2370              
2371             Checks if the given string parameter (must contain the braces)
2372             is a valid x86 addressing mode in AT&T syntax.
2373             Works best after any pre-processing of the input, i.e. after all macros,
2374             constants, etc. have been replaced by the real values.
2375             Returns 1 if yes.
2376              
2377             =cut
2378              
2379             sub is_valid_addr_att($) {
2380              
2381 35     35 1 13498 my $elem = shift;
2382 35         102 return is_valid_16bit_addr_att($elem)
2383             | is_valid_32bit_addr_att($elem)
2384             | is_valid_64bit_addr_att($elem);
2385             }
2386              
2387             =head2 is_valid_addr
2388              
2389             Checks if the given string parameter (must contain the square braces)
2390             is a valid x86 addressing mode (Intel or AT&T syntax).
2391             Works best after any pre-processing of the input, i.e. after all macros,
2392             constants, etc. have been replaced by the real values.
2393             Returns 1 if yes.
2394              
2395             =cut
2396              
2397             sub is_valid_addr($) {
2398              
2399 10     10 1 35 my $elem = shift;
2400 10         36 return is_valid_addr_intel($elem)
2401             | is_valid_addr_att($elem);
2402             }
2403              
2404             =head2 is_att_suffixed_instr
2405              
2406             Tells if the given instruction is suffixed in AT&T syntax.
2407             Returns 1 if yes.
2408              
2409             =cut
2410              
2411             sub is_att_suffixed_instr($) {
2412              
2413 24137     24137 1 33366 return _is_in_array (shift, \@att_suff_instr);
2414             }
2415              
2416             =head2 is_att_suffixed_instr_fpu
2417              
2418             Tells if the given FPU non-integer instruction is suffixed in AT&T syntax.
2419             Returns 1 if yes
2420              
2421             =cut
2422              
2423             sub is_att_suffixed_instr_fpu($) {
2424              
2425 23777     23777 1 36653 return _is_in_array (shift, \@att_suff_instr_fpu);
2426             }
2427              
2428             =head2 add_att_suffix_instr
2429              
2430             Creates the AT&T syntax instruction array from the Intel-syntax array.
2431             Returns the new array.
2432              
2433             =cut
2434              
2435             sub add_att_suffix_instr(@) {
2436              
2437 26     26 1 14629 my @result = ();
2438 26         56 foreach (@_) {
2439 24137 100       33105 if ( is_att_suffixed_instr ($_) ) {
2440              
2441 220         501 push @result, $_.'b';
2442 220         370 push @result, $_.'w';
2443 220         345 push @result, $_.'l';
2444 220         437 push @result, $_.'q';
2445             }
2446             else {
2447             # FPU instructions
2448 23917 100       49776 if ( /^fi(\w+)/io ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2449              
2450 140         562 push @result, $_.'s';
2451 140         208 push @result, $_.'l';
2452 140         249 push @result, $_.'q';
2453             }
2454             elsif ( is_att_suffixed_instr_fpu ($_) ) {
2455              
2456 280         575 push @result, $_.'s';
2457 280         422 push @result, $_.'l';
2458 280         506 push @result, $_.'t';
2459             }
2460             elsif ( /^\s*(mov[sz])x\s+([^,]+)\s*,\s*([^,]+)(.*)/io ) {
2461              
2462             # add suffixes to MOVSX/MOVZX instructions
2463 15         22 my ($inst, $arg1, $arg2, $rest, $z1, $z2);
2464 15         33 $inst = $1;
2465 15         29 $z1 = $2;
2466 15         19 $z2 = $3;
2467 15         28 $rest = $4;
2468 15         53 ($arg1 = $z1) =~ s/\s*$//o;
2469 15         45 ($arg2 = $z2) =~ s/\s*$//o;
2470 15 100 100     29 if ( is_reg8($arg2) && is_reg32($arg1) ) {
    100 100        
    100 100        
    100 100        
    100 100        
2471 2         7 push @result, "${inst}bl";
2472             } elsif ( is_reg8($arg2) && is_reg16($arg1) ) {
2473 2         7 push @result, "${inst}bw";
2474             } elsif ( is_reg8($arg2) && is_reg64($arg1) ) {
2475 2         7 push @result, "${inst}bq";
2476             } elsif ( is_reg16($arg2) && is_reg32($arg1) ) {
2477 2         6 push @result, "${inst}wl";
2478             } elsif ( is_reg16($arg2) && is_reg64($arg1) ) {
2479 2         7 push @result, "${inst}wq";
2480             }
2481 15         39 push @result, "$_";
2482             }
2483             elsif ( /^\s*(mov[sz])x/io ) {
2484              
2485             # add suffixes to MOVSX/MOVZX instructions
2486 32         134 push @result, "$1bl";
2487 32         75 push @result, "$1bw";
2488 32         63 push @result, "$1bq";
2489 32         61 push @result, "$1wl";
2490 32         59 push @result, "$1wq";
2491 32         71 push @result, "$_";
2492             }
2493             elsif ( /^\s*cbw\b/io ) {
2494              
2495 10         40 push @result, 'cbtw';
2496             }
2497             elsif ( /^\s*cwde\b/io ) {
2498              
2499 10         44 push @result, 'cwtl';
2500             }
2501             elsif ( /^\s*cwd\b/io ) {
2502              
2503 10         60 push @result, 'cwtd';
2504             }
2505             elsif ( /^\s*cdq\b/io ) {
2506              
2507 10         31 push @result, 'cltd';
2508             }
2509             else {
2510 23410         48283 push @result, "$_";
2511             }
2512             }
2513             }
2514             # adding AT&T suffixes can create duplicate entries. Remove them here:
2515 26         464 return _remove_duplicates (@result);
2516             }
2517              
2518             =head2 conv_att_addr_to_intel
2519              
2520             Converts the given string representing a valid AT&T addressing mode to Intel syntax.
2521             Works best after any pre-processing of the input, i.e. after all macros,
2522             constants, etc. have been replaced by the real values.
2523             Returns the resulting string.
2524              
2525             =cut
2526              
2527             sub conv_att_addr_to_intel($) {
2528              
2529 54     54 1 2597 my $par = shift;
2530 54         144 $par =~ s/%([a-zA-Z]+)/$1/go;
2531             # seg: disp(base, index, scale)
2532 54         115 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$3+$5*$4+$2]/o;
2533 54         109 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$1$3+$4+$2]/o;
2534 54         112 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$2+$3*$4]/o;
2535 54         125 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$1$2+$3]/o;
2536 54         111 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*,\s*1\s*\)/[$1$2]/o;
2537 54         105 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$3*$4+$2]/o;
2538 54         118 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*\)/[$1$3+$2]/o;
2539 54         99 $par =~ s/(\w+\s*:\s*)\s*\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$2*$3]/o;
2540 54         123 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*\)/[$1$2]/o;
2541              
2542             # disp(base, index, scale)
2543 54         155 $par =~ s/([\w\+\-\(\)]+)\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$2+$3*$4+$1]/o;
2544 54         134 $par =~ s/([\w\+\-\(\)]+)\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$2+$3+$1]/o;
2545 54         127 $par =~ s/\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/\t[$1+$2*$3]/o;
2546 54         125 $par =~ s/\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/\t[$1+$2]/o;
2547 54         109 $par =~ s/([\w\+\-\(\)]+)\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$2*$3+$1]/o;
2548 54         123 $par =~ s/\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1*$2]/o;
2549              
2550             # disp(, index)
2551 54         158 $par =~ s/([\w\-\+\(\)]+)\(\s*,\s*1\s*\)/[$1]/o;
2552 54         117 $par =~ s/([\w\-\+\(\)]+)\(\s*,\s*(\w+)\s*\)/[$2+$1]/o;
2553              
2554             # (base, index)
2555 54         131 $par =~ s/\(\s*,\s*1\s*\)/[$1]/o;
2556 54         140 $par =~ s/\(\s*,\s*(\w+)\s*\)/[$1]/o;
2557              
2558             # disp(base)
2559 54 100       203 $par =~ s/([\w\-\+\(\)]+)\(\s*(\w+)\s*\)/[$2+$1]/o unless $par =~ /st\(\d\)/io;
2560 54 100       302 $par =~ s/\(\s*(\w+)\s*\)/[$1]/o unless $par =~ /st\(\d\)/io;
2561              
2562 54         158 return $par;
2563             }
2564              
2565             =head2 conv_intel_addr_to_att
2566              
2567             Converts the given string representing a valid Intel addressing mode to AT&T syntax.
2568             Works best after any pre-processing of the input, i.e. after all macros,
2569             constants, etc. have been replaced by the real values.
2570             Returns the resulting string.
2571              
2572             =cut
2573              
2574             sub conv_intel_addr_to_att($) {
2575              
2576 423     423 1 139684 my $par = shift;
2577 423         741 my ($a1, $a2, $a3, $z1, $z2, $z3);
2578             # seg: disp(base, index, scale)
2579             # [seg:base+index*scale+disp]
2580 423 100       7261 if ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2581              
2582 17         52 $a1 = $2;
2583 17         36 $a2 = $4;
2584 17         36 $a3 = $7;
2585 17         42 $z1 = _nopluses($a1);
2586 17         41 $z2 = _nopluses($a2);
2587 17         34 $z3 = _nopluses($a3);
2588 17 100 100     51 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2589 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($3,$5,$6)/o;
2590             } elsif ( is_reg($3) && is_reg($6) ) {
2591 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($3,$6,$5)/o;
2592             } elsif ( is_reg($5) && is_reg($8) ) {
2593 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($8,$5,$6)/o;
2594             } elsif ( is_reg($6) && is_reg($8) ) {
2595 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($8,$6,$5)/o;
2596             } elsif ( is_reg($3) && is_reg($8) ) {
2597 4         61 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5*$6)$9($3,$8)/o;
2598             } elsif ( is_reg($3) ) {
2599 2         34 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z2$5*$6)$9($3)/o;
2600             } elsif ( is_reg($5) ) {
2601 2         35 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z1$3)$9(,$5,$6)/o;
2602             } elsif ( is_reg($6) ) {
2603 2         30 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z1$3)$9(,$6,$5)/o;
2604             } elsif ( is_reg($8) ) {
2605 2         35 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6)$9($8)/o;
2606             } else {
2607 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6$z3$8)$9(,1)/o;
2608             }
2609             }
2610             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o ) {
2611              
2612 17         53 $a1 = $2;
2613 17         46 $a2 = $4;
2614 17         41 $a3 = $6;
2615 17         53 $z1 = _nopluses($a1);
2616 17         40 $z2 = _nopluses($a2);
2617 17         36 $z3 = _nopluses($a3);
2618 17 100 100     44 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2619 4         59 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z3$7*$8)$9($3,$5)/o;
2620             } elsif ( is_reg($5) && is_reg($7) ) {
2621 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($5,$7,$8)/o;
2622             } elsif ( is_reg($5) && is_reg($8) ) {
2623 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($5,$8,$7)/o;
2624             } elsif ( is_reg($3) && is_reg($7) ) {
2625 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$9($3,$7,$8)/o;
2626             } elsif ( is_reg($3) && is_reg($8) ) {
2627 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$9($3,$8,$7)/o;
2628             } elsif ( is_reg($3) ) {
2629 2         33 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5$z3$7*$8)$9($3)/o;
2630             } elsif ( is_reg($5) ) {
2631 2         41 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z3$7*$8)$9($5)/o;
2632             } elsif ( is_reg($7) ) {
2633 2         33 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$9(,$7,$8)/o;
2634             } elsif ( is_reg($8) ) {
2635 2         33 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$9(,$8,$7)/o;
2636             } else {
2637 1         17 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5$z3$7*$8)$9(,1)/o;
2638             }
2639             }
2640             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2641              
2642 17         53 $a1 = $2;
2643 17         36 $a2 = $5;
2644 17         43 $a3 = $7;
2645 17         45 $z1 = _nopluses($a1);
2646 17         44 $z2 = _nopluses($a2);
2647 17         39 $z3 = _nopluses($a3);
2648 17 100 100     52 if ( is_reg($3) && is_reg($6) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2649 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($6,$3,$4)/o;
2650             } elsif ( is_reg($4) && is_reg($6) ) {
2651 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($6,$4,$3)/o;
2652             } elsif ( is_reg($6) && is_reg($8) ) {
2653 4         68 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4)$9($6,$8)/o;
2654             } elsif ( is_reg($3) && is_reg($8) ) {
2655 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$9($8,$3,$4)/o;
2656             } elsif ( is_reg($4) && is_reg($8) ) {
2657 1         18 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$9($8,$4,$3)/o;
2658             } elsif ( is_reg($3) ) {
2659 2         32 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6$z3$8)$9(,$3,$4)/o;
2660             } elsif ( is_reg($4) ) {
2661 2         33 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6$z3$8)$9(,$4,$3)/o;
2662             } elsif ( is_reg($6) ) {
2663 2         34 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z3$8)$9($6)/o;
2664             } elsif ( is_reg($8) ) {
2665 2         34 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6)$9($8)/o;
2666             } else {
2667 1         18 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6$z3$8)$9(,1)/o;
2668             }
2669             }
2670             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2671              
2672 7         24 $a1 = $2;
2673 7         21 $a2 = $4;
2674 7         16 $a3 = $6;
2675 7         20 $z1 = _nopluses($a1);
2676 7         16 $z2 = _nopluses($a2);
2677 7         17 $z3 = _nopluses($a3);
2678 7 100 100     21 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100          
    100          
    100          
2679 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$7)$8($3,$5,)/o;
2680             } elsif ( is_reg($3) && is_reg($7) ) {
2681 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$8($3,$7,)/o;
2682             } elsif ( is_reg($5) && is_reg($7) ) {
2683 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$8($7,$5,)/o;
2684             } elsif ( is_reg($3) ) {
2685 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$5$z3$7)$8($3)/o;
2686             } elsif ( is_reg($5) ) {
2687 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z3$7)$8($5)/o;
2688             } elsif ( is_reg($7) ) {
2689 1         18 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$8($7)/o;
2690             } else {
2691 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5$z3$7)$8(,1)/o;
2692             }
2693             }
2694             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o ) {
2695              
2696 7         25 $a1 = $2;
2697 7         19 $a2 = $4;
2698 7         21 $z1 = _nopluses($a1);
2699 7         18 $z2 = _nopluses($a2);
2700 7 100 100     20 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100          
    100          
    100          
2701 1         12 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($3,$5,$6)/o;
2702             } elsif ( is_reg($3) && is_reg($6) ) {
2703 1         14 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($3,$6,$5)/o;
2704             } elsif ( is_reg($3) ) {
2705 2         26 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5*$6)$7($3)/o;
2706             } elsif ( is_reg($5) ) {
2707 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$7(,$5,$6)/o;
2708             } elsif ( is_reg($6) ) {
2709 1         14 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$7(,$6,$5)/o;
2710             } else {
2711 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6)$7(,1)/o;
2712             }
2713             }
2714             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2715              
2716 5         18 $a1 = $2;
2717 5         14 $a2 = $4;
2718 5         125 $z1 = _nopluses($a1);
2719 5         13 $z2 = _nopluses($a2);
2720 5 100 100     15 if ( is_reg($3) && is_reg($5) ) {
    100          
    100          
2721 1         12 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($3,$5,)/o;
2722             } elsif ( is_reg($3) ) {
2723 2         24 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$6($3)/o;
2724             } elsif ( is_reg($5) ) {
2725 1         14 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$6($5)/o;
2726             } else {
2727 1         15 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$6(,1)/o;
2728             }
2729             }
2730             elsif ( $par =~ /\[\s*(\w+)\s*:\s*(\w+)\s*\]/o ) {
2731              
2732 2 100       11 if ( is_reg($2) ) {
2733 1         12 $par =~ s/\[\s*(\w+)\s*:\s*(\w+)\s*\]/$1:($2)/o;
2734             } else {
2735 1         15 $par =~ s/\[\s*(\w+)\s*:\s*(\w+)\s*\]/$1:$2(,1)/o;
2736             }
2737             }
2738             elsif ( $par =~ /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2739              
2740 7         24 $a1 = $2;
2741 7         15 $a2 = $5;
2742 7         23 $z1 = _nopluses($a1);
2743 7         20 $z2 = _nopluses($a2);
2744 7 100 100     20 if ( is_reg($3) && is_reg($6) ) {
    100 100        
    100          
    100          
    100          
2745 1         14 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($6,$3,$4)/o;
2746             } elsif ( is_reg($4) && is_reg($6) ) {
2747 1         12 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($6,$4,$3)/o;
2748             } elsif ( is_reg($3) ) {
2749 1         16 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$7(,$3,$4)/o;
2750             } elsif ( is_reg($4) ) {
2751 1         14 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$7(,$4,$3)/o;
2752             } elsif ( is_reg($6) ) {
2753 2         25 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4)$7($6)/o;
2754             } else {
2755 1         18 $par =~ s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6)$7(,1)/o;
2756             }
2757             }
2758              
2759             # disp(base, index, scale)
2760             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2761 50         160 $a1 = $1;
2762 50         106 $a2 = $3;
2763 50         99 $a3 = $6;
2764 50         141 $z1 = _nopluses($a1);
2765 50         111 $z2 = _nopluses($a2);
2766 50         116 $z3 = _nopluses($a3);
2767 50 100 100     115 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2768 19         247 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($2,$4,$5)/o;
2769             } elsif ( is_reg($2) && is_reg($5) ) {
2770 2         35 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($2,$5,$4)/o;
2771             } elsif ( is_reg($2) && is_reg($7) ) {
2772 8         117 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4*$5)$8($2,$7)/o;
2773             } elsif ( is_reg($4) && is_reg($7) ) {
2774 2         31 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($7,$4,$5)/o;
2775             } elsif ( is_reg($5) && is_reg($7) ) {
2776 2         29 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($7,$5,$4)/o;
2777             } elsif ( is_reg($2) ) {
2778 4         60 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7$z2$4*$5)$8($2)/o;
2779             } elsif ( is_reg($4) ) {
2780 4         56 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7+$z1$2)$8(,$4,$5)/o;
2781             } elsif ( is_reg($5) ) {
2782 4         63 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7+$z1$2)$8(,$5,$4)/o;
2783             } elsif ( is_reg($7) ) {
2784 4         60 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5)$8($7)/o;
2785             } else {
2786 1         15 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5$z3$7)$8(,1)/o;
2787             }
2788             }
2789             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2790 33         86 $a1 = $1;
2791 33         72 $a2 = $4;
2792 33         63 $a3 = $6;
2793 33         78 $z1 = _nopluses($a1);
2794 33         95 $z2 = _nopluses($a2);
2795 33         71 $z3 = _nopluses($a3);
2796 33 100 100     466 if ( is_reg($2) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2797 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($5,$2,$3)/o;
2798             } elsif ( is_reg($3) && is_reg($5) ) {
2799 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($5,$3,$2)/o;
2800             } elsif ( is_reg($2) && is_reg($7) ) {
2801 2         29 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$8($7,$2,$3)/o;
2802             } elsif ( is_reg($3) && is_reg($7) ) {
2803 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$8($7,$3,$2)/o;
2804             } elsif ( is_reg($5) && is_reg($7) ) {
2805 8         118 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3)$8($5,$7)/o;
2806             } elsif ( is_reg($2) ) {
2807 4         60 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5$z3$7)$8(,$2,$3)/o;
2808             } elsif ( is_reg($3) ) {
2809 4         63 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5$z3$7)$8(,$3,$2)/o;
2810             } elsif ( is_reg($5) ) {
2811 4         57 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z3$7)$8($5)/o;
2812             } elsif ( is_reg($7) ) {
2813 4         57 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5)$8($7)/o;
2814             } else {
2815 1         17 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5$z3$7)$8(,1)/o;
2816             }
2817             }
2818             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o ) {
2819 33         92 $a1 = $1;
2820 33         69 $a2 = $3;
2821 33         69 $a3 = $5;
2822 33         84 $z1 = _nopluses($a1);
2823 33         102 $z2 = _nopluses($a2);
2824 33         72 $z3 = _nopluses($a3);
2825 33 100 100     86 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2826 8         109 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z3$6*$7)$8($2,$4)/o;
2827             } elsif ( is_reg($2) && is_reg($6) ) {
2828 2         28 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4)$8($2,$6,$7)/o;
2829             } elsif ( is_reg($2) && is_reg($7) ) {
2830 2         34 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4)$8($2,$7,$6)/o;
2831             } elsif ( is_reg($4) && is_reg($6) ) {
2832 2         32 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($4,$6,$7)/o;
2833             } elsif ( is_reg($4) && is_reg($7) ) {
2834 2         29 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($4,$7,$6)/o;
2835             } elsif ( is_reg($2) ) {
2836 4         61 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4$z3$6*$7)$8($2)/o;
2837             } elsif ( is_reg($4) ) {
2838 4         65 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z3$6*$7$z1$2)$8($4)/o;
2839             } elsif ( is_reg($6) ) {
2840 4         60 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$8(,$6,$7)/o;
2841             } elsif ( is_reg($7) ) {
2842 4         64 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$8(,$7,$6)/o;
2843             } else {
2844 1         17 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4$z3$6*$7)$8(,1)/o;
2845             }
2846             }
2847             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2848 13         39 $a1 = $1;
2849 13         27 $a2 = $3;
2850 13         29 $a3 = $5;
2851 13         32 $z1 = _nopluses($a1);
2852 13         28 $z2 = _nopluses($a2);
2853 13         33 $z3 = _nopluses($a3);
2854 13 100 100     32 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100          
    100          
    100          
2855 2         31 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6)$7($2,$4)/o;
2856             } elsif ( is_reg($2) && is_reg($6) ) {
2857 2         33 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4)$7($2,$6)/o;
2858             } elsif ( is_reg($4) && is_reg($6) ) {
2859 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$7($4,$6)/o;
2860             } elsif ( is_reg($2) ) {
2861 2         28 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6$z2$4)$7($2)/o;
2862             } elsif ( is_reg($4) ) {
2863 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6+$z1$2)$7($4)/o;
2864             } elsif ( is_reg($6) ) {
2865 2         27 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$7($6)/o;
2866             } else {
2867 1         14 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4$z3$6)$7(,1)/o;
2868             }
2869             }
2870             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o ) {
2871 13         51 $a1 = $1;
2872 13         32 $a2 = $3;
2873 13         35 $z1 = _nopluses($a1);
2874 13         30 $z2 = _nopluses($a2);
2875 13 100 100     42 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100          
    100          
    100          
2876 2         27 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($2,$4,$5)/o;
2877             } elsif ( is_reg($2) && is_reg($5) ) {
2878 2         24 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($2,$5,$4)/o;
2879             } elsif ( is_reg($2) ) {
2880 4         54 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4*$5)$6($2)/o;
2881             } elsif ( is_reg($4) ) {
2882 2         30 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$6(,$4,$5)/o;
2883             } elsif ( is_reg($5) ) {
2884 2         32 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$6(,$5,$4)/o;
2885             } else {
2886 1         14 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5)$6(,1)/o;
2887             }
2888             }
2889             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2890 9         28 $a1 = $1;
2891 9         26 $a2 = $3;
2892 9         22 $z1 = _nopluses($a1);
2893 9         24 $z2 = _nopluses($a2);
2894 9 100 100     45 if ( is_reg($2) && is_reg($4) ) {
    100          
    100          
2895 2         24 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($2,$4)/o;
2896             } elsif ( is_reg($2) ) {
2897 4         54 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4)$5($2)/o;
2898             } elsif ( is_reg($4) ) {
2899 2         25 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$5($4)/o;
2900             } else {
2901 1         13 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($2$z2$4)$5(,1)/o;
2902             }
2903             }
2904             elsif ( $par =~ /\[\s*(\w+)\s*\]/o ) {
2905 122 100       271 if ( is_reg($1) ) {
2906             # disp(base)
2907 110         799 $par =~ s/\[\s*(\w+)\s*\]/($1)/o;
2908             } else {
2909 12         108 $par =~ s/\[\s*(\w+)\s*\]/$1(,1)/o;
2910             }
2911             }
2912             elsif ( $par =~ /\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o ) {
2913 13         48 $a1 = $1;
2914 13         31 $a2 = $4;
2915 13         31 $z1 = _nopluses($a1);
2916 13         31 $z2 = _nopluses($a2);
2917 13 100 100     36 if ( is_reg($2) && is_reg($5) ) {
    100 100        
    100          
    100          
    100          
2918 2         26 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($5,$2,$3)/o;
2919             } elsif ( is_reg($3) && is_reg($5) ) {
2920 2         25 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($5,$3,$2)/o;
2921             } elsif ( is_reg($2) ) {
2922 2         28 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$6(,$2,$3)/o;
2923             } elsif ( is_reg($3) ) {
2924 2         29 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$6(,$3,$2)/o;
2925             } elsif ( is_reg($5) ) {
2926 4         57 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3)$6($5)/o;
2927             } else {
2928 1         12 $par =~ s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5)$6(,1)/o;
2929             }
2930             }
2931 423         1099 foreach my $i (@regs_intel) {
2932 90522         545494 $par =~ s/\b($i)\b/%$1/;
2933             }
2934              
2935 423         936 foreach my $r (@regs_intel) {
2936              
2937 90522         433048 $par =~ s/\%\%$r\b/\%$r/gi;
2938             }
2939 423         1744 return $par;
2940             }
2941              
2942             =head2 conv_att_instr_to_intel
2943              
2944             Converts the given string representing a valid AT&T instruction to Intel syntax.
2945             Works best after any pre-processing of the input, i.e. after all macros,
2946             constants, etc. have been replaced by the real values.
2947             Returns the resulting string.
2948              
2949             =cut
2950              
2951             sub conv_att_instr_to_intel($) {
2952              
2953 51     51 1 56034 my $par = shift;
2954             # (changing "xxx" to "[xxx]", if there's no '$' or '%')
2955              
2956             # (elements of memory operands mustn't be taken as instruction operands, so there are no '()'s here)
2957 51 100       458 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)/o ) {
2958              
2959 13         35 my ($a1, $a2, $a3, $a4);
2960              
2961 13         46 $a1 = $1;
2962 13         43 $a2 = $2;
2963 13         39 $a3 = $3;
2964 13         51 $a4 = $4;
2965              
2966             # (don't touch "call/jmp xxx")
2967             #if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
2968              
2969             # (we mustn't change digits and %st(n))
2970 13 100 100     157 if ( $a2 !~ /\$/o && $a2 !~ /\%/o && $a2 !~ /_L\d+/o && $a2 =~ /[a-zA-Z_\.]/o ) {
      100        
2971              
2972 1         5 $a2 = "[$a2]";
2973             }
2974 13 100 100     126 if ( $a3 !~ /\$/o && $a3 !~ /\%/o && $a3 !~ /_L\d+/o && $a3 =~ /[a-zA-Z_\.]/o ) {
      100        
2975              
2976 1         3 $a3 = "[$a3]";
2977             }
2978 13 100 100     110 if ( $a4 !~ /\$/o && $a4 !~ /\%/o && $a4 !~ /_L\d+/o && $a4 =~ /[a-zA-Z_\.]/o ) {
      100        
2979              
2980 1         4 $a4 = "[$a4]";
2981             }
2982              
2983             # (ATTENTION: operand order will be changed later)
2984 13         73 $par = "\t$a1\t$a2, $a3, $a4\n";
2985             #}
2986             }
2987              
2988 51 100       294 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)\s*$/o ) {
2989              
2990 11         25 my ($a1, $a2, $a3);
2991              
2992 11         32 $a1 = $1;
2993 11         31 $a2 = $2;
2994 11         30 $a3 = $3;
2995              
2996             # (don't touch "call/jmp xxx")
2997             #if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
2998              
2999             # (we mustn't change digits and %st(n))
3000 11 100 100     119 if ( $a2 !~ /\$/o && $a2 !~ /\%/o && $a2 !~ /_L\d+/o && $a2 =~ /[a-zA-Z_\.]/o ) {
      100        
3001              
3002 1         4 $a2 = "[$a2]";
3003             }
3004 11 100 100     144 if ( $a3 !~ /\$/o && $a3 !~ /\%/o && $a3 !~ /_L\d+/o && $a3 =~ /[a-zA-Z_\.]/o ) {
      100        
3005              
3006 1         4 $a3 = "[$a3]";
3007             }
3008              
3009             # (ATTENTION: operand order will be changed later)
3010 11         47 $par = "\t$a1\t$a2, $a3\n";
3011             #}
3012             }
3013              
3014 51 100       283 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*\s*$/o ) {
3015              
3016 8         18 my ($a1, $a2);
3017              
3018 8         27 $a1 = $1;
3019 8         26 $a2 = $2;
3020              
3021             # (don't touch "call/jmp xxx")
3022 8 100 100     75 if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
3023              
3024             # (we mustn't change digits and %st(n))
3025 6 100 100     66 if ( $a2 !~ /\$/o && $a2 !~ /\%/o && $a2 !~ /_L\d+/o && $a2 =~ /[a-zA-Z_\.]/o ) {
      100        
3026              
3027 1         5 $a2 = "[$a2]";
3028             }
3029              
3030             # (ATTENTION: operand order will be changed later)
3031 6         24 $par = "\t$a1\t$a2\n";
3032             }
3033             }
3034              
3035             # (removing dollar chars)
3036 51         200 $par =~ s/\$//go;
3037             # (removing percent chars)
3038 51         229 $par =~ s/%//go;
3039             # (removing asterisk chars)
3040 51         130 $par =~ s/\*//go;
3041              
3042             # (changing memory references):
3043 51         221 $par = conv_att_addr_to_intel $par;
3044              
3045             # (changing "st[N]" to "stN")
3046 51         196 $par =~ s/(\s)st\[(\d)\]/$1 st$2/go;
3047             # (changing "st" to "st0")
3048 51         137 $par =~ s/(\s)st(\s|,)/$1 st0$2/go;
3049              
3050              
3051             # (changing operands' order):
3052 51 100       283 if ( $par =~ /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)/o ) {
3053 22 100       104 if ( is_instr($1) ) {
3054 20         454 $par =~ s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)/\t$1\t$4, $3, $2/o;
3055             }
3056             }
3057 51 100       401 if ( $par =~ /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/o ) {
3058 17 100       68 if ( is_instr($1) ) {
3059 15         355 $par =~ s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$3, $2$4/o;
3060             }
3061             }
3062 51 100       353 if ( $par =~ /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/o ) {
3063 12 100       52 if ( is_instr($1) ) {
3064 10         185 $par =~ s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$2$3/o;
3065             }
3066             }
3067              
3068 51         199 foreach my $i (@instr) {
3069              
3070 134385         1623616 $par =~ s/^\s*$i[b]\s*(.*)$/\t$i\tbyte $1/i;
3071 134385         1611565 $par =~ s/^\s*$i[w]\s*(.*)$/\t$i\tword $1/i;
3072 134385         1696327 $par =~ s/^\s*$i[l]\s*(.*)$/\t$i\tdword $1/i;
3073             }
3074              
3075 51         235 $par =~ s/^\s*movsbw\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, byte $2\n/io;
3076 51         207 $par =~ s/^\s*movsbl\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, byte $2\n/io;
3077 51         174 $par =~ s/^\s*movswl\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, word $2\n/io;
3078 51         155 $par =~ s/^\s*movzbw\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, byte $2\n/io;
3079 51         118 $par =~ s/^\s*movzbl\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, byte $2\n/io;
3080 51         155 $par =~ s/^\s*movzwl\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, word $2\n/io;
3081              
3082 51         166 $par =~ s/^\s*l?(jmp|call)\s*(\[[\w\*\+\-\s]+\])/\t$1\tdword $2/io;
3083 51         269 $par =~ s/^\s*l?(jmp|call)\s*([\w\*\+\-]+)/\t$1\tdword $2/io;
3084 51         191 $par =~ s/^\s*l?(jmp|call)\s*(\w+)\s*,\s*(\w+)/\t$1\t$2:$3/io;
3085 51         135 $par =~ s/^\s*lret\s*(.*)$/\tret\t$1\t/i;
3086              
3087 51         131 $par =~ s/^\s*cbtw\s*/\tcbw\t/io;
3088 51         134 $par =~ s/^\s*cwtl\s*/\tcwde\t/io;
3089 51         120 $par =~ s/^\s*cwtd\s*/\tcwd\t/io;
3090 51         146 $par =~ s/^\s*cltd\s*/\tcdq\t/io;
3091              
3092 51 100       382 $par =~ s/^\s*f(\w+)s\s+(.*)$/\tf$1\tdword $2/io unless $par =~ /fchs\s/io;
3093 51 100       303 $par =~ s/^\s*f(\w+)l\s+(.*)$/\tf$1\tqword $2/io unless $par =~ /fmul\s/io;
3094 51         164 $par =~ s/^\s*f(\w+)q\s+(.*)$/\tf$1\tqword $2/io;
3095 51 100       221 $par =~ s/^\s*f(\w+)t\s+(.*)$/\tf$1\ttword $2/io unless $par =~ /fst\s/io;
3096              
3097             # (REP**: removing the end of line char)
3098 51         221 $par =~ s/^\s*(rep[enz]{0,2})\s*/\t$1/io;
3099              
3100 51         422 return $par;
3101             }
3102              
3103             =head2 conv_intel_instr_to_att
3104              
3105             Converts the given string representing a valid Intel instruction to AT&T syntax.
3106             Works best after any pre-processing of the input, i.e. after all macros,
3107             constants, etc. have been replaced by the real values.
3108             Returns the resulting string.
3109              
3110             =cut
3111              
3112             sub conv_intel_instr_to_att($) {
3113              
3114 194     194 1 128005 my $par = shift;
3115 194         372 my ($a1, $a2, $a3, $a4);
3116 194         605 $par =~ s/ptr//gi;
3117              
3118             # (add the suffix)
3119 194         447 foreach my $i (@att_suff_instr) {
3120              
3121 2895 100       49527 if ( $par =~ /^\s*$i\s+([^,]+)/i ) {
3122              
3123 167         748 ($a1 = $1) =~ s/\s+$//o;
3124 167 100       4668 if ( $par =~ /[^;]+\bbyte\b/io ) {
    100          
    100          
    100          
    100          
    100          
3125              
3126 3         44 $par =~ s/^\s*$i\b/\t${i}b/i;
3127 3         27 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3128              
3129             } elsif ( $par =~ /[^;]+\bword\b/io ) {
3130              
3131 3         44 $par =~ s/^\s*$i\b/\t${i}w/i;
3132 3         21 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3133              
3134             } elsif ( $par =~ /[^;]+\bdword\b/io ) {
3135              
3136 3         58 $par =~ s/^\s*$i\b/\t${i}l/i;
3137 3         23 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3138              
3139             } elsif ( $par =~ /[^;]+\bqword\b/io ) {
3140              
3141 3         60 $par =~ s/^\s*$i\b/\t${i}q/i;
3142 3         23 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3143              
3144             } elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3145              
3146 113         354 ($a2 = $2) =~ s/\s+$//o;
3147 113         253 ($a3 = $3) =~ s/\s+$//o;
3148 113 100       515 if ( $a3 !~ /\[.*\]/o ) {
    100          
    100          
3149              
3150 69 100       183 if ( is_reg8 ($a3) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  5 100       47  
    100          
    100          
    100          
    100          
3151 5         53 elsif ( is_reg16($a3) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3152 13         120 elsif ( is_reg32($a3) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3153 5         49 elsif ( is_reg64($a3) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3154             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3155 21         55 $a1 = $1;
3156 21         56 $a1 =~ s/\s+$//o;
3157 21 100       49 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       27  
    100          
    100          
3158 2         28 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3159 11         106 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3160 2         33 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3161             # (default: let the programmer decide)
3162             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3163             }
3164             elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i ) {
3165 10         32 $a2 = $2;
3166 10         27 $a2 =~ s/\s+$//o;
3167 10 100       28 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       18  
    100          
    100          
3168 1         20 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3169 5         68 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3170 1         21 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3171             # (default: let the programmer decide)
3172             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3173             }
3174             # taken care of by the first conditions
3175             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+),\s*([^\[\],]+)\s*/i ) {
3176             #$par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+),\s*([^\[\],]+)\s*/i;
3177             #$a3 = $3;
3178             #$a3 =~ s/\s+$//o;
3179             #if ( is_reg8 ($a3) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3180             #elsif ( is_reg16($a3) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3181             #elsif ( is_reg32($a3) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3182             #elsif ( is_reg64($a3) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3183             # (default: let the programmer decide)
3184             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3185             #} else {
3186             # (default: let the programmer decide)
3187             #$par =~ s/^\s*$i\b/\t${i}l/i;
3188             #}
3189              
3190             } elsif ( $a2 !~ /\[.*\]/o ) {
3191              
3192 33 100       86 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       31  
    100          
    100          
    100          
3193 2         32 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3194 7         72 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3195 2         31 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3196             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3197 10         32 $a1 = $1;
3198 10         30 $a1 =~ s/\s+$//o;
3199 10 100       26 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       18  
    100          
    100          
3200 1         19 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3201 6         63 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3202 1         21 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3203             # (default: let the programmer decide)
3204             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3205             }
3206             # taken care of by the first conditions
3207             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i ) {
3208             #$par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i;
3209             #$a1 = $2;
3210             #$a1 =~ s/\s+$//o;
3211             #if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3212             #elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3213             #elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3214             #elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3215             # (default: let the programmer decide)
3216             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3217             #} else {
3218             # (default: let the programmer decide)
3219             #$par =~ s/^\s*$i\b/\t${i}l/i;
3220             #}
3221              
3222             } elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3223              
3224 10         26 $a1 = $1;
3225 10         28 $a1 =~ s/\s+$//o;
3226 10 100       28 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       20  
    100          
    100          
3227 1         18 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3228 1         25 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3229 1         20 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3230             # (default: let the programmer decide)
3231             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3232              
3233             #} else {
3234             # (default: let the programmer decide)
3235             #$par =~ s/^\s*$i\b/\t${i}l/i;
3236             }
3237             } elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+)/i ) {
3238              
3239 34         153 ($a2 = $2) =~ s/\s+$//o;
3240 34 100       323 if ( $a2 !~ /\[.*\]/o ) {
    100          
3241              
3242 23 100       59 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  3 100       58  
    100          
    100          
    100          
3243 3         52 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3244 7         95 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3245 3         52 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3246             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {
3247 6         27 $a1 = $1;
3248 6         19 $a1 =~ s/\s+$//o;
3249 6 100       15 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       19  
    100          
    100          
3250 1         32 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3251 2         30 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3252 1         21 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3253             # (default: let the programmer decide)
3254             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3255             }
3256             # taken care of by the first conditions
3257             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)/i ) {
3258             #$a1 = $2;
3259             #$a1 =~ s/\s+$//o;
3260             #if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3261             #elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3262             #elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3263             #elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3264             # (default: let the programmer decide)
3265             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3266             #} else {
3267             # (default: let the programmer decide)
3268             #$par =~ s/^\s*$i\b/\t${i}l/i;
3269             #}
3270              
3271             } elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {
3272              
3273 9         34 $a1 = $1;
3274 9         29 $a1 =~ s/\s+$//o;
3275 9 100       26 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       39  
    100          
    100          
3276 2         41 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3277 2         42 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3278 2         61 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3279             # (default: let the programmer decide)
3280             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3281              
3282             #} else {
3283             # (default: let the programmer decide)
3284             #$par =~ s/^\s*$i\b/\t${i}l/i;
3285             }
3286             } else { #if ( $par =~ /^\s*$i\s+([^,]+)\s*/i ) {
3287              
3288 8         109 $par =~ /^\s*$i\s+([^,]+)\s*/i;
3289 8         34 ($a1 = $1) =~ s/\s+$//o;
3290 8 100       23 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       19  
    100          
    100          
3291 1         18 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3292 2         42 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3293 1         19 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3294             #else {
3295             # (default: let the programmer decide)
3296             #$par =~ s/^\s*$i\b/\t${i}l/i;
3297             #}
3298              
3299             #} else {
3300             # (default: long)
3301             # unreachable code
3302             #$par =~ s/^\s*$i\b/\t${i}l/i;
3303             }
3304 167         524 last;
3305             }
3306             }
3307              
3308             # (add suffixes to MOVSX/MOVZX instructions)
3309 194 100       880 if ( $par =~ /^\s*(mov[sz])x\s+([^,]+)\s*,\s*([^,]+)(.*)/io ) {
3310              
3311 21         55 my ($inst, $arg1, $arg2, $rest, $z1, $z2);
3312 21         64 $inst = $1;
3313 21         50 $z1 = $2;
3314 21         50 $z2 = $3;
3315 21         43 $rest = $4;
3316 21         125 ($arg1 = $z1) =~ s/\s*$//o;
3317 21         99 ($arg2 = $z2) =~ s/\s*$//o;
3318             # operand order is changed later
3319 21 100 100     144 if ( ($par =~ /\bbyte\b/io || is_reg8($arg2) ) && is_reg32($arg1) ) {
    100 100        
    100 100        
    100 100        
    100 100        
      100        
      100        
      100        
      100        
      100        
3320 2         11 $par = "\t${inst}bl\t$arg1, $arg2 $rest\n";
3321             } elsif ( ($par =~ /\bbyte\b/io || is_reg8($arg2) ) && is_reg16($arg1) ) {
3322 2         11 $par = "\t${inst}bw\t$arg1, $arg2 $rest\n";
3323             } elsif ( ($par =~ /\bword\b/io || is_reg16($arg2)) && is_reg32($arg1) ) {
3324 2         11 $par = "\t${inst}wl\t$arg1, $arg2 $rest\n";
3325             } elsif ( ($par =~ /\bbyte\b/io || is_reg8($arg2)) && is_reg64($arg1) ) {
3326 2         11 $par = "\t${inst}bq\t$arg1, $arg2 $rest\n";
3327             } elsif ( ($par =~ /\bword\b/io || is_reg16($arg2)) && is_reg64($arg1) ) {
3328 2         10 $par = "\t${inst}wq\t$arg1, $arg2 $rest\n";
3329             }
3330             # if we can't decide on register sizes, leave it for the programmer to fix
3331             }
3332              
3333             # (changing operands' order):
3334 194 100       1958 if ( $par =~ /^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)/o ) {
3335 114 100       268 if ( is_instr($1) ) {
3336 113         1723 $par =~ s/^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)/\t$1\t$6, $4, $2/o;
3337             }
3338             }
3339 194 100       3285 if ( $par =~ /^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/o ) {
3340 64 100       173 if ( is_instr($1) ) {
3341 63         1296 $par =~ s/^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/\t$1\t$4, $2$6\n/o;
3342             }
3343             }
3344 194 100       1894 if ( $par =~ /^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/o ) {
3345 15 100       110 if ( is_instr($1) ) {
3346 14         199 $par =~ s/^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/\t$1\t$2$4\n/o;
3347             }
3348             }
3349              
3350             # (FPU instructions)
3351 194         476 $par =~ s/^\s*fi(\w+)\s+word\s*(.*)/\tfi${1}s\t$2/io;
3352 194         361 $par =~ s/^\s*fi(\w+)\s+dword\s*(.*)/\tfi${1}l\t$2/io;
3353 194         330 $par =~ s/^\s*fi(\w+)\s+qword\s*(.*)/\tfi${1}q\t$2/io;
3354              
3355 194         363 $par =~ s/^\s*f([^iI]\w+)\s+dword\s*(.*)/\tf${1}s\t$2/io;
3356 194         305 $par =~ s/^\s*f([^iI]\w+)\s+qword\s*(.*)/\tf${1}l\t$2/io;
3357 194         367 $par =~ s/^\s*f([^iI]\w+)\s+t(word|byte)\s*(.*)/\tf${1}t\t$3/io;
3358              
3359             # (change "xxx" to "$xxx", if there are no "[]")
3360             # (don't touch "call/jmp xxx")
3361 194 100       629 if ( $par !~ /^\s*(j[a-z]+|call)/io ) {
3362              
3363 192 100       1196 if ( $par =~ /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)\s*/gio ) {
    100          
    100          
3364              
3365 114         260 $a1 = $1;
3366 114         189 $a2 = $2;
3367 114         213 $a3 = $3;
3368 114         181 $a4 = $4;
3369 114         219 $a1 =~ s/\s+$//o;
3370 114         169 $a2 =~ s/\s+$//o;
3371 114         189 $a3 =~ s/\s+$//o;
3372 114         160 $a4 =~ s/\s+$//o;
3373 114         265 $a2 =~ s/(t?byte|[dqpft]?word)//io;
3374 114         215 $a3 =~ s/(t?byte|[dqpft]?word)//io;
3375 114         223 $a4 =~ s/(t?byte|[dqpft]?word)//io;
3376 114         198 $a2 =~ s/^\s+//o;
3377 114         195 $a3 =~ s/^\s+//o;
3378 114         210 $a4 =~ s/^\s+//o;
3379              
3380 114 100 100     483 if ( $a2 !~ /\[/o && !is_reg($a2) ) { $a2 = "\$$a2"; }
  41         97  
3381 114 100 100     394 if ( $a3 !~ /\[/o && !is_reg($a3) ) { $a3 = "\$$a3"; }
  40         106  
3382 114 100 100     390 if ( $a4 !~ /\[/o && !is_reg($a4) ) { $a4 = "\$$a4"; }
  25         61  
3383              
3384 114         406 $par = "\t$a1\t$a2, $a3, $a4\n";
3385              
3386             } elsif ( $par =~ /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*/gio ) {
3387              
3388 64         158 $a1 = $1;
3389 64         116 $a2 = $2;
3390 64         117 $a3 = $3;
3391 64         139 $a1 =~ s/\s+$//o;
3392 64         219 $a2 =~ s/\s+$//o;
3393 64         256 $a3 =~ s/\s+$//o;
3394 64         182 $a2 =~ s/(t?byte|[dqpft]?word)//io;
3395 64         164 $a3 =~ s/(t?byte|[dqpft]?word)//io;
3396 64         137 $a2 =~ s/^\s+//o;
3397 64         129 $a3 =~ s/^\s+//o;
3398              
3399 64 100 100     257 if ( $a2 !~ /\[/o && !is_reg($a2) ) { $a2 = "\$$a2"; }
  7         24  
3400 64 100 100     266 if ( $a3 !~ /\[/o && !is_reg($a3) ) { $a3 = "\$$a3"; }
  3         9  
3401              
3402 64         225 $par = "\t$a1\t$a2, $a3\n";
3403              
3404             } elsif ( $par =~ /^\s*(\w+)\s+([^,]+)\s*/gio ) {
3405              
3406 13         34 $a1 = $1;
3407 13         31 $a2 = $2;
3408 13         60 $a1 =~ s/\s+$//o;
3409 13         61 $a2 =~ s/\s+$//o;
3410 13         39 $a2 =~ s/(t?byte|[dqpft]?word)//io;
3411 13         29 $a2 =~ s/^\s+//o;
3412              
3413 13 100 100     62 if ( $a2 !~ /\[/o && !is_reg($a2) ) { $a2 = "\$$a2"; }
  2         6  
3414              
3415 13         45 $par = "\t$a1\t$a2\n";
3416              
3417             }
3418             }
3419              
3420 194         478 $par =~ s/^\s*cbw\b/\tcbtw/io;
3421 194         337 $par =~ s/^\s*cwde\b/\tcwtl/io;
3422 194         334 $par =~ s/^\s*cwd\b/\tcwtd/io;
3423 194         326 $par =~ s/^\s*cdq\b/\tcltd/io;
3424              
3425             # (adding asterisk chars)
3426 194         445 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*(\[[\w\*\+\-\s]+\])/\t$1\t*$3/io;
3427 194         401 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*((0x)?\d+h?)/\t$1\t*$3/io;
3428 194         376 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*([\w\*\+\-\s]+)/\t$1\t$3/io;
3429 194         290 $par =~ s/^\s*(jmp|call)\s+([^:]+)\s*:\s*([^:]+)/\tl$1\t$2, $3/io;
3430 194         508 $par =~ s/^\s*retf\s+(.*)$/\tlret\t$1/io;
3431              
3432             # (changing memory references):
3433 194         482 $par = conv_intel_addr_to_att $par;
3434              
3435             # (changing "stN" to "st(N)")
3436 194         434 $par =~ s/\bst(\d)\b/\%st($1)/go;
3437              
3438             # (adding percent chars)
3439 194         381 foreach my $r (@regs_intel) {
3440              
3441 41516         231917 $par =~ s/\b$r\b/\%$r/gi;
3442             }
3443 194         396 foreach my $r (@regs_intel) {
3444              
3445 41516         202386 $par =~ s/\%\%$r\b/\%$r/gi;
3446             }
3447              
3448             # (REP**: adding the end of line char)
3449 194         555 $par =~ s/^\s*(rep[enz]{0,2})\s+/\t$1\n\t/io;
3450              
3451 194         813 return $par;
3452             }
3453              
3454             =head1 SUPPORT AND DOCUMENTATION
3455              
3456             After installing, you can find documentation for this module with the perldoc command.
3457              
3458             perldoc Asm::X86
3459              
3460             You can also look for information at:
3461              
3462             Search CPAN
3463             https://metacpan.org/release/Asm-X86
3464             http://search.cpan.org/dist/Asm-X86
3465              
3466             CPAN Request Tracker:
3467             https://rt.cpan.org/Public/Dist/Display.html?Name=Asm-X86
3468             http://rt.cpan.org/NoAuth/Bugs.html?Dist=Asm-X86
3469              
3470             CPAN Ratings:
3471             https://cpanratings.perl.org/dist/Asm-X86
3472             http://cpanratings.perl.org/d/Asm-X86
3473              
3474             =head1 AUTHOR
3475              
3476             Bogdan Drozdowski, C<< >>
3477              
3478             =head1 COPYRIGHT
3479              
3480             Copyright 2008-2021 Bogdan Drozdowski, all rights reserved.
3481              
3482             =head1 LICENSE
3483              
3484             This program is free software; you can redistribute it and/or modify it
3485             under the same terms as Perl itself.
3486              
3487             =cut
3488              
3489             1; # End of Asm::X86