File Coverage

blib/lib/Asm/X86.pm
Criterion Covered Total %
statement 869 869 100.0
branch 844 844 100.0
condition 765 765 100.0
subroutine 76 76 100.0
pod 55 55 100.0
total 2609 2609 100.0


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