blob: 832e8416020faebc89420a890a083adc411f5eff [file] [log] [blame]
Eli Benderskyb17201f2012-12-20 19:16:57 +00001#!/usr/bin/python
2
3# Auto-generates an exhaustive and repetitive test for correct bundle-locked
4# alignment on x86.
5# For every possible offset in an aligned bundle, a bundle-locked group of every
6# size in the inclusive range [1, bundle_size] is inserted. An appropriate CHECK
7# is added to verify that NOP padding occurred (or did not occur) as expected.
Eli Bendersky59d15212013-01-07 23:12:59 +00008# Run with --align-to-end to generate a similar test with align_to_end for each
9# .bundle_lock directive.
Eli Benderskyb17201f2012-12-20 19:16:57 +000010
Eli Bendersky59d15212013-01-07 23:12:59 +000011# This script runs with Python 2.7 and 3.2+
Eli Benderskyb17201f2012-12-20 19:16:57 +000012
13from __future__ import print_function
Eli Bendersky59d15212013-01-07 23:12:59 +000014import argparse
Eli Benderskyb17201f2012-12-20 19:16:57 +000015
16BUNDLE_SIZE_POW2 = 4
17BUNDLE_SIZE = 2 ** BUNDLE_SIZE_POW2
18
19PREAMBLE = '''
20# RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \\
21# RUN: | llvm-objdump -triple i386 -disassemble -no-show-raw-insn - | FileCheck %s
22
23# !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!!
24# It tests that bundle-aligned grouping works correctly in MC. Read the
25# source of the script for more details.
26
27 .text
28 .bundle_align_mode {0}
29'''.format(BUNDLE_SIZE_POW2).lstrip()
30
31ALIGNTO = ' .align {0}, 0x90'
32NOPFILL = ' .fill {0}, 1, 0x90'
33
Eli Bendersky59d15212013-01-07 23:12:59 +000034def print_bundle_locked_sequence(len, align_to_end=False):
35 print(' .bundle_lock{0}'.format(' align_to_end' if align_to_end else ''))
Eli Benderskyb17201f2012-12-20 19:16:57 +000036 print(' .rept {0}'.format(len))
37 print(' inc %eax')
38 print(' .endr')
39 print(' .bundle_unlock')
40
Eli Bendersky59d15212013-01-07 23:12:59 +000041def generate(align_to_end=False):
Eli Benderskyb17201f2012-12-20 19:16:57 +000042 print(PREAMBLE)
43
44 ntest = 0
45 for instlen in range(1, BUNDLE_SIZE + 1):
46 for offset in range(0, BUNDLE_SIZE):
47 # Spread out all the instructions to not worry about cross-bundle
48 # interference.
49 print(ALIGNTO.format(2 * BUNDLE_SIZE))
50 print('INSTRLEN_{0}_OFFSET_{1}:'.format(instlen, offset))
51 if offset > 0:
52 print(NOPFILL.format(offset))
Eli Bendersky59d15212013-01-07 23:12:59 +000053 print_bundle_locked_sequence(instlen, align_to_end)
Eli Benderskyb17201f2012-12-20 19:16:57 +000054
55 # Now generate an appropriate CHECK line
56 base_offset = ntest * 2 * BUNDLE_SIZE
57 inst_orig_offset = base_offset + offset # had it not been padded...
Eli Bendersky59d15212013-01-07 23:12:59 +000058
59 def print_check(adjusted_offset=None):
60 if adjusted_offset is not None:
61 print('# CHECK: {0:x}: nop'.format(inst_orig_offset))
62 print('# CHECK: {0:x}: incl'.format(adjusted_offset))
63 else:
64 print('# CHECK: {0:x}: incl'.format(inst_orig_offset))
Eli Benderskyb17201f2012-12-20 19:16:57 +000065
Eli Bendersky59d15212013-01-07 23:12:59 +000066 if align_to_end:
67 if offset + instlen == BUNDLE_SIZE:
68 # No padding needed
69 print_check()
70 elif offset + instlen < BUNDLE_SIZE:
71 # Pad to end at nearest bundle boundary
72 offset_to_end = base_offset + (BUNDLE_SIZE - instlen)
73 print_check(offset_to_end)
74 else: # offset + instlen > BUNDLE_SIZE
75 # Pad to end at next bundle boundary
76 offset_to_end = base_offset + (BUNDLE_SIZE * 2 - instlen)
77 print_check(offset_to_end)
Eli Benderskyb17201f2012-12-20 19:16:57 +000078 else:
Eli Bendersky59d15212013-01-07 23:12:59 +000079 if offset + instlen > BUNDLE_SIZE:
80 # Padding needed
81 aligned_offset = (inst_orig_offset + instlen) & ~(BUNDLE_SIZE - 1)
82 print_check(aligned_offset)
83 else:
84 # No padding needed
85 print_check()
Eli Benderskyb17201f2012-12-20 19:16:57 +000086
87 print()
88 ntest += 1
89
90if __name__ == '__main__':
Eli Bendersky59d15212013-01-07 23:12:59 +000091 argparser = argparse.ArgumentParser()
92 argparser.add_argument('--align-to-end',
93 action='store_true',
94 help='generate .bundle_lock with align_to_end option')
95 args = argparser.parse_args()
96 generate(align_to_end=args.align_to_end)
97
Eli Benderskyb17201f2012-12-20 19:16:57 +000098