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