main_main.c revision ad00ea9f40f930d98bb2d278291a6c4c6636d6d6
135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
31f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll/*--- Begin                                       main_main.c ---*/
435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
6f8ed9d874a7b8651654591c68c6d431c758d787csewardj/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
9f8ed9d874a7b8651654591c68c6d431c758d787csewardj
1089ae8477745fd2a15453557d729a50e627325ee2sewardj   Copyright (C) 2004-2013 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
29f8ed9d874a7b8651654591c68c6d431c758d787csewardj
30f8ed9d874a7b8651654591c68c6d431c758d787csewardj   Neither the names of the U.S. Department of Energy nor the
31f8ed9d874a7b8651654591c68c6d431c758d787csewardj   University of California nor the names of its contributors may be
32f8ed9d874a7b8651654591c68c6d431c758d787csewardj   used to endorse or promote products derived from this software
33f8ed9d874a7b8651654591c68c6d431c758d787csewardj   without prior written permission.
34f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/
35f8ed9d874a7b8651654591c68c6d431c758d787csewardj
36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "libvex.h"
3733b024301d2311965cc68dc4cc900f3d0fdd8085florian#include "libvex_emnote.h"
3881ec4189e287a97256f1e0a9fa7c0be316aaefc6sewardj#include "libvex_guest_x86.h"
3944d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj#include "libvex_guest_amd64.h"
402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex_guest_arm.h"
41bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj#include "libvex_guest_arm64.h"
42aabdfbf4193a965a8c50c643e536129d1d33661bcerion#include "libvex_guest_ppc32.h"
43f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#include "libvex_guest_ppc64.h"
442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "libvex_guest_s390x.h"
45d0e5fe765fb79e5495206f8d0969133178b871f2sewardj#include "libvex_guest_mips32.h"
46b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj#include "libvex_guest_mips64.h"
47f13a16a82132fa2358899c7683193effecf9a56fsewardj
48cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h"
49cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h"
50cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_generic_regs.h"
51cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "ir_opt.h"
522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
53cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_x86_defs.h"
54cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_amd64_defs.h"
55cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_ppc_defs.h"
566c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#include "host_arm_defs.h"
57bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj#include "host_arm64_defs.h"
582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "host_s390_defs.h"
59d0e5fe765fb79e5495206f8d0969133178b871f2sewardj#include "host_mips_defs.h"
602a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
61cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h"
62cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_x86_defs.h"
63cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_amd64_defs.h"
64cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_arm_defs.h"
65bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj#include "guest_arm64_defs.h"
66cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_ppc_defs.h"
672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "guest_s390_defs.h"
68d0e5fe765fb79e5495206f8d0969133178b871f2sewardj#include "guest_mips_defs.h"
6935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
7069d98e3853a63e578e039894e2ef00ca6f9878c8sewardj#include "host_generic_simd128.h"
7169d98e3853a63e578e039894e2ef00ca6f9878c8sewardj
7235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
7335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* This file contains the top level interface to the library. */
7435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
755117ce116f47141cb23d1b49cc826e19323add97sewardj/* --------- fwds ... --------- */
765117ce116f47141cb23d1b49cc826e19323add97sewardj
775117ce116f47141cb23d1b49cc826e19323add97sewardjstatic Bool   are_valid_hwcaps ( VexArch arch, UInt hwcaps );
7855085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
795117ce116f47141cb23d1b49cc826e19323add97sewardj
805117ce116f47141cb23d1b49cc826e19323add97sewardj
818bde7f1c67483371551aac0d4019c24c919063f7sewardj/* --------- helpers --------- */
828bde7f1c67483371551aac0d4019c24c919063f7sewardj
838bde7f1c67483371551aac0d4019c24c919063f7sewardj__attribute__((noinline))
848bde7f1c67483371551aac0d4019c24c919063f7sewardjstatic UInt udiv32 ( UInt x, UInt y ) { return x/y; }
858bde7f1c67483371551aac0d4019c24c919063f7sewardj__attribute__((noinline))
868bde7f1c67483371551aac0d4019c24c919063f7sewardjstatic  Int sdiv32 (  Int x,  Int y ) { return x/y; }
878bde7f1c67483371551aac0d4019c24c919063f7sewardj
888bde7f1c67483371551aac0d4019c24c919063f7sewardj
8935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Initialise the library. --------- */
9035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
9135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
9235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
9308613749b639323cc7582c1bbe56c6e21c69774fsewardjvoid LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
9408613749b639323cc7582c1bbe56c6e21c69774fsewardj{
9565902992da28822e4753594c7b72f7cb177fe3a6sewardj   vex_bzero(vcon, sizeof(*vcon));
9608613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_verbosity            = 0;
9708613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_level                = 2;
98c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe   vcon->iropt_register_updates     = VexRegUpdUnwindregsAtMemAccess;
9908613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->iropt_unroll_thresh        = 120;
10018b4bb706744f3d02ada9d7c2288df5ec7dc7115sewardj   vcon->guest_max_insns            = 60;
10108613749b639323cc7582c1bbe56c6e21c69774fsewardj   vcon->guest_chase_thresh         = 10;
102984d9b164dd17f07e603c41fe1e506e641e57d18sewardj   vcon->guest_chase_cond           = False;
10308613749b639323cc7582c1bbe56c6e21c69774fsewardj}
10408613749b639323cc7582c1bbe56c6e21c69774fsewardj
10508613749b639323cc7582c1bbe56c6e21c69774fsewardj
10608613749b639323cc7582c1bbe56c6e21c69774fsewardj/* Exported to library client. */
10708613749b639323cc7582c1bbe56c6e21c69774fsewardj
108887a11a609f3e61d2ae8fe4e67f176207715da7esewardjvoid LibVEX_Init (
10935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* failure exit function */
1102b51587159d1d7c331719886d896c0a9cf217ee4sewardj   __attribute__ ((noreturn))
11135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   void (*failure_exit) ( void ),
11235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* logging output function */
113d97636248eaa5ac7e5b323c5c048efafe179e5c3sewardj   void (*log_bytes) ( HChar*, Int nbytes ),
11435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   /* debug paranoia level */
11535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   Int debuglevel,
11608613749b639323cc7582c1bbe56c6e21c69774fsewardj   /* Control ... */
117f72c2c12a06fdfada40f8a42fac44514c2d9c181florian   const 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);
140984d9b164dd17f07e603c41fe1e506e641e57d18sewardj   vassert(vcon->guest_chase_cond == True
141984d9b164dd17f07e603c41fe1e506e641e57d18sewardj           || vcon->guest_chase_cond == False);
142443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj
143ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Check that Vex has been built with sizes of basic types as
144ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      stated in priv/libvex_basictypes.h.  Failure of any of these is
145ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      a serious configuration error and should be corrected
146ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      immediately.  If any of these assertions fail you can fully
147ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj      expect Vex not to work properly, if at all. */
148ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
149ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(UChar));
150ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Char));
151ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(UShort));
152ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(2 == sizeof(Short));
153ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(UInt));
154ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Int));
155ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(ULong));
156ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Long));
157ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Float));
158ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Double));
159ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(1 == sizeof(Bool));
160ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(4 == sizeof(Addr32));
161ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(8 == sizeof(Addr64));
162c9a43665879a03886b27a65b68af2a2c11b04f59sewardj   vassert(16 == sizeof(U128));
16369d98e3853a63e578e039894e2ef00ca6f9878c8sewardj   vassert(16 == sizeof(V128));
164c9069f2908814843e9a4da00da9c8905440195a6sewardj   vassert(32 == sizeof(U256));
165ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
166ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
167ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(int*));
168ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   vassert(sizeof(void*) == sizeof(HWord));
169ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj
17097e87935760215710e2d88bd66ca77fdeefd8dd7sewardj   vassert(VEX_HOST_WORDSIZE == sizeof(void*));
17197e87935760215710e2d88bd66ca77fdeefd8dd7sewardj   vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
17297e87935760215710e2d88bd66ca77fdeefd8dd7sewardj
173c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   /* These take a lot of space, so make sure we don't have
174c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      any unnoticed size regressions. */
175c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   if (VEX_HOST_WORDSIZE == 4) {
176420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      vassert(sizeof(IRExpr) == 16);
177c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(sizeof(IRStmt) == 20 /* x86 */
178c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj              || sizeof(IRStmt) == 24 /* arm */);
179c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   } else {
180420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      vassert(sizeof(IRExpr) == 32);
181d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      vassert(sizeof(IRStmt) == 32);
182c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
183c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
1848bde7f1c67483371551aac0d4019c24c919063f7sewardj   /* Check that signed integer division on the host rounds towards
1858bde7f1c67483371551aac0d4019c24c919063f7sewardj      zero.  If not, h_calc_sdiv32_w_arm_semantics() won't work
1868bde7f1c67483371551aac0d4019c24c919063f7sewardj      correctly. */
1878bde7f1c67483371551aac0d4019c24c919063f7sewardj   /* 100.0 / 7.0 == 14.2857 */
1888bde7f1c67483371551aac0d4019c24c919063f7sewardj   vassert(udiv32(100, 7) == 14);
1898bde7f1c67483371551aac0d4019c24c919063f7sewardj   vassert(sdiv32(100, 7) == 14);
1908bde7f1c67483371551aac0d4019c24c919063f7sewardj   vassert(sdiv32(-100, 7) == -14); /* and not -15 */
1918bde7f1c67483371551aac0d4019c24c919063f7sewardj   vassert(sdiv32(100, -7) == -14); /* ditto */
1928bde7f1c67483371551aac0d4019c24c919063f7sewardj   vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
1938bde7f1c67483371551aac0d4019c24c919063f7sewardj
194ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj   /* Really start up .. */
195443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_debuglevel         = debuglevel;
19608613749b639323cc7582c1bbe56c6e21c69774fsewardj   vex_control            = *vcon;
197443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj   vex_initdone           = True;
198d887b8634b2c2685f528bd968459c628e8f86a34sewardj   vexSetAllocMode ( VexAllocModeTEMP );
19935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
20035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
20135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
20235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* --------- Make a translation. --------- */
20335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
20435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* Exported to library client. */
20535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
20617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardjVexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
20735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{
20881bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* This the bundle of functions we need to do the back-end stuff
20981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      (insn selection, reg-alloc, assembly) whilst being insulated
21081bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      from the target instruction set. */
211f13a16a82132fa2358899c7683193effecf9a56fsewardj   HReg* available_real_regs;
212f13a16a82132fa2358899c7683193effecf9a56fsewardj   Int   n_available_real_regs;
213d8c64e082224b2e688abdef9219cc76fd82b373bflorian   Bool         (*isMove)       ( const HInstr*, HReg*, HReg* );
214d8c64e082224b2e688abdef9219cc76fd82b373bflorian   void         (*getRegUsage)  ( HRegUsage*, const HInstr*, Bool );
215fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj   void         (*mapRegs)      ( HRegRemap*, HInstr*, Bool );
2166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   void         (*genSpill)     ( HInstr**, HInstr**, HReg, Int, Bool );
2176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   void         (*genReload)    ( HInstr**, HInstr**, HReg, Int, Bool );
218fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj   HInstr*      (*directReload) ( HInstr*, HReg, Short );
219d8c64e082224b2e688abdef9219cc76fd82b373bflorian   void         (*ppInstr)      ( const HInstr*, Bool );
220fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj   void         (*ppReg)        ( HReg );
221d8c64e082224b2e688abdef9219cc76fd82b373bflorian   HInstrArray* (*iselSB)       ( IRSB*, VexArch, const VexArchInfo*,
222d8c64e082224b2e688abdef9219cc76fd82b373bflorian                                  const VexAbiInfo*, Int, Int, Bool, Bool,
223d8c64e082224b2e688abdef9219cc76fd82b373bflorian                                  Addr64 );
224c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   Int          (*emit)         ( /*MB_MOD*/Bool*,
225d8c64e082224b2e688abdef9219cc76fd82b373bflorian                                  UChar*, Int, const HInstr*, Bool, VexEndness,
2268462d113e3efeacceb304222dada8d85f748295aflorian                                  const void*, const void*, const void*,
2278462d113e3efeacceb304222dada8d85f748295aflorian                                  const void* );
2281ff4756e1731485e6bf3cd96717cd8398daec1f2florian   IRExpr*      (*specHelper)   ( const HChar*, IRExpr**, IRStmt**, Int );
2298d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Bool         (*preciseMemExnsFn) ( Int, Int );
230f13a16a82132fa2358899c7683193effecf9a56fsewardj
2319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   DisOneInstrFn disInstrFn;
2329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
233eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   VexGuestLayout* guest_layout;
234dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   IRSB*           irsb;
235eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   HInstrArray*    vcode;
236eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   HInstrArray*    rcode;
237eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj   Int             i, j, k, out_used, guest_sizeB;
23805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   Int             offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
239c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   Int             offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
240b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   UChar           insn_bytes[128];
241cf7879021370aabcccb1a9347244fcc7d5680141sewardj   IRType          guest_word_type;
242cf7879021370aabcccb1a9347244fcc7d5680141sewardj   IRType          host_word_type;
243c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   Bool            mode64, chainingAllowed;
244c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   Addr64          max_ga;
245f13a16a82132fa2358899c7683193effecf9a56fsewardj
24649651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   guest_layout           = NULL;
24736ca51378f8851635df814230fa23f2c409b9eddsewardj   available_real_regs    = NULL;
24836ca51378f8851635df814230fa23f2c409b9eddsewardj   n_available_real_regs  = 0;
24936ca51378f8851635df814230fa23f2c409b9eddsewardj   isMove                 = NULL;
25036ca51378f8851635df814230fa23f2c409b9eddsewardj   getRegUsage            = NULL;
25136ca51378f8851635df814230fa23f2c409b9eddsewardj   mapRegs                = NULL;
25236ca51378f8851635df814230fa23f2c409b9eddsewardj   genSpill               = NULL;
25336ca51378f8851635df814230fa23f2c409b9eddsewardj   genReload              = NULL;
254fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj   directReload           = NULL;
25536ca51378f8851635df814230fa23f2c409b9eddsewardj   ppInstr                = NULL;
25636ca51378f8851635df814230fa23f2c409b9eddsewardj   ppReg                  = NULL;
257dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   iselSB                 = NULL;
25836ca51378f8851635df814230fa23f2c409b9eddsewardj   emit                   = NULL;
25984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   specHelper             = NULL;
2608d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   preciseMemExnsFn       = NULL;
2619e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   disInstrFn             = NULL;
262cf7879021370aabcccb1a9347244fcc7d5680141sewardj   guest_word_type        = Ity_INVALID;
263cf7879021370aabcccb1a9347244fcc7d5680141sewardj   host_word_type         = Ity_INVALID;
26405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   offB_CMSTART           = 0;
26505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   offB_CMLEN             = 0;
266c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   offB_GUEST_IP          = 0;
267c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   szB_GUEST_IP           = 0;
268c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   offB_HOST_EvC_COUNTER  = 0;
269c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   offB_HOST_EvC_FAILADDR = 0;
27092b643609c5fa432b11fc726c2706ae3f3296eb4cerion   mode64                 = False;
271c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   chainingAllowed        = False;
27236ca51378f8851635df814230fa23f2c409b9eddsewardj
27317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vex_traceflags = vta->traceflags;
27458800ff1f3bc35d5cae9885c9d8a51a8d9d33016sewardj
27535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj   vassert(vex_initdone);
276c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vassert(vta->needs_self_check  != NULL);
277c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vassert(vta->disp_cp_xassisted != NULL);
278c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   /* Both the chainers and the indir are either NULL or non-NULL. */
279c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   if (vta->disp_cp_chain_me_to_slowEP        != NULL) {
280c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
281c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(vta->disp_cp_xindir             != NULL);
282c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      chainingAllowed = True;
283c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   } else {
284c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
285c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(vta->disp_cp_xindir             == NULL);
286c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
2872eeeb9bc9367c26449deaa632e9f8eafa60c4685florian
2882d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexSetAllocModeTEMP_and_clear();
2892d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
2902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
291f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* First off, check that the guest and host insn sets
292f13a16a82132fa2358899c7683193effecf9a56fsewardj      are supported. */
2932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
29417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   switch (vta->arch_host) {
2952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
296bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:
297fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj         mode64       = False;
298f13a16a82132fa2358899c7683193effecf9a56fsewardj         getAllocableRegs_X86 ( &n_available_real_regs,
299f13a16a82132fa2358899c7683193effecf9a56fsewardj                                &available_real_regs );
300b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_X86Instr;
301b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_X86Instr;
302b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_X86Instr;
303b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_X86;
304b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_X86;
305b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         directReload = (__typeof__(directReload)) directReload_X86;
306b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppX86Instr;
307b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegX86;
308fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj         iselSB       = iselSB_X86;
309b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_X86Instr;
310cf7879021370aabcccb1a9347244fcc7d5680141sewardj         host_word_type    = Ity_I32;
3115117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
3129b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE);
313f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
3142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
315c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj      case VexArchAMD64:
31692b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mode64      = True;
317c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         getAllocableRegs_AMD64 ( &n_available_real_regs,
318c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj                                  &available_real_regs );
319b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_AMD64Instr;
320b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_AMD64Instr;
321b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_AMD64Instr;
322b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_AMD64;
323b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_AMD64;
324b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppAMD64Instr;
325b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegAMD64;
326b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_AMD64;
327b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_AMD64Instr;
328c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         host_word_type    = Ity_I64;
3295117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
3309b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE);
331c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj         break;
332c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj
333487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion      case VexArchPPC32:
33492b643609c5fa432b11fc726c2706ae3f3296eb4cerion         mode64      = False;
3355b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getAllocableRegs_PPC ( &n_available_real_regs,
3365b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                &available_real_regs, mode64 );
337b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_PPCInstr;
338b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
339b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_PPCInstr;
340b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_PPC;
341b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_PPC;
342b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppPPCInstr;
343b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegPPC;
344b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_PPC;
345b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_PPCInstr;
346487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion         host_word_type    = Ity_I32;
3475117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
3489b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessBE);
349487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion         break;
350487e4c9a453dfd32d87dbd4a51fac8aec054d563cerion
351f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:
352f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         mode64      = True;
3535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         getAllocableRegs_PPC ( &n_available_real_regs,
3545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                &available_real_regs, mode64 );
355b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_PPCInstr;
356b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
357b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_PPCInstr;
358b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_PPC;
359b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_PPC;
360b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppPPCInstr;
361b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegPPC;
362b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_PPC;
363b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_PPCInstr;
364f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         host_word_type    = Ity_I64;
3655117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
3661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         vassert(vta->archinfo_host.endness == VexEndnessBE ||
3671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                 vta->archinfo_host.endness == VexEndnessLE );
368f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
369f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      case VexArchS390X:
3712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         mode64      = True;
3722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         getAllocableRegs_S390 ( &n_available_real_regs,
3732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                 &available_real_regs, mode64 );
374b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_S390Instr;
375b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_S390Instr;
376b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_S390Instr;
377b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_S390;
378b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_S390;
379017c0d529daefd1f76c7d00a90b8cc810cc8e410florian         // fixs390: consider implementing directReload_S390
380b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppS390Instr;
381b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegS390;
382b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_S390;
383b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_S390Instr;
3842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         host_word_type    = Ity_I64;
3852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
3869b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessBE);
3872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         break;
3882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
3896c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case VexArchARM:
3902a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj         mode64      = False;
3916c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         getAllocableRegs_ARM ( &n_available_real_regs,
3926c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                                &available_real_regs );
393b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_ARMInstr;
394b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_ARMInstr;
395b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_ARMInstr;
396b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_ARM;
397b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_ARM;
398b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppARMInstr;
399b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegARM;
400b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_ARM;
401b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_ARMInstr;
4026c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         host_word_type    = Ity_I32;
4036c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
4049b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE);
4056c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         break;
4066c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
407bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      case VexArchARM64:
408bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         mode64      = True;
409bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         getAllocableRegs_ARM64 ( &n_available_real_regs,
410bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj                                  &available_real_regs );
411b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_ARM64Instr;
412b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_ARM64Instr;
413b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_ARM64Instr;
414b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_ARM64;
415b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_ARM64;
416b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppARM64Instr;
417b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegARM64;
418b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_ARM64;
419b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_ARM64Instr;
420bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         host_word_type    = Ity_I64;
421bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
4229b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE);
423bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         break;
424bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj
425d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:
426d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         mode64      = False;
427d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         getAllocableRegs_MIPS ( &n_available_real_regs,
428d0e5fe765fb79e5495206f8d0969133178b871f2sewardj                                &available_real_regs, mode64 );
429b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_MIPSInstr;
430b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
431b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
432b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_MIPS;
433b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_MIPS;
434b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppMIPSInstr;
435b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegMIPS;
436b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_MIPS;
437b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_MIPSInstr;
438d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         host_word_type    = Ity_I32;
439d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
4409b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE
4419b76916dcc1628e133d57db001563429c6e3a590sewardj                 || vta->archinfo_host.endness == VexEndnessBE);
442d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         break;
443d0e5fe765fb79e5495206f8d0969133178b871f2sewardj
444b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:
445b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mode64      = True;
446b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         getAllocableRegs_MIPS ( &n_available_real_regs,
447b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 &available_real_regs, mode64 );
448b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         isMove       = (__typeof__(isMove)) isMove_MIPSInstr;
449b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         getRegUsage  = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
450b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         mapRegs      = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
451b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genSpill     = (__typeof__(genSpill)) genSpill_MIPS;
452b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         genReload    = (__typeof__(genReload)) genReload_MIPS;
453b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppInstr      = (__typeof__(ppInstr)) ppMIPSInstr;
454b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         ppReg        = (__typeof__(ppReg)) ppHRegMIPS;
455b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         iselSB       = iselSB_MIPS;
456b66ad464f49a09366e6cefe7c61ce9aa6f144c71florian         emit         = (__typeof__(emit)) emit_MIPSInstr;
457b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         host_word_type    = Ity_I64;
458b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
4599b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_host.endness == VexEndnessLE
4609b76916dcc1628e133d57db001563429c6e3a590sewardj                 || vta->archinfo_host.endness == VexEndnessBE);
461b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
462b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
463f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
4646c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vpanic("LibVEX_Translate: unsupported host insn set");
465f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
466f13a16a82132fa2358899c7683193effecf9a56fsewardj
4672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
46817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   switch (vta->arch_guest) {
4692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
470bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:
471c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         preciseMemExnsFn       = guest_x86_state_requires_precise_mem_exns;
472c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         disInstrFn             = disInstr_X86;
473c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         specHelper             = guest_x86_spechelper;
474c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_sizeB            = sizeof(VexGuestX86State);
475c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_word_type        = Ity_I32;
476c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_layout           = &x86guest_layout;
47705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestX86State,guest_CMSTART);
47805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestX86State,guest_CMLEN);
479c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_GUEST_IP          = offsetof(VexGuestX86State,guest_EIP);
480c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         szB_GUEST_IP           = sizeof( ((VexGuestX86State*)0)->guest_EIP );
481c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestX86State,host_EvC_COUNTER);
482c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
4835117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
4849b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE);
4856c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(0 == sizeof(VexGuestX86State) % 16);
48605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
48705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN  ) == 4);
488ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
489f13a16a82132fa2358899c7683193effecf9a56fsewardj         break;
4902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
49144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj      case VexArchAMD64:
492c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         preciseMemExnsFn       = guest_amd64_state_requires_precise_mem_exns;
493c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         disInstrFn             = disInstr_AMD64;
494c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         specHelper             = guest_amd64_spechelper;
495c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_sizeB            = sizeof(VexGuestAMD64State);
496c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_word_type        = Ity_I64;
497c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_layout           = &amd64guest_layout;
49805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestAMD64State,guest_CMSTART);
49905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestAMD64State,guest_CMLEN);
500c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_GUEST_IP          = offsetof(VexGuestAMD64State,guest_RIP);
501c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         szB_GUEST_IP           = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
502c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
503c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
5045117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
5059b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE);
5066c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(0 == sizeof(VexGuestAMD64State) % 16);
50705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
50805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN   ) == 8);
509ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR  ) == 8);
51044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj         break;
51144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj
512aabdfbf4193a965a8c50c643e536129d1d33661bcerion      case VexArchPPC32:
5133dee849ec7c38746749065e67dc53b75daa7617dsewardj         preciseMemExnsFn       = guest_ppc32_state_requires_precise_mem_exns;
5143dee849ec7c38746749065e67dc53b75daa7617dsewardj         disInstrFn             = disInstr_PPC;
5153dee849ec7c38746749065e67dc53b75daa7617dsewardj         specHelper             = guest_ppc32_spechelper;
5163dee849ec7c38746749065e67dc53b75daa7617dsewardj         guest_sizeB            = sizeof(VexGuestPPC32State);
5173dee849ec7c38746749065e67dc53b75daa7617dsewardj         guest_word_type        = Ity_I32;
5183dee849ec7c38746749065e67dc53b75daa7617dsewardj         guest_layout           = &ppc32Guest_layout;
51905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestPPC32State,guest_CMSTART);
52005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestPPC32State,guest_CMLEN);
5213dee849ec7c38746749065e67dc53b75daa7617dsewardj         offB_GUEST_IP          = offsetof(VexGuestPPC32State,guest_CIA);
5223dee849ec7c38746749065e67dc53b75daa7617dsewardj         szB_GUEST_IP           = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
5233dee849ec7c38746749065e67dc53b75daa7617dsewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
5243dee849ec7c38746749065e67dc53b75daa7617dsewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
5255117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
5269b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessBE);
5276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(0 == sizeof(VexGuestPPC32State) % 16);
52805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
52905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN   ) == 4);
530ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR  ) == 4);
531aabdfbf4193a965a8c50c643e536129d1d33661bcerion         break;
532aabdfbf4193a965a8c50c643e536129d1d33661bcerion
533f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:
5349e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         preciseMemExnsFn       = guest_ppc64_state_requires_precise_mem_exns;
5359e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         disInstrFn             = disInstr_PPC;
5369e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         specHelper             = guest_ppc64_spechelper;
5379e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         guest_sizeB            = sizeof(VexGuestPPC64State);
5389e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         guest_word_type        = Ity_I64;
5399e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         guest_layout           = &ppc64Guest_layout;
54005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestPPC64State,guest_CMSTART);
54105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestPPC64State,guest_CMLEN);
5429e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         offB_GUEST_IP          = offsetof(VexGuestPPC64State,guest_CIA);
5439e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         szB_GUEST_IP           = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
5449e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
5459e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
5465117ce116f47141cb23d1b49cc826e19323add97sewardj         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
5471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         vassert(vta->archinfo_guest.endness == VexEndnessBE ||
5481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                 vta->archinfo_guest.endness == VexEndnessLE );
549f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(0 == sizeof(VexGuestPPC64State) % 16);
55005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART    ) == 8);
55105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN      ) == 8);
5523fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR     ) == 8);
5533fd3967db856eb90b2030ebeb42b685d45bc3276sewardj         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
554f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
555f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      case VexArchS390X:
5572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
5582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         disInstrFn       = disInstr_S390;
5592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         specHelper       = guest_s390x_spechelper;
5602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         guest_sizeB      = sizeof(VexGuestS390XState);
5612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         guest_word_type  = Ity_I64;
5622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         guest_layout     = &s390xGuest_layout;
56305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART     = offsetof(VexGuestS390XState,guest_CMSTART);
56405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN       = offsetof(VexGuestS390XState,guest_CMLEN);
5658844a6329d275814456e3a2a5a7bffac75da0957florian         offB_GUEST_IP          = offsetof(VexGuestS390XState,guest_IA);
5668844a6329d275814456e3a2a5a7bffac75da0957florian         szB_GUEST_IP           = sizeof( ((VexGuestS390XState*)0)->guest_IA);
5678844a6329d275814456e3a2a5a7bffac75da0957florian         offB_HOST_EvC_COUNTER  = offsetof(VexGuestS390XState,host_EvC_COUNTER);
5688844a6329d275814456e3a2a5a7bffac75da0957florian         offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
5692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
5709b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessBE);
5712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         vassert(0 == sizeof(VexGuestS390XState) % 16);
57205f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART    ) == 8);
57305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN      ) == 8);
5742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR     ) == 8);
5752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         break;
5762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
5776c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case VexArchARM:
578c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         preciseMemExnsFn       = guest_arm_state_requires_precise_mem_exns;
579c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         disInstrFn             = disInstr_ARM;
580c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         specHelper             = guest_arm_spechelper;
581c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_sizeB            = sizeof(VexGuestARMState);
582c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_word_type        = Ity_I32;
583c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         guest_layout           = &armGuest_layout;
58405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestARMState,guest_CMSTART);
58505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestARMState,guest_CMLEN);
586c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_GUEST_IP          = offsetof(VexGuestARMState,guest_R15T);
587c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         szB_GUEST_IP           = sizeof( ((VexGuestARMState*)0)->guest_R15T );
588c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestARMState,host_EvC_COUNTER);
589c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
5906c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
5919b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE);
5926c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(0 == sizeof(VexGuestARMState) % 16);
59305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
59405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN  ) == 4);
5956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
5966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         break;
5976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
598bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      case VexArchARM64:
599bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         preciseMemExnsFn     = guest_arm64_state_requires_precise_mem_exns;
600bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         disInstrFn           = disInstr_ARM64;
601bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         specHelper           = guest_arm64_spechelper;
602bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         guest_sizeB          = sizeof(VexGuestARM64State);
603bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         guest_word_type      = Ity_I64;
604bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         guest_layout         = &arm64Guest_layout;
60505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART         = offsetof(VexGuestARM64State,guest_CMSTART);
60605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN           = offsetof(VexGuestARM64State,guest_CMLEN);
607bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         offB_GUEST_IP        = offsetof(VexGuestARM64State,guest_PC);
608bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         szB_GUEST_IP         = sizeof( ((VexGuestARM64State*)0)->guest_PC );
609bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestARM64State,host_EvC_COUNTER);
610bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
611bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
6129b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE);
613bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         vassert(0 == sizeof(VexGuestARM64State) % 16);
61405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
61505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN  ) == 8);
616bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
617bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         break;
618bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj
619d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:
620d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         preciseMemExnsFn       = guest_mips32_state_requires_precise_mem_exns;
621d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         disInstrFn             = disInstr_MIPS;
622d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         specHelper             = guest_mips32_spechelper;
623d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         guest_sizeB            = sizeof(VexGuestMIPS32State);
624d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         guest_word_type        = Ity_I32;
625d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         guest_layout           = &mips32Guest_layout;
62605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestMIPS32State,guest_CMSTART);
62705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestMIPS32State,guest_CMLEN);
628d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         offB_GUEST_IP          = offsetof(VexGuestMIPS32State,guest_PC);
629d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         szB_GUEST_IP           = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
630d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
631d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
632d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
6339b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE
6349b76916dcc1628e133d57db001563429c6e3a590sewardj                 || vta->archinfo_guest.endness == VexEndnessBE);
635d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         vassert(0 == sizeof(VexGuestMIPS32State) % 16);
63605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
63705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN  ) == 4);
638d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
639d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         break;
640d0e5fe765fb79e5495206f8d0969133178b871f2sewardj
641b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:
642b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         preciseMemExnsFn       = guest_mips64_state_requires_precise_mem_exns;
643b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         disInstrFn             = disInstr_MIPS;
644b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         specHelper             = guest_mips64_spechelper;
645b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         guest_sizeB            = sizeof(VexGuestMIPS64State);
646b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         guest_word_type        = Ity_I64;
647b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         guest_layout           = &mips64Guest_layout;
64805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMSTART           = offsetof(VexGuestMIPS64State,guest_CMSTART);
64905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         offB_CMLEN             = offsetof(VexGuestMIPS64State,guest_CMLEN);
650b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         offB_GUEST_IP          = offsetof(VexGuestMIPS64State,guest_PC);
651b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         szB_GUEST_IP           = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
652b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         offB_HOST_EvC_COUNTER  = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
653b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
654b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
6559b76916dcc1628e133d57db001563429c6e3a590sewardj         vassert(vta->archinfo_guest.endness == VexEndnessLE
6569b76916dcc1628e133d57db001563429c6e3a590sewardj                 || vta->archinfo_guest.endness == VexEndnessBE);
657b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(0 == sizeof(VexGuestMIPS64State) % 16);
65805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
65905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN  ) == 8);
660b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
661b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
662b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
663f13a16a82132fa2358899c7683193effecf9a56fsewardj      default:
664887a11a609f3e61d2ae8fe4e67f176207715da7esewardj         vpanic("LibVEX_Translate: unsupported guest insn set");
665f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
666f13a16a82132fa2358899c7683193effecf9a56fsewardj
667bc161a407b3cbd722821812afb8fb47420ae538fsewardj   /* Set up result struct. */
668bc161a407b3cbd722821812afb8fb47420ae538fsewardj   VexTranslateResult res;
669fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   res.status         = VexTransOK;
670fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   res.n_sc_extents   = 0;
671fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   res.offs_profInc   = -1;
672fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   res.n_guest_instrs = 0;
673bc161a407b3cbd722821812afb8fb47420ae538fsewardj
6749df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   /* yet more sanity checks ... */
67517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->arch_guest == vta->arch_host) {
6769df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      /* doesn't necessarily have to be true, but if it isn't it means
6770ec57c595719a395e71b48792a4d62c5b896b6d3sewardj         we are simulating one flavour of an architecture a different
6780ec57c595719a395e71b48792a4d62c5b896b6d3sewardj         flavour of the same architecture, which is pretty strange. */
6795117ce116f47141cb23d1b49cc826e19323add97sewardj      vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
6809b76916dcc1628e133d57db001563429c6e3a590sewardj      /* ditto */
6819b76916dcc1628e133d57db001563429c6e3a590sewardj      vassert(vta->archinfo_guest.endness == vta->archinfo_host.endness);
6829df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   }
6832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
6842d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
6852d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
686f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_FE)
687f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
688f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Front end "
689f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
690f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
691dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   irsb = bb_to_IR ( vta->guest_extents,
692bc161a407b3cbd722821812afb8fb47420ae538fsewardj                     &res.n_sc_extents,
693fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj                     &res.n_guest_instrs,
694c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                     vta->callback_opaque,
6959e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                     disInstrFn,
69617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->guest_bytes,
69717c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->guest_bytes_addr,
69817c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     vta->chase_into_ok,
6999b76916dcc1628e133d57db001563429c6e3a590sewardj                     vta->archinfo_host.endness,
700442e51a26cf3bc7f243167a4ff3fbfb02206f6e6sewardj                     vta->sigill_diag,
701a5f55da7e956978fddad927436da5fab9568f3f1sewardj                     vta->arch_guest,
70217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                     &vta->archinfo_guest,
703dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                     &vta->abiinfo_both,
704db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                     guest_word_type,
705bc161a407b3cbd722821812afb8fb47420ae538fsewardj                     vta->needs_self_check,
706c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                     vta->preamble_function,
70705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj                     offB_CMSTART,
70805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj                     offB_CMLEN,
709c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                     offB_GUEST_IP,
710c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                     szB_GUEST_IP );
711f13a16a82132fa2358899c7683193effecf9a56fsewardj
7122d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
7132d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
714dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (irsb == NULL) {
715f13a16a82132fa2358899c7683193effecf9a56fsewardj      /* Access failure. */
7162d6b14aa64df2ff85f8da143516779d5d43574cbsewardj      vexSetAllocModeTEMP_and_clear();
717f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_traceflags = 0;
718bc161a407b3cbd722821812afb8fb47420ae538fsewardj      res.status = VexTransAccessFail; return res;
719f13a16a82132fa2358899c7683193effecf9a56fsewardj   }
720aa59f942f729b5c98703d84321265313daeb32b8sewardj
72117c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
72217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
72317c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   for (i = 0; i < vta->guest_extents->n_used; i++) {
72417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      vassert(vta->guest_extents->len[i] < 10000); /* sanity */
72572c72814ab82c51d8ee8accad1a00f2d37942545sewardj   }
72672c72814ab82c51d8ee8accad1a00f2d37942545sewardj
727aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* If debugging, show the raw guest bytes for this bb. */
728109ffdbb31ff652ae83d0ad400966f68c46cd4f1sewardj   if (0 || (vex_traceflags & VEX_TRACE_FE)) {
72917c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      if (vta->guest_extents->n_used > 1) {
73072c72814ab82c51d8ee8accad1a00f2d37942545sewardj         vex_printf("can't show code due to extents > 1\n");
73172c72814ab82c51d8ee8accad1a00f2d37942545sewardj      } else {
73272c72814ab82c51d8ee8accad1a00f2d37942545sewardj         /* HACK */
7338462d113e3efeacceb304222dada8d85f748295aflorian         const UChar* p = vta->guest_bytes;
73401f8cce97179cf4363240784a26adde19287a3a6sewardj         UInt   sum = 0;
73517c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj         UInt   guest_bytes_read = (UInt)vta->guest_extents->len[0];
73601f8cce97179cf4363240784a26adde19287a3a6sewardj         vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
73701f8cce97179cf4363240784a26adde19287a3a6sewardj                                           guest_bytes_read );
73801f8cce97179cf4363240784a26adde19287a3a6sewardj         for (i = 0; i < guest_bytes_read; i++) {
73901f8cce97179cf4363240784a26adde19287a3a6sewardj            UInt b = (UInt)p[i];
74001f8cce97179cf4363240784a26adde19287a3a6sewardj            vex_printf(" %02x", b );
74101f8cce97179cf4363240784a26adde19287a3a6sewardj            sum = (sum << 1) ^ b;
74201f8cce97179cf4363240784a26adde19287a3a6sewardj         }
74301f8cce97179cf4363240784a26adde19287a3a6sewardj         vex_printf("  %08x\n\n", sum);
74472c72814ab82c51d8ee8accad1a00f2d37942545sewardj      }
745aa59f942f729b5c98703d84321265313daeb32b8sewardj   }
746aa59f942f729b5c98703d84321265313daeb32b8sewardj
747aa59f942f729b5c98703d84321265313daeb32b8sewardj   /* Sanity check the initial IR. */
748dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   sanityCheckIRSB( irsb, "initial IR",
749b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                    False/*can be non-flat*/, guest_word_type );
750e8e9d73817f92d295f45b1c6c823c613bc2e90aesewardj
7512d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
7522d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
753edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   /* Clean it up, hopefully a lot. */
754dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
755ec0d9a028955060c5216341c6fc37400ec0cb4besewardj                              vta->guest_bytes_addr,
756ec0d9a028955060c5216341c6fc37400ec0cb4besewardj                              vta->arch_guest );
757dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   sanityCheckIRSB( irsb, "after initial iropt",
758b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                    True/*must be flat*/, guest_word_type );
759edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
760f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_OPT1) {
761f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
762f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After pre-instr IR optimisation "
763f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
764dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      ppIRSB ( irsb );
765edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj      vex_printf("\n");
766edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj   }
767edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj
7682d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
7692d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
770f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Get the thing instrumented. */
77117c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1)
772dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      irsb = vta->instrument1(vta->callback_opaque,
773dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                              irsb, guest_layout,
77417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              vta->guest_extents,
77550481921c3c61054b5629c4dcebf5ec680dbf6e9florian                              &vta->archinfo_host,
77617c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              guest_word_type, host_word_type);
7772d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
7782d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
77917c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument2)
780dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      irsb = vta->instrument2(vta->callback_opaque,
781dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                              irsb, guest_layout,
78217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              vta->guest_extents,
78350481921c3c61054b5629c4dcebf5ec680dbf6e9florian                              &vta->archinfo_host,
78417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj                              guest_word_type, host_word_type);
78549651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
786f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_INST) {
787f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
788f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " After instrumentation "
789f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
790dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      ppIRSB ( irsb );
791f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
792f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
793f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
79417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1 || vta->instrument2)
795dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      sanityCheckIRSB( irsb, "after instrumentation",
796b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                       True/*must be flat*/, guest_word_type );
797f13a16a82132fa2358899c7683193effecf9a56fsewardj
7989578a8bf6159d81eeadeb771c3214109cfee3715sewardj   /* Do a post-instrumentation cleanup pass. */
79917c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   if (vta->instrument1 || vta->instrument2) {
800dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      do_deadcode_BB( irsb );
801dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      irsb = cprop_BB( irsb );
802dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      do_deadcode_BB( irsb );
803dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
804b92307503d4fb9265136e182d10c42ebb9dd8272sewardj                       True/*must be flat*/, guest_word_type );
8059578a8bf6159d81eeadeb771c3214109cfee3715sewardj   }
8069578a8bf6159d81eeadeb771c3214109cfee3715sewardj
8072d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
8082d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
8099578a8bf6159d81eeadeb771c3214109cfee3715sewardj   if (vex_traceflags & VEX_TRACE_OPT2) {
8109578a8bf6159d81eeadeb771c3214109cfee3715sewardj      vex_printf("\n------------------------"
8119578a8bf6159d81eeadeb771c3214109cfee3715sewardj                   " After post-instr IR optimisation "
8129578a8bf6159d81eeadeb771c3214109cfee3715sewardj                   "------------------------\n\n");
813dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      ppIRSB ( irsb );
8149578a8bf6159d81eeadeb771c3214109cfee3715sewardj      vex_printf("\n");
8159578a8bf6159d81eeadeb771c3214109cfee3715sewardj   }
8169578a8bf6159d81eeadeb771c3214109cfee3715sewardj
817f9517d0d452899780e8c34f02bef004ef7c5a163sewardj   /* Turn it into virtual-registerised code.  Build trees -- this
818f9517d0d452899780e8c34f02bef004ef7c5a163sewardj      also throws away any dead bindings. */
81962140c196b8c18a23ba0fe54295f0ffa000a0054florian   max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
820f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
821be1b6ff6cdb576c59734762fb778ae48eb8e7a10sewardj   if (vta->finaltidy) {
822be1b6ff6cdb576c59734762fb778ae48eb8e7a10sewardj      irsb = vta->finaltidy(irsb);
823be1b6ff6cdb576c59734762fb778ae48eb8e7a10sewardj   }
824be1b6ff6cdb576c59734762fb778ae48eb8e7a10sewardj
8252d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
8262d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
827f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_TREES) {
828f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
829f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "  After tree-building "
830f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
831dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      ppIRSB ( irsb );
832f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
833f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
834f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
835e908c426bc9991611a1731ee881208d148e913fbsewardj   /* HACK */
836bc161a407b3cbd722821812afb8fb47420ae538fsewardj   if (0) {
837bc161a407b3cbd722821812afb8fb47420ae538fsewardj      *(vta->host_bytes_used) = 0;
838bc161a407b3cbd722821812afb8fb47420ae538fsewardj      res.status = VexTransOK; return res;
839bc161a407b3cbd722821812afb8fb47420ae538fsewardj   }
840e908c426bc9991611a1731ee881208d148e913fbsewardj   /* end HACK */
841c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj
842f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
843f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
844f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Instruction selection "
845f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n");
846f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
847c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   /* No guest has its IP field at offset zero.  If this fails it
848c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      means some transformation pass somewhere failed to update/copy
849c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      irsb->offsIP properly. */
850c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vassert(irsb->offsIP >= 16);
851c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
852c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vcode = iselSB ( irsb, vta->arch_host,
853c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    &vta->archinfo_host,
854c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    &vta->abiinfo_both,
855c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    offB_HOST_EvC_COUNTER,
856c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    offB_HOST_EvC_FAILADDR,
857c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    chainingAllowed,
858c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    vta->addProfInc,
859c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                    max_ga );
860f13a16a82132fa2358899c7683193effecf9a56fsewardj
8612d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
8622d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
863f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE)
864f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n");
865f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
866f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_VCODE) {
8671f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < vcode->arr_used; i++) {
8681f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
86992b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr(vcode->arr[i], mode64);
8701f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
8711f40a0a104034009e253675288ebefdcccf30da8sewardj      }
872fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
873fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
874fbcaf3312f39fb73d54821636c6168db76245f61sewardj
875f13a16a82132fa2358899c7683193effecf9a56fsewardj   /* Register allocate. */
876f13a16a82132fa2358899c7683193effecf9a56fsewardj   rcode = doRegisterAllocation ( vcode, available_real_regs,
877f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion                                  n_available_real_regs,
87872c72814ab82c51d8ee8accad1a00f2d37942545sewardj                                  isMove, getRegUsage, mapRegs,
879fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj                                  genSpill, genReload, directReload,
880fb7373aee5e8a3039f2916ecf09870f3ec0c1805sewardj                                  guest_sizeB,
88192b643609c5fa432b11fc726c2706ae3f3296eb4cerion                                  ppInstr, ppReg, mode64 );
882f13a16a82132fa2358899c7683193effecf9a56fsewardj
8832d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
8842d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
885f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_RCODE) {
886f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
887f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Register-allocated code "
888f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
8891f40a0a104034009e253675288ebefdcccf30da8sewardj      for (i = 0; i < rcode->arr_used; i++) {
8901f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("%3d   ", i);
89192b643609c5fa432b11fc726c2706ae3f3296eb4cerion         ppInstr(rcode->arr[i], mode64);
8921f40a0a104034009e253675288ebefdcccf30da8sewardj         vex_printf("\n");
8931f40a0a104034009e253675288ebefdcccf30da8sewardj      }
894fbcaf3312f39fb73d54821636c6168db76245f61sewardj      vex_printf("\n");
895fbcaf3312f39fb73d54821636c6168db76245f61sewardj   }
896fbcaf3312f39fb73d54821636c6168db76245f61sewardj
897e908c426bc9991611a1731ee881208d148e913fbsewardj   /* HACK */
898bc161a407b3cbd722821812afb8fb47420ae538fsewardj   if (0) {
899bc161a407b3cbd722821812afb8fb47420ae538fsewardj      *(vta->host_bytes_used) = 0;
900bc161a407b3cbd722821812afb8fb47420ae538fsewardj      res.status = VexTransOK; return res;
901bc161a407b3cbd722821812afb8fb47420ae538fsewardj   }
902e908c426bc9991611a1731ee881208d148e913fbsewardj   /* end HACK */
903e908c426bc9991611a1731ee881208d148e913fbsewardj
90481bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   /* Assemble */
905f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   if (vex_traceflags & VEX_TRACE_ASM) {
906f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj      vex_printf("\n------------------------"
907f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   " Assembly "
908f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj                   "------------------------\n\n");
909f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   }
910f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj
91181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   out_used = 0; /* tracks along the host_bytes array */
91281bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   for (i = 0; i < rcode->arr_used; i++) {
913c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      HInstr* hi           = rcode->arr[i];
914c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      Bool    hi_isProfInc = False;
915c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
916c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         ppInstr(hi, mode64);
917bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n");
918bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
919c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      j = emit( &hi_isProfInc,
9209b76916dcc1628e133d57db001563429c6e3a590sewardj                insn_bytes, sizeof insn_bytes, hi,
9219b76916dcc1628e133d57db001563429c6e3a590sewardj                mode64, vta->archinfo_host.endness,
922c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                vta->disp_cp_chain_me_to_slowEP,
923c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                vta->disp_cp_chain_me_to_fastEP,
924c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                vta->disp_cp_xindir,
925c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                vta->disp_cp_xassisted );
926c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
927bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         for (k = 0; k < j; k++)
92872c72814ab82c51d8ee8accad1a00f2d37942545sewardj            if (insn_bytes[k] < 16)
92986898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("0%x ",  (UInt)insn_bytes[k]);
93086898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj            else
93186898e8e1501f624d49b1cc43561c7a2a3b104f4sewardj               vex_printf("%x ", (UInt)insn_bytes[k]);
932bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj         vex_printf("\n\n");
933bad34a9c950dcc0c3f68ea2904206f3341fb5e91sewardj      }
934c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
9352d6b14aa64df2ff85f8da143516779d5d43574cbsewardj         vexSetAllocModeTEMP_and_clear();
936f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj         vex_traceflags = 0;
937bc161a407b3cbd722821812afb8fb47420ae538fsewardj         res.status = VexTransOutputFull;
938bc161a407b3cbd722821812afb8fb47420ae538fsewardj         return res;
93981bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
940c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      if (UNLIKELY(hi_isProfInc)) {
941c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(vta->addProfInc); /* else where did it come from? */
942c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(res.offs_profInc == -1); /* there can be only one (tm) */
943c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(out_used >= 0);
944c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         res.offs_profInc = out_used;
945c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      }
946c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      { UChar* dst = &vta->host_bytes[out_used];
947c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        for (k = 0; k < j; k++) {
948c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj           dst[k] = insn_bytes[k];
949c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        }
950c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        out_used += j;
95181bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj      }
95217c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj      vassert(out_used <= vta->host_bytes_size);
95381bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj   }
95417c7f95c78bb3c8ced934e41a4bf1aae6d857d59sewardj   *(vta->host_bytes_used) = out_used;
95581bd550f9a1d58ceeedb159d18642d9790e75eb4sewardj
9562d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexAllocSanityCheck();
9572d6b14aa64df2ff85f8da143516779d5d43574cbsewardj
9582d6b14aa64df2ff85f8da143516779d5d43574cbsewardj   vexSetAllocModeTEMP_and_clear();
959f13a16a82132fa2358899c7683193effecf9a56fsewardj
96065ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj   if (vex_traceflags) {
96165ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj      /* Print the expansion ratio for this SB. */
96265ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj      j = 0; /* total guest bytes */
96365ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj      for (i = 0; i < vta->guest_extents->n_used; i++) {
96465ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj         j += vta->guest_extents->len[i];
96565ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj      }
96665ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj      if (1) vex_printf("VexExpansionRatio %d %d   %d :10\n\n",
96765ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj                        j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
96865ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj   }
96965ea17e33e244e3615a6e0d9c9a388a12d758f06sewardj
970f48ac19a67a98af44fe452c8c2be4192ac94b62dsewardj   vex_traceflags = 0;
971bc161a407b3cbd722821812afb8fb47420ae538fsewardj   res.status = VexTransOK;
972bc161a407b3cbd722821812afb8fb47420ae538fsewardj   return res;
97335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj}
97435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
97535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
976c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* --------- Chain/Unchain XDirects. --------- */
977c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
9787d6f81de12e6d8deb3e119ab318f361d97a10a65florianVexInvalRange LibVEX_Chain ( VexArch     arch_host,
9797d6f81de12e6d8deb3e119ab318f361d97a10a65florian                             VexEndness  endness_host,
9807d6f81de12e6d8deb3e119ab318f361d97a10a65florian                             void*       place_to_chain,
9817d6f81de12e6d8deb3e119ab318f361d97a10a65florian                             const void* disp_cp_chain_me_EXPECTED,
9827d6f81de12e6d8deb3e119ab318f361d97a10a65florian                             const void* place_to_jump_to )
983c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{
984c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   switch (arch_host) {
985c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchX86:
9867d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return chainXDirect_X86(endness_host,
9877d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 place_to_chain,
9887d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 disp_cp_chain_me_EXPECTED,
9897d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 place_to_jump_to);
990c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchAMD64:
9917d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return chainXDirect_AMD64(endness_host,
9927d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_chain,
9937d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   disp_cp_chain_me_EXPECTED,
9947d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_jump_to);
995c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchARM:
9967d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return chainXDirect_ARM(endness_host,
9977d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 place_to_chain,
9987d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 disp_cp_chain_me_EXPECTED,
9997d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 place_to_jump_to);
1000bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      case VexArchARM64:
10017d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return chainXDirect_ARM64(endness_host,
10027d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_chain,
10037d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   disp_cp_chain_me_EXPECTED,
10047d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_jump_to);
10058844a6329d275814456e3a2a5a7bffac75da0957florian      case VexArchS390X:
10067d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return chainXDirect_S390(endness_host,
10077d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  place_to_chain,
10087d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  disp_cp_chain_me_EXPECTED,
10097d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  place_to_jump_to);
10103dee849ec7c38746749065e67dc53b75daa7617dsewardj      case VexArchPPC32:
10119b76916dcc1628e133d57db001563429c6e3a590sewardj         return chainXDirect_PPC(endness_host,
10129b76916dcc1628e133d57db001563429c6e3a590sewardj                                 place_to_chain,
10133dee849ec7c38746749065e67dc53b75daa7617dsewardj                                 disp_cp_chain_me_EXPECTED,
10143dee849ec7c38746749065e67dc53b75daa7617dsewardj                                 place_to_jump_to, False/*!mode64*/);
1015f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj      case VexArchPPC64:
10169b76916dcc1628e133d57db001563429c6e3a590sewardj         return chainXDirect_PPC(endness_host,
10179b76916dcc1628e133d57db001563429c6e3a590sewardj                                 place_to_chain,
1018f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj                                 disp_cp_chain_me_EXPECTED,
1019f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj                                 place_to_jump_to, True/*mode64*/);
1020d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:
10219b76916dcc1628e133d57db001563429c6e3a590sewardj         return chainXDirect_MIPS(endness_host,
10229b76916dcc1628e133d57db001563429c6e3a590sewardj                                  place_to_chain,
1023d0e5fe765fb79e5495206f8d0969133178b871f2sewardj                                  disp_cp_chain_me_EXPECTED,
1024d0e5fe765fb79e5495206f8d0969133178b871f2sewardj                                  place_to_jump_to, False/*!mode64*/);
1025b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:
10269b76916dcc1628e133d57db001563429c6e3a590sewardj         return chainXDirect_MIPS(endness_host,
10279b76916dcc1628e133d57db001563429c6e3a590sewardj                                  place_to_chain,
1028b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                  disp_cp_chain_me_EXPECTED,
1029b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                  place_to_jump_to, True/*!mode64*/);
1030c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      default:
1031c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(0);
1032c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
1033c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj}
1034c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
10357d6f81de12e6d8deb3e119ab318f361d97a10a65florianVexInvalRange LibVEX_UnChain ( VexArch     arch_host,
10367d6f81de12e6d8deb3e119ab318f361d97a10a65florian                               VexEndness  endness_host,
10377d6f81de12e6d8deb3e119ab318f361d97a10a65florian                               void*       place_to_unchain,
10387d6f81de12e6d8deb3e119ab318f361d97a10a65florian                               const void* place_to_jump_to_EXPECTED,
10397d6f81de12e6d8deb3e119ab318f361d97a10a65florian                               const void* disp_cp_chain_me )
1040c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{
1041c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   switch (arch_host) {
1042c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchX86:
10437d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return unchainXDirect_X86(endness_host,
10447d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_unchain,
10457d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_jump_to_EXPECTED,
10467d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   disp_cp_chain_me);
1047c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchAMD64:
10487d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return unchainXDirect_AMD64(endness_host,
10497d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     place_to_unchain,
10507d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     place_to_jump_to_EXPECTED,
10517d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     disp_cp_chain_me);
1052c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchARM:
10537d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return unchainXDirect_ARM(endness_host,
10547d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_unchain,
10557d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   place_to_jump_to_EXPECTED,
10567d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   disp_cp_chain_me);
1057c6acaa420e6f1c60e1d46f52c1e9b79c0490ce09sewardj      case VexArchARM64:
10587d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return unchainXDirect_ARM64(endness_host,
10597d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     place_to_unchain,
10607d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     place_to_jump_to_EXPECTED,
10617d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                     disp_cp_chain_me);
10628844a6329d275814456e3a2a5a7bffac75da0957florian      case VexArchS390X:
10637d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return unchainXDirect_S390(endness_host,
10647d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    place_to_unchain,
10657d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    place_to_jump_to_EXPECTED,
10667d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    disp_cp_chain_me);
10673dee849ec7c38746749065e67dc53b75daa7617dsewardj      case VexArchPPC32:
10689b76916dcc1628e133d57db001563429c6e3a590sewardj         return unchainXDirect_PPC(endness_host,
10699b76916dcc1628e133d57db001563429c6e3a590sewardj                                   place_to_unchain,
10703dee849ec7c38746749065e67dc53b75daa7617dsewardj                                   place_to_jump_to_EXPECTED,
10713dee849ec7c38746749065e67dc53b75daa7617dsewardj                                   disp_cp_chain_me, False/*!mode64*/);
1072f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj      case VexArchPPC64:
10739b76916dcc1628e133d57db001563429c6e3a590sewardj         return unchainXDirect_PPC(endness_host,
10749b76916dcc1628e133d57db001563429c6e3a590sewardj                                   place_to_unchain,
1075f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj                                   place_to_jump_to_EXPECTED,
1076f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj                                   disp_cp_chain_me, True/*mode64*/);
1077d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:
10789b76916dcc1628e133d57db001563429c6e3a590sewardj         return unchainXDirect_MIPS(endness_host,
10799b76916dcc1628e133d57db001563429c6e3a590sewardj                                    place_to_unchain,
1080b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                    place_to_jump_to_EXPECTED,
1081b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                    disp_cp_chain_me, False/*!mode64*/);
1082b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:
10839b76916dcc1628e133d57db001563429c6e3a590sewardj         return unchainXDirect_MIPS(endness_host,
10849b76916dcc1628e133d57db001563429c6e3a590sewardj                                    place_to_unchain,
1085b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                    place_to_jump_to_EXPECTED,
1086b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                    disp_cp_chain_me, True/*!mode64*/);
1087c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      default:
1088c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(0);
1089c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
1090c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj}
1091c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
10929b76916dcc1628e133d57db001563429c6e3a590sewardjInt LibVEX_evCheckSzB ( VexArch    arch_host,
10939b76916dcc1628e133d57db001563429c6e3a590sewardj                        VexEndness endness_host )
1094c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{
1095c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1096c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   if (UNLIKELY(cached == 0)) {
1097c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      switch (arch_host) {
1098c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         case VexArchX86:
10999b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_X86(endness_host); break;
1100c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         case VexArchAMD64:
11019b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_AMD64(endness_host); break;
1102c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         case VexArchARM:
11039b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_ARM(endness_host); break;
1104bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj         case VexArchARM64:
11059b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_ARM64(endness_host); break;
11068844a6329d275814456e3a2a5a7bffac75da0957florian         case VexArchS390X:
11079b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_S390(endness_host); break;
11083dee849ec7c38746749065e67dc53b75daa7617dsewardj         case VexArchPPC32:
1109f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj         case VexArchPPC64:
11109b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_PPC(endness_host); break;
1111d0e5fe765fb79e5495206f8d0969133178b871f2sewardj         case VexArchMIPS32:
1112b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         case VexArchMIPS64:
11139b76916dcc1628e133d57db001563429c6e3a590sewardj            cached = evCheckSzB_MIPS(endness_host); break;
1114c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         default:
1115c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            vassert(0);
1116c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      }
1117c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
1118c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   return cached;
1119c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj}
1120c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
11219b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange LibVEX_PatchProfInc ( VexArch    arch_host,
11229b76916dcc1628e133d57db001563429c6e3a590sewardj                                    VexEndness endness_host,
11239b76916dcc1628e133d57db001563429c6e3a590sewardj                                    void*      place_to_patch,
11247d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    const ULong* location_of_counter )
1125c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{
1126c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   switch (arch_host) {
1127c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchX86:
11287d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return patchProfInc_X86(endness_host, place_to_patch,
11297d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 location_of_counter);
1130c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchAMD64:
11317d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return patchProfInc_AMD64(endness_host, place_to_patch,
11327d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   location_of_counter);
1133c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      case VexArchARM:
11347d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return patchProfInc_ARM(endness_host, place_to_patch,
11357d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                 location_of_counter);
11360ad37a9e5936c15460f067bee8948b900cdab036sewardj      case VexArchARM64:
11377d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return patchProfInc_ARM64(endness_host, place_to_patch,
11387d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                   location_of_counter);
11398844a6329d275814456e3a2a5a7bffac75da0957florian      case VexArchS390X:
11407d6f81de12e6d8deb3e119ab318f361d97a10a65florian         return patchProfInc_S390(endness_host, place_to_patch,
11417d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  location_of_counter);
11423dee849ec7c38746749065e67dc53b75daa7617dsewardj      case VexArchPPC32:
11439b76916dcc1628e133d57db001563429c6e3a590sewardj         return patchProfInc_PPC(endness_host, place_to_patch,
11443dee849ec7c38746749065e67dc53b75daa7617dsewardj                                 location_of_counter, False/*!mode64*/);
1145f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj      case VexArchPPC64:
11469b76916dcc1628e133d57db001563429c6e3a590sewardj         return patchProfInc_PPC(endness_host, place_to_patch,
1147f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj                                 location_of_counter, True/*mode64*/);
1148d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:
11499b76916dcc1628e133d57db001563429c6e3a590sewardj         return patchProfInc_MIPS(endness_host, place_to_patch,
1150d0e5fe765fb79e5495206f8d0969133178b871f2sewardj                                  location_of_counter, False/*!mode64*/);
1151b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:
11529b76916dcc1628e133d57db001563429c6e3a590sewardj         return patchProfInc_MIPS(endness_host, place_to_patch,
1153b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                  location_of_counter, True/*!mode64*/);
1154c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      default:
1155c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vassert(0);
1156c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
1157c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj}
1158c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
1159c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
1160893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* --------- Emulation warnings. --------- */
1161893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj
11621ff4756e1731485e6bf3cd96717cd8398daec1f2florianconst HChar* LibVEX_EmNote_string ( VexEmNote ew )
1163893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{
1164893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   switch (ew) {
11656ef84bed9bb3af22060eb1759788034602bbcc88florian     case EmNote_NONE:
1166893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "none";
1167893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_x87exns:
1168893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "Unmasking x87 FP exceptions";
1169893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_x87precision:
1170893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj        return "Selection of non-80-bit x87 FP precision";
1171893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     case EmWarn_X86_sseExns:
11725edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Unmasking SSE FP exceptions";
11735edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj     case EmWarn_X86_fz:
11745edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
11755edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj     case EmWarn_X86_daz:
11765edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj        return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
11776d26984a0df6a7d20b658bac6edf869eb872cca3sewardj     case EmWarn_X86_acFlag:
11786d26984a0df6a7d20b658bac6edf869eb872cca3sewardj        return "Setting %eflags.ac (setting noted but ignored)";
11799dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPCexns:
11809dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "Unmasking PPC32/64 FP exceptions";
11819dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPC64_redir_overflow:
11829dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "PPC64 function redirection stack overflow";
11839dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj     case EmWarn_PPC64_redir_underflow:
11849dd9cf1cb0b6915fc2f7dff642455ca41e162649sewardj        return "PPC64 function redirection stack underflow";
11854b8efad55c1c7f9941b605b2f171b71a094c1f33florian     case EmWarn_S390X_fpext_rounding:
11864b8efad55c1c7f9941b605b2f171b71a094c1f33florian        return "The specified rounding mode cannot be supported. That\n"
11872a4de0bb56f33835bab59c0e483acc8410baed98florian               "  feature requires the floating point extension facility\n"
11884b8efad55c1c7f9941b605b2f171b71a094c1f33florian               "  which is not available on this host. Continuing using\n"
11894b8efad55c1c7f9941b605b2f171b71a094c1f33florian               "  the rounding mode from FPC. Results may differ!";
1190f0fa1be734f2bcbc20ac638cc61dc149deb8b644florian     case EmWarn_S390X_invalid_rounding:
1191f0fa1be734f2bcbc20ac638cc61dc149deb8b644florian        return "The specified rounding mode is invalid.\n"
1192f0fa1be734f2bcbc20ac638cc61dc149deb8b644florian               "  Continuing using 'round to nearest'. Results may differ!";
1193e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian     case EmFail_S390X_stfle:
11944e0083ee421db6d2900eaa00dc70c86ee829e28bflorian        return "Instruction stfle is not supported on this host";
1195e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian     case EmFail_S390X_stckf:
1196c5c669b461e3cbcd89d6bdbb4ecb9bcfd2ad23f5florian        return "Instruction stckf is not supported on this host";
1197e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian     case EmFail_S390X_ecag:
11988c88cb6ae821021e1e00be18f5a8bea3c557080aflorian        return "Instruction ecag is not supported on this host";
1199ad00ea9f40f930d98bb2d278291a6c4c6636d6d6florian     case EmFail_S390X_pfpo:
1200ad00ea9f40f930d98bb2d278291a6c4c6636d6d6florian        return "Instruction pfpo is not supported on this host";
1201e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian     case EmFail_S390X_fpext:
1202e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian        return "Encountered an instruction that requires the floating "
1203e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian               "point extension facility.\n"
1204e75dafa8ecce0a5cc64cf4b91b32b192250894dcflorian               "  That facility is not available on this host";
120578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian     case EmFail_S390X_invalid_PFPO_rounding_mode:
12062a4de0bb56f33835bab59c0e483acc8410baed98florian        return "The rounding mode in GPR 0 for the PFPO instruction"
120778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian               " is invalid";
120878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian     case EmFail_S390X_invalid_PFPO_function:
12092a4de0bb56f33835bab59c0e483acc8410baed98florian        return "The function code in GPR 0 for the PFPO instruction"
121078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian               " is invalid";
1211893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj     default:
12126ef84bed9bb3af22060eb1759788034602bbcc88florian        vpanic("LibVEX_EmNote_string: unknown warning");
1213893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj   }
1214893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj}
121535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj
12165117ce116f47141cb23d1b49cc826e19323add97sewardj/* ------------------ Arch/HwCaps stuff. ------------------ */
1217bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
1218bef170b7e84713d1e2181b9204d9415d29de3d65sewardjconst HChar* LibVEX_ppVexArch ( VexArch arch )
1219bef170b7e84713d1e2181b9204d9415d29de3d65sewardj{
1220bef170b7e84713d1e2181b9204d9415d29de3d65sewardj   switch (arch) {
1221bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArch_INVALID: return "INVALID";
1222bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchX86:      return "X86";
1223bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchAMD64:    return "AMD64";
1224bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      case VexArchARM:      return "ARM";
1225bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      case VexArchARM64:    return "ARM64";
12260ec57c595719a395e71b48792a4d62c5b896b6d3sewardj      case VexArchPPC32:    return "PPC32";
1227f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case VexArchPPC64:    return "PPC64";
12282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      case VexArchS390X:    return "S390X";
1229d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32:   return "MIPS32";
1230b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64:   return "MIPS64";
1231bef170b7e84713d1e2181b9204d9415d29de3d65sewardj      default:              return "VexArch???";
1232bef170b7e84713d1e2181b9204d9415d29de3d65sewardj   }
1233bef170b7e84713d1e2181b9204d9415d29de3d65sewardj}
1234bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
12359b76916dcc1628e133d57db001563429c6e3a590sewardjconst HChar* LibVEX_ppVexEndness ( VexEndness endness )
12369b76916dcc1628e133d57db001563429c6e3a590sewardj{
12379b76916dcc1628e133d57db001563429c6e3a590sewardj   switch (endness) {
12389b76916dcc1628e133d57db001563429c6e3a590sewardj      case VexEndness_INVALID: return "INVALID";
12399b76916dcc1628e133d57db001563429c6e3a590sewardj      case VexEndnessLE:       return "LittleEndian";
12409b76916dcc1628e133d57db001563429c6e3a590sewardj      case VexEndnessBE:       return "BigEndian";
12419b76916dcc1628e133d57db001563429c6e3a590sewardj      default:                 return "VexEndness???";
12429b76916dcc1628e133d57db001563429c6e3a590sewardj   }
12439b76916dcc1628e133d57db001563429c6e3a590sewardj}
12449b76916dcc1628e133d57db001563429c6e3a590sewardj
12455117ce116f47141cb23d1b49cc826e19323add97sewardjconst HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
1246bef170b7e84713d1e2181b9204d9415d29de3d65sewardj{
124755085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar* str = show_hwcaps(arch,hwcaps);
12485117ce116f47141cb23d1b49cc826e19323add97sewardj   return str ? str : "INVALID";
1249bef170b7e84713d1e2181b9204d9415d29de3d65sewardj}
1250bef170b7e84713d1e2181b9204d9415d29de3d65sewardj
12515117ce116f47141cb23d1b49cc826e19323add97sewardj
125227e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj/* Write default settings info *vai. */
125327e1dd6317760f3222f8a82185fa0e8ba138c85bsewardjvoid LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
125427e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj{
125565902992da28822e4753594c7b72f7cb177fe3a6sewardj   vex_bzero(vai, sizeof(*vai));
12569b76916dcc1628e133d57db001563429c6e3a590sewardj   vai->hwcaps                  = 0;
12579b76916dcc1628e133d57db001563429c6e3a590sewardj   vai->endness                 = VexEndness_INVALID;
12589b76916dcc1628e133d57db001563429c6e3a590sewardj   vai->ppc_icache_line_szB     = 0;
12599b76916dcc1628e133d57db001563429c6e3a590sewardj   vai->ppc_dcbz_szB            = 0;
12609b76916dcc1628e133d57db001563429c6e3a590sewardj   vai->ppc_dcbzl_szB           = 0;
126165902992da28822e4753594c7b72f7cb177fe3a6sewardj   vai->arm64_dMinLine_lg2_szB  = 0;
126265902992da28822e4753594c7b72f7cb177fe3a6sewardj   vai->arm64_iMinLine_lg2_szB  = 0;
1263f192a391bc556ff6e074ec055df5b883895e5b52florian   vai->hwcache_info.num_levels = 0;
1264f192a391bc556ff6e074ec055df5b883895e5b52florian   vai->hwcache_info.num_caches = 0;
126565902992da28822e4753594c7b72f7cb177fe3a6sewardj   vai->hwcache_info.caches     = NULL;
1266f192a391bc556ff6e074ec055df5b883895e5b52florian   vai->hwcache_info.icaches_maintain_coherence = True;  // whatever
126727e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj}
126827e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj
1269dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Write default settings info *vbi. */
1270dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjvoid LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
1271aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj{
127265902992da28822e4753594c7b72f7cb177fe3a6sewardj   vex_bzero(vbi, sizeof(*vbi));
1273dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   vbi->guest_stack_redzone_size       = 0;
12742e28ac4ec6d9bc40e2e1ec35d779e38a717dcba7sewardj   vbi->guest_amd64_assume_fs_is_zero  = False;
12752e28ac4ec6d9bc40e2e1ec35d779e38a717dcba7sewardj   vbi->guest_amd64_assume_gs_is_0x60  = False;
1276dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   vbi->guest_ppc_zap_RZ_at_blr        = False;
1277dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   vbi->guest_ppc_zap_RZ_at_bl         = NULL;
1278dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   vbi->host_ppc_calls_use_fndescrs    = False;
1279aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj}
1280aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj
128127e1dd6317760f3222f8a82185fa0e8ba138c85bsewardj
12825117ce116f47141cb23d1b49cc826e19323add97sewardj/* Return a string showing the hwcaps in a nice way.  The string will
12835117ce116f47141cb23d1b49cc826e19323add97sewardj   be NULL for invalid combinations of flags, so these functions also
12845117ce116f47141cb23d1b49cc826e19323add97sewardj   serve as a way to validate hwcaps values. */
12855117ce116f47141cb23d1b49cc826e19323add97sewardj
128655085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_x86 ( UInt hwcaps )
12875117ce116f47141cb23d1b49cc826e19323add97sewardj{
12886c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw   /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
1289536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj   switch (hwcaps) {
1290536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj      case 0:
1291536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj         return "x86-sse0";
12926c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT:
12936c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext";
12946c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
12956c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext-sse1";
12966c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
12976c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext-sse1-sse2";
12986c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1299536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj           | VEX_HWCAPS_X86_LZCNT:
13006c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext-sse1-sse2-lzcnt";
13016c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1302536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj           | VEX_HWCAPS_X86_SSE3:
13036c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext-sse1-sse2-sse3";
13046c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1305536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj           | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
13066c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw         return "x86-mmxext-sse1-sse2-sse3-lzcnt";
1307536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj      default:
1308536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj         return NULL;
1309536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj   }
13105117ce116f47141cb23d1b49cc826e19323add97sewardj}
13115117ce116f47141cb23d1b49cc826e19323add97sewardj
131255085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_amd64 ( UInt hwcaps )
13135117ce116f47141cb23d1b49cc826e19323add97sewardj{
1314e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj   /* SSE3 and CX16 are orthogonal and > baseline, although we really
1315e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      don't expect to come across anything which can do SSE3 but can't
1316536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj      do CX16.  Still, we can handle that case.  LZCNT is similarly
1317818c730f624828ef2d5532e32e952924094b699esewardj      orthogonal. */
1318818c730f624828ef2d5532e32e952924094b699esewardj
1319818c730f624828ef2d5532e32e952924094b699esewardj   /* Throw out obviously stupid cases: */
1320818c730f624828ef2d5532e32e952924094b699esewardj   Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1321818c730f624828ef2d5532e32e952924094b699esewardj   Bool have_avx  = (hwcaps & VEX_HWCAPS_AMD64_AVX)  != 0;
1322cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   Bool have_bmi  = (hwcaps & VEX_HWCAPS_AMD64_BMI)  != 0;
1323cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1324cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   /* AVX without SSE3 */
1325818c730f624828ef2d5532e32e952924094b699esewardj   if (have_avx && !have_sse3)
1326818c730f624828ef2d5532e32e952924094b699esewardj      return NULL;
1327cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   /* AVX2 or BMI without AVX */
1328cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   if ((have_avx2 || have_bmi) && !have_avx)
1329cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      return NULL;
1330818c730f624828ef2d5532e32e952924094b699esewardj
1331818c730f624828ef2d5532e32e952924094b699esewardj   /* This isn't threadsafe.  We might need to fix it at some point. */
1332818c730f624828ef2d5532e32e952924094b699esewardj   static HChar buf[100] = { 0 };
1333818c730f624828ef2d5532e32e952924094b699esewardj   if (buf[0] != 0) return buf; /* already constructed */
1334818c730f624828ef2d5532e32e952924094b699esewardj
1335818c730f624828ef2d5532e32e952924094b699esewardj   vex_bzero(buf, sizeof(buf));
1336818c730f624828ef2d5532e32e952924094b699esewardj
1337818c730f624828ef2d5532e32e952924094b699esewardj   HChar* p = &buf[0];
1338818c730f624828ef2d5532e32e952924094b699esewardj
1339818c730f624828ef2d5532e32e952924094b699esewardj   p = p + vex_sprintf(p, "%s", "amd64");
1340818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps == 0) {
1341818c730f624828ef2d5532e32e952924094b699esewardj      /* special-case the baseline case */
1342818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-sse2");
1343818c730f624828ef2d5532e32e952924094b699esewardj      goto out;
1344818c730f624828ef2d5532e32e952924094b699esewardj   }
1345818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1346818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-cx16");
1347818c730f624828ef2d5532e32e952924094b699esewardj   }
1348818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1349818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-lzcnt");
1350818c730f624828ef2d5532e32e952924094b699esewardj   }
1351818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1352818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-rdtscp");
1353536fbabcc3770f42bb7370efd75e8e30e9a841c8sewardj   }
1354818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1355818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-sse3");
1356818c730f624828ef2d5532e32e952924094b699esewardj   }
1357818c730f624828ef2d5532e32e952924094b699esewardj   if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1358818c730f624828ef2d5532e32e952924094b699esewardj      p = p + vex_sprintf(p, "%s", "-avx");
1359818c730f624828ef2d5532e32e952924094b699esewardj   }
1360cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1361cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      p = p + vex_sprintf(p, "%s", "-avx2");
1362cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   }
1363cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1364cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj      p = p + vex_sprintf(p, "%s", "-bmi");
1365cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj   }
1366818c730f624828ef2d5532e32e952924094b699esewardj
1367818c730f624828ef2d5532e32e952924094b699esewardj  out:
1368818c730f624828ef2d5532e32e952924094b699esewardj   vassert(buf[sizeof(buf)-1] == 0);
1369818c730f624828ef2d5532e32e952924094b699esewardj   return buf;
13705117ce116f47141cb23d1b49cc826e19323add97sewardj}
13715117ce116f47141cb23d1b49cc826e19323add97sewardj
137255085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
13735117ce116f47141cb23d1b49cc826e19323add97sewardj{
13745117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic with complications.  Basically V > F > baseline,
13755117ce116f47141cb23d1b49cc826e19323add97sewardj      but once you have F then you can have FX or GX too. */
13765117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt F  = VEX_HWCAPS_PPC32_F;
13775117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt V  = VEX_HWCAPS_PPC32_V;
13785117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt FX = VEX_HWCAPS_PPC32_FX;
13795117ce116f47141cb23d1b49cc826e19323add97sewardj   const UInt GX = VEX_HWCAPS_PPC32_GX;
138066d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj   const UInt VX = VEX_HWCAPS_PPC32_VX;
1381c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   const UInt DFP = VEX_HWCAPS_PPC32_DFP;
13820c74bb5aa3240f693df0568d578baabf0c376dc4carll   const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
13835117ce116f47141cb23d1b49cc826e19323add97sewardj         UInt c  = hwcaps;
13845117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == 0)           return "ppc32-int";
13855117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == F)           return "ppc32-int-flt";
13865117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|FX))      return "ppc32-int-flt-FX";
13875117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|GX))      return "ppc32-int-flt-GX";
13885117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|FX|GX))   return "ppc32-int-flt-FX-GX";
13895117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V))       return "ppc32-int-flt-vmx";
13905117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|FX))    return "ppc32-int-flt-vmx-FX";
13915117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|GX))    return "ppc32-int-flt-vmx-GX";
13925117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
1393c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   if (c == (F|V|FX|GX|DFP))    return "ppc32-int-flt-vmx-FX-GX-DFP";
1394c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
13950c74bb5aa3240f693df0568d578baabf0c376dc4carll   if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
13960c74bb5aa3240f693df0568d578baabf0c376dc4carll      return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
13970c74bb5aa3240f693df0568d578baabf0c376dc4carll
13985117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
13995117ce116f47141cb23d1b49cc826e19323add97sewardj}
14005117ce116f47141cb23d1b49cc826e19323add97sewardj
140155085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
14025117ce116f47141cb23d1b49cc826e19323add97sewardj{
14035117ce116f47141cb23d1b49cc826e19323add97sewardj   /* Monotonic with complications.  Basically V > baseline(==F),
14045117ce116f47141cb23d1b49cc826e19323add97sewardj      but once you have F then you can have FX or GX too. */
14053fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt V  = VEX_HWCAPS_PPC64_V;
14063fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt FX = VEX_HWCAPS_PPC64_FX;
14073fd3967db856eb90b2030ebeb42b685d45bc3276sewardj   const UInt GX = VEX_HWCAPS_PPC64_GX;
140866d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj   const UInt VX = VEX_HWCAPS_PPC64_VX;
1409c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   const UInt DFP = VEX_HWCAPS_PPC64_DFP;
14100c74bb5aa3240f693df0568d578baabf0c376dc4carll   const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
14115117ce116f47141cb23d1b49cc826e19323add97sewardj         UInt c  = hwcaps;
14125117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == 0)         return "ppc64-int-flt";
14135117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == FX)        return "ppc64-int-flt-FX";
14145117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == GX)        return "ppc64-int-flt-GX";
14155117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (FX|GX))   return "ppc64-int-flt-FX-GX";
14165117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == V)         return "ppc64-int-flt-vmx";
14175117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|FX))    return "ppc64-int-flt-vmx-FX";
14185117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|GX))    return "ppc64-int-flt-vmx-GX";
14195117ce116f47141cb23d1b49cc826e19323add97sewardj   if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
1420c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   if (c == (V|FX|GX|DFP))    return "ppc64-int-flt-vmx-FX-GX-DFP";
1421c66d6fa5d9397f167b162483cf3419051cc01a80sewardj   if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
14220c74bb5aa3240f693df0568d578baabf0c376dc4carll   if (c == (V|FX|GX|VX|DFP|ISA2_07))
14230c74bb5aa3240f693df0568d578baabf0c376dc4carll      return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
14245117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
14255117ce116f47141cb23d1b49cc826e19323add97sewardj}
14265117ce116f47141cb23d1b49cc826e19323add97sewardj
142755085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_arm ( UInt hwcaps )
14285117ce116f47141cb23d1b49cc826e19323add97sewardj{
1429ec0d9a028955060c5216341c6fc37400ec0cb4besewardj   Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1430ec0d9a028955060c5216341c6fc37400ec0cb4besewardj   Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1431ec0d9a028955060c5216341c6fc37400ec0cb4besewardj               VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1432ec0d9a028955060c5216341c6fc37400ec0cb4besewardj   switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1433ec0d9a028955060c5216341c6fc37400ec0cb4besewardj      case 5:
1434ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         if (N)
1435ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return NULL;
1436ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         if (vfp)
1437ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return "ARMv5-vfp";
1438ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         else
1439ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return "ARMv5";
1440ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         return NULL;
1441ec0d9a028955060c5216341c6fc37400ec0cb4besewardj      case 6:
1442ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         if (N)
1443ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return NULL;
1444ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         if (vfp)
1445ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return "ARMv6-vfp";
1446ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         else
1447ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            return "ARMv6";
1448ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         return NULL;
1449ec0d9a028955060c5216341c6fc37400ec0cb4besewardj      case 7:
1450ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         if (vfp) {
1451ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            if (N)
1452ec0d9a028955060c5216341c6fc37400ec0cb4besewardj               return "ARMv7-vfp-neon";
1453ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            else
1454ec0d9a028955060c5216341c6fc37400ec0cb4besewardj               return "ARMv7-vfp";
1455ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         } else {
1456ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            if (N)
1457ec0d9a028955060c5216341c6fc37400ec0cb4besewardj               return "ARMv7-neon";
1458ec0d9a028955060c5216341c6fc37400ec0cb4besewardj            else
1459ec0d9a028955060c5216341c6fc37400ec0cb4besewardj               return "ARMv7";
1460ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         }
1461ec0d9a028955060c5216341c6fc37400ec0cb4besewardj      default:
1462ec0d9a028955060c5216341c6fc37400ec0cb4besewardj         return NULL;
1463ec0d9a028955060c5216341c6fc37400ec0cb4besewardj   }
14645117ce116f47141cb23d1b49cc826e19323add97sewardj   return NULL;
14655117ce116f47141cb23d1b49cc826e19323add97sewardj}
14665117ce116f47141cb23d1b49cc826e19323add97sewardj
1467bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardjstatic const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1468bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj{
1469bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj   /* Since there are no variants, just insist that hwcaps is zero,
1470bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      and declare it invalid otherwise. */
1471bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj  if (hwcaps == 0)
1472bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj     return "baseline";
1473bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj  return NULL;
1474bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj}
1475bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj
147655085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_s390x ( UInt hwcaps )
14772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{
1478d07b8566ab17faf70748cfce1304699f1d15c34esewardj   static const HChar prefix[] = "s390x";
14799061eb34b539df910f64354e8f3495aad47e8891florian   static const struct {
14809061eb34b539df910f64354e8f3495aad47e8891florian      UInt  hwcaps_bit;
14819061eb34b539df910f64354e8f3495aad47e8891florian      HChar name[6];
14829061eb34b539df910f64354e8f3495aad47e8891florian   } hwcaps_list[] = {
14839061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_LDISP, "ldisp" },
14849061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_EIMM,  "eimm" },
14859061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_GIE,   "gie" },
14869061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_DFP,   "dfp" },
14879061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_FGX,   "fgx" },
14889061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_STFLE, "stfle" },
14899061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_ETF2,  "etf2" },
14909061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_ETF3,  "etf3" },
14919061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_STCKF, "stckf" },
14929061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_FPEXT, "fpext" },
14939061eb34b539df910f64354e8f3495aad47e8891florian      { VEX_HWCAPS_S390X_LSC,   "lsc" },
149478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian      { VEX_HWCAPS_S390X_PFPO,  "pfpo" },
1495d07b8566ab17faf70748cfce1304699f1d15c34esewardj   };
14969061eb34b539df910f64354e8f3495aad47e8891florian#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
14979061eb34b539df910f64354e8f3495aad47e8891florian   static HChar buf[sizeof prefix +
14989061eb34b539df910f64354e8f3495aad47e8891florian                    NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
14999061eb34b539df910f64354e8f3495aad47e8891florian                    1];  // '\0'
15009061eb34b539df910f64354e8f3495aad47e8891florian   HChar *p;
15019061eb34b539df910f64354e8f3495aad47e8891florian   UInt i;
1502d07b8566ab17faf70748cfce1304699f1d15c34esewardj
1503d07b8566ab17faf70748cfce1304699f1d15c34esewardj   if (buf[0] != '\0') return buf;  /* already constructed */
15042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
1505652b56aecd7af6012e82801557b3833f74b19b59sewardj   hwcaps = VEX_HWCAPS_S390X(hwcaps);
1506652b56aecd7af6012e82801557b3833f74b19b59sewardj
1507d07b8566ab17faf70748cfce1304699f1d15c34esewardj   p = buf + vex_sprintf(buf, "%s", prefix);
15089061eb34b539df910f64354e8f3495aad47e8891florian   for (i = 0 ; i < NUM_HWCAPS; ++i) {
15099061eb34b539df910f64354e8f3495aad47e8891florian      if (hwcaps & hwcaps_list[i].hwcaps_bit)
15109061eb34b539df910f64354e8f3495aad47e8891florian         p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
15119061eb34b539df910f64354e8f3495aad47e8891florian   }
1512d07b8566ab17faf70748cfce1304699f1d15c34esewardj
1513d07b8566ab17faf70748cfce1304699f1d15c34esewardj   /* If there are no facilities, add "zarch" */
1514d07b8566ab17faf70748cfce1304699f1d15c34esewardj   if (hwcaps == 0)
1515d07b8566ab17faf70748cfce1304699f1d15c34esewardj     vex_sprintf(p, "-%s", "zarch");
1516d07b8566ab17faf70748cfce1304699f1d15c34esewardj
1517d07b8566ab17faf70748cfce1304699f1d15c34esewardj   return buf;
15182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}
15192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
152055085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps_mips32 ( UInt hwcaps )
1521d0e5fe765fb79e5495206f8d0969133178b871f2sewardj{
1522c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   /* MIPS baseline. */
1523bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
1524c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      /* MIPS baseline with dspr2. */
1525bc7d6f46346df80207c8454b35055b04f16bc1adpetarj      if (VEX_MIPS_PROC_DSP2(hwcaps)) {
1526c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         return "MIPS-baseline-dspr2";
1527c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      }
1528c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      /* MIPS baseline with dsp. */
1529bc7d6f46346df80207c8454b35055b04f16bc1adpetarj      if (VEX_MIPS_PROC_DSP(hwcaps)) {
1530c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         return "MIPS-baseline-dsp";
1531c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      }
1532c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      return "MIPS-baseline";
1533c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   }
1534c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj
1535c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   /* Broadcom baseline. */
1536bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
1537c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      return "Broadcom-baseline";
1538c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   }
1539c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj
1540c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   /* Netlogic baseline. */
1541bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
1542c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj      return "Netlogic-baseline";
1543c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   }
1544c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj
1545bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   /* Cavium baseline. */
1546bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1547bc7d6f46346df80207c8454b35055b04f16bc1adpetarj      return "Cavium-baseline";
1548bc7d6f46346df80207c8454b35055b04f16bc1adpetarj   }
1549bc7d6f46346df80207c8454b35055b04f16bc1adpetarj
1550d0e5fe765fb79e5495206f8d0969133178b871f2sewardj   return NULL;
1551d0e5fe765fb79e5495206f8d0969133178b871f2sewardj}
1552d0e5fe765fb79e5495206f8d0969133178b871f2sewardj
1553b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjstatic const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1554b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
1555b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return "mips64-baseline";
1556b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
1557b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
15585117ce116f47141cb23d1b49cc826e19323add97sewardj/* ---- */
155955085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
15605117ce116f47141cb23d1b49cc826e19323add97sewardj{
15615117ce116f47141cb23d1b49cc826e19323add97sewardj   switch (arch) {
1562d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchX86:    return show_hwcaps_x86(hwcaps);
1563d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchAMD64:  return show_hwcaps_amd64(hwcaps);
1564d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchPPC32:  return show_hwcaps_ppc32(hwcaps);
1565d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchPPC64:  return show_hwcaps_ppc64(hwcaps);
1566d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchARM:    return show_hwcaps_arm(hwcaps);
1567bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj      case VexArchARM64:  return show_hwcaps_arm64(hwcaps);
1568d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchS390X:  return show_hwcaps_s390x(hwcaps);
1569d0e5fe765fb79e5495206f8d0969133178b871f2sewardj      case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
1570b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
15715117ce116f47141cb23d1b49cc826e19323add97sewardj      default: return NULL;
15725117ce116f47141cb23d1b49cc826e19323add97sewardj   }
15735117ce116f47141cb23d1b49cc826e19323add97sewardj}
15745117ce116f47141cb23d1b49cc826e19323add97sewardj
15755117ce116f47141cb23d1b49cc826e19323add97sewardjstatic Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
15765117ce116f47141cb23d1b49cc826e19323add97sewardj{
15775117ce116f47141cb23d1b49cc826e19323add97sewardj   return show_hwcaps(arch,hwcaps) != NULL;
15785117ce116f47141cb23d1b49cc826e19323add97sewardj}
15795117ce116f47141cb23d1b49cc826e19323add97sewardj
15805117ce116f47141cb23d1b49cc826e19323add97sewardj
158135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
1582cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                         main_main.c ---*/
158335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/
1584