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