| OLD | NEW |
| 1 # -*- python -*- | 1 # -*- python -*- |
| 2 # Copyright 2011 The Native Client Authors. All rights reserved. | 2 # Copyright 2011 The Native Client Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 Import('env') | 6 Import('env') |
| 7 | 7 |
| 8 # If this test is failing on the bots, you can find the seed | 8 # If this test is failing on the bots, you can find the seed |
| 9 # from the output of the bot. Look for "--seed=". | 9 # from the output of the bot. Look for "--seed=". |
| 10 # To reproduce the exact problem, set settings['seed'] below | 10 # To reproduce the exact problem, set settings['seed'] below |
| 11 # to the fixed seed you found on the bot. | 11 # to the fixed seed you found on the bot. |
| 12 | 12 |
| 13 # | 13 # |
| 14 # Calling Convention Test | 14 # Calling Convention Test |
| 15 # | 15 # |
| 16 # The "generate.py" script generates 4 modules (module0.c ... module3.c). | 16 # The "generate.py" script generates 4 modules (module0.c ... module3.c). |
| 17 # Each module has functions, and calls to other functions in other modules. | 17 # Each module has functions, and calls to other functions in other modules. |
| 18 # Each function has multiple fixed and variable arguments. | 18 # Each function has multiple fixed and variable arguments. |
| 19 # This tests (by brute force) the correctness of the calling convention. | 19 # This tests (by brute force) the correctness of the calling convention. |
| 20 # | 20 # |
| 21 # To test toolchain compatibility, some of the modules are built | 21 # To test toolchain compatibility, some of the modules are built |
| 22 # using PNaCl, and some with NNaCl. | 22 # using PNaCl, and some with NNaCl. |
| 23 | 23 |
| 24 import random | 24 import random |
| 25 | 25 |
| 26 base_env = env.Clone() | 26 base_env = env.Clone() |
| 27 callingconv_h = base_env.File('callingconv.h').srcnode() | 27 callingconv_h = base_env.File('callingconv.h').srcnode() |
| 28 extra_cflags = [ '-Wno-long-long', '-I' + callingconv_h.dir.abspath ] | 28 extra_cflags = [ '-Wno-long-long', '-I' + callingconv_h.dir.abspath ] |
| 29 base_env.Append(CFLAGS = extra_cflags) | |
| 30 | 29 |
| 31 settings = { | 30 settings = { |
| 32 'num_functions' : 200, | 31 'num_functions' : 200, |
| 33 'calls_per_func' : 4, | 32 'calls_per_func' : 4, |
| 34 'max_args_per_func': 16, | 33 'max_args_per_func': 16, |
| 35 'num_modules' : 4, | |
| 36 } | 34 } |
| 37 | 35 |
| 38 # va_arg of struct types is broken in PNaCl | 36 # va_arg of struct types is broken in PNaCl |
| 39 if env.Bit('bitcode'): | 37 if env.Bit('bitcode'): |
| 40 settings['allow_struct_va_arg'] = 0 | 38 settings['allow_struct_va_arg'] = 0 |
| 41 | 39 |
| 42 # Structure passing in PNaCl is broken. | 40 # Structure passing in PNaCl is broken. |
| 43 # On X86-32, long long and double in structures are passed | 41 # On X86-32, long long and double in structures are passed |
| 44 # with the wrong alignment. | 42 # with the wrong alignment. |
| 45 # On X86-64, the ABI is not implemented. | 43 # On X86-64, the ABI is not implemented. |
| 46 # There's a good chance ARM has similar problems. | 44 # There's a good chance ARM has similar problems. |
| 47 if env.Bit('bitcode'): | 45 if env.Bit('bitcode'): |
| 48 settings['allow_struct'] = 0 | 46 settings['allow_struct'] = 0 |
| 49 | 47 |
| 50 # Environments for building module sources | 48 # Environments for building module sources |
| 51 envlist = [] | 49 envlist = [] |
| 52 | 50 |
| 53 if env.Bit('bitcode'): | 51 if env.Bit('bitcode'): |
| 54 # For PNaCl, do a mixed test: | 52 # For PNaCl, we do a mixed test. |
| 55 # Compile two modules with PNaCl (straight to native code) | 53 # Create environments for pnacl-clang, pnacl-gcc, and nacl-gcc. |
| 56 # and the other modules with the native toolchain. | 54 # For each environment, we compile a test module straight to native code. |
| 57 pnacl_env = base_env.Clone() | 55 pnacl_env = base_env.Clone() |
| 58 pnacl_env.PNaClForceNative() | 56 pnacl_env.PNaClForceNative() |
| 59 envlist.append(pnacl_env) | 57 envlist.append(pnacl_env) |
| 60 | 58 |
| 59 if env['PNACL_FRONTEND'] == 'clang': |
| 60 alt_env = base_env.PNaClChangeFrontend('llvmgcc') |
| 61 alt_env.PNaClForceNative() |
| 62 envlist.append(alt_env) |
| 63 |
| 61 # On X86-32 and X86-64, test against nacl-gcc also. | 64 # On X86-32 and X86-64, test against nacl-gcc also. |
| 62 # For ARM, we can only test PNaCl's self-consistency. | 65 # For ARM, we can only test PNaCl's self-consistency. |
| 63 if not base_env.Bit('target_arm'): | 66 if not base_env.Bit('target_arm'): |
| 64 native_env = base_env.PNaClGetNNaClEnv() # Clears CFLAGS | 67 native_env = base_env.PNaClGetNNaClEnv() |
| 65 native_env.Append(CFLAGS = extra_cflags) | |
| 66 envlist.append(native_env) | 68 envlist.append(native_env) |
| 67 | 69 |
| 68 link_env = pnacl_env | 70 link_env = pnacl_env |
| 69 else: | 71 else: |
| 70 # For NNaCl toolchain, just test self-consistency | 72 # For NNaCl toolchain, just test self-consistency |
| 71 link_env = base_env | 73 link_env = base_env |
| 72 envlist.append(base_env) | 74 envlist.append(base_env) |
| 73 | 75 |
| 74 num_modules = settings['num_modules'] | 76 # Add custom CFLAGS |
| 77 # This must be done here, since PNaClGetNNaClEnv and |
| 78 # PNaclChangeFrontend wipe CFLAGS. |
| 79 for e in envlist: |
| 80 e.Append(CFLAGS = extra_cflags) |
| 81 |
| 82 # Create two modules for each environment, |
| 83 # so that we test toolchain self-interaction. |
| 84 envlist = envlist + envlist |
| 85 |
| 86 num_modules = len(envlist) |
| 87 settings['num_modules'] = num_modules |
| 75 module_filenames = [ 'module%d.c' % i for i in xrange(num_modules) ] | 88 module_filenames = [ 'module%d.c' % i for i in xrange(num_modules) ] |
| 76 | 89 |
| 77 # Generate the module source files (module0.c, module1.c, ...) | 90 # Generate the module source files (module0.c, module1.c, ...) |
| 78 settings_args = ['--%s=%s' % (k,str(v)) for k,v in settings.iteritems()] | 91 settings_args = ['--%s=%s' % (k,str(v)) for k,v in settings.iteritems()] |
| 79 base_env['GENERATOR_SETTINGS'] = ' '.join(settings_args) | 92 base_env['GENERATOR_SETTINGS'] = ' '.join(settings_args) |
| 80 | 93 |
| 81 nodes = base_env.Command( | 94 nodes = base_env.Command( |
| 82 ['callingconv.golden'] + module_filenames, | 95 ['callingconv.golden'] + module_filenames, |
| 83 base_env.File('generate.py'), | 96 base_env.File('generate.py'), |
| 84 Action('${PYTHON} ${SOURCE} ${GENERATOR_SETTINGS} -- ${TARGETS}')) | 97 Action('${PYTHON} ${SOURCE} ${GENERATOR_SETTINGS} -- ${TARGETS}')) |
| 85 | 98 |
| 86 # All the modules and callingconv.c depend on the header file | 99 # Create the module objects |
| 87 base_env.Depends(nodes, callingconv_h) | |
| 88 | |
| 89 # Assign each module a build environment | |
| 90 module_env = [] | |
| 91 j = 0 | |
| 92 for i in xrange(num_modules): | |
| 93 module_env.append(envlist[j]) | |
| 94 j = (j+1) % len(envlist) | |
| 95 | |
| 96 # Create the module component objects | |
| 97 modules = [] | 100 modules = [] |
| 98 for i in xrange(num_modules): | 101 for i in xrange(num_modules): |
| 99 modules.append(module_env[i].ComponentObject(nodes[i+1])) | 102 obj = envlist[i].ComponentObject(nodes[i+1]) |
| 103 envlist[i].Depends(obj, callingconv_h) |
| 104 modules.append(obj) |
| 100 | 105 |
| 101 # Compile callingconv.c | 106 # Compile callingconv.c |
| 102 callingconv = link_env.ComponentObject('callingconv.c') | 107 callingconv = link_env.ComponentObject('callingconv.c') |
| 108 link_env.Depends(callingconv, callingconv_h) |
| 109 |
| 103 | 110 |
| 104 prog = link_env.ComponentProgram('callingconv', | 111 prog = link_env.ComponentProgram('callingconv', |
| 105 [callingconv] + modules, | 112 [callingconv] + modules, |
| 106 EXTRA_LIBS=['${NONIRT_LIBS}']) | 113 EXTRA_LIBS=['${NONIRT_LIBS}']) |
| 107 | 114 |
| 108 node = link_env.CommandSelLdrTestNacl( | 115 node = link_env.CommandSelLdrTestNacl( |
| 109 'callingconv.out', | 116 'callingconv.out', |
| 110 prog, | 117 prog, |
| 111 stdout_golden=nodes[0]) | 118 stdout_golden=nodes[0]) |
| 112 | 119 |
| 113 env.AddNodeToTestSuite(node, ['medium_tests'], 'run_callingconv_test', | 120 env.AddNodeToTestSuite(node, ['medium_tests'], 'run_callingconv_test', |
| 114 # This test takes too long to compile for ARM | 121 # This test takes too long to compile for ARM |
| 115 # and the resulting code doesn't pass this test. | 122 # and the resulting code doesn't pass this test. |
| 116 is_broken=env.Bit('target_arm')) | 123 is_broken=env.Bit('target_arm')) |
| OLD | NEW |