14f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov/*--------------------------------------------------------------------*/
28530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany/*--- Machine-related stuff.                           m_machine.c ---*/
38530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany/*--------------------------------------------------------------------*/
48530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
58530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany/*
68530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   This file is part of Valgrind, a dynamic binary instrumentation
78530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   framework.
88530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
98530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   Copyright (C) 2000-2013 Julian Seward
108530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany      jseward@acm.org
118530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
128530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   This program is free software; you can redistribute it and/or
138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   modify it under the terms of the GNU General Public License as
148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   published by the Free Software Foundation; either version 2 of the
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   License, or (at your option) any later version.
165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   This program is distributed in the hope that it will be useful, but
188530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany   WITHOUT ANY WARRANTY; without even the implied warranty of
190586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany   General Public License for more details.
21c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany
2267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   You should have received a copy of the GNU General Public License
23c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   along with this program; if not, write to the Free Software
2414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
255e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov   02111-1307, USA.
265e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
2711f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov   The GNU General Public License is contained in the file COPYING.
285cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov*/
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
308530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "pub_core_basics.h"
316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany#include "pub_core_vki.h"
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "pub_core_libcsetjmp.h"   // setjmp facilities
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "pub_core_threadstate.h"
3474737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov#include "pub_core_libcassert.h"
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "pub_core_libcbase.h"
36b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#include "pub_core_libcfile.h"
37996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "pub_core_libcprint.h"
38996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "pub_core_mallocfree.h"
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "pub_core_machine.h"
40348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#include "pub_core_cpuid.h"
41348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#include "pub_core_libcsignal.h"   // for ppc32 messing with SIGILL and SIGFPE
42348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#include "pub_core_debuglog.h"
430586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INSTR_PTR(regs)    ((regs).vex.VG_INSTR_PTR)
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define STACK_PTR(regs)    ((regs).vex.VG_STACK_PTR)
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define FRAME_PTR(regs)    ((regs).vex.VG_FRAME_PTR)
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
490586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry VyukovAddr VG_(get_IP) ( ThreadId tid ) {
500586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov   return INSTR_PTR( VG_(threads)[tid].arch );
5167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov}
525cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry VyukovAddr VG_(get_SP) ( ThreadId tid ) {
535e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov   return STACK_PTR( VG_(threads)[tid].arch );
545e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
555e2d3776a314629680921abd1d55d89d95a2da90Alexey SamsonovAddr VG_(get_FP) ( ThreadId tid ) {
565cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov   return FRAME_PTR( VG_(threads)[tid].arch );
575e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
585e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
595e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonovvoid VG_(set_IP) ( ThreadId tid, Addr ip ) {
605cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov   INSTR_PTR( VG_(threads)[tid].arch ) = ip;
6167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov}
6267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovvoid VG_(set_SP) ( ThreadId tid, Addr sp ) {
6311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov   STACK_PTR( VG_(threads)[tid].arch ) = sp;
6411f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov}
6511f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov
6611f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukovvoid VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                ThreadId tid )
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines{
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  if defined(VGA_x86)
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_EIP;
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_ESP;
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.X86.r_ebp
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_EBP;
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_amd64)
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = VG_(threads)[tid].arch.vex.guest_RIP;
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = VG_(threads)[tid].arch.vex.guest_RSP;
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.AMD64.r_rbp
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_RBP;
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_ppc32)
802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_CIA;
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_GPR1;
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.PPC32.r_lr
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_LR;
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_ppc64)
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = VG_(threads)[tid].arch.vex.guest_CIA;
862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = VG_(threads)[tid].arch.vex.guest_GPR1;
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.PPC64.r_lr
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_LR;
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_arm)
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_R15T;
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R13;
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM.r14
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_R14;
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM.r12
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_R12;
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM.r11
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_R11;
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM.r7
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_R7;
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_arm64)
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC;
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = VG_(threads)[tid].arch.vex.guest_XSP;
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM64.x29 = VG_(threads)[tid].arch.vex.guest_X29;
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.ARM64.x30 = VG_(threads)[tid].arch.vex.guest_X30;
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_s390x)
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_IA;
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_SP;
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.S390X.r_fp
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r11;
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.S390X.r_lr
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r14;
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_mips32)
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC;
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29;
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS32.r30
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r30;
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS32.r31
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r31;
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS32.r28
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r28;
1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif defined(VGA_mips64)
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC;
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29;
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS64.r30
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r30;
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS64.r31
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r31;
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   regs->misc.MIPS64.r28
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      = VG_(threads)[tid].arch.vex.guest_r28;
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  else
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    error "Unknown arch"
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  endif
1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVG_(get_shadow_regs_area) ( ThreadId tid,
1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /*DST*/UChar* dst,
1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /*SRC*/Int shadowNo, PtrdiffT offset, SizeT size )
1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines{
1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   void*        src;
1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   ThreadState* tst;
1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   vg_assert(VG_(is_valid_tid)(tid));
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   // Bounds check
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   vg_assert(offset + size <= sizeof(VexGuestArchState));
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   // Copy
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   tst = & VG_(threads)[tid];
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   src = NULL;
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   switch (shadowNo) {
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      case 0: src = (void*)(((Addr)&(tst->arch.vex)) + offset); break;
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      case 1: src = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break;
1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      case 2: src = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break;
1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   tl_assert(src != NULL);
15667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   VG_(memcpy)( dst, src, size);
15767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
15867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
15967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovvoid
16067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey SamsonovVG_(set_shadow_regs_area) ( ThreadId tid,
16167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov                            /*DST*/Int shadowNo, PtrdiffT offset, SizeT size,
16267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov                            /*SRC*/const UChar* src )
16367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov{
16467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   void*        dst;
16567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   ThreadState* tst;
166a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
16767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   vg_assert(VG_(is_valid_tid)(tid));
16867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   // Bounds check
16967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
17067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   vg_assert(offset + size <= sizeof(VexGuestArchState));
17167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   // Copy
17267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   tst = & VG_(threads)[tid];
17367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   dst = NULL;
17467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   switch (shadowNo) {
17567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov      case 0: dst = (void*)(((Addr)&(tst->arch.vex)) + offset); break;
17667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov      case 1: dst = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break;
17767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov      case 2: dst = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break;
17867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   }
17967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   tl_assert(dst != NULL);
18067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   VG_(memcpy)( dst, src, size);
18167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
18267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
18367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
18467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovstatic void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId,
18567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov                                                        const HChar*, Addr))
18667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov{
18767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   VexGuestArchState* vex = &(VG_(get_ThreadState)(tid)->arch.vex);
18867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   VG_(debugLog)(2, "machine", "apply_to_GPs_of_tid %d\n", tid);
18967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#if defined(VGA_x86)
19067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "EAX", vex->guest_EAX);
191a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "ECX", vex->guest_ECX);
192a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "EDX", vex->guest_EDX);
19367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "EBX", vex->guest_EBX);
19467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "ESI", vex->guest_ESI);
19567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "EDI", vex->guest_EDI);
19667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "ESP", vex->guest_ESP);
19767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov   (*f)(tid, "EBP", vex->guest_EBP);
198be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#elif defined(VGA_amd64)
199be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RAX", vex->guest_RAX);
200be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RCX", vex->guest_RCX);
201be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RDX", vex->guest_RDX);
202be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RBX", vex->guest_RBX);
203be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RSI", vex->guest_RSI);
204be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RDI", vex->guest_RDI);
205be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RSP", vex->guest_RSP);
206be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "RBP", vex->guest_RBP);
207be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R8" , vex->guest_R8 );
208be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R9" , vex->guest_R9 );
209be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R10", vex->guest_R10);
210a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "R11", vex->guest_R11);
211be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R12", vex->guest_R12);
212be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R13", vex->guest_R13);
213a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "R14", vex->guest_R14);
214be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "R15", vex->guest_R15);
215be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#elif defined(VGA_ppc32) || defined(VGA_ppc64)
216be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR0" , vex->guest_GPR0 );
217be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR1" , vex->guest_GPR1 );
218be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR2" , vex->guest_GPR2 );
219be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR3" , vex->guest_GPR3 );
220be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR4" , vex->guest_GPR4 );
221be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR5" , vex->guest_GPR5 );
222be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR6" , vex->guest_GPR6 );
223be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR7" , vex->guest_GPR7 );
224be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR8" , vex->guest_GPR8 );
225be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR9" , vex->guest_GPR9 );
226be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR10", vex->guest_GPR10);
227be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR11", vex->guest_GPR11);
228a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "GPR12", vex->guest_GPR12);
229be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR13", vex->guest_GPR13);
230be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR14", vex->guest_GPR14);
231be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR15", vex->guest_GPR15);
232be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR16", vex->guest_GPR16);
233be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR17", vex->guest_GPR17);
234be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR18", vex->guest_GPR18);
235a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "GPR19", vex->guest_GPR19);
236a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "GPR20", vex->guest_GPR20);
237be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR21", vex->guest_GPR21);
238be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR22", vex->guest_GPR22);
239be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR23", vex->guest_GPR23);
240be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR24", vex->guest_GPR24);
241be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov   (*f)(tid, "GPR25", vex->guest_GPR25);
2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR26", vex->guest_GPR26);
2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR27", vex->guest_GPR27);
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR28", vex->guest_GPR28);
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR29", vex->guest_GPR29);
2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR30", vex->guest_GPR30);
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "GPR31", vex->guest_GPR31);
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "CTR"  , vex->guest_CTR  );
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "LR"   , vex->guest_LR   );
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_arm)
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R0" , vex->guest_R0 );
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R1" , vex->guest_R1 );
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R2" , vex->guest_R2 );
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R3" , vex->guest_R3 );
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R4" , vex->guest_R4 );
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R5" , vex->guest_R5 );
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R6" , vex->guest_R6 );
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R8" , vex->guest_R8 );
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R9" , vex->guest_R9 );
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R10", vex->guest_R10);
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R11", vex->guest_R11);
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R12", vex->guest_R12);
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R13", vex->guest_R13);
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "R14", vex->guest_R14);
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_s390x)
2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "r0" , vex->guest_r0 );
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "r1" , vex->guest_r1 );
2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "r2" , vex->guest_r2 );
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   (*f)(tid, "r3" , vex->guest_r3 );
2707cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r4" , vex->guest_r4 );
2717cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r5" , vex->guest_r5 );
2727cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r6" , vex->guest_r6 );
2737cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r7" , vex->guest_r7 );
2745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r8" , vex->guest_r8 );
2757cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r9" , vex->guest_r9 );
2765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r10", vex->guest_r10);
2777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r11", vex->guest_r11);
2787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r12", vex->guest_r12);
2797cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r13", vex->guest_r13);
280a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r14", vex->guest_r14);
281ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov   (*f)(tid, "r15", vex->guest_r15);
282ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#elif defined(VGA_mips32) || defined(VGA_mips64)
283a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r0" , vex->guest_r0 );
284ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov   (*f)(tid, "r1" , vex->guest_r1 );
285ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov   (*f)(tid, "r2" , vex->guest_r2 );
2867cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r3" , vex->guest_r3 );
2877cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r4" , vex->guest_r4 );
2887cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r5" , vex->guest_r5 );
2895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r6" , vex->guest_r6 );
2905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r7" , vex->guest_r7 );
2915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r8" , vex->guest_r8 );
2927cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r9" , vex->guest_r9 );
2937cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r10", vex->guest_r10);
2947cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r11", vex->guest_r11);
2957cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r12", vex->guest_r12);
2967cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r13", vex->guest_r13);
2977cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r14", vex->guest_r14);
2987cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r15", vex->guest_r15);
2997cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r16", vex->guest_r16);
3005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r17", vex->guest_r17);
3015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r18", vex->guest_r18);
3025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "r19", vex->guest_r19);
3037cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r20", vex->guest_r20);
3047cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r21", vex->guest_r21);
3057cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r22", vex->guest_r22);
3067cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r23", vex->guest_r23);
3077cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r24", vex->guest_r24);
308a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r25", vex->guest_r25);
309a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r26", vex->guest_r26);
310a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r27", vex->guest_r27);
3117cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r28", vex->guest_r28);
312ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov   (*f)(tid, "r29", vex->guest_r29);
313a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "r30", vex->guest_r30);
3147cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov   (*f)(tid, "r31", vex->guest_r31);
315b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#elif defined(VGA_arm64)
316b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x0" , vex->guest_X0 );
317b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x1" , vex->guest_X1 );
318b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x2" , vex->guest_X2 );
319b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x3" , vex->guest_X3 );
320b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x4" , vex->guest_X4 );
321b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x5" , vex->guest_X5 );
322b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x6" , vex->guest_X6 );
323b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x7" , vex->guest_X7 );
324b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x8" , vex->guest_X8 );
325b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x9" , vex->guest_X9 );
326b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x10", vex->guest_X10);
327b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x11", vex->guest_X11);
328b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x12", vex->guest_X12);
329b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x13", vex->guest_X13);
330b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x14", vex->guest_X14);
331b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x15", vex->guest_X15);
332b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x16", vex->guest_X16);
333b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x17", vex->guest_X17);
334b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x18", vex->guest_X18);
335b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (*f)(tid, "x19", vex->guest_X19);
3368ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov   (*f)(tid, "x20", vex->guest_X20);
3376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany   (*f)(tid, "x21", vex->guest_X21);
33844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov   (*f)(tid, "x22", vex->guest_X22);
339996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov   (*f)(tid, "x23", vex->guest_X23);
34067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   (*f)(tid, "x24", vex->guest_X24);
3415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "x25", vex->guest_X25);
3425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "x26", vex->guest_X26);
3435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   (*f)(tid, "x27", vex->guest_X27);
3446afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany   (*f)(tid, "x28", vex->guest_X28);
345a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "x29", vex->guest_X29);
346a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   (*f)(tid, "x30", vex->guest_X30);
3478530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#else
3488530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#  error Unknown arch
349a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif
350c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
35144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov
3528ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov
3538530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryanyvoid VG_(apply_to_GP_regs)(void (*f)(ThreadId, const HChar*, UWord))
354c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov{
3556afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany   ThreadId tid;
35644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov
357996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov   for (tid = 1; tid < VG_N_THREADS; tid++) {
35867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov      if (VG_(is_valid_tid)(tid)
3595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines          || VG_(threads)[tid].exitreason == VgSrc_ExitProcess) {
3605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines         // live thread or thread instructed to die by another thread that
3615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines         // called exit.
3626afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany         apply_to_GPs_of_tid(tid, f);
363a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      }
364a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   }
3658530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
3668530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
367a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovvoid VG_(thread_stack_reset_iter)(/*OUT*/ThreadId* tid)
368c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany{
36944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov   *tid = (ThreadId)(-1);
370c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov}
3718530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
372b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya SerebryanyBool VG_(thread_stack_next)(/*MOD*/ThreadId* tid,
3736afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany                            /*OUT*/Addr* stack_min,
37444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov                            /*OUT*/Addr* stack_max)
375996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov{
37667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   ThreadId i;
3775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   for (i = (*tid)+1; i < VG_N_THREADS; i++) {
3785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      if (i == VG_INVALID_THREADID)
3795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines         continue;
3806afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany      if (VG_(threads)[i].status != VgTs_Empty) {
381a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov         *tid       = i;
382a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov         *stack_min = VG_(get_SP)(i);
3838530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany         *stack_max = VG_(threads)[i].client_stack_highest_word;
3848530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany         return True;
385a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      }
386c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   }
38744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov   return False;
3881f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko}
3898530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
390b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovAddr VG_(thread_get_stack_max)(ThreadId tid)
391b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov{
392b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
393b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(VG_(threads)[tid].status != VgTs_Empty);
394b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   return VG_(threads)[tid].client_stack_highest_word;
39567f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov}
396b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
397b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovSizeT VG_(thread_get_stack_size)(ThreadId tid)
398b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov{
399b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
400b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(VG_(threads)[tid].status != VgTs_Empty);
401a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   return VG_(threads)[tid].client_stack_szB;
402b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
403b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
404b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovAddr VG_(thread_get_altstack_min)(ThreadId tid)
405b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov{
406b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
407b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(VG_(threads)[tid].status != VgTs_Empty);
408b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   return (Addr)VG_(threads)[tid].altstack.ss_sp;
409b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
410b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
41167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry VyukovSizeT VG_(thread_get_altstack_size)(ThreadId tid)
412b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov{
413b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
414b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(VG_(threads)[tid].status != VgTs_Empty);
415b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   return VG_(threads)[tid].altstack.ss_size;
416b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
417a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
418b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov//-------------------------------------------------------------
419b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov/* Details about the capabilities of the underlying (host) CPU.  These
420b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   details are acquired by (1) enquiring with the CPU at startup, or
421b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   (2) from the AT_SYSINFO entries the kernel gave us (ppc32 cache
422b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   line size).  It's a bit nasty in the sense that there's no obvious
423b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   way to stop uses of some of this info before it's ready to go.
424b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   See pub_core_machine.h for more information about that.
425b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
426b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   VG_(machine_get_hwcaps) may use signals (although it attempts to
42767f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   leave signal state unchanged) and therefore should only be
428b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   called before m_main sets up the client's signal state.
429b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov*/
430b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
431b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov/* --------- State --------- */
432b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic Bool hwcaps_done = False;
433a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
434b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov/* --- all archs --- */
435b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic VexArch     va = VexArch_INVALID;
436b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic VexArchInfo vai;
437b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
438c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if defined(VGA_x86)
439c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyUInt VG_(machine_x86_have_mxcsr) = 0;
44044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#endif
441996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#if defined(VGA_ppc32)
44267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry VyukovUInt VG_(machine_ppc32_has_FP)  = 0;
443a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy StepanovUInt VG_(machine_ppc32_has_VMX) = 0;
444c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#endif
445b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if defined(VGA_ppc64)
446a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy StepanovULong VG_(machine_ppc64_has_VMX) = 0;
447c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#endif
448c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if defined(VGA_arm)
449a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy StepanovInt VG_(machine_arm_archlevel) = 4;
450153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
45144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov
452153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
453153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany/* For hwcaps detection on ppc32/64, s390x, and arm we'll need to do SIGILL
454c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   testing, so we need a VG_MINIMAL_JMP_BUF. */
455f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov#if defined(VGA_ppc32) || defined(VGA_ppc64) \
45644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    || defined(VGA_arm) || defined(VGA_s390x) || defined(VGA_mips32)
457f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov#include "pub_core_libcsetjmp.h"
45867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovstatic VG_MINIMAL_JMP_BUF(env_unsup_insn);
459a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovstatic void handler_unsup_insn ( Int x ) {
460f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov   VG_MINIMAL_LONGJMP(env_unsup_insn);
461a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov}
462c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#endif
463c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
464a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
465153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany/* Helper function for VG_(machine_get_hwcaps), assumes the SIGILL/etc
46644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov * handlers are installed.  Determines the the sizes affected by dcbz
467153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany * and dcbzl instructions and updates the given VexArchInfo structure
468153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany * accordingly.
469c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany *
470f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov * Not very defensive: assumes that as long as the dcbz/dcbzl
471f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov * instructions don't raise a SIGILL, that they will zero an aligned,
47244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov * contiguous block of memory of a sensible size. */
473f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov#if defined(VGA_ppc32) || defined(VGA_ppc64)
47467f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovstatic void find_ppc_dcbz_sz(VexArchInfo *arch_info)
475a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov{
476f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov   Int dcbz_szB = 0;
477a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   Int dcbzl_szB;
478c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#  define MAX_DCBZL_SZB (128) /* largest known effect of dcbzl */
479c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   char test_block[4*MAX_DCBZL_SZB];
480a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   char *aligned = test_block;
481153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany   Int i;
48244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov
483153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany   /* round up to next max block size, assumes MAX_DCBZL_SZB is pof2 */
484153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany   aligned = (char *)(((HWord)aligned + MAX_DCBZL_SZB) & ~(MAX_DCBZL_SZB - 1));
485b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert((aligned + MAX_DCBZL_SZB) <= &test_block[sizeof(test_block)]);
486b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
487b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   /* dcbz often clears 32B, although sometimes whatever the native cache
488b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    * block size is */
489b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   VG_(memset)(test_block, 0xff, sizeof(test_block));
49067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   __asm__ __volatile__("dcbz 0,%0"
491b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        : /*out*/
492b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        : "r" (aligned) /*in*/
493b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        : "memory" /*clobber*/);
494b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   for (dcbz_szB = 0, i = 0; i < sizeof(test_block); ++i) {
495b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      if (!test_block[i])
496a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov         ++dcbz_szB;
497b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   }
498b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   vg_assert(dcbz_szB == 16 || dcbz_szB == 32 || dcbz_szB == 64 || dcbz_szB == 128);
499b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
500b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   /* dcbzl clears 128B on G5/PPC970, and usually 32B on other platforms */
501b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
502b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      dcbzl_szB = 0; /* indicates unsupported */
503b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   }
504b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   else {
505b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      VG_(memset)(test_block, 0xff, sizeof(test_block));
50667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov      /* some older assemblers won't understand the dcbzl instruction
507b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov       * variant, so we directly emit the instruction ourselves */
508b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      __asm__ __volatile__("mr 9, %0 ; .long 0x7C204FEC" /*dcbzl 0,9*/
509b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                           : /*out*/
510b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                           : "r" (aligned) /*in*/
511b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                           : "memory", "r9" /*clobber*/);
512a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      for (dcbzl_szB = 0, i = 0; i < sizeof(test_block); ++i) {
513b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov         if (!test_block[i])
514b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            ++dcbzl_szB;
515b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      }
516b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov      vg_assert(dcbzl_szB == 16 || dcbzl_szB == 32 || dcbzl_szB == 64 || dcbzl_szB == 128);
517b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   }
518b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
519b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   arch_info->ppc_dcbz_szB  = dcbz_szB;
520b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   arch_info->ppc_dcbzl_szB = dcbzl_szB;
521b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
52267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov   VG_(debugLog)(1, "machine", "dcbz_szB=%d dcbzl_szB=%d\n",
523b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                 dcbz_szB, dcbzl_szB);
524b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#  undef MAX_DCBZL_SZB
525b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
526b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif /* defined(VGA_ppc32) || defined(VGA_ppc64) */
527b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
528a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#ifdef VGA_s390x
529b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
530b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov/* Read /proc/cpuinfo. Look for lines like these
531b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
532b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov   processor 0: version = FF,  identification = 0117C9,  machine = 2064
533c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
534a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   and return the machine model. If the machine model could not be determined
535a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   or it is an unknown model, return VEX_S390X_MODEL_UNKNOWN. */
536a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
53744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanovstatic UInt VG_(get_machine_model)(void)
538996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov{
539c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   static struct model_map {
540c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      HChar name[5];
541c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      UInt  id;
542c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany   } model_map[] = {
54344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov      { "2064", VEX_S390X_MODEL_Z900 },
544c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      { "2066", VEX_S390X_MODEL_Z800 },
545996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov      { "2084", VEX_S390X_MODEL_Z990 },
546c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      { "2086", VEX_S390X_MODEL_Z890 },
547c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      { "2094", VEX_S390X_MODEL_Z9_EC },
548c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      { "2096", VEX_S390X_MODEL_Z9_BC },
549a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      { "2097", VEX_S390X_MODEL_Z10_EC },
550c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany      { "2098", VEX_S390X_MODEL_Z10_BC },
55144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov      { "2817", VEX_S390X_MODEL_Z196 },
552a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      { "2818", VEX_S390X_MODEL_Z114 },
553fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov      { "2827", VEX_S390X_MODEL_ZEC12 },
554fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov      { "2828", VEX_S390X_MODEL_ZBC12 },
555fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov   };
556fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
557fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov   Int    model, n, fh;
5585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   SysRes fd;
5595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   SizeT  num_bytes, file_buf_size;
56015832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko   HChar *p, *m, *model_name, *file_buf;
561fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
5625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   /* Slurp contents of /proc/cpuinfo into FILE_BUF */
563fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov   fd = VG_(open)( "/proc/cpuinfo", 0, VKI_S_IRUSR );
564fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov   if ( sr_isError(fd) ) return VEX_S390X_MODEL_UNKNOWN;
565fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
566a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   fh  = sr_Res(fd);
567fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
568fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov   /* Determine the size of /proc/cpuinfo.
569a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      Work around broken-ness in /proc file system implementation.
570fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov      fstat returns a zero size for /proc/cpuinfo although it is
5719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      claimed to be a regular file. */
572cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   num_bytes = 0;
573cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   file_buf_size = 1000;
5740586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov   file_buf = VG_(malloc)("cpuinfo", file_buf_size + 1);
5750586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov   while (42) {
5760586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov      n = VG_(read)(fh, file_buf, file_buf_size);
5772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (n < 0) break;
5780586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov
5790586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov      num_bytes += n;
580cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov      if (n < file_buf_size) break;  /* reached EOF */
581cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   }
5829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
5839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   if (n < 0) num_bytes = 0;   /* read error; ignore contents */
584cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov
5859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   if (num_bytes > file_buf_size) {
5869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      VG_(free)( file_buf );
587cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov      VG_(lseek)( fh, 0, VKI_SEEK_SET );
5889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      file_buf = VG_(malloc)( "cpuinfo", num_bytes + 1 );
5899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      n = VG_(read)( fh, file_buf, num_bytes );
5909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      if (n < 0) num_bytes = 0;
591cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   }
5929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
5939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   file_buf[num_bytes] = '\0';
594cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   VG_(close)(fh);
5959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
5969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   /* Parse file */
597cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   model = VEX_S390X_MODEL_UNKNOWN;
5989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   for (p = file_buf; *p; ++p) {
5999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      /* Beginning of line */
6009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     if (VG_(strncmp)( p, "processor", sizeof "processor" - 1 ) != 0) continue;
601cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov
6029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     m = VG_(strstr)( p, "machine" );
6039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     if (m == NULL) continue;
604cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov
6059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     p = m + sizeof "machine" - 1;
6069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     while ( VG_(isspace)( *p ) || *p == '=') {
607cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov       if (*p == '\n') goto next_line;
6089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov       ++p;
6099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     }
6109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
611cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov     model_name = p;
6129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     for (n = 0; n < sizeof model_map / sizeof model_map[0]; ++n) {
6139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov       struct model_map *mm = model_map + n;
614cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov       SizeT len = VG_(strlen)( mm->name );
6159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov       if ( VG_(strncmp)( mm->name, model_name, len ) == 0 &&
6169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov            VG_(isspace)( model_name[len] )) {
617cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov         if (mm->id < model) model = mm->id;
6189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov         p = model_name + len;
6199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov         break;
6209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov       }
6219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     }
6229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     /* Skip until end-of-line */
6239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov     while (*p != '\n')
6245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines       ++p;
6255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   next_line: ;
6265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   }
6279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
6289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   VG_(free)( file_buf );
6299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   VG_(debugLog)(1, "machine", "model = %s\n",
6309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov                 model == VEX_S390X_MODEL_UNKNOWN ? "UNKNOWN"
6319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov                                                  : model_map[model].name);
6329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   return model;
6339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
6349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
6359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#endif /* VGA_s390x */
6369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
6375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if defined(VGA_mips32) || defined(VGA_mips64)
6385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
6395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines/* Read /proc/cpuinfo and return the machine model. */
6409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovstatic UInt VG_(get_machine_model)(void)
6419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov{
6429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   const char *search_MIPS_str = "MIPS";
6439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   const char *search_Broadcom_str = "Broadcom";
6449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   const char *search_Netlogic_str = "Netlogic";
6459358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   const char *search_Cavium_str= "Cavium";
6469358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   Int    n, fh;
647cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   SysRes fd;
6489358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   SizeT  num_bytes, file_buf_size;
6499358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   HChar  *file_buf;
6505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
6515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   /* Slurp contents of /proc/cpuinfo into FILE_BUF */
6525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   fd = VG_(open)( "/proc/cpuinfo", 0, VKI_S_IRUSR );
6539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   if ( sr_isError(fd) ) return -1;
6549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
655cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov   fh  = sr_Res(fd);
6569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
6579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   /* Determine the size of /proc/cpuinfo.
6589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      Work around broken-ness in /proc file system implementation.
6599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      fstat returns a zero size for /proc/cpuinfo although it is
660cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov      claimed to be a regular file. */
6619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   num_bytes = 0;
6629358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   file_buf_size = 1000;
6635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   file_buf = VG_(malloc)("cpuinfo", file_buf_size + 1);
6645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   while (42) {
6655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      n = VG_(read)(fh, file_buf, file_buf_size);
6669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      if (n < 0) break;
6679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
668cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov      num_bytes += n;
6699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov      if (n < file_buf_size) break;  /* reached EOF */
6709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   }
6719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
6729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov   if (n < 0) num_bytes = 0;   /* read error; ignore contents */
6732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   if (num_bytes > file_buf_size) {
6752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      VG_(free)( file_buf );
6762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      VG_(lseek)( fh, 0, VKI_SEEK_SET );
6772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      file_buf = VG_(malloc)( "cpuinfo", num_bytes + 1 );
6782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      n = VG_(read)( fh, file_buf, num_bytes );
6792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (n < 0) num_bytes = 0;
6802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
6812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   file_buf[num_bytes] = '\0';
6832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   VG_(close)(fh);
6842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   /* Parse file */
6862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   if (VG_(strstr) (file_buf, search_Broadcom_str) != NULL)
687a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov       return VEX_PRID_COMP_BROADCOM;
688a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   if (VG_(strstr) (file_buf, search_Netlogic_str) != NULL)
689a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov       return VEX_PRID_COMP_NETLOGIC;
690a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   if (VG_(strstr)(file_buf, search_Cavium_str) != NULL)
691a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov       return VEX_PRID_COMP_CAVIUM;
692a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   if (VG_(strstr) (file_buf, search_MIPS_str) != NULL)
693a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov       return VEX_PRID_COMP_MIPS;
694a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
6952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   /* Did not find string in the proc file. */
6962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   return -1;
6979358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
6989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
699a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif
7009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
701e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov/* Determine what insn set and insn set variant the host has, and
702e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   record it.  To be called once at system startup.  Returns False if
703e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   this a CPU incapable of running Valgrind.
704e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   Also determine information about the caches on this host. */
705e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
706e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy StepanovBool VG_(machine_get_hwcaps)( void )
7075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines{
7085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   vg_assert(hwcaps_done == False);
7095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   hwcaps_done = True;
710e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
711e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   // Whack default settings into vai, so that we only need to fill in
712e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   // any interesting bits.
713e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov   LibVEX_default_VexArchInfo(&vai);
714e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
715e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#if defined(VGA_x86)
716a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   { Bool have_sse1, have_sse2, have_cx8, have_lzcnt, have_mmxext;
717e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov     UInt eax, ebx, ecx, edx, max_extended;
718e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov     HChar vstr[13];
719e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov     vstr[0] = 0;
720a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
721e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov     if (!VG_(has_cpuid)())
722e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov        /* we can't do cpuid at all.  Give up. */
723e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov        return False;
724e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
7252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(cpuid)(0, 0, &eax, &ebx, &ecx, &edx);
7262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (eax < 1)
727996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov        /* we can't ask for cpuid(x) for x > 0.  Give up. */
7282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return False;
7292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
7302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Get processor ID string, and max basic/extended index
7312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        values. */
7322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(memcpy)(&vstr[0], &ebx, 4);
7332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(memcpy)(&vstr[4], &edx, 4);
7342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(memcpy)(&vstr[8], &ecx, 4);
7352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vstr[12] = 0;
7362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
7372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(cpuid)(0x80000000, 0, &eax, &ebx, &ecx, &edx);
7382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     max_extended = eax;
7392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
7402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* get capabilities bits into edx */
7412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(cpuid)(1, 0, &eax, &ebx, &ecx, &edx);
742996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
743c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov     have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
7444ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
7454ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7464ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     /* cmpxchg8b is a minimum requirement now; if we don't have it we
7474ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        must simply give up.  But all CPUs since Pentium-I have it, so
7484ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        that doesn't seem like much of a restriction. */
7494ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
7504ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     if (!have_cx8)
751c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov        return False;
7524ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7534ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     /* Figure out if this is an AMD that can do MMXEXT. */
7544ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     have_mmxext = False;
755996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     if (0 == VG_(strcmp)(vstr, "AuthenticAMD")
7564ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov         && max_extended >= 0x80000001) {
757c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov        VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx);
758996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov        /* Some older AMD processors support a sse1 subset (Integer SSE). */
7594ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        have_mmxext = !have_sse1 && ((edx & (1<<22)) != 0);
760c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov     }
761996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7624ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     /* Figure out if this is an AMD or Intel that can do LZCNT. */
763c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov     have_lzcnt = False;
764996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     if ((0 == VG_(strcmp)(vstr, "AuthenticAMD")
7659eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko          || 0 == VG_(strcmp)(vstr, "GenuineIntel"))
7664ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov         && max_extended >= 0x80000001) {
767c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov        VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx);
768996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov        have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */
7694ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     }
7704ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
771c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov     /* Intel processors don't define the mmxext extension, but since it
7724ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        is just a sse1 subset always define it when we have sse1. */
7734ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     if (have_sse1)
774c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov        have_mmxext = True;
7759eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko
7764ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     va = VexArchX86;
7774ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov     if (have_sse2 && have_sse1 && have_mmxext) {
7782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT;
7794ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        vai.hwcaps |= VEX_HWCAPS_X86_SSE1;
7804ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        vai.hwcaps |= VEX_HWCAPS_X86_SSE2;
7812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if (have_lzcnt)
7824ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov           vai.hwcaps |= VEX_HWCAPS_X86_LZCNT;
7834ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        VG_(machine_x86_have_mxcsr) = 1;
7842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else if (have_sse1 && have_mmxext) {
7854ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT;
7869eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko        vai.hwcaps |= VEX_HWCAPS_X86_SSE1;
7874ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        VG_(machine_x86_have_mxcsr) = 1;
7882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else if (have_mmxext) {
7894ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT; /*integer only sse1 subset*/
7904ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov        VG_(machine_x86_have_mxcsr) = 0;
7912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
7924ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov       vai.hwcaps = 0; /*baseline - no sse at all*/
7934ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov       VG_(machine_x86_have_mxcsr) = 0;
7942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
7959eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko
796996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     VG_(machine_get_cache_info)(&vai);
797ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov
798996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     return True;
799ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov   }
800a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
801a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#elif defined(VGA_amd64)
802a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   { Bool have_sse3, have_cx8, have_cx16;
803a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     Bool have_lzcnt, have_avx, have_bmi, have_avx2;
804a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     Bool have_rdtscp;
805a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     UInt eax, ebx, ecx, edx, max_basic, max_extended;
806a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     HChar vstr[13];
807996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     vstr[0] = 0;
808996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
809996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov     if (!VG_(has_cpuid)())
810996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov        /* we can't do cpuid at all.  Give up. */
811ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov        return False;
812a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
813a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     VG_(cpuid)(0, 0, &eax, &ebx, &ecx, &edx);
814a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     max_basic = eax;
815a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     if (max_basic < 1)
816a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        /* we can't ask for cpuid(x) for x > 0.  Give up. */
817a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        return False;
818a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
819ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov     /* Get processor ID string, and max basic/extended index
820ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov        values. */
821ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov     VG_(memcpy)(&vstr[0], &ebx, 4);
822745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov     VG_(memcpy)(&vstr[4], &edx, 4);
8232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(memcpy)(&vstr[8], &ecx, 4);
8242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vstr[12] = 0;
8252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(cpuid)(0x80000000, 0, &eax, &ebx, &ecx, &edx);
8272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     max_extended = eax;
8282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* get capabilities bits into edx */
8302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(cpuid)(1, 0, &eax, &ebx, &ecx, &edx);
8312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // we assume that SSE1 and SSE2 are available by default
8332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_sse3 = (ecx & (1<<0)) != 0;  /* True => have sse3 insns */
8342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // ssse3   is ecx:9
8352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // sse41   is ecx:19
8362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // sse42   is ecx:20
8372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // osxsave is ecx:27
8392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // avx     is ecx:28
8402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     // fma     is ecx:12
8412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_avx = False;
8422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* have_fma = False; */
8432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if ( (ecx & ((1<<27)|(1<<28))) == ((1<<27)|(1<<28)) ) {
8445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        /* processor supports AVX instructions and XGETBV is enabled
8455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines           by OS */
8465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        ULong w;
8472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__("movq $0,%%rcx ; "
8482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             ".byte 0x0F,0x01,0xD0 ; " /* xgetbv */
8492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             "movq %%rax,%0"
8502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             :/*OUT*/"=r"(w) :/*IN*/
8512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             :/*TRASH*/"rdx","rcx");
8522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if ((w & 6) == 6) {
8532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           /* OS has enabled both XMM and YMM state support */
8542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           have_avx = True;
8552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           /* have_fma = (ecx & (1<<12)) != 0; */
8562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           /* have_fma: Probably correct, but gcc complains due to
8572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines              unusedness. &*/
8582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        }
8592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
8602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* cmpxchg8b is a minimum requirement now; if we don't have it we
8625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        must simply give up.  But all CPUs since Pentium-I have it, so
8635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        that doesn't seem like much of a restriction. */
8642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
8652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (!have_cx8)
8662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return False;
8672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* on amd64 we tolerate older cpus, which don't have cmpxchg16b */
8692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_cx16 = (ecx & (1<<13)) != 0; /* True => have cmpxchg16b */
8702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Figure out if this CPU can do LZCNT. */
8722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_lzcnt = False;
8732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (max_extended >= 0x80000001) {
8742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx);
8752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */
8762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
8772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* Can we do RDTSCP? */
8795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     have_rdtscp = False;
8805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     if (max_extended >= 0x80000001) {
8812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx);
8822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_rdtscp = (edx & (1<<27)) != 0; /* True => have RDTSVCP */
8832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
8842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Check for BMI1 and AVX2. If we have AVX1 (plus OS support). */
8862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_bmi = False;
8872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_avx2 = False;
8882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_avx && max_basic >= 7) {
8892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        VG_(cpuid)(7, 0, &eax, &ebx, &ecx, &edx);
8902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_bmi = (ebx & (1<<3)) != 0; /* True => have BMI1 */
8912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_avx2 = (ebx & (1<<5)) != 0; /* True => have AVX2 */
8922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
8932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     va         = VexArchAMD64;
8952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vai.hwcaps = (have_sse3   ? VEX_HWCAPS_AMD64_SSE3   : 0)
8962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_cx16   ? VEX_HWCAPS_AMD64_CX16   : 0)
8972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_lzcnt  ? VEX_HWCAPS_AMD64_LZCNT  : 0)
8982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_avx    ? VEX_HWCAPS_AMD64_AVX    : 0)
8992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_bmi    ? VEX_HWCAPS_AMD64_BMI    : 0)
9002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_avx2   ? VEX_HWCAPS_AMD64_AVX2   : 0)
9012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                | (have_rdtscp ? VEX_HWCAPS_AMD64_RDTSCP : 0);
9022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_get_cache_info)(&vai);
9042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     return True;
9062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
9072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_ppc32)
9092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   {
9102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Find out which subset of the ppc32 instruction set is supported by
9112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        verifying whether various ppc32 instructions generate a SIGILL
9122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        or a SIGFPE. An alternative approach is to check the AT_HWCAP and
9132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        AT_PLATFORM entries in the ELF auxiliary table -- see also
9142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        the_iifii.client_auxv in m_main.c.
9152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      */
9162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigset_t          saved_set, tmp_set;
9172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
9182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_toK_t     tmp_sigill_act,   tmp_sigfpe_act;
9192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP;
9212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     volatile Bool have_isa_2_07;
9222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     Int r;
9232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* This is a kludge.  Really we ought to back-convert saved_act
9252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
9262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        since that's a no-op on all ppc32 platforms so far supported,
9272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        it's not worth the typing effort.  At least include most basic
9282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        sanity check: */
9292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
9302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigemptyset)(&tmp_set);
9322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaddset)(&tmp_set, VKI_SIGILL);
9332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
9342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
9362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
9372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
9392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
9402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act = saved_sigill_act;
9412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
9432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
9442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act = saved_sigfpe_act;
9452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* NODEFER: signal handler does not return (from the kernel's point of
9472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        view), hence if it is to successfully catch a signal more than once,
9482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        we need the NODEFER flag. */
9492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
9502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
9512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags |=  VKI_SA_NODEFER;
9522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.ksa_handler = handler_unsup_insn;
9532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
9542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
9552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
9572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
9582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.sa_flags |=  VKI_SA_NODEFER;
9592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
9602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
9612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
9622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* standard FP insns */
9642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_F = True;
9652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
9662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_F = False;
9672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
9682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0xFC000090"); /*fmr 0,0 */
9692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
9702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Altivec insns */
9722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_V = True;
9732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
9742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_V = False;
9752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
9762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        /* Unfortunately some older assemblers don't speak Altivec (or
9772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           choose not to), so to be safe we directly emit the 32-bit
9782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           word corresponding to "vor 0,0,0".  This fixes a build
9792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           problem that happens on Debian 3.1 (ppc32), and probably
9802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           various other places. */
9812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
9822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
9832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* General-Purpose optional (fsqrt, fsqrts) */
9852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_FX = True;
9862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
9872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_FX = False;
9882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
9892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0 */
9902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
9912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
9932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_GX = True;
9942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
9952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_GX = False;
9962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
9974e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov        __asm__ __volatile__(".long 0xFC000034"); /* frsqrte 0,0 */
998745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov     }
9994e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
10004e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     /* VSX support implies Power ISA 2.06 */
10014e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     have_VX = True;
10024e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
10034e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov        have_VX = False;
10044e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     } else {
10054e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov        __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp XT,XB */
10064e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     }
1007a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
10084e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     /* Check for Decimal Floating Point (DFP) support. */
10094e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     have_DFP = True;
10102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
10112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_DFP = False;
10122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
10132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0xee4e8005"); /* dadd  FRT,FRA, FRB */
10142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
10152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Check for ISA 2.07 support. */
10172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_isa_2_07 = True;
10184e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1019a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        have_isa_2_07 = False;
10204e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     } else {
10214e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov        __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */
1022a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     }
10234e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
10244e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     /* determine dcbz/dcbzl sizes while we still have the signal
10254ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov      * handlers registered */
10264ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov     find_ppc_dcbz_sz(&vai);
1027a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
10284e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
10294e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     vg_assert(r == 0);
10304e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov     r = VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
1031745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov     vg_assert(r == 0);
10322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
10332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
10342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d\n",
10352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    (Int)have_F, (Int)have_V, (Int)have_FX,
10362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    (Int)have_GX, (Int)have_VX, (Int)have_DFP,
10372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    (Int)have_isa_2_07);
10382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Make FP a prerequisite for VMX (bogusly so), and for FX and GX. */
10392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_V && !have_F)
10402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_V = False;
10412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_FX && !have_F)
10422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_FX = False;
10432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_GX && !have_F)
10442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_GX = False;
10452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_ppc32_has_FP)  = have_F ? 1 : 0;
10472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_ppc32_has_VMX) = have_V ? 1 : 0;
10482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     va = VexArchPPC32;
10502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vai.hwcaps = 0;
10522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_F)  vai.hwcaps |= VEX_HWCAPS_PPC32_F;
10532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_V)  vai.hwcaps |= VEX_HWCAPS_PPC32_V;
10542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC32_FX;
10552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC32_GX;
10562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC32_VX;
10572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC32_DFP;
10582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA2_07;
10592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_get_cache_info)(&vai);
10612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* But we're not done yet: VG_(machine_ppc32_set_clszB) must be
10632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        called before we're ready to go. */
10642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     return True;
10652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
10662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_ppc64)
10682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   {
10692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Same instruction set detection algorithm as for ppc32. */
10702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigset_t          saved_set, tmp_set;
10712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
10722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_toK_t     tmp_sigill_act,   tmp_sigfpe_act;
10732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP;
10752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     volatile Bool have_isa_2_07;
10762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     Int r;
10772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* This is a kludge.  Really we ought to back-convert saved_act
10792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
10802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        since that's a no-op on all ppc64 platforms so far supported,
10812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        it's not worth the typing effort.  At least include most basic
1082103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        sanity check: */
10832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
1084e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1085e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigemptyset)(&tmp_set);
1086e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaddset)(&tmp_set, VKI_SIGILL);
10872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
10882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1089e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
1090e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     vg_assert(r == 0);
10912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1092e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
1093e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     vg_assert(r == 0);
10942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act = saved_sigill_act;
10952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1096e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
1097e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigfpe_act = saved_sigfpe_act;
10982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1099103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     /* NODEFER: signal handler does not return (from the kernel's point of
1100103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        view), hence if it is to successfully catch a signal more than once,
1101103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        we need the NODEFER flag. */
11022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
11032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
1104103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     tmp_sigill_act.sa_flags |=  VKI_SA_NODEFER;
1105103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     tmp_sigill_act.ksa_handler = handler_unsup_insn;
11062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
1107103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov
1108103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
11092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
11102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigfpe_act.sa_flags |=  VKI_SA_NODEFER;
1111103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
1112103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
1113a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1114a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     /* standard FP insns */
1115a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     have_F = True;
1116a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1117a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        have_F = False;
1118e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
1119103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        __asm__ __volatile__("fmr 0,0");
1120e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     }
1121e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1122103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     /* Altivec insns */
11232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_V = True;
11242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1125e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        have_V = False;
1126e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
1127e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
11285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     }
11295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
11305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* General-Purpose optional (fsqrt, fsqrts) */
1131e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     have_FX = True;
1132e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
11332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_FX = False;
1134e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
1135e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/
11362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
1137e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1138e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
11392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_GX = True;
11402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1141e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        have_GX = False;
1142e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
11435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/
11445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     }
11455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1146e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* VSX support implies Power ISA 2.06 */
1147e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     have_VX = True;
11482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1149e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        have_VX = False;
1150e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
11512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp XT,XB */
1152e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     }
1153e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
11542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Check for Decimal Floating Point (DFP) support. */
11552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_DFP = True;
1156103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1157103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        have_DFP = False;
1158103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     } else {
11595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        __asm__ __volatile__(".long 0xee4e8005"); /* dadd  FRT,FRA, FRB */
11605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     }
11615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1162103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     /* Check for ISA 2.07 support. */
1163103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     have_isa_2_07 = True;
11642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1165103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        have_isa_2_07 = False;
1166103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     } else {
11672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */
1168103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     }
1169103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov
11702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* determine dcbz/dcbzl sizes while we still have the signal
11712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      * handlers registered */
1172103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     find_ppc_dcbz_sz(&vai);
1173103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov
11745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
11755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
11765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
1177103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d\n",
1178103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov                    (Int)have_F, (Int)have_V, (Int)have_FX,
11792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    (Int)have_GX, (Int)have_VX, (Int)have_DFP,
1180103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov                    (Int)have_isa_2_07);
1181103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     /* on ppc64, if we don't even have FP, just give up. */
11822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (!have_F)
1183103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov        return False;
1184103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov
1185a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     VG_(machine_ppc64_has_VMX) = have_V ? 1 : 0;
1186a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1187a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     va = VexArchPPC64;
1188a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1189a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     vai.hwcaps = 0;
1190e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (have_V)  vai.hwcaps |= VEX_HWCAPS_PPC64_V;
1191103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov     if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC64_FX;
1192e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC64_GX;
1193e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC64_VX;
11942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC64_DFP;
11952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA2_07;
11962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
11972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_get_cache_info)(&vai);
11982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
11992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be
12002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        called before we're ready to go. */
12012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     return True;
12022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
12032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_s390x)
12052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  include "libvex_s390x_common.h"
12072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   {
12092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Instruction set detection code borrowed from ppc above. */
12102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigset_t          saved_set, tmp_set;
12112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_fromK_t saved_sigill_act;
12122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vki_sigaction_toK_t     tmp_sigill_act;
12132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     volatile Bool have_LDISP, have_STFLE;
12152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     Int i, r, model;
12162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* If the model is "unknown" don't treat this as an error. Assume
12182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        this is a brand-new machine model for which we don't have the
12192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        identification yet. Keeping fingers crossed. */
12202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     model = VG_(get_machine_model)();
12212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Unblock SIGILL and stash away the old action for that signal */
12232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigemptyset)(&tmp_set);
12242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaddset)(&tmp_set, VKI_SIGILL);
12252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
12272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
12282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
12302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
12312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act = saved_sigill_act;
12322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* NODEFER: signal handler does not return (from the kernel's point of
12342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        view), hence if it is to successfully catch a signal more than once,
12352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        we need the NODEFER flag. */
12362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
12372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
12382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.sa_flags |=  VKI_SA_NODEFER;
12392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     tmp_sigill_act.ksa_handler = handler_unsup_insn;
12402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
12412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Determine hwcaps. Note, we cannot use the stfle insn because it
12435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        is not supported on z900. */
12445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
12455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     have_LDISP = True;
12462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
12472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_LDISP = False;
12482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
12492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines       /* BASR loads the address of the next insn into r1. Needed to avoid
12502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          a segfault in XY. */
12512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        __asm__ __volatile__("basr %%r1,%%r0\n\t"
12522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             ".long  0xe3001000\n\t"  /* XY  0,0(%r1) */
12532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             ".short 0x0057" : : : "r0", "r1", "cc", "memory");
12542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
12552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Check availability og STFLE. If available store facility bits
12572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        in hoststfle. */
12585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     ULong hoststfle[S390_NUM_FACILITY_DW];
12595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
12605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     for (i = 0; i < S390_NUM_FACILITY_DW; ++i)
12612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        hoststfle[i] = 0;
12622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     have_STFLE = True;
12642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
12652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        have_STFLE = False;
12662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } else {
12672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines         register ULong reg0 asm("0") = S390_NUM_FACILITY_DW - 1;
12682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines         __asm__ __volatile__(" .insn s,0xb2b00000,%0\n"   /* stfle */
12702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                              : "=m" (hoststfle), "+d"(reg0)
12712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                              : : "cc", "memory");
12722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
12735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
12745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* Restore signals */
12755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
12762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
12772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
12782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vg_assert(r == 0);
12792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     va = VexArchS390X;
12802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vai.hwcaps = model;
12822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_STFLE) vai.hwcaps |= VEX_HWCAPS_S390X_STFLE;
12832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_LDISP) {
12842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        /* Use long displacement only on machines >= z990. For all other
12852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           machines it is millicoded and therefore slow. */
12862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if (model >= VEX_S390X_MODEL_Z990)
12872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           vai.hwcaps |= VEX_HWCAPS_S390X_LDISP;
12885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     }
12895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
12905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* Detect presence of certain facilities using the STFLE insn.
12912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        Note, that these facilities were introduced at the same time or later
12922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        as STFLE, so the absence of STLFE implies the absence of the facility
12932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        we're trying to detect. */
12942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     struct fac_hwcaps_map {
12952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        UInt installed;
12962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        UInt facility_bit;
12972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        UInt hwcaps_bit;
12982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        const HChar name[6];   // may need adjustment for new facility names
12992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     } fac_hwcaps[] = {
13002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_EIMM,  VEX_HWCAPS_S390X_EIMM,  "EIMM"  },
13012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_GIE,   VEX_HWCAPS_S390X_GIE,   "GIE"   },
13022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_DFP,   VEX_HWCAPS_S390X_DFP,   "DFP"   },
13032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_FPSE,  VEX_HWCAPS_S390X_FGX,   "FGX"   },
13042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_ETF2,  VEX_HWCAPS_S390X_ETF2,  "ETF2"  },
13052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_ETF3,  VEX_HWCAPS_S390X_ETF3,  "ETF3"  },
13062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_STCKF, VEX_HWCAPS_S390X_STCKF, "STCKF" },
13072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_FPEXT, VEX_HWCAPS_S390X_FPEXT, "FPEXT" },
13082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_LSC,   VEX_HWCAPS_S390X_LSC,   "LSC"   },
13092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        { False, S390_FAC_PFPO,  VEX_HWCAPS_S390X_PFPO,  "PFPO"  },
13102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     };
13112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Set hwcaps according to the detected facilities */
13132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) {
13142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        vg_assert(fac_hwcaps[i].facility_bit <= 63);  // for now
13152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if (hoststfle[0] & (1ULL << (63 - fac_hwcaps[i].facility_bit))) {
13162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           fac_hwcaps[i].installed = True;
13172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           vai.hwcaps |= fac_hwcaps[i].hwcaps_bit;
13182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        }
13192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
13202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     /* Build up a string showing the probed-for facilities */
13222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     HChar fac_str[(sizeof fac_hwcaps / sizeof fac_hwcaps[0]) *
13232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                   (sizeof fac_hwcaps[0].name + 3) + //  %s %d
13242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                   7 + 1 + 4 + 2  // machine %4d
13252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                   + 1];  // \0
13262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     HChar *p = fac_str;
13272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     p += VG_(sprintf)(p, "machine %4d  ", model);
13282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) {
13292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        p += VG_(sprintf)(p, " %s %1d", fac_hwcaps[i].name,
13302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                          fac_hwcaps[i].installed);
13312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     }
13322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     *p++ = '\0';
13332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(debugLog)(1, "machine", "%s\n", fac_str);
13352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps);
13362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_get_cache_info)(&vai);
13382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     return True;
13402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
1341e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1342e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#elif defined(VGA_arm)
1343e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov   {
1344e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* Same instruction set detection algorithm as for ppc32. */
13455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     vki_sigset_t          saved_set, tmp_set;
13465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
13475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     vki_sigaction_toK_t     tmp_sigill_act,   tmp_sigfpe_act;
1348e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
13497cdae1683c9c2fcd4473a5862c90c64be3a8c5fdEvgeniy Stepanov     volatile Bool have_VFP, have_VFP2, have_VFP3, have_NEON;
1350e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     volatile Int archlevel;
1351e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     Int r;
1352e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1353e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* This is a kludge.  Really we ought to back-convert saved_act
1354e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
1355e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        since that's a no-op on all ppc64 platforms so far supported,
1356e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        it's not worth the typing effort.  At least include most basic
13575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines        sanity check: */
13585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
13595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1360e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigemptyset)(&tmp_set);
1361e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaddset)(&tmp_set, VKI_SIGILL);
1362e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
1363e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1364e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
1365e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     vg_assert(r == 0);
1366e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1367e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
1368e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     vg_assert(r == 0);
1369e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigill_act = saved_sigill_act;
1370e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1371e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
1372a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     tmp_sigfpe_act = saved_sigfpe_act;
1373a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1374a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     /* NODEFER: signal handler does not return (from the kernel's point of
1375a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        view), hence if it is to successfully catch a signal more than once,
1376e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        we need the NODEFER flag. */
1377e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
1378e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
1379e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigill_act.sa_flags |=  VKI_SA_NODEFER;
1380e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigill_act.ksa_handler = handler_unsup_insn;
1381e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
1382e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1383e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
13845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
13855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     tmp_sigfpe_act.sa_flags |=  VKI_SA_NODEFER;
13865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
1387e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
138839d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov
1389e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* VFP insns */
1390e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     have_VFP = True;
1391e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1392e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        have_VFP = False;
1393e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
1394e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        __asm__ __volatile__(".word 0xEEB02B42"); /* VMOV.F64 d2, d2 */
1395e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     }
139639d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov     /* There are several generation of VFP extension but they differs very
139739d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov        little so for now we will not distinguish them. */
13985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     have_VFP2 = have_VFP;
13995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     have_VFP3 = have_VFP;
14005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1401e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     /* NEON insns */
1402e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     have_NEON = True;
1403e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1404e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        have_NEON = False;
1405e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     } else {
1406e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        __asm__ __volatile__(".word 0xF2244154"); /* VMOV q2, q2 */
1407a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     }
1408a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1409a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     /* ARM architecture level */
1410e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     archlevel = 5; /* v5 will be base level */
1411e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov     if (archlevel < 7) {
1412e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        archlevel = 7;
1413e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov        if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1414a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov           archlevel = 5;
1415906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        } else {
1416a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov           __asm__ __volatile__(".word 0xF45FF000"); /* PLI [PC,#-0] */
1417a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov        }
1418906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov     }
1419906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov     if (archlevel < 6) {
1420906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        archlevel = 6;
1421a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov        if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1422a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov           archlevel = 5;
1423a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov        } else {
1424a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov           __asm__ __volatile__(".word 0xE6822012"); /* PKHBT r2, r2, r2 */
1425a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov        }
1426a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     }
1427a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
14283fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act);
14293fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(convert_sigaction_fromK_to_toK)(&saved_sigfpe_act, &tmp_sigfpe_act);
14302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
14312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
14323fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
14333fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14343fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(debugLog)(1, "machine", "ARMv%d VFP %d VFP2 %d VFP3 %d NEON %d\n",
14352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           archlevel, (Int)have_VFP, (Int)have_VFP2, (Int)have_VFP3,
14362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines           (Int)have_NEON);
14373fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14383fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(machine_arm_archlevel) = archlevel;
14393fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     va = VexArchARM;
14412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     vai.hwcaps = VEX_ARM_ARCHLEVEL(archlevel);
14433fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     if (have_VFP3) vai.hwcaps |= VEX_HWCAPS_ARM_VFP3;
14443fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     if (have_VFP2) vai.hwcaps |= VEX_HWCAPS_ARM_VFP2;
14453fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     if (have_VFP)  vai.hwcaps |= VEX_HWCAPS_ARM_VFP;
14462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     if (have_NEON) vai.hwcaps |= VEX_HWCAPS_ARM_NEON;
14472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     VG_(machine_get_cache_info)(&vai);
14493fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14503fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     return True;
14513fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov   }
14522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined(VGA_arm64)
14542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   {
14553fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     va = VexArchARM64;
14563fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
1457a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     /* So far there are no variants. */
1458a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     vai.hwcaps = 0;
1459906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov
1460a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     VG_(machine_get_cache_info)(&vai);
1461a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1462a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     /* 0 denotes 'not set'.  The range of legitimate values here,
1463a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov        after being set that is, is 2 though 17 inclusive. */
1464a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     vg_assert(vai.arm64_dMinLine_lg2_szB == 0);
1465a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     vg_assert(vai.arm64_iMinLine_lg2_szB == 0);
14663fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     ULong ctr_el0;
14673fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     __asm__ __volatile__("mrs %0, ctr_el0" : "=r"(ctr_el0));
14683fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     vai.arm64_dMinLine_lg2_szB = ((ctr_el0 >> 16) & 0xF) + 2;
14693fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     vai.arm64_iMinLine_lg2_szB = ((ctr_el0 >>  0) & 0xF) + 2;
14703fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     VG_(debugLog)(1, "machine", "ARM64: ctr_el0.dMinLine_szB = %d, "
14713fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov                      "ctr_el0.iMinLine_szB = %d\n",
14723fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov                   1 << vai.arm64_dMinLine_lg2_szB,
14733fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov                   1 << vai.arm64_iMinLine_lg2_szB);
1474a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
14753fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     return True;
14763fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov   }
14773fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14783fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov#elif defined(VGA_mips32)
14793fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov   {
14803fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     /* Define the position of F64 bit in FIR register. */
14813fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov#    define FP64 22
14823fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov     va = VexArchMIPS32;
1483906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov     UInt model = VG_(get_machine_model)();
1484a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     if (model == -1)
1485a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov         return False;
1486a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1487a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     vai.hwcaps = model;
1488a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1489906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov     /* Same instruction set detection algorithm as for ppc32/arm... */
1490a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     vki_sigset_t          saved_set, tmp_set;
1491a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     vki_sigaction_fromK_t saved_sigill_act;
1492a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     vki_sigaction_toK_t   tmp_sigill_act;
1493a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1494a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     volatile Bool have_DSP, have_DSPr2;
1495a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     Int r;
149657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov
149757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
149857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov
149957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     VG_(sigemptyset)(&tmp_set);
150057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     VG_(sigaddset)(&tmp_set, VKI_SIGILL);
150157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov
150257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
150357876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     vg_assert(r == 0);
1504a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
150557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
150657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     vg_assert(r == 0);
150757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     tmp_sigill_act = saved_sigill_act;
150857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov
150957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     /* NODEFER: signal handler does not return (from the kernel's point of
151057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov        view), hence if it is to successfully catch a signal more than once,
151157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov        we need the NODEFER flag. */
151257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov     tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
1513906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov     tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
1514a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     tmp_sigill_act.sa_flags |=  VKI_SA_NODEFER;
1515a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov     tmp_sigill_act.ksa_handler = handler_unsup_insn;
1516a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
1517a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1518a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov     if (model == VEX_PRID_COMP_MIPS) {
1519906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        /* DSPr2 instructions. */
1520a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov        have_DSPr2 = True;
1521906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1522a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov           have_DSPr2 = False;
1523897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        } else {
15246a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko           __asm__ __volatile__(".word 0x7d095351"); /* precr.qb.ph t2, t0, t1 */
15256a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko        }
15266a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko        if (have_DSPr2) {
15276a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko           /* We assume it's 74K, since it can run DSPr2. */
1528897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov           vai.hwcaps |= VEX_PRID_IMP_74K;
1529897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        } else {
15305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines           /* DSP instructions. */
15315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines           have_DSP = True;
15325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines           if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
1533897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov              have_DSP = False;
1534f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov           } else {
1535897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov              __asm__ __volatile__(".word 0x7c3f44b8"); /* rddsp t0, 0x3f */
1536897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov           }
1537897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov           if (have_DSP) {
153830e970f769ccf11e61e472c6f8b22f8e866c592fKostya Serebryany              /* We assume it's 34K, since it has support for DSP. */
1539a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov              vai.hwcaps |= VEX_PRID_IMP_34K;
1540897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov           }
1541897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        }
15425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     }
15435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
15445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     /* Check if CPU has FPU and 32 dbl. prec. FP registers */
1545897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     int FIR = 0;
1546f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov     __asm__ __volatile__(
1547897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        "cfc1 %0, $0"  "\n\t"
1548897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        : "=r" (FIR)
1549897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     );
15506a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko     if (FIR & (1 << FP64)) {
1551897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov        vai.hwcaps |= VEX_PRID_CPU_32FPR;
1552897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     }
15535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
15545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act);
15555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
1556897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
1557f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov
1558897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps);
1559897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     VG_(machine_get_cache_info)(&vai);
1560897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
1561897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     return True;
1562897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   }
1563897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
15645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#elif defined(VGA_mips64)
15655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   {
15665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines     va = VexArchMIPS64;
1567897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     UInt model = VG_(get_machine_model)();
1568897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     if (model== -1)
1569a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov         return False;
1570a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1571897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     vai.hwcaps = model;
1572897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
1573897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov     VG_(machine_get_cache_info)(&vai);
15742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
15752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     return True;
15762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   }
15772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
15785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
15795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  error "Unknown arch"
15805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
15812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
15822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
15832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/* Notify host cpu instruction cache line size. */
15842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined(VGA_ppc32)
15852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid VG_(machine_ppc32_set_clszB)( Int szB )
15862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines{
15872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   vg_assert(hwcaps_done);
15882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
15892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   /* Either the value must not have been set yet (zero) or we can
1590897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      tolerate it being set to the same value multiple times, as the
1591897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      stack scanning logic in m_main is a bit stupid. */
1592897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   vg_assert(vai.ppc_icache_line_szB == 0
15935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines             || vai.ppc_icache_line_szB == szB);
15945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
15955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   vg_assert(szB == 16 || szB == 32 || szB == 64 || szB == 128);
1596897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   vai.ppc_icache_line_szB = szB;
1597897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
1598a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif
1599a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1600897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
1601897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov/* Notify host cpu instruction cache line size. */
1602897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#if defined(VGA_ppc64)
16032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid VG_(machine_ppc64_set_clszB)( Int szB )
16042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines{
1605a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   vg_assert(hwcaps_done);
1606a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1607a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   /* Either the value must not have been set yet (zero) or we can
1608a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      tolerate it being set to the same value multiple times, as the
16092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      stack scanning logic in m_main is a bit stupid. */
1610897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   vg_assert(vai.ppc_icache_line_szB == 0
1611897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov             || vai.ppc_icache_line_szB == szB);
16122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1613897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   vg_assert(szB == 16 || szB == 32 || szB == 64 || szB == 128);
1614897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   vai.ppc_icache_line_szB = szB;
16159530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
16169530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
16179530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
16189530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
16199530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov/* Notify host's ability to handle NEON instructions. */
16209530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#if defined(VGA_arm)
16219530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanovvoid VG_(machine_arm_set_has_NEON)( Bool has_neon )
16225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines{
16235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   vg_assert(hwcaps_done);
16245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   /* There's nothing else we can sanity check. */
16259530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
1626a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   if (has_neon) {
16279530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov      vai.hwcaps |= VEX_HWCAPS_ARM_NEON;
16289530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   } else {
16299530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov      vai.hwcaps &= ~VEX_HWCAPS_ARM_NEON;
16309530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   }
16319530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
16329530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
16335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
16345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
16355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines/* Fetch host cpu info, once established. */
16369530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanovvoid VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa,
16379530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov                                   /*OUT*/VexArchInfo* pVai )
16389530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov{
16399530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   vg_assert(hwcaps_done);
16409530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   if (pVa)  *pVa  = va;
16419530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   if (pVai) *pVai = vai;
16429530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
1643a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1644a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1645a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov/* Returns the size of the largest guest register that we will
16469530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   simulate in this run.  This depends on both the guest architecture
16479530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   and on the specific capabilities we are simulating for that guest
16489530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   (eg, AVX or non-AVX ?, for amd64).  Should return either 4, 8, 16
16499530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov   or 32.  General rule: if in doubt, return a value larger than
16509d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   reality.
16519d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov
16529d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   This information is needed by Cachegrind and Callgrind to decide
16539d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   what the minimum cache line size they are prepared to simulate is.
16549d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   Basically require that the minimum cache line size is at least as
16555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   large as the largest register that might get transferred to/from
16565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   memory, so as to guarantee that any such transaction can straddle
16575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   at most 2 cache lines.
16589d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov*/
16599d60087654f89e3452841350d9eca97644edca9dEvgeniy StepanovInt VG_(machine_get_size_of_largest_guest_register) ( void )
16609d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov{
16619d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   vg_assert(hwcaps_done);
16629d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   /* Once hwcaps_done is True, we can fish around inside va/vai to
16639d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov      find the information we need. */
16649d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov
1665a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#  if defined(VGA_x86)
16669d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   vg_assert(va == VexArchX86);
16679d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov   /* We don't support AVX, so 32 is out.  At the other end, even if
16689d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov      we don't support any SSE, the X87 can generate 10 byte
16699d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov      transfers, so let's say 16 to be on the safe side.  Hence the
167056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov      answer is always 16. */
167156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   return 16;
167256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov
167356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#  elif defined(VGA_amd64)
16745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   /* if AVX then 32 else 16 */
16755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   return (vai.hwcaps & VEX_HWCAPS_AMD64_AVX) ? 32 : 16;
16765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
167756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#  elif defined(VGA_ppc32)
167856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   /* 8 if boring; 16 if signs of Altivec or other exotic stuff */
167956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC32_V) return 16;
168056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC32_VX) return 16;
168156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC32_DFP) return 16;
168256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   return 8;
168356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov
1684a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#  elif defined(VGA_ppc64)
1685a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov   /* 8 if boring; 16 if signs of Altivec or other exotic stuff */
168656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC64_V) return 16;
168756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC64_VX) return 16;
168856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov   if (vai.hwcaps & VEX_HWCAPS_PPC64_DFP) return 16;
1689897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov   return 8;
1690447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1691447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  elif defined(VGA_s390x)
1692447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov   return 8;
1693447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1694447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  elif defined(VGA_arm)
1695447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov   /* Really it depends whether or not we have NEON, but let's just
1696447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      assume we always do. */
1697447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov   return 16;
1698447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1699447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  elif defined(VGA_arm64)
1700447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov   /* ARM64 always has Neon, AFAICS. */
17015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines   return 16;
17025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
17035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  elif defined(VGA_mips32)
1704447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov   /* The guest state implies 4, but that can't really be true, can
17053538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov      it? */
17063538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov   return 8;
1707447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1708447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  elif defined(VGA_mips64)
17093538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov   return 8;
1710447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1711512c616cacf70ca029a2bf719a482b902f3687cdEvgeniy Stepanov#  else
1712447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#    error "Unknown arch"
1713447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  endif
1714447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
1715447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1716447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
1717447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// Given a pointer to a function as obtained by "& functionname" in C,
1718447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// produce a pointer to the actual entry point for the function.
1719447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovvoid* VG_(fnptr_to_fnentry)( void* f )
1720a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov{
1721447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#  if defined(VGP_x86_linux) || defined(VGP_amd64_linux)  \
1722447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      || defined(VGP_arm_linux)                           \
1723447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      || defined(VGP_ppc32_linux) || defined(VGO_darwin)  \
1724447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \
17259eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
17269eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov   return f;
17279eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#  elif defined(VGP_ppc64_linux)
17289eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov   /* ppc64-linux uses the AIX scheme, in which f is a pointer to a
17299eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      3-word function descriptor, of which the first word is the entry
17309eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      address. */
17319eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov   UWord* descr = (UWord*)f;
17329eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov   return (void*)(descr[0]);
17335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  else
17345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#    error "Unknown platform"
17355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  endif
17369eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov}
17379eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov
17389eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov/*--------------------------------------------------------------------*/
17399eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov/*--- end                                                          ---*/
17409eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov/*--------------------------------------------------------------------*/
17419eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov