1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin                                       main_main.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright (C) 2004-2013 OpenWorks LLP
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      info@open-works.net
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02110-1301, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Neither the names of the U.S. Department of Energy nor the
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   University of California nor the names of its contributors may be
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used to endorse or promote products derived from this software
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   without prior written permission.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h"
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_emnote.h"
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_x86.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_amd64.h"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_arm.h"
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_guest_arm64.h"
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_ppc32.h"
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_ppc64.h"
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_guest_s390x.h"
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "libvex_guest_mips32.h"
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_guest_mips64.h"
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_globals.h"
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_util.h"
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_generic_regs.h"
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "ir_opt.h"
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_x86_defs.h"
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_amd64_defs.h"
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_ppc_defs.h"
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_arm_defs.h"
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "host_arm64_defs.h"
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "host_s390_defs.h"
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "host_mips_defs.h"
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_generic_bb_to_IR.h"
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_x86_defs.h"
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_amd64_defs.h"
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_arm_defs.h"
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "guest_arm64_defs.h"
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_ppc_defs.h"
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "guest_s390_defs.h"
68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "guest_mips_defs.h"
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_generic_simd128.h"
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This file contains the top level interface to the library. */
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- fwds ... --------- */
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool   are_valid_hwcaps ( VexArch arch, UInt hwcaps );
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* --------- helpers --------- */
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((noinline))
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt udiv32 ( UInt x, UInt y ) { return x/y; }
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((noinline))
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic  Int sdiv32 (  Int x,  Int y ) { return x/y; }
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Initialise the library. --------- */
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Exported to library client. */
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
95eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vex_bzero(vcon, sizeof(*vcon));
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->iropt_verbosity            = 0;
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->iropt_level                = 2;
98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vcon->iropt_register_updates     = VexRegUpdUnwindregsAtMemAccess;
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->iropt_unroll_thresh        = 120;
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->guest_max_insns            = 60;
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->guest_chase_thresh         = 10;
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vcon->guest_chase_cond           = False;
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Exported to library client. */
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_Init (
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* failure exit function */
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __attribute__ ((noreturn))
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void (*failure_exit) ( void ),
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* logging output function */
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void (*log_bytes) ( HChar*, Int nbytes ),
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* debug paranoia level */
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int debuglevel,
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Are we supporting valgrind checking? */
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool valgrind_support,
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Control ... */
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*READONLY*/VexControl* vcon
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown)
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First off, do enough minimal setup so that the following
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assertions can fail in a sane fashion, if need be. */
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_failure_exit = failure_exit;
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_log_bytes    = log_bytes;
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now it's safe to check parameters for sanity. */
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!vex_initdone);
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(failure_exit);
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(log_bytes);
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(debuglevel >= 0);
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->iropt_verbosity >= 0);
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->iropt_level >= 0);
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->iropt_level <= 2);
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->iropt_unroll_thresh >= 0);
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->iropt_unroll_thresh <= 400);
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->guest_max_insns >= 1);
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->guest_max_insns <= 100);
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->guest_chase_thresh >= 0);
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vcon->guest_chase_cond == True
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           || vcon->guest_chase_cond == False);
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check that Vex has been built with sizes of basic types as
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stated in priv/libvex_basictypes.h.  Failure of any of these is
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a serious configuration error and should be corrected
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      immediately.  If any of these assertions fail you can fully
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      expect Vex not to work properly, if at all. */
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(1 == sizeof(UChar));
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(1 == sizeof(Char));
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(2 == sizeof(UShort));
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(2 == sizeof(Short));
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(4 == sizeof(UInt));
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(4 == sizeof(Int));
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(8 == sizeof(ULong));
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(8 == sizeof(Long));
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(4 == sizeof(Float));
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(8 == sizeof(Double));
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(1 == sizeof(Bool));
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(4 == sizeof(Addr32));
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(8 == sizeof(Addr64));
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(16 == sizeof(U128));
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(16 == sizeof(V128));
166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(32 == sizeof(U256));
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(sizeof(void*) == sizeof(int*));
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(sizeof(void*) == sizeof(HWord));
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(VEX_HOST_WORDSIZE == sizeof(void*));
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* These take a lot of space, so make sure we don't have
176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      any unnoticed size regressions. */
177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (VEX_HOST_WORDSIZE == 4) {
178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(sizeof(IRExpr) == 16);
179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(sizeof(IRStmt) == 20 /* x86 */
180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              || sizeof(IRStmt) == 24 /* arm */);
181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(sizeof(IRExpr) == 32);
183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(sizeof(IRStmt) == 32);
184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Check that signed integer division on the host rounds towards
187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      zero.  If not, h_calc_sdiv32_w_arm_semantics() won't work
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      correctly. */
189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* 100.0 / 7.0 == 14.2857 */
190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(udiv32(100, 7) == 14);
191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(sdiv32(100, 7) == 14);
192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(sdiv32(-100, 7) == -14); /* and not -15 */
193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(sdiv32(100, -7) == -14); /* ditto */
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Really start up .. */
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_debuglevel         = debuglevel;
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_valgrind_support   = valgrind_support;
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_control            = *vcon;
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_initdone           = True;
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexSetAllocMode ( VexAllocModeTEMP );
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Make a translation. --------- */
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Exported to library client. */
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* This the bundle of functions we need to do the back-end stuff
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (insn selection, reg-alloc, assembly) whilst being insulated
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      from the target instruction set. */
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HReg* available_real_regs;
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   n_available_real_regs;
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool         (*isMove)       ( HInstr*, HReg*, HReg* );
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*getRegUsage)  ( HRegUsage*, HInstr*, Bool );
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*mapRegs)      ( HRegRemap*, HInstr*, Bool );
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*genSpill)     ( HInstr**, HInstr**, HReg, Int, Bool );
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*genReload)    ( HInstr**, HInstr**, HReg, Int, Bool );
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HInstr*      (*directReload) ( HInstr*, HReg, Short );
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*ppInstr)      ( HInstr*, Bool );
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void         (*ppReg)        ( HReg );
224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   HInstrArray* (*iselSB)       ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  Int, Int, Bool, Bool, Addr64 );
226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Int          (*emit)         ( /*MB_MOD*/Bool*,
227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  UChar*, Int, HInstr*, Bool,
228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  void*, void*, void*, void* );
229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   IRExpr*      (*specHelper)   ( const HChar*, IRExpr**, IRStmt**, Int );
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool         (*preciseMemExnsFn) ( Int, Int );
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DisOneInstrFn disInstrFn;
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VexGuestLayout* guest_layout;
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool            host_is_bigendian = False;
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRSB*           irsb;
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HInstrArray*    vcode;
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HInstrArray*    rcode;
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int             i, j, k, out_used, guest_sizeB;
240eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   Int             offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Int             offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UChar           insn_bytes[128];
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRType          guest_word_type;
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRType          host_word_type;
245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool            mode64, chainingAllowed;
246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Addr64          max_ga;
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest_layout           = NULL;
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   available_real_regs    = NULL;
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n_available_real_regs  = 0;
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   isMove                 = NULL;
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   getRegUsage            = NULL;
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mapRegs                = NULL;
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   genSpill               = NULL;
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   genReload              = NULL;
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   directReload           = NULL;
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppInstr                = NULL;
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppReg                  = NULL;
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   iselSB                 = NULL;
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   emit                   = NULL;
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   specHelper             = NULL;
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   preciseMemExnsFn       = NULL;
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   disInstrFn             = NULL;
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest_word_type        = Ity_INVALID;
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   host_word_type         = Ity_INVALID;
266eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   offB_CMSTART           = 0;
267eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   offB_CMLEN             = 0;
268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   offB_GUEST_IP          = 0;
269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   szB_GUEST_IP           = 0;
270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   offB_HOST_EvC_COUNTER  = 0;
271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   offB_HOST_EvC_FAILADDR = 0;
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mode64                 = False;
273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   chainingAllowed        = False;
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_traceflags = vta->traceflags;
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vex_initdone);
278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(vta->needs_self_check  != NULL);
279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(vta->disp_cp_xassisted != NULL);
280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Both the chainers and the indir are either NULL or non-NULL. */
281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (vta->disp_cp_chain_me_to_slowEP        != NULL) {
282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(vta->disp_cp_xindir             != NULL);
284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      chainingAllowed = True;
285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(vta->disp_cp_xindir             == NULL);
288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexSetAllocModeTEMP_and_clear();
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First off, check that the guest and host insn sets
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      are supported. */
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (vta->arch_host) {
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchX86:
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mode64       = False;
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getAllocableRegs_X86 ( &n_available_real_regs,
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                &available_real_regs );
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         isMove       = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getRegUsage  = (void(*)(HRegUsage*,HInstr*, Bool))
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        getRegUsage_X86Instr;
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs      = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genSpill     = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        genSpill_X86;
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genReload    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        genReload_X86;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr      = (void(*)(HInstr*, Bool)) ppX86Instr;
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppReg        = (void(*)(HReg)) ppHRegX86;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         iselSB       = iselSB_X86;
314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit         = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        emit_X86Instr;
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_is_bigendian = False;
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_word_type    = Ity_I32;
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchAMD64:
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mode64      = True;
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getAllocableRegs_AMD64 ( &n_available_real_regs,
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  &available_real_regs );
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       getRegUsage_AMD64Instr;
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       genSpill_AMD64;
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       genReload_AMD64;
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr     = (void(*)(HInstr*, Bool)) ppAMD64Instr;
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppReg       = (void(*)(HReg)) ppHRegAMD64;
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         iselSB      = iselSB_AMD64;
337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       emit_AMD64Instr;
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_is_bigendian = False;
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_word_type    = Ity_I64;
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC32:
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mode64      = False;
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getAllocableRegs_PPC ( &n_available_real_regs,
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                &available_real_regs, mode64 );
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs     = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr     = (void(*)(HInstr*,Bool)) ppPPCInstr;
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppReg       = (void(*)(HReg)) ppHRegPPC;
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         iselSB      = iselSB_PPC;
357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       emit_PPCInstr;
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_is_bigendian = True;
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_word_type    = Ity_I32;
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC64:
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mode64      = True;
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getAllocableRegs_PPC ( &n_available_real_regs,
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                &available_real_regs, mode64 );
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr     = (void(*)(HInstr*, Bool)) ppPPCInstr;
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppReg       = (void(*)(HReg)) ppHRegPPC;
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         iselSB      = iselSB_PPC;
377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       emit_PPCInstr;
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_is_bigendian = True;
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_word_type    = Ity_I64;
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case VexArchS390X:
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         mode64      = True;
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         getAllocableRegs_S390 ( &n_available_real_regs,
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                 &available_real_regs, mode64 );
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ppInstr     = (void(*)(HInstr*, Bool)) ppS390Instr;
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ppReg       = (void(*)(HReg)) ppHRegS390;
396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         iselSB      = iselSB_S390;
397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*)) emit_S390Instr;
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         host_is_bigendian = True;
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         host_word_type    = Ity_I64;
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchARM:
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mode64      = False;
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getAllocableRegs_ARM ( &n_available_real_regs,
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                &available_real_regs );
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr     = (void(*)(HInstr*, Bool)) ppARMInstr;
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppReg       = (void(*)(HReg)) ppHRegARM;
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         iselSB      = iselSB_ARM;
416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       emit_ARMInstr;
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_is_bigendian = False;
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         host_word_type    = Ity_I32;
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         break;
423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:
425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         mode64      = True;
426436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         getAllocableRegs_ARM64 ( &n_available_real_regs,
427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                  &available_real_regs );
428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARM64Instr;
429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       getRegUsage_ARM64Instr;
431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool))
432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       mapRegs_ARM64Instr;
433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       genSpill_ARM64;
435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       genReload_ARM64;
437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppInstr     = (void(*)(HInstr*, Bool)) ppARM64Instr;
438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppReg       = (void(*)(HReg)) ppHRegARM64;
439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         iselSB      = iselSB_ARM64;
440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                               void*,void*,void*,void*))
442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       emit_ARM64Instr;
443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         host_is_bigendian = False;
444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         host_word_type    = Ity_I64;
445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:
449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mode64      = False;
450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         getAllocableRegs_MIPS ( &n_available_real_regs,
451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                &available_real_regs, mode64 );
452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppInstr     = (void(*)(HInstr*, Bool)) ppMIPSInstr;
458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppReg       = (void(*)(HReg)) ppHRegMIPS;
459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         iselSB      = iselSB_MIPS;
460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*,void*,void*,void*))
462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       emit_MIPSInstr;
463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        if defined(VKI_LITTLE_ENDIAN)
464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         host_is_bigendian = False;
465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        elif defined(VKI_BIG_ENDIAN)
466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         host_is_bigendian = True;
467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        endif
468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         host_word_type    = Ity_I32;
469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:
473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         mode64      = True;
474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         getAllocableRegs_MIPS ( &n_available_real_regs,
475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                 &available_real_regs, mode64 );
476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         isMove      = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         mapRegs     = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         genSpill    = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         genReload   = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppInstr     = (void(*)(HInstr*, Bool)) ppMIPSInstr;
482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppReg       = (void(*)(HReg)) ppHRegMIPS;
483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         iselSB      = iselSB_MIPS;
484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         emit        = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                               void*,void*,void*,void*))
486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       emit_MIPSInstr;
487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        if defined(VKI_LITTLE_ENDIAN)
488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         host_is_bigendian = False;
489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        elif defined(VKI_BIG_ENDIAN)
490436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         host_is_bigendian = True;
491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        endif
492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         host_word_type    = Ity_I64;
493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("LibVEX_Translate: unsupported host insn set");
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (vta->arch_guest) {
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchX86:
504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_x86_state_requires_precise_mem_exns;
505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_X86;
506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_x86_spechelper;
507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestX86State);
508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I32;
509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &x86guest_layout;
510eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestX86State,guest_CMSTART);
511eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestX86State,guest_CMLEN);
512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestX86State,guest_EIP);
513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestX86State*)0)->guest_EIP );
514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestX86State,host_EvC_COUNTER);
515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == sizeof(VexGuestX86State) % 16);
518eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
519eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN  ) == 4);
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchAMD64:
524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_amd64_state_requires_precise_mem_exns;
525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_AMD64;
526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_amd64_spechelper;
527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestAMD64State);
528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I64;
529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &amd64guest_layout;
530eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestAMD64State,guest_CMSTART);
531eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestAMD64State,guest_CMLEN);
532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestAMD64State,guest_RIP);
533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == sizeof(VexGuestAMD64State) % 16);
538eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
539eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN   ) == 8);
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR  ) == 8);
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC32:
544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_ppc32_state_requires_precise_mem_exns;
545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_PPC;
546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_ppc32_spechelper;
547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestPPC32State);
548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I32;
549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &ppc32Guest_layout;
550eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestPPC32State,guest_CMSTART);
551eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestPPC32State,guest_CMLEN);
552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestPPC32State,guest_CIA);
553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == sizeof(VexGuestPPC32State) % 16);
558eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
559eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN   ) == 4);
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR  ) == 4);
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC64:
564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_ppc64_state_requires_precise_mem_exns;
565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_PPC;
566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_ppc64_spechelper;
567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestPPC64State);
568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I64;
569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &ppc64Guest_layout;
570eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestPPC64State,guest_CMSTART);
571eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestPPC64State,guest_CMLEN);
572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestPPC64State,guest_CIA);
573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == sizeof(VexGuestPPC64State) % 16);
578eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART    ) == 8);
579eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN      ) == 8);
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR     ) == 8);
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case VexArchS390X:
585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         disInstrFn       = disInstr_S390;
587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         specHelper       = guest_s390x_spechelper;
588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         guest_sizeB      = sizeof(VexGuestS390XState);
589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         guest_word_type  = Ity_I64;
590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         guest_layout     = &s390xGuest_layout;
591eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART     = offsetof(VexGuestS390XState,guest_CMSTART);
592eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN       = offsetof(VexGuestS390XState,guest_CMLEN);
593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestS390XState,guest_IA);
594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestS390XState*)0)->guest_IA);
595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestS390XState,host_EvC_COUNTER);
596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(0 == sizeof(VexGuestS390XState) % 16);
599eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART    ) == 8);
600eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN      ) == 8);
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR     ) == 8);
602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchARM:
605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_arm_state_requires_precise_mem_exns;
606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_ARM;
607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_arm_spechelper;
608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestARMState);
609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I32;
610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &armGuest_layout;
611eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestARMState,guest_CMSTART);
612eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestARMState,guest_CMLEN);
613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestARMState,guest_R15T);
614663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestARMState*)0)->guest_R15T );
615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestARMState,host_EvC_COUNTER);
616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == sizeof(VexGuestARMState) % 16);
619eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
620eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN  ) == 4);
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:
625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         preciseMemExnsFn     = guest_arm64_state_requires_precise_mem_exns;
626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         disInstrFn           = disInstr_ARM64;
627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         specHelper           = guest_arm64_spechelper;
628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_sizeB          = sizeof(VexGuestARM64State);
629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_word_type      = Ity_I64;
630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_layout         = &arm64Guest_layout;
631eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART         = offsetof(VexGuestARM64State,guest_CMSTART);
632eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN           = offsetof(VexGuestARM64State,guest_CMLEN);
633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_GUEST_IP        = offsetof(VexGuestARM64State,guest_PC);
634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         szB_GUEST_IP         = sizeof( ((VexGuestARM64State*)0)->guest_PC );
635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_HOST_EvC_COUNTER  = offsetof(VexGuestARM64State,host_EvC_COUNTER);
636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(0 == sizeof(VexGuestARM64State) % 16);
639eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
640eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN  ) == 8);
641436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:
645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         preciseMemExnsFn       = guest_mips32_state_requires_precise_mem_exns;
646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         disInstrFn             = disInstr_MIPS;
647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         specHelper             = guest_mips32_spechelper;
648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_sizeB            = sizeof(VexGuestMIPS32State);
649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_word_type        = Ity_I32;
650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         guest_layout           = &mips32Guest_layout;
651eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestMIPS32State,guest_CMSTART);
652eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestMIPS32State,guest_CMLEN);
653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_GUEST_IP          = offsetof(VexGuestMIPS32State,guest_PC);
654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         szB_GUEST_IP           = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_COUNTER  = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(0 == sizeof(VexGuestMIPS32State) % 16);
659eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
660eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN  ) == 4);
661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         break;
663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:
665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         preciseMemExnsFn       = guest_mips64_state_requires_precise_mem_exns;
666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         disInstrFn             = disInstr_MIPS;
667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         specHelper             = guest_mips64_spechelper;
668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_sizeB            = sizeof(VexGuestMIPS64State);
669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_word_type        = Ity_I64;
670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         guest_layout           = &mips64Guest_layout;
671eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMSTART           = offsetof(VexGuestMIPS64State,guest_CMSTART);
672eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         offB_CMLEN             = offsetof(VexGuestMIPS64State,guest_CMLEN);
673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_GUEST_IP          = offsetof(VexGuestMIPS64State,guest_PC);
674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         szB_GUEST_IP           = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_HOST_EvC_COUNTER  = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(0 == sizeof(VexGuestMIPS64State) % 16);
679eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
680eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN  ) == 8);
681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("LibVEX_Translate: unsupported guest insn set");
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Set up result struct. */
689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexTranslateResult res;
690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   res.status         = VexTransOK;
691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   res.n_sc_extents   = 0;
692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   res.offs_profInc   = -1;
693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   res.n_guest_instrs = 0;
694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* yet more sanity checks ... */
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->arch_guest == vta->arch_host) {
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* doesn't necessarily have to be true, but if it isn't it means
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         we are simulating one flavour of an architecture a different
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         flavour of the same architecture, which is pretty strange. */
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_FE)
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " Front end "
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   irsb = bb_to_IR ( vta->guest_extents,
711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     &res.n_sc_extents,
712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     &res.n_guest_instrs,
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->callback_opaque,
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     disInstrFn,
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->guest_bytes,
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->guest_bytes_addr,
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->chase_into_ok,
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     host_is_bigendian,
719436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                     vta->sigill_diag,
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->arch_guest,
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     &vta->archinfo_guest,
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     &vta->abiinfo_both,
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     guest_word_type,
724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     vta->needs_self_check,
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     vta->preamble_function,
726eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                     offB_CMSTART,
727eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                     offB_CMLEN,
728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     offB_GUEST_IP,
729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     szB_GUEST_IP );
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (irsb == NULL) {
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Access failure. */
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vexSetAllocModeTEMP_and_clear();
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_traceflags = 0;
737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      res.status = VexTransAccessFail; return res;
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < vta->guest_extents->n_used; i++) {
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(vta->guest_extents->len[i] < 10000); /* sanity */
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If debugging, show the raw guest bytes for this bb. */
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0 || (vex_traceflags & VEX_TRACE_FE)) {
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (vta->guest_extents->n_used > 1) {
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("can't show code due to extents > 1\n");
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* HACK */
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* p = (UChar*)vta->guest_bytes;
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt   sum = 0;
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt   guest_bytes_read = (UInt)vta->guest_extents->len[0];
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                           guest_bytes_read );
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 0; i < guest_bytes_read; i++) {
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt b = (UInt)p[i];
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(" %02x", b );
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            sum = (sum << 1) ^ b;
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("  %08x\n\n", sum);
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Sanity check the initial IR. */
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sanityCheckIRSB( irsb, "initial IR",
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    False/*can be non-flat*/, guest_word_type );
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Clean it up, hopefully a lot. */
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              vta->guest_bytes_addr,
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              vta->arch_guest );
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sanityCheckIRSB( irsb, "after initial iropt",
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    True/*must be flat*/, guest_word_type );
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_OPT1) {
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " After pre-instr IR optimisation "
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppIRSB ( irsb );
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Get the thing instrumented. */
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->instrument1)
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      irsb = vta->instrument1(vta->callback_opaque,
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              irsb, guest_layout,
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              vta->guest_extents,
794436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                              &vta->archinfo_host,
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              guest_word_type, host_word_type);
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->instrument2)
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      irsb = vta->instrument2(vta->callback_opaque,
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              irsb, guest_layout,
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              vta->guest_extents,
802436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                              &vta->archinfo_host,
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              guest_word_type, host_word_type);
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_INST) {
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " After instrumentation "
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppIRSB ( irsb );
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->instrument1 || vta->instrument2)
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sanityCheckIRSB( irsb, "after instrumentation",
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       True/*must be flat*/, guest_word_type );
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Do a post-instrumentation cleanup pass. */
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->instrument1 || vta->instrument2) {
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      do_deadcode_BB( irsb );
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      irsb = cprop_BB( irsb );
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      do_deadcode_BB( irsb );
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       True/*must be flat*/, guest_word_type );
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_OPT2) {
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " After post-instr IR optimisation "
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppIRSB ( irsb );
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Turn it into virtual-registerised code.  Build trees -- this
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      also throws away any dead bindings. */
838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vta->finaltidy) {
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      irsb = vta->finaltidy(irsb);
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_TREES) {
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "  After tree-building "
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppIRSB ( irsb );
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* HACK */
855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0) {
856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *(vta->host_bytes_used) = 0;
857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      res.status = VexTransOK; return res;
858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* end HACK */
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_VCODE)
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " Instruction selection "
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n");
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* No guest has its IP field at offset zero.  If this fails it
867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      means some transformation pass somewhere failed to update/copy
868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      irsb->offsIP properly. */
869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(irsb->offsIP >= 16);
870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vcode = iselSB ( irsb, vta->arch_host,
872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    &vta->archinfo_host,
873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    &vta->abiinfo_both,
874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    offB_HOST_EvC_COUNTER,
875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    offB_HOST_EvC_FAILADDR,
876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    chainingAllowed,
877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    vta->addProfInc,
878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    max_ga );
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_VCODE)
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_VCODE) {
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < vcode->arr_used; i++) {
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%3d   ", i);
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr(vcode->arr[i], mode64);
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("\n");
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Register allocate. */
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rcode = doRegisterAllocation ( vcode, available_real_regs,
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  n_available_real_regs,
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  isMove, getRegUsage, mapRegs,
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  genSpill, genReload, directReload,
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  guest_sizeB,
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  ppInstr, ppReg, mode64 );
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_RCODE) {
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " Register-allocated code "
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < rcode->arr_used; i++) {
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%3d   ", i);
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppInstr(rcode->arr[i], mode64);
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("\n");
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n");
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* HACK */
917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0) {
918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *(vta->host_bytes_used) = 0;
919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      res.status = VexTransOK; return res;
920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* end HACK */
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Assemble */
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (vex_traceflags & VEX_TRACE_ASM) {
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("\n------------------------"
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   " Assembly "
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "------------------------\n\n");
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   out_used = 0; /* tracks along the host_bytes array */
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < rcode->arr_used; i++) {
932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      HInstr* hi           = rcode->arr[i];
933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Bool    hi_isProfInc = False;
934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppInstr(hi, mode64);
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("\n");
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      j = emit( &hi_isProfInc,
939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                insn_bytes, sizeof insn_bytes, hi, mode64,
940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                vta->disp_cp_chain_me_to_slowEP,
941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                vta->disp_cp_chain_me_to_fastEP,
942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                vta->disp_cp_xindir,
943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                vta->disp_cp_xassisted );
944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (k = 0; k < j; k++)
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (insn_bytes[k] < 16)
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf("0%x ",  (UInt)insn_bytes[k]);
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf("%x ", (UInt)insn_bytes[k]);
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("\n\n");
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vexSetAllocModeTEMP_and_clear();
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_traceflags = 0;
955b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         res.status = VexTransOutputFull;
956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return res;
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (UNLIKELY(hi_isProfInc)) {
959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(vta->addProfInc); /* else where did it come from? */
960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(res.offs_profInc == -1); /* there can be only one (tm) */
961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(out_used >= 0);
962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         res.offs_profInc = out_used;
963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      { UChar* dst = &vta->host_bytes[out_used];
965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        for (k = 0; k < j; k++) {
966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng           dst[k] = insn_bytes[k];
967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        }
968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        out_used += j;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(out_used <= vta->host_bytes_size);
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *(vta->host_bytes_used) = out_used;
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexAllocSanityCheck();
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vexSetAllocModeTEMP_and_clear();
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
978436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (vex_traceflags) {
979436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* Print the expansion ratio for this SB. */
980436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      j = 0; /* total guest bytes */
981436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      for (i = 0; i < vta->guest_extents->n_used; i++) {
982436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         j += vta->guest_extents->len[i];
983436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
984436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (1) vex_printf("VexExpansionRatio %d %d   %d :10\n\n",
985436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
986436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_traceflags = 0;
989b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   res.status = VexTransOK;
990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return res;
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* --------- Chain/Unchain XDirects. --------- */
995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
996663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange LibVEX_Chain ( VexArch arch_host,
997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             void*   place_to_chain,
998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             void*   disp_cp_chain_me_EXPECTED,
999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             void*   place_to_jump_to )
1000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange (*chainXDirect)(void*, void*, void*) = NULL;
1002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   switch (arch_host) {
1003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchX86:
1004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         chainXDirect = chainXDirect_X86; break;
1005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchAMD64:
1006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         chainXDirect = chainXDirect_AMD64; break;
1007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchARM:
1008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         chainXDirect = chainXDirect_ARM; break;
1009436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:
1010436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         chainXDirect = chainXDirect_ARM64; break;
1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchS390X:
1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         chainXDirect = chainXDirect_S390; break;
1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC32:
1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return chainXDirect_PPC(place_to_chain,
1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 disp_cp_chain_me_EXPECTED,
1016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 place_to_jump_to, False/*!mode64*/);
1017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC64:
1018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return chainXDirect_PPC(place_to_chain,
1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 disp_cp_chain_me_EXPECTED,
1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 place_to_jump_to, True/*mode64*/);
1021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:
1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return chainXDirect_MIPS(place_to_chain,
1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  disp_cp_chain_me_EXPECTED,
1024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  place_to_jump_to, False/*!mode64*/);
1025436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:
1026436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return chainXDirect_MIPS(place_to_chain,
1027436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                  disp_cp_chain_me_EXPECTED,
1028436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                  place_to_jump_to, True/*!mode64*/);
1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      default:
1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(0);
1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(chainXDirect);
1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir
1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      = chainXDirect(place_to_chain, disp_cp_chain_me_EXPECTED,
1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     place_to_jump_to);
1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange LibVEX_UnChain ( VexArch arch_host,
1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*   place_to_unchain,
1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*   place_to_jump_to_EXPECTED,
1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               void*   disp_cp_chain_me )
1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange (*unchainXDirect)(void*, void*, void*) = NULL;
1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   switch (arch_host) {
1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchX86:
1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unchainXDirect = unchainXDirect_X86; break;
1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchAMD64:
1049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unchainXDirect = unchainXDirect_AMD64; break;
1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchARM:
1051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unchainXDirect = unchainXDirect_ARM; break;
1052436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:
1053436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         unchainXDirect = unchainXDirect_ARM64; break;
1054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchS390X:
1055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unchainXDirect = unchainXDirect_S390; break;
1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC32:
1057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return unchainXDirect_PPC(place_to_unchain,
1058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   place_to_jump_to_EXPECTED,
1059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   disp_cp_chain_me, False/*!mode64*/);
1060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC64:
1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return unchainXDirect_PPC(place_to_unchain,
1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   place_to_jump_to_EXPECTED,
1063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   disp_cp_chain_me, True/*mode64*/);
1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:
1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return unchainXDirect_MIPS(place_to_unchain,
1066436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    place_to_jump_to_EXPECTED,
1067436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    disp_cp_chain_me, False/*!mode64*/);
1068436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:
1069436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return unchainXDirect_MIPS(place_to_unchain,
1070436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    place_to_jump_to_EXPECTED,
1071436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    disp_cp_chain_me, True/*!mode64*/);
1072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      default:
1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(0);
1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(unchainXDirect);
1076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir
1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      = unchainXDirect(place_to_unchain, place_to_jump_to_EXPECTED,
1078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       disp_cp_chain_me);
1079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
1080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1082663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengInt LibVEX_evCheckSzB ( VexArch arch_host )
1083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (UNLIKELY(cached == 0)) {
1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      switch (arch_host) {
1087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchX86:
1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_X86(); break;
1089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchAMD64:
1090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_AMD64(); break;
1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchARM:
1092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_ARM(); break;
1093436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         case VexArchARM64:
1094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            cached = evCheckSzB_ARM64(); break;
1095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchS390X:
1096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_S390(); break;
1097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchPPC32:
1098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchPPC64:
1099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_PPC(); break;
1100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         case VexArchMIPS32:
1101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         case VexArchMIPS64:
1102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            cached = evCheckSzB_MIPS(); break;
1103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         default:
1104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(0);
1105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
1106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return cached;
1108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1110663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    void*   place_to_patch,
1112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    ULong*  location_of_counter )
1113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange (*patchProfInc)(void*,ULong*) = NULL;
1115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   switch (arch_host) {
1116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchX86:
1117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         patchProfInc = patchProfInc_X86; break;
1118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchAMD64:
1119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         patchProfInc = patchProfInc_AMD64; break;
1120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchARM:
1121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         patchProfInc = patchProfInc_ARM; break;
1122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchS390X:
1123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         patchProfInc = patchProfInc_S390; break;
1124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC32:
1125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return patchProfInc_PPC(place_to_patch,
1126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 location_of_counter, False/*!mode64*/);
1127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC64:
1128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return patchProfInc_PPC(place_to_patch,
1129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 location_of_counter, True/*mode64*/);
1130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:
1131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return patchProfInc_MIPS(place_to_patch,
1132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  location_of_counter, False/*!mode64*/);
1133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:
1134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return patchProfInc_MIPS(place_to_patch,
1135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                  location_of_counter, True/*!mode64*/);
1136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      default:
1137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(0);
1138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(patchProfInc);
1140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir
1141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      = patchProfInc(place_to_patch, location_of_counter);
1142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
1143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Emulation warnings. --------- */
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* LibVEX_EmNote_string ( VexEmNote ew )
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ew) {
1151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmNote_NONE:
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "none";
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_x87exns:
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Unmasking x87 FP exceptions";
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_x87precision:
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Selection of non-80-bit x87 FP precision";
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_sseExns:
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Unmasking SSE FP exceptions";
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_fz:
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_daz:
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_X86_acFlag:
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Setting %eflags.ac (setting noted but ignored)";
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_PPCexns:
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "Unmasking PPC32/64 FP exceptions";
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_PPC64_redir_overflow:
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "PPC64 function redirection stack overflow";
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     case EmWarn_PPC64_redir_underflow:
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return "PPC64 function redirection stack underflow";
1171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmWarn_S390X_fpext_rounding:
1172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "The specified rounding mode cannot be supported. That\n"
1173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "  feature requires the floating point extension facility.\n"
1174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "  which is not available on this host. Continuing using\n"
1175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "  the rounding mode from FPC. Results may differ!";
1176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmWarn_S390X_invalid_rounding:
1177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "The specified rounding mode is invalid.\n"
1178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "  Continuing using 'round to nearest'. Results may differ!";
1179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_stfle:
1180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "Instruction stfle is not supported on this host";
1181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_stckf:
1182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "Instruction stckf is not supported on this host";
1183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_ecag:
1184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "Instruction ecag is not supported on this host";
1185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_fpext:
1186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "Encountered an instruction that requires the floating "
1187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "point extension facility.\n"
1188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               "  That facility is not available on this host";
1189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_invalid_PFPO_rounding_mode:
1190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "The rounding mode specified in GPR 0 for PFPO instruction"
1191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               " is invalid";
1192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     case EmFail_S390X_invalid_PFPO_function:
1193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return "The function code specified in GPR 0 for PFPO instruction"
1194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               " is invalid";
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     default:
1196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        vpanic("LibVEX_EmNote_string: unknown warning");
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Arch/HwCaps stuff. ------------------ */
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst HChar* LibVEX_ppVexArch ( VexArch arch )
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (arch) {
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArch_INVALID: return "INVALID";
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchX86:      return "X86";
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchAMD64:    return "AMD64";
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchARM:      return "ARM";
1209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:    return "ARM64";
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC32:    return "PPC32";
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VexArchPPC64:    return "PPC64";
1212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case VexArchS390X:    return "S390X";
1213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32:   return "MIPS32";
1214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64:   return "MIPS64";
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:              return "VexArch???";
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const HChar* str = show_hwcaps(arch,hwcaps);
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return str ? str : "INVALID";
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Write default settings info *vai. */
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1229eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vex_bzero(vai, sizeof(*vai));
1230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->hwcaps              = 0;
1231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->ppc_icache_line_szB = 0;
1232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->ppc_dcbz_szB        = 0;
1233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->ppc_dcbzl_szB       = 0;
1234eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vai->arm64_dMinLine_lg2_szB  = 0;
1235eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vai->arm64_iMinLine_lg2_szB  = 0;
1236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->hwcache_info.num_levels = 0;
1237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->hwcache_info.num_caches = 0;
1238eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vai->hwcache_info.caches     = NULL;
1239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vai->hwcache_info.icaches_maintain_coherence = True;  // whatever
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Write default settings info *vbi. */
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1245eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vex_bzero(vbi, sizeof(*vbi));
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_stack_redzone_size       = 0;
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_amd64_assume_fs_is_zero  = False;
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_amd64_assume_gs_is_0x60  = False;
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_ppc_zap_RZ_at_blr        = False;
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_ppc_zap_RZ_at_bl         = NULL;
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->guest_ppc_sc_continues_at_LR   = False;
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->host_ppc_calls_use_fndescrs    = False;
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vbi->host_ppc32_regalign_int64_args = False;
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return a string showing the hwcaps in a nice way.  The string will
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be NULL for invalid combinations of flags, so these functions also
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   serve as a way to validate hwcaps values. */
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_x86 ( UInt hwcaps )
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (hwcaps) {
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0:
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return "x86-sse0";
1267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT:
1268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext";
1269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext-sse1";
1271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext-sse1-sse2";
1273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           | VEX_HWCAPS_X86_LZCNT:
1275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext-sse1-sse2-lzcnt";
1276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           | VEX_HWCAPS_X86_SSE3:
1278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext-sse1-sse2-sse3";
1279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
1281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "x86-mmxext-sse1-sse2-sse3-lzcnt";
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL;
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_amd64 ( UInt hwcaps )
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* SSE3 and CX16 are orthogonal and > baseline, although we really
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      don't expect to come across anything which can do SSE3 but can't
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      do CX16.  Still, we can handle that case.  LZCNT is similarly
1292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      orthogonal. */
1293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Throw out obviously stupid cases: */
1295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Bool have_avx  = (hwcaps & VEX_HWCAPS_AMD64_AVX)  != 0;
1297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Bool have_bmi  = (hwcaps & VEX_HWCAPS_AMD64_BMI)  != 0;
1298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* AVX without SSE3 */
1300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (have_avx && !have_sse3)
1301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return NULL;
1302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* AVX2 or BMI without AVX */
1303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if ((have_avx2 || have_bmi) && !have_avx)
1304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return NULL;
1305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* This isn't threadsafe.  We might need to fix it at some point. */
1307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   static HChar buf[100] = { 0 };
1308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (buf[0] != 0) return buf; /* already constructed */
1309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vex_bzero(buf, sizeof(buf));
1311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar* p = &buf[0];
1313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   p = p + vex_sprintf(p, "%s", "amd64");
1315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps == 0) {
1316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* special-case the baseline case */
1317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-sse2");
1318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      goto out;
1319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-cx16");
1322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-lzcnt");
1325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-rdtscp");
1328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-sse3");
1331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-avx");
1334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-avx2");
1337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      p = p + vex_sprintf(p, "%s", "-bmi");
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  out:
1343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(buf[sizeof(buf)-1] == 0);
1344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return buf;
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Monotonic with complications.  Basically V > F > baseline,
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      but once you have F then you can have FX or GX too. */
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt F  = VEX_HWCAPS_PPC32_F;
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt V  = VEX_HWCAPS_PPC32_V;
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt FX = VEX_HWCAPS_PPC32_FX;
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt GX = VEX_HWCAPS_PPC32_GX;
1355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const UInt VX = VEX_HWCAPS_PPC32_VX;
1356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   const UInt DFP = VEX_HWCAPS_PPC32_DFP;
1357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt c  = hwcaps;
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == 0)           return "ppc32-int";
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == F)           return "ppc32-int-flt";
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|FX))      return "ppc32-int-flt-FX";
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|GX))      return "ppc32-int-flt-GX";
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|FX|GX))   return "ppc32-int-flt-FX-GX";
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|V))       return "ppc32-int-flt-vmx";
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|V|FX))    return "ppc32-int-flt-vmx-FX";
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|V|GX))    return "ppc32-int-flt-vmx-GX";
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
1368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (c == (F|V|FX|GX|DFP))    return "ppc32-int-flt-vmx-FX-GX-DFP";
1369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
1370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Monotonic with complications.  Basically V > baseline(==F),
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      but once you have F then you can have FX or GX too. */
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt V  = VEX_HWCAPS_PPC64_V;
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt FX = VEX_HWCAPS_PPC64_FX;
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const UInt GX = VEX_HWCAPS_PPC64_GX;
1383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const UInt VX = VEX_HWCAPS_PPC64_VX;
1384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   const UInt DFP = VEX_HWCAPS_PPC64_DFP;
1385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt c  = hwcaps;
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == 0)         return "ppc64-int-flt";
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == FX)        return "ppc64-int-flt-FX";
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == GX)        return "ppc64-int-flt-GX";
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (FX|GX))   return "ppc64-int-flt-FX-GX";
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == V)         return "ppc64-int-flt-vmx";
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (V|FX))    return "ppc64-int-flt-vmx-FX";
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (V|GX))    return "ppc64-int-flt-vmx-GX";
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
1395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (c == (V|FX|GX|DFP))    return "ppc64-int-flt-vmx-FX-GX-DFP";
1396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
1397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (c == (V|FX|GX|VX|DFP|ISA2_07))
1398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_arm ( UInt hwcaps )
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 5:
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (N)
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return NULL;
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (vfp)
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "ARMv5-vfp";
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "ARMv5";
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL;
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 6:
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (N)
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return NULL;
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (vfp)
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "ARMv6-vfp";
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "ARMv6";
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL;
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 7:
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (vfp) {
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (N)
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "ARMv7-vfp-neon";
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "ARMv7-vfp";
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (N)
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "ARMv7-neon";
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "ARMv7";
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL;
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
1444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Since there are no variants, just insist that hwcaps is zero,
1445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      and declare it invalid otherwise. */
1446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  if (hwcaps == 0)
1447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     return "baseline";
1448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  return NULL;
1449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
1450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_s390x ( UInt hwcaps )
1452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static const HChar prefix[] = "s390x";
1454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   static const struct {
1455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UInt  hwcaps_bit;
1456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar name[6];
1457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   } hwcaps_list[] = {
1458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_EIMM,  "eimm" },
1460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_GIE,   "gie" },
1461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_DFP,   "dfp" },
1462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_FGX,   "fgx" },
1463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_STFLE, "stfle" },
1464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_ETF2,  "etf2" },
1465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_ETF3,  "etf3" },
1466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_STCKF, "stckf" },
1467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_LSC,   "lsc" },
1469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { VEX_HWCAPS_S390X_PFPO,  "pfpo" },
1470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   };
1471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   static HChar buf[sizeof prefix +
1473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    1];  // '\0'
1475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar *p;
1476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UInt i;
1477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (buf[0] != '\0') return buf;  /* already constructed */
1479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   hwcaps = VEX_HWCAPS_S390X(hwcaps);
1481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = buf + vex_sprintf(buf, "%s", prefix);
1483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (i = 0 ; i < NUM_HWCAPS; ++i) {
1484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (hwcaps & hwcaps_list[i].hwcaps_bit)
1485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* If there are no facilities, add "zarch" */
1489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (hwcaps == 0)
1490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     vex_sprintf(p, "-%s", "zarch");
1491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return buf;
1493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_mips32 ( UInt hwcaps )
1496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* MIPS baseline. */
1498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
1499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* MIPS baseline with dspr2. */
1500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (VEX_MIPS_PROC_DSP2(hwcaps)) {
1501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "MIPS-baseline-dspr2";
1502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
1503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* MIPS baseline with dsp. */
1504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (VEX_MIPS_PROC_DSP(hwcaps)) {
1505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return "MIPS-baseline-dsp";
1506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
1507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "MIPS-baseline";
1508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1510436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Broadcom baseline. */
1511436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
1512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "Broadcom-baseline";
1513436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1514436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Netlogic baseline. */
1516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
1517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "Netlogic-baseline";
1518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Cavium baseline. */
1521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return "Cavium-baseline";
1523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
1524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return NULL;
1526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
1530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return "mips64-baseline";
1531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
1532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---- */
1534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (arch) {
1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchX86:    return show_hwcaps_x86(hwcaps);
1538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchAMD64:  return show_hwcaps_amd64(hwcaps);
1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC32:  return show_hwcaps_ppc32(hwcaps);
1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchPPC64:  return show_hwcaps_ppc64(hwcaps);
1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchARM:    return show_hwcaps_arm(hwcaps);
1542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchARM64:  return show_hwcaps_arm64(hwcaps);
1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchS390X:  return show_hwcaps_s390x(hwcaps);
1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
1545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: return NULL;
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return show_hwcaps(arch,hwcaps) != NULL;
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                         main_main.c ---*/
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
1559