main_main.c revision f48ac19a67a98af44fe452c8c2be4192ac94b62d
135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---                                                         ---*/
4c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- This file (main/vex_main.c) is                          ---*/
535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---                                                         ---*/
735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
9887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "libvex.h"
1081ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj#include "libvex_guest_x86.h"
11f13a16a82132fa2358899c7683193effecf9a56fsewardj
12c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_globals.h"
13c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_util.h"
14c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "host-generic/h_generic_regs.h"
15c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "host-x86/hdefs.h"
16c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "guest-x86/gdefs.h"
17edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj#include "ir/iropt.h"
1835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
1935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
2035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* This file contains the top level interface to the library. */
2135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
2235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Initialise the library. --------- */
2335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
2435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
2535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
2608613749b639323cc7582c1bbe56c6e21c69774fsewardjvoid LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
2708613749b639323cc7582c1bbe56c6e21c69774fsewardj{
2808613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_verbosity            = 0;
2908613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_level                = 2;
3008613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_precise_memory_exns  = False;
3108613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_unroll_thresh        = 120;
3208613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->guest_max_insns            = 50;
3308613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->guest_chase_thresh         = 10;
3408613749b639323cc7582c1bbe56c6e21c69774fsewardj}
3508613749b639323cc7582c1bbe56c6e21c69774fsewardj
3608613749b639323cc7582c1bbe56c6e21c69774fsewardj
3708613749b639323cc7582c1bbe56c6e21c69774fsewardj/* Exported to library client. */
3808613749b639323cc7582c1bbe56c6e21c69774fsewardj
39887a11a609f3e61d2ae8fe4e67f176207715da7esewardjvoid LibVEX_Init (
4035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* failure exit function */
412b51587159d1d7c331719886d896c0a9cf217ee4sewardj   __attribute__ ((noreturn))
4235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   void (*failure_exit) ( void ),
4335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* logging output function */
4435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   void (*log_bytes) ( Char*, Int nbytes ),
4535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* debug paranoia level */
4635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Int debuglevel,
4735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* Are we supporting valgrind checking? */
4835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Bool valgrind_support,
4908613749b639323cc7582c1bbe56c6e21c69774fsewardj   /* Control ... */
5008613749b639323cc7582c1bbe56c6e21c69774fsewardj   /*READONLY*/VexControl* vcon
5135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj)
5235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{
5308613749b639323cc7582c1bbe56c6e21c69774fsewardj   /* First off, do enough minimal setup so that the following
5408613749b639323cc7582c1bbe56c6e21c69774fsewardj      assertions can fail in a sane fashion, if need be. */
55ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vex_failure_exit = failure_exit;
56ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vex_log_bytes    = log_bytes;
57ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
58ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Now it's safe to check parameters for sanity. */
5935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(!vex_initdone);
6035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(failure_exit);
6135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(log_bytes);
6235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(debuglevel >= 0);
6308613749b639323cc7582c1bbe56c6e21c69774fsewardj
6408613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_verbosity >= 0);
6508613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_level >= 0);
6608613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_level <= 2);
6708613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_unroll_thresh >= 0);
6808613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_unroll_thresh <= 400);
6908613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_max_insns >= 1);
7008613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_max_insns <= 100);
7108613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_chase_thresh >= 0);
7208613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
73443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj
7481ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj   /* All the guest state structs must have an 8-aligned size. */
7581ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj   vassert(0 == sizeof(VexGuestX86State) % 8);
7681ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj
77ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Check that Vex has been built with sizes of basic types as
78ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      stated in priv/libvex_basictypes.h.  Failure of any of these is
79ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      a serious configuration error and should be corrected
80ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      immediately.  If any of these assertions fail you can fully
81ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      expect Vex not to work properly, if at all. */
82ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
83ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(UChar));
84ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Char));
85ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(UShort));
86ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(Short));
87ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(UInt));
88ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Int));
89ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(ULong));
90ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Long));
91ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Float));
92ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Double));
93ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Bool));
94ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Addr32));
95ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Addr64));
96ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
97ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
98ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(int*));
99ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(HWord));
100ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
101ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Really start up .. */
102443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_debuglevel         = debuglevel;
103443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_valgrind_support   = valgrind_support;
10408613749b639323cc7582c1bbe56c6e21c69774fsewardj   vex_control            = *vcon;
105443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_initdone           = True;
106443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   LibVEX_SetAllocMode ( AllocModeTEMPORARY );
10735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
10835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
10935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
11035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Make a translation. --------- */
11135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
11235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
11335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
114887a11a609f3e61d2ae8fe4e67f176207715da7esewardjTranslateResult LibVEX_Translate (
11535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* The instruction sets we are translating from and to. */
11635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   InsnSet iset_guest,
11735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   InsnSet iset_host,
11835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* IN: the block to translate, and its guest address. */
11981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   UChar* guest_bytes,
12035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Addr64 guest_bytes_addr,
12135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* OUT: the number of bytes actually read */
12235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Int* guest_bytes_read,
12335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* IN: a place to put the resulting code, and its size */
12481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   UChar* host_bytes,
12581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   Int    host_bytes_size,
12635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* OUT: how much of the output area is used. */
12735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Int* host_bytes_used,
12849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   /* IN: optionally, two instrumentation functions. */
12949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   IRBB* (*instrument1) ( IRBB*, VexGuestLayoutInfo* ),
13049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   IRBB* (*instrument2) ( IRBB*, VexGuestLayoutInfo* ),
131c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   HWord (*tool_findhelper) ( Char* ),
13235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* IN: optionally, an access check function for guest code. */
13358800ff1f3bc35d5cae9885c9d8a51a8d9d33016sewardj   Bool (*byte_accessible) ( Addr64 ),
134f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   /* IN: debug: trace vex activity at various points */
135f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   Int  traceflags
13635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj)
13735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{
13881bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* This the bundle of functions we need to do the back-end stuff
13981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      (insn selection, reg-alloc, assembly) whilst being insulated
14081bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      from the target instruction set. */
141f13a16a82132fa2358899c7683193effecf9a56fsewardj   HReg* available_real_regs;
142f13a16a82132fa2358899c7683193effecf9a56fsewardj   Int   n_available_real_regs;
143443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   Bool         (*isMove)      (HInstr*, HReg*, HReg*);
144443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   void         (*getRegUsage) (HRegUsage*, HInstr*);
145443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   void         (*mapRegs)     (HRegRemap*, HInstr*);
146443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   HInstr*      (*genSpill)    ( HReg, Int );
147443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   HInstr*      (*genReload)   ( HReg, Int );
148443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   void         (*ppInstr)     ( HInstr* );
149443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   void         (*ppReg)       ( HReg );
150c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   HInstrArray* (*iselBB)      ( IRBB*, HWord(*)(Char*), HWord(*)(Char*) );
151443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   IRBB*        (*bbToIR)      ( UChar*, Addr64, Int*,
152443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj                                         Bool(*)(Addr64), Bool );
15381bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   Int          (*emit)        ( UChar*, Int, HInstr* );
154c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   HWord        (*findHelper)  ( Char* );
15584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   IRExpr*      (*specHelper)  ( Char*, IRExpr** );
1568d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Bool         (*preciseMemExnsFn) ( Int, Int );
157f13a16a82132fa2358899c7683193effecf9a56fsewardj
15849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   VexGuestLayoutInfo* guest_layout;
15949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   Bool                host_is_bigendian = False;
16049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   IRBB*               irbb;
16149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   HInstrArray*        vcode;
16249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   HInstrArray*        rcode;
163f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   Int                 i, j, k, out_used, guest_sizeB;
16449651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   UChar               insn_bytes[32];
16549651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   IRType              guest_word_size;
166f13a16a82132fa2358899c7683193effecf9a56fsewardj
16749651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   guest_layout           = NULL;
16836ca51378f8851635df814230fa23f2c409b9eddsewardj   available_real_regs    = NULL;
16936ca51378f8851635df814230fa23f2c409b9eddsewardj   n_available_real_regs  = 0;
17036ca51378f8851635df814230fa23f2c409b9eddsewardj   isMove                 = NULL;
17136ca51378f8851635df814230fa23f2c409b9eddsewardj   getRegUsage            = NULL;
17236ca51378f8851635df814230fa23f2c409b9eddsewardj   mapRegs                = NULL;
17336ca51378f8851635df814230fa23f2c409b9eddsewardj   genSpill               = NULL;
17436ca51378f8851635df814230fa23f2c409b9eddsewardj   genReload              = NULL;
17536ca51378f8851635df814230fa23f2c409b9eddsewardj   ppInstr                = NULL;
17636ca51378f8851635df814230fa23f2c409b9eddsewardj   ppReg                  = NULL;
17736ca51378f8851635df814230fa23f2c409b9eddsewardj   iselBB                 = NULL;
17836ca51378f8851635df814230fa23f2c409b9eddsewardj   bbToIR                 = NULL;
17936ca51378f8851635df814230fa23f2c409b9eddsewardj   emit                   = NULL;
18036ca51378f8851635df814230fa23f2c409b9eddsewardj   findHelper             = NULL;
18184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   specHelper             = NULL;
1828d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   preciseMemExnsFn       = NULL;
183c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   guest_word_size        = Ity_INVALID;
18436ca51378f8851635df814230fa23f2c409b9eddsewardj
185f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   vex_traceflags = traceflags;
18658800ff1f3bc35d5cae9885c9d8a51a8d9d33016sewardj
18735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(vex_initdone);
188443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   LibVEX_ClearTemporary(False);
189f13a16a82132fa2358899c7683193effecf9a56fsewardj
190f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* First off, check that the guest and host insn sets
191f13a16a82132fa2358899c7683193effecf9a56fsewardj      are supported. */
192f13a16a82132fa2358899c7683193effecf9a56fsewardj   switch (iset_host) {
193f13a16a82132fa2358899c7683193effecf9a56fsewardj      case InsnSetX86:
194f13a16a82132fa2358899c7683193effecf9a56fsewardj         getAllocableRegs_X86 ( &n_available_real_regs,
195f13a16a82132fa2358899c7683193effecf9a56fsewardj                                &available_real_regs );
196f13a16a82132fa2358899c7683193effecf9a56fsewardj         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
197f13a16a82132fa2358899c7683193effecf9a56fsewardj         getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
198f13a16a82132fa2358899c7683193effecf9a56fsewardj         mapRegs     = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
199f13a16a82132fa2358899c7683193effecf9a56fsewardj         genSpill    = (HInstr*(*)(HReg,Int)) genSpill_X86;
200f13a16a82132fa2358899c7683193effecf9a56fsewardj         genReload   = (HInstr*(*)(HReg,Int)) genReload_X86;
2012b51587159d1d7c331719886d896c0a9cf217ee4sewardj         ppInstr     = (void(*)(HInstr*)) ppX86Instr;
2022b51587159d1d7c331719886d896c0a9cf217ee4sewardj         ppReg       = (void(*)(HReg)) ppHRegX86;
203f13a16a82132fa2358899c7683193effecf9a56fsewardj         iselBB      = iselBB_X86;
20481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         emit        = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
205c9a6570e86f4252f8a486b4df48de8710d357a4asewardj	 host_is_bigendian = False;
206f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
207f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
208887a11a609f3e61d2ae8fe4e67f176207715da7esewardj         vpanic("LibVEX_Translate: unsupported target insn set");
209f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
210f13a16a82132fa2358899c7683193effecf9a56fsewardj
211f13a16a82132fa2358899c7683193effecf9a56fsewardj   switch (iset_guest) {
212f13a16a82132fa2358899c7683193effecf9a56fsewardj      case InsnSetX86:
2138d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj         preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
2148d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj         bbToIR           = bbToIR_X86Instr;
2158d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj         findHelper       = x86guest_findhelper;
2168d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj         specHelper       = x86guest_spechelper;
21781ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj         guest_sizeB      = sizeof(VexGuestX86State);
218c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj	 guest_word_size  = Ity_I32;
21949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj         guest_layout     = &x86guest_layout;
220f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
221f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
222887a11a609f3e61d2ae8fe4e67f176207715da7esewardj         vpanic("LibVEX_Translate: unsupported guest insn set");
223f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
224f13a16a82132fa2358899c7683193effecf9a56fsewardj
225f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_FE)
226f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
227f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Front end "
228f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
229f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
230f13a16a82132fa2358899c7683193effecf9a56fsewardj   irbb = bbToIR ( guest_bytes,
231f13a16a82132fa2358899c7683193effecf9a56fsewardj		   guest_bytes_addr,
232f13a16a82132fa2358899c7683193effecf9a56fsewardj		   guest_bytes_read,
233c9a6570e86f4252f8a486b4df48de8710d357a4asewardj		   byte_accessible,
234c9a6570e86f4252f8a486b4df48de8710d357a4asewardj		   host_is_bigendian );
235f13a16a82132fa2358899c7683193effecf9a56fsewardj
236f13a16a82132fa2358899c7683193effecf9a56fsewardj   if (irbb == NULL) {
237f13a16a82132fa2358899c7683193effecf9a56fsewardj      /* Access failure. */
238443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj      LibVEX_ClearTemporary(False);
239f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_traceflags = 0;
240f13a16a82132fa2358899c7683193effecf9a56fsewardj      return TransAccessFail;
241f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
242aa59f942f729b5c98703d84321265313daeb32b8sewardj
243aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* If debugging, show the raw guest bytes for this bb. */
244f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_FE) {
245aa59f942f729b5c98703d84321265313daeb32b8sewardj      UChar* p = guest_bytes;
246aa59f942f729b5c98703d84321265313daeb32b8sewardj      vex_printf(". 0 %llx %d\n.", guest_bytes_addr, *guest_bytes_read );
247aa59f942f729b5c98703d84321265313daeb32b8sewardj      for (i = 0; i < *guest_bytes_read; i++)
248aa59f942f729b5c98703d84321265313daeb32b8sewardj         vex_printf(" %02x", (Int)p[i] );
249f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n\n");
250aa59f942f729b5c98703d84321265313daeb32b8sewardj   }
251aa59f942f729b5c98703d84321265313daeb32b8sewardj
252aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* Sanity check the initial IR. */
253c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   sanityCheckIRBB(irbb, guest_word_size);
254e8e9d73817f92d295f45b1c6c823c613bc2e90aesewardj
255edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   /* Clean it up, hopefully a lot. */
2568d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
2578d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj                              guest_bytes_addr );
258c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   sanityCheckIRBB(irbb, guest_word_size);
259edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
260f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_OPT1) {
261f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
262f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After pre-instr IR optimisation "
263f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
264edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj      ppIRBB ( irbb );
265edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj      vex_printf("\n");
266edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   }
267edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
268f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Get the thing instrumented. */
26949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   if (instrument1)
27049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj      irbb = (*instrument1)(irbb, guest_layout);
27149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   if (instrument2)
27249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj      irbb = (*instrument2)(irbb, guest_layout);
27349651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
274f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_INST) {
275f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
276f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After instrumentation "
277f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
278f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      ppIRBB ( irbb );
279f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
280f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
281f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
28249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   if (instrument1 || instrument2)
283c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj      sanityCheckIRBB(irbb, guest_word_size);
284f13a16a82132fa2358899c7683193effecf9a56fsewardj
285f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Turn it into virtual-registerised code. */
28649651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   do_deadcode_BB( irbb );
28749651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   do_treebuild_BB( irbb );
288f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
289f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_TREES) {
290f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
291f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "  After tree-building "
292f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
293f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      ppIRBB ( irbb );
294f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
295f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
296f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
297f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
298f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
299f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Instruction selection "
300f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n");
301f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
302c5fc7aa465504e5d5ad2d1820a84b4c143775655sewardj   vcode = iselBB ( irbb, findHelper, tool_findhelper );
303f13a16a82132fa2358899c7683193effecf9a56fsewardj
304f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
305f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
306f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
307f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj#if 0
308f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE) {
3091f40a0a104034009e253675288ebefdcccf30da8sewardj      vex_printf("\n-------- Virtual registerised code --------\n");
3101f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < vcode->arr_used; i++) {
3111f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
3121f40a0a104034009e253675288ebefdcccf30da8sewardj         ppInstr(vcode->arr[i]);
3131f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
3141f40a0a104034009e253675288ebefdcccf30da8sewardj      }
315fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
316fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
317f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj#endif
318fbcaf3312f39fb73d54821636c6168db76245f61sewardj
319f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Register allocate. */
320f13a16a82132fa2358899c7683193effecf9a56fsewardj   rcode = doRegisterAllocation ( vcode, available_real_regs,
321f13a16a82132fa2358899c7683193effecf9a56fsewardj                  	       	  n_available_real_regs,
322f13a16a82132fa2358899c7683193effecf9a56fsewardj			          isMove, getRegUsage, mapRegs,
32381ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj			          genSpill, genReload, guest_sizeB,
3242b51587159d1d7c331719886d896c0a9cf217ee4sewardj				  ppInstr, ppReg );
325f13a16a82132fa2358899c7683193effecf9a56fsewardj
326f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_RCODE) {
327f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
328f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Register-allocated code "
329f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
3301f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < rcode->arr_used; i++) {
3311f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
3321f40a0a104034009e253675288ebefdcccf30da8sewardj         ppInstr(rcode->arr[i]);
3331f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
3341f40a0a104034009e253675288ebefdcccf30da8sewardj      }
335fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
336fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
337fbcaf3312f39fb73d54821636c6168db76245f61sewardj
33881bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* Assemble */
339f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_ASM) {
340f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
341f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Assembly "
342f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
343f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
344f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
34581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   out_used = 0; /* tracks along the host_bytes array */
34681bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   for (i = 0; i < rcode->arr_used; i++) {
347f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      if (vex_traceflags & VEX_TRACE_ASM) {
348bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         ppInstr(rcode->arr[i]);
349bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n");
350bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
35181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      j = (*emit)( insn_bytes, 32, rcode->arr[i] );
352f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      if (vex_traceflags & VEX_TRACE_ASM) {
353bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         for (k = 0; k < j; k++)
35486898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj	    if (insn_bytes[k] < 16)
35586898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("0%x ",  (UInt)insn_bytes[k]);
35686898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj            else
35786898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("%x ", (UInt)insn_bytes[k]);
358bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n\n");
359bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
36081bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      if (out_used + j > host_bytes_size) {
36181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         LibVEX_ClearTemporary(False);
362f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj         vex_traceflags = 0;
36381bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         return TransOutputFull;
36481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
36581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      for (k = 0; k < j; k++) {
36681bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         host_bytes[out_used] = insn_bytes[k];
36781bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         out_used++;
36881bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
36981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      vassert(out_used <= host_bytes_size);
37081bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   }
37181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   *host_bytes_used = out_used;
37281bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj
3731f40a0a104034009e253675288ebefdcccf30da8sewardj   LibVEX_ClearTemporary(False);
374f13a16a82132fa2358899c7683193effecf9a56fsewardj
375f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   vex_traceflags = 0;
37635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   return TransOK;
37735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
37835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
37935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
38035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
38135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
382c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- end                                     main/vex_main.c ---*/
38335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
384