main_main.c revision aca070a5b3418a6a9b01e3c57a7eb0fbb5050908
135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---                                                         ---*/
4c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- This file (main/vex_main.c) is                          ---*/
5dbcfae724d5338205befbcd379a48f2303658198sewardj/*--- Copyright (C) OpenWorks LLP.  All rights reserved.      ---*/
635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---                                                         ---*/
735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
9f8ed9d874a7b8651654591c68c6d431c758d787csewardj/*
10f8ed9d874a7b8651654591c68c6d431c758d787csewardj   This file is part of LibVEX, a library for dynamic binary
11f8ed9d874a7b8651654591c68c6d431c758d787csewardj   instrumentation and translation.
12f8ed9d874a7b8651654591c68c6d431c758d787csewardj
13a33e9a4056799036a0e39f17657e252eb6e09503sewardj   Copyright (C) 2004-2006 OpenWorks LLP.  All rights reserved.
147bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
157bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   This library is made available under a dual licensing scheme.
167bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   If you link LibVEX against other code all of which is itself
187bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   licensed under the GNU General Public License, version 2 dated June
197bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
207bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL
217bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   is missing, you can obtain a copy of the GPL v2 from the Free
227bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
237bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
247bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
257bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   For any other uses of LibVEX, you must first obtain a commercial
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   license from OpenWorks LLP.  Please contact info@open-works.co.uk
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   for information about commercial licensing.
287bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
297bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   This software is provided by OpenWorks LLP "as is" and any express
307bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   or implied warranties, including, but not limited to, the implied
317bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   warranties of merchantability and fitness for a particular purpose
327bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   are disclaimed.  In no event shall OpenWorks LLP be liable for any
337bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   direct, indirect, incidental, special, exemplary, or consequential
347bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   damages (including, but not limited to, procurement of substitute
357bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   goods or services; loss of use, data, or profits; or business
367bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   interruption) however caused and on any theory of liability,
377bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   whether in contract, strict liability, or tort (including
387bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   negligence or otherwise) arising in any way out of the use of this
397bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   software, even if advised of the possibility of such damage.
40f8ed9d874a7b8651654591c68c6d431c758d787csewardj
41f8ed9d874a7b8651654591c68c6d431c758d787csewardj   Neither the names of the U.S. Department of Energy nor the
42f8ed9d874a7b8651654591c68c6d431c758d787csewardj   University of California nor the names of its contributors may be
43f8ed9d874a7b8651654591c68c6d431c758d787csewardj   used to endorse or promote products derived from this software
44f8ed9d874a7b8651654591c68c6d431c758d787csewardj   without prior written permission.
45f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/
46f8ed9d874a7b8651654591c68c6d431c758d787csewardj
47887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "libvex.h"
48893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj#include "libvex_emwarn.h"
4981ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj#include "libvex_guest_x86.h"
5044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj#include "libvex_guest_amd64.h"
512a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex_guest_arm.h"
52aabdfbf4193a965a8c50c643e536129d1d33661bcerion#include "libvex_guest_ppc32.h"
53f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#include "libvex_guest_ppc64.h"
54f13a16a82132fa2358899c7683193effecf9a56fsewardj
55c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_globals.h"
56c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_util.h"
57c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "host-generic/h_generic_regs.h"
582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "ir/iropt.h"
592a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
60c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "host-x86/hdefs.h"
61c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj#include "host-amd64/hdefs.h"
62d0eae2d5b6d8224bf1f075098e044b23ecffd9aecerion#include "host-ppc/hdefs.h"
632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
649e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "guest-generic/bb_to_IR.h"
65c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "guest-x86/gdefs.h"
6644d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj#include "guest-amd64/gdefs.h"
672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "guest-arm/gdefs.h"
68d0eae2d5b6d8224bf1f075098e044b23ecffd9aecerion#include "guest-ppc/gdefs.h"
6935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
7035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
7135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* This file contains the top level interface to the library. */
7235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
735117ce116f47141cb23d1b49cc826e19323add97sewardj/* --------- fwds ... --------- */
745117ce116f47141cb23d1b49cc826e19323add97sewardj
755117ce116f47141cb23d1b49cc826e19323add97sewardjstatic Bool   are_valid_hwcaps ( VexArch arch, UInt hwcaps );
765117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
775117ce116f47141cb23d1b49cc826e19323add97sewardj
785117ce116f47141cb23d1b49cc826e19323add97sewardj
7935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Initialise the library. --------- */
8035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
8135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
8235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
83d887b8634b2c2685f528bd968459c628e8f86a34sewardjconst HChar* LibVEX_Version ( void )
8480f5fceef55dc74b2ccca99d957699cbfc495176sewardj{
8580f5fceef55dc74b2ccca99d957699cbfc495176sewardjreturn
8680f5fceef55dc74b2ccca99d957699cbfc495176sewardj#include "main/vex_svnversion.h"
8780f5fceef55dc74b2ccca99d957699cbfc495176sewardj    ;
8880f5fceef55dc74b2ccca99d957699cbfc495176sewardj}
8980f5fceef55dc74b2ccca99d957699cbfc495176sewardj
9080f5fceef55dc74b2ccca99d957699cbfc495176sewardj
9180f5fceef55dc74b2ccca99d957699cbfc495176sewardj/* Exported to library client. */
9280f5fceef55dc74b2ccca99d957699cbfc495176sewardj
9308613749b639323cc7582c1bbe56c6e21c69774fsewardjvoid LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
9408613749b639323cc7582c1bbe56c6e21c69774fsewardj{
9508613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_verbosity            = 0;
9608613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_level                = 2;
9708613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_precise_memory_exns  = False;
9808613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_unroll_thresh        = 120;
9918b4bb706744f3d02ada9d7c2288df5ec7dc7115sewardj   vcon->guest_max_insns            = 60;
10008613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->guest_chase_thresh         = 10;
10108613749b639323cc7582c1bbe56c6e21c69774fsewardj}
10208613749b639323cc7582c1bbe56c6e21c69774fsewardj
10308613749b639323cc7582c1bbe56c6e21c69774fsewardj
10408613749b639323cc7582c1bbe56c6e21c69774fsewardj/* Exported to library client. */
10508613749b639323cc7582c1bbe56c6e21c69774fsewardj
106887a11a609f3e61d2ae8fe4e67f176207715da7esewardjvoid LibVEX_Init (
10735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* failure exit function */
1082b51587159d1d7c331719886d896c0a9cf217ee4sewardj   __attribute__ ((noreturn))
10935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   void (*failure_exit) ( void ),
11035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* logging output function */
111d97636248eaa5ac7e5b323c5c048efafe179e5c3sewardj   void (*log_bytes) ( HChar*, Int nbytes ),
11235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* debug paranoia level */
11335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Int debuglevel,
11435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* Are we supporting valgrind checking? */
11535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Bool valgrind_support,
11608613749b639323cc7582c1bbe56c6e21c69774fsewardj   /* Control ... */
11708613749b639323cc7582c1bbe56c6e21c69774fsewardj   /*READONLY*/VexControl* vcon
11835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj)
11935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{
12008613749b639323cc7582c1bbe56c6e21c69774fsewardj   /* First off, do enough minimal setup so that the following
12108613749b639323cc7582c1bbe56c6e21c69774fsewardj      assertions can fail in a sane fashion, if need be. */
122ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vex_failure_exit = failure_exit;
123ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vex_log_bytes    = log_bytes;
124ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
125ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Now it's safe to check parameters for sanity. */
12635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(!vex_initdone);
12735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(failure_exit);
12835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(log_bytes);
12935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(debuglevel >= 0);
13008613749b639323cc7582c1bbe56c6e21c69774fsewardj
13108613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_verbosity >= 0);
13208613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_level >= 0);
13308613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_level <= 2);
13408613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_unroll_thresh >= 0);
13508613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->iropt_unroll_thresh <= 400);
13608613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_max_insns >= 1);
13708613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_max_insns <= 100);
13808613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_chase_thresh >= 0);
13908613749b639323cc7582c1bbe56c6e21c69774fsewardj   vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
140443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj
141ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Check that Vex has been built with sizes of basic types as
142ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      stated in priv/libvex_basictypes.h.  Failure of any of these is
143ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      a serious configuration error and should be corrected
144ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      immediately.  If any of these assertions fail you can fully
145ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      expect Vex not to work properly, if at all. */
146ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
147ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(UChar));
148ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Char));
149ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(UShort));
150ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(Short));
151ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(UInt));
152ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Int));
153ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(ULong));
154ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Long));
155ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Float));
156ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Double));
157ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Bool));
158ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Addr32));
159ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Addr64));
160c9a43665879a03886b27a65b68af2a2c11b04f59sewardj   vassert(16 == sizeof(U128));
161ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
162ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
163ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(int*));
164ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(HWord));
165ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
16697e87935760215710e2d88bd66ca77fdeefd8dd7sewardj   vassert(VEX_HOST_WORDSIZE == sizeof(void*));
16797e87935760215710e2d88bd66ca77fdeefd8dd7sewardj   vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
16897e87935760215710e2d88bd66ca77fdeefd8dd7sewardj
169ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Really start up .. */
170443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_debuglevel         = debuglevel;
171443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_valgrind_support   = valgrind_support;
17208613749b639323cc7582c1bbe56c6e21c69774fsewardj   vex_control            = *vcon;
173443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_initdone           = True;
174d887b8634b2c2685f528bd968459c628e8f86a34sewardj   vexSetAllocMode ( VexAllocModeTEMP );
17535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
17635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
17735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
17835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Make a translation. --------- */
17935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
18035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
18135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
18217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardjVexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
18335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{
18481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* This the bundle of functions we need to do the back-end stuff
18581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      (insn selection, reg-alloc, assembly) whilst being insulated
18681bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      from the target instruction set. */
187f13a16a82132fa2358899c7683193effecf9a56fsewardj   HReg* available_real_regs;
188f13a16a82132fa2358899c7683193effecf9a56fsewardj   Int   n_available_real_regs;
18992b643609c5fa432b11fc726c2706ae3f3296eb4cerion   Bool         (*isMove)      ( HInstr*, HReg*, HReg* );
19092b643609c5fa432b11fc726c2706ae3f3296eb4cerion   void         (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
19192b643609c5fa432b11fc726c2706ae3f3296eb4cerion   void         (*mapRegs)     ( HRegRemap*, HInstr*, Bool );
19292b643609c5fa432b11fc726c2706ae3f3296eb4cerion   HInstr*      (*genSpill)    ( HReg, Int, Bool );
19392b643609c5fa432b11fc726c2706ae3f3296eb4cerion   HInstr*      (*genReload)   ( HReg, Int, Bool );
19492b643609c5fa432b11fc726c2706ae3f3296eb4cerion   void         (*ppInstr)     ( HInstr*, Bool );
195443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   void         (*ppReg)       ( HReg );
196aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   HInstrArray* (*iselBB)      ( IRBB*, VexArch, VexArchInfo*,
197aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                                 VexMiscInfo* );
19817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   Int          (*emit)        ( UChar*, Int, HInstr*, Bool, void* );
199d97636248eaa5ac7e5b323c5c048efafe179e5c3sewardj   IRExpr*      (*specHelper)  ( HChar*, IRExpr** );
2008d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Bool         (*preciseMemExnsFn) ( Int, Int );
201f13a16a82132fa2358899c7683193effecf9a56fsewardj
2029e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   DisOneInstrFn disInstrFn;
2039e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
204eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   VexGuestLayout* guest_layout;
205eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   Bool            host_is_bigendian = False;
206eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   IRBB*           irbb;
207eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   HInstrArray*    vcode;
208eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   HInstrArray*    rcode;
209eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   Int             i, j, k, out_used, guest_sizeB;
210c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   Int             offB_TISTART, offB_TILEN;
211eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   UChar           insn_bytes[32];
212cf7879021370aabcccb1a9347244fcc7d5680141sewardj   IRType          guest_word_type;
213cf7879021370aabcccb1a9347244fcc7d5680141sewardj   IRType          host_word_type;
21492b643609c5fa432b11fc726c2706ae3f3296eb4cerion   Bool            mode64;
215f13a16a82132fa2358899c7683193effecf9a56fsewardj
21649651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   guest_layout           = NULL;
21736ca51378f8851635df814230fa23f2c409b9eddsewardj   available_real_regs    = NULL;
21836ca51378f8851635df814230fa23f2c409b9eddsewardj   n_available_real_regs  = 0;
21936ca51378f8851635df814230fa23f2c409b9eddsewardj   isMove                 = NULL;
22036ca51378f8851635df814230fa23f2c409b9eddsewardj   getRegUsage            = NULL;
22136ca51378f8851635df814230fa23f2c409b9eddsewardj   mapRegs                = NULL;
22236ca51378f8851635df814230fa23f2c409b9eddsewardj   genSpill               = NULL;
22336ca51378f8851635df814230fa23f2c409b9eddsewardj   genReload              = NULL;
22436ca51378f8851635df814230fa23f2c409b9eddsewardj   ppInstr                = NULL;
22536ca51378f8851635df814230fa23f2c409b9eddsewardj   ppReg                  = NULL;
22636ca51378f8851635df814230fa23f2c409b9eddsewardj   iselBB                 = NULL;
22736ca51378f8851635df814230fa23f2c409b9eddsewardj   emit                   = NULL;
22884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   specHelper             = NULL;
2298d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   preciseMemExnsFn       = NULL;
2309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   disInstrFn             = NULL;
231cf7879021370aabcccb1a9347244fcc7d5680141sewardj   guest_word_type        = Ity_INVALID;
232cf7879021370aabcccb1a9347244fcc7d5680141sewardj   host_word_type         = Ity_INVALID;
233db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   offB_TISTART           = 0;
234db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   offB_TILEN             = 0;
23592b643609c5fa432b11fc726c2706ae3f3296eb4cerion   mode64                 = False;
23636ca51378f8851635df814230fa23f2c409b9eddsewardj
23717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vex_traceflags = vta->traceflags;
23858800ff1f3bc35d5cae9885c9d8a51a8d9d33016sewardj
23935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(vex_initdone);
2402d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexSetAllocModeTEMP_and_clear();
2412d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
2422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
243f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* First off, check that the guest and host insn sets
244f13a16a82132fa2358899c7683193effecf9a56fsewardj      are supported. */
2452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
24617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   switch (vta->arch_host) {
2472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
248bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:
24992b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mode64      = False;
250f13a16a82132fa2358899c7683193effecf9a56fsewardj         getAllocableRegs_X86 ( &n_available_real_regs,
251f13a16a82132fa2358899c7683193effecf9a56fsewardj                                &available_real_regs );
252f13a16a82132fa2358899c7683193effecf9a56fsewardj         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
25392b643609c5fa432b11fc726c2706ae3f3296eb4cerion         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_X86Instr;
25492b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
25592b643609c5fa432b11fc726c2706ae3f3296eb4cerion         genSpill    = (HInstr*(*)(HReg,Int, Bool)) genSpill_X86;
25692b643609c5fa432b11fc726c2706ae3f3296eb4cerion         genReload   = (HInstr*(*)(HReg,Int, Bool)) genReload_X86;
25792b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr     = (void(*)(HInstr*, Bool)) ppX86Instr;
2582b51587159d1d7c331719886d896c0a9cf217ee4sewardj         ppReg       = (void(*)(HReg)) ppHRegX86;
259f13a16a82132fa2358899c7683193effecf9a56fsewardj         iselBB      = iselBB_X86;
2600528bb5bd879eed0e8fa7e2bc9bc8debea00bf5fsewardj         emit        = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_X86Instr;
26172c72814ab82c51d8ee8accad1a00f2d37942545sewardj         host_is_bigendian = False;
262cf7879021370aabcccb1a9347244fcc7d5680141sewardj         host_word_type    = Ity_I32;
2635117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
26417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
265f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
2662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
267c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj      case VexArchAMD64:
26892b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mode64      = True;
269c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         getAllocableRegs_AMD64 ( &n_available_real_regs,
270c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj                                  &available_real_regs );
271c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
27292b643609c5fa432b11fc726c2706ae3f3296eb4cerion         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_AMD64Instr;
27392b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
27492b643609c5fa432b11fc726c2706ae3f3296eb4cerion         genSpill    = (HInstr*(*)(HReg,Int, Bool)) genSpill_AMD64;
27592b643609c5fa432b11fc726c2706ae3f3296eb4cerion         genReload   = (HInstr*(*)(HReg,Int, Bool)) genReload_AMD64;
27692b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr     = (void(*)(HInstr*, Bool)) ppAMD64Instr;
277c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         ppReg       = (void(*)(HReg)) ppHRegAMD64;
278c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         iselBB      = iselBB_AMD64;
2790528bb5bd879eed0e8fa7e2bc9bc8debea00bf5fsewardj         emit        = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_AMD64Instr;
280c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         host_is_bigendian = False;
281c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         host_word_type    = Ity_I64;
2825117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
28317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
284c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         break;
285c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj
286487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion      case VexArchPPC32:
28792b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mode64      = False;
2885b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getAllocableRegs_PPC ( &n_available_real_regs,
2895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                &available_real_regs, mode64 );
2905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
2915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
2925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         mapRegs     = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
2935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         genSpill    = (HInstr*(*)(HReg,Int,Bool)) genSpill_PPC;
2945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         genReload   = (HInstr*(*)(HReg,Int,Bool)) genReload_PPC;
2955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         ppInstr     = (void(*)(HInstr*,Bool)) ppPPCInstr;
2965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         ppReg       = (void(*)(HReg)) ppHRegPPC;
2975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         iselBB      = iselBB_PPC;
2985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         emit        = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
299487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion         host_is_bigendian = True;
300487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion         host_word_type    = Ity_I32;
3015117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
30217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
303487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion         break;
304487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion
305f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:
306f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         mode64      = True;
3075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getAllocableRegs_PPC ( &n_available_real_regs,
3085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                &available_real_regs, mode64 );
3095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
3105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
3115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
3125b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         genSpill    = (HInstr*(*)(HReg,Int, Bool)) genSpill_PPC;
3135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         genReload   = (HInstr*(*)(HReg,Int, Bool)) genReload_PPC;
3145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         ppInstr     = (void(*)(HInstr*, Bool)) ppPPCInstr;
3155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         ppReg       = (void(*)(HReg)) ppHRegPPC;
3165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         iselBB      = iselBB_PPC;
3175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         emit        = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
318f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         host_is_bigendian = True;
319f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         host_word_type    = Ity_I64;
3205117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
32117c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
322f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
323f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
324f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
325887a11a609f3e61d2ae8fe4e67f176207715da7esewardj         vpanic("LibVEX_Translate: unsupported target insn set");
326f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
327f13a16a82132fa2358899c7683193effecf9a56fsewardj
3282a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
32917c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   switch (vta->arch_guest) {
3302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
331bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:
3328d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj         preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
3339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         disInstrFn       = disInstr_X86;
3342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         specHelper       = guest_x86_spechelper;
33581ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj         guest_sizeB      = sizeof(VexGuestX86State);
336cf7879021370aabcccb1a9347244fcc7d5680141sewardj         guest_word_type  = Ity_I32;
33749651f4b59b1ab7e0e70cccd34001630eafbe957sewardj         guest_layout     = &x86guest_layout;
338db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TISTART     = offsetof(VexGuestX86State,guest_TISTART);
339db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TILEN       = offsetof(VexGuestX86State,guest_TILEN);
3405117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
341e74f6f7cb93e88b774ca3635c8969dc3314d85acsewardj         vassert(0 == sizeof(VexGuestX86State) % 8);
342ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
343ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN  ) == 4);
344ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
345f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
3462a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
34744d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj      case VexArchAMD64:
34844d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
3499e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         disInstrFn       = disInstr_AMD64;
35044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         specHelper       = guest_amd64_spechelper;
35144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         guest_sizeB      = sizeof(VexGuestAMD64State);
35244d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         guest_word_type  = Ity_I64;
35344d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         guest_layout     = &amd64guest_layout;
354db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TISTART     = offsetof(VexGuestAMD64State,guest_TISTART);
355db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TILEN       = offsetof(VexGuestAMD64State,guest_TILEN);
3565117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
357e74f6f7cb93e88b774ca3635c8969dc3314d85acsewardj         vassert(0 == sizeof(VexGuestAMD64State) % 8);
358db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
359ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN   ) == 8);
360ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR  ) == 8);
36144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         break;
36244d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj
363bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchARM:
3642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
3659e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         disInstrFn       = NULL; /* HACK */
3662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         specHelper       = guest_arm_spechelper;
3672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         guest_sizeB      = sizeof(VexGuestARMState);
3682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         guest_word_type  = Ity_I32;
3692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         guest_layout     = &armGuest_layout;
370db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TISTART     = 0; /* hack ... arm has bitrot */
371db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TILEN       = 0; /* hack ... arm has bitrot */
3725117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
3732a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         break;
3742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
375aabdfbf4193a965a8c50c643e536129d1d33661bcerion      case VexArchPPC32:
376aabdfbf4193a965a8c50c643e536129d1d33661bcerion         preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
3775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         disInstrFn       = disInstr_PPC;
378aabdfbf4193a965a8c50c643e536129d1d33661bcerion         specHelper       = guest_ppc32_spechelper;
379aabdfbf4193a965a8c50c643e536129d1d33661bcerion         guest_sizeB      = sizeof(VexGuestPPC32State);
380aabdfbf4193a965a8c50c643e536129d1d33661bcerion         guest_word_type  = Ity_I32;
381aabdfbf4193a965a8c50c643e536129d1d33661bcerion         guest_layout     = &ppc32Guest_layout;
382db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TISTART     = offsetof(VexGuestPPC32State,guest_TISTART);
383db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         offB_TILEN       = offsetof(VexGuestPPC32State,guest_TILEN);
3845117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
385e74f6f7cb93e88b774ca3635c8969dc3314d85acsewardj         vassert(0 == sizeof(VexGuestPPC32State) % 8);
386db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
387ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN   ) == 4);
388ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR  ) == 4);
389aabdfbf4193a965a8c50c643e536129d1d33661bcerion         break;
390aabdfbf4193a965a8c50c643e536129d1d33661bcerion
391f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:
392f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
3935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         disInstrFn       = disInstr_PPC;
394f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         specHelper       = guest_ppc64_spechelper;
395f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         guest_sizeB      = sizeof(VexGuestPPC64State);
396f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         guest_word_type  = Ity_I64;
397f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         guest_layout     = &ppc64Guest_layout;
398f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         offB_TISTART     = offsetof(VexGuestPPC64State,guest_TISTART);
399f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         offB_TILEN       = offsetof(VexGuestPPC64State,guest_TILEN);
4005117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
401f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(0 == sizeof(VexGuestPPC64State) % 16);
4023fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART    ) == 8);
4033fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN      ) == 8);
4043fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR     ) == 8);
4053fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
406f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
407f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
408f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
409887a11a609f3e61d2ae8fe4e67f176207715da7esewardj         vpanic("LibVEX_Translate: unsupported guest insn set");
410f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
411f13a16a82132fa2358899c7683193effecf9a56fsewardj
4129df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   /* yet more sanity checks ... */
41317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->arch_guest == vta->arch_host) {
4149df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      /* doesn't necessarily have to be true, but if it isn't it means
4150ec57c595719a395e71b48792a4d62c5b896b6d3sewardj         we are simulating one flavour of an architecture a different
4160ec57c595719a395e71b48792a4d62c5b896b6d3sewardj         flavour of the same architecture, which is pretty strange. */
4175117ce116f47141cb23d1b49cc826e19323add97sewardj      vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
4189df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   }
4192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
4202d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
4212d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
422f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_FE)
423f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
424f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Front end "
425f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
426f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
42717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   irbb = bb_to_IR ( vta->guest_extents,
428c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                     vta->callback_opaque,
4299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                     disInstrFn,
43017c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->guest_bytes,
43117c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->guest_bytes_addr,
43217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->chase_into_ok,
4339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                     host_is_bigendian,
434a5f55da7e956978fddad927436da5fab9568f3f1sewardj                     vta->arch_guest,
43517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     &vta->archinfo_guest,
436aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                     &vta->miscinfo_both,
437db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                     guest_word_type,
43817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->do_self_check,
439c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                     vta->preamble_function,
440db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                     offB_TISTART,
441c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                     offB_TILEN );
442f13a16a82132fa2358899c7683193effecf9a56fsewardj
4432d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
4442d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
445f13a16a82132fa2358899c7683193effecf9a56fsewardj   if (irbb == NULL) {
446f13a16a82132fa2358899c7683193effecf9a56fsewardj      /* Access failure. */
4472d6b14aa64df2ff85f8da143516779d5d43574cbsewardj      vexSetAllocModeTEMP_and_clear();
448f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_traceflags = 0;
449d887b8634b2c2685f528bd968459c628e8f86a34sewardj      return VexTransAccessFail;
450f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
451aa59f942f729b5c98703d84321265313daeb32b8sewardj
45217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
45317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
45417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   for (i = 0; i < vta->guest_extents->n_used; i++) {
45517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      vassert(vta->guest_extents->len[i] < 10000); /* sanity */
45672c72814ab82c51d8ee8accad1a00f2d37942545sewardj   }
45772c72814ab82c51d8ee8accad1a00f2d37942545sewardj
458aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* If debugging, show the raw guest bytes for this bb. */
459109ffdbb31ff652ae83d0ad400966f68c46cd4f1sewardj   if (0 || (vex_traceflags & VEX_TRACE_FE)) {
46017c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      if (vta->guest_extents->n_used > 1) {
46172c72814ab82c51d8ee8accad1a00f2d37942545sewardj         vex_printf("can't show code due to extents > 1\n");
46272c72814ab82c51d8ee8accad1a00f2d37942545sewardj      } else {
46372c72814ab82c51d8ee8accad1a00f2d37942545sewardj         /* HACK */
46417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         UChar* p = (UChar*)vta->guest_bytes;
46517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         UInt   guest_bytes_read = (UInt)vta->guest_extents->len[0];
46617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vex_printf(". 0 %llx %u\n.", vta->guest_bytes_addr, guest_bytes_read );
46772c72814ab82c51d8ee8accad1a00f2d37942545sewardj         for (i = 0; i < guest_bytes_read; i++)
468f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            vex_printf(" %02x", (Int)p[i] );
46972c72814ab82c51d8ee8accad1a00f2d37942545sewardj         vex_printf("\n\n");
47072c72814ab82c51d8ee8accad1a00f2d37942545sewardj      }
471aa59f942f729b5c98703d84321265313daeb32b8sewardj   }
472aa59f942f729b5c98703d84321265313daeb32b8sewardj
473aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* Sanity check the initial IR. */
474b92307503d4fb9265136e182d10c42ebb9dd8272sewardj   sanityCheckIRBB( irbb, "initial IR",
475b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                    False/*can be non-flat*/, guest_word_type );
476e8e9d73817f92d295f45b1c6c823c613bc2e90aesewardj
4772d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
4782d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
479edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   /* Clean it up, hopefully a lot. */
4808d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
48117c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              vta->guest_bytes_addr );
482b92307503d4fb9265136e182d10c42ebb9dd8272sewardj   sanityCheckIRBB( irbb, "after initial iropt",
483b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                    True/*must be flat*/, guest_word_type );
484edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
485f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_OPT1) {
486f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
487f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After pre-instr IR optimisation "
488f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
489edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj      ppIRBB ( irbb );
490edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj      vex_printf("\n");
491edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   }
492edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
4932d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
4942d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
495f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Get the thing instrumented. */
49617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1)
497c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      irbb = vta->instrument1(vta->callback_opaque,
498c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                              irbb, guest_layout,
49917c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              vta->guest_extents,
50017c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              guest_word_type, host_word_type);
5012d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
5022d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
50317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument2)
504c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      irbb = vta->instrument2(vta->callback_opaque,
505c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                              irbb, guest_layout,
50617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              vta->guest_extents,
50717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              guest_word_type, host_word_type);
50849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
509f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_INST) {
510f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
511f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After instrumentation "
512f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
513f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      ppIRBB ( irbb );
514f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
515f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
516f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
51717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1 || vta->instrument2)
518b92307503d4fb9265136e182d10c42ebb9dd8272sewardj      sanityCheckIRBB( irbb, "after instrumentation",
519b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                       True/*must be flat*/, guest_word_type );
520f13a16a82132fa2358899c7683193effecf9a56fsewardj
5219578a8bf6159d81eeadeb771c3214109cfee3715sewardj   /* Do a post-instrumentation cleanup pass. */
52217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1 || vta->instrument2) {
5239578a8bf6159d81eeadeb771c3214109cfee3715sewardj      do_deadcode_BB( irbb );
5249578a8bf6159d81eeadeb771c3214109cfee3715sewardj      irbb = cprop_BB( irbb );
5259578a8bf6159d81eeadeb771c3214109cfee3715sewardj      do_deadcode_BB( irbb );
526b92307503d4fb9265136e182d10c42ebb9dd8272sewardj      sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
527b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                       True/*must be flat*/, guest_word_type );
5289578a8bf6159d81eeadeb771c3214109cfee3715sewardj   }
5299578a8bf6159d81eeadeb771c3214109cfee3715sewardj
5302d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
5312d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
5329578a8bf6159d81eeadeb771c3214109cfee3715sewardj   if (vex_traceflags & VEX_TRACE_OPT2) {
5339578a8bf6159d81eeadeb771c3214109cfee3715sewardj      vex_printf("\n------------------------"
5349578a8bf6159d81eeadeb771c3214109cfee3715sewardj                   " After post-instr IR optimisation "
5359578a8bf6159d81eeadeb771c3214109cfee3715sewardj                   "------------------------\n\n");
5369578a8bf6159d81eeadeb771c3214109cfee3715sewardj      ppIRBB ( irbb );
5379578a8bf6159d81eeadeb771c3214109cfee3715sewardj      vex_printf("\n");
5389578a8bf6159d81eeadeb771c3214109cfee3715sewardj   }
5399578a8bf6159d81eeadeb771c3214109cfee3715sewardj
540f9517d0d452899780e8c34f02bef004ef7c5a163sewardj   /* Turn it into virtual-registerised code.  Build trees -- this
541f9517d0d452899780e8c34f02bef004ef7c5a163sewardj      also throws away any dead bindings. */
542f9517d0d452899780e8c34f02bef004ef7c5a163sewardj   ado_treebuild_BB( irbb );
543f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
5442d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
5452d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
546f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_TREES) {
547f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
548f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "  After tree-building "
549f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
550f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      ppIRBB ( irbb );
551f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
552f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
553f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
554e908c426bc9991611a1731ee881208d148e913fbsewardj   /* HACK */
55517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
556e908c426bc9991611a1731ee881208d148e913fbsewardj   /* end HACK */
557c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj
558f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
559f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
560f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Instruction selection "
561f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n");
562f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
563aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vcode = iselBB ( irbb, vta->arch_host, &vta->archinfo_host,
564aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                          &vta->miscinfo_both );
565f13a16a82132fa2358899c7683193effecf9a56fsewardj
5662d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
5672d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
568f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
569f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
570f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
571f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE) {
5721f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < vcode->arr_used; i++) {
5731f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
57492b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr(vcode->arr[i], mode64);
5751f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
5761f40a0a104034009e253675288ebefdcccf30da8sewardj      }
577fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
578fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
579fbcaf3312f39fb73d54821636c6168db76245f61sewardj
580f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Register allocate. */
581f13a16a82132fa2358899c7683193effecf9a56fsewardj   rcode = doRegisterAllocation ( vcode, available_real_regs,
582f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion                                  n_available_real_regs,
58372c72814ab82c51d8ee8accad1a00f2d37942545sewardj                                  isMove, getRegUsage, mapRegs,
58472c72814ab82c51d8ee8accad1a00f2d37942545sewardj                                  genSpill, genReload, guest_sizeB,
58592b643609c5fa432b11fc726c2706ae3f3296eb4cerion                                  ppInstr, ppReg, mode64 );
586f13a16a82132fa2358899c7683193effecf9a56fsewardj
5872d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
5882d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
589f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_RCODE) {
590f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
591f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Register-allocated code "
592f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
5931f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < rcode->arr_used; i++) {
5941f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
59592b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr(rcode->arr[i], mode64);
5961f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
5971f40a0a104034009e253675288ebefdcccf30da8sewardj      }
598fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
599fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
600fbcaf3312f39fb73d54821636c6168db76245f61sewardj
601e908c426bc9991611a1731ee881208d148e913fbsewardj   /* HACK */
60217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
603e908c426bc9991611a1731ee881208d148e913fbsewardj   /* end HACK */
604e908c426bc9991611a1731ee881208d148e913fbsewardj
60581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* Assemble */
606f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_ASM) {
607f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
608f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Assembly "
609f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
610f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
611f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
61281bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   out_used = 0; /* tracks along the host_bytes array */
61381bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   for (i = 0; i < rcode->arr_used; i++) {
614f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      if (vex_traceflags & VEX_TRACE_ASM) {
61592b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr(rcode->arr[i], mode64);
616bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n");
617bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
61817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      j = (*emit)( insn_bytes, 32, rcode->arr[i], mode64, vta->dispatch );
619f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      if (vex_traceflags & VEX_TRACE_ASM) {
620bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         for (k = 0; k < j; k++)
62172c72814ab82c51d8ee8accad1a00f2d37942545sewardj            if (insn_bytes[k] < 16)
62286898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("0%x ",  (UInt)insn_bytes[k]);
62386898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj            else
62486898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("%x ", (UInt)insn_bytes[k]);
625bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n\n");
626bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
62717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      if (out_used + j > vta->host_bytes_size) {
6282d6b14aa64df2ff85f8da143516779d5d43574cbsewardj         vexSetAllocModeTEMP_and_clear();
629f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj         vex_traceflags = 0;
630d887b8634b2c2685f528bd968459c628e8f86a34sewardj         return VexTransOutputFull;
63181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
63281bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      for (k = 0; k < j; k++) {
63317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         vta->host_bytes[out_used] = insn_bytes[k];
63481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj         out_used++;
63581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
63617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      vassert(out_used <= vta->host_bytes_size);
63781bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   }
63817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   *(vta->host_bytes_used) = out_used;
63981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj
6402d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
6412d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
6422d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexSetAllocModeTEMP_and_clear();
643f13a16a82132fa2358899c7683193effecf9a56fsewardj
644f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   vex_traceflags = 0;
645d887b8634b2c2685f528bd968459c628e8f86a34sewardj   return VexTransOK;
64635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
64735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
64835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
649893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* --------- Emulation warnings. --------- */
650893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
651893aadad7f29f7801ce26cb7575c16e90bd3767fsewardjHChar* LibVEX_EmWarn_string ( VexEmWarn ew )
652893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{
653893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   switch (ew) {
654893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_NONE:
655893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "none";
656893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_x87exns:
657893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "Unmasking x87 FP exceptions";
658893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_x87precision:
659893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "Selection of non-80-bit x87 FP precision";
660893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_sseExns:
6615edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Unmasking SSE FP exceptions";
6625edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj     case EmWarn_X86_fz:
6635edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
6645edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj     case EmWarn_X86_daz:
6655edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
6666d26984a0df6a7d20b658bac6edf869eb872cca3sewardj     case EmWarn_X86_acFlag:
6676d26984a0df6a7d20b658bac6edf869eb872cca3sewardj        return "Setting %eflags.ac (setting noted but ignored)";
6689dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPCexns:
6699dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "Unmasking PPC32/64 FP exceptions";
6709dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPC64_redir_overflow:
6719dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "PPC64 function redirection stack overflow";
6729dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPC64_redir_underflow:
6739dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "PPC64 function redirection stack underflow";
674893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     default:
675893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        vpanic("LibVEX_EmWarn_string: unknown warning");
676893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   }
677893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj}
67835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
6795117ce116f47141cb23d1b49cc826e19323add97sewardj/* ------------------ Arch/HwCaps stuff. ------------------ */
680bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
681bef170b7e84713d1e2181b9204d9415d29de3d65sewardjconst HChar* LibVEX_ppVexArch ( VexArch arch )
682bef170b7e84713d1e2181b9204d9415d29de3d65sewardj{
683bef170b7e84713d1e2181b9204d9415d29de3d65sewardj   switch (arch) {
684bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArch_INVALID: return "INVALID";
685bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:      return "X86";
686bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchAMD64:    return "AMD64";
687bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchARM:      return "ARM";
6880ec57c595719a395e71b48792a4d62c5b896b6d3sewardj      case VexArchPPC32:    return "PPC32";
689f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:    return "PPC64";
690bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      default:              return "VexArch???";
691bef170b7e84713d1e2181b9204d9415d29de3d65sewardj   }
692bef170b7e84713d1e2181b9204d9415d29de3d65sewardj}
693bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
6945117ce116f47141cb23d1b49cc826e19323add97sewardjconst HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
695bef170b7e84713d1e2181b9204d9415d29de3d65sewardj{
6965117ce116f47141cb23d1b49cc826e19323add97sewardj   HChar* str = show_hwcaps(arch,hwcaps);
6975117ce116f47141cb23d1b49cc826e19323add97sewardj   return str ? str : "INVALID";
698bef170b7e84713d1e2181b9204d9415d29de3d65sewardj}
699bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
7005117ce116f47141cb23d1b49cc826e19323add97sewardj
70127e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj/* Write default settings info *vai. */
70227e1dd6317760f3222f8a82185fa0e8ba138c85bsewardjvoid LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
70327e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj{
7045117ce116f47141cb23d1b49cc826e19323add97sewardj   vai->hwcaps             = 0;
7055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vai->ppc_cache_line_szB = 0;
70627e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj}
70727e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj
708aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj/* Write default settings info *vmi. */
709aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardjvoid LibVEX_default_VexMiscInfo ( /*OUT*/VexMiscInfo* vmi )
710aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj{
711aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->guest_stack_redzone_size       = 0;
712aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->guest_ppc_zap_RZ_at_blr        = False;
713aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->guest_ppc_zap_RZ_at_bl         = NULL;
714aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->guest_ppc_sc_continues_at_LR   = False;
715aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->host_ppc_calls_use_fndescrs    = False;
716aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   vmi->host_ppc32_regalign_int64_args = False;
717aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj}
718aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj
71927e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj
7205117ce116f47141cb23d1b49cc826e19323add97sewardj/* Return a string showing the hwcaps in a nice way.  The string will
7215117ce116f47141cb23d1b49cc826e19323add97sewardj   be NULL for invalid combinations of flags, so these functions also
7225117ce116f47141cb23d1b49cc826e19323add97sewardj   serve as a way to validate hwcaps values. */
7235117ce116f47141cb23d1b49cc826e19323add97sewardj
7245117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps_x86 ( UInt hwcaps )
7255117ce116f47141cb23d1b49cc826e19323add97sewardj{
7265117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
7275117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == 0)
7285117ce116f47141cb23d1b49cc826e19323add97sewardj      return "x86-sse0";
7295117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == VEX_HWCAPS_X86_SSE1)
7305117ce116f47141cb23d1b49cc826e19323add97sewardj      return "x86-sse1";
7315117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == (VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2))
7325117ce116f47141cb23d1b49cc826e19323add97sewardj      return "x86-sse1-sse2";
7335117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == (VEX_HWCAPS_X86_SSE1
7345117ce116f47141cb23d1b49cc826e19323add97sewardj                  | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3))
7355117ce116f47141cb23d1b49cc826e19323add97sewardj      return "x86-sse1-sse2-sse3";
7365117ce116f47141cb23d1b49cc826e19323add97sewardj
7375117ce116f47141cb23d1b49cc826e19323add97sewardj   return False;
7385117ce116f47141cb23d1b49cc826e19323add97sewardj}
7395117ce116f47141cb23d1b49cc826e19323add97sewardj
7405117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps_amd64 ( UInt hwcaps )
7415117ce116f47141cb23d1b49cc826e19323add97sewardj{
7425117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic, SSE3 > baseline. */
7435117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == 0)
7445117ce116f47141cb23d1b49cc826e19323add97sewardj      return "amd64-sse2";
7455117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == VEX_HWCAPS_AMD64_SSE3)
7465117ce116f47141cb23d1b49cc826e19323add97sewardj      return "amd64-sse3";
7475117ce116f47141cb23d1b49cc826e19323add97sewardj   return False;
7485117ce116f47141cb23d1b49cc826e19323add97sewardj}
7495117ce116f47141cb23d1b49cc826e19323add97sewardj
7505117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps_ppc32 ( UInt hwcaps )
7515117ce116f47141cb23d1b49cc826e19323add97sewardj{
7525117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic with complications.  Basically V > F > baseline,
7535117ce116f47141cb23d1b49cc826e19323add97sewardj      but once you have F then you can have FX or GX too. */
7545117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt F  = VEX_HWCAPS_PPC32_F;
7555117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt V  = VEX_HWCAPS_PPC32_V;
7565117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt FX = VEX_HWCAPS_PPC32_FX;
7575117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt GX = VEX_HWCAPS_PPC32_GX;
7585117ce116f47141cb23d1b49cc826e19323add97sewardj         UInt c  = hwcaps;
7595117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == 0)           return "ppc32-int";
7605117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == F)           return "ppc32-int-flt";
7615117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|FX))      return "ppc32-int-flt-FX";
7625117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|GX))      return "ppc32-int-flt-GX";
7635117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|FX|GX))   return "ppc32-int-flt-FX-GX";
7645117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V))       return "ppc32-int-flt-vmx";
7655117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|FX))    return "ppc32-int-flt-vmx-FX";
7665117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|GX))    return "ppc32-int-flt-vmx-GX";
7675117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
7685117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
7695117ce116f47141cb23d1b49cc826e19323add97sewardj}
7705117ce116f47141cb23d1b49cc826e19323add97sewardj
7715117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps_ppc64 ( UInt hwcaps )
7725117ce116f47141cb23d1b49cc826e19323add97sewardj{
7735117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic with complications.  Basically V > baseline(==F),
7745117ce116f47141cb23d1b49cc826e19323add97sewardj      but once you have F then you can have FX or GX too. */
7753fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt V  = VEX_HWCAPS_PPC64_V;
7763fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt FX = VEX_HWCAPS_PPC64_FX;
7773fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt GX = VEX_HWCAPS_PPC64_GX;
7785117ce116f47141cb23d1b49cc826e19323add97sewardj         UInt c  = hwcaps;
7795117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == 0)         return "ppc64-int-flt";
7805117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == FX)        return "ppc64-int-flt-FX";
7815117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == GX)        return "ppc64-int-flt-GX";
7825117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (FX|GX))   return "ppc64-int-flt-FX-GX";
7835117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == V)         return "ppc64-int-flt-vmx";
7845117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|FX))    return "ppc64-int-flt-vmx-FX";
7855117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|GX))    return "ppc64-int-flt-vmx-GX";
7865117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
7875117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
7885117ce116f47141cb23d1b49cc826e19323add97sewardj}
7895117ce116f47141cb23d1b49cc826e19323add97sewardj
7905117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps_arm ( UInt hwcaps )
7915117ce116f47141cb23d1b49cc826e19323add97sewardj{
7925117ce116f47141cb23d1b49cc826e19323add97sewardj   if (hwcaps == 0) return "arm-baseline";
7935117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
7945117ce116f47141cb23d1b49cc826e19323add97sewardj}
7955117ce116f47141cb23d1b49cc826e19323add97sewardj
7965117ce116f47141cb23d1b49cc826e19323add97sewardj/* ---- */
7975117ce116f47141cb23d1b49cc826e19323add97sewardjstatic HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
7985117ce116f47141cb23d1b49cc826e19323add97sewardj{
7995117ce116f47141cb23d1b49cc826e19323add97sewardj   switch (arch) {
8003fd3967db856eb90b2030ebeb42b685d45bc3276sewardj      case VexArchX86:   return show_hwcaps_x86(hwcaps);
8015117ce116f47141cb23d1b49cc826e19323add97sewardj      case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
8025117ce116f47141cb23d1b49cc826e19323add97sewardj      case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
8035117ce116f47141cb23d1b49cc826e19323add97sewardj      case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
8043fd3967db856eb90b2030ebeb42b685d45bc3276sewardj      case VexArchARM:   return show_hwcaps_arm(hwcaps);
8055117ce116f47141cb23d1b49cc826e19323add97sewardj      default: return NULL;
8065117ce116f47141cb23d1b49cc826e19323add97sewardj   }
8075117ce116f47141cb23d1b49cc826e19323add97sewardj}
8085117ce116f47141cb23d1b49cc826e19323add97sewardj
8095117ce116f47141cb23d1b49cc826e19323add97sewardjstatic Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
8105117ce116f47141cb23d1b49cc826e19323add97sewardj{
8115117ce116f47141cb23d1b49cc826e19323add97sewardj   return show_hwcaps(arch,hwcaps) != NULL;
8125117ce116f47141cb23d1b49cc826e19323add97sewardj}
8135117ce116f47141cb23d1b49cc826e19323add97sewardj
8145117ce116f47141cb23d1b49cc826e19323add97sewardj
81535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
816c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- end                                     main/vex_main.c ---*/
81735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
818