xref: /aosp_15_r20/external/llvm/utils/testgen/mc-bundling-x86-gen.py (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker
2*9880d681SAndroid Build Coastguard Worker#!/usr/bin/python
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker# Auto-generates an exhaustive and repetitive test for correct bundle-locked
5*9880d681SAndroid Build Coastguard Worker# alignment on x86.
6*9880d681SAndroid Build Coastguard Worker# For every possible offset in an aligned bundle, a bundle-locked group of every
7*9880d681SAndroid Build Coastguard Worker# size in the inclusive range [1, bundle_size] is inserted. An appropriate CHECK
8*9880d681SAndroid Build Coastguard Worker# is added to verify that NOP padding occurred (or did not occur) as expected.
9*9880d681SAndroid Build Coastguard Worker# Run with --align-to-end to generate a similar test with align_to_end for each
10*9880d681SAndroid Build Coastguard Worker# .bundle_lock directive.
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker# This script runs with Python 2.7 and 3.2+
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerfrom __future__ import print_function
15*9880d681SAndroid Build Coastguard Workerimport argparse
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard WorkerBUNDLE_SIZE_POW2 = 4
18*9880d681SAndroid Build Coastguard WorkerBUNDLE_SIZE = 2 ** BUNDLE_SIZE_POW2
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard WorkerPREAMBLE = '''
21*9880d681SAndroid Build Coastguard Worker# RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \\
22*9880d681SAndroid Build Coastguard Worker# RUN:   | llvm-objdump -triple i386 -disassemble -no-show-raw-insn - | FileCheck %s
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker# !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!!
25*9880d681SAndroid Build Coastguard Worker#     It tests that bundle-aligned grouping works correctly in MC. Read the
26*9880d681SAndroid Build Coastguard Worker#     source of the script for more details.
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker  .text
29*9880d681SAndroid Build Coastguard Worker  .bundle_align_mode {0}
30*9880d681SAndroid Build Coastguard Worker'''.format(BUNDLE_SIZE_POW2).lstrip()
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard WorkerALIGNTO = '  .align {0}, 0x90'
33*9880d681SAndroid Build Coastguard WorkerNOPFILL = '  .fill {0}, 1, 0x90'
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Workerdef print_bundle_locked_sequence(len, align_to_end=False):
36*9880d681SAndroid Build Coastguard Worker  print('  .bundle_lock{0}'.format(' align_to_end' if align_to_end else ''))
37*9880d681SAndroid Build Coastguard Worker  print('  .rept {0}'.format(len))
38*9880d681SAndroid Build Coastguard Worker  print('  inc %eax')
39*9880d681SAndroid Build Coastguard Worker  print('  .endr')
40*9880d681SAndroid Build Coastguard Worker  print('  .bundle_unlock')
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Workerdef generate(align_to_end=False):
43*9880d681SAndroid Build Coastguard Worker  print(PREAMBLE)
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker  ntest = 0
46*9880d681SAndroid Build Coastguard Worker  for instlen in range(1, BUNDLE_SIZE + 1):
47*9880d681SAndroid Build Coastguard Worker    for offset in range(0, BUNDLE_SIZE):
48*9880d681SAndroid Build Coastguard Worker      # Spread out all the instructions to not worry about cross-bundle
49*9880d681SAndroid Build Coastguard Worker      # interference.
50*9880d681SAndroid Build Coastguard Worker      print(ALIGNTO.format(2 * BUNDLE_SIZE))
51*9880d681SAndroid Build Coastguard Worker      print('INSTRLEN_{0}_OFFSET_{1}:'.format(instlen, offset))
52*9880d681SAndroid Build Coastguard Worker      if offset > 0:
53*9880d681SAndroid Build Coastguard Worker        print(NOPFILL.format(offset))
54*9880d681SAndroid Build Coastguard Worker      print_bundle_locked_sequence(instlen, align_to_end)
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker      # Now generate an appropriate CHECK line
57*9880d681SAndroid Build Coastguard Worker      base_offset = ntest * 2 * BUNDLE_SIZE
58*9880d681SAndroid Build Coastguard Worker      inst_orig_offset = base_offset + offset  # had it not been padded...
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker      def print_check(adjusted_offset=None, nop_split_offset=None):
61*9880d681SAndroid Build Coastguard Worker        if adjusted_offset is not None:
62*9880d681SAndroid Build Coastguard Worker          print('# CHECK: {0:x}: nop'.format(inst_orig_offset))
63*9880d681SAndroid Build Coastguard Worker          if nop_split_offset is not None:
64*9880d681SAndroid Build Coastguard Worker            print('# CHECK: {0:x}: nop'.format(nop_split_offset))
65*9880d681SAndroid Build Coastguard Worker          print('# CHECK: {0:x}: incl'.format(adjusted_offset))
66*9880d681SAndroid Build Coastguard Worker        else:
67*9880d681SAndroid Build Coastguard Worker          print('# CHECK: {0:x}: incl'.format(inst_orig_offset))
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker      if align_to_end:
70*9880d681SAndroid Build Coastguard Worker        if offset + instlen == BUNDLE_SIZE:
71*9880d681SAndroid Build Coastguard Worker          # No padding needed
72*9880d681SAndroid Build Coastguard Worker          print_check()
73*9880d681SAndroid Build Coastguard Worker        elif offset + instlen < BUNDLE_SIZE:
74*9880d681SAndroid Build Coastguard Worker          # Pad to end at nearest bundle boundary
75*9880d681SAndroid Build Coastguard Worker          offset_to_end = base_offset + (BUNDLE_SIZE - instlen)
76*9880d681SAndroid Build Coastguard Worker          print_check(offset_to_end)
77*9880d681SAndroid Build Coastguard Worker        else: # offset + instlen > BUNDLE_SIZE
78*9880d681SAndroid Build Coastguard Worker          # Pad to end at next bundle boundary, splitting the nop sequence
79*9880d681SAndroid Build Coastguard Worker          # at the nearest bundle boundary
80*9880d681SAndroid Build Coastguard Worker          offset_to_nearest_bundle = base_offset + BUNDLE_SIZE
81*9880d681SAndroid Build Coastguard Worker          offset_to_end = base_offset + (BUNDLE_SIZE * 2 - instlen)
82*9880d681SAndroid Build Coastguard Worker          if offset_to_nearest_bundle == offset_to_end:
83*9880d681SAndroid Build Coastguard Worker            offset_to_nearest_bundle = None
84*9880d681SAndroid Build Coastguard Worker          print_check(offset_to_end, offset_to_nearest_bundle)
85*9880d681SAndroid Build Coastguard Worker      else:
86*9880d681SAndroid Build Coastguard Worker        if offset + instlen > BUNDLE_SIZE:
87*9880d681SAndroid Build Coastguard Worker          # Padding needed
88*9880d681SAndroid Build Coastguard Worker          aligned_offset = (inst_orig_offset + instlen) & ~(BUNDLE_SIZE - 1)
89*9880d681SAndroid Build Coastguard Worker          print_check(aligned_offset)
90*9880d681SAndroid Build Coastguard Worker        else:
91*9880d681SAndroid Build Coastguard Worker          # No padding needed
92*9880d681SAndroid Build Coastguard Worker          print_check()
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker      print()
95*9880d681SAndroid Build Coastguard Worker      ntest += 1
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Workerif __name__ == '__main__':
98*9880d681SAndroid Build Coastguard Worker  argparser = argparse.ArgumentParser()
99*9880d681SAndroid Build Coastguard Worker  argparser.add_argument('--align-to-end',
100*9880d681SAndroid Build Coastguard Worker                         action='store_true',
101*9880d681SAndroid Build Coastguard Worker                         help='generate .bundle_lock with align_to_end option')
102*9880d681SAndroid Build Coastguard Worker  args = argparser.parse_args()
103*9880d681SAndroid Build Coastguard Worker  generate(align_to_end=args.align_to_end)
104