blob: 521e63caf47e0e906515cfcc575ebddae203938a [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardje6c53e02011-10-23 07:33:43 +000010 Copyright (C) 2004-2011 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex.h"
sewardj893aada2004-11-29 19:57:54 +000037#include "libvex_emwarn.h"
sewardj81ec4182004-10-25 23:15:52 +000038#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000039#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000040#include "libvex_guest_arm.h"
cerionaabdfbf2005-01-29 12:56:15 +000041#include "libvex_guest_ppc32.h"
cerionf0de28c2005-12-13 20:21:11 +000042#include "libvex_guest_ppc64.h"
sewardj2019a972011-03-07 16:04:07 +000043#include "libvex_guest_s390x.h"
sewardjf13a16a2004-07-05 17:10:14 +000044
sewardjcef7d3e2009-07-02 12:21:59 +000045#include "main_globals.h"
46#include "main_util.h"
47#include "host_generic_regs.h"
48#include "ir_opt.h"
sewardj35421a32004-07-05 13:12:34 +000049
sewardjcef7d3e2009-07-02 12:21:59 +000050#include "host_x86_defs.h"
51#include "host_amd64_defs.h"
52#include "host_ppc_defs.h"
sewardj6c299f32009-12-31 18:00:12 +000053#include "host_arm_defs.h"
sewardj2019a972011-03-07 16:04:07 +000054#include "host_s390_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000055
sewardjcef7d3e2009-07-02 12:21:59 +000056#include "guest_generic_bb_to_IR.h"
57#include "guest_x86_defs.h"
58#include "guest_amd64_defs.h"
59#include "guest_arm_defs.h"
60#include "guest_ppc_defs.h"
sewardj2019a972011-03-07 16:04:07 +000061#include "guest_s390_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000062
sewardj69d98e32010-06-18 08:17:41 +000063#include "host_generic_simd128.h"
64
sewardj35421a32004-07-05 13:12:34 +000065
66/* This file contains the top level interface to the library. */
67
sewardj5117ce12006-01-27 21:20:15 +000068/* --------- fwds ... --------- */
69
70static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
71static HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
72
73
sewardj35421a32004-07-05 13:12:34 +000074/* --------- Initialise the library. --------- */
75
76/* Exported to library client. */
77
sewardj08613742004-10-25 13:01:45 +000078void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
79{
80 vcon->iropt_verbosity = 0;
81 vcon->iropt_level = 2;
82 vcon->iropt_precise_memory_exns = False;
83 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000084 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +000085 vcon->guest_chase_thresh = 10;
sewardj984d9b12010-01-15 10:53:21 +000086 vcon->guest_chase_cond = False;
sewardj08613742004-10-25 13:01:45 +000087}
88
89
90/* Exported to library client. */
91
sewardj887a11a2004-07-05 17:26:47 +000092void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000093 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000094 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000095 void (*failure_exit) ( void ),
96 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +000097 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +000098 /* debug paranoia level */
99 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000100 /* Are we supporting valgrind checking? */
101 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000102 /* Control ... */
103 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000104)
105{
sewardj08613742004-10-25 13:01:45 +0000106 /* First off, do enough minimal setup so that the following
107 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000108 vex_failure_exit = failure_exit;
109 vex_log_bytes = log_bytes;
110
111 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000112 vassert(!vex_initdone);
113 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000114 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000115 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000116
117 vassert(vcon->iropt_verbosity >= 0);
118 vassert(vcon->iropt_level >= 0);
119 vassert(vcon->iropt_level <= 2);
120 vassert(vcon->iropt_unroll_thresh >= 0);
121 vassert(vcon->iropt_unroll_thresh <= 400);
122 vassert(vcon->guest_max_insns >= 1);
123 vassert(vcon->guest_max_insns <= 100);
124 vassert(vcon->guest_chase_thresh >= 0);
125 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj984d9b12010-01-15 10:53:21 +0000126 vassert(vcon->guest_chase_cond == True
127 || vcon->guest_chase_cond == False);
sewardj443cd9d2004-07-18 23:06:45 +0000128
sewardjea602bc2004-10-14 21:40:12 +0000129 /* Check that Vex has been built with sizes of basic types as
130 stated in priv/libvex_basictypes.h. Failure of any of these is
131 a serious configuration error and should be corrected
132 immediately. If any of these assertions fail you can fully
133 expect Vex not to work properly, if at all. */
134
135 vassert(1 == sizeof(UChar));
136 vassert(1 == sizeof(Char));
137 vassert(2 == sizeof(UShort));
138 vassert(2 == sizeof(Short));
139 vassert(4 == sizeof(UInt));
140 vassert(4 == sizeof(Int));
141 vassert(8 == sizeof(ULong));
142 vassert(8 == sizeof(Long));
143 vassert(4 == sizeof(Float));
144 vassert(8 == sizeof(Double));
145 vassert(1 == sizeof(Bool));
146 vassert(4 == sizeof(Addr32));
147 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000148 vassert(16 == sizeof(U128));
sewardj69d98e32010-06-18 08:17:41 +0000149 vassert(16 == sizeof(V128));
sewardjea602bc2004-10-14 21:40:12 +0000150
151 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
152 vassert(sizeof(void*) == sizeof(int*));
153 vassert(sizeof(void*) == sizeof(HWord));
154
sewardj97e87932005-02-07 00:00:50 +0000155 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
156 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
157
sewardjc6f970f2012-04-02 21:54:49 +0000158 /* These take a lot of space, so make sure we don't have
159 any unnoticed size regressions. */
160 if (VEX_HOST_WORDSIZE == 4) {
161 vassert(sizeof(IRExpr) == 24);
162 vassert(sizeof(IRStmt) == 20 /* x86 */
163 || sizeof(IRStmt) == 24 /* arm */);
164 } else {
165 vassert(sizeof(IRExpr) == 48);
166 vassert(sizeof(IRStmt) == 40);
167 }
168
sewardjea602bc2004-10-14 21:40:12 +0000169 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000170 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000171 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000172 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000173 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000174 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000175}
176
177
178/* --------- Make a translation. --------- */
179
180/* Exported to library client. */
181
sewardj17c7f952005-12-15 14:02:34 +0000182VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000183{
sewardj81bd5502004-07-21 18:49:27 +0000184 /* This the bundle of functions we need to do the back-end stuff
185 (insn selection, reg-alloc, assembly) whilst being insulated
186 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000187 HReg* available_real_regs;
188 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000189 Bool (*isMove) ( HInstr*, HReg*, HReg* );
190 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
191 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000192 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
193 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000194 HInstr* (*directReload) ( HInstr*, HReg, Short );
195 void (*ppInstr) ( HInstr*, Bool );
196 void (*ppReg) ( HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000197 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
198 Int, Int, Bool, Bool, Addr64 );
199 Int (*emit) ( /*MB_MOD*/Bool*,
200 UChar*, Int, HInstr*, Bool,
201 void*, void*, void*, void* );
sewardjec0d9a02010-08-22 12:54:56 +0000202 IRExpr* (*specHelper) ( HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000203 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000204
sewardj9e6491a2005-07-02 19:24:10 +0000205 DisOneInstrFn disInstrFn;
206
sewardjeeac8412004-11-02 00:26:55 +0000207 VexGuestLayout* guest_layout;
208 Bool host_is_bigendian = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000209 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000210 HInstrArray* vcode;
211 HInstrArray* rcode;
212 Int i, j, k, out_used, guest_sizeB;
sewardjc6f970f2012-04-02 21:54:49 +0000213 Int offB_TISTART, offB_TILEN, offB_GUEST_IP, szB_GUEST_IP;
214 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
215 UChar insn_bytes[64];
sewardjcf787902004-11-03 09:08:33 +0000216 IRType guest_word_type;
217 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000218 Bool mode64, chainingAllowed;
219 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000220
sewardj49651f42004-10-28 22:11:04 +0000221 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000222 available_real_regs = NULL;
223 n_available_real_regs = 0;
224 isMove = NULL;
225 getRegUsage = NULL;
226 mapRegs = NULL;
227 genSpill = NULL;
228 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000229 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000230 ppInstr = NULL;
231 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000232 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000233 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000234 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000235 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000236 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000237 guest_word_type = Ity_INVALID;
238 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000239 offB_TISTART = 0;
240 offB_TILEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000241 offB_GUEST_IP = 0;
242 szB_GUEST_IP = 0;
243 offB_HOST_EvC_COUNTER = 0;
244 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000245 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000246 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000247
sewardj17c7f952005-12-15 14:02:34 +0000248 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000249
sewardj35421a32004-07-05 13:12:34 +0000250 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000251 vassert(vta->needs_self_check != NULL);
252 vassert(vta->disp_cp_xassisted != NULL);
253 /* Both the chainers and the indir are either NULL or non-NULL. */
254 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
255 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
256 vassert(vta->disp_cp_xindir != NULL);
257 chainingAllowed = True;
258 } else {
259 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
260 vassert(vta->disp_cp_xindir == NULL);
261 }
florian2eeeb9b2011-09-23 18:03:21 +0000262
sewardj2d6b14a2005-11-23 04:25:07 +0000263 vexSetAllocModeTEMP_and_clear();
264 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000265
sewardjf13a16a2004-07-05 17:10:14 +0000266 /* First off, check that the guest and host insn sets
267 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000268
sewardj17c7f952005-12-15 14:02:34 +0000269 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000270
sewardjbef170b2004-12-21 01:23:00 +0000271 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000272 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000273 getAllocableRegs_X86 ( &n_available_real_regs,
274 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000275 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000276 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
277 getRegUsage_X86Instr;
sewardjfb7373a2007-08-25 21:29:03 +0000278 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000279 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
280 genSpill_X86;
281 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
282 genReload_X86;
sewardjfb7373a2007-08-25 21:29:03 +0000283 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
284 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
285 ppReg = (void(*)(HReg)) ppHRegX86;
286 iselSB = iselSB_X86;
sewardjc6f970f2012-04-02 21:54:49 +0000287 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
288 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000289 emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000290 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000291 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000292 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardjf13a16a2004-07-05 17:10:14 +0000293 break;
sewardj2a9ad022004-11-25 02:46:58 +0000294
sewardjc33671d2005-02-01 20:30:00 +0000295 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000296 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000297 getAllocableRegs_AMD64 ( &n_available_real_regs,
298 &available_real_regs );
299 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000300 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
301 getRegUsage_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000302 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000303 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
304 genSpill_AMD64;
305 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
306 genReload_AMD64;
cerion92b64362005-12-13 12:02:26 +0000307 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000308 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000309 iselSB = iselSB_AMD64;
sewardjc6f970f2012-04-02 21:54:49 +0000310 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
311 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000312 emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000313 host_is_bigendian = False;
314 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000315 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardjc33671d2005-02-01 20:30:00 +0000316 break;
sewardjc6f970f2012-04-02 21:54:49 +0000317#if 0
cerion487e4c92005-02-04 16:28:19 +0000318 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000319 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000320 getAllocableRegs_PPC ( &n_available_real_regs,
321 &available_real_regs, mode64 );
322 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
323 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
324 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000325 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
326 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000327 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
328 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000329 iselSB = iselSB_PPC;
sewardj010ac542011-05-29 09:29:18 +0000330 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*,void*))
331 emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000332 host_is_bigendian = True;
333 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000334 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj010ac542011-05-29 09:29:18 +0000335 /* return-to-dispatcher scheme */
336 vassert(vta->dispatch_unassisted == NULL);
337 vassert(vta->dispatch_assisted == NULL);
cerion487e4c92005-02-04 16:28:19 +0000338 break;
339
cerionf0de28c2005-12-13 20:21:11 +0000340 case VexArchPPC64:
341 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000342 getAllocableRegs_PPC ( &n_available_real_regs,
343 &available_real_regs, mode64 );
344 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
345 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
346 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000347 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
348 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000349 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
350 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000351 iselSB = iselSB_PPC;
sewardj010ac542011-05-29 09:29:18 +0000352 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*,void*))
353 emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000354 host_is_bigendian = True;
355 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000356 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
sewardj010ac542011-05-29 09:29:18 +0000357 /* return-to-dispatcher scheme */
358 vassert(vta->dispatch_unassisted == NULL);
359 vassert(vta->dispatch_assisted == NULL);
cerionf0de28c2005-12-13 20:21:11 +0000360 break;
361
sewardj2019a972011-03-07 16:04:07 +0000362 case VexArchS390X:
363 mode64 = True;
364 getAllocableRegs_S390 ( &n_available_real_regs,
365 &available_real_regs, mode64 );
366 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
367 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
368 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
369 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
370 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
371 ppInstr = (void(*)(HInstr*, Bool)) ppS390Instr;
372 ppReg = (void(*)(HReg)) ppHRegS390;
373 iselSB = iselSB_S390;
sewardj010ac542011-05-29 09:29:18 +0000374 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*,void*))
375 emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000376 host_is_bigendian = True;
377 host_word_type = Ity_I64;
378 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj010ac542011-05-29 09:29:18 +0000379 /* return-to-dispatcher scheme */
380 vassert(vta->dispatch_unassisted == NULL);
381 vassert(vta->dispatch_assisted == NULL);
sewardj2019a972011-03-07 16:04:07 +0000382 break;
sewardjc6f970f2012-04-02 21:54:49 +0000383#endif
sewardj6c299f32009-12-31 18:00:12 +0000384 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000385 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000386 getAllocableRegs_ARM ( &n_available_real_regs,
387 &available_real_regs );
sewardj2a1ed8e2009-12-31 19:26:03 +0000388 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
389 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
390 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
391 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
392 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
393 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
394 ppReg = (void(*)(HReg)) ppHRegARM;
395 iselSB = iselSB_ARM;
sewardjc6f970f2012-04-02 21:54:49 +0000396 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
397 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000398 emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000399 host_is_bigendian = False;
400 host_word_type = Ity_I32;
401 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000402 break;
403
sewardjf13a16a2004-07-05 17:10:14 +0000404 default:
sewardj6c299f32009-12-31 18:00:12 +0000405 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000406 }
407
sewardj2a9ad022004-11-25 02:46:58 +0000408
sewardj17c7f952005-12-15 14:02:34 +0000409 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000410
sewardjbef170b2004-12-21 01:23:00 +0000411 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000412 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
413 disInstrFn = disInstr_X86;
414 specHelper = guest_x86_spechelper;
415 guest_sizeB = sizeof(VexGuestX86State);
416 guest_word_type = Ity_I32;
417 guest_layout = &x86guest_layout;
418 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
419 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
420 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
421 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
422 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
423 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000424 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000425 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardjce02aa72006-01-12 12:27:58 +0000426 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
427 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
428 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000429 break;
sewardj2a9ad022004-11-25 02:46:58 +0000430
sewardj44d494d2005-01-20 20:26:33 +0000431 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000432 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
433 disInstrFn = disInstr_AMD64;
434 specHelper = guest_amd64_spechelper;
435 guest_sizeB = sizeof(VexGuestAMD64State);
436 guest_word_type = Ity_I64;
437 guest_layout = &amd64guest_layout;
438 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
439 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
440 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
441 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
442 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
443 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000444 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000445 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000446 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000447 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
448 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000449 break;
sewardjc6f970f2012-04-02 21:54:49 +0000450#if 0
cerionaabdfbf2005-01-29 12:56:15 +0000451 case VexArchPPC32:
452 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000453 disInstrFn = disInstr_PPC;
cerionaabdfbf2005-01-29 12:56:15 +0000454 specHelper = guest_ppc32_spechelper;
455 guest_sizeB = sizeof(VexGuestPPC32State);
456 guest_word_type = Ity_I32;
457 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000458 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
459 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000460 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000461 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000462 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000463 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
464 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000465 break;
466
cerionf0de28c2005-12-13 20:21:11 +0000467 case VexArchPPC64:
468 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000469 disInstrFn = disInstr_PPC;
cerionf0de28c2005-12-13 20:21:11 +0000470 specHelper = guest_ppc64_spechelper;
471 guest_sizeB = sizeof(VexGuestPPC64State);
472 guest_word_type = Ity_I64;
473 guest_layout = &ppc64Guest_layout;
474 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
475 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000476 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000477 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000478 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
479 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
480 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
481 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000482 break;
483
sewardj2019a972011-03-07 16:04:07 +0000484 case VexArchS390X:
485 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
486 disInstrFn = disInstr_S390;
487 specHelper = guest_s390x_spechelper;
488 guest_sizeB = sizeof(VexGuestS390XState);
489 guest_word_type = Ity_I64;
490 guest_layout = &s390xGuest_layout;
491 offB_TISTART = offsetof(VexGuestS390XState,guest_TISTART);
492 offB_TILEN = offsetof(VexGuestS390XState,guest_TILEN);
493 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
494 vassert(0 == sizeof(VexGuestS390XState) % 16);
495 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TISTART ) == 8);
496 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TILEN ) == 8);
497 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
498 break;
sewardjc6f970f2012-04-02 21:54:49 +0000499#endif
sewardj6c299f32009-12-31 18:00:12 +0000500 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000501 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
502 disInstrFn = disInstr_ARM;
503 specHelper = guest_arm_spechelper;
504 guest_sizeB = sizeof(VexGuestARMState);
505 guest_word_type = Ity_I32;
506 guest_layout = &armGuest_layout;
507 offB_TISTART = offsetof(VexGuestARMState,guest_TISTART);
508 offB_TILEN = offsetof(VexGuestARMState,guest_TILEN);
509 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
510 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
511 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
512 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000513 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
514 vassert(0 == sizeof(VexGuestARMState) % 16);
515 vassert(sizeof( ((VexGuestARMState*)0)->guest_TISTART) == 4);
516 vassert(sizeof( ((VexGuestARMState*)0)->guest_TILEN ) == 4);
517 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
518 break;
519
sewardjf13a16a2004-07-05 17:10:14 +0000520 default:
sewardj887a11a2004-07-05 17:26:47 +0000521 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000522 }
523
sewardjbc161a42011-06-07 21:28:38 +0000524 /* Set up result struct. */
525 VexTranslateResult res;
526 res.status = VexTransOK;
527 res.n_sc_extents = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000528 res.offs_profInc = -1;
sewardjbc161a42011-06-07 21:28:38 +0000529
sewardj9df271d2004-12-31 22:37:42 +0000530 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000531 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000532 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000533 we are simulating one flavour of an architecture a different
534 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000535 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000536 }
sewardj2a9ad022004-11-25 02:46:58 +0000537
sewardj2d6b14a2005-11-23 04:25:07 +0000538 vexAllocSanityCheck();
539
sewardjf48ac192004-10-29 00:41:29 +0000540 if (vex_traceflags & VEX_TRACE_FE)
541 vex_printf("\n------------------------"
542 " Front end "
543 "------------------------\n\n");
544
sewardjdd40fdf2006-12-24 02:20:24 +0000545 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000546 &res.n_sc_extents,
sewardjc716aea2006-01-17 01:48:46 +0000547 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000548 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000549 vta->guest_bytes,
550 vta->guest_bytes_addr,
551 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000552 host_is_bigendian,
sewardja5f55da2006-04-30 23:37:32 +0000553 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000554 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000555 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000556 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000557 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000558 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000559 offB_TISTART,
sewardjc6f970f2012-04-02 21:54:49 +0000560 offB_TILEN,
561 offB_GUEST_IP,
562 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000563
sewardj2d6b14a2005-11-23 04:25:07 +0000564 vexAllocSanityCheck();
565
sewardjdd40fdf2006-12-24 02:20:24 +0000566 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000567 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000568 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000569 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000570 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000571 }
sewardjaa59f942004-10-09 09:34:36 +0000572
sewardj17c7f952005-12-15 14:02:34 +0000573 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
574 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
575 for (i = 0; i < vta->guest_extents->n_used; i++) {
576 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000577 }
578
sewardjaa59f942004-10-09 09:34:36 +0000579 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000580 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000581 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000582 vex_printf("can't show code due to extents > 1\n");
583 } else {
584 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000585 UChar* p = (UChar*)vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000586 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000587 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000588 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
589 guest_bytes_read );
590 for (i = 0; i < guest_bytes_read; i++) {
591 UInt b = (UInt)p[i];
592 vex_printf(" %02x", b );
593 sum = (sum << 1) ^ b;
594 }
595 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000596 }
sewardjaa59f942004-10-09 09:34:36 +0000597 }
598
599 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000600 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000601 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000602
sewardj2d6b14a2005-11-23 04:25:07 +0000603 vexAllocSanityCheck();
604
sewardjedf4d692004-08-17 13:52:58 +0000605 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000606 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000607 vta->guest_bytes_addr,
608 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000609 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000610 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000611
sewardjf48ac192004-10-29 00:41:29 +0000612 if (vex_traceflags & VEX_TRACE_OPT1) {
613 vex_printf("\n------------------------"
614 " After pre-instr IR optimisation "
615 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000616 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000617 vex_printf("\n");
618 }
619
sewardj2d6b14a2005-11-23 04:25:07 +0000620 vexAllocSanityCheck();
621
sewardjf13a16a2004-07-05 17:10:14 +0000622 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000623 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000624 irsb = vta->instrument1(vta->callback_opaque,
625 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000626 vta->guest_extents,
627 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000628 vexAllocSanityCheck();
629
sewardj17c7f952005-12-15 14:02:34 +0000630 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000631 irsb = vta->instrument2(vta->callback_opaque,
632 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000633 vta->guest_extents,
634 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000635
sewardjf48ac192004-10-29 00:41:29 +0000636 if (vex_traceflags & VEX_TRACE_INST) {
637 vex_printf("\n------------------------"
638 " After instrumentation "
639 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000640 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000641 vex_printf("\n");
642 }
643
sewardj17c7f952005-12-15 14:02:34 +0000644 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000645 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000646 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000647
sewardj9578a8b2004-11-04 19:44:48 +0000648 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000649 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000650 do_deadcode_BB( irsb );
651 irsb = cprop_BB( irsb );
652 do_deadcode_BB( irsb );
653 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000654 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000655 }
656
sewardj2d6b14a2005-11-23 04:25:07 +0000657 vexAllocSanityCheck();
658
sewardj9578a8b2004-11-04 19:44:48 +0000659 if (vex_traceflags & VEX_TRACE_OPT2) {
660 vex_printf("\n------------------------"
661 " After post-instr IR optimisation "
662 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000663 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000664 vex_printf("\n");
665 }
666
sewardjf9517d02005-11-28 13:39:37 +0000667 /* Turn it into virtual-registerised code. Build trees -- this
668 also throws away any dead bindings. */
sewardjc6f970f2012-04-02 21:54:49 +0000669 max_ga = ado_treebuild_BB( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000670
sewardjbe1b6ff2007-08-28 06:06:27 +0000671 if (vta->finaltidy) {
672 irsb = vta->finaltidy(irsb);
673 }
674
sewardj2d6b14a2005-11-23 04:25:07 +0000675 vexAllocSanityCheck();
676
sewardjf48ac192004-10-29 00:41:29 +0000677 if (vex_traceflags & VEX_TRACE_TREES) {
678 vex_printf("\n------------------------"
679 " After tree-building "
680 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000681 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000682 vex_printf("\n");
683 }
684
sewardje908c422005-02-04 21:18:16 +0000685 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000686 if (0) {
687 *(vta->host_bytes_used) = 0;
688 res.status = VexTransOK; return res;
689 }
sewardje908c422005-02-04 21:18:16 +0000690 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000691
sewardjf48ac192004-10-29 00:41:29 +0000692 if (vex_traceflags & VEX_TRACE_VCODE)
693 vex_printf("\n------------------------"
694 " Instruction selection "
695 "------------------------\n");
696
sewardjc6f970f2012-04-02 21:54:49 +0000697 /* No guest has its IP field at offset zero. If this fails it
698 means some transformation pass somewhere failed to update/copy
699 irsb->offsIP properly. */
700 vassert(irsb->offsIP >= 16);
701
702 vcode = iselSB ( irsb, vta->arch_host,
703 &vta->archinfo_host,
704 &vta->abiinfo_both,
705 offB_HOST_EvC_COUNTER,
706 offB_HOST_EvC_FAILADDR,
707 chainingAllowed,
708 vta->addProfInc,
709 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000710
sewardj2d6b14a2005-11-23 04:25:07 +0000711 vexAllocSanityCheck();
712
sewardjf48ac192004-10-29 00:41:29 +0000713 if (vex_traceflags & VEX_TRACE_VCODE)
714 vex_printf("\n");
715
sewardjf48ac192004-10-29 00:41:29 +0000716 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000717 for (i = 0; i < vcode->arr_used; i++) {
718 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000719 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000720 vex_printf("\n");
721 }
sewardjfbcaf332004-07-08 01:46:01 +0000722 vex_printf("\n");
723 }
sewardjfbcaf332004-07-08 01:46:01 +0000724
sewardjf13a16a2004-07-05 17:10:14 +0000725 /* Register allocate. */
726 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000727 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000728 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000729 genSpill, genReload, directReload,
730 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000731 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000732
sewardj2d6b14a2005-11-23 04:25:07 +0000733 vexAllocSanityCheck();
734
sewardjf48ac192004-10-29 00:41:29 +0000735 if (vex_traceflags & VEX_TRACE_RCODE) {
736 vex_printf("\n------------------------"
737 " Register-allocated code "
738 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000739 for (i = 0; i < rcode->arr_used; i++) {
740 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000741 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000742 vex_printf("\n");
743 }
sewardjfbcaf332004-07-08 01:46:01 +0000744 vex_printf("\n");
745 }
sewardjfbcaf332004-07-08 01:46:01 +0000746
sewardje908c422005-02-04 21:18:16 +0000747 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000748 if (0) {
749 *(vta->host_bytes_used) = 0;
750 res.status = VexTransOK; return res;
751 }
sewardje908c422005-02-04 21:18:16 +0000752 /* end HACK */
753
sewardj81bd5502004-07-21 18:49:27 +0000754 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000755 if (vex_traceflags & VEX_TRACE_ASM) {
756 vex_printf("\n------------------------"
757 " Assembly "
758 "------------------------\n\n");
759 }
760
sewardj81bd5502004-07-21 18:49:27 +0000761 out_used = 0; /* tracks along the host_bytes array */
762 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000763 HInstr* hi = rcode->arr[i];
764 Bool hi_isProfInc = False;
765 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
766 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000767 vex_printf("\n");
768 }
sewardjc6f970f2012-04-02 21:54:49 +0000769 j = emit( &hi_isProfInc,
770 insn_bytes, sizeof insn_bytes, hi, mode64,
771 vta->disp_cp_chain_me_to_slowEP,
772 vta->disp_cp_chain_me_to_fastEP,
773 vta->disp_cp_xindir,
774 vta->disp_cp_xassisted );
775 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000776 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000777 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000778 vex_printf("0%x ", (UInt)insn_bytes[k]);
779 else
780 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000781 vex_printf("\n\n");
782 }
sewardjc6f970f2012-04-02 21:54:49 +0000783 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000784 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000785 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000786 res.status = VexTransOutputFull;
787 return res;
sewardj81bd5502004-07-21 18:49:27 +0000788 }
sewardjc6f970f2012-04-02 21:54:49 +0000789 if (UNLIKELY(hi_isProfInc)) {
790 vassert(vta->addProfInc); /* else where did it come from? */
791 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
792 vassert(out_used >= 0);
793 res.offs_profInc = out_used;
794 }
795 { UChar* dst = &vta->host_bytes[out_used];
796 for (k = 0; k < j; k++) {
797 dst[k] = insn_bytes[k];
798 }
799 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000800 }
sewardj17c7f952005-12-15 14:02:34 +0000801 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000802 }
sewardj17c7f952005-12-15 14:02:34 +0000803 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000804
sewardj2d6b14a2005-11-23 04:25:07 +0000805 vexAllocSanityCheck();
806
807 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000808
sewardjf48ac192004-10-29 00:41:29 +0000809 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000810 res.status = VexTransOK;
811 return res;
sewardj35421a32004-07-05 13:12:34 +0000812}
813
814
sewardjc6f970f2012-04-02 21:54:49 +0000815/* --------- Chain/Unchain XDirects. --------- */
816
817VexInvalRange LibVEX_Chain ( VexArch arch_host,
818 void* place_to_chain,
819 void* disp_cp_chain_me_EXPECTED,
820 void* place_to_jump_to )
821{
822 VexInvalRange (*chainXDirect)(void*, void*, void*) = NULL;
823 switch (arch_host) {
824 case VexArchX86:
825 chainXDirect = chainXDirect_X86; break;
826 case VexArchAMD64:
827 chainXDirect = chainXDirect_AMD64; break;
828 case VexArchARM:
829 chainXDirect = chainXDirect_ARM; break;
830 default:
831 vassert(0);
832 }
833 vassert(chainXDirect);
834 VexInvalRange vir
835 = chainXDirect(place_to_chain, disp_cp_chain_me_EXPECTED,
836 place_to_jump_to);
837 return vir;
838}
839
840VexInvalRange LibVEX_UnChain ( VexArch arch_host,
841 void* place_to_unchain,
842 void* place_to_jump_to_EXPECTED,
843 void* disp_cp_chain_me )
844{
845 VexInvalRange (*unchainXDirect)(void*, void*, void*) = NULL;
846 switch (arch_host) {
847 case VexArchX86:
848 unchainXDirect = unchainXDirect_X86; break;
849 case VexArchAMD64:
850 unchainXDirect = unchainXDirect_AMD64; break;
851 case VexArchARM:
852 unchainXDirect = unchainXDirect_ARM; break;
853 default:
854 vassert(0);
855 }
856 vassert(unchainXDirect);
857 VexInvalRange vir
858 = unchainXDirect(place_to_unchain, place_to_jump_to_EXPECTED,
859 disp_cp_chain_me);
860 return vir;
861}
862
863Int LibVEX_evCheckSzB ( VexArch arch_host )
864{
865 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
866 if (UNLIKELY(cached == 0)) {
867 switch (arch_host) {
868 case VexArchX86:
869 cached = evCheckSzB_X86(); break;
870 case VexArchAMD64:
871 cached = evCheckSzB_AMD64(); break;
872 case VexArchARM:
873 cached = evCheckSzB_ARM(); break;
874 default:
875 vassert(0);
876 }
877 }
878 return cached;
879}
880
881VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
882 void* place_to_patch,
883 ULong* location_of_counter )
884{
885 VexInvalRange (*patchProfInc)(void*,ULong*) = NULL;
886 switch (arch_host) {
887 case VexArchX86:
888 patchProfInc = patchProfInc_X86; break;
889 case VexArchAMD64:
890 patchProfInc = patchProfInc_AMD64; break;
891 case VexArchARM:
892 patchProfInc = patchProfInc_ARM; break;
893 default:
894 vassert(0);
895 }
896 vassert(patchProfInc);
897 VexInvalRange vir
898 = patchProfInc(place_to_patch, location_of_counter);
899 return vir;
900}
901
902
sewardj893aada2004-11-29 19:57:54 +0000903/* --------- Emulation warnings. --------- */
904
905HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
906{
907 switch (ew) {
908 case EmWarn_NONE:
909 return "none";
910 case EmWarn_X86_x87exns:
911 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000912 case EmWarn_X86_x87precision:
913 return "Selection of non-80-bit x87 FP precision";
914 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000915 return "Unmasking SSE FP exceptions";
916 case EmWarn_X86_fz:
917 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
918 case EmWarn_X86_daz:
919 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000920 case EmWarn_X86_acFlag:
921 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +0000922 case EmWarn_PPCexns:
923 return "Unmasking PPC32/64 FP exceptions";
924 case EmWarn_PPC64_redir_overflow:
925 return "PPC64 function redirection stack overflow";
926 case EmWarn_PPC64_redir_underflow:
927 return "PPC64 function redirection stack underflow";
sewardj893aada2004-11-29 19:57:54 +0000928 default:
929 vpanic("LibVEX_EmWarn_string: unknown warning");
930 }
931}
sewardj35421a32004-07-05 13:12:34 +0000932
sewardj5117ce12006-01-27 21:20:15 +0000933/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +0000934
935const HChar* LibVEX_ppVexArch ( VexArch arch )
936{
937 switch (arch) {
938 case VexArch_INVALID: return "INVALID";
939 case VexArchX86: return "X86";
940 case VexArchAMD64: return "AMD64";
941 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000942 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +0000943 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +0000944 case VexArchS390X: return "S390X";
sewardjbef170b2004-12-21 01:23:00 +0000945 default: return "VexArch???";
946 }
947}
948
sewardj5117ce12006-01-27 21:20:15 +0000949const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +0000950{
sewardj5117ce12006-01-27 21:20:15 +0000951 HChar* str = show_hwcaps(arch,hwcaps);
952 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +0000953}
954
sewardj5117ce12006-01-27 21:20:15 +0000955
sewardj27e1dd62005-06-30 11:49:14 +0000956/* Write default settings info *vai. */
957void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
958{
sewardj5117ce12006-01-27 21:20:15 +0000959 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +0000960 vai->ppc_cache_line_szB = 0;
sewardje971c6a2010-09-03 15:49:57 +0000961 vai->ppc_dcbz_szB = 0;
962 vai->ppc_dcbzl_szB = 0;
963
sewardj27e1dd62005-06-30 11:49:14 +0000964}
965
sewardjdd40fdf2006-12-24 02:20:24 +0000966/* Write default settings info *vbi. */
967void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +0000968{
sewardjdd40fdf2006-12-24 02:20:24 +0000969 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +0000970 vbi->guest_amd64_assume_fs_is_zero = False;
971 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000972 vbi->guest_ppc_zap_RZ_at_blr = False;
973 vbi->guest_ppc_zap_RZ_at_bl = NULL;
974 vbi->guest_ppc_sc_continues_at_LR = False;
975 vbi->host_ppc_calls_use_fndescrs = False;
976 vbi->host_ppc32_regalign_int64_args = False;
sewardjaca070a2006-10-17 00:28:22 +0000977}
978
sewardj27e1dd62005-06-30 11:49:14 +0000979
sewardj5117ce12006-01-27 21:20:15 +0000980/* Return a string showing the hwcaps in a nice way. The string will
981 be NULL for invalid combinations of flags, so these functions also
982 serve as a way to validate hwcaps values. */
983
984static HChar* show_hwcaps_x86 ( UInt hwcaps )
985{
986 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
sewardj536fbab2010-07-29 15:39:05 +0000987 switch (hwcaps) {
988 case 0:
989 return "x86-sse0";
990 case VEX_HWCAPS_X86_SSE1:
991 return "x86-sse1";
992 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
993 return "x86-sse1-sse2";
994 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
995 | VEX_HWCAPS_X86_LZCNT:
996 return "x86-sse1-sse2-lzcnt";
997 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
998 | VEX_HWCAPS_X86_SSE3:
999 return "x86-sse1-sse2-sse3";
1000 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1001 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
1002 return "x86-sse1-sse2-sse3-lzcnt";
1003 default:
1004 return NULL;
1005 }
sewardj5117ce12006-01-27 21:20:15 +00001006}
1007
1008static HChar* show_hwcaps_amd64 ( UInt hwcaps )
1009{
sewardje9d8a262009-07-01 08:06:34 +00001010 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1011 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001012 do CX16. Still, we can handle that case. LZCNT is similarly
1013 orthogonal. */
1014 switch (hwcaps) {
1015 case 0:
1016 return "amd64-sse2";
1017 case VEX_HWCAPS_AMD64_SSE3:
1018 return "amd64-sse3";
1019 case VEX_HWCAPS_AMD64_CX16:
1020 return "amd64-sse2-cx16";
1021 case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16:
1022 return "amd64-sse3-cx16";
1023 case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_LZCNT:
1024 return "amd64-sse3-lzcnt";
1025 case VEX_HWCAPS_AMD64_CX16 | VEX_HWCAPS_AMD64_LZCNT:
1026 return "amd64-sse2-cx16-lzcnt";
1027 case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16
1028 | VEX_HWCAPS_AMD64_LZCNT:
1029 return "amd64-sse3-cx16-lzcnt";
1030
1031 default:
1032 return NULL;
1033 }
sewardj5117ce12006-01-27 21:20:15 +00001034}
1035
1036static HChar* show_hwcaps_ppc32 ( UInt hwcaps )
1037{
1038 /* Monotonic with complications. Basically V > F > baseline,
1039 but once you have F then you can have FX or GX too. */
1040 const UInt F = VEX_HWCAPS_PPC32_F;
1041 const UInt V = VEX_HWCAPS_PPC32_V;
1042 const UInt FX = VEX_HWCAPS_PPC32_FX;
1043 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001044 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardj5117ce12006-01-27 21:20:15 +00001045 UInt c = hwcaps;
1046 if (c == 0) return "ppc32-int";
1047 if (c == F) return "ppc32-int-flt";
1048 if (c == (F|FX)) return "ppc32-int-flt-FX";
1049 if (c == (F|GX)) return "ppc32-int-flt-GX";
1050 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1051 if (c == (F|V)) return "ppc32-int-flt-vmx";
1052 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1053 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1054 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardj66d5ef22011-04-15 11:55:00 +00001055 if (c == (F|V|FX|GX|VX)) return "ppc32-int-flt-vmx-FX-GX-VX";
sewardj5117ce12006-01-27 21:20:15 +00001056 return NULL;
1057}
1058
1059static HChar* show_hwcaps_ppc64 ( UInt hwcaps )
1060{
1061 /* Monotonic with complications. Basically V > baseline(==F),
1062 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001063 const UInt V = VEX_HWCAPS_PPC64_V;
1064 const UInt FX = VEX_HWCAPS_PPC64_FX;
1065 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001066 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardj5117ce12006-01-27 21:20:15 +00001067 UInt c = hwcaps;
1068 if (c == 0) return "ppc64-int-flt";
1069 if (c == FX) return "ppc64-int-flt-FX";
1070 if (c == GX) return "ppc64-int-flt-GX";
1071 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1072 if (c == V) return "ppc64-int-flt-vmx";
1073 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1074 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1075 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardj66d5ef22011-04-15 11:55:00 +00001076 if (c == (V|FX|GX|VX)) return "ppc64-int-flt-vmx-FX-GX-VX";
sewardj5117ce12006-01-27 21:20:15 +00001077 return NULL;
1078}
1079
1080static HChar* show_hwcaps_arm ( UInt hwcaps )
1081{
sewardjec0d9a02010-08-22 12:54:56 +00001082 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1083 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1084 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1085 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1086 case 5:
1087 if (N)
1088 return NULL;
1089 if (vfp)
1090 return "ARMv5-vfp";
1091 else
1092 return "ARMv5";
1093 return NULL;
1094 case 6:
1095 if (N)
1096 return NULL;
1097 if (vfp)
1098 return "ARMv6-vfp";
1099 else
1100 return "ARMv6";
1101 return NULL;
1102 case 7:
1103 if (vfp) {
1104 if (N)
1105 return "ARMv7-vfp-neon";
1106 else
1107 return "ARMv7-vfp";
1108 } else {
1109 if (N)
1110 return "ARMv7-neon";
1111 else
1112 return "ARMv7";
1113 }
1114 default:
1115 return NULL;
1116 }
sewardj5117ce12006-01-27 21:20:15 +00001117 return NULL;
1118}
1119
sewardj2019a972011-03-07 16:04:07 +00001120static HChar* show_hwcaps_s390x ( UInt hwcaps )
1121{
sewardjd07b8562011-04-27 11:58:22 +00001122 static const HChar prefix[] = "s390x";
1123 static const HChar facilities[][6] = {
1124 { "ldisp" },
1125 { "eimm" },
1126 { "gie" },
1127 { "dfp" },
1128 { "fgx" },
1129 };
1130 static HChar buf[sizeof facilities + sizeof prefix + 1];
1131 static HChar *p;
1132
1133 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001134
sewardj652b56a2011-04-13 15:38:17 +00001135 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1136
sewardjd07b8562011-04-27 11:58:22 +00001137 p = buf + vex_sprintf(buf, "%s", prefix);
1138 if (hwcaps & VEX_HWCAPS_S390X_LDISP)
1139 p = p + vex_sprintf(p, "-%s", facilities[0]);
1140 if (hwcaps & VEX_HWCAPS_S390X_EIMM)
1141 p = p + vex_sprintf(p, "-%s", facilities[1]);
1142 if (hwcaps & VEX_HWCAPS_S390X_GIE)
1143 p = p + vex_sprintf(p, "-%s", facilities[2]);
1144 if (hwcaps & VEX_HWCAPS_S390X_DFP)
1145 p = p + vex_sprintf(p, "-%s", facilities[3]);
1146 if (hwcaps & VEX_HWCAPS_S390X_FGX)
1147 p = p + vex_sprintf(p, "-%s", facilities[4]);
sewardj2019a972011-03-07 16:04:07 +00001148
sewardjd07b8562011-04-27 11:58:22 +00001149 /* If there are no facilities, add "zarch" */
1150 if (hwcaps == 0)
1151 vex_sprintf(p, "-%s", "zarch");
1152
1153 return buf;
sewardj2019a972011-03-07 16:04:07 +00001154}
1155
sewardj5117ce12006-01-27 21:20:15 +00001156/* ---- */
1157static HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
1158{
1159 switch (arch) {
sewardj3fd39672006-01-27 22:05:55 +00001160 case VexArchX86: return show_hwcaps_x86(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001161 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1162 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1163 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
sewardj3fd39672006-01-27 22:05:55 +00001164 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardj2019a972011-03-07 16:04:07 +00001165 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001166 default: return NULL;
1167 }
1168}
1169
1170static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1171{
1172 return show_hwcaps(arch,hwcaps) != NULL;
1173}
1174
1175
sewardj35421a32004-07-05 13:12:34 +00001176/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001177/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001178/*---------------------------------------------------------------*/