mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174067 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
 | |
| #!/usr/bin/python
 | |
| 
 | |
| # Auto-generates an exhaustive and repetitive test for correct bundle-locked
 | |
| # alignment on x86.
 | |
| # For every possible offset in an aligned bundle, a bundle-locked group of every
 | |
| # size in the inclusive range [1, bundle_size] is inserted. An appropriate CHECK
 | |
| # is added to verify that NOP padding occurred (or did not occur) as expected.
 | |
| # Run with --align-to-end to generate a similar test with align_to_end for each
 | |
| # .bundle_lock directive.
 | |
| 
 | |
| # This script runs with Python 2.7 and 3.2+
 | |
| 
 | |
| from __future__ import print_function
 | |
| import argparse
 | |
| 
 | |
| BUNDLE_SIZE_POW2 = 4
 | |
| BUNDLE_SIZE = 2 ** BUNDLE_SIZE_POW2
 | |
| 
 | |
| PREAMBLE = '''
 | |
| # RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \\
 | |
| # RUN:   | llvm-objdump -triple i386 -disassemble -no-show-raw-insn - | FileCheck %s
 | |
| 
 | |
| # !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!!
 | |
| #     It tests that bundle-aligned grouping works correctly in MC. Read the
 | |
| #     source of the script for more details.
 | |
| 
 | |
|   .text
 | |
|   .bundle_align_mode {0}
 | |
| '''.format(BUNDLE_SIZE_POW2).lstrip()
 | |
| 
 | |
| ALIGNTO = '  .align {0}, 0x90'
 | |
| NOPFILL = '  .fill {0}, 1, 0x90'
 | |
| 
 | |
| def print_bundle_locked_sequence(len, align_to_end=False):
 | |
|   print('  .bundle_lock{0}'.format(' align_to_end' if align_to_end else ''))
 | |
|   print('  .rept {0}'.format(len))
 | |
|   print('  inc %eax')
 | |
|   print('  .endr')
 | |
|   print('  .bundle_unlock')
 | |
| 
 | |
| def generate(align_to_end=False):
 | |
|   print(PREAMBLE)
 | |
| 
 | |
|   ntest = 0
 | |
|   for instlen in range(1, BUNDLE_SIZE + 1):
 | |
|     for offset in range(0, BUNDLE_SIZE):
 | |
|       # Spread out all the instructions to not worry about cross-bundle
 | |
|       # interference.
 | |
|       print(ALIGNTO.format(2 * BUNDLE_SIZE))
 | |
|       print('INSTRLEN_{0}_OFFSET_{1}:'.format(instlen, offset))
 | |
|       if offset > 0:
 | |
|         print(NOPFILL.format(offset))
 | |
|       print_bundle_locked_sequence(instlen, align_to_end)
 | |
| 
 | |
|       # Now generate an appropriate CHECK line
 | |
|       base_offset = ntest * 2 * BUNDLE_SIZE
 | |
|       inst_orig_offset = base_offset + offset  # had it not been padded...
 | |
| 
 | |
|       def print_check(adjusted_offset=None, nop_split_offset=None):
 | |
|         if adjusted_offset is not None:
 | |
|           print('# CHECK: {0:x}: nop'.format(inst_orig_offset))
 | |
|           if nop_split_offset is not None:
 | |
|             print('# CHECK: {0:x}: nop'.format(nop_split_offset))
 | |
|           print('# CHECK: {0:x}: incl'.format(adjusted_offset))
 | |
|         else:
 | |
|           print('# CHECK: {0:x}: incl'.format(inst_orig_offset))
 | |
| 
 | |
|       if align_to_end:
 | |
|         if offset + instlen == BUNDLE_SIZE:
 | |
|           # No padding needed
 | |
|           print_check()
 | |
|         elif offset + instlen < BUNDLE_SIZE:
 | |
|           # Pad to end at nearest bundle boundary
 | |
|           offset_to_end = base_offset + (BUNDLE_SIZE - instlen)
 | |
|           print_check(offset_to_end)
 | |
|         else: # offset + instlen > BUNDLE_SIZE
 | |
|           # Pad to end at next bundle boundary, splitting the nop sequence
 | |
|           # at the nearest bundle boundary
 | |
|           offset_to_nearest_bundle = base_offset + BUNDLE_SIZE
 | |
|           offset_to_end = base_offset + (BUNDLE_SIZE * 2 - instlen)
 | |
|           if offset_to_nearest_bundle == offset_to_end:
 | |
|             offset_to_nearest_bundle = None
 | |
|           print_check(offset_to_end, offset_to_nearest_bundle)
 | |
|       else:
 | |
|         if offset + instlen > BUNDLE_SIZE:
 | |
|           # Padding needed
 | |
|           aligned_offset = (inst_orig_offset + instlen) & ~(BUNDLE_SIZE - 1)
 | |
|           print_check(aligned_offset)
 | |
|         else:
 | |
|           # No padding needed
 | |
|           print_check()
 | |
| 
 | |
|       print()
 | |
|       ntest += 1
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|   argparser = argparse.ArgumentParser()
 | |
|   argparser.add_argument('--align-to-end',
 | |
|                          action='store_true',
 | |
|                          help='generate .bundle_lock with align_to_end option')
 | |
|   args = argparser.parse_args()
 | |
|   generate(align_to_end=args.align_to_end)
 |