Beispiel #1
0
def dump_header_with_header(agi, fname, header_dict):
    """ 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 
             form 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()
Beispiel #2
0
    def dump_operand_accessors(self, agi):
        ''' Dump operand accessor to inspect the data 
            structure xed_operand_storage_t '''
        fo_list = []
        h_fname = get_operand_accessors_fn()
        c_fname = h_fname.replace('.h', '.c')

        for opname in self.operand_fields.keys():
            getter_fo = self._gen_op_getter_fo(opname)
            setter_fo = self._gen_op_setter_fo(opname)
            fo_list.append(getter_fo)
            fo_list.append(setter_fo)

        # generate a generic getter
        generic_getter = self._gen_generic_getter()
        generic_setter = self._gen_generic_setter()
        xeddir = os.path.abspath(agi.common.options.xeddir)
        gendir = agi.common.options.gendir

        h_file = codegen.xed_file_emitter_t(xeddir,
                                            gendir,
                                            h_fname,
                                            shell_file=False,
                                            is_private=False)

        h_file.add_header(['xed-decoded-inst.h', 'xed-operand-storage.h'])
        h_file.start()

        for fo in fo_list:
            decl = fo.emit_header()
            h_file.add_code(decl)
        h_file.add_code(generic_getter.emit_header())
        h_file.add_code(generic_setter.emit_header())

        for fo in fo_list:
            fo.emit_file_emitter(h_file)

        h_file.close()

        c_file = codegen.file_emitter_t(gendir, c_fname, shell_file=False)
        c_file.add_header(h_fname)
        c_file.start()
        generic_getter.emit_file_emitter(c_file)
        generic_setter.emit_file_emitter(c_file)
        c_file.close()
Beispiel #3
0
def write_table(agi,ots):
   """Emit the xtypes enum and write the initialization table"""
   
   fp = codegen.xed_file_emitter_t(agi.common.options.xeddir,
                                   agi.common.options.gendir,
                                   'xed-init-operand-type-mappings.c')
   fp.start()
   fp.add_code("const xed_operand_type_info_t xed_operand_xtype_info[] = {")
   names = list(ots.keys())
   names.sort()
   names = ['INVALID'] + names
   ots['INVALID'] = operand_type_t('INVALID','INVALID','0')
   for n in names:
      v = ots[n]
      s = '/* %s */ { XED_OPERAND_ELEMENT_TYPE_%s, %s },' % (n, v.dtype, v.bits_per_element)
      fp.add_code(s)
   fp.add_code_eol("}")
   fp.close()
   return fp.full_file_name
Beispiel #4
0
 def __init__(self,
              lines,
              xeddir,
              gendir,
              base_name,
              type_name,
              prefix,
              namespace='XED',
              stream_ifdef='XED_PRINT',
              cplusplus=True,
              proto_prefix='XED_DLL_EXPORT',
              extra_header="xed-common-hdrs.h",
              upper_case=True,
              density='automatic',
              string_convert=True):
     self.cplusplus = cplusplus
     self.lines = lines
     self.tuples = None  # list  [enumer.enumer_value_t] objects
     self.gendir = gendir
     self.xeddir = xeddir
     self.base_name = base_name
     self.type_name = type_name
     self.prefix = prefix
     self.proto_prefix = proto_prefix
     self.extra_header = extra_header  # could be a list
     self.upper_case = upper_case
     self.density = density
     self.string_convert = string_convert
     self.file_emitter = \
         codegen.xed_file_emitter_t(xeddir,
                                    gendir,
                                    self.base_name +'-enum.txt',
                                    shell_file=True)
     self.base_fn = self.base_name + '-enum'
     if self.cplusplus:
         self.cfn = self.base_fn + '.cpp'
         self.hfn = self.base_fn + '.H'
     else:
         self.cfn = self.base_fn + '.c'
         self.hfn = self.base_fn + '.h'
     self.namespace = namespace
     self.stream_ifdef = stream_ifdef
Beispiel #5
0
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()
Beispiel #6
0
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()
Beispiel #7
0
def work(lines,   xeddir = '.',   gendir = 'obj'):
   tables = []
   while lines:
       y = constant_table_t()
       y.read(lines)
       #y.dump()
       olines = y.emit_init()
       #for l in olines:
       #    print l
       tables.append(y)
       
   tables=filter(lambda(x): x.valid() , tables)
   names=map(lambda(x): x.name , tables)

   srcs = emit_convert_enum(['INVALID'] + names, xeddir, gendir)
   src_file_name = 'xed-convert-table-init.c'
   hdr_file_name = 'xed-convert-table-init.h'
   xfe = codegen.xed_file_emitter_t(xeddir, gendir, src_file_name)
   xfe.add_header(hdr_file_name)
   xfe.start()

   hfe = codegen.xed_file_emitter_t(xeddir,
                                    gendir,
                                    hdr_file_name)
   hfe.start()

   xfe.add_code('xed_convert_table_t xed_convert_table[XED_OPERAND_CONVERT_LAST];')
   
   for t in tables:
       l = t.emit_init()
       l = map(lambda(x): x+'\n', l)
       xfe.writelines(l)
   fo = codegen.function_object_t('xed_init_convert_tables', 'void')
   
   s1 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].table_name = %s;' % ('INVALID', '0')
   s2 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].limit      = %s;' % ('INVALID', '0')
   s3 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].opnd       = %s;' % ('INVALID', 'XED_OPERAND_INVALID')
   fo.add_code(s1)
   fo.add_code(s2)
   fo.add_code(s3)
   
   for t in tables:
       s1 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].table_name = %s;' % (t.name, t.string_table_name)
       s2 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].limit      = %s;' % (t.name, len(t.value_string_pairs))
       s3 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].opnd       = %s;' % (t.name, t.operand)
       fo.add_code(s1)
       fo.add_code(s2)
       fo.add_code(s3)

   fo.emit_file_emitter(xfe)
   xfe.close()

   hdr = []
   hdr.append("typedef struct {\n")
   hdr.append("   const char** table_name;\n")
   hdr.append("   xed_operand_enum_t opnd;\n") # which operand indexes the table!
   hdr.append("   unsigned int limit;\n")
   hdr.append("} xed_convert_table_t;")
   hdr.append("extern xed_convert_table_t xed_convert_table[XED_OPERAND_CONVERT_LAST];")
   hfe.writelines(map(lambda(x): x+'\n', hdr))
   hfe.close()

   srcs.append(hfe.full_file_name)
   srcs.append(xfe.full_file_name)
   return srcs
Beispiel #8
0
def work(arg):
    (chips, chip_features_dict) = read_database(arg.input_file_name)

    isa_set_per_chip_fn = dump_chip_hierarchy(arg, chips, chip_features_dict)
    # the XED_CHIP_ enum
    chips.append("ALL")
    chip_enum = enum_txt_writer.enum_info_t(['INVALID'] + chips,
                                            arg.xeddir,
                                            arg.gendir,
                                            'xed-chip',
                                            'xed_chip_enum_t',
                                            'XED_CHIP_',
                                            cplusplus=False)
    chip_enum.print_enum()
    chip_enum.run_enumer()

    # Add the "ALL" chip

    # the XED_ISA_SET_ enum
    isa_set = set()
    for vl in chip_features_dict.values():
        for v in vl:
            isa_set.add(v.upper())
    isa_set = list(isa_set)
    isa_set.sort()

    chip_features_dict['ALL'] = isa_set

    isa_set = ['INVALID'] + isa_set
    isa_set_enum = enum_txt_writer.enum_info_t(isa_set,
                                               arg.xeddir,
                                               arg.gendir,
                                               'xed-isa-set',
                                               'xed_isa_set_enum_t',
                                               'XED_ISA_SET_',
                                               cplusplus=False)
    isa_set_enum.print_enum()
    isa_set_enum.run_enumer()

    # the initialization file and header
    chip_features_cfn = 'xed-chip-features-table.c'
    chip_features_hfn = 'xed-chip-features-table.h'
    cfe = codegen.xed_file_emitter_t(arg.xeddir,
                                     arg.gendir,
                                     chip_features_cfn,
                                     shell_file=False)
    private_gendir = os.path.join(arg.gendir, 'include-private')
    hfe = codegen.xed_file_emitter_t(arg.xeddir,
                                     private_gendir,
                                     chip_features_hfn,
                                     shell_file=False)
    for header in ['xed-isa-set-enum.h', 'xed-chip-enum.h']:
        cfe.add_header(header)
        hfe.add_header(header)
    cfe.start()
    hfe.start()

    cfe.write("xed_uint64_t xed_chip_features[XED_CHIP_LAST][4];\n")
    hfe.write("extern xed_uint64_t xed_chip_features[XED_CHIP_LAST][4];\n")

    fo = codegen.function_object_t('xed_init_chip_model_info', 'void')
    fo.add_code_eol("const xed_uint64_t one=1")
    # make a set for each machine name
    spacing = "\n      |"
    for c in chips:
        s0 = ['0']
        s1 = ['0']
        s2 = ['0']
        s3 = ['0']
        # loop over the features
        for f in chip_features_dict[c]:
            feature_index = _feature_index(isa_set, f)

            if feature_index < 64:
                s0.append('(one<<XED_ISA_SET_%s)' % (f))
            elif feature_index < 128:
                s1.append('(one<<(XED_ISA_SET_%s-64))' % (f))
            elif feature_index < 192:
                s2.append('(one<<(XED_ISA_SET_%s-128))' % (f))
            elif feature_index < 256:
                s3.append('(one<<(XED_ISA_SET_%s-192))' % (f))
            else:
                _die("Feature index > 256. Need anotehr features array")

        s0s = spacing.join(s0)
        s1s = spacing.join(s1)
        s2s = spacing.join(s2)
        s3s = spacing.join(s3)

        for i, x in enumerate([s0s, s1s, s2s, s3s]):
            fo.add_code_eol("xed_chip_features[XED_CHIP_{}][{}] = {}".format(
                c, i, x))

    cfe.write(fo.emit())
    cfe.close()
    hfe.write(fo.emit_header())
    hfe.close()

    return ([
        isa_set_per_chip_fn, chip_enum.hdr_full_file_name,
        chip_enum.src_full_file_name, isa_set_enum.hdr_full_file_name,
        isa_set_enum.src_full_file_name, hfe.full_file_name, cfe.full_file_name
    ], chips, isa_set)
Beispiel #9
0
def _dump_capture_chain_fo_lu(agi, patterns):
    """
    Creates chain capturing functions - for each pattern,
    dumps those functions definitions, dumps a mapping
    from inum(xed_inst_t index) to those functions.
    """
    fn_2_fo = {}
    inum_2_fn = {}

    nop_fo = _gen_empty_capture_fo()
    fn_2_fo[nop_fo.function_name] = nop_fo
    for ptrn in patterns:
        ii = ptrn.ii
        nt_names = _get_nt_names_from_ii(ii)
        if len(nt_names) == 0:
            #if no NTs we use empty capturing function
            fn = nop_fo.function_name
        else:
            fn = _get_xed3_capture_chain_fn(nt_names)
        if fn not in fn_2_fo:
            fo = _gen_capture_chain_fo(nt_names)
            fn_2_fo[fn] = fo
        inum_2_fn[ii.inum] = (fn, ptrn.ptrn)

    #dump chain functions
    headers = [_xed3_nt_capture_header]
    ild_codegen.dump_flist_2_header(agi,
                                    _xed3_chain_header,
                                    headers,
                                    list(fn_2_fo.values()),
                                    is_private=True)

    lu_size = max(inum_2_fn.keys()) + 1

    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,
                                        _xed3_chain_lu_header,
                                        shell_file=False,
                                        is_private=True)
    h_file.add_header(_xed3_chain_header)
    h_file.start()
    lu_name = 'xed3_chain_fptr_lu'
    xed3_chain_f_t = 'xed3_chain_function_t'

    fptr_typedef = 'typedef %s(*%s)(%s*);' % (
        _xed3_chain_return_t, xed3_chain_f_t, ildutil.xed3_decoded_inst_t)

    h_file.add_code(fptr_typedef)

    h_file.add_code('static {} {}[{}] = {{'.format(xed3_chain_f_t, lu_name,
                                                   lu_size))

    empty_line = '/*NO PATTERN*/ (%s)0,' % xed3_chain_f_t

    for inum in range(0, lu_size):
        if inum in inum_2_fn:
            (fn, ptrn_str) = inum_2_fn[inum]
            entry_str = '/*\n%s\ninum=%s*/ %s,' % (ptrn_str, inum, fn)
        else:
            entry_str = empty_line
        h_file.add_code(entry_str)
    h_file.add_code('};')
    h_file.close()
Beispiel #10
0
def emit_map_info_tables(agi):
    '''variable modrm,disp,imm tables, per encoding space using natural
       map ids. returns list of files generated'''
    map_features_cfn = 'xed-map-feature-tables.c'
    map_features_hfn = 'xed-map-feature-tables.h'
    private_gendir = os.path.join(agi.common.options.gendir, 'include-private')
    hfe = codegen.xed_file_emitter_t(agi.common.options.xeddir, private_gendir,
                                     map_features_hfn)

    for h in ['xed-map-info.h']:
        hfe.add_header(h)
    hfe.start()

    sorted_list = sorted(agi.map_info, key=lambda x: x.map_name)

    spaces = list(set([mi.space for mi in sorted_list]))
    sorted_spaces = sorted(spaces, key=lambda x: encoding_space_to_vexvalid(x))
    max_space_id = _encoding_space_max()  # legacy,vex,evex,xop,knc
    #max_space_id = encoding_space_to_vexvalid(sorted_spaces[-1])

    max_map_id = max([mi.map_id for mi in agi.map_info])  #0...31

    fields = ['modrm', 'disp', 'imm']

    cvt_yes_no_var = {'yes': 1, 'no': 0, 'var': 2}
    cvt_imm = {'0': 0, '1': 1, '2': 2, '4': 4, 'var': 7}

    field_to_cvt = {
        'modrm': cvt_yes_no_var,
        'disp': cvt_yes_no_var,
        'imm': cvt_imm
    }

    bits_per_chunk = 64

    # The field width in bits must be a power of 2 for current design,
    # otherwise the bits of interest can span the 64b chunks we are
    # using to store the values.
    field_to_bits = {'modrm': 2, 'disp': 2, 'imm': 4}

    def collect_codes(field, space_maps):
        '''cvt is dict converting strings to integers. the codes are indexed by map id.'''
        cvt = field_to_cvt[field]
        codes = {key: 0 for key in range(0, max_map_id + 1)}

        for mi in space_maps:
            codes[mi.map_id] = cvt[getattr(mi, field)]

        codes_as_list = [codes[i] for i in range(0, max_map_id + 1)]
        return codes_as_list

    def convert_list_to_integer(lst, bits_per_field):
        '''return an integer or a list of integer if more than 64b'''
        integers = []
        tot = 0
        shift = 0
        for v in lst:
            if shift >= 64:
                integers.append(tot)
                tot = 0
                shift = 0
            tot = tot + (v << shift)
            shift = shift + bits_per_field
        integers.append(tot)

        if len(integers) == 1:
            return integers[0]
        return integers

    for space_id in _encoding_space_range():

        space = _space_id_to_name[space_id]
        space_maps = [mi for mi in sorted_list if mi.space == space]

        for field in fields:
            bits_per_field = field_to_bits[field]
            total_bits = max_map_id * bits_per_field
            required_chunks = math.ceil(total_bits / bits_per_chunk)
            values_per_chunk = bits_per_chunk // bits_per_field
            ilog2_values_per_chunk = int(math.log2(values_per_chunk))
            mask = (1 << bits_per_field) - 1

            f = codegen.function_object_t('xed_ild_has_{}_{}'.format(
                field, space),
                                          'xed_bool_t',
                                          static=True,
                                          inline=True)
            f.add_arg('xed_uint_t m')
            if space_maps:
                codes = collect_codes(field, space_maps)
                constant = convert_list_to_integer(codes, bits_per_field)
            else:
                codes = [0]
                constant = 0
            f.add_code('/* {} */'.format(codes))
            if set(codes) == {0}:  # all zero values...
                f.add_code_eol('return 0')
                f.add_code_eol('(void)m')
            else:
                if required_chunks <= 1:
                    f.add_code_eol(
                        'const xed_uint64_t data_const = 0x{:x}ULL'.format(
                            constant))
                    f.add_code_eol(
                        'return (xed_bool_t)((data_const >> ({}*m)) & {})'.
                        format(bits_per_field, mask))
                else:
                    f.add_code('const xed_uint64_t data_const[{}] = {{'.format(
                        required_chunks))
                    ln = ['0x{:x}ULL'.format(c) for c in constant]
                    f.add_code_eol(' {} }}'.format(", ".join(ln)))

                    f.add_code_eol(
                        'const xed_uint64_t chunkno = m >> {}'.format(
                            ilog2_values_per_chunk))
                    f.add_code_eol(
                        'const xed_uint64_t offset = m & ({}-1)'.format(
                            values_per_chunk))
                    f.add_code_eol(
                        'return (xed_bool_t)((data_const[chunkno] >> ({}*offset)) & {})'
                        .format(bits_per_field, mask))

            hfe.write(f.emit())  # emit the inline function in the header

    # emit a function that covers all spaces
    for field in fields:
        bits_per_field = field_to_bits[field]
        total_bits = max_map_id * bits_per_field
        required_chunks = math.ceil(total_bits / bits_per_chunk)
        values_per_chunk = bits_per_chunk // bits_per_field
        ilog2_values_per_chunk = int(math.log2(values_per_chunk))
        mask = (1 << bits_per_field) - 1

        f = codegen.function_object_t('xed_ild_has_{}'.format(field),
                                      'xed_bool_t',
                                      static=True,
                                      inline=True)
        f.add_arg('xed_uint_t vv')
        f.add_arg('xed_uint_t m')
        if required_chunks <= 1:
            f.add_code(
                'const xed_uint64_t data_const[{}] = {{'.format(max_space_id +
                                                                1))
        else:
            f.add_code('const xed_uint64_t data_const[{}][{}] = {{'.format(
                max_space_id + 1, required_chunks))

        for space_id in _encoding_space_range():
            space = _space_id_to_name[space_id]
            space_maps = [mi for mi in sorted_list if mi.space == space]
            if space_maps:
                codes = collect_codes(field, space_maps)
                constant = convert_list_to_integer(codes, bits_per_field)
            else:
                codes = [0] * required_chunks
                if required_chunks <= 1:
                    constant = 0
                else:
                    constant = [0] * required_chunks

            f.add_code('/* {} {} */'.format(codes, space))
            if required_chunks <= 1:
                f.add_code(' 0x{:x}ULL,'.format(constant))
            else:
                ln = ['0x{:x}ULL'.format(c) for c in constant]
                f.add_code('{{ {} }},'.format(", ".join(ln)))

        f.add_code_eol('}')
        f.add_code_eol('xed_assert(vv < {})'.format(max_space_id + 1))
        if required_chunks <= 1:
            f.add_code_eol(
                'return (xed_bool_t)((data_const[vv] >> ({}*m)) & {})'.format(
                    bits_per_field, mask))
        else:
            f.add_code_eol('const xed_uint64_t chunkno = m >> {}'.format(
                ilog2_values_per_chunk))
            f.add_code_eol('const xed_uint64_t offset = m & ({}-1)'.format(
                values_per_chunk))
            f.add_code_eol(
                'return (xed_bool_t)((data_const[vv][chunkno] >> ({}*offset)) & {})'
                .format(bits_per_field, mask))

        hfe.write(f.emit())  # emit the inline function in the header

    # emit a set of functions for determining the valid maps in each encoding space
    if max_map_id > 64:
        genutil.die("Need to make this work with multiple chunks of u64")
    for space_id in _encoding_space_range():
        space = _space_id_to_name[space_id]

        space_maps = [mi for mi in sorted_list if mi.space == space]
        f = codegen.function_object_t('xed_ild_map_valid_{}'.format(space),
                                      'xed_bool_t',
                                      static=True,
                                      inline=True)
        f.add_arg('xed_uint_t m')
        max_id = _encoding_space_max()
        #max_id = max( [mi.map_id for mi in space_maps ] )
        codes_dict = {key: 0 for key in range(0, max_map_id + 1)}
        for mi in space_maps:
            codes_dict[mi.map_id] = 1
        codes = [codes_dict[i] for i in range(0, max_map_id + 1)]

        f.add_code('/* {} */'.format(codes))
        constant = convert_list_to_integer(codes, 1)
        f.add_code_eol(
            'const xed_uint64_t data_const = 0x{:x}ULL'.format(constant))
        # no need for a max-map test since, the upper bits of the
        # constant will be zero already
        f.add_code_eol('return (xed_bool_t)((data_const >> m) & 1)')
        hfe.write(f.emit())  # emit the inline function in the header

    # emit a table filling in "xed_map_info_t xed_legacy_maps[] = { ... }"

    legacy_maps = [mi for mi in sorted_list if mi.space == 'legacy']
    legacy_maps = sorted(legacy_maps,
                         key=lambda x: -len(x.search_pattern) * 10 + x.map_id)

    hfe.add_code('const xed_map_info_t xed_legacy_maps[] = {')
    for mi in legacy_maps:
        if mi.map_id == 0:
            continue
        has_legacy_opcode = 1 if mi.legacy_opcode != 'N/A' else 0
        legacy_opcode = mi.legacy_opcode if mi.legacy_opcode != 'N/A' else 0
        legacy_escape = mi.legacy_escape if mi.legacy_escape != 'N/A' else 0

        hfe.add_code('{{ {}, {}, {}, {}, {} }},'.format(
            legacy_escape, has_legacy_opcode, legacy_opcode, mi.map_id,
            mi.opcpos))
    hfe.add_code_eol('}')

    hfe.close()
    return [hfe.full_file_name]