4 # Auto-generates an exhaustive and repetitive test for correct bundle-locked
6 # For every possible offset in an aligned bundle, a bundle-locked group of every
7 # size in the inclusive range [1, bundle_size] is inserted. An appropriate CHECK
8 # is added to verify that NOP padding occurred (or did not occur) as expected.
9 # Run with --align-to-end to generate a similar test with align_to_end for each
10 # .bundle_lock directive.
12 # This script runs with Python 2.7 and 3.2+
14 from __future__
import print_function
18 BUNDLE_SIZE
= 2 ** BUNDLE_SIZE_POW2
21 # RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \\
22 # RUN: | llvm-objdump -triple i386 -disassemble -no-show-raw-insn - | FileCheck %s
24 # !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!!
25 # It tests that bundle-aligned grouping works correctly in MC. Read the
26 # source of the script for more details.
29 .bundle_align_mode {0}
30 '''.format(BUNDLE_SIZE_POW2
).lstrip()
32 ALIGNTO
= ' .align {0}, 0x90'
33 NOPFILL
= ' .fill {0}, 1, 0x90'
35 def print_bundle_locked_sequence(len, align_to_end
=False):
36 print(' .bundle_lock{0}'.format(' align_to_end' if align_to_end
else ''))
37 print(' .rept {0}'.format(len))
40 print(' .bundle_unlock')
42 def generate(align_to_end
=False):
46 for instlen
in range(1, BUNDLE_SIZE
+ 1):
47 for offset
in range(0, BUNDLE_SIZE
):
48 # Spread out all the instructions to not worry about cross-bundle
50 print(ALIGNTO
.format(2 * BUNDLE_SIZE
))
51 print('INSTRLEN_{0}_OFFSET_{1}:'.format(instlen
, offset
))
53 print(NOPFILL
.format(offset
))
54 print_bundle_locked_sequence(instlen
, align_to_end
)
56 # Now generate an appropriate CHECK line
57 base_offset
= ntest
* 2 * BUNDLE_SIZE
58 inst_orig_offset
= base_offset
+ offset
# had it not been padded...
60 def print_check(adjusted_offset
=None, nop_split_offset
=None):
61 if adjusted_offset
is not None:
62 print('# CHECK: {0:x}: nop'.format(inst_orig_offset
))
63 if nop_split_offset
is not None:
64 print('# CHECK: {0:x}: nop'.format(nop_split_offset
))
65 print('# CHECK: {0:x}: incl'.format(adjusted_offset
))
67 print('# CHECK: {0:x}: incl'.format(inst_orig_offset
))
70 if offset
+ instlen
== BUNDLE_SIZE
:
73 elif offset
+ instlen
< BUNDLE_SIZE
:
74 # Pad to end at nearest bundle boundary
75 offset_to_end
= base_offset
+ (BUNDLE_SIZE
- instlen
)
76 print_check(offset_to_end
)
77 else: # offset + instlen > BUNDLE_SIZE
78 # Pad to end at next bundle boundary, splitting the nop sequence
79 # at the nearest bundle boundary
80 offset_to_nearest_bundle
= base_offset
+ BUNDLE_SIZE
81 offset_to_end
= base_offset
+ (BUNDLE_SIZE
* 2 - instlen
)
82 if offset_to_nearest_bundle
== offset_to_end
:
83 offset_to_nearest_bundle
= None
84 print_check(offset_to_end
, offset_to_nearest_bundle
)
86 if offset
+ instlen
> BUNDLE_SIZE
:
88 aligned_offset
= (inst_orig_offset
+ instlen
) & ~
(BUNDLE_SIZE
- 1)
89 print_check(aligned_offset
)
97 if __name__
== '__main__':
98 argparser
= argparse
.ArgumentParser()
99 argparser
.add_argument('--align-to-end',
101 help='generate .bundle_lock with align_to_end option')
102 args
= argparser
.parse_args()
103 generate(align_to_end
=args
.align_to_end
)