int main(int argc, char** argv) {
    xed_machine_mode_enum_t mmode;
    xed_bool_t long_mode = 1;
    xed_ild_t ild;
    xed_uint_t length = 0;
    xed_uint_t i;
#define NTIMES 100
    xed_uint64_t t1,t2,delta[NTIMES],tot;    
    unsigned char itext[15] = { 0xf2, 0x2e, 0x4f, 0x0F, 0x85, 0x99,
                                0x00, 0x00, 0x00 };

    // initialize the XED tables -- one time.
    xed_tables_init();

    // The state of the machine -- required for decoding
    if (long_mode) {
        mmode=XED_MACHINE_MODE_LONG_64;
    }
    else {
        mmode=XED_MACHINE_MODE_LEGACY_32;
    }

    for(i=0;i<NTIMES;i++) {
        t1 = xed_get_time();
        xed_ild_init(&ild, mmode, XED_CHIP_INVALID, itext, 15);
        length = xed_instruction_length_decode(&ild);
        t2 = xed_get_time();
        delta[i] = t2-t1;
    }

    tot = 0;
    for(i=0;i<NTIMES;i++) {
        printf("Decode time[%3d] = " XED_FMT_LU "\n", i,delta[i]);
        if (i>0)
            tot += delta[i];
    }
    printf("Avg time = " XED_FMT_LU "\n", tot/(NTIMES-1));
    
    print_ild(&ild);
    printf("length = %d\n",length);

    return 0;
    (void) argc; (void) argv; //pacify compiler

}
int main(int argc, char** argv) {
    xed_ild_t ild;
    xed_uint_t uargc = (xed_uint_t)argc;
    xed_uint_t length = 0;
    xed_uint_t dlen = 0;    
    xed_uint_t i,j,input_nibbles=0;
    xed_uint8_t itext[XED_MAX_INSTRUCTION_BYTES];
    char src[MAX_INPUT_NIBBLES+1];
    xed_state_t dstate;
    xed_decoded_inst_t xedd;
    xed_uint_t first_argv;
    xed_uint_t bytes;
    xed_error_enum_t xed_error;
    xed_chip_enum_t chip = XED_CHIP_INVALID;
    int already_set_mode = 0;
    
    // initialize the XED tables -- one time.
    xed_tables_init();

    xed_state_zero(&dstate);

    first_argv = 1;
    dstate.mmode=XED_MACHINE_MODE_LEGACY_32;
    dstate.stack_addr_width=XED_ADDRESS_WIDTH_32b;

    for(i=1;i< uargc;i++) {
        if (strcmp(argv[i], "-64") == 0) {
            assert(already_set_mode == 0);
            already_set_mode = 1;
            dstate.mmode=XED_MACHINE_MODE_LONG_64;
            first_argv++;
        }
        else if (strcmp(argv[i], "-16") == 0) {
            assert(already_set_mode == 0);
            already_set_mode = 1;
            dstate.mmode=XED_MACHINE_MODE_LEGACY_16;
            dstate.stack_addr_width=XED_ADDRESS_WIDTH_16b;
            first_argv++;
        }
        else if (strcmp(argv[i], "-s16") == 0) {
            already_set_mode = 1;
            dstate.stack_addr_width=XED_ADDRESS_WIDTH_16b;
            first_argv++;
        }
        else if (strcmp(argv[i], "-chip") == 0) {
            assert(i+1 < uargc);
            chip = str2xed_chip_enum_t(argv[i+1]);
            printf("Setting chip to %s\n", xed_chip_enum_t2str(chip));
            assert(chip != XED_CHIP_INVALID);
            first_argv+=2;
        }

    }

    assert(first_argv < uargc);

    xed_decoded_inst_zero_set_mode(&xedd, &dstate);

    if (first_argv >= uargc) {
      printf("Need some hex instruction nibbles");
      exit(1);
    }
    
    for(i=first_argv;i<uargc;i++) { 
      for(j=0;argv[i][j];j++) {
        assert(input_nibbles < MAX_INPUT_NIBBLES);
        src[input_nibbles] = argv[i][j];
        input_nibbles++;
      }
    }
    src[input_nibbles] = 0;
    if (input_nibbles & 1) {
      printf("Need an even number of nibbles");
      exit(1);
    }

    bytes = xed_convert_ascii_to_hex(src, itext, XED_MAX_INSTRUCTION_BYTES);
                            
    printf("Attempting to decode: ");
    for(i=0;i<bytes;i++) {
      printf("%02x", itext[i]);
    }
    printf("\n");

    xed_ild_init(&ild, dstate.mmode, chip, itext, XED_MAX_INSTRUCTION_BYTES);
    length = xed_instruction_length_decode(&ild);
    print_ild(&ild);
    printf("ILD length = %d\n",length);


    xed_decoded_inst_set_input_chip(&xedd, chip);
    xed_error = xed_decode(&xedd, 
                           XED_REINTERPRET_CAST(const xed_uint8_t*,itext), 
                           bytes);

    switch(xed_error)    {
      case XED_ERROR_NONE:
        break;
      case XED_ERROR_BUFFER_TOO_SHORT:
        printf("Not enough bytes provided\n");
        exit(1);
      case XED_ERROR_INVALID_FOR_CHIP:
        printf("The instruction was not valid for the specified chip.\n");
        exit(1);
      case XED_ERROR_GENERAL_ERROR:
        printf("Could not decode given input.\n");
        exit(1);
      default:
        printf("Unhandled error code %s\n",xed_error_enum_t2str(xed_error));
        exit(1);
    }
        
    dlen =  xed_decoded_inst_get_length(&xedd);
    printf ("Traditional length =  %d\n", dlen);
    if (dlen != length) {
      printf ("Length error\n");
      exit(1);
    }
    printf ("Length matched\n");
    return 0;
}
void xed_disas_test(xed_disas_info_t di) {

    static int first = 1;
#if !defined(XED_ILD_ONLY)
    xed_uint64_t errors = 0;
#endif
    unsigned int m;
    unsigned char* z;
    unsigned char* zlimit;
    unsigned int length;
    
    int skipping;
    int last_all_zeros;
    unsigned int i;

    int okay;

//for ILD comparing perf measurements
#if defined(XED_ILD_ONLY) && defined(XED_ILD)
#include "xed-ild.h"
    xed_ild_t ild_data = {0}; 
#endif

    //For XED_ILD_ONLY we want to run only ILD decoding to get 
    //better timing precision. That means, that we don't run xed_decode
    //and don't use xedd at all
#if !defined(XED_ILD_ONLY)
    xed_decoded_inst_t xedd;
#endif

    xed_uint64_t runtime_instruction_address;

    xed_dot_graph_supp_t* gs = 0;
    xed_bool_t graph_empty = 1;
    
//#define     XED_USE_DECODE_CACHE
#if defined(XED_USE_DECODE_CACHE)
    xed_decode_cache_t cache;
    xed_uint32_t n_cache_entries = 16*1024;
    xed_decode_cache_entry_t* cache_entries = 
        (xed_decode_cache_entry_t*) malloc(n_cache_entries * 
                                           sizeof(xed_decode_cache_entry_t));
    xed_decode_cache_initialize(&cache, cache_entries, n_cache_entries);
#endif


    if (di.dot_graph_output) {
        xed_syntax_enum_t syntax = XED_SYNTAX_INTEL;
        gs = xed_dot_graph_supp_create(syntax);
    }

    if (first) {
        xed_decode_stats_zero(&xed_stats, &di);

#if defined(XED_ILD_ONLY) && defined(XED_ILD) //for ILD comparing
        xed_decode_stats_zero(&ild_stats, &di);
#endif
        first = 0;
    }

    m = di.ninst; // number of things to decode
    z = di.a;
  
    if (di.runtime_vaddr_disas_start) 
        if (di.runtime_vaddr_disas_start > di.runtime_vaddr)
            z = (di.runtime_vaddr_disas_start - di.runtime_vaddr) + di.a;

    zlimit = 0;
    if (di.runtime_vaddr_disas_end) {
        if (di.runtime_vaddr_disas_end > di.runtime_vaddr)
            zlimit = (di.runtime_vaddr_disas_end - di.runtime_vaddr) + di.a;
        else  /* end address is before start of this region -- skip it */
            goto finish;
    } 


    if (z >= di.q)   /* start pointer  is after end of section */
        goto finish;

    // for skipping long strings of zeros
    skipping = 0;
    last_all_zeros = 0;
    for( i=0; i<m;i++) 
    {
        int ilim,elim;
        if (zlimit && z >= zlimit) {
            if (di.xml_format == 0)
                printf("# end of range.\n");
            break;
        }
        if (z >= di.q) {
            if (di.xml_format == 0)
#if !defined(XED_ILD_ONLY)
                printf("# end of text section.\n");
#endif
            break;
        }

        /* if we get near the end of the section, clip the itext length */
        ilim = 15;
        elim = di.q - z;
        if (elim < ilim) 
           ilim = elim;

        if (CLIENT_VERBOSE3) {
            printf("\n==============================================\n");
            printf("Decoding instruction " XED_FMT_U "\n", i);
            printf("==============================================\n");
        }
    
        // if we get two full things of 0's in a row, start skipping.
        if (all_zeros((xed_uint8_t*) z, ilim)) 
        {
            if (skipping) {
                z = z + ilim;
                continue;
            }
            else if (last_all_zeros) { 
#if !defined(XED_ILD_ONLY)
                printf("...\n");
#endif
                z = z + ilim;
                skipping = 1;
                continue;
            }
            else
                last_all_zeros = 1;
        }
        else
        {
            skipping = 0;
            last_all_zeros = 0;
        }

        runtime_instruction_address =  ((xed_uint64_t)(z-di.a)) + 
                                       di.runtime_vaddr;
         
        if (CLIENT_VERBOSE3) {
            char tbuf[XED_HEX_BUFLEN];
            printf("Runtime Address " XED_FMT_LX ,runtime_instruction_address);
            xed_print_hex_line(tbuf, (xed_uint8_t*) z, ilim,XED_HEX_BUFLEN);
            printf(" [%s]\n", tbuf);
        }
        okay = 0;
        length = 0;

        //For XED_ILD_ONLY we want to run only ILD decoding to get 
        //better timing precision. That means, that we don't run xed_decode
        //and won't use xedd at all
#if !defined(XED_ILD_ONLY)
        xed_decoded_inst_zero_set_mode(&xedd, di.dstate);
        if (di.late_init) 
            (*di.late_init)(&xedd);
#endif
        
        if ( di.decode_only )
        {
            xed_uint64_t t1;
            xed_uint64_t t2;
            xed_error_enum_t xed_error = XED_ERROR_NONE;
#if !defined(XED_ILD_ONLY)
            t1 = xed_get_time();
            
            
    #if defined(XED_USE_DECODE_CACHE)
            xed_error = xed_decode_cache(&xedd, 
                                    XED_REINTERPRET_CAST(const xed_uint8_t*,z),
                                    ilim, 
                                    &cache);
    #else
            xed_error = xed_decode(&xedd, 
                                   XED_REINTERPRET_CAST(const xed_uint8_t*,z),
                                   ilim);
    #endif
            t2 = xed_get_time();
            okay = (xed_error == XED_ERROR_NONE);
            xed_decode_stats_reset(&xed_stats, t1, t2);
            length = xed_decoded_inst_get_length(&xedd);

#else //defined(XED_ILD_ONLY)
            
            xed_machine_mode_enum_t mmode;
            const xed_uint8_t* itext = z;

            okay = 1;
            mmode = xed_state_get_machine_mode(di.dstate);
            
            xed_ild_init(&ild_data, mmode,
                         xed_decoded_inst_get_input_chip(&xedd),
                         itext, ILD_ITEXT_MAX_BYTES);
            
            t1 = xed_get_time();
            xed_instruction_length_decode(&ild_data);
            t2 = xed_get_time();

            xed_decode_stats_reset(&ild_stats, t1, t2);
            length = ild_data.length;
#endif //defined(XED_ILD_ONLY)

            if (okay && length == 0) {
                printf("Zero length on decoded instruction!\n");
                xed_decode_error( runtime_instruction_address, 
                                  z-di.a, z, xed_error);
                xedex_derror("Dieing");
            }

            if (di.resync && di.symfn) {
                xed_bool_t resync = 0;
                unsigned int x;
                for(x=1;x<length;x++) {

                    char* name = (*di.symfn)(runtime_instruction_address+x, 
                                             di.caller_symbol_data);
                    if (name) {
                        char buf[XED_HEX_BUFLEN];
                        /* bad news. We found a symbol in the middle of an
                         * instruction. That probably means decoding is
                         * messed up.  This usually happens because of
                         * data-in the code/text section.  We should reject
                         * the current instruction and pick up at the
                         * symbol address. */
                        printf("ERROR: found symbol in the middle of"
                               " an instruction. Resynchronizing...\n");
                        printf("ERROR: Rejecting: [");
                        xed_print_hex_line(buf, z, x, XED_HEX_BUFLEN);
                        printf("%s]\n",buf);

                        z += x;
                        resync = 1;
                        break;
                    }
                }
                if (resync)
                    continue;
            }

            xed_stats.total_ilen += length;

//we don't want to print out disassembly with ILD perf
#if !defined(XED_ILD_ONLY) 

            if (okay)  {
                if (CLIENT_VERBOSE1) {
                    char tbuf[XED_TMP_BUF_LEN];
                    xed_decoded_inst_dump(&xedd,tbuf, XED_TMP_BUF_LEN);
                    printf("%s\n",tbuf);
                }
                if (CLIENT_VERBOSE)  {
                    char buffer[XED_TMP_BUF_LEN];
                    unsigned int dec_len;
                    unsigned int sp;
                    if (di.symfn) {
                        char* name = (*di.symfn)(runtime_instruction_address, 
                                                 di.caller_symbol_data);
                        if (name) {
                            if (di.xml_format) 
                                printf("\n<SYM>%s</SYM>\n", name);
                            else
                                printf("\nSYM %s:\n", name);
                        }
                    }
                    if (di.xml_format) {
                        printf("<ASMLINE>\n"); 
                        printf("  <ADDR>" XED_FMT_LX "</ADDR>\n", 
                               runtime_instruction_address);
                        printf("  <CATEGORY>%s</CATEGORY>\n", 
                               xed_category_enum_t2str(
                                        xed_decoded_inst_get_category(&xedd)));
                        printf("  <EXTENSION>%s</EXTENSION>\n",
                               xed_extension_enum_t2str(
                                       xed_decoded_inst_get_extension(&xedd)));
                        printf("  <ITEXT>");
                        dec_len = xed_decoded_inst_get_length(&xedd);
                        xed_print_hex_line(buffer, (xed_uint8_t*) z, 
                                           dec_len, XED_TMP_BUF_LEN);
                        printf("%s</ITEXT>\n",buffer);
                        buffer[0]=0;
                        disassemble(buffer,XED_TMP_BUF_LEN, 
                                    &xedd, runtime_instruction_address, 
                                    di.caller_symbol_data);
                        printf( "  %s\n",buffer);
                        printf("</ASMLINE>\n"); 
                    }
                    else {
                        printf("XDIS " XED_FMT_LX ": ",
                               runtime_instruction_address);
                        printf("%-9s ",
                               xed_category_enum_t2str(
                                 xed_decoded_inst_get_category(&xedd)));
                        printf("%-6s ",
                               xed_extension_enum_t2str(
                                xed_decoded_inst_get_extension(&xedd)));
                        dec_len = xed_decoded_inst_get_length(&xedd);
                        xed_print_hex_line(buffer, (xed_uint8_t*) z, 
                                           dec_len, XED_HEX_BUFLEN);
                        printf("%s",buffer);
                        // pad out the instruction bytes
                        for ( sp=dec_len; sp < 12; sp++) 
                            printf("  ");
                        printf(" ");
                        buffer[0]=0;
                        disassemble(buffer,XED_TMP_BUF_LEN,
                                    &xedd, 
                                    runtime_instruction_address, 
                                    di.caller_symbol_data);
                        printf( "%s",buffer);
                        if (gs) {
                            graph_empty = 0;
                            xed_dot_graph_add_instruction(
                                gs,
                                &xedd,
                                runtime_instruction_address,
                                di.caller_symbol_data);
                        }

                        if (di.line_number_info_fn)
                            (*di.line_number_info_fn)(runtime_instruction_address);
                        
                        printf( "\n");
                    }
                }
            }
            else {
                errors++;
                xed_decode_error( runtime_instruction_address, z-di.a, z, 
                                  xed_error);
                // just give a length of 1B to see if we can restart decode...
                length = 1;
            }
        }
    #if defined(XED_ENCODER)        
        else
        {