
/*---------------------------------------------------------------*/
/*---                                                         ---*/
/*--- This file (test_main.c) is                              ---*/
/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
/*---                                                         ---*/
/*---------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include "libvex_basictypes.h"
#include "libvex.h"

#include "test_main.h"


/*---------------------------------------------------------------*/
/*--- Test                                                    ---*/
/*---------------------------------------------------------------*/


__attribute__ ((noreturn))
static
void failure_exit ( void )
{
   fprintf(stdout, "VEX did failure_exit.  Bye.\n");
   exit(1);
}

static
void log_bytes ( Char* bytes, Int nbytes )
{
   fwrite ( bytes, 1, nbytes, stdout );
}

#define N_LINEBUF 10000
static Char linebuf[N_LINEBUF];

#define N_ORIGBUF 1000
#define N_TRANSBUF 5000

static UChar origbuf[N_ORIGBUF];
static UChar transbuf[N_TRANSBUF];

static Bool verbose = True;

/* Forwards */
static IRBB* ac_instrument ( IRBB*, VexGuestLayoutInfo* );


int main ( int argc, char** argv )
{
   FILE* f;
   Int i;
   UInt u, sum;
   Addr32 orig_addr;
   Int bb_number, n_bbs_done = 0;
   Int orig_nbytes, trans_used, orig_used;
   TranslateResult tres;
   VexControl vcon;

   if (argc != 2) {
      fprintf(stderr, "usage: vex file.org\n");
      exit(1);
   }
   f = fopen(argv[1], "r");
   if (!f) {
      fprintf(stderr, "can't open `%s'\n", argv[1]);
      exit(1);
   }

   /* Run with default params.  However, we can't allow bb chasing
      since that causes the front end to get segfaults when it tries
      to read code outside the initial BB we hand it. */
   LibVEX_default_VexControl ( &vcon );
   vcon.guest_chase_thresh = 0;
   vcon.iropt_level = 2;

   LibVEX_Init ( &failure_exit, &log_bytes, 
                 1,  /* debug_paranoia */ 
                 TEST_VSUPPORT, /* valgrind support */
                 &vcon );


   while (!feof(f)) {

      fgets(linebuf, N_LINEBUF,f);
      if (linebuf[0] == 0) continue;
      if (linebuf[0] != '.') continue;

      if (n_bbs_done == TEST_N_BBS) break;
      n_bbs_done++;

      /* first line is:   . bb-number bb-addr n-bytes */
      assert(3 == sscanf(&linebuf[1], " %d %x %d\n", 
                                 & bb_number,
                                 & orig_addr, & orig_nbytes ));
      assert(orig_nbytes >= 1);
      assert(!feof(f));
      fgets(linebuf, N_LINEBUF,f);
      assert(linebuf[0] == '.');

      /* second line is:   . byte byte byte etc */
      if (verbose)
         printf("============ Basic Block %d, "
                "Start %x, nbytes %2d ============", 
                n_bbs_done-1, orig_addr, orig_nbytes);

      assert(orig_nbytes >= 1 && orig_nbytes <= N_ORIGBUF);
      for (i = 0; i < orig_nbytes; i++) {
         assert(1 == sscanf(&linebuf[2 + 3*i], "%x", &u));
         origbuf[i] = (UChar)u;
      }

      for (i = 0; i < TEST_N_ITERS; i++)
         tres
            = LibVEX_Translate ( 
                 InsnSetX86, InsnSetX86,
                 origbuf, (Addr64)orig_addr, &orig_used,
                 transbuf, N_TRANSBUF, &trans_used,
                 ac_instrument, //NULL, /* instrument1 */
                 NULL, /* instrument2 */
                 NULL, /* access checker */
                 TEST_FLAGS 
              );

      if (tres != TransOK)
         printf("\ntres = %d\n", (Int)tres);
      assert(tres == TransOK);
      assert(orig_used == orig_nbytes);

      sum = 0;
      for (i = 0; i < trans_used; i++)
         sum += (UInt)transbuf[i];
      printf ( " %6.2f ... %d\n", (double)trans_used / (double)orig_used, sum );
   }

   fclose(f);
   printf("\n");
   LibVEX_ClearTemporary(True);

   return 0;
}

//////////////////////////////////////////////////////////////////////

static
void panic ( Char* s )
{
  printf("\npanic: %s\n", s);
  failure_exit();
}

static
IRBB* ac_instrument (IRBB* bb_in, VexGuestLayoutInfo* layout)
{
/* Use this rather than eg. -1 because it's a UInt. */
#define INVALID_DATA_SIZE   999999

   Int         i;
   Int         sz;
   IRCallee*   helper;
   IRStmt*    st;
   IRExpr* data;
   IRExpr* addr;
   Bool needSz;

   /* Set up BB */
   IRBB* bb     = emptyIRBB();
   bb->tyenv    = dopyIRTypeEnv(bb_in->tyenv);
   bb->next     = dopyIRExpr(bb_in->next);
   bb->jumpkind = bb_in->jumpkind;

   /* No loads to consider in ->next. */
   assert(isAtom(bb_in->next));

   for (i = 0; i <  bb_in->stmts_used; i++) {
      st = bb_in->stmts[i];
      if (!st) continue;

      switch (st->tag) {

         case Ist_Tmp:
            data = st->Ist.Tmp.data;
            if (data->tag == Iex_LDle) {
               addr = data->Iex.LDle.addr;
               sz = sizeofIRType(data->Iex.LDle.ty);
               needSz = False;
               switch (sz) {
                  case 4: helper = mkIRCallee(1, "ac_helperc_LOAD4", 
                                                 0x12345601); break;
                  case 2: helper = mkIRCallee(0, "ac_helperc_LOAD2",
                                                 0x12345602); break;
                  case 1: helper = mkIRCallee(1, "ac_helperc_LOAD1",
                                                 0x12345603); break;
                  default: helper = mkIRCallee(0, "ac_helperc_LOADN",
                                                  0x12345604);
                                                  needSz = True; break;
               }
               if (needSz) {
                  addStmtToIRBB( 
                     bb,
                     IRStmt_Dirty(
                        unsafeIRDirty_0_N( helper, 
                                           mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
                  ));
               } else {
                  addStmtToIRBB( 
                     bb,
                     IRStmt_Dirty(
                        unsafeIRDirty_0_N( helper, 
                                           mkIRExprVec_1(addr) )
                  ));
               }
            }
            break;

         case Ist_STle:
            data = st->Ist.STle.data;
            addr = st->Ist.STle.addr;
            assert(isAtom(data));
            assert(isAtom(addr));
            sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data));
            needSz = False;
            switch (sz) {
               case 4: helper = mkIRCallee(1, "ac_helperc_STORE4", 
                                              0x12345605); break;
               case 2: helper = mkIRCallee(0, "ac_helperc_STORE2", 
                                              0x12345606); break;
               case 1: helper = mkIRCallee(1, "ac_helperc_STORE1", 
                                              0x12345607); break;
               default: helper = mkIRCallee(0, "ac_helperc_STOREN", 
                                               0x12345608);
                                               needSz = True; break;
            }
            if (needSz) {
               addStmtToIRBB( 
                  bb,
                  IRStmt_Dirty(
                     unsafeIRDirty_0_N( helper, 
                                        mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
               ));
            } else {
               addStmtToIRBB( 
                  bb,
                  IRStmt_Dirty(
                     unsafeIRDirty_0_N( helper, 
                                        mkIRExprVec_1(addr) )
               ));
            }
            break;

         case Ist_Put:
            assert(isAtom(st->Ist.Put.data));
            break;

         case Ist_PutI:
            assert(isAtom(st->Ist.PutI.off));
            assert(isAtom(st->Ist.PutI.data));
            break;

         case Ist_Exit:
            assert(isAtom(st->Ist.Exit.cond));
            break;

         case Ist_Dirty:
            /* If the call doesn't interact with memory, we ain't
               interested. */
            if (st->Ist.Dirty.details->mFx == Ifx_None)
               break;
            goto unhandled;

         default:
         unhandled:
            printf("\n");
            ppIRStmt(st);
            printf("\n");
            panic("addrcheck: unhandled IRStmt");
      }

      addStmtToIRBB( bb, dopyIRStmt(st));
   }

   return bb;
}
