def init_pin_environment_compile(env): env['pintool_suffix'] = '' env['pintool_suffix'] = env['DLLEXT'] if env['host_cpu'] == 'x86-64': env['pin_arch'] = 'intel64' env['sde_arch'] = 'intel64' env['arch'] = 'intel64' else: env['pin_arch'] = 'ia32' env['sde_arch'] = 'ia32' env['arch'] = 'ia32' if 'avx' in env: if env['avx']: if env['host_cpu'] == 'x86-64': env['sde_arch'] = 'intel64-avx' else: env['avx'] = False pin_cpu_bits = {'ia32': '32', 'x86-64': '64', 'ipf': '64'} pin_cpu_types = {'ia32': 'ia32', 'x86-64': 'ia32e', 'ipf': 'ipf'} pin_fund_cpu_types = {'ia32': 'ia32', 'x86-64': 'intel64', 'ipf': 'ia64'} pin_os_types = {'mac': 'm', 'lin': 'l', 'win': 'w'} pin_os_targets = {'mac': 'MAC', 'lin': 'LINUX', 'win': 'WINDOWS'} env['pin_cpu_bits'] = pin_cpu_bits pin_cpu = pin_cpu_types[env['host_cpu']].upper() pin_fund_cpu = pin_fund_cpu_types[env['host_cpu']].upper() pin_os = pin_os_targets[env['host_os']] env.add_define('TARGET_' + pin_cpu) env.add_define('HOST_' + pin_cpu) env.add_define('TARGET_' + pin_os) env.add_define('HOST_' + pin_os) if env.on_mac(): env.add_define('TARGET_MAC') env.add_define('SDE_INIT') env.add_define('BIGARRAY_MULTIPLIER=1') if env['host_cpu'] != 'ipf': env.add_define('USING_XED') ############################################################################ pin_header_dirs = [] pin_header_dirs = [ mbuild.join(env['pin'], 'source', 'include', 'pin'), mbuild.join(env['pin'], 'source', 'include', 'pin', 'gen'), mbuild.join(env['pin'], 'source', 'tools', 'PinPoints'), mbuild.join(env['pin'], 'extras', 'components', 'include'), mbuild.join(env['pin'], 'extras', 'xed-%(pin_arch)s', 'include', 'xed') ] for hdir in pin_header_dirs: hdir = env.expand_string(hdir) add_include_dir(env, hdir)
def find_linux_linker(env): ld1 = env.expand_string("%(LINK)s") ld2 = mbuild.join(env.expand_string("%(toolchain)s"), 'gld') ld3 = mbuild.join(env.expand_string("%(toolchain)s"), 'ld') ld4 = env.path_search(ld1) ld5 = env.path_search('gld') ld6 = env.path_search('ld') locs = [ld1, ld2, ld3, ld4, ld5, ld6] found = find_file(locs) if found: env['LINK'] = found else: mbuild.die("Cannot find linker (ld,gld): %s" % ("\n\t".join(locs)))
def find_linux_archiver(env): ar1 = env.expand_string("%(AR)s") ar2 = mbuild.join(env.expand_string("%(toolchain)s"), 'gar') ar3 = mbuild.join(env.expand_string("%(toolchain)s"), 'ar') ar4 = env.path_search(ar1) ar5 = env.path_search('gar') ar6 = env.path_search('ar') locs = [ar1, ar2, ar3, ar4, ar5, ar6] found = find_file(locs) if found: env['AR'] = found else: mbuild.die("Cannot find archiver (ar,gar): %s" % ("\n\t".join(locs)))
def work(agi, all_state_space, all_ops_widths, patterns): """ Main entry point of the module. For each NT generate a capturing function. Then for each sequence of NTs in patterns generate a chain capturing function that would call single capturing functions for each NT. Then for each combination of operands generate operands chain captuirng function. Also generate lookup tables to obtain those chain capturing functions from inum (xed_inst_t index). """ gendir = ild_gendir = agi.common.options.gendir logfn = mbuild.join(gendir, 'xed3_nt_cdicts.txt') log_f = open(logfn, 'w') #generate NT capturing functions capture_fn_list = [] for nt_name in list(agi.nonterminal_dict.keys()): #skip nonterminals that we don't want to capture: #PREFIXES, AVX_SPLITTER, *ISA, etc. if _skip_nt(nt_name): continue _vlog(log_f, 'processing %s\n' % nt_name) #create a constraint_dict_t for each NT nt_cdict = _gen_cdict(agi, nt_name, all_state_space) _vlog(log_f, 'NT:%s:\n%s\n' % (nt_name, nt_cdict)) gi = agi.generator_dict[nt_name] gi.xed3_cdict = nt_cdict #just for transporting #create a function_object_t for the NT fo = _gen_capture_fo(agi, nt_name, all_ops_widths) gi.xed3_capture_fo = fo capture_fn_list.append(fo) _vlog(log_f, fo.emit()) #dump NT capturing functions headers = [operand_storage.get_operand_accessors_fn(), ildutil.ild_header] ild_codegen.dump_flist_2_header(agi, _xed3_nt_capture_header, headers, capture_fn_list, is_private=True) #in each pattern we have a number of NTs, #now that we have a capturing function for each NT #we can create a create a function that would call #needed capturing functions for each pattern. #Also dump lookup tables from inum(xed_inst_t index) to #chain capturing functions _dump_capture_chain_fo_lu(agi, patterns) #do the same for operands of each xed_inst_t _dump_op_capture_chain_fo_lu(agi, patterns) #create chain capturing functions for the NTs that come from #spine, before the INSTRUCTIONS NT _dump_dynamic_part1_f(agi) log_f.close()
def dump_lookup_new(agi, l1_lookup, name_pfx, lu_h_fn, headers, lu_elem_type, define_dict=None, all_zero_by_map=None, output_dir='include-private'): if output_dir: ofn = mbuild.join(output_dir, lu_h_fn) else: ofn = lu_h_fn h_file = agi.open_file(ofn, start=False) for header in headers: h_file.add_header(header) h_file.start() if define_dict: print_defines(h_file, define_dict) array_names = _dump_lookup_low(agi, h_file, l1_lookup, name_pfx, lu_elem_type, all_zero_by_map) _dump_top_level_dispatch_array(agi, h_file, array_names, 'xed_ild_{}_table'.format(name_pfx), lu_elem_type) h_file.close()
def find_windows_h(env): include_path = os.environ['INCLUDE'] include_dirs = include_path.split(';') for curr_dir in include_dirs: if os.path.exists(mbuild.join(curr_dir, 'windows.h')): return curr_dir return None
def init(env): xbc.init(env) if nchk(env, 'xed_lib_dir'): env['xed_lib_dir'] = '../lib' if nchk(env, 'xed_inc_dir'): env['xed_inc_dir'] = '../include' if nchk(env, 'xed_dir'): env['xed_dir'] = '..' fx = mbuild.join(env['xed_dir'], "include", "public") # static headers if os.path.exists(fx): env.add_include_dir(fx) fx = mbuild.join(env['xed_dir'], "include", "public", 'xed') if os.path.exists(fx): env.add_include_dir(fx) env.add_include_dir(env['src_dir']) # examples dir env.add_include_dir(env['xed_inc_dir']) # generated headers
def init_pintool_environment_link(env): pin_lib_dirs = [] env['xed_lib_dir'] = mbuild.join(env['pin'], 'extras', 'xed-%(pin_arch)s', 'lib') pin_lib_dirs = [ mbuild.join(env['pin'], '%(pin_arch)s', 'lib'), mbuild.join(env['pin'], '%(pin_arch)s', 'lib-ext'), mbuild.join(env['pin'], '%(pin_arch)s', 'runtime', 'pincrt') ] pin_lib_dirs.append('%(xed_lib_dir)s') lflags = '' for ldir in pin_lib_dirs: lflags += ' %(LOPT)s' + ldir env['LINKFLAGS'] += lflags
def gen_xed3(agi,ild_info,is_3dnow,ild_patterns, all_state_space,ild_gendir,all_ops_widths): all_cnames = set() ptrn_dict = {} maps = ild_info.get_maps(is_3dnow) for insn_map in maps: ptrn_dict[insn_map] = collections.defaultdict(list) for ptrn in ild_patterns: ptrn_dict[ptrn.insn_map][ptrn.opcode].append(ptrn) #FIXME:bad name vv_lu = {} #mapping between a operands to their look up function op_lu_map = {} for vv in sorted(all_state_space['VEXVALID'].keys()): #cdict is a 2D dictionary: #cdict[map][opcode] = ild_cdict.constraint_dict_t #each constraint_dict_t describes all the patterns that fall #into corresponding map-opcode #cnames is a set of all constraint names from the patterns #in the given vv space cdict,cnames = ild_cdict.get_constraints_lu_table(ptrn_dict, is_3dnow, all_state_space, vv, all_ops_widths) all_cnames = all_cnames.union(cnames) _msg("vv%s cnames: %s" % (vv,cnames)) #now generate the C hash functions for the constraint #dictionaries (ph_lu,lu_fo_list,operands_lu_list) = ild_cdict.gen_ph_fos( agi, cdict, is_3dnow, mbuild.join(ild_gendir, 'all_constraints_vv%s.txt' %vv), ptrn_dict, vv) #hold only one instance of each function for op in operands_lu_list : if op.function_name not in op_lu_map: op_lu_map[op.function_name] = op vv_lu[str(vv)] = (ph_lu,lu_fo_list) _msg("all cnames: %s" % all_cnames) #dump the hash functions and lookup tables for obtaining these #hash functions in the decode time ild_codegen.dump_vv_map_lookup(agi, vv_lu, is_3dnow, list(op_lu_map.values()), h_fn='xed3-phash.h') #xed3_nt.work generates all the functions and lookup tables for #dynamic decoding xed3_nt.work(agi, all_state_space, all_ops_widths, ild_patterns)
def work(): env = mbuild.env_t() env.parser.add_option( "--bulk-make-tests", "-b", dest="bulk_tests", action="append", default=[], help= "List of bulk tests from which to create test references. Repeatable") env.parser.add_option( "--rebase-tests", dest="rebase_tests", action="store_true", default=False, help="Update the reference output files. Do not compare.") env.parser.add_option("--tests", dest="tests", action="append", default=[], help="Directory where tests live.") env.parser.add_option("--otests", dest="otests", action="store", default='tests-base', help="Directory where tests live.") env.parser.add_option("-c", "--code", dest="codes", action="append", default=[], help="Codes for test subsetting (DEC, ENC, AVX, " + "AVX512X, AVX512PF, XOP, KNC)." + " Only used for running tests, not creating them.") env.parse_args() if not env['tests']: env['tests'] = ['tests-base'] xed = mbuild.join(env['build_dir'], 'xed') #xedexe = xed + ".exe" #if not os.path.exists(xed) and not os.path.exists(xedexe): # mbuild.die("Need the xed command line tool: %s or %s\n\n" % (xed,xedexe)) if len(env['bulk_tests']) != 0: mbuild.msgb("MAKE BULK TESTS") make_bulk_tests(env) sys.exit(0) if env['rebase_tests']: rebase_tests(env) sys.exit(0) errors = run_tests(env) sys.exit(errors)
def make_bulk_tests(env): i = 0 for bulk_test_file in env['bulk_tests']: print("[READING BULK TESTS] %s" % (bulk_test_file)) tests = open(bulk_test_file, 'r').readlines() tests = [x.strip() for x in tests] for test in tests: if test: si = mbuild.join(env['otests'], "test-%05d" % (i)) create_reference(env, si, test, make_new=True) i = i + 1
def make_bulk_tests(env): i = 0 for bulk_test_file in env['bulk_tests']: print "[READING BULK TESTS] %s" % (bulk_test_file) tests = file(bulk_test_file).readlines() tests = map(lambda x: x.strip(), tests) for test in tests: if test: si = mbuild.join(env['otests'], "test-%05d" % (i)) create_reference(env, si, test, make_new=True) i = i + 1
def locate_pin_tree(env): if 'pin' not in env: find_build_kit_path(env) env['pin'] = mbuild.join(env['build_kit_path'], 'pinkit') if not env['pin']: mbuild.die('Pin directory is not setup ' + 'properly in the environment {0}'.format(env['pin'])) if not os.path.exists(env['pin']): mbuild.die('cannot find the PIN directory: {0:s}'.format(env['pin'])) mbuild.msgb("FOUND PIN KIT", env['pin']) env['kit'] = True
def start(self, full_header=True): """override the parent's start() function to apply the IP header.""" self.emit_header(full_header) ip_header_file_name = mbuild.join(self.xeddir, 'misc', 'apache-header.txt') for line in self.emit_ip_header(ip_header_file_name): self.emit(line) if not self.shell_file: self.system_headers_emit() self.user_headers_emit() self.misc_headers_emit() self.namespace_start()
def dump_flist_2_header(agi, fname, headers, functions, is_private=True, emit_headers=True, emit_bodies=True): if is_private: h_file = agi.open_file(mbuild.join('include-private', fname), start=False) else: h_file = agi.open_file(fname, start=False) codegen.dump_flist_2_header(h_file, functions, headers, emit_headers, emit_bodies)
def make_bulk_tests(env): i = 0 for bulk_test_file in env['bulk_tests']: print("[READING BULK TESTS] %s" % (bulk_test_file)) tests = open(bulk_test_file, 'r').readlines() tests = [re.sub(r"#.*", '', x) for x in tests] # remove comments tests = [x.strip() for x in tests ] # remove leading/trailing whitespace, newlines for test in tests: if test: si = mbuild.join(env['otests'], "test-%05d" % (i)) create_reference(env, si, test, make_new=True) i = i + 1
def init_pin_crt_compile(env): # Add PIN CRT macros env.add_define('PIN_CRT=1 ') # PIN CRT windwos flags if env.on_windows(): env.add_define('_WINDOWS_H_PATH_="%s"' % (find_windows_h(env))) env.add_define('_TIME_T_DEFINED') env.add_define('_WCTYPE_T_DEFINED') if env['host_cpu'] == 'ia32': env.add_define('__i386__') else: env.add_define('__LP64__') # Add special flags flags = ' /FIinclude/msvc_compat.h /fp:strict ' env['CXXFLAGS'] += flags env['CCFLAGS'] += flags # Add PIN system include headers for CRT if env['host_cpu'] == 'x86-64': bionic_arch = 'x86_64' fenv_arch = 'amd64' else: bionic_arch = 'x86' fenv_arch = 'i387' pin_sys_header_dirs = [ mbuild.join(env['pin'], 'extras', 'stlport', 'include'), mbuild.join(env['pin'], 'extras'), mbuild.join(env['pin'], 'extras', 'libstdc++', 'include'), mbuild.join(env['pin'], 'extras', 'crt', 'include'), mbuild.join(env['pin'], 'extras', 'crt'), mbuild.join(env['pin'], 'extras', 'crt', 'include', 'arch-' + bionic_arch), mbuild.join(env['pin'], 'extras', 'crt', 'include', 'kernel', 'uapi'), mbuild.join(env['pin'], 'extras', 'crt', 'include', 'kernel', 'uapi', 'asm-x86'), mbuild.join(env['pin'], 'extras', 'crt', 'include', fenv_arch) ] for sys_hdir in pin_sys_header_dirs: sys_hdir = env.expand_string(sys_hdir) add_system_include_dir(env, sys_hdir)
def work(agi, united_lookup, eosz_nts, ild_gendir, debug): #dump lookup tables for each NT #just for debugging nt_arrays = [] for nt_name in eosz_nts: array = ild_nt.gen_nt_lookup(agi, nt_name, 'EOSZ') if not array: return None nt_arrays.append(array) ild_nt.dump_lu_arrays(agi, nt_arrays, 'ild_eosz_debug.txt', 'ild_eosz_debug_header.txt') #get all sequences of NTs that set EOSZ #we will use these sequences to create EOSZ-computing functions all_eosz_seq = get_all_eosz_seq(united_lookup) debug.write('EOSZ SEQS: %s\n' % all_eosz_seq) #for each EOSZ sequence create a lookup array nt_seq_arrays = {} for nt_seq in all_eosz_seq: array = ild_nt.gen_nt_seq_lookup(agi, nt_seq, _eosz_token) if not array: return None nt_seq_arrays[tuple(nt_seq)] = array #init function calls all single init functions for the created tables init_f = ild_nt.gen_init_function(list(nt_seq_arrays.values()), 'xed_ild_eosz_init') #dump init and lookup functions for EOSZ sequences ild_nt.dump_lu_arrays(agi, list(nt_seq_arrays.values()), _eosz_c_fn, mbuild.join('include-private', _eosz_header_fn), init_f) #generate EOSZ getter functions - they get xed_decoded_inst_t* #and return EOSZ value (corresponding to EOSZ NT sequence #that they represent) getter_fos = [] for names in nt_seq_arrays.keys(): arr = nt_seq_arrays[names] getter_fo = ild_codegen.gen_derived_operand_getter( agi, _eosz_token, arr, list(names)) getter_fos.append(getter_fo) ild_codegen.dump_flist_2_header(agi, 'xed-ild-eosz-getters.h', [ ildutil.ild_private_header, _eosz_header_fn, operand_storage.get_operand_accessors_fn() ], getter_fos) #getter_lookup = gen_getter_fn_lookup(agi, united_lookup, nt_seq_arrays) return nt_seq_arrays
def dump_header_with_header(agi, fname, header_dict): # FIXME: 2019-10-18 no longer used """ emit the header fname. add the header in header_dict with the maximal id. this mechanism is used in order to choose header files in the build time, different build configuration use different header files. e.g. when building without AVX512 we are using the basic getters. when building with AVX512 the header that is used comes from avx512 layer. FIXME: when all avx512 will move into the base layer we can removed this mechanism and use C defines. """ _msg("HEADER DICT: %s" % header_dict) xeddir = os.path.abspath(agi.common.options.xeddir) gendir = mbuild.join(agi.common.options.gendir, 'include-private') if header_dict: header = max(header_dict, key=header_dict.get) header = os.path.normcase(header) header_basename = os.path.basename(header) _msg("HEADER: %s" % header) if os.path.exists(header): _msg("HEADER EXISTS: %s" % header) else: _msg("BADNESS - HEADER DOES NOT EXIST: %s" % header) try: shutil.copyfile(header, os.path.join(gendir, header_basename)) except: ildutil.ild_err("Failed to copyfile src=%s dst=%s" % (header, os.path.join(gendir, header_basename))) else: header_basename = None h_file = codegen.xed_file_emitter_t(xeddir, gendir, fname, shell_file=False, is_private=True) if header_basename: h_file.add_header(header_basename) h_file.start() h_file.close()
def work(agi, united_lookup, easz_nts, ild_gendir, debug): #dump lookup tables for each NT #just for debugging nt_arrays = [] for nt_name in easz_nts: array = ild_nt.gen_nt_lookup(agi, nt_name, 'EASZ') if not array: return nt_arrays.append(array) ild_nt.dump_lu_arrays(agi, nt_arrays, 'ild_easz_debug.txt', 'ild_easz_debug_header.txt') all_easz_seq = get_all_easz_seq(united_lookup) debug.write('EASZ SEQS: %s\n' % all_easz_seq) nt_seq_arrays = {} for nt_seq in all_easz_seq: array = ild_nt.gen_nt_seq_lookup(agi, nt_seq, _easz_token) if not array: return nt_seq_arrays[tuple(nt_seq)] = array #init function calls all single init functions for the created tables nt_seq_values = [v for (k,v) in sorted(nt_seq_arrays.items())] init_f = ild_nt.gen_init_function(nt_seq_values, 'xed_ild_easz_init') ild_nt.dump_lu_arrays(agi, nt_seq_values, _easz_c_fn, mbuild.join('include-private', _easz_header_fn), init_f) getter_fos = [] for names in nt_seq_arrays.keys(): arr = nt_seq_arrays[names] getter_fo = ild_codegen.gen_derived_operand_getter(agi, _easz_token, arr, list(names)) getter_fos.append(getter_fo) headers = [ildutil.ild_private_header, _easz_header_fn, operand_storage.get_operand_accessors_fn()] ild_codegen.dump_flist_2_header(agi, 'xed-ild-easz-getters.h', headers, getter_fos) #getter_lookup = gen_getter_fn_lookup(agi, united_lookup, nt_seq_arrays) return nt_seq_arrays
def dump_lookup(agi, l1_lookup, name_pfx, lu_h_fn, headers, lu_elem_type, define_dict=None, all_zero_by_map=None, output_dir='include-private'): """Dump the lookup tables - from opcode value to the L1 function pointers (in most cases they are L2 function pointers, which doesn't matter, because they have the same signature) @param l1_lookup: 2D dict so that l1_lookup[string(insn_map)][string(opcode)] == string(L1_function_name) all 0..255 opcode values should be set in the dict, so that if 0x0,0x0F map-opcode is illegal, then l1_lookup['0x0']['0x0F'] should be set to some string indicating that L1 function is undefined. all_zero_by_map is an optional dict[map] -> {True,False}. If True skip emitting the map. return a dictionary of the array names generated. """ if output_dir: ofn = mbuild.join(output_dir,lu_h_fn) else: ofn = lu_h_fn h_file = agi.open_file(ofn, start=False) for header in headers: h_file.add_header(header) h_file.start() if define_dict: print_defines(h_file, define_dict) array_names = _dump_lookup_low(agi, h_file, l1_lookup, name_pfx, lu_elem_type, all_zero_by_map) h_file.close() return array_names
def __init__(self, gendir, file_name, shell_file=False, namespace=None): """gendir is the output dir. If shell_file is True, we delimit the header differently.""" self.file_name = file_name self.gendir = gendir self.namespace = namespace # True for shell-like files, False for C++ files. Determines the comment syntax self.shell_file = shell_file self.lines = [] self.full_file_name = mbuild.join(self.gendir, self.file_name) self.eol = '\n' self.closed = False self.header = False if file_emitter_t.header_file_name_pattern.search(self.file_name): self.header = True self.headers = [] self.system_headers = [] self.misc_header = []
def _gen_xed3_op_struct(agi, hfn): """ Dump xed3_oprands_struct_t definition """ xeddir = os.path.abspath(agi.common.options.xeddir) gendir = mbuild.join(agi.common.options.gendir) h_file = codegen.xed_file_emitter_t(xeddir,gendir, hfn, shell_file=False, is_private=False) h_file.add_header('xed-operand-storage.h') h_file.start() typedef_s = 'typedef struct xed3_operands_struct_s {' h_file.add_code(typedef_s) for op_name in agi.xed3_operand_names: h_file.add_code('%s %s;'% (_xed_op_type, op_name.lower())) h_file.add_code('} %s;' %_xed3_opstruct_type) h_file.close()
def dump_nt_enum_2_capture_fptr(agi, fname): """Dump mapping nt_enum -> nt_capture_fptr """ xeddir = os.path.abspath(agi.common.options.xeddir) gendir = mbuild.join(agi.common.options.gendir, 'include-private') h_file = codegen.xed_file_emitter_t(xeddir, gendir, fname, shell_file=False, is_private=True) h_file.add_header('xed-lookup-functions.h') h_file.add_header(_xed3_nt_capture_header) h_file.start() lu_name = 'xed3_nt_2_capture' xed3_capture_f_t = 'xed3_capture_function_t' fptr_typedef = 'typedef void(*%s)(%s*);' % (xed3_capture_f_t, ildutil.xed3_decoded_inst_t) fptr_typedef = 'typedef void(*%s)(xed_decoded_inst_t*);' % xed3_capture_f_t h_file.add_code(fptr_typedef) h_file.add_code(('static %s ' % xed3_capture_f_t) +\ '%s[XED_NONTERMINAL_LAST] = {' % lu_name) nonterminals = list(agi.nonterminal_dict.keys()) invalid_line = '/*XED_NONTERMINAL_INVALID*/ (%s)0,' % xed3_capture_f_t h_file.add_code(invalid_line) for nt_name in list(agi.xed3_nt_enum_val_map.values()): enum_val = 'XED_NONTERMINAL_%s' % nt_name.upper() if _skip_nt(nt_name): fn = '0' else: fn = get_xed3_nt_capture_fn(nt_name) h_file.add_code('/*%s*/ (%s)%s,' % (enum_val, xed3_capture_f_t, fn)) h_file.add_code('};') h_file.close()
def _compile_with_pin_crt_win(env): env.add_include_dir('%(pin_root)s/extras/stlport/include') env.add_include_dir('%(pin_root)s/extras') env.add_include_dir('%(pin_root)s/extras/libstdc++/include') env.add_include_dir('%(pin_root)s/extras/crt/include') env.add_include_dir('%(pin_root)s/extras/crt') env.add_include_dir('%(pin_root)s/extras/crt/include/arch-%(bionic_arch)s') env.add_include_dir('%(pin_root)s/extras/crt/include/kernel/uapi') env.add_include_dir('%(pin_root)s/extras/crt/include/kernel/uapi/asm-x86') env.add_to_var('LINKFLAGS', '/NODEFAULTLIB') env.add_to_var('LINKFLAGS', 'stlport-static.lib') env.add_to_var('LINKFLAGS', 'm-static.lib') env.add_to_var('LINKFLAGS', 'c-static.lib') env.add_to_var('LINKFLAGS', 'os-apis.lib') env.add_to_var('LINKFLAGS', 'ntdll-%(arch)s.lib') env.add_to_var('LINKFLAGS', '/IGNORE:4210') env.add_to_var('LINKFLAGS', '/IGNORE:4049') env.add_to_var('LINKFLAGS', '/LIBPATH:%(pin_crt_dir)s') env.add_to_var('LINKFLAGS', '/LIBPATH:%(pin_root)s/%(pin_arch)s/lib-ext') # for DLLs if env['shared']: env['first_lib'] = '%(pin_crt_dir)s/crtbeginS%(OBJEXT)s' # for EXEs env['first_example_lib'] = '%(pin_crt_dir)s/crtbegin%(OBJEXT)s' _add_to_flags(env, '/GR-') _add_to_flags(env, '/GS-') env['original_windows_h_path'] = mbuild.join(os.environ['WindowsSdkDir'], 'Include', 'um') env.add_define('_WINDOWS_H_PATH_="%(original_windows_h_path)s"') _add_to_flags(env, '/FIinclude/msvc_compat.h') env.add_define('TARGET_WINDOWS')
def __init__(self, type_name, prefix, values, cfn, hfn, gendir, namespace=None, stream_guard=None, add_last_element=True, cplusplus=False, proto_prefix='', extra_header=None, density='automatic', string_convert=1): """ @type type_name: string @param type_name: the name of the generated type @type prefix: string @param prefix: prepended to all enumeration names @type values: list @param values: list of L{enumer_value_t} objects @type cfn: string @param cfn: output source file name @type hfn: string @param hfn: output header file name @type gendir: string @param gendir: output directory @type namespace: string @param namespace: namespace wrapper @type stream_guard: string @param stream_guard: #ifdef test for ostream/istream functionality @type add_last_element: xed_bool_t @param add_last_element: If True (default), add a _LAST element. @type cplusplus: xed_bool_t @param cplusplus: True=>C++ or False=>C @type proto_prefix: string @param proto_prefix: default is empty string. useful for DLL export decorations @type extra_header: string or list @param extra_header: another header to include in the .H file. @type density: string @param density: density of enumerated values. Can be sparse (default) or dense. Default is automatic which use the presence or absence of preset values to determine density @type string_convert: integer @param string_convert: 1=default, generate convert routines, 0=empty stubs, -1=no-stubs or prototypes """ self.debug = False self.proto_prefix = proto_prefix self.cplusplus = cplusplus self.type_name = type_name self.prefix = prefix self.cfn = cfn self.hfn = hfn self.density = density self.string_convert = string_convert self.extra_header = extra_header self.values = self._unique(values) # list of enumer_value_t's self.can_be_dense = True self.preset_values = self._scan_for_preset_values(self.values) if self.preset_values: self.can_be_dense = \ self._scan_for_dense_zero_based_preset_values(self.values) #sys.stderr.write("Can be dense %s\n" % (str(self.can_be_dense))) #sys.stderr.write("Preset values %s\n" % (str(self.preset_values))) if self.density == 'automatic': if self.can_be_dense: self.density = 'dense' else: self.density = 'sparse' if self.preset_values and \ self.can_be_dense == False and \ self.density == 'dense': sys.stderr.write( "\nERROR(enumer.py): dense enum had some values specified preventing dense-enum generation\n\n" ) sys.exit(1) self.add_last_element = add_last_element if add_last_element: self.values.append(enumer_value_t('LAST')) (unique, duplicates) = self._partition_duplicates(self.values) # clobber the values with just the unique values self.values = unique self.duplicates = duplicates self.namespace = namespace self.stream_guard = stream_guard self.system_headers = ["string.h"] if self.cplusplus: self.system_headers.append("cassert") self.system_headers.append("string") else: self.system_headers.append('assert.h') self.convert_function_headers = [_make_str2foo(), _make_foo2str()] if self.cplusplus: self.ostream_function_headers = [ 'std::ostream& operator<<(std::ostream& o, const %s& v)', 'std::istream& operator>>(std::istream& o, %s& v)' ] self.operator_function_headers = [ '%s& operator++(%s& x, int)', '%s& operator--(%s& x, int)' ] else: self.ostream_function_headers = [] self.operator_function_headers = [] if self.cplusplus: namespace = self.namespace else: namespace = None full_header_file_name = mbuild.join(gendir, self.hfn) self.hf = codegen.file_emitter_t(gendir, self.hfn, namespace=namespace) if type(self.extra_header) == list: for hdr in self.extra_header: self.hf.add_header(hdr) elif self.extra_header: self.hf.add_header(self.extra_header) full_source_file_name = mbuild.join(gendir, self.cfn) self.cf = codegen.file_emitter_t(gendir, self.cfn, namespace=namespace) self.cf.add_header(self.hfn) for sh in self.system_headers: self.cf.add_system_header(sh) if self.cplusplus: if self.stream_guard and self.stream_guard != '': self.hf.add_misc_header("#if %s==1" % self.stream_guard) self.hf.add_misc_header("# include <iostream>") self.hf.add_misc_header("#endif") else: self.hf.add_misc_header("#include <iostream>") self.hf.start() self.cf.start()
def work(agi, united_lookup, imm_nts, ild_gendir, eosz_dict, debug): """ main entry point of the module. """ #dump lookup functions for each NT #Let's call these function Level3 functions (L3) nt_dict = {} #generate the L3 functions #Every NT, that changes IMM_WIDTH, defines a L3 function. #For example SIMM8() NT defines a L3 function that returns 1 (1 byte). #And SIMMv() NT defines a function that gets EOSZ and returns IMM_WIDTH #value depending on EOSZ. #UIMM8_1 doesn't bind IMM_WIDTH operand, it is a special case #there is nothing to generate for it. for nt_name in _filter_uimm1_nt(imm_nts): array = ild_nt.gen_nt_lookup(agi, nt_name, _imm_token, target_type=ildutil.ild_c_op_type, level='l3') nt_dict[nt_name] = array #create function that calls all initialization functions for L3 init_f = ild_nt.gen_init_function(list(nt_dict.values()), 'xed_ild_imm_l3_init') #dump L3 functions ild_nt.dump_lu_arrays(agi, list(nt_dict.values()), _l3_c_fn, mbuild.join('include-private',_l3_header_fn), init_f) #get all IMM NT sequences that are used in patterns #The only case of IMM sequence is when we have UIMM1() NT - the second #immediate NT. all_imm_seq = get_all_imm_seq(united_lookup) debug.write('IMM SEQS: %s\n' % all_imm_seq) # L2 / Level2 functions: set imm_width # Now we define functions that compute EOSZ value (using one of # the EOSZ-resolution functions) and then use # one of the L3 functions(that need EOSZ) to set IMM_WIDTH. # The names of these functions should be something like # xed_ild_SIMMz_OSZ_NONTERM_DF64 - to define the imm-binding nonterm # and to define the EOSZ-resolution NT sequence. # L2 functions are defined by single ild_info_t object - by its # eosz_nt_seq and imm_nt_seq l2_functions = ild_codegen.gen_l2_func_list(agi, nt_dict, eosz_dict, _ild_t_imm_member) #append function for imm_bytes==0 l2_functions.append(_gen_imm0_function(agi)) l2_headers = [ild_eosz.get_ntseq_header_fn(), _l3_header_fn, ildutil.ild_header, operand_storage.get_operand_accessors_fn()] ild_codegen.dump_flist_2_header(agi, _l2_header_fn, l2_headers, l2_functions) # L1 / Level1 functions: # Now we define functions that resolve conflicts (if any) # using modrm.reg bits, and that way decide which L2 function to # call to set the IMM value. # These functions will be the value of map,opcode lookup tables. # These functions should be dumped after we have a look on the # united_lookup mapping in order to know what conflicts exist and # for each conflict to create a resolution lookup table. # L1 functions are defined by a list of ild_info_t objects that # have same map,opcode. res = gen_l1_functions_and_lookup(agi, united_lookup, nt_dict) l1_functions,l1_lookup = res ild_codegen.dump_flist_2_header(agi, _l1_header_fn, [_l2_header_fn], l1_functions) headers = [_l1_header_fn, ildutil.ild_private_header, operand_storage.get_operand_accessors_fn()] ild_codegen.dump_lookup(agi, l1_lookup, _ild_t_imm_member, _imm_lu_header_fn, headers, ildutil.l1_ptr_typename)
def find_tests(env): test_dirs = [] for d in env['tests']: test_dirs.extend(mbuild.glob(mbuild.join(d, "test-[0-9][0-9]*"))) return test_dirs
def _xed_lib_dir_join(env, s): return mbuild.join(env['xed_lib_dir'], s)
def build_dir_join(env, lst): return [mbuild.join(env['build_dir'], x) for x in lst]