1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*---------------------------------------------------------------*/
4 /*--- Begin main_main.c ---*/
5 /*---------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2004-2017 OpenWorks LLP
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
29 Neither the names of the U.S. Department of Energy nor the
30 University of California nor the names of its contributors may be
31 used to endorse or promote products derived from this software
32 without prior written permission.
36 #include "libvex_emnote.h"
37 #include "libvex_guest_x86.h"
38 #include "libvex_guest_amd64.h"
39 #include "libvex_guest_arm.h"
40 #include "libvex_guest_arm64.h"
41 #include "libvex_guest_ppc32.h"
42 #include "libvex_guest_ppc64.h"
43 #include "libvex_guest_s390x.h"
44 #include "libvex_guest_mips32.h"
45 #include "libvex_guest_mips64.h"
47 #include "main_globals.h"
48 #include "main_util.h"
49 #include "host_generic_regs.h"
52 #include "host_x86_defs.h"
53 #include "host_amd64_defs.h"
54 #include "host_ppc_defs.h"
55 #include "host_arm_defs.h"
56 #include "host_arm64_defs.h"
57 #include "host_s390_defs.h"
58 #include "host_mips_defs.h"
59 #include "host_nanomips_defs.h"
61 #include "guest_generic_bb_to_IR.h"
62 #include "guest_x86_defs.h"
63 #include "guest_amd64_defs.h"
64 #include "guest_arm_defs.h"
65 #include "guest_arm64_defs.h"
66 #include "guest_ppc_defs.h"
67 #include "guest_s390_defs.h"
68 #include "guest_mips_defs.h"
69 #include "guest_nanomips_defs.h"
71 #include "host_generic_simd128.h"
73 /* For each architecture <arch>, we define 2 macros:
74 <arch>FN that has as argument a pointer (typically to a function
75 or the return value of a function).
76 <arch>ST that has as argument a statement.
77 If main_main.c is compiled for <arch>, then these macros just expand
79 Otherwise, the macros expand to respectively NULL and vassert(0).
80 These macros are used to avoid introducing dependencies to object
81 files not needed for the (only) architecture we are compiling for.
83 To still compile the below for all supported architectures, define
84 VEXMULTIARCH. This is used by the file multiarch_main_main.c */
86 #if defined(VGA_x86) || defined(VEXMULTIARCH)
91 #define X86ST(f) vassert(0)
94 #if defined(VGA_amd64) || defined(VEXMULTIARCH)
98 #define AMD64FN(f) NULL
99 #define AMD64ST(f) vassert(0)
102 #if defined(VGA_ppc32) || defined(VEXMULTIARCH)
106 #define PPC32FN(f) NULL
107 #define PPC32ST(f) vassert(0)
110 #if defined(VGA_ppc64be) || defined(VGA_ppc64le) || defined(VEXMULTIARCH)
114 #define PPC64FN(f) NULL
115 #define PPC64ST(f) vassert(0)
118 #if defined(VGA_s390x) || defined(VEXMULTIARCH)
122 #define S390FN(f) NULL
123 #define S390ST(f) vassert(0)
126 #if defined(VGA_arm) || defined(VEXMULTIARCH)
130 #define ARMFN(f) NULL
131 #define ARMST(f) vassert(0)
134 #if defined(VGA_arm64) || defined(VEXMULTIARCH)
138 #define ARM64FN(f) NULL
139 #define ARM64ST(f) vassert(0)
142 #if defined(VGA_mips32) || defined(VEXMULTIARCH)
143 #define MIPS32FN(f) f
144 #define MIPS32ST(f) f
146 #define MIPS32FN(f) NULL
147 #define MIPS32ST(f) vassert(0)
150 #if defined(VGA_mips64) || defined(VEXMULTIARCH)
151 #define MIPS64FN(f) f
152 #define MIPS64ST(f) f
154 #define MIPS64FN(f) NULL
155 #define MIPS64ST(f) vassert(0)
158 #if defined(VGA_nanomips) || defined(VEXMULTIARCH)
159 #define NANOMIPSFN(f) f
160 #define NANOMIPSST(f) f
162 #define NANOMIPSFN(f) NULL
163 #define NANOMIPSST(f) vassert(0)
166 /* This file contains the top level interface to the library. */
168 /* --------- fwds ... --------- */
170 static void check_hwcaps ( VexArch arch
, UInt hwcaps
);
171 static const HChar
* show_hwcaps ( VexArch arch
, UInt hwcaps
);
172 static IRType
arch_word_size ( VexArch arch
);
174 /* --------- helpers --------- */
176 __attribute__((noinline
))
177 static UInt
udiv32 ( UInt x
, UInt y
) { return x
/y
; }
178 __attribute__((noinline
))
179 static Int
sdiv32 ( Int x
, Int y
) { return x
/y
; }
182 /* --------- Initialise the library. --------- */
184 /* Exported to library client. */
186 void LibVEX_default_VexControl ( /*OUT*/ VexControl
* vcon
)
188 vex_bzero(vcon
, sizeof(*vcon
));
189 vcon
->iropt_verbosity
= 0;
190 vcon
->iropt_level
= 2;
191 vcon
->iropt_register_updates_default
= VexRegUpdUnwindregsAtMemAccess
;
192 vcon
->iropt_unroll_thresh
= 120;
193 vcon
->guest_max_insns
= 60;
194 vcon
->guest_chase
= True
;
195 vcon
->regalloc_version
= 3;
199 /* Exported to library client. */
202 /* failure exit function */
203 __attribute__ ((noreturn
))
204 void (*failure_exit
) ( void ),
205 /* logging output function */
206 void (*log_bytes
) ( const HChar
*, SizeT nbytes
),
207 /* debug paranoia level */
210 const VexControl
* vcon
213 /* First off, do enough minimal setup so that the following
214 assertions can fail in a sane fashion, if need be. */
215 vex_failure_exit
= failure_exit
;
216 vex_log_bytes
= log_bytes
;
218 /* Now it's safe to check parameters for sanity. */
219 vassert(!vex_initdone
);
220 vassert(failure_exit
);
222 vassert(debuglevel
>= 0);
224 vassert(vcon
->iropt_verbosity
>= 0);
225 vassert(vcon
->iropt_level
>= 0);
226 vassert(vcon
->iropt_level
<= 2);
227 vassert(vcon
->iropt_unroll_thresh
>= 0);
228 vassert(vcon
->iropt_unroll_thresh
<= 400);
229 vassert(vcon
->guest_max_insns
>= 1);
230 vassert(vcon
->guest_max_insns
<= 100);
231 vassert(vcon
->guest_chase
== False
|| vcon
->guest_chase
== True
);
232 vassert(vcon
->regalloc_version
== 2 || vcon
->regalloc_version
== 3);
234 /* Check that Vex has been built with sizes of basic types as
235 stated in priv/libvex_basictypes.h. Failure of any of these is
236 a serious configuration error and should be corrected
237 immediately. If any of these assertions fail you can fully
238 expect Vex not to work properly, if at all. */
240 vassert(1 == sizeof(UChar
));
241 vassert(1 == sizeof(Char
));
242 vassert(2 == sizeof(UShort
));
243 vassert(2 == sizeof(Short
));
244 vassert(4 == sizeof(UInt
));
245 vassert(4 == sizeof(Int
));
246 vassert(8 == sizeof(ULong
));
247 vassert(8 == sizeof(Long
));
248 vassert(4 == sizeof(Float
));
249 vassert(8 == sizeof(Double
));
250 vassert(1 == sizeof(Bool
));
251 vassert(4 == sizeof(Addr32
));
252 vassert(8 == sizeof(Addr64
));
253 vassert(16 == sizeof(U128
));
254 vassert(16 == sizeof(V128
));
255 vassert(32 == sizeof(U256
));
257 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
258 vassert(sizeof(void*) == sizeof(int*));
259 vassert(sizeof(void*) == sizeof(HWord
));
260 vassert(sizeof(void*) == sizeof(Addr
));
261 vassert(sizeof(unsigned long) == sizeof(SizeT
));
263 vassert(VEX_HOST_WORDSIZE
== sizeof(void*));
264 vassert(VEX_HOST_WORDSIZE
== sizeof(HWord
));
266 /* These take a lot of space, so make sure we don't have
267 any unnoticed size regressions. */
268 if (VEX_HOST_WORDSIZE
== 4) {
269 vassert(sizeof(IRExpr
) == 16);
270 vassert(sizeof(IRStmt
) == 20 /* x86 */
271 || sizeof(IRStmt
) == 24 /* arm */);
273 vassert(sizeof(IRExpr
) == 32);
274 vassert(sizeof(IRStmt
) == 32);
278 vassert(sizeof(HReg
) == 4);
279 /* If N_RREGUNIVERSE_REGS ever exceeds 64, the bitset fields in
280 RRegSet and HRegUsage will need to be changed to something
281 better than ULong. */
282 vassert(N_RREGUNIVERSE_REGS
== 64);
284 /* Check that signed integer division on the host rounds towards
285 zero. If not, h_calc_sdiv32_w_arm_semantics() won't work
287 /* 100.0 / 7.0 == 14.2857 */
288 vassert(udiv32(100, 7) == 14);
289 vassert(sdiv32(100, 7) == 14);
290 vassert(sdiv32(-100, 7) == -14); /* and not -15 */
291 vassert(sdiv32(100, -7) == -14); /* ditto */
292 vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
294 /* Really start up .. */
295 vex_debuglevel
= debuglevel
;
298 vexSetAllocMode ( VexAllocModeTEMP
);
302 /* --------- Make a translation. --------- */
304 /* KLUDGE: S390 need to know the hwcaps of the host when generating
305 code. But that info is not passed to emit_S390Instr. Only mode64 is
306 being passed. So, ideally, we want this passed as an argument, too.
307 Until then, we use a global variable. This variable is set as a side
308 effect of LibVEX_Translate. The variable is defined here rather than
309 in host_s390_defs.c to avoid having main_main.c dragging S390
310 object files in non VEXMULTIARCH. */
311 UInt s390_host_hwcaps
;
314 /* Exported to library client. */
316 IRSB
* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs
* vta
,
317 /*OUT*/ VexTranslateResult
* res
,
318 /*OUT*/ VexRegisterUpdates
* pxControl
)
320 IRExpr
* (*specHelper
) ( const HChar
*, IRExpr
**, IRStmt
**, Int
);
321 Bool (*preciseMemExnsFn
) ( Int
, Int
, VexRegisterUpdates
);
322 DisOneInstrFn disInstrFn
;
324 VexGuestLayout
* guest_layout
;
327 Int offB_CMSTART
, offB_CMLEN
, offB_GUEST_IP
, szB_GUEST_IP
;
328 IRType guest_word_type
;
329 IRType host_word_type
;
334 preciseMemExnsFn
= NULL
;
335 guest_word_type
= arch_word_size(vta
->arch_guest
);
336 host_word_type
= arch_word_size(vta
->arch_host
);
342 vassert(vex_initdone
);
343 vassert(vta
->needs_self_check
!= NULL
);
344 vassert(vta
->disp_cp_xassisted
!= NULL
);
345 /* Both the chainers and the indir are either NULL or non-NULL. */
346 if (vta
->disp_cp_chain_me_to_slowEP
!= NULL
) {
347 vassert(vta
->disp_cp_chain_me_to_fastEP
!= NULL
);
348 vassert(vta
->disp_cp_xindir
!= NULL
);
350 vassert(vta
->disp_cp_chain_me_to_fastEP
== NULL
);
351 vassert(vta
->disp_cp_xindir
== NULL
);
354 vexSetAllocModeTEMP_and_clear();
355 vexAllocSanityCheck();
357 vex_traceflags
= vta
->traceflags
;
359 /* KLUDGE: export hwcaps. */
360 if (vta
->arch_host
== VexArchS390X
) {
361 s390_host_hwcaps
= vta
->archinfo_host
.hwcaps
;
364 /* First off, check that the guest and host insn sets
367 switch (vta
->arch_guest
) {
371 = X86FN(guest_x86_state_requires_precise_mem_exns
);
372 disInstrFn
= X86FN(disInstr_X86
);
373 specHelper
= X86FN(guest_x86_spechelper
);
374 guest_layout
= X86FN(&x86guest_layout
);
375 offB_CMSTART
= offsetof(VexGuestX86State
,guest_CMSTART
);
376 offB_CMLEN
= offsetof(VexGuestX86State
,guest_CMLEN
);
377 offB_GUEST_IP
= offsetof(VexGuestX86State
,guest_EIP
);
378 szB_GUEST_IP
= sizeof( ((VexGuestX86State
*)0)->guest_EIP
);
379 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
);
380 vassert(0 == sizeof(VexGuestX86State
) % LibVEX_GUEST_STATE_ALIGN
);
381 vassert(sizeof( ((VexGuestX86State
*)0)->guest_CMSTART
) == 4);
382 vassert(sizeof( ((VexGuestX86State
*)0)->guest_CMLEN
) == 4);
383 vassert(sizeof( ((VexGuestX86State
*)0)->guest_NRADDR
) == 4);
388 = AMD64FN(guest_amd64_state_requires_precise_mem_exns
);
389 disInstrFn
= AMD64FN(disInstr_AMD64
);
390 specHelper
= AMD64FN(guest_amd64_spechelper
);
391 guest_layout
= AMD64FN(&amd64guest_layout
);
392 offB_CMSTART
= offsetof(VexGuestAMD64State
,guest_CMSTART
);
393 offB_CMLEN
= offsetof(VexGuestAMD64State
,guest_CMLEN
);
394 offB_GUEST_IP
= offsetof(VexGuestAMD64State
,guest_RIP
);
395 szB_GUEST_IP
= sizeof( ((VexGuestAMD64State
*)0)->guest_RIP
);
396 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
);
397 vassert(0 == sizeof(VexGuestAMD64State
) % LibVEX_GUEST_STATE_ALIGN
);
398 vassert(sizeof( ((VexGuestAMD64State
*)0)->guest_CMSTART
) == 8);
399 vassert(sizeof( ((VexGuestAMD64State
*)0)->guest_CMLEN
) == 8);
400 vassert(sizeof( ((VexGuestAMD64State
*)0)->guest_NRADDR
) == 8);
405 = PPC32FN(guest_ppc32_state_requires_precise_mem_exns
);
406 disInstrFn
= PPC32FN(disInstr_PPC
);
407 specHelper
= PPC32FN(guest_ppc32_spechelper
);
408 guest_layout
= PPC32FN(&ppc32Guest_layout
);
409 offB_CMSTART
= offsetof(VexGuestPPC32State
,guest_CMSTART
);
410 offB_CMLEN
= offsetof(VexGuestPPC32State
,guest_CMLEN
);
411 offB_GUEST_IP
= offsetof(VexGuestPPC32State
,guest_CIA
);
412 szB_GUEST_IP
= sizeof( ((VexGuestPPC32State
*)0)->guest_CIA
);
413 vassert(vta
->archinfo_guest
.endness
== VexEndnessBE
);
414 vassert(0 == sizeof(VexGuestPPC32State
) % LibVEX_GUEST_STATE_ALIGN
);
415 vassert(sizeof( ((VexGuestPPC32State
*)0)->guest_CMSTART
) == 4);
416 vassert(sizeof( ((VexGuestPPC32State
*)0)->guest_CMLEN
) == 4);
417 vassert(sizeof( ((VexGuestPPC32State
*)0)->guest_NRADDR
) == 4);
422 = PPC64FN(guest_ppc64_state_requires_precise_mem_exns
);
423 disInstrFn
= PPC64FN(disInstr_PPC
);
424 specHelper
= PPC64FN(guest_ppc64_spechelper
);
425 guest_layout
= PPC64FN(&ppc64Guest_layout
);
426 offB_CMSTART
= offsetof(VexGuestPPC64State
,guest_CMSTART
);
427 offB_CMLEN
= offsetof(VexGuestPPC64State
,guest_CMLEN
);
428 offB_GUEST_IP
= offsetof(VexGuestPPC64State
,guest_CIA
);
429 szB_GUEST_IP
= sizeof( ((VexGuestPPC64State
*)0)->guest_CIA
);
430 vassert(vta
->archinfo_guest
.endness
== VexEndnessBE
||
431 vta
->archinfo_guest
.endness
== VexEndnessLE
);
432 vassert(0 == sizeof(VexGuestPPC64State
) % LibVEX_GUEST_STATE_ALIGN
);
433 vassert(sizeof( ((VexGuestPPC64State
*)0)->guest_CMSTART
) == 8);
434 vassert(sizeof( ((VexGuestPPC64State
*)0)->guest_CMLEN
) == 8);
435 vassert(sizeof( ((VexGuestPPC64State
*)0)->guest_NRADDR
) == 8);
436 vassert(sizeof( ((VexGuestPPC64State
*)0)->guest_NRADDR_GPR2
) == 8);
441 = S390FN(guest_s390x_state_requires_precise_mem_exns
);
442 disInstrFn
= S390FN(disInstr_S390
);
443 specHelper
= S390FN(guest_s390x_spechelper
);
444 guest_layout
= S390FN(&s390xGuest_layout
);
445 offB_CMSTART
= offsetof(VexGuestS390XState
,guest_CMSTART
);
446 offB_CMLEN
= offsetof(VexGuestS390XState
,guest_CMLEN
);
447 offB_GUEST_IP
= offsetof(VexGuestS390XState
,guest_IA
);
448 szB_GUEST_IP
= sizeof( ((VexGuestS390XState
*)0)->guest_IA
);
449 vassert(vta
->archinfo_guest
.endness
== VexEndnessBE
);
450 vassert(0 == sizeof(VexGuestS390XState
) % LibVEX_GUEST_STATE_ALIGN
);
451 vassert(sizeof( ((VexGuestS390XState
*)0)->guest_CMSTART
) == 8);
452 vassert(sizeof( ((VexGuestS390XState
*)0)->guest_CMLEN
) == 8);
453 vassert(sizeof( ((VexGuestS390XState
*)0)->guest_NRADDR
) == 8);
458 = ARMFN(guest_arm_state_requires_precise_mem_exns
);
459 disInstrFn
= ARMFN(disInstr_ARM
);
460 specHelper
= ARMFN(guest_arm_spechelper
);
461 guest_layout
= ARMFN(&armGuest_layout
);
462 offB_CMSTART
= offsetof(VexGuestARMState
,guest_CMSTART
);
463 offB_CMLEN
= offsetof(VexGuestARMState
,guest_CMLEN
);
464 offB_GUEST_IP
= offsetof(VexGuestARMState
,guest_R15T
);
465 szB_GUEST_IP
= sizeof( ((VexGuestARMState
*)0)->guest_R15T
);
466 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
);
467 vassert(0 == sizeof(VexGuestARMState
) % LibVEX_GUEST_STATE_ALIGN
);
468 vassert(sizeof( ((VexGuestARMState
*)0)->guest_CMSTART
) == 4);
469 vassert(sizeof( ((VexGuestARMState
*)0)->guest_CMLEN
) == 4);
470 vassert(sizeof( ((VexGuestARMState
*)0)->guest_NRADDR
) == 4);
475 = ARM64FN(guest_arm64_state_requires_precise_mem_exns
);
476 disInstrFn
= ARM64FN(disInstr_ARM64
);
477 specHelper
= ARM64FN(guest_arm64_spechelper
);
478 guest_layout
= ARM64FN(&arm64Guest_layout
);
479 offB_CMSTART
= offsetof(VexGuestARM64State
,guest_CMSTART
);
480 offB_CMLEN
= offsetof(VexGuestARM64State
,guest_CMLEN
);
481 offB_GUEST_IP
= offsetof(VexGuestARM64State
,guest_PC
);
482 szB_GUEST_IP
= sizeof( ((VexGuestARM64State
*)0)->guest_PC
);
483 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
);
484 vassert(0 == sizeof(VexGuestARM64State
) % LibVEX_GUEST_STATE_ALIGN
);
485 vassert(sizeof( ((VexGuestARM64State
*)0)->guest_CMSTART
) == 8);
486 vassert(sizeof( ((VexGuestARM64State
*)0)->guest_CMLEN
) == 8);
487 vassert(sizeof( ((VexGuestARM64State
*)0)->guest_NRADDR
) == 8);
492 = MIPS32FN(guest_mips32_state_requires_precise_mem_exns
);
493 disInstrFn
= MIPS32FN(disInstr_MIPS
);
494 specHelper
= MIPS32FN(guest_mips32_spechelper
);
495 guest_layout
= MIPS32FN(&mips32Guest_layout
);
496 offB_CMSTART
= offsetof(VexGuestMIPS32State
,guest_CMSTART
);
497 offB_CMLEN
= offsetof(VexGuestMIPS32State
,guest_CMLEN
);
498 offB_GUEST_IP
= offsetof(VexGuestMIPS32State
,guest_PC
);
499 szB_GUEST_IP
= sizeof( ((VexGuestMIPS32State
*)0)->guest_PC
);
500 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
501 || vta
->archinfo_guest
.endness
== VexEndnessBE
);
502 vassert(0 == sizeof(VexGuestMIPS32State
) % LibVEX_GUEST_STATE_ALIGN
);
503 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_CMSTART
) == 4);
504 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_CMLEN
) == 4);
505 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_NRADDR
) == 4);
510 = MIPS64FN(guest_mips64_state_requires_precise_mem_exns
);
511 disInstrFn
= MIPS64FN(disInstr_MIPS
);
512 specHelper
= MIPS64FN(guest_mips64_spechelper
);
513 guest_layout
= MIPS64FN(&mips64Guest_layout
);
514 offB_CMSTART
= offsetof(VexGuestMIPS64State
,guest_CMSTART
);
515 offB_CMLEN
= offsetof(VexGuestMIPS64State
,guest_CMLEN
);
516 offB_GUEST_IP
= offsetof(VexGuestMIPS64State
,guest_PC
);
517 szB_GUEST_IP
= sizeof( ((VexGuestMIPS64State
*)0)->guest_PC
);
518 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
519 || vta
->archinfo_guest
.endness
== VexEndnessBE
);
520 vassert(0 == sizeof(VexGuestMIPS64State
) % LibVEX_GUEST_STATE_ALIGN
);
521 vassert(sizeof( ((VexGuestMIPS64State
*)0)->guest_CMSTART
) == 8);
522 vassert(sizeof( ((VexGuestMIPS64State
*)0)->guest_CMLEN
) == 8);
523 vassert(sizeof( ((VexGuestMIPS64State
*)0)->guest_NRADDR
) == 8);
526 case VexArchNANOMIPS
:
528 = NANOMIPSFN(guest_mips32_state_requires_precise_mem_exns
);
529 disInstrFn
= NANOMIPSFN(disInstr_nanoMIPS
);
530 specHelper
= NANOMIPSFN(guest_mips32_spechelper
);
531 guest_layout
= NANOMIPSFN(&mips32Guest_layout
);
532 offB_CMSTART
= offsetof(VexGuestMIPS32State
,guest_CMSTART
);
533 offB_CMLEN
= offsetof(VexGuestMIPS32State
,guest_CMLEN
);
534 offB_GUEST_IP
= offsetof(VexGuestMIPS32State
,guest_PC
);
535 szB_GUEST_IP
= sizeof( ((VexGuestMIPS32State
*)0)->guest_PC
);
536 vassert(vta
->archinfo_guest
.endness
== VexEndnessLE
537 || vta
->archinfo_guest
.endness
== VexEndnessBE
);
538 vassert(0 == sizeof(VexGuestMIPS32State
) % LibVEX_GUEST_STATE_ALIGN
);
539 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_CMSTART
) == 4);
540 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_CMLEN
) == 4);
541 vassert(sizeof( ((VexGuestMIPS32State
*)0)->guest_NRADDR
) == 4);
545 vpanic("LibVEX_Translate: unsupported guest insn set");
548 // Are the guest's hardware capabilities feasible. The function will
549 // not return if hwcaps are infeasible in some sense.
550 // FIXME: how can we know the guest's hardware capabilities?
551 check_hwcaps(vta
->arch_guest
, vta
->archinfo_guest
.hwcaps
);
553 res
->status
= VexTransOK
;
554 res
->n_sc_extents
= 0;
555 res
->offs_profInc
= -1;
556 res
->n_guest_instrs
= 0;
557 res
->n_uncond_in_trace
= 0;
558 res
->n_cond_in_trace
= 0;
561 /* yet more sanity checks ... */
562 if (vta
->arch_guest
== vta
->arch_host
) {
563 /* doesn't necessarily have to be true, but if it isn't it means
564 we are simulating one flavour of an architecture a different
565 flavour of the same architecture, which is pretty strange. */
566 vassert(vta
->archinfo_guest
.hwcaps
== vta
->archinfo_host
.hwcaps
);
568 vassert(vta
->archinfo_guest
.endness
== vta
->archinfo_host
.endness
);
572 vexAllocSanityCheck();
574 if (vex_traceflags
& VEX_TRACE_FE
)
575 vex_printf("\n------------------------"
577 "------------------------\n\n");
579 *pxControl
= vex_control
.iropt_register_updates_default
;
580 vassert(*pxControl
>= VexRegUpdSpAtMemAccess
581 && *pxControl
<= VexRegUpdAllregsAtEachInsn
);
583 irsb
= bb_to_IR ( vta
->guest_extents
,
585 &res
->n_guest_instrs
,
586 &res
->n_uncond_in_trace
,
587 &res
->n_cond_in_trace
,
589 vta
->callback_opaque
,
592 vta
->guest_bytes_addr
,
594 vta
->archinfo_host
.endness
,
597 &vta
->archinfo_guest
,
600 vta
->needs_self_check
,
601 vta
->preamble_function
,
607 vexAllocSanityCheck();
610 /* Access failure. */
611 vexSetAllocModeTEMP_and_clear();
615 vassert(vta
->guest_extents
->n_used
>= 1 && vta
->guest_extents
->n_used
<= 3);
616 vassert(vta
->guest_extents
->base
[0] == vta
->guest_bytes_addr
);
617 for (i
= 0; i
< vta
->guest_extents
->n_used
; i
++) {
618 vassert(vta
->guest_extents
->len
[i
] < 10000); /* sanity */
621 /* bb_to_IR() could have caused pxControl to change. */
622 vassert(*pxControl
>= VexRegUpdSpAtMemAccess
623 && *pxControl
<= VexRegUpdAllregsAtEachInsn
);
625 /* If debugging, show the raw guest bytes for this bb. */
626 if (0 || (vex_traceflags
& VEX_TRACE_FE
)) {
627 if (vta
->guest_extents
->n_used
> 1) {
628 vex_printf("can't show code due to extents > 1\n");
631 const UChar
* p
= vta
->guest_bytes
;
633 UInt guest_bytes_read
= (UInt
)vta
->guest_extents
->len
[0];
634 vex_printf("GuestBytes %lx %u ", vta
->guest_bytes_addr
,
636 for (i
= 0; i
< guest_bytes_read
; i
++) {
638 vex_printf(" %02x", b
);
639 sum
= (sum
<< 1) ^ b
;
641 vex_printf(" %08x\n\n", sum
);
645 /* Sanity check the initial IR. */
646 sanityCheckIRSB( irsb
, "initial IR",
647 False
/*can be non-flat*/, guest_word_type
);
649 vexAllocSanityCheck();
651 /* Clean it up, hopefully a lot. */
652 irsb
= do_iropt_BB ( irsb
, specHelper
, preciseMemExnsFn
, *pxControl
,
653 vta
->guest_bytes_addr
,
656 // JRS 2016 Aug 03: Sanity checking is expensive, we already checked
657 // the output of the front end, and iropt never screws up the IR by
658 // itself, unless it is being hacked on. So remove this post-iropt
659 // check in "production" use.
660 // sanityCheckIRSB( irsb, "after initial iropt",
661 // True/*must be flat*/, guest_word_type );
663 if (vex_traceflags
& VEX_TRACE_OPT1
) {
664 vex_printf("\n------------------------"
665 " After pre-instr IR optimisation "
666 "------------------------\n\n");
671 vexAllocSanityCheck();
673 /* Get the thing instrumented. */
674 if (vta
->instrument1
)
675 irsb
= vta
->instrument1(vta
->callback_opaque
,
679 guest_word_type
, host_word_type
);
680 vexAllocSanityCheck();
682 if (vta
->instrument2
)
683 irsb
= vta
->instrument2(vta
->callback_opaque
,
687 guest_word_type
, host_word_type
);
689 if (vex_traceflags
& VEX_TRACE_INST
) {
690 vex_printf("\n------------------------"
691 " After instrumentation "
692 "------------------------\n\n");
697 // JRS 2016 Aug 03: as above, this never actually fails in practice.
698 // And we'll sanity check anyway after the post-instrumentation
699 // cleanup pass. So skip this check in "production" use.
700 // if (vta->instrument1 || vta->instrument2)
701 // sanityCheckIRSB( irsb, "after instrumentation",
702 // True/*must be flat*/, guest_word_type );
704 /* Do a post-instrumentation cleanup pass. */
705 if (vta
->instrument1
|| vta
->instrument2
) {
706 do_deadcode_BB( irsb
);
707 irsb
= cprop_BB( irsb
);
708 do_deadcode_BB( irsb
);
709 sanityCheckIRSB( irsb
, "after post-instrumentation cleanup",
710 True
/*must be flat*/, guest_word_type
);
713 vexAllocSanityCheck();
715 if (vex_traceflags
& VEX_TRACE_OPT2
) {
716 vex_printf("\n------------------------"
717 " After post-instr IR optimisation "
718 "------------------------\n\n");
727 /* Back end of the compilation pipeline. Is not exported. */
729 static void libvex_BackEnd ( const VexTranslateArgs
*vta
,
730 /*MOD*/ VexTranslateResult
* res
,
732 VexRegisterUpdates pxControl
)
734 /* This the bundle of functions we need to do the back-end stuff
735 (insn selection, reg-alloc, assembly) whilst being insulated
736 from the target instruction set. */
737 void (*getRegUsage
) ( HRegUsage
*, const HInstr
*, Bool
);
738 void (*mapRegs
) ( HRegRemap
*, HInstr
*, Bool
);
739 void (*genSpill
) ( HInstr
**, HInstr
**, HReg
, Int
, Bool
);
740 void (*genReload
) ( HInstr
**, HInstr
**, HReg
, Int
, Bool
);
741 HInstr
* (*genMove
) ( HReg
, HReg
, Bool
);
742 HInstr
* (*directReload
) ( HInstr
*, HReg
, Short
);
743 void (*ppInstr
) ( const HInstr
*, Bool
);
744 UInt (*ppReg
) ( HReg
);
745 HInstrArray
* (*iselSB
) ( const IRSB
*, VexArch
, const VexArchInfo
*,
746 const VexAbiInfo
*, Int
, Int
, Bool
, Bool
,
748 Int (*emit
) ( /*MB_MOD*/Bool
*,
749 UChar
*, Int
, const HInstr
*, Bool
, VexEndness
,
750 const void*, const void*, const void*,
752 Bool (*preciseMemExnsFn
) ( Int
, Int
, VexRegisterUpdates
);
754 const RRegUniverse
* rRegUniv
= NULL
;
756 Bool mode64
, chainingAllowed
;
757 Int i
, j
, k
, out_used
;
759 Int offB_HOST_EvC_COUNTER
;
760 Int offB_HOST_EvC_FAILADDR
;
762 UChar insn_bytes
[128];
778 chainingAllowed
= False
;
780 offB_HOST_EvC_COUNTER
= 0;
781 offB_HOST_EvC_FAILADDR
= 0;
782 preciseMemExnsFn
= NULL
;
784 vassert(vex_initdone
);
785 vassert(vta
->disp_cp_xassisted
!= NULL
);
787 vex_traceflags
= vta
->traceflags
;
789 /* Both the chainers and the indir are either NULL or non-NULL. */
790 if (vta
->disp_cp_chain_me_to_slowEP
!= NULL
) {
791 vassert(vta
->disp_cp_chain_me_to_fastEP
!= NULL
);
792 vassert(vta
->disp_cp_xindir
!= NULL
);
793 chainingAllowed
= True
;
795 vassert(vta
->disp_cp_chain_me_to_fastEP
== NULL
);
796 vassert(vta
->disp_cp_xindir
== NULL
);
799 switch (vta
->arch_guest
) {
803 = X86FN(guest_x86_state_requires_precise_mem_exns
);
804 guest_sizeB
= sizeof(VexGuestX86State
);
805 offB_HOST_EvC_COUNTER
= offsetof(VexGuestX86State
,host_EvC_COUNTER
);
806 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestX86State
,host_EvC_FAILADDR
);
811 = AMD64FN(guest_amd64_state_requires_precise_mem_exns
);
812 guest_sizeB
= sizeof(VexGuestAMD64State
);
813 offB_HOST_EvC_COUNTER
= offsetof(VexGuestAMD64State
,host_EvC_COUNTER
);
814 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestAMD64State
,host_EvC_FAILADDR
);
819 = PPC32FN(guest_ppc32_state_requires_precise_mem_exns
);
820 guest_sizeB
= sizeof(VexGuestPPC32State
);
821 offB_HOST_EvC_COUNTER
= offsetof(VexGuestPPC32State
,host_EvC_COUNTER
);
822 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestPPC32State
,host_EvC_FAILADDR
);
827 = PPC64FN(guest_ppc64_state_requires_precise_mem_exns
);
828 guest_sizeB
= sizeof(VexGuestPPC64State
);
829 offB_HOST_EvC_COUNTER
= offsetof(VexGuestPPC64State
,host_EvC_COUNTER
);
830 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestPPC64State
,host_EvC_FAILADDR
);
835 = S390FN(guest_s390x_state_requires_precise_mem_exns
);
836 guest_sizeB
= sizeof(VexGuestS390XState
);
837 offB_HOST_EvC_COUNTER
= offsetof(VexGuestS390XState
,host_EvC_COUNTER
);
838 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestS390XState
,host_EvC_FAILADDR
);
843 = ARMFN(guest_arm_state_requires_precise_mem_exns
);
844 guest_sizeB
= sizeof(VexGuestARMState
);
845 offB_HOST_EvC_COUNTER
= offsetof(VexGuestARMState
,host_EvC_COUNTER
);
846 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestARMState
,host_EvC_FAILADDR
);
851 = ARM64FN(guest_arm64_state_requires_precise_mem_exns
);
852 guest_sizeB
= sizeof(VexGuestARM64State
);
853 offB_HOST_EvC_COUNTER
= offsetof(VexGuestARM64State
,host_EvC_COUNTER
);
854 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestARM64State
,host_EvC_FAILADDR
);
859 = MIPS32FN(guest_mips32_state_requires_precise_mem_exns
);
860 guest_sizeB
= sizeof(VexGuestMIPS32State
);
861 offB_HOST_EvC_COUNTER
= offsetof(VexGuestMIPS32State
,host_EvC_COUNTER
);
862 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestMIPS32State
,host_EvC_FAILADDR
);
867 = MIPS64FN(guest_mips64_state_requires_precise_mem_exns
);
868 guest_sizeB
= sizeof(VexGuestMIPS64State
);
869 offB_HOST_EvC_COUNTER
= offsetof(VexGuestMIPS64State
,host_EvC_COUNTER
);
870 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestMIPS64State
,host_EvC_FAILADDR
);
873 case VexArchNANOMIPS
:
875 = NANOMIPSFN(guest_mips32_state_requires_precise_mem_exns
);
876 guest_sizeB
= sizeof(VexGuestMIPS32State
);
877 offB_HOST_EvC_COUNTER
= offsetof(VexGuestMIPS32State
,host_EvC_COUNTER
);
878 offB_HOST_EvC_FAILADDR
= offsetof(VexGuestMIPS32State
,host_EvC_FAILADDR
);
882 vpanic("LibVEX_Codegen: unsupported guest insn set");
886 switch (vta
->arch_host
) {
890 rRegUniv
= X86FN(getRRegUniverse_X86());
892 = CAST_TO_TYPEOF(getRegUsage
) X86FN(getRegUsage_X86Instr
);
893 mapRegs
= CAST_TO_TYPEOF(mapRegs
) X86FN(mapRegs_X86Instr
);
894 genSpill
= CAST_TO_TYPEOF(genSpill
) X86FN(genSpill_X86
);
895 genReload
= CAST_TO_TYPEOF(genReload
) X86FN(genReload_X86
);
896 genMove
= CAST_TO_TYPEOF(genMove
) X86FN(genMove_X86
);
897 directReload
= CAST_TO_TYPEOF(directReload
) X86FN(directReload_X86
);
898 ppInstr
= CAST_TO_TYPEOF(ppInstr
) X86FN(ppX86Instr
);
899 ppReg
= CAST_TO_TYPEOF(ppReg
) X86FN(ppHRegX86
);
900 iselSB
= X86FN(iselSB_X86
);
901 emit
= CAST_TO_TYPEOF(emit
) X86FN(emit_X86Instr
);
902 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
);
907 rRegUniv
= AMD64FN(getRRegUniverse_AMD64());
909 = CAST_TO_TYPEOF(getRegUsage
) AMD64FN(getRegUsage_AMD64Instr
);
910 mapRegs
= CAST_TO_TYPEOF(mapRegs
) AMD64FN(mapRegs_AMD64Instr
);
911 genSpill
= CAST_TO_TYPEOF(genSpill
) AMD64FN(genSpill_AMD64
);
912 genReload
= CAST_TO_TYPEOF(genReload
) AMD64FN(genReload_AMD64
);
913 genMove
= CAST_TO_TYPEOF(genMove
) AMD64FN(genMove_AMD64
);
914 directReload
= CAST_TO_TYPEOF(directReload
) AMD64FN(directReload_AMD64
);
915 ppInstr
= CAST_TO_TYPEOF(ppInstr
) AMD64FN(ppAMD64Instr
);
916 ppReg
= CAST_TO_TYPEOF(ppReg
) AMD64FN(ppHRegAMD64
);
917 iselSB
= AMD64FN(iselSB_AMD64
);
918 emit
= CAST_TO_TYPEOF(emit
) AMD64FN(emit_AMD64Instr
);
919 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
);
924 rRegUniv
= PPC32FN(getRRegUniverse_PPC(mode64
));
926 = CAST_TO_TYPEOF(getRegUsage
) PPC32FN(getRegUsage_PPCInstr
);
927 mapRegs
= CAST_TO_TYPEOF(mapRegs
) PPC32FN(mapRegs_PPCInstr
);
928 genSpill
= CAST_TO_TYPEOF(genSpill
) PPC32FN(genSpill_PPC
);
929 genReload
= CAST_TO_TYPEOF(genReload
) PPC32FN(genReload_PPC
);
930 genMove
= CAST_TO_TYPEOF(genMove
) PPC32FN(genMove_PPC
);
931 ppInstr
= CAST_TO_TYPEOF(ppInstr
) PPC32FN(ppPPCInstr
);
932 ppReg
= CAST_TO_TYPEOF(ppReg
) PPC32FN(ppHRegPPC
);
933 iselSB
= PPC32FN(iselSB_PPC
);
934 emit
= CAST_TO_TYPEOF(emit
) PPC32FN(emit_PPCInstr
);
935 vassert(vta
->archinfo_host
.endness
== VexEndnessBE
);
940 rRegUniv
= PPC64FN(getRRegUniverse_PPC(mode64
));
942 = CAST_TO_TYPEOF(getRegUsage
) PPC64FN(getRegUsage_PPCInstr
);
943 mapRegs
= CAST_TO_TYPEOF(mapRegs
) PPC64FN(mapRegs_PPCInstr
);
944 genSpill
= CAST_TO_TYPEOF(genSpill
) PPC64FN(genSpill_PPC
);
945 genReload
= CAST_TO_TYPEOF(genReload
) PPC64FN(genReload_PPC
);
946 genMove
= CAST_TO_TYPEOF(genMove
) PPC64FN(genMove_PPC
);
947 ppInstr
= CAST_TO_TYPEOF(ppInstr
) PPC64FN(ppPPCInstr
);
948 ppReg
= CAST_TO_TYPEOF(ppReg
) PPC64FN(ppHRegPPC
);
949 iselSB
= PPC64FN(iselSB_PPC
);
950 emit
= CAST_TO_TYPEOF(emit
) PPC64FN(emit_PPCInstr
);
951 vassert(vta
->archinfo_host
.endness
== VexEndnessBE
||
952 vta
->archinfo_host
.endness
== VexEndnessLE
);
957 rRegUniv
= S390FN(getRRegUniverse_S390());
959 = CAST_TO_TYPEOF(getRegUsage
) S390FN(getRegUsage_S390Instr
);
960 mapRegs
= CAST_TO_TYPEOF(mapRegs
) S390FN(mapRegs_S390Instr
);
961 genSpill
= CAST_TO_TYPEOF(genSpill
) S390FN(genSpill_S390
);
962 genReload
= CAST_TO_TYPEOF(genReload
) S390FN(genReload_S390
);
963 genMove
= CAST_TO_TYPEOF(genMove
) S390FN(genMove_S390
);
964 directReload
= CAST_TO_TYPEOF(directReload
) S390FN(directReload_S390
);
965 ppInstr
= CAST_TO_TYPEOF(ppInstr
) S390FN(ppS390Instr
);
966 ppReg
= CAST_TO_TYPEOF(ppReg
) S390FN(ppHRegS390
);
967 iselSB
= S390FN(iselSB_S390
);
968 emit
= CAST_TO_TYPEOF(emit
) S390FN(emit_S390Instr
);
969 vassert(vta
->archinfo_host
.endness
== VexEndnessBE
);
974 rRegUniv
= ARMFN(getRRegUniverse_ARM());
976 = CAST_TO_TYPEOF(getRegUsage
) ARMFN(getRegUsage_ARMInstr
);
977 mapRegs
= CAST_TO_TYPEOF(mapRegs
) ARMFN(mapRegs_ARMInstr
);
978 genSpill
= CAST_TO_TYPEOF(genSpill
) ARMFN(genSpill_ARM
);
979 genReload
= CAST_TO_TYPEOF(genReload
) ARMFN(genReload_ARM
);
980 genMove
= CAST_TO_TYPEOF(genMove
) ARMFN(genMove_ARM
);
981 ppInstr
= CAST_TO_TYPEOF(ppInstr
) ARMFN(ppARMInstr
);
982 ppReg
= CAST_TO_TYPEOF(ppReg
) ARMFN(ppHRegARM
);
983 iselSB
= ARMFN(iselSB_ARM
);
984 emit
= CAST_TO_TYPEOF(emit
) ARMFN(emit_ARMInstr
);
985 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
);
990 rRegUniv
= ARM64FN(getRRegUniverse_ARM64());
992 = CAST_TO_TYPEOF(getRegUsage
) ARM64FN(getRegUsage_ARM64Instr
);
993 mapRegs
= CAST_TO_TYPEOF(mapRegs
) ARM64FN(mapRegs_ARM64Instr
);
994 genSpill
= CAST_TO_TYPEOF(genSpill
) ARM64FN(genSpill_ARM64
);
995 genReload
= CAST_TO_TYPEOF(genReload
) ARM64FN(genReload_ARM64
);
996 genMove
= CAST_TO_TYPEOF(genMove
) ARM64FN(genMove_ARM64
);
997 ppInstr
= CAST_TO_TYPEOF(ppInstr
) ARM64FN(ppARM64Instr
);
998 ppReg
= CAST_TO_TYPEOF(ppReg
) ARM64FN(ppHRegARM64
);
999 iselSB
= ARM64FN(iselSB_ARM64
);
1000 emit
= CAST_TO_TYPEOF(emit
) ARM64FN(emit_ARM64Instr
);
1001 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
);
1006 rRegUniv
= MIPS32FN(getRRegUniverse_MIPS(mode64
));
1008 = CAST_TO_TYPEOF(getRegUsage
) MIPS32FN(getRegUsage_MIPSInstr
);
1009 mapRegs
= CAST_TO_TYPEOF(mapRegs
) MIPS32FN(mapRegs_MIPSInstr
);
1010 genSpill
= CAST_TO_TYPEOF(genSpill
) MIPS32FN(genSpill_MIPS
);
1011 genReload
= CAST_TO_TYPEOF(genReload
) MIPS32FN(genReload_MIPS
);
1012 genMove
= CAST_TO_TYPEOF(genMove
) MIPS32FN(genMove_MIPS
);
1013 ppInstr
= CAST_TO_TYPEOF(ppInstr
) MIPS32FN(ppMIPSInstr
);
1014 ppReg
= CAST_TO_TYPEOF(ppReg
) MIPS32FN(ppHRegMIPS
);
1015 iselSB
= MIPS32FN(iselSB_MIPS
);
1016 emit
= CAST_TO_TYPEOF(emit
) MIPS32FN(emit_MIPSInstr
);
1017 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
1018 || vta
->archinfo_host
.endness
== VexEndnessBE
);
1023 rRegUniv
= MIPS64FN(getRRegUniverse_MIPS(mode64
));
1025 = CAST_TO_TYPEOF(getRegUsage
) MIPS64FN(getRegUsage_MIPSInstr
);
1026 mapRegs
= CAST_TO_TYPEOF(mapRegs
) MIPS64FN(mapRegs_MIPSInstr
);
1027 genSpill
= CAST_TO_TYPEOF(genSpill
) MIPS64FN(genSpill_MIPS
);
1028 genReload
= CAST_TO_TYPEOF(genReload
) MIPS64FN(genReload_MIPS
);
1029 genMove
= CAST_TO_TYPEOF(genMove
) MIPS64FN(genMove_MIPS
);
1030 ppInstr
= CAST_TO_TYPEOF(ppInstr
) MIPS64FN(ppMIPSInstr
);
1031 ppReg
= CAST_TO_TYPEOF(ppReg
) MIPS64FN(ppHRegMIPS
);
1032 iselSB
= MIPS64FN(iselSB_MIPS
);
1033 emit
= CAST_TO_TYPEOF(emit
) MIPS64FN(emit_MIPSInstr
);
1034 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
1035 || vta
->archinfo_host
.endness
== VexEndnessBE
);
1038 case VexArchNANOMIPS
:
1040 rRegUniv
= NANOMIPSFN(getRRegUniverse_NANOMIPS(mode64
));
1042 = CAST_TO_TYPEOF(getRegUsage
) NANOMIPSFN(getRegUsage_NANOMIPSInstr
);
1043 mapRegs
= CAST_TO_TYPEOF(mapRegs
) NANOMIPSFN(mapRegs_NANOMIPSInstr
);
1044 genSpill
= CAST_TO_TYPEOF(genSpill
) NANOMIPSFN(genSpill_NANOMIPS
);
1045 genReload
= CAST_TO_TYPEOF(genReload
) NANOMIPSFN(genReload_NANOMIPS
);
1046 genMove
= CAST_TO_TYPEOF(genMove
) NANOMIPSFN(genMove_NANOMIPS
);
1047 ppInstr
= CAST_TO_TYPEOF(ppInstr
) NANOMIPSFN(ppNANOMIPSInstr
);
1048 ppReg
= CAST_TO_TYPEOF(ppReg
) NANOMIPSFN(ppHRegNANOMIPS
);
1049 iselSB
= NANOMIPSFN(iselSB_NANOMIPS
);
1050 emit
= CAST_TO_TYPEOF(emit
) NANOMIPSFN(emit_NANOMIPSInstr
);
1051 vassert(vta
->archinfo_host
.endness
== VexEndnessLE
1052 || vta
->archinfo_host
.endness
== VexEndnessBE
);
1056 vpanic("LibVEX_Translate: unsupported host insn set");
1059 // Are the host's hardware capabilities feasible. The function will
1060 // not return if hwcaps are infeasible in some sense.
1061 check_hwcaps(vta
->arch_host
, vta
->archinfo_host
.hwcaps
);
1064 /* Turn it into virtual-registerised code. Build trees -- this
1065 also throws away any dead bindings. */
1066 max_ga
= ado_treebuild_BB( irsb
, preciseMemExnsFn
, pxControl
);
1068 if (vta
->finaltidy
) {
1069 irsb
= vta
->finaltidy(irsb
);
1072 vexAllocSanityCheck();
1074 if (vex_traceflags
& VEX_TRACE_TREES
) {
1075 vex_printf("\n------------------------"
1076 " After tree-building "
1077 "------------------------\n\n");
1084 *(vta
->host_bytes_used
) = 0;
1085 res
->status
= VexTransOK
; return;
1089 if (vex_traceflags
& VEX_TRACE_VCODE
)
1090 vex_printf("\n------------------------"
1091 " Instruction selection "
1092 "------------------------\n");
1094 /* No guest has its IP field at offset zero. If this fails it
1095 means some transformation pass somewhere failed to update/copy
1096 irsb->offsIP properly. */
1097 vassert(irsb
->offsIP
>= 16);
1099 vcode
= iselSB ( irsb
, vta
->arch_host
,
1100 &vta
->archinfo_host
,
1102 offB_HOST_EvC_COUNTER
,
1103 offB_HOST_EvC_FAILADDR
,
1108 vexAllocSanityCheck();
1110 if (vex_traceflags
& VEX_TRACE_VCODE
)
1113 if (vex_traceflags
& VEX_TRACE_VCODE
) {
1114 for (i
= 0; i
< vcode
->arr_used
; i
++) {
1115 vex_printf("%3d ", i
);
1116 ppInstr(vcode
->arr
[i
], mode64
);
1122 /* Register allocate. */
1123 RegAllocControl con
= {
1124 .univ
= rRegUniv
, .getRegUsage
= getRegUsage
, .mapRegs
= mapRegs
,
1125 .genSpill
= genSpill
, .genReload
= genReload
, .genMove
= genMove
,
1126 .directReload
= directReload
, .guest_sizeB
= guest_sizeB
,
1127 .ppInstr
= ppInstr
, .ppReg
= ppReg
, .mode64
= mode64
};
1128 switch (vex_control
.regalloc_version
) {
1130 rcode
= doRegisterAllocation_v2(vcode
, &con
);
1133 rcode
= doRegisterAllocation_v3(vcode
, &con
);
1139 vexAllocSanityCheck();
1141 if (vex_traceflags
& VEX_TRACE_RCODE
) {
1142 vex_printf("\n------------------------"
1143 " Register-allocated code "
1144 "------------------------\n\n");
1145 for (i
= 0; i
< rcode
->arr_used
; i
++) {
1146 vex_printf("%3d ", i
);
1147 ppInstr(rcode
->arr
[i
], mode64
);
1155 *(vta
->host_bytes_used
) = 0;
1156 res
->status
= VexTransOK
; return;
1161 if (vex_traceflags
& VEX_TRACE_ASM
) {
1162 vex_printf("\n------------------------"
1164 "------------------------\n\n");
1167 out_used
= 0; /* tracks along the host_bytes array */
1168 for (i
= 0; i
< rcode
->arr_used
; i
++) {
1169 HInstr
* hi
= rcode
->arr
[i
];
1170 Bool hi_isProfInc
= False
;
1171 if (UNLIKELY(vex_traceflags
& VEX_TRACE_ASM
)) {
1172 ppInstr(hi
, mode64
);
1175 j
= emit( &hi_isProfInc
,
1176 insn_bytes
, sizeof insn_bytes
, hi
,
1177 mode64
, vta
->archinfo_host
.endness
,
1178 vta
->disp_cp_chain_me_to_slowEP
,
1179 vta
->disp_cp_chain_me_to_fastEP
,
1180 vta
->disp_cp_xindir
,
1181 vta
->disp_cp_xassisted
);
1182 if (UNLIKELY(vex_traceflags
& VEX_TRACE_ASM
)) {
1183 for (k
= 0; k
< j
; k
++)
1184 vex_printf("%02x ", (UInt
)insn_bytes
[k
]);
1187 if (UNLIKELY(out_used
+ j
> vta
->host_bytes_size
)) {
1188 vexSetAllocModeTEMP_and_clear();
1190 res
->status
= VexTransOutputFull
;
1193 if (UNLIKELY(hi_isProfInc
)) {
1194 vassert(vta
->addProfInc
); /* else where did it come from? */
1195 vassert(res
->offs_profInc
== -1); /* there can be only one (tm) */
1196 vassert(out_used
>= 0);
1197 res
->offs_profInc
= out_used
;
1199 { UChar
* dst
= &vta
->host_bytes
[out_used
];
1200 for (k
= 0; k
< j
; k
++) {
1201 dst
[k
] = insn_bytes
[k
];
1206 *(vta
->host_bytes_used
) = out_used
;
1208 vexAllocSanityCheck();
1210 vexSetAllocModeTEMP_and_clear();
1212 if (vex_traceflags
) {
1213 /* Print the expansion ratio for this SB. */
1214 j
= 0; /* total guest bytes */
1215 for (i
= 0; i
< vta
->guest_extents
->n_used
; i
++) {
1216 j
+= vta
->guest_extents
->len
[i
];
1218 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
1219 j
, out_used
, (10 * out_used
) / (j
== 0 ? 1 : j
));
1223 res
->status
= VexTransOK
;
1228 /* Exported to library client. */
1230 VexTranslateResult
LibVEX_Translate ( /*MOD*/ VexTranslateArgs
* vta
)
1232 VexTranslateResult res
= { 0 };
1233 VexRegisterUpdates pxControl
= VexRegUpd_INVALID
;
1235 IRSB
* irsb
= LibVEX_FrontEnd(vta
, &res
, &pxControl
);
1236 libvex_BackEnd(vta
, &res
, irsb
, pxControl
);
1241 /* --------- Chain/Unchain XDirects. --------- */
1243 VexInvalRange
LibVEX_Chain ( VexArch arch_host
,
1244 VexEndness endness_host
,
1245 void* place_to_chain
,
1246 const void* disp_cp_chain_me_EXPECTED
,
1247 const void* place_to_jump_to
)
1249 switch (arch_host
) {
1251 X86ST(return chainXDirect_X86(endness_host
,
1253 disp_cp_chain_me_EXPECTED
,
1256 AMD64ST(return chainXDirect_AMD64(endness_host
,
1258 disp_cp_chain_me_EXPECTED
,
1261 ARMST(return chainXDirect_ARM(endness_host
,
1263 disp_cp_chain_me_EXPECTED
,
1266 ARM64ST(return chainXDirect_ARM64(endness_host
,
1268 disp_cp_chain_me_EXPECTED
,
1271 S390ST(return chainXDirect_S390(endness_host
,
1273 disp_cp_chain_me_EXPECTED
,
1276 PPC32ST(return chainXDirect_PPC(endness_host
,
1278 disp_cp_chain_me_EXPECTED
,
1279 place_to_jump_to
, False
/*!mode64*/));
1281 PPC64ST(return chainXDirect_PPC(endness_host
,
1283 disp_cp_chain_me_EXPECTED
,
1284 place_to_jump_to
, True
/*mode64*/));
1286 MIPS32ST(return chainXDirect_MIPS(endness_host
,
1288 disp_cp_chain_me_EXPECTED
,
1289 place_to_jump_to
, False
/*!mode64*/));
1291 MIPS64ST(return chainXDirect_MIPS(endness_host
,
1293 disp_cp_chain_me_EXPECTED
,
1294 place_to_jump_to
, True
/*!mode64*/));
1295 case VexArchNANOMIPS
:
1296 NANOMIPSST(return chainXDirect_NANOMIPS(endness_host
,
1298 disp_cp_chain_me_EXPECTED
,
1305 VexInvalRange
LibVEX_UnChain ( VexArch arch_host
,
1306 VexEndness endness_host
,
1307 void* place_to_unchain
,
1308 const void* place_to_jump_to_EXPECTED
,
1309 const void* disp_cp_chain_me
)
1311 switch (arch_host
) {
1313 X86ST(return unchainXDirect_X86(endness_host
,
1315 place_to_jump_to_EXPECTED
,
1318 AMD64ST(return unchainXDirect_AMD64(endness_host
,
1320 place_to_jump_to_EXPECTED
,
1323 ARMST(return unchainXDirect_ARM(endness_host
,
1325 place_to_jump_to_EXPECTED
,
1328 ARM64ST(return unchainXDirect_ARM64(endness_host
,
1330 place_to_jump_to_EXPECTED
,
1333 S390ST(return unchainXDirect_S390(endness_host
,
1335 place_to_jump_to_EXPECTED
,
1338 PPC32ST(return unchainXDirect_PPC(endness_host
,
1340 place_to_jump_to_EXPECTED
,
1341 disp_cp_chain_me
, False
/*!mode64*/));
1343 PPC64ST(return unchainXDirect_PPC(endness_host
,
1345 place_to_jump_to_EXPECTED
,
1346 disp_cp_chain_me
, True
/*mode64*/));
1348 MIPS32ST(return unchainXDirect_MIPS(endness_host
,
1350 place_to_jump_to_EXPECTED
,
1351 disp_cp_chain_me
, False
/*!mode64*/));
1353 MIPS64ST(return unchainXDirect_MIPS(endness_host
,
1355 place_to_jump_to_EXPECTED
,
1356 disp_cp_chain_me
, True
/*!mode64*/));
1357 case VexArchNANOMIPS
:
1358 NANOMIPSST(return unchainXDirect_NANOMIPS(endness_host
,
1360 place_to_jump_to_EXPECTED
,
1367 Int
LibVEX_evCheckSzB ( VexArch arch_host
)
1369 static Int cached
= 0; /* DO NOT MAKE NON-STATIC */
1370 if (UNLIKELY(cached
== 0)) {
1371 switch (arch_host
) {
1373 X86ST(cached
= evCheckSzB_X86()); break;
1375 AMD64ST(cached
= evCheckSzB_AMD64()); break;
1377 ARMST(cached
= evCheckSzB_ARM()); break;
1379 ARM64ST(cached
= evCheckSzB_ARM64()); break;
1381 S390ST(cached
= evCheckSzB_S390()); break;
1383 PPC32ST(cached
= evCheckSzB_PPC()); break;
1385 PPC64ST(cached
= evCheckSzB_PPC()); break;
1387 MIPS32ST(cached
= evCheckSzB_MIPS()); break;
1389 MIPS64ST(cached
= evCheckSzB_MIPS()); break;
1390 case VexArchNANOMIPS
:
1391 NANOMIPSST(cached
= evCheckSzB_NANOMIPS()); break;
1399 VexInvalRange
LibVEX_PatchProfInc ( VexArch arch_host
,
1400 VexEndness endness_host
,
1401 void* place_to_patch
,
1402 const ULong
* location_of_counter
)
1404 switch (arch_host
) {
1406 X86ST(return patchProfInc_X86(endness_host
, place_to_patch
,
1407 location_of_counter
));
1409 AMD64ST(return patchProfInc_AMD64(endness_host
, place_to_patch
,
1410 location_of_counter
));
1412 ARMST(return patchProfInc_ARM(endness_host
, place_to_patch
,
1413 location_of_counter
));
1415 ARM64ST(return patchProfInc_ARM64(endness_host
, place_to_patch
,
1416 location_of_counter
));
1418 S390ST(return patchProfInc_S390(endness_host
, place_to_patch
,
1419 location_of_counter
));
1421 PPC32ST(return patchProfInc_PPC(endness_host
, place_to_patch
,
1422 location_of_counter
, False
/*!mode64*/));
1424 PPC64ST(return patchProfInc_PPC(endness_host
, place_to_patch
,
1425 location_of_counter
, True
/*mode64*/));
1427 MIPS32ST(return patchProfInc_MIPS(endness_host
, place_to_patch
,
1428 location_of_counter
, False
/*!mode64*/));
1430 MIPS64ST(return patchProfInc_MIPS(endness_host
, place_to_patch
,
1431 location_of_counter
, True
/*!mode64*/));
1432 case VexArchNANOMIPS
:
1433 NANOMIPSST(return patchProfInc_NANOMIPS(endness_host
, place_to_patch
,
1434 location_of_counter
));
1441 /* --------- Emulation warnings. --------- */
1443 const HChar
* LibVEX_EmNote_string ( VexEmNote ew
)
1448 case EmWarn_X86_x87exns
:
1449 return "Unmasking x87 FP exceptions";
1450 case EmWarn_X86_x87precision
:
1451 return "Selection of non-80-bit x87 FP precision";
1452 case EmWarn_X86_sseExns
:
1453 return "Unmasking SSE FP exceptions";
1455 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1456 case EmWarn_X86_daz
:
1457 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
1458 case EmWarn_X86_acFlag
:
1459 return "Setting %eflags.ac (setting noted but ignored)";
1460 case EmWarn_PPCexns
:
1461 return "Unmasking PPC32/64 FP exceptions";
1462 case EmWarn_PPC64_redir_overflow
:
1463 return "PPC64 function redirection stack overflow";
1464 case EmWarn_PPC64_redir_underflow
:
1465 return "PPC64 function redirection stack underflow";
1466 case EmWarn_S390X_fpext_rounding
:
1467 return "The specified rounding mode cannot be supported. That\n"
1468 " feature requires the floating point extension facility\n"
1469 " which is not available on this host. Continuing using\n"
1470 " the rounding mode from FPC. Results may differ!";
1471 case EmWarn_S390X_invalid_rounding
:
1472 return "The specified rounding mode is invalid.\n"
1473 " Continuing using 'round to nearest'. Results may differ!";
1474 case EmFail_S390X_stfle
:
1475 return "Instruction stfle is not supported on this host";
1476 case EmFail_S390X_stckf
:
1477 return "Instruction stckf is not supported on this host";
1478 case EmFail_S390X_ecag
:
1479 return "Instruction ecag is not supported on this host";
1480 case EmFail_S390X_pfpo
:
1481 return "Instruction pfpo is not supported on this host";
1482 case EmFail_S390X_DFP_insn
:
1483 return "DFP instructions are not supported on this host";
1484 case EmFail_S390X_fpext
:
1485 return "Encountered an instruction that requires the floating "
1486 "point extension facility.\n"
1487 " That facility is not available on this host";
1488 case EmFail_S390X_invalid_PFPO_rounding_mode
:
1489 return "The rounding mode in GPR 0 for the PFPO instruction"
1491 case EmFail_S390X_invalid_PFPO_function
:
1492 return "The function code in GPR 0 for the PFPO instruction"
1494 case EmFail_S390X_vx
:
1495 return "Encountered an instruction that requires the vector facility.\n"
1496 " That facility is not available on this host";
1498 vpanic("LibVEX_EmNote_string: unknown warning");
1502 /* ------------------ Arch/HwCaps stuff. ------------------ */
1504 const HChar
* LibVEX_ppVexArch ( VexArch arch
)
1507 case VexArch_INVALID
: return "INVALID";
1508 case VexArchX86
: return "X86";
1509 case VexArchAMD64
: return "AMD64";
1510 case VexArchARM
: return "ARM";
1511 case VexArchARM64
: return "ARM64";
1512 case VexArchPPC32
: return "PPC32";
1513 case VexArchPPC64
: return "PPC64";
1514 case VexArchS390X
: return "S390X";
1515 case VexArchMIPS32
: return "MIPS32";
1516 case VexArchMIPS64
: return "MIPS64";
1517 case VexArchNANOMIPS
: return "NANOMIPS";
1518 default: return "VexArch???";
1522 const HChar
* LibVEX_ppVexEndness ( VexEndness endness
)
1525 case VexEndness_INVALID
: return "INVALID";
1526 case VexEndnessLE
: return "LittleEndian";
1527 case VexEndnessBE
: return "BigEndian";
1528 default: return "VexEndness???";
1532 /* Return a string with the hardware capabilities to the extent as
1533 they pertain to the translation process. No attempt is made, to
1534 detect *all* capabilities an architecture may have. */
1535 const HChar
* LibVEX_ppVexHwCaps ( VexArch arch
, UInt hwcaps
)
1537 return show_hwcaps(arch
, hwcaps
);
1541 /* Write default settings info *vai. */
1542 void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo
* vai
)
1544 vex_bzero(vai
, sizeof(*vai
));
1546 vai
->endness
= VexEndness_INVALID
;
1547 vai
->ppc_icache_line_szB
= 0;
1548 vai
->ppc_dcbz_szB
= 0;
1549 vai
->ppc_dcbzl_szB
= 0;
1550 vai
->arm64_dMinLine_lg2_szB
= 0;
1551 vai
->arm64_iMinLine_lg2_szB
= 0;
1552 vai
->arm64_requires_fallback_LLSC
= False
;
1553 vai
->hwcache_info
.num_levels
= 0;
1554 vai
->hwcache_info
.num_caches
= 0;
1555 vai
->hwcache_info
.caches
= NULL
;
1556 vai
->hwcache_info
.icaches_maintain_coherence
= True
; // whatever
1559 /* Write default settings info *vbi. */
1560 void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo
* vbi
)
1562 vex_bzero(vbi
, sizeof(*vbi
));
1563 vbi
->guest_stack_redzone_size
= 0;
1564 vbi
->guest_amd64_assume_fs_is_const
= False
;
1565 vbi
->guest_amd64_assume_gs_is_const
= False
;
1566 vbi
->guest_amd64_sigbus_on_misalign
= False
;
1567 vbi
->guest_ppc_zap_RZ_at_blr
= False
;
1568 vbi
->guest_ppc_zap_RZ_at_bl
= NULL
;
1569 vbi
->guest__use_fallback_LLSC
= False
;
1570 vbi
->host_ppc_calls_use_fndescrs
= False
;
1574 static IRType
arch_word_size (VexArch arch
) {
1579 case VexArchNANOMIPS
:
1591 vex_printf("Fatal: unknown arch in arch_word_size\n");
1597 /* Convenience macro to be used in show_hwcaps_ARCH functions */
1598 #define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1600 /* Return a string showing the hwcaps in a nice way. The string will
1601 be NULL for unrecognised hardware capabilities. */
1603 static const HChar
* show_hwcaps_x86 ( UInt hwcaps
)
1605 static const HChar prefix
[] = "x86";
1606 static const struct {
1610 { VEX_HWCAPS_X86_MMXEXT
, "mmxext" },
1611 { VEX_HWCAPS_X86_SSE1
, "sse1" },
1612 { VEX_HWCAPS_X86_SSE2
, "sse2" },
1613 { VEX_HWCAPS_X86_SSE3
, "sse3" },
1614 { VEX_HWCAPS_X86_LZCNT
, "lzcnt" },
1616 /* Allocate a large enough buffer */
1617 static HChar buf
[sizeof prefix
+
1618 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1619 if (buf
[0] != '\0') return buf
; /* already constructed */
1621 HChar
*p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1624 vex_sprintf(p
, "-%s", "sse0");
1627 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1628 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1629 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1635 static const HChar
* show_hwcaps_amd64 ( UInt hwcaps
)
1637 static const HChar prefix
[] = "amd64";
1638 static const struct {
1642 { VEX_HWCAPS_AMD64_CX16
, "cx16" },
1643 { VEX_HWCAPS_AMD64_LZCNT
, "lzcnt" },
1644 { VEX_HWCAPS_AMD64_RDTSCP
, "rdtscp" },
1645 { VEX_HWCAPS_AMD64_SSE3
, "sse3" },
1646 { VEX_HWCAPS_AMD64_SSSE3
, "ssse3" },
1647 { VEX_HWCAPS_AMD64_AVX
, "avx" },
1648 { VEX_HWCAPS_AMD64_AVX2
, "avx2" },
1649 { VEX_HWCAPS_AMD64_BMI
, "bmi" },
1650 { VEX_HWCAPS_AMD64_F16C
, "f16c" },
1651 { VEX_HWCAPS_AMD64_RDRAND
, "rdrand" },
1652 { VEX_HWCAPS_AMD64_RDSEED
, "rdseed" },
1654 /* Allocate a large enough buffer */
1655 static HChar buf
[sizeof prefix
+
1656 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1657 if (buf
[0] != '\0') return buf
; /* already constructed */
1659 HChar
*p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1662 vex_sprintf(p
, "-%s", "sse2");
1665 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1666 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1667 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1673 static const HChar
* show_hwcaps_ppc32 ( UInt hwcaps
)
1675 static const HChar prefix
[] = "ppc32-int";
1676 static const struct {
1680 { VEX_HWCAPS_PPC32_F
, "flt" },
1681 { VEX_HWCAPS_PPC32_V
, "vmx" },
1682 { VEX_HWCAPS_PPC32_FX
, "FX" },
1683 { VEX_HWCAPS_PPC32_GX
, "GX" },
1684 { VEX_HWCAPS_PPC32_VX
, "VX" },
1685 { VEX_HWCAPS_PPC32_DFP
, "DFP" },
1686 { VEX_HWCAPS_PPC32_ISA2_07
, "ISA2_07" },
1687 { VEX_HWCAPS_PPC32_ISA3_0
, "ISA3_0" },
1688 { VEX_HWCAPS_PPC32_ISA3_1
, "ISA3_1" },
1690 /* Allocate a large enough buffer */
1691 static HChar buf
[sizeof prefix
+
1692 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1693 if (buf
[0] != '\0') return buf
; /* already constructed */
1695 HChar
*p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1697 if (hwcaps
== 0) return buf
;
1700 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1701 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1702 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1707 static const HChar
* show_hwcaps_ppc64 ( UInt hwcaps
)
1709 static const HChar prefix
[] = "ppc64-int-flt";
1710 static const struct {
1714 { VEX_HWCAPS_PPC64_FX
, "FX" },
1715 { VEX_HWCAPS_PPC64_GX
, "GX" },
1716 { VEX_HWCAPS_PPC64_V
, "vmx" },
1717 { VEX_HWCAPS_PPC64_DFP
, "DFP" },
1718 { VEX_HWCAPS_PPC64_ISA2_07
, "ISA2_07" },
1719 { VEX_HWCAPS_PPC64_ISA3_0
, "ISA3_0" },
1720 { VEX_HWCAPS_PPC64_ISA3_1
, "ISA3_1" },
1722 /* Allocate a large enough buffer */
1723 static HChar buf
[sizeof prefix
+
1724 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1725 if (buf
[0] != '\0') return buf
; /* already constructed */
1727 HChar
*p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1729 if (hwcaps
== 0) return buf
;
1732 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1733 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1734 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1739 static const HChar
* show_hwcaps_arm ( UInt hwcaps
)
1741 static const HChar prefix
[] = "ARM";
1742 static const struct {
1746 { VEX_HWCAPS_ARM_NEON
, "neon" },
1747 { VEX_HWCAPS_ARM_VFP
| VEX_HWCAPS_ARM_VFP2
| VEX_HWCAPS_ARM_VFP3
, "vfp" },
1749 /* Allocate a large enough buffer */
1750 static HChar buf
[sizeof prefix
+ 12 + // level
1751 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1752 if (buf
[0] != '\0') return buf
; /* already constructed */
1757 level
= VEX_ARM_ARCHLEVEL(hwcaps
);
1759 p
= buf
+ vex_sprintf(buf
, "%sv%u", prefix
, level
);
1760 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1761 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1762 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1767 static const HChar
* show_hwcaps_arm64 ( UInt hwcaps
)
1769 static const HChar prefix
[] = "v8";
1770 static const struct {
1774 { VEX_HWCAPS_ARM64_FHM
, "fhm" },
1775 { VEX_HWCAPS_ARM64_DPBCVAP
, "dpcvap" },
1776 { VEX_HWCAPS_ARM64_DPBCVADP
, "dpbcvadp" },
1777 { VEX_HWCAPS_ARM64_SM3
, "sm3" },
1778 { VEX_HWCAPS_ARM64_SM4
, "sm4" },
1779 { VEX_HWCAPS_ARM64_SHA3
, "sha3" },
1780 { VEX_HWCAPS_ARM64_RDM
, "rdm" },
1781 { VEX_HWCAPS_ARM64_I8MM
, "i8mm" },
1782 { VEX_HWCAPS_ARM64_ATOMICS
, "atomics" },
1783 { VEX_HWCAPS_ARM64_BF16
, "bf16" },
1784 { VEX_HWCAPS_ARM64_FP16
, "fp16" },
1785 { VEX_HWCAPS_ARM64_VFP16
, "vfp16" },
1788 static HChar buf
[sizeof prefix
+ // '\0'
1789 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1];
1791 HChar
*p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1793 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1794 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1795 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1801 static const HChar
* show_hwcaps_s390x ( UInt hwcaps
)
1803 static const HChar prefix
[] = "s390x";
1804 static const struct {
1808 { VEX_HWCAPS_S390X_LDISP
, "ldisp" },
1809 { VEX_HWCAPS_S390X_EIMM
, "eimm" },
1810 { VEX_HWCAPS_S390X_GIE
, "gie" },
1811 { VEX_HWCAPS_S390X_DFP
, "dfp" },
1812 { VEX_HWCAPS_S390X_FGX
, "fgx" },
1813 { VEX_HWCAPS_S390X_STFLE
, "stfle" },
1814 { VEX_HWCAPS_S390X_ETF2
, "etf2" },
1815 { VEX_HWCAPS_S390X_ETF3
, "etf3" },
1816 { VEX_HWCAPS_S390X_STCKF
, "stckf" },
1817 { VEX_HWCAPS_S390X_FPEXT
, "fpext" },
1818 { VEX_HWCAPS_S390X_LSC
, "lsc" },
1819 { VEX_HWCAPS_S390X_PFPO
, "pfpo" },
1820 { VEX_HWCAPS_S390X_VX
, "vx" },
1821 { VEX_HWCAPS_S390X_MSA5
, "msa5" },
1822 { VEX_HWCAPS_S390X_MI2
, "mi2" },
1823 { VEX_HWCAPS_S390X_LSC2
, "lsc2" },
1824 { VEX_HWCAPS_S390X_LSC2
, "vxe" },
1826 /* Allocate a large enough buffer */
1827 static HChar buf
[sizeof prefix
+
1828 NUM_HWCAPS
* (sizeof hwcaps_list
[0].name
+ 1) + 1]; // '\0'
1830 if (buf
[0] != '\0') return buf
; /* already constructed */
1835 hwcaps
= VEX_HWCAPS_S390X(hwcaps
);
1837 p
= buf
+ vex_sprintf(buf
, "%s", prefix
);
1838 for (i
= 0 ; i
< NUM_HWCAPS
; ++i
) {
1839 if (hwcaps
& hwcaps_list
[i
].hwcaps_bit
)
1840 p
= p
+ vex_sprintf(p
, "-%s", hwcaps_list
[i
].name
);
1843 /* If there are no facilities, add "zarch" */
1845 vex_sprintf(p
, "-%s", "zarch");
1850 static const HChar
* show_hwcaps_mips32 ( UInt hwcaps
)
1852 /* MIPS baseline. */
1853 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_MIPS
) {
1854 /* MIPS baseline with msa. */
1855 if (VEX_MIPS_PROC_MSA(hwcaps
)) {
1856 return "MIPS-baseline-msa";
1858 /* MIPS baseline with dspr2. */
1859 if (VEX_MIPS_PROC_DSP2(hwcaps
)) {
1860 return "MIPS-baseline-dspr2";
1862 /* MIPS baseline with dsp. */
1863 if (VEX_MIPS_PROC_DSP(hwcaps
)) {
1864 return "MIPS-baseline-dsp";
1866 return "MIPS-baseline";
1869 /* Broadcom baseline. */
1870 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_BROADCOM
) {
1871 return "Broadcom-baseline";
1874 /* Netlogic baseline. */
1875 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_NETLOGIC
) {
1876 return "Netlogic-baseline";
1879 /* Cavium baseline. */
1880 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_CAVIUM
) {
1881 return "Cavium-baseline";
1884 /* Ingenic baseline. */
1885 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_INGENIC_E1
) {
1886 return "Ingenic-baseline";
1889 /* Loongson baseline. */
1890 if ((VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_LEGACY
) &&
1891 (VEX_MIPS_PROC_ID(hwcaps
) == VEX_PRID_IMP_LOONGSON_64
)) {
1892 return "Loongson-baseline";
1895 return "Unsupported baseline";
1898 static const HChar
* show_hwcaps_mips64 ( UInt hwcaps
)
1900 /* Netlogic baseline. */
1901 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_NETLOGIC
) {
1902 return "Netlogic-baseline";
1905 /* Cavium baseline. */
1906 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_CAVIUM
) {
1907 return "Cavium-baseline";
1910 /* Loongson baseline. */
1911 if ((VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_LEGACY
) &&
1912 (VEX_MIPS_PROC_ID(hwcaps
) == VEX_PRID_IMP_LOONGSON_64
)) {
1913 return "Loongson-baseline";
1916 /* MIPS64 baseline. */
1917 if (VEX_MIPS_COMP_ID(hwcaps
) == VEX_PRID_COMP_MIPS
) {
1918 /* MIPS baseline with msa. */
1919 if (VEX_MIPS_PROC_MSA(hwcaps
)) {
1920 return "MIPS64-baseline-msa";
1922 return "MIPS64-baseline";
1925 return "Unsupported baseline";
1930 /* Thie function must not return NULL. */
1932 static const HChar
* show_hwcaps ( VexArch arch
, UInt hwcaps
)
1935 case VexArchX86
: return show_hwcaps_x86(hwcaps
);
1936 case VexArchAMD64
: return show_hwcaps_amd64(hwcaps
);
1937 case VexArchPPC32
: return show_hwcaps_ppc32(hwcaps
);
1938 case VexArchPPC64
: return show_hwcaps_ppc64(hwcaps
);
1939 case VexArchARM
: return show_hwcaps_arm(hwcaps
);
1940 case VexArchARM64
: return show_hwcaps_arm64(hwcaps
);
1941 case VexArchS390X
: return show_hwcaps_s390x(hwcaps
);
1942 case VexArchMIPS32
: return show_hwcaps_mips32(hwcaps
);
1943 case VexArchMIPS64
: return show_hwcaps_mips64(hwcaps
);
1944 default: return NULL
;
1948 /* To be used to complain about hwcaps we cannot handle */
1949 __attribute__((noreturn
))
1950 static void invalid_hwcaps ( VexArch arch
, UInt hwcaps
, const HChar
*message
)
1953 " Found: %s\n", message
, show_hwcaps(arch
, hwcaps
));
1956 /* This function will not return iff the hwcaps don't pass the test. */
1957 static void check_hwcaps ( VexArch arch
, UInt hwcaps
)
1961 if (hwcaps
== 0) return; // baseline
1963 /* Monotonic: SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
1964 static const UInt extras
[] = {
1965 VEX_HWCAPS_X86_MMXEXT
, VEX_HWCAPS_X86_SSE1
, VEX_HWCAPS_X86_SSE2
,
1970 for (i
= 0; i
< sizeof extras
/ sizeof extras
[0]; ++i
) {
1972 if (caps
== hwcaps
) return;
1973 /* For SSE2 or later LZCNT is optional */
1974 if ((caps
& VEX_HWCAPS_X86_SSE2
) != 0) {
1975 if ((caps
| VEX_HWCAPS_X86_LZCNT
) == hwcaps
) return;
1978 invalid_hwcaps(arch
, hwcaps
, "Cannot handle capabilities\n");
1981 case VexArchAMD64
: {
1982 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1983 don't expect to come across anything which can do SSE3 but can't
1984 do CX16. Still, we can handle that case. LZCNT is similarly
1987 /* Throw out obviously stupid cases: */
1988 Bool have_sse3
= (hwcaps
& VEX_HWCAPS_AMD64_SSE3
) != 0;
1989 Bool have_ssse3
= (hwcaps
& VEX_HWCAPS_AMD64_SSSE3
) != 0;
1990 Bool have_avx
= (hwcaps
& VEX_HWCAPS_AMD64_AVX
) != 0;
1991 Bool have_bmi
= (hwcaps
& VEX_HWCAPS_AMD64_BMI
) != 0;
1992 Bool have_avx2
= (hwcaps
& VEX_HWCAPS_AMD64_AVX2
) != 0;
1994 /* SSSE3 without SSE3 */
1995 if (have_ssse3
&& !have_sse3
)
1996 invalid_hwcaps(arch
, hwcaps
,
1997 "Support for SSSE3 requires SSE3 capabilities\n");
1998 /* AVX without SSSE3 */
1999 if (have_avx
&& !have_ssse3
)
2000 invalid_hwcaps(arch
, hwcaps
,
2001 "Support for AVX requires SSSE3 capabilities\n");
2002 /* AVX2 or BMI without AVX */
2003 if (have_avx2
&& !have_avx
)
2004 invalid_hwcaps(arch
, hwcaps
,
2005 "Support for AVX2 requires AVX capabilities\n");
2006 if (have_bmi
&& !have_avx
)
2007 invalid_hwcaps(arch
, hwcaps
,
2008 "Support for BMI requires AVX capabilities\n");
2012 case VexArchPPC32
: {
2013 /* Monotonic with complications. Basically V > F > baseline,
2014 but once you have F then you can have FX or GX too. */
2015 if (hwcaps
== 0) return; // baseline
2017 if ((hwcaps
& VEX_HWCAPS_PPC32_F
) == 0)
2018 invalid_hwcaps(arch
, hwcaps
,
2019 "Missing floating point capability\n");
2020 /* V, FX, and GX can appear in any combination */
2022 /* DFP requires V and FX and GX */
2023 UInt v_fx_gx
= VEX_HWCAPS_PPC32_V
| VEX_HWCAPS_PPC32_FX
|
2024 VEX_HWCAPS_PPC32_GX
;
2025 Bool has_v_fx_gx
= (hwcaps
& v_fx_gx
) == v_fx_gx
;
2027 if ((hwcaps
& VEX_HWCAPS_PPC32_DFP
) && ! has_v_fx_gx
)
2028 invalid_hwcaps(arch
, hwcaps
,
2029 "DFP requires VMX and FX and GX capabilities\n");
2031 /* VX requires V and FX and GX */
2032 if ((hwcaps
& VEX_HWCAPS_PPC32_VX
) && ! has_v_fx_gx
)
2033 invalid_hwcaps(arch
, hwcaps
,
2034 "VX requires VMX and FX and GX capabilities\n");
2036 /* ISA2_07 requires everything else */
2037 if ((hwcaps
& VEX_HWCAPS_PPC32_ISA2_07
) != 0) {
2039 invalid_hwcaps(arch
, hwcaps
,
2040 "ISA2_07 requires VMX and FX and GX capabilities\n");
2041 if (! (hwcaps
& VEX_HWCAPS_PPC32_VX
))
2042 invalid_hwcaps(arch
, hwcaps
,
2043 "ISA2_07 requires VX capabilities\n");
2044 if (! (hwcaps
& VEX_HWCAPS_PPC32_DFP
))
2045 invalid_hwcaps(arch
, hwcaps
,
2046 "ISA2_07 requires DFP capabilities\n");
2049 /* ISA 3.0 not supported on 32-bit machines */
2050 if ((hwcaps
& VEX_HWCAPS_PPC32_ISA3_0
) != 0) {
2051 invalid_hwcaps(arch
, hwcaps
,
2052 "ISA 3.0 not supported in 32-bit mode \n");
2057 case VexArchPPC64
: {
2058 /* Monotonic with complications. Basically V > baseline(==F),
2059 but once you have F then you can have FX or GX too. */
2060 if (hwcaps
== 0) return; // baseline
2062 /* V, FX, and GX can appear in any combination */
2064 /* DFP requires V and FX and GX */
2065 UInt v_fx_gx
= VEX_HWCAPS_PPC64_V
| VEX_HWCAPS_PPC64_FX
|
2066 VEX_HWCAPS_PPC64_GX
;
2067 Bool has_v_fx_gx
= (hwcaps
& v_fx_gx
) == v_fx_gx
;
2069 if ((hwcaps
& VEX_HWCAPS_PPC64_DFP
) && ! has_v_fx_gx
)
2070 invalid_hwcaps(arch
, hwcaps
,
2071 "DFP requires VMX and FX and GX capabilities\n");
2073 /* VX requires V and FX and GX */
2074 if ((hwcaps
& VEX_HWCAPS_PPC32_VX
) && ! has_v_fx_gx
)
2075 invalid_hwcaps(arch
, hwcaps
,
2076 "VX requires VMX and FX and GX capabilities\n");
2078 /* ISA2_07 requires everything else */
2079 if ((hwcaps
& VEX_HWCAPS_PPC64_ISA2_07
) != 0) {
2081 invalid_hwcaps(arch
, hwcaps
,
2082 "ISA2_07 requires VMX and FX and GX capabilities\n");
2083 if (! (hwcaps
& VEX_HWCAPS_PPC64_VX
))
2084 invalid_hwcaps(arch
, hwcaps
,
2085 "ISA2_07 requires VX capabilities\n");
2086 if (! (hwcaps
& VEX_HWCAPS_PPC64_DFP
))
2087 invalid_hwcaps(arch
, hwcaps
,
2088 "ISA2_07 requires DFP capabilities\n");
2091 /* ISA3_0 requires everything else */
2092 if ((hwcaps
& VEX_HWCAPS_PPC64_ISA3_0
) != 0) {
2094 & VEX_HWCAPS_PPC64_ISA2_07
) == VEX_HWCAPS_PPC64_ISA2_07
))
2095 invalid_hwcaps(arch
, hwcaps
,
2096 "ISA3_0 requires ISA2_07 capabilities\n");
2098 invalid_hwcaps(arch
, hwcaps
,
2099 "ISA3_0 requires VMX and FX and GX capabilities\n");
2100 if ( !(hwcaps
& VEX_HWCAPS_PPC64_VX
))
2101 invalid_hwcaps(arch
, hwcaps
,
2102 "ISA3_0 requires VX capabilities\n");
2103 if ( !(hwcaps
& VEX_HWCAPS_PPC64_DFP
))
2104 invalid_hwcaps(arch
, hwcaps
,
2105 "ISA3_0 requires DFP capabilities\n");
2108 /* ISA3_1 requires everything else */
2109 if ((hwcaps
& VEX_HWCAPS_PPC64_ISA3_1
) != 0) {
2111 & VEX_HWCAPS_PPC64_ISA3_0
) == VEX_HWCAPS_PPC64_ISA3_0
))
2112 invalid_hwcaps(arch
, hwcaps
,
2113 "ISA3_1 requires ISA3_0 capabilities\n");
2115 & VEX_HWCAPS_PPC64_ISA2_07
) == VEX_HWCAPS_PPC64_ISA2_07
))
2116 invalid_hwcaps(arch
, hwcaps
,
2117 "ISA3_1 requires ISA2_07 capabilities\n");
2119 invalid_hwcaps(arch
, hwcaps
,
2120 "ISA3_1 requires VMX and FX and GX capabilities\n");
2121 if ( !(hwcaps
& VEX_HWCAPS_PPC64_VX
))
2122 invalid_hwcaps(arch
, hwcaps
,
2123 "ISA3_1 requires VX capabilities\n");
2124 if ( !(hwcaps
& VEX_HWCAPS_PPC64_DFP
))
2125 invalid_hwcaps(arch
, hwcaps
,
2126 "ISA3_1 requires DFP capabilities\n");
2132 Bool NEON
= ((hwcaps
& VEX_HWCAPS_ARM_NEON
) != 0);
2133 Bool VFP3
= ((hwcaps
& VEX_HWCAPS_ARM_VFP3
) != 0);
2134 UInt level
= VEX_ARM_ARCHLEVEL(hwcaps
);
2138 invalid_hwcaps(arch
, hwcaps
,
2139 "NEON instructions are not supported for ARMv5.\n");
2143 invalid_hwcaps(arch
, hwcaps
,
2144 "NEON instructions are not supported for ARMv6.\n");
2150 invalid_hwcaps(arch
, hwcaps
,
2151 "NEON and VFP3 are required for ARMv8.\n");
2154 invalid_hwcaps(arch
, hwcaps
,
2155 "ARM architecture level is not supported.\n");
2159 case VexArchARM64
: {
2160 /* Mandatory dependencies. */
2161 Bool have_fp16
= ((hwcaps
& VEX_HWCAPS_ARM64_FP16
) != 0);
2162 Bool have_vfp16
= ((hwcaps
& VEX_HWCAPS_ARM64_VFP16
) != 0);
2163 if (have_fp16
!= have_vfp16
)
2164 invalid_hwcaps(arch
, hwcaps
,
2165 "Mismatch detected between scalar and vector FP16 features.\n");
2170 if (! s390_host_has_ldisp
)
2171 invalid_hwcaps(arch
, hwcaps
,
2172 "Host does not have long displacement facility.\n");
2176 switch (VEX_MIPS_COMP_ID(hwcaps
)) {
2177 case VEX_PRID_COMP_MIPS
:
2178 case VEX_PRID_COMP_CAVIUM
:
2179 case VEX_PRID_COMP_INGENIC_E1
:
2180 case VEX_PRID_COMP_BROADCOM
:
2181 case VEX_PRID_COMP_NETLOGIC
:
2184 invalid_hwcaps(arch
, hwcaps
, "Unsupported baseline\n");
2188 switch (VEX_MIPS_COMP_ID(hwcaps
)) {
2189 case VEX_PRID_COMP_MIPS
:
2190 case VEX_PRID_COMP_CAVIUM
:
2191 case VEX_PRID_COMP_NETLOGIC
:
2193 case VEX_PRID_COMP_LEGACY
:
2194 if (VEX_MIPS_PROC_ID(hwcaps
) == VEX_PRID_IMP_LOONGSON_64
)
2198 invalid_hwcaps(arch
, hwcaps
, "Unsupported baseline\n");
2201 case VexArchNANOMIPS
:
2204 invalid_hwcaps(arch
, hwcaps
, "Unsupported baseline\n");
2207 vpanic("unknown architecture");
2212 /*---------------------------------------------------------------*/
2213 /*--- end main_main.c ---*/
2214 /*---------------------------------------------------------------*/