File Coverage

blib/lib/Asm/X86.pm
Criterion Covered Total %
statement 893 898 99.4
branch 855 886 96.5
condition 864 948 91.1
subroutine 76 76 100.0
pod 55 55 100.0
total 2743 2863 95.8


line stmt bran cond sub pod time code
1             package Asm::X86;
2              
3 10     10   656540 use warnings;
  10         99  
  10         1134  
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   69 use strict;
  10         20  
  10         344061  
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.62
48              
49             =cut
50              
51             our $VERSION = '0.62';
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   133 my @result = ();
190 100         159 foreach (@_) {
191 2440         3687 push @result, "%$_";
192             }
193 100         578 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   103 my %new_hash;
207 36         106 foreach (@_) {
208 75597         112366 $new_hash{$_} = 1;
209             }
210 36         13700 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   1636 my $elem = shift;
224 669         1737 $elem =~ s/^\s*\++//o;
225 669 100       1518 $elem = '+' if $elem eq '';
226 669         1371 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   3000035 my $elem = shift;
242 2050146         2425199 my $arr = shift;
243 2050146 100       5181322 return 0 unless $elem =~ /^\w+$/o;
244 2043576         3211601 foreach (@$arr) {
245 113099473 100       256818350 return 1 if /^$elem$/i;
246             }
247 837668         3190986 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   68374 my $elem = shift;
263 44011         54825 my $arr = shift;
264 44011 100       171897 return 0 unless $elem =~ /^\%\w+$/o;
265 31154         57394 foreach (@$arr) {
266 746286 100       1910222 return 1 if /^$elem$/i;
267             }
268 15283         73673 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 1868564 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 167567 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 4787 my $elem = shift;
890 2377         4197 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 4801 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 4275 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 1815 my $elem = shift;
924 877         1988 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 15788 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 7332 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 1852 my $elem = shift;
958 825         1737 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 509900 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 13397 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 1258 my $elem = shift;
992 547         1370 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 4320 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 3946 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 1980 my $elem = shift;
1026 780         1926 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 809175 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 13955 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 1186 my $elem = shift;
1063 519         1384 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 271093 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 7875 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 1124 my $elem = shift;
1103 519         1495 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 650574 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 13896 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 1523 my $elem = shift;
1137 712         1725 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 3880 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 3650 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 1448 my $elem = shift;
1173 593         1533 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 4081 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 4966 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 1400 my $elem = shift;
1207 593         1363 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 3891 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 3729 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 1324 my $elem = shift;
1241 593         1444 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 19559 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 29369 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 58511 my $elem = shift;
1275 324         748 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   50871 my $reg = shift;
1292 27738 100 100     175435 return 1 if $reg =~ /^bx$/io || $reg =~ /^bp$/io
      100        
      100        
1293             || $reg =~ /^si$/io || $reg =~ /^di$/io;
1294 8894         54281 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   3333 my $reg1 = shift;
1309 1825         3153 my $reg2 = shift;
1310 1825 100 100     16335 return 1 if ($reg1 =~ /^b.$/io && $reg2 =~ /^b.$/io)
      100        
      100        
1311             || ($reg1 =~ /^.i$/io && $reg2 =~ /^.i$/io);
1312 913         2333 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   32519 my $segreg = shift;
1327 14403         26660 my $reg1_sign = shift;
1328 14403         23189 my $reg1 = shift;
1329 14403         23765 my $reg2_sign = shift;
1330 14403         21437 my $reg2 = shift;
1331 14403         20646 my $disp_sign = shift;
1332 14403         20690 my $disp = shift;
1333              
1334 14403 100 100     44220 return 0 if defined $segreg && ! is_segreg_intel($segreg);
1335 14359 100 66     44051 return 0 if defined $reg1 && is_reg_intel($reg1)
      100        
1336             && (! _is_valid_16bit_addr_reg_intel ($reg1));
1337 11262 100 100     29669 return 0 if defined $reg2 && is_reg_intel($reg2)
      100        
1338             && (! _is_valid_16bit_addr_reg_intel ($reg2));
1339 7985 100 100     21756 return 0 if defined $disp && is_reg_intel($disp)
      100        
1340             && (! _is_valid_16bit_addr_reg_intel ($disp));
1341              
1342 5465 100 33     22259 return 0 if defined $reg1 && defined $reg1_sign
      66        
      100        
1343             && is_reg_intel($reg1) && $reg1_sign =~ /-/o;
1344 4738 100 66     19648 return 0 if defined $reg2 && defined $reg2_sign
      100        
      100        
1345             && is_reg_intel($reg2) && $reg2_sign =~ /-/o;
1346 3418 100 66     13892 return 0 if defined $disp && defined $disp_sign
      100        
      100        
1347             && is_reg_intel($disp) && $disp_sign =~ /-/o;
1348 2350 50 66     11682 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     7700 if ( defined $reg1 && is_reg16_intel($reg1) ) {
1352              
1353 1581 50 33     6381 return 0 if defined $reg1_sign && $reg1_sign =~ /-/o;
1354             # must be one of predefined registers
1355 1581 50       3018 if ( _is_valid_16bit_addr_reg_intel ($reg1) ) {
1356              
1357 1581 100 100     4365 if ( defined $reg2 && is_reg16_intel($reg2) ) {
    100 100        
1358              
1359 769 100       2008 return 0 if _is_same_type_16bit_addr_reg_intel ($reg1, $reg2);
1360 385 50 33     1760 return 0 if defined $reg2_sign && $reg2_sign =~ /-/o;
1361 385 50 66     1172 return 0 if defined $disp && is_reg_intel($disp);
1362              
1363             # must be one of predefined registers
1364 385 50       850 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       1337 return 0 if _is_same_type_16bit_addr_reg_intel ($reg1, $disp);
1372 288 50 33     1363 return 0 if defined $disp_sign && $disp_sign =~ /-/o;
1373              
1374             # must be one of predefined registers
1375 288 50       737 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         1451 return 1;
1383             }
1384             }
1385 0         0 return 0;
1386             } else {
1387 769 100 100     2520 if ( defined $reg2 && is_reg16_intel($reg2) ) {
1388              
1389 642 50 33     2700 return 0 if defined $reg2_sign && $reg2_sign =~ /-/o;
1390             # must be one of predefined registers
1391 642 50       1420 if ( _is_valid_16bit_addr_reg_intel ($reg2) )
1392             {
1393 642 100 100     1978 if ( defined $disp && is_reg16_intel($disp) ) {
1394              
1395 480 100       1106 return 0 if _is_same_type_16bit_addr_reg_intel ($disp, $reg2);
1396 240 50 33     1191 return 0 if defined $disp_sign && $disp_sign =~ /-/o;
1397              
1398             # must be one of predefined registers
1399 240 50       473 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         1121 return 1;
1406             }
1407             }
1408 0         0 return 0;
1409             } else {
1410 127 50 66     791 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         1437 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 15252296 my $elem = shift;
1431 23912 100 100     457541 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         596 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         4485 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         22522 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         331 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         2312 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         12047 return _validate_16bit_addr_parts_intel (undef, $1, $2, $3, $4, $5, $6);
1457             }
1458 9509         39947 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   2432 my $reg = shift;
1473 1462 100 100     8699 return 1 if $reg =~ /^%bx$/io || $reg =~ /^%bp$/io
      100        
      100        
1474             || $reg =~ /^%si$/io || $reg =~ /^%di$/io;
1475 186         1088 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   166 my $reg1 = shift;
1490 129         176 my $reg2 = shift;
1491 129 100 100     990 return 1 if ($reg1 =~ /^%b.$/io && $reg2 =~ /^%b.$/io)
      100        
      100        
1492             || ($reg1 =~ /^%.i$/io && $reg2 =~ /^%.i$/io);
1493 65         157 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   2106 my $segreg = shift;
1508 1088         1586 my $basereg_sign = shift;
1509 1088         2089 my $basereg = shift;
1510 1088         1452 my $indexreg_sign = shift;
1511 1088         1783 my $indexreg = shift;
1512 1088         1385 my $scale = shift;
1513 1088         1526 my $disp_sign = shift;
1514 1088         1757 my $disp = shift;
1515              
1516 1088 100 100     3030 return 0 if defined $segreg && ! is_segreg_att($segreg);
1517 1067 100       2172 if ( defined $basereg ) {
1518 946 100 100     3258 return 0 if $basereg =~ /%/o && ! is_reg16_att($basereg);
1519 785 100 100     1891 return 0 if is_reg_att($basereg) && ! _is_valid_16bit_addr_reg_att ($basereg);
1520 663 100 100     1798 return 0 if defined $disp && ! is_reg_att($basereg); # disallow 'var(var)'
1521             }
1522 766 100       1899 if ( defined $indexreg ) {
1523 656 100 100     2078 return 0 if $indexreg =~ /%/o && ! is_reg16_att($indexreg);
1524 470 100 100     1217 return 0 if is_reg_att($indexreg) && ! _is_valid_16bit_addr_reg_att ($indexreg);
1525 418 50 66     1192 if ( ! defined $basereg && ! defined $scale ) {
1526             # just one value inside - check for "(,1)
1527 61 100 100     332 return 0 if $indexreg ne '1' || is_reg_att($disp);
1528             }
1529             }
1530 477 100 100     1044 return 0 if defined $disp && is_reg_att($disp);
1531 259 50 33     565 return 0 if defined $scale && $scale ne '1';
1532 259 100 100     749 if ( defined $basereg && defined $indexreg ) {
1533              
1534 141 100 100     231 return 0 if ! _is_valid_16bit_addr_reg_att($basereg)
1535             || ! _is_valid_16bit_addr_reg_att($indexreg);
1536 129 100       263 return 0 if _is_same_type_16bit_addr_reg_att ($basereg, $indexreg);
1537             }
1538 183 0 66     537 return 0 if defined $basereg && defined $basereg_sign
      33        
      33        
1539             && is_reg_att($basereg) && $basereg_sign =~ /-/o;
1540 183 0 66     469 return 0 if defined $indexreg && defined $indexreg_sign
      33        
      33        
1541             && is_reg_att($indexreg) && $indexreg_sign =~ /-/o;
1542              
1543 183         831 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 1816309 my $elem = shift;
1559 1850 100       36327 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         154 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         190 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         69 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         28 return 0;
1575             }
1576             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1577              
1578 99         292 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         598 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         216 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         52 return 0;
1592             }
1593             elsif ( $elem =~ /^([%\w]+):\s*([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1594              
1595 60         187 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         111 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         206 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         74 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         26 return 0;
1613             }
1614             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*([%\w]+)\s*\)$/o ) {
1615              
1616 94         268 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         628 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         250 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         58 return 0;
1630             }
1631             elsif ( $elem =~ /^([+-]*)\s*([%\w]+)\s*\(\s*,\s*([%\w]+)\s*\)$/o ) {
1632              
1633 62         204 return _validate_16bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
1634             }
1635 728         3177 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 13 my $elem = shift;
1651 4         16 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   310404 my $segreg = shift;
1666 154412         295745 my $base_reg_sign = shift;
1667 154412         240037 my $base_reg = shift;
1668 154412         227788 my $index_reg_sign = shift;
1669 154412         219368 my $index_reg = shift;
1670 154412         210497 my $scale = shift;
1671 154412         212643 my $disp_sign = shift;
1672 154412         223264 my $disp = shift;
1673              
1674 154412 100 100     407873 return 0 if defined $segreg && ! is_segreg_intel($segreg);
1675 151960 100 100     421056 return 0 if defined $base_reg && is_reg_intel($base_reg) && ! is_addressable32_intel($base_reg);
      100        
1676 117634 100 100     385579 return 0 if defined $index_reg && is_reg_intel($index_reg) && ! is_addressable32_intel($index_reg);
      100        
1677 66427 100 100     187910 return 0 if defined $scale && is_reg_intel($scale) && ! is_addressable32_intel($scale);
      100        
1678 39478 100 100     112380 return 0 if defined $disp && is_reg_intel($disp) && ! is_addressable32_intel($disp);
      100        
1679              
1680 12280 100 100     53404 return 0 if defined $index_reg && defined $scale
      100        
      100        
1681             && is_reg_intel($index_reg) && is_reg_intel($scale);
1682 11404 100 66     41338 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     39497 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     35532 return 0 if defined $scale && defined $index_reg_sign
      100        
      100        
1687             && is_reg_intel($scale) && $index_reg_sign =~ /-/o;
1688 7698 100 66     30113 return 0 if defined $disp && defined $disp_sign
      100        
      100        
1689             && is_reg_intel($disp) && $disp_sign =~ /-/o;
1690              
1691 6711 100 100     25295 if ( defined $index_reg && defined $scale ) {
1692              
1693 6192 100 100     23073 return 0 if $index_reg =~ /\besp\b/io && $scale =~ /\b\d+\b/o && $scale != 1;
      100        
1694 6039 100 100     20668 return 0 if $scale =~ /\besp\b/io && $index_reg =~ /\b\d+\b/o && $index_reg != 1;
      100        
1695 5886 100 100     12195 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     11541 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     32334 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     28993 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         41877 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 82992605 my $elem = shift;
1721             # [seg:base+index*scale+disp]
1722 154447 100 100     3651250 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         80498 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         84495 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         80178 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         14054 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         26590 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         14586 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         551 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         843 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         15602 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         45523 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         44147 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         42006 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         7027 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         13468 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         7450 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         266 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         427 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         7804 return _validate_32bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, $3, $4);
1802             }
1803 35         162 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   6232 my $segreg = shift;
1817 3076         4565 my $base_reg_sign = shift;
1818 3076         5238 my $base_reg = shift;
1819 3076         4117 my $index_reg_sign = shift;
1820 3076         4595 my $index_reg = shift;
1821 3076         4214 my $scale = shift;
1822 3076         4698 my $disp_sign = shift;
1823 3076         4484 my $disp = shift;
1824              
1825 3076 100 100     8867 return 0 if defined $segreg && ! is_segreg_att ($segreg);
1826 3033 100 100     11695 if ( defined $index_reg && ! defined $base_reg && ! defined $scale ) {
      100        
1827             # just one value inside - check for "(,1)
1828 215 100 100     680 return 1 if $index_reg eq '1' && ! is_reg_att($disp);
1829             }
1830 3028 100 100     7873 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     4311 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     5086 return 0 if defined $disp && is_reg_att($disp);
1835 1433 100 100     5951 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     2517 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     1669 return 0 if defined $base_reg && ! is_addressable32_att($base_reg);
1845             }
1846 271         1317 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 5781268 my $elem = shift;
1862 11296 100       274669 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         109 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         193 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         180 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         105 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         83 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         1236 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         749 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         1169 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         626 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         299 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         195 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         217 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         116 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         67 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         1259 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         712 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         1194 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         605 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         329 return _validate_32bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
1941             }
1942 8220         35051 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 12 my $elem = shift;
1958 4         18 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   368239 my $reg = shift;
1974 242259 100 100     406403 return 1 if is_reg64_intel($reg) || is_r32_in64_intel($reg) || is_addressable32_intel($reg);
      100        
1975 118182         681714 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   289409 my $segreg = shift;
1989 137817         241629 my $base_reg_sign = shift;
1990 137817         205030 my $base_reg = shift;
1991 137817         211487 my $index_reg_sign = shift;
1992 137817         199038 my $index_reg = shift;
1993 137817         212725 my $scale = shift;
1994 137817         188724 my $disp_sign = shift;
1995 137817         201410 my $disp = shift;
1996 137817         215196 my $was64 = 0;
1997 137817         172366 my $nregs = 0;
1998              
1999 137817 100 100     365111 return 0 if defined $segreg && ! is_segreg_intel($segreg);
2000 135409 100 100     371053 if ( defined $base_reg && is_reg_intel($base_reg) ) {
2001              
2002 90372 100       184543 return 0 if ! _is_valid_64bit_addr_reg_intel($base_reg);
2003 61329         99042 $nregs++;
2004 61329 100       96943 $was64++ if is_reg64_intel($base_reg);
2005             }
2006 106366 100 100     294780 if ( defined $index_reg && is_reg_intel($index_reg) ) {
2007              
2008 77825 100       153110 return 0 if ! _is_valid_64bit_addr_reg_intel($index_reg);
2009 34496         60786 $nregs++;
2010 34496 100       56472 $was64++ if is_reg64_intel($index_reg);
2011             }
2012 63037 100 100     182854 if ( defined $scale && is_reg_intel($scale) ) {
2013              
2014 41911 100       85255 return 0 if ! _is_valid_64bit_addr_reg_intel($scale);
2015 19108         28375 $nregs++;
2016 19108 100       33662 $was64++ if is_reg64_intel($scale);
2017             }
2018 40234 100 100     115328 if ( defined $disp && is_reg_intel($disp) ) {
2019              
2020 32151 100       66148 return 0 if ! _is_valid_64bit_addr_reg_intel($disp);
2021 9144         14247 $nregs++;
2022 9144 100       14408 $was64++ if is_reg64_intel($disp);
2023             }
2024 17227 100 100     78151 return 0 if $was64 != 0 && $was64 != $nregs;
2025              
2026 13720 100 100     54669 return 0 if defined $index_reg && defined $scale
      100        
      100        
2027             && is_reg_intel($index_reg) && is_reg_intel($scale);
2028 12844 100 66     51236 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     44843 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     44721 return 0 if defined $scale && defined $index_reg_sign
      100        
      100        
2033             && is_reg_intel($scale) && $index_reg_sign =~ /-/o;
2034 8781 100 66     38541 return 0 if defined $disp && defined $disp_sign
      100        
      100        
2035             && is_reg_intel($disp) && $disp_sign =~ /-/o;
2036 7573 100 100     30920 if ( defined $index_reg && defined $scale ) {
2037 7129 100 100     39373 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     38220 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     13679 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     14639 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     43078 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     38436 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         54536 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 79644749 my $elem = shift;
2067             # [seg:base+index*scale+disp]
2068 137852 100 100     3371538 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         72273 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         72613 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         70019 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         12606 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         24148 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         13248 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         479 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         1010 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         13283 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         39752 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         37889 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         38110 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         6627 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         11875 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         6572 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         242 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         510 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         6655 return _validate_64bit_addr_parts_intel (undef, $1, $2, undef, undef, undef, $3, $4);
2148             }
2149 35         173 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   6366 my $reg = shift;
2164 3843 100 100     6535 return 1 if is_reg64_att($reg) || is_r32_in64_att($reg) || is_addressable32_att($reg);
      100        
2165 2281         14027 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   5439 my $segreg = shift;
2179 3006         4098 my $base_reg_sign = shift;
2180 3006         5054 my $base_reg = shift;
2181 3006         4931 my $index_reg_sign = shift;
2182 3006         4618 my $index_reg = shift;
2183 3006         4169 my $scale = shift;
2184 3006         4087 my $disp_sign = shift;
2185 3006         5016 my $disp = shift;
2186 3006         4076 my $was64 = 0;
2187 3006         3920 my $nregs = 0;
2188              
2189 3006 100 100     8141 return 0 if defined $segreg && ! is_segreg_att($segreg);
2190 2949 100       6136 if ( defined $base_reg ) {
2191              
2192 2301 50 66     6521 if ( ! defined $index_reg && ! defined $scale ) {
2193             # just one value inside - allow '(var)',
2194             # disallow 'var(var)', allow 'var(%reg)'
2195 851 50 100     2970 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     3510 return 0 if is_reg_att($base_reg)
      100        
2200             && (! _is_valid_64bit_addr_reg_att($base_reg) || $base_reg =~ /^%rip$/io);
2201 963         1697 $nregs++;
2202 963 100       1473 $was64++ if is_reg64_att($base_reg);
2203             }
2204 1611 100       3222 if ( defined $index_reg ) {
2205              
2206 1567 100 100     4107 if ( ! defined $base_reg && ! defined $scale ) {
2207             # just one value inside - check for "(,1)
2208 214 100 100     603 return 1 if $index_reg eq '1' && ! is_reg_att($disp);
2209             }
2210 1562 100       3045 return 0 if ! _is_valid_64bit_addr_reg_att($index_reg);
2211 587 100 100     2805 return 0 if $index_reg =~ /^%rsp$/io || $index_reg =~ /^%rip$/io;
2212 490         739 $nregs++;
2213 490 100       827 $was64++ if is_reg64_att($index_reg);
2214             }
2215 534 100 100     1451 return 0 if defined $disp && is_reg_att($disp);
2216 495 100 100     2146 return 0 if $was64 != 0 && $was64 != $nregs;
2217              
2218 328 50 100     1004 return 0 if defined $index_reg && defined $scale
      66        
      66        
2219             && is_reg_att($index_reg) && is_reg_att($scale);
2220 328 0 66     922 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     883 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     850 return 0 if defined $scale && defined $index_reg_sign
      33        
      33        
2225             && is_reg_att($scale) && $index_reg_sign =~ /-/o;
2226 328 50 66     930 return 0 if defined $disp && defined $disp_sign
      66        
      33        
2227             && is_reg_att($disp) && $disp_sign =~ /-/o;
2228 328 100 66     717 return 0 if defined $scale && (is_reg_att($scale)
      100        
2229             || ($scale != 1 && $scale != 2 && $scale != 4 && $scale != 8));
2230 312 50 100     1151 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     1046 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         1427 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 5261395 my $elem = shift;
2251 10078 100       238940 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         107 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         188 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         243 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         108 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         67 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         1089 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         723 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         1243 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         558 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         316 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         125 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         182 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         223 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         105 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         73 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         1160 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         725 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         1206 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         528 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         310 return _validate_64bit_addr_parts_att (undef, undef, undef, undef, $3, undef, $1, $2);
2330             }
2331 7072         30398 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 13 my $elem = shift;
2347 4         14 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 11403 my $elem = shift;
2364 33         89 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 12976 my $elem = shift;
2382 35         95 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 29 my $elem = shift;
2400 10         43 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 40376 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 38762 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 17406 my @result = ();
2438 26         64 foreach (@_) {
2439 24137 100       36868 if ( is_att_suffixed_instr ($_) ) {
2440              
2441 220         547 push @result, $_.'b';
2442 220         379 push @result, $_.'w';
2443 220         350 push @result, $_.'l';
2444 220         493 push @result, $_.'q';
2445             }
2446             else {
2447             # FPU instructions
2448 23917 100       56842 if ( /^fi(\w+)/io ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2449              
2450 140         514 push @result, $_.'s';
2451 140         229 push @result, $_.'l';
2452 140         273 push @result, $_.'q';
2453             }
2454             elsif ( is_att_suffixed_instr_fpu ($_) ) {
2455              
2456 280         616 push @result, $_.'s';
2457 280         447 push @result, $_.'l';
2458 280         591 push @result, $_.'t';
2459             }
2460             elsif ( /^\s*(mov[sz])x\s+([^,]+)\s*,\s*([^,]+)(.*)/io ) {
2461              
2462             # add suffixes to MOVSX/MOVZX instructions
2463 15         33 my ($inst, $arg1, $arg2, $rest, $z1, $z2);
2464 15         39 $inst = $1;
2465 15         27 $z1 = $2;
2466 15         24 $z2 = $3;
2467 15         27 $rest = $4;
2468 15         65 ($arg1 = $z1) =~ s/\s*$//o;
2469 15         54 ($arg2 = $z2) =~ s/\s*$//o;
2470 15 100 100     34 if ( is_reg8($arg2) && is_reg32($arg1) ) {
    100 100        
    100 100        
    100 100        
    100 100        
2471 2         8 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         8 push @result, "${inst}bq";
2476             } elsif ( is_reg16($arg2) && is_reg32($arg1) ) {
2477 2         8 push @result, "${inst}wl";
2478             } elsif ( is_reg16($arg2) && is_reg64($arg1) ) {
2479 2         8 push @result, "${inst}wq";
2480             }
2481 15         46 push @result, "$_";
2482             }
2483             elsif ( /^\s*(mov[sz])x/io ) {
2484              
2485             # add suffixes to MOVSX/MOVZX instructions
2486 32         125 push @result, "$1bl";
2487 32         128 push @result, "$1bw";
2488 32         62 push @result, "$1bq";
2489 32         67 push @result, "$1wl";
2490 32         63 push @result, "$1wq";
2491 32         78 push @result, "$_";
2492             }
2493             elsif ( /^\s*cbw\b/io ) {
2494              
2495 10         44 push @result, 'cbtw';
2496             }
2497             elsif ( /^\s*cwde\b/io ) {
2498              
2499 10         30 push @result, 'cwtl';
2500             }
2501             elsif ( /^\s*cwd\b/io ) {
2502              
2503 10         37 push @result, 'cwtd';
2504             }
2505             elsif ( /^\s*cdq\b/io ) {
2506              
2507 10         29 push @result, 'cltd';
2508             }
2509             else {
2510 23410         59853 push @result, "$_";
2511             }
2512             }
2513             }
2514             # adding AT&T suffixes can create duplicate entries. Remove them here:
2515 26         503 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 2473 my $par = shift;
2530 54         154 $par =~ s/%([a-zA-Z]+)/$1/go;
2531             # seg: disp(base, index, scale)
2532 54         99 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$3+$5*$4+$2]/o;
2533 54         108 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$1$3+$4+$2]/o;
2534 54         91 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$2+$3*$4]/o;
2535 54         107 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$1$2+$3]/o;
2536 54         118 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*,\s*1\s*\)/[$1$2]/o;
2537 54         107 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$3*$4+$2]/o;
2538 54         129 $par =~ s/(\w+\s*:\s*)([\w\+\-\(\)]+)\s*\(\s*(\w+)\s*\)/[$1$3+$2]/o;
2539 54         127 $par =~ s/(\w+\s*:\s*)\s*\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1$2*$3]/o;
2540 54         101 $par =~ s/(\w+\s*:\s*)\(\s*(\w+)\s*\)/[$1$2]/o;
2541              
2542             # disp(base, index, scale)
2543 54         149 $par =~ s/([\w\+\-\(\)]+)\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$2+$3*$4+$1]/o;
2544 54         132 $par =~ s/([\w\+\-\(\)]+)\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/[$2+$3+$1]/o;
2545 54         133 $par =~ s/\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d)\s*\)/\t[$1+$2*$3]/o;
2546 54         137 $par =~ s/\(\s*(\w+)\s*,\s*(\w+)\s*,?\s*\)/\t[$1+$2]/o;
2547 54         116 $par =~ s/([\w\+\-\(\)]+)\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$2*$3+$1]/o;
2548 54         129 $par =~ s/\(\s*,\s*(\w+)\s*,\s*(\d)\s*\)/[$1*$2]/o;
2549              
2550             # disp(, index)
2551 54         119 $par =~ s/([\w\-\+\(\)]+)\(\s*,\s*1\s*\)/[$1]/o;
2552 54         107 $par =~ s/([\w\-\+\(\)]+)\(\s*,\s*(\w+)\s*\)/[$2+$1]/o;
2553              
2554             # (base, index)
2555 54         118 $par =~ s/\(\s*,\s*1\s*\)/[$1]/o;
2556 54         111 $par =~ s/\(\s*,\s*(\w+)\s*\)/[$1]/o;
2557              
2558             # disp(base)
2559 54 100       254 $par =~ s/([\w\-\+\(\)]+)\(\s*(\w+)\s*\)/[$2+$1]/o unless $par =~ /st\(\d\)/io;
2560 54 100       289 $par =~ s/\(\s*(\w+)\s*\)/[$1]/o unless $par =~ /st\(\d\)/io;
2561              
2562 54         168 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 134811 my $par = shift;
2577 423         774 my ($z1, $z2, $z3);
2578             # seg: disp(base, index, scale)
2579             # [seg:base+index*scale+disp]
2580 423         1374 my $a_seg_base_index_scale_disp = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2581 423         1010 my $a_seg_base_disp_index_scale = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o;
2582 423         932 my $a_seg_index_scale_base_disp = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2583 423         859 my $a_seg_base_index_disp = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2584 423         905 my $a_seg_base_index_scale = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o;
2585 423         898 my $a_seg_base_index = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2586 423         934 my $a_seg_base = qr/\[\s*(\w+)\s*:\s*(\w+)\s*\]/o;
2587 423         860 my $a_seg_index_scale_base = qr/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2588              
2589 423         833 my $a_base_index_scale_disp = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2590 423         870 my $a_index_scale_base_disp = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2591 423         819 my $a_base_disp_index_scale = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o;
2592 423         824 my $a_base_index_disp = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2593 423         826 my $a_base_index_scale = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/o;
2594 423         878 my $a_base_index = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2595 423         800 my $a_base = qr/\[\s*(\w+)\s*\]/o;
2596 423         935 my $a_index_scale_base = qr/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/o;
2597              
2598 423 100       9858 if ( $par =~ /$a_seg_base_index_scale_disp/ ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
2599              
2600 17         56 $z1 = _nopluses($2);
2601 17         42 $z2 = _nopluses($4);
2602 17         39 $z3 = _nopluses($7);
2603 17 100 100     46 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2604 1         16 $par =~ s/$a_seg_base_index_scale_disp/$1:($z3$8)$9($3,$5,$6)/;
2605             } elsif ( is_reg($3) && is_reg($6) ) {
2606 1         15 $par =~ s/$a_seg_base_index_scale_disp/$1:($z3$8)$9($3,$6,$5)/;
2607             } elsif ( is_reg($5) && is_reg($8) ) {
2608 1         17 $par =~ s/$a_seg_base_index_scale_disp/$1:($z1$3)$9($8,$5,$6)/;
2609             } elsif ( is_reg($6) && is_reg($8) ) {
2610 1         15 $par =~ s/$a_seg_base_index_scale_disp/$1:($z1$3)$9($8,$6,$5)/;
2611             } elsif ( is_reg($3) && is_reg($8) ) {
2612 4         64 $par =~ s/$a_seg_base_index_scale_disp/$1:($z2$5*$6)$9($3,$8)/;
2613             } elsif ( is_reg($3) ) {
2614 2         33 $par =~ s/$a_seg_base_index_scale_disp/$1:($z3$8$z2$5*$6)$9($3)/;
2615             } elsif ( is_reg($5) ) {
2616 2         34 $par =~ s/$a_seg_base_index_scale_disp/$1:($z3$8$z1$3)$9(,$5,$6)/;
2617             } elsif ( is_reg($6) ) {
2618 2         31 $par =~ s/$a_seg_base_index_scale_disp/$1:($z3$8$z1$3)$9(,$6,$5)/;
2619             } elsif ( is_reg($8) ) {
2620 2         33 $par =~ s/$a_seg_base_index_scale_disp/$1:($z1$3$z2$5*$6)$9($8)/;
2621             } else {
2622 1         29 $par =~ s/$a_seg_base_index_scale_disp/$1:($z1$3$z2$5*$6$z3$8)$9(,1)/;
2623             }
2624             }
2625             elsif ( $par =~ /$a_seg_base_disp_index_scale/ ) {
2626              
2627 17         60 $z1 = _nopluses($2);
2628 17         37 $z2 = _nopluses($4);
2629 17         40 $z3 = _nopluses($6);
2630 17 100 100     43 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2631 4         60 $par =~ s/$a_seg_base_disp_index_scale/$1:($z3$7*$8)$9($3,$5)/;
2632             } elsif ( is_reg($5) && is_reg($7) ) {
2633 1         16 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3)$9($5,$7,$8)/;
2634             } elsif ( is_reg($5) && is_reg($8) ) {
2635 1         18 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3)$9($5,$8,$7)/;
2636             } elsif ( is_reg($3) && is_reg($7) ) {
2637 1         16 $par =~ s/$a_seg_base_disp_index_scale/$1:($z2$5)$9($3,$7,$8)/;
2638             } elsif ( is_reg($3) && is_reg($8) ) {
2639 1         33 $par =~ s/$a_seg_base_disp_index_scale/$1:($z2$5)$9($3,$8,$7)/;
2640             } elsif ( is_reg($3) ) {
2641 2         35 $par =~ s/$a_seg_base_disp_index_scale/$1:($z2$5$z3$7*$8)$9($3)/;
2642             } elsif ( is_reg($5) ) {
2643 2         39 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3$z3$7*$8)$9($5)/;
2644             } elsif ( is_reg($7) ) {
2645 2         35 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3$z2$5)$9(,$7,$8)/;
2646             } elsif ( is_reg($8) ) {
2647 2         31 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3$z2$5)$9(,$8,$7)/;
2648             } else {
2649 1         19 $par =~ s/$a_seg_base_disp_index_scale/$1:($z1$3$z2$5$z3$7*$8)$9(,1)/;
2650             }
2651             }
2652             elsif ( $par =~ /$a_seg_index_scale_base_disp/ ) {
2653              
2654 17         52 $z1 = _nopluses($2);
2655 17         49 $z2 = _nopluses($5);
2656 17         38 $z3 = _nopluses($7);
2657 17 100 100     44 if ( is_reg($3) && is_reg($6) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2658 1         17 $par =~ s/$a_seg_index_scale_base_disp/$1:($z3$8)$9($6,$3,$4)/;
2659             } elsif ( is_reg($4) && is_reg($6) ) {
2660 1         16 $par =~ s/$a_seg_index_scale_base_disp/$1:($z3$8)$9($6,$4,$3)/;
2661             } elsif ( is_reg($6) && is_reg($8) ) {
2662 4         73 $par =~ s/$a_seg_index_scale_base_disp/$1:($z1$3*$4)$9($6,$8)/;
2663             } elsif ( is_reg($3) && is_reg($8) ) {
2664 1         18 $par =~ s/$a_seg_index_scale_base_disp/$1:($z2$6)$9($8,$3,$4)/;
2665             } elsif ( is_reg($4) && is_reg($8) ) {
2666 1         115 $par =~ s/$a_seg_index_scale_base_disp/$1:($z2$6)$9($8,$4,$3)/;
2667             } elsif ( is_reg($3) ) {
2668 2         32 $par =~ s/$a_seg_index_scale_base_disp/$1:($z2$6$z3$8)$9(,$3,$4)/;
2669             } elsif ( is_reg($4) ) {
2670 2         34 $par =~ s/$a_seg_index_scale_base_disp/$1:($z2$6$z3$8)$9(,$4,$3)/;
2671             } elsif ( is_reg($6) ) {
2672 2         39 $par =~ s/$a_seg_index_scale_base_disp/$1:($z1$3*$4$z3$8)$9($6)/;
2673             } elsif ( is_reg($8) ) {
2674 2         39 $par =~ s/$a_seg_index_scale_base_disp/$1:($z1$3*$4$z2$6)$9($8)/;
2675             } else {
2676 1         19 $par =~ s/$a_seg_index_scale_base_disp/$1:($z1$3*$4$z2$6$z3$8)$9(,1)/;
2677             }
2678             }
2679             elsif ( $par =~ /$a_seg_base_index_disp/ ) {
2680              
2681 7         24 $z1 = _nopluses($2);
2682 7         22 $z2 = _nopluses($4);
2683 7         18 $z3 = _nopluses($6);
2684 7 100 100     26 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100 100        
    100          
    100          
    100          
2685 1         17 $par =~ s/$a_seg_base_index_disp/$1:($z3$7)$8($3,$5,)/;
2686             } elsif ( is_reg($3) && is_reg($7) ) {
2687 1         27 $par =~ s/$a_seg_base_index_disp/$1:($z2$5)$8($3,$7,)/;
2688             } elsif ( is_reg($5) && is_reg($7) ) {
2689 1         19 $par =~ s/$a_seg_base_index_disp/$1:($z1$3)$8($7,$5,)/;
2690             } elsif ( is_reg($3) ) {
2691 1         16 $par =~ s/$a_seg_base_index_disp/$1:($z1$5$z3$7)$8($3)/;
2692             } elsif ( is_reg($5) ) {
2693 1         16 $par =~ s/$a_seg_base_index_disp/$1:($z1$3$z3$7)$8($5)/;
2694             } elsif ( is_reg($7) ) {
2695 1         16 $par =~ s/$a_seg_base_index_disp/$1:($z1$3$z2$5)$8($7)/;
2696             } else {
2697 1         20 $par =~ s/$a_seg_base_index_disp/$1:($z1$3$z2$5$z3$7)$8(,1)/;
2698             }
2699             }
2700             elsif ( $par =~ /$a_seg_base_index_scale/ ) {
2701              
2702 7         25 $z1 = _nopluses($2);
2703 7         21 $z2 = _nopluses($4);
2704 7 100 100     26 if ( is_reg($3) && is_reg($5) ) {
    100 100        
    100          
    100          
    100          
2705 1         14 $par =~ s/$a_seg_base_index_scale/$1:($3,$5,$6)/;
2706             } elsif ( is_reg($3) && is_reg($6) ) {
2707 1         13 $par =~ s/$a_seg_base_index_scale/$1:($3,$6,$5)/;
2708             } elsif ( is_reg($3) ) {
2709 2         32 $par =~ s/$a_seg_base_index_scale/$1:($z2$5*$6)$7($3)/;
2710             } elsif ( is_reg($5) ) {
2711 1         20 $par =~ s/$a_seg_base_index_scale/$1:($z1$3)$7(,$5,$6)/;
2712             } elsif ( is_reg($6) ) {
2713 1         17 $par =~ s/$a_seg_base_index_scale/$1:($z1$3)$7(,$6,$5)/;
2714             } else {
2715 1         19 $par =~ s/$a_seg_base_index_scale/$1:($z1$3$z2$5*$6)$7(,1)/;
2716             }
2717             }
2718             elsif ( $par =~ /$a_seg_base_index/ ) {
2719              
2720 5         19 $z1 = _nopluses($2);
2721 5         23 $z2 = _nopluses($4);
2722 5 100 100     18 if ( is_reg($3) && is_reg($5) ) {
    100          
    100          
2723 1         15 $par =~ s/$a_seg_base_index/$1:($3,$5,)/;
2724             } elsif ( is_reg($3) ) {
2725 2         29 $par =~ s/$a_seg_base_index/$1:($z2$5)$6($3)/;
2726             } elsif ( is_reg($5) ) {
2727 1         16 $par =~ s/$a_seg_base_index/$1:($z1$3)$6($5)/;
2728             } else {
2729 1         15 $par =~ s/$a_seg_base_index/$1:($z1$3$z2$5)$6(,1)/;
2730             }
2731             }
2732             elsif ( $par =~ /$a_seg_base/ ) {
2733              
2734 2 100       9 if ( is_reg($2) ) {
2735 1         11 $par =~ s/$a_seg_base/$1:($2)/;
2736             } else {
2737 1         13 $par =~ s/$a_seg_base/$1:$2(,1)/;
2738             }
2739             }
2740             elsif ( $par =~ /$a_seg_index_scale_base/ ) {
2741              
2742 7         25 $z1 = _nopluses($2);
2743 7         19 $z2 = _nopluses($5);
2744 7 100 100     24 if ( is_reg($3) && is_reg($6) ) {
    100 100        
    100          
    100          
    100          
2745 1         15 $par =~ s/$a_seg_index_scale_base/$1:($6,$3,$4)/;
2746             } elsif ( is_reg($4) && is_reg($6) ) {
2747 1         15 $par =~ s/$a_seg_index_scale_base/$1:($6,$4,$3)/;
2748             } elsif ( is_reg($3) ) {
2749 1         16 $par =~ s/$a_seg_index_scale_base/$1:($z2$6)$7(,$3,$4)/;
2750             } elsif ( is_reg($4) ) {
2751 1         15 $par =~ s/$a_seg_index_scale_base/$1:($z2$6)$7(,$4,$3)/;
2752             } elsif ( is_reg($6) ) {
2753 2         40 $par =~ s/$a_seg_index_scale_base/$1:($z1$3*$4)$7($6)/;
2754             } else {
2755 1         18 $par =~ s/$a_seg_index_scale_base/$1:($z1$3*$4$z2$6)$7(,1)/;
2756             }
2757             }
2758             # disp(base, index, scale)
2759             elsif ( $par =~ /$a_base_index_scale_disp/ ) {
2760              
2761 50         150 $z1 = _nopluses($1);
2762 50         120 $z2 = _nopluses($3);
2763 50         101 $z3 = _nopluses($6);
2764 50 100 100     128 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2765 19         290 $par =~ s/$a_base_index_scale_disp/($z3$7)$8($2,$4,$5)/;
2766             } elsif ( is_reg($2) && is_reg($5) ) {
2767 2         35 $par =~ s/$a_base_index_scale_disp/($z3$7)$8($2,$5,$4)/;
2768             } elsif ( is_reg($2) && is_reg($7) ) {
2769 8         126 $par =~ s/$a_base_index_scale_disp/($z2$4*$5)$8($2,$7)/;
2770             } elsif ( is_reg($4) && is_reg($7) ) {
2771 2         62 $par =~ s/$a_base_index_scale_disp/($z1$2)$8($7,$4,$5)/;
2772             } elsif ( is_reg($5) && is_reg($7) ) {
2773 2         33 $par =~ s/$a_base_index_scale_disp/($z1$2)$8($7,$5,$4)/;
2774             } elsif ( is_reg($2) ) {
2775 4         74 $par =~ s/$a_base_index_scale_disp/($z3$7$z2$4*$5)$8($2)/;
2776             } elsif ( is_reg($4) ) {
2777 4         59 $par =~ s/$a_base_index_scale_disp/($z3$7+$z1$2)$8(,$4,$5)/;
2778             } elsif ( is_reg($5) ) {
2779 4         70 $par =~ s/$a_base_index_scale_disp/($z3$7+$z1$2)$8(,$5,$4)/;
2780             } elsif ( is_reg($7) ) {
2781 4         75 $par =~ s/$a_base_index_scale_disp/($z1$2$z2$4*$5)$8($7)/;
2782             } else {
2783 1         17 $par =~ s/$a_base_index_scale_disp/($z1$2$z2$4*$5$z3$7)$8(,1)/;
2784             }
2785             }
2786             elsif ( $par =~ /$a_index_scale_base_disp/ ) {
2787              
2788 33         91 $z1 = _nopluses($1);
2789 33         80 $z2 = _nopluses($4);
2790 33         65 $z3 = _nopluses($6);
2791 33 100 100     80 if ( is_reg($2) && is_reg($5) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2792 2         32 $par =~ s/$a_index_scale_base_disp/($z3$7)$8($5,$2,$3)/;
2793             } elsif ( is_reg($3) && is_reg($5) ) {
2794 2         33 $par =~ s/$a_index_scale_base_disp/($z3$7)$8($5,$3,$2)/;
2795             } elsif ( is_reg($2) && is_reg($7) ) {
2796 2         31 $par =~ s/$a_index_scale_base_disp/($z2$5)$8($7,$2,$3)/;
2797             } elsif ( is_reg($3) && is_reg($7) ) {
2798 2         33 $par =~ s/$a_index_scale_base_disp/($z2$5)$8($7,$3,$2)/;
2799             } elsif ( is_reg($5) && is_reg($7) ) {
2800 8         115 $par =~ s/$a_index_scale_base_disp/($z1$2*$3)$8($5,$7)/;
2801             } elsif ( is_reg($2) ) {
2802 4         62 $par =~ s/$a_index_scale_base_disp/($z2$5$z3$7)$8(,$2,$3)/;
2803             } elsif ( is_reg($3) ) {
2804 4         67 $par =~ s/$a_index_scale_base_disp/($z2$5$z3$7)$8(,$3,$2)/;
2805             } elsif ( is_reg($5) ) {
2806 4         64 $par =~ s/$a_index_scale_base_disp/($z1$2*$3$z3$7)$8($5)/;
2807             } elsif ( is_reg($7) ) {
2808 4         76 $par =~ s/$a_index_scale_base_disp/($z1$2*$3$z2$5)$8($7)/;
2809             } else {
2810 1         16 $par =~ s/$a_index_scale_base_disp/($z1$2*$3$z2$5$z3$7)$8(,1)/;
2811             }
2812             }
2813             elsif ( $par =~ /$a_base_disp_index_scale/ ) {
2814              
2815 33         94 $z1 = _nopluses($1);
2816 33         75 $z2 = _nopluses($3);
2817 33         73 $z3 = _nopluses($5);
2818 33 100 100     74 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
2819 8         133 $par =~ s/$a_base_disp_index_scale/($z3$6*$7)$8($2,$4)/;
2820             } elsif ( is_reg($2) && is_reg($6) ) {
2821 2         32 $par =~ s/$a_base_disp_index_scale/($z2$4)$8($2,$6,$7)/;
2822             } elsif ( is_reg($2) && is_reg($7) ) {
2823 2         33 $par =~ s/$a_base_disp_index_scale/($z2$4)$8($2,$7,$6)/;
2824             } elsif ( is_reg($4) && is_reg($6) ) {
2825 2         30 $par =~ s/$a_base_disp_index_scale/($z1$2)$8($4,$6,$7)/;
2826             } elsif ( is_reg($4) && is_reg($7) ) {
2827 2         31 $par =~ s/$a_base_disp_index_scale/($z1$2)$8($4,$7,$6)/;
2828             } elsif ( is_reg($2) ) {
2829 4         58 $par =~ s/$a_base_disp_index_scale/($z2$4$z3$6*$7)$8($2)/;
2830             } elsif ( is_reg($4) ) {
2831 4         67 $par =~ s/$a_base_disp_index_scale/($z3$6*$7$z1$2)$8($4)/;
2832             } elsif ( is_reg($6) ) {
2833 4         67 $par =~ s/$a_base_disp_index_scale/($z1$2$z2$4)$8(,$6,$7)/;
2834             } elsif ( is_reg($7) ) {
2835 4         67 $par =~ s/$a_base_disp_index_scale/($z1$2$z2$4)$8(,$7,$6)/;
2836             } else {
2837 1         26 $par =~ s/$a_base_disp_index_scale/($z1$2$z2$4$z3$6*$7)$8(,1)/;
2838             }
2839             }
2840             elsif ( $par =~ /$a_base_index_disp/ ) {
2841              
2842 13         42 $z1 = _nopluses($1);
2843 13         37 $z2 = _nopluses($3);
2844 13         31 $z3 = _nopluses($5);
2845 13 100 100     29 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100 100        
    100          
    100          
    100          
2846 2         30 $par =~ s/$a_base_index_disp/($z3$6)$7($2,$4)/;
2847             } elsif ( is_reg($2) && is_reg($6) ) {
2848 2         34 $par =~ s/$a_base_index_disp/($z2$4)$7($2,$6)/;
2849             } elsif ( is_reg($4) && is_reg($6) ) {
2850 2         35 $par =~ s/$a_base_index_disp/($z1$2)$7($4,$6)/;
2851             } elsif ( is_reg($2) ) {
2852 2         33 $par =~ s/$a_base_index_disp/($z3$6$z2$4)$7($2)/;
2853             } elsif ( is_reg($4) ) {
2854 2         28 $par =~ s/$a_base_index_disp/($z3$6+$z1$2)$7($4)/;
2855             } elsif ( is_reg($6) ) {
2856 2         46 $par =~ s/$a_base_index_disp/($z1$2$z2$4)$7($6)/;
2857             } else {
2858 1         16 $par =~ s/$a_base_index_disp/($z1$2$z2$4$z3$6)$7(,1)/;
2859             }
2860             }
2861             elsif ( $par =~ /$a_base_index_scale/ ) {
2862              
2863 13         43 $z1 = _nopluses($1);
2864 13         61 $z2 = _nopluses($3);
2865 13 100 100     31 if ( is_reg($2) && is_reg($4) ) {
    100 100        
    100          
    100          
    100          
2866 2         29 $par =~ s/$a_base_index_scale/($2,$4,$5)/;
2867             } elsif ( is_reg($2) && is_reg($5) ) {
2868 2         27 $par =~ s/$a_base_index_scale/($2,$5,$4)/;
2869             } elsif ( is_reg($2) ) {
2870 4         60 $par =~ s/$a_base_index_scale/($z2$4*$5)$6($2)/;
2871             } elsif ( is_reg($4) ) {
2872 2         34 $par =~ s/$a_base_index_scale/($z1$2)$6(,$4,$5)/;
2873             } elsif ( is_reg($5) ) {
2874 2         32 $par =~ s/$a_base_index_scale/($z1$2)$6(,$5,$4)/;
2875             } else {
2876 1         13 $par =~ s/$a_base_index_scale/($z1$2$z2$4*$5)$6(,1)/;
2877             }
2878             }
2879             elsif ( $par =~ /$a_base_index/ ) {
2880              
2881 9         30 $z1 = _nopluses($1);
2882 9         25 $z2 = _nopluses($3);
2883 9 100 100     27 if ( is_reg($2) && is_reg($4) ) {
    100          
    100          
2884 2         28 $par =~ s/$a_base_index/($2,$4)/;
2885             } elsif ( is_reg($2) ) {
2886 4         55 $par =~ s/$a_base_index/($z2$4)$5($2)/;
2887             } elsif ( is_reg($4) ) {
2888 2         30 $par =~ s/$a_base_index/($z1$2)$5($4)/;
2889             } else {
2890 1         16 $par =~ s/$a_base_index/($2$z2$4)$5(,1)/;
2891             }
2892             }
2893             elsif ( $par =~ /$a_base/ ) {
2894 122 100       308 if ( is_reg($1) ) {
2895             # disp(base)
2896 110         894 $par =~ s/$a_base/($1)/;
2897             } else {
2898 12         116 $par =~ s/$a_base/$1(,1)/;
2899             }
2900             }
2901             elsif ( $par =~ /$a_index_scale_base/ ) {
2902              
2903 13         45 $z1 = _nopluses($1);
2904 13         35 $z2 = _nopluses($4);
2905 13 100 100     35 if ( is_reg($2) && is_reg($5) ) {
    100 100        
    100          
    100          
    100          
2906 2         28 $par =~ s/$a_index_scale_base/($5,$2,$3)/;
2907             } elsif ( is_reg($3) && is_reg($5) ) {
2908 2         31 $par =~ s/$a_index_scale_base/($5,$3,$2)/;
2909             } elsif ( is_reg($2) ) {
2910 2         40 $par =~ s/$a_index_scale_base/($z2$5)$6(,$2,$3)/;
2911             } elsif ( is_reg($3) ) {
2912 2         31 $par =~ s/$a_index_scale_base/($z2$5)$6(,$3,$2)/;
2913             } elsif ( is_reg($5) ) {
2914 4         57 $par =~ s/$a_index_scale_base/($z1$2*$3)$6($5)/;
2915             } else {
2916 1         17 $par =~ s/$a_index_scale_base/($z1$2*$3$z2$5)$6(,1)/;
2917             }
2918             }
2919 423         1177 foreach my $i (@regs_intel) {
2920 90522         568451 $par =~ s/\b($i)\b/%$1/;
2921             }
2922              
2923 423         955 foreach my $r (@regs_intel) {
2924              
2925 90522         438324 $par =~ s/\%\%$r\b/\%$r/gi;
2926             }
2927 423         3395 return $par;
2928             }
2929              
2930             # =head2 _change_to_intel_addr_if_applicable
2931             #
2932             # PRIVATE SUBROUTINE.
2933             # If the parameter is applicable to be an address (i.e. not a variable,
2934             # register or a label), returns its value in square brackets (intel-syntax
2935             # memory reference).
2936             #
2937             # =cut
2938             #
2939             sub _change_to_intel_addr_if_applicable($) {
2940              
2941 67     67   129 my $par = shift;
2942             # (we mustn't change digits and %st(n))
2943 67 100 100     473 if ( $par !~ /\$/o && $par !~ /\%/o && $par !~ /_L\d+/o && $par =~ /[a-zA-Z_\.]/o ) {
      100        
2944              
2945 6         26 return "[$par]";
2946             }
2947 61         129 return $par;
2948             }
2949              
2950             =head2 conv_att_instr_to_intel
2951              
2952             Converts the given string representing a valid AT&T instruction to Intel syntax.
2953             Works best after any pre-processing of the input, i.e. after all macros,
2954             constants, etc. have been replaced by the real values.
2955             Returns the resulting string.
2956              
2957             =cut
2958              
2959             sub conv_att_instr_to_intel($) {
2960              
2961 51     51 1 51167 my $par = shift;
2962             # (changing "xxx" to "[xxx]", if there's no '$' or '%')
2963              
2964             # (elements of memory operands mustn't be taken as instruction operands, so there are no '()'s here)
2965 51 100       432 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)/o ) {
2966              
2967 13         31 my ($a1, $a2, $a3, $a4);
2968              
2969 13         40 $a1 = $1;
2970 13         32 $a2 = $2;
2971 13         32 $a3 = $3;
2972 13         31 $a4 = $4;
2973              
2974             #if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
2975              
2976 13         42 $a2 = _change_to_intel_addr_if_applicable ($a2);
2977 13         32 $a3 = _change_to_intel_addr_if_applicable ($a3);
2978 13         30 $a4 = _change_to_intel_addr_if_applicable ($a4);
2979              
2980             # (ATTENTION: operand order will be changed later)
2981 13         65 $par = "\t$a1\t$a2, $a3, $a4\n";
2982             #}
2983             }
2984              
2985 51 100       285 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*,\s*([\$\%\w\+\-]+)\s*$/o ) {
2986              
2987 11         24 my ($a1, $a2, $a3);
2988              
2989 11         37 $a1 = $1;
2990 11         24 $a2 = $2;
2991 11         22 $a3 = $3;
2992              
2993             #if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
2994              
2995 11         29 $a2 = _change_to_intel_addr_if_applicable ($a2);
2996 11         29 $a3 = _change_to_intel_addr_if_applicable ($a3);
2997              
2998             # (ATTENTION: operand order will be changed later)
2999 11         41 $par = "\t$a1\t$a2, $a3\n";
3000             #}
3001             }
3002              
3003 51 100       264 if ( $par =~ /^\s*(\w+)\s+([\$\%\w\+\-]+)\s*\s*$/o ) {
3004              
3005 8         20 my ($a1, $a2);
3006              
3007 8         25 $a1 = $1;
3008 8         18 $a2 = $2;
3009              
3010             # (don't touch "call/jmp xxx")
3011 8 100 100     65 if ( $a1 !~ /call/io && $a1 !~ /^\s*j[a-z]{1,3}/io ) {
3012              
3013 6         19 $a2 = _change_to_intel_addr_if_applicable ($a2);
3014              
3015             # (ATTENTION: operand order will be changed later)
3016 6         25 $par = "\t$a1\t$a2\n";
3017             }
3018             }
3019              
3020             # (removing dollar chars)
3021 51         172 $par =~ s/\$//go;
3022             # (removing percent chars)
3023 51         199 $par =~ s/%//go;
3024             # (removing asterisk chars)
3025 51         125 $par =~ s/\*//go;
3026              
3027             # (changing memory references):
3028 51         146 $par = conv_att_addr_to_intel $par;
3029              
3030             # (changing "st[N]" to "stN")
3031 51         132 $par =~ s/(\s)st\[(\d)\]/$1 st$2/go;
3032             # (changing "st" to "st0")
3033 51         119 $par =~ s/(\s)st(\s|,)/$1 st0$2/go;
3034              
3035             # (changing operands' order):
3036 51         207 my $i_3op = qr/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)/o;
3037 51         166 my $i_2op = qr/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/o;
3038 51         152 my $i_1op = qr/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\(\)]+\]?)([^,]*(;.*)?)$/o;
3039 51 100       412 if ( $par =~ /$i_3op/ ) {
3040 22 100       83 if ( is_instr($1) ) {
3041 20         311 $par =~ s/$i_3op/\t$1\t$4, $3, $2/;
3042             }
3043             }
3044 51 100       438 if ( $par =~ /$i_2op/) {
3045 17 100       54 if ( is_instr($1) ) {
3046 15         230 $par =~ s/$i_2op/\t$1\t$3, $2$4/;
3047             }
3048             }
3049 51 100       396 if ( $par =~ /$i_1op/ ) {
3050 12 100       49 if ( is_instr($1) ) {
3051 10         144 $par =~ s/$i_1op/\t$1\t$2$3/;
3052             }
3053             }
3054              
3055 51         140 foreach my $i (@instr) {
3056              
3057 134385         1894549 $par =~ s/^\s*$i[b]\s*(.*)$/\t$i\tbyte $1/i;
3058 134385         1874064 $par =~ s/^\s*$i[w]\s*(.*)$/\t$i\tword $1/i;
3059 134385         1955531 $par =~ s/^\s*$i[l]\s*(.*)$/\t$i\tdword $1/i;
3060             }
3061              
3062 51         220 $par =~ s/^\s*movsbw\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, byte $2\n/io;
3063 51         129 $par =~ s/^\s*movsbl\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, byte $2\n/io;
3064 51         133 $par =~ s/^\s*movswl\s+(.*)\s*,\s*(.*)$/\tmovsx\t$1, word $2\n/io;
3065 51         130 $par =~ s/^\s*movzbw\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, byte $2\n/io;
3066 51         121 $par =~ s/^\s*movzbl\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, byte $2\n/io;
3067 51         112 $par =~ s/^\s*movzwl\s+(.*)\s*,\s*(.*)$/\tmovzx\t$1, word $2\n/io;
3068              
3069 51         168 $par =~ s/^\s*l?(jmp|call)\s*(\[[\w\*\+\-\s]+\])/\t$1\tdword $2/io;
3070 51         206 $par =~ s/^\s*l?(jmp|call)\s*([\w\*\+\-]+)/\t$1\tdword $2/io;
3071 51         174 $par =~ s/^\s*l?(jmp|call)\s*(\w+)\s*,\s*(\w+)/\t$1\t$2:$3/io;
3072 51         130 $par =~ s/^\s*lret\s*(.*)$/\tret\t$1\t/i;
3073              
3074 51         110 $par =~ s/^\s*cbtw\s*/\tcbw\t/io;
3075 51         123 $par =~ s/^\s*cwtl\s*/\tcwde\t/io;
3076 51         88 $par =~ s/^\s*cwtd\s*/\tcwd\t/io;
3077 51         92 $par =~ s/^\s*cltd\s*/\tcdq\t/io;
3078              
3079 51 100       268 $par =~ s/^\s*f(\w+)s\s+(.*)$/\tf$1\tdword $2/io unless $par =~ /fchs\s/io;
3080 51 100       170 $par =~ s/^\s*f(\w+)l\s+(.*)$/\tf$1\tqword $2/io unless $par =~ /fmul\s/io;
3081 51         111 $par =~ s/^\s*f(\w+)q\s+(.*)$/\tf$1\tqword $2/io;
3082 51 100       178 $par =~ s/^\s*f(\w+)t\s+(.*)$/\tf$1\ttword $2/io unless $par =~ /fst\s/io;
3083              
3084             # (REP**: removing the end of line char)
3085 51         105 $par =~ s/^\s*(rep[enz]{0,2})\s*/\t$1/io;
3086              
3087 51         467 return $par;
3088             }
3089              
3090             # =head2 _remove_size_qualifiers_add_dollar_add_dollar
3091             #
3092             # PRIVATE SUBROUTINE.
3093             # Returns the parameter after removing any size qualifiers (byte, word,
3094             # dword, etc.) and any leading and trailing whitespace.
3095             # If the parameter is not a memory reference or a register, prefixes it with
3096             # a dollar-sign.
3097             #
3098             # =cut
3099             #
3100             sub _remove_size_qualifiers_add_dollar($) {
3101              
3102 483     483   1025 my $par = shift;
3103 483         1066 $par =~ s/\s+$//o;
3104 483         1011 $par =~ s/(t?byte|[dqpft]?word)//io;
3105 483         854 $par =~ s/^\s+//o;
3106 483 100 100     1361 if ( $par !~ /\[/o && !is_reg($par) )
3107             {
3108 118         260 $par = "\$$par";
3109             }
3110 483         1003 return $par;
3111             }
3112              
3113             =head2 conv_intel_instr_to_att
3114              
3115             Converts the given string representing a valid Intel instruction to AT&T syntax.
3116             Works best after any pre-processing of the input, i.e. after all macros,
3117             constants, etc. have been replaced by the real values.
3118             Returns the resulting string.
3119              
3120             =cut
3121              
3122             sub conv_intel_instr_to_att($) {
3123              
3124 194     194 1 123055 my $par = shift;
3125 194         374 my ($a1, $a2, $a3, $a4);
3126 194         538 $par =~ s/ptr//gi;
3127              
3128             # (add the suffix)
3129 194         394 foreach my $i (@att_suff_instr) {
3130              
3131 2895 100       47609 if ( $par =~ /^\s*$i\s+([^,]+)/i ) {
3132              
3133 167         745 ($a1 = $1) =~ s/\s+$//o;
3134 167 100       4250 if ( $par =~ /[^;]+\bbyte\b/io ) {
    100          
    100          
    100          
    100          
    100          
3135              
3136 3         44 $par =~ s/^\s*$i\b/\t${i}b/i;
3137 3         20 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3138              
3139             } elsif ( $par =~ /[^;]+\bword\b/io ) {
3140              
3141 3         40 $par =~ s/^\s*$i\b/\t${i}w/i;
3142 3         21 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3143              
3144             } elsif ( $par =~ /[^;]+\bdword\b/io ) {
3145              
3146 3         61 $par =~ s/^\s*$i\b/\t${i}l/i;
3147 3         21 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3148              
3149             } elsif ( $par =~ /[^;]+\bqword\b/io ) {
3150              
3151 3         66 $par =~ s/^\s*$i\b/\t${i}q/i;
3152 3         24 $par =~ s/\b(t?byte|[dqpft]?word)\b//io;
3153              
3154             } elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3155              
3156 113         349 ($a2 = $2) =~ s/\s+$//o;
3157 113         246 ($a3 = $3) =~ s/\s+$//o;
3158 113 100       452 if ( $a3 !~ /\[.*\]/o ) {
    100          
    100          
3159              
3160 69 100       157 if ( is_reg8 ($a3) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  5 100       63  
    100          
    100          
    100          
    100          
3161 5         52 elsif ( is_reg16($a3) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3162 13         113 elsif ( is_reg32($a3) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3163 5         53 elsif ( is_reg64($a3) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3164             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3165 21         56 $a1 = $1;
3166 21         54 $a1 =~ s/\s+$//o;
3167 21 100       48 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       28  
    100          
    100          
3168 2         25 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3169 11         100 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3170 2         28 elsif ( is_reg64($a1) ) { $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             elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i ) {
3175 10         34 $a2 = $2;
3176 10         29 $a2 =~ s/\s+$//o;
3177 10 100       22 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       19  
    100          
    100          
3178 1         19 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3179 5         53 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3180 1         23 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3181             # (default: let the programmer decide)
3182             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3183             }
3184             # taken care of by the first conditions
3185             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+),\s*([^\[\],]+)\s*/i ) {
3186             #$par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+),\s*([^\[\],]+)\s*/i;
3187             #$a3 = $3;
3188             #$a3 =~ s/\s+$//o;
3189             #if ( is_reg8 ($a3) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3190             #elsif ( is_reg16($a3) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3191             #elsif ( is_reg32($a3) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3192             #elsif ( is_reg64($a3) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3193             # (default: let the programmer decide)
3194             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3195             #} else {
3196             # (default: let the programmer decide)
3197             #$par =~ s/^\s*$i\b/\t${i}l/i;
3198             #}
3199              
3200             } elsif ( $a2 !~ /\[.*\]/o ) {
3201              
3202 33 100       85 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       26  
    100          
    100          
    100          
3203 2         26 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3204 7         75 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3205 2         28 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3206             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3207 10         27 $a1 = $1;
3208 10         26 $a1 =~ s/\s+$//o;
3209 10 100       22 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       51  
    100          
    100          
3210 1         19 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3211 6         64 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3212 1         22 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3213             # (default: let the programmer decide)
3214             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3215             }
3216             # taken care of by the first conditions
3217             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i ) {
3218             #$par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)\s*,\s*([^,]+)/i;
3219             #$a1 = $2;
3220             #$a1 =~ s/\s+$//o;
3221             #if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3222             #elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3223             #elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3224             #elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3225             # (default: let the programmer decide)
3226             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3227             #} else {
3228             # (default: let the programmer decide)
3229             #$par =~ s/^\s*$i\b/\t${i}l/i;
3230             #}
3231              
3232             } elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)\s*,\s*([^,]+)/i ) {
3233              
3234 10         28 $a1 = $1;
3235 10         25 $a1 =~ s/\s+$//o;
3236 10 100       33 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       19  
    100          
    100          
3237 1         19 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3238 1         19 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3239 1         18 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3240             # (default: let the programmer decide)
3241             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3242              
3243             #} else {
3244             # (default: let the programmer decide)
3245             #$par =~ s/^\s*$i\b/\t${i}l/i;
3246             }
3247             } elsif ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^,]+)/i ) {
3248              
3249 34         124 ($a2 = $2) =~ s/\s+$//o;
3250 34 100       441 if ( $a2 !~ /\[.*\]/o ) {
    100          
3251              
3252 23 100       63 if ( is_reg8 ($a2) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  3 100       45  
    100          
    100          
    100          
3253 3         51 elsif ( is_reg16($a2) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3254 7         85 elsif ( is_reg32($a2) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3255 3         59 elsif ( is_reg64($a2) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3256             elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {
3257 6         20 $a1 = $1;
3258 6         15 $a1 =~ s/\s+$//o;
3259 6 100       18 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       19  
    100          
    100          
3260 1         19 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3261 2         52 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3262 1         20 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3263             # (default: let the programmer decide)
3264             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3265             }
3266             # taken care of by the first conditions
3267             #else {#if ( $par =~ /^\s*$i\s+([^,]+)\s*,\s*([^\[\],]+)/i ) {
3268             #$a1 = $2;
3269             #$a1 =~ s/\s+$//o;
3270             #if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
3271             #elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3272             #elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3273             #elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3274             # (default: let the programmer decide)
3275             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3276             #} else {
3277             # (default: let the programmer decide)
3278             #$par =~ s/^\s*$i\b/\t${i}l/i;
3279             #}
3280              
3281             } elsif ( $par =~ /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {
3282              
3283 9         29 $a1 = $1;
3284 9         19 $a1 =~ s/\s+$//o;
3285 9 100       26 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  2 100       47  
    100          
    100          
3286 2         37 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3287 2         68 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3288 2         42 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3289             # (default: let the programmer decide)
3290             #else { $par =~ s/^\s*$i\b/\t${i}l/i; }
3291              
3292             #} else {
3293             # (default: let the programmer decide)
3294             #$par =~ s/^\s*$i\b/\t${i}l/i;
3295             }
3296             } else { #if ( $par =~ /^\s*$i\s+([^,]+)\s*/i ) {
3297              
3298 8         80 $par =~ /^\s*$i\s+([^,]+)\s*/i;
3299 8         38 ($a1 = $1) =~ s/\s+$//o;
3300 8 100       22 if ( is_reg8 ($a1) ) { $par =~ s/^\s*$i\b/\t${i}b/i; }
  1 100       18  
    100          
    100          
3301 1         18 elsif ( is_reg16($a1) ) { $par =~ s/^\s*$i\b/\t${i}w/i; }
3302 2         62 elsif ( is_reg32($a1) ) { $par =~ s/^\s*$i\b/\t${i}l/i; }
3303 1         20 elsif ( is_reg64($a1) ) { $par =~ s/^\s*$i\b/\t${i}q/i; }
3304             #else {
3305             # (default: let the programmer decide)
3306             #$par =~ s/^\s*$i\b/\t${i}l/i;
3307             #}
3308              
3309             #} else {
3310             # (default: long)
3311             # unreachable code
3312             #$par =~ s/^\s*$i\b/\t${i}l/i;
3313             }
3314 167         479 last;
3315             }
3316             }
3317              
3318             # (add suffixes to MOVSX/MOVZX instructions)
3319 194 100       870 if ( $par =~ /^\s*(mov[sz])x\s+([^,]+)\s*,\s*([^,]+)(.*)/io ) {
3320              
3321 21         51 my ($inst, $arg1, $arg2, $rest, $z1, $z2);
3322 21         66 $inst = $1;
3323 21         46 $z1 = $2;
3324 21         49 $z2 = $3;
3325 21         44 $rest = $4;
3326 21         113 ($arg1 = $z1) =~ s/\s*$//o;
3327 21         97 ($arg2 = $z2) =~ s/\s*$//o;
3328             # operand order is changed later
3329 21 100 100     135 if ( ($par =~ /\bbyte\b/io || is_reg8($arg2) ) && is_reg32($arg1) ) {
    100 100        
    100 100        
    100 100        
    100 100        
      100        
      100        
      100        
      100        
      100        
3330 2         11 $par = "\t${inst}bl\t$arg1, $arg2 $rest\n";
3331             } elsif ( ($par =~ /\bbyte\b/io || is_reg8($arg2) ) && is_reg16($arg1) ) {
3332 2         11 $par = "\t${inst}bw\t$arg1, $arg2 $rest\n";
3333             } elsif ( ($par =~ /\bword\b/io || is_reg16($arg2)) && is_reg32($arg1) ) {
3334 2         15 $par = "\t${inst}wl\t$arg1, $arg2 $rest\n";
3335             } elsif ( ($par =~ /\bbyte\b/io || is_reg8($arg2)) && is_reg64($arg1) ) {
3336 2         16 $par = "\t${inst}bq\t$arg1, $arg2 $rest\n";
3337             } elsif ( ($par =~ /\bword\b/io || is_reg16($arg2)) && is_reg64($arg1) ) {
3338 2         20 $par = "\t${inst}wq\t$arg1, $arg2 $rest\n";
3339             }
3340             # if we can't decide on register sizes, leave it for the programmer to fix
3341             }
3342              
3343             # (changing operands' order):
3344 194         714 my $i_3op = qr/^\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;
3345 194         464 my $i_2op = qr/^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)\s*,\s*((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/o;
3346 194         421 my $i_1op = qr/^\s*(\w+)\s+((t?byte|[dqpft]?word)?\s*\[?[\.\w\*\+\-\s\(\)\[\]]+\]?)([^,]*(;.*)?)$/o;
3347 194 100       2266 if ( $par =~ /$i_3op/ ) {
3348 114 100       289 if ( is_instr($1) ) {
3349 113         1670 $par =~ s/$i_3op/\t$1\t$6, $4, $2/;
3350             }
3351             }
3352 194 100       3493 if ( $par =~ /$i_2op/ ) {
3353 64 100       188 if ( is_instr($1) ) {
3354 63         954 $par =~ s/$i_2op/\t$1\t$4, $2$6\n/;
3355             }
3356             }
3357 194 100       2223 if ( $par =~ /$i_1op/ ) {
3358 15 100       56 if ( is_instr($1) ) {
3359 14         264 $par =~ s/$i_1op/\t$1\t$2$4\n/;
3360             }
3361             }
3362              
3363             # (FPU instructions)
3364 194         522 $par =~ s/^\s*fi(\w+)\s+word\s*(.*)/\tfi${1}s\t$2/io;
3365 194         389 $par =~ s/^\s*fi(\w+)\s+dword\s*(.*)/\tfi${1}l\t$2/io;
3366 194         311 $par =~ s/^\s*fi(\w+)\s+qword\s*(.*)/\tfi${1}q\t$2/io;
3367              
3368 194         357 $par =~ s/^\s*f([^iI]\w+)\s+dword\s*(.*)/\tf${1}s\t$2/io;
3369 194         321 $par =~ s/^\s*f([^iI]\w+)\s+qword\s*(.*)/\tf${1}l\t$2/io;
3370 194         314 $par =~ s/^\s*f([^iI]\w+)\s+t(word|byte)\s*(.*)/\tf${1}t\t$3/io;
3371              
3372             # (change "xxx" to "$xxx", if there are no "[]")
3373             # (don't touch "call/jmp xxx")
3374 194 100       585 if ( $par !~ /^\s*(j[a-z]+|call)/io ) {
3375              
3376 192 100       1149 if ( $par =~ /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)\s*/gio ) {
    100          
    100          
3377              
3378 114         242 $a1 = $1;
3379 114         226 $a1 =~ s/\s+$//o;
3380 114         255 $a2 = _remove_size_qualifiers_add_dollar ($2);
3381 114         223 $a3 = _remove_size_qualifiers_add_dollar ($3);
3382 114         249 $a4 = _remove_size_qualifiers_add_dollar ($4);
3383              
3384 114         355 $par = "\t$a1\t$a2, $a3, $a4\n";
3385              
3386             } elsif ( $par =~ /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*/gio ) {
3387              
3388 64         199 $a1 = $1;
3389 64         139 $a1 =~ s/\s+$//o;
3390 64         141 $a2 = _remove_size_qualifiers_add_dollar ($2);
3391 64         127 $a3 = _remove_size_qualifiers_add_dollar ($3);
3392              
3393 64         207 $par = "\t$a1\t$a2, $a3\n";
3394              
3395             } elsif ( $par =~ /^\s*(\w+)\s+([^,]+)\s*/gio ) {
3396              
3397 13         33 $a1 = $1;
3398 13         31 $a1 =~ s/\s+$//o;
3399 13         28 $a2 = _remove_size_qualifiers_add_dollar ($2);
3400              
3401 13         46 $par = "\t$a1\t$a2\n";
3402             }
3403             }
3404              
3405 194         453 $par =~ s/^\s*cbw\b/\tcbtw/io;
3406 194         356 $par =~ s/^\s*cwde\b/\tcwtl/io;
3407 194         287 $par =~ s/^\s*cwd\b/\tcwtd/io;
3408 194         327 $par =~ s/^\s*cdq\b/\tcltd/io;
3409              
3410             # (adding asterisk chars)
3411 194         456 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*(\[[\w\*\+\-\s]+\])/\t$1\t*$3/io;
3412 194         425 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*((0x)?\d+h?)/\t$1\t*$3/io;
3413 194         355 $par =~ s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*([\w\*\+\-\s]+)/\t$1\t$3/io;
3414 194         290 $par =~ s/^\s*(jmp|call)\s+([^:]+)\s*:\s*([^:]+)/\tl$1\t$2, $3/io;
3415 194         443 $par =~ s/^\s*retf\s+(.*)$/\tlret\t$1/io;
3416              
3417             # (changing memory references):
3418 194         431 $par = conv_intel_addr_to_att $par;
3419              
3420             # (changing "stN" to "st(N)")
3421 194         494 $par =~ s/\bst(\d)\b/\%st($1)/go;
3422              
3423             # (adding percent chars)
3424 194         367 foreach my $r (@regs_intel) {
3425              
3426 41516         232151 $par =~ s/\b$r\b/\%$r/gi;
3427             }
3428 194         430 foreach my $r (@regs_intel) {
3429              
3430 41516         203499 $par =~ s/\%\%$r\b/\%$r/gi;
3431             }
3432              
3433             # (REP**: adding the end of line char)
3434 194         600 $par =~ s/^\s*(rep[enz]{0,2})\s+/\t$1\n\t/io;
3435              
3436 194         1019 return $par;
3437             }
3438              
3439             =head1 SUPPORT AND DOCUMENTATION
3440              
3441             After installing, you can find documentation for this module with the perldoc command.
3442              
3443             perldoc Asm::X86
3444              
3445             You can also look for information at:
3446              
3447             Search CPAN
3448             https://metacpan.org/release/Asm-X86
3449             http://search.cpan.org/dist/Asm-X86
3450              
3451             CPAN Request Tracker:
3452             https://rt.cpan.org/Public/Dist/Display.html?Name=Asm-X86
3453             http://rt.cpan.org/NoAuth/Bugs.html?Dist=Asm-X86
3454              
3455             CPAN Ratings:
3456             https://cpanratings.perl.org/dist/Asm-X86
3457             http://cpanratings.perl.org/d/Asm-X86
3458              
3459             =head1 AUTHOR
3460              
3461             Bogdan Drozdowski, C<< >>
3462              
3463             =head1 COPYRIGHT
3464              
3465             Copyright 2008-2021 Bogdan Drozdowski, all rights reserved.
3466              
3467             =head1 LICENSE
3468              
3469             This program is free software; you can redistribute it and/or modify it
3470             under the same terms as Perl itself.
3471              
3472             =cut
3473              
3474             1; # End of Asm::X86