1f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--------------------------------------------------------------------*/ 2f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--- Machine-related stuff. m_machine.c ---*/ 3f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--------------------------------------------------------------------*/ 4f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 5f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/* 6f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn This file is part of Valgrind, a dynamic binary instrumentation 7f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn framework. 8f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 9ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2000-2017 Julian Seward 10f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn jseward@acm.org 11f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 12f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn This program is free software; you can redistribute it and/or 13f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn modify it under the terms of the GNU General Public License as 14f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn published by the Free Software Foundation; either version 2 of the 15f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn License, or (at your option) any later version. 16f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 17f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn This program is distributed in the hope that it will be useful, but 18f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn WITHOUT ANY WARRANTY; without even the implied warranty of 19f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn General Public License for more details. 21f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 22f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn You should have received a copy of the GNU General Public License 23f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn along with this program; if not, write to the Free Software 24f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 25f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 02111-1307, USA. 26f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 27f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn The GNU General Public License is contained in the file COPYING. 28f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn*/ 29f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 30c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 314cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 32c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_threadstate.h" 33f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn#include "pub_core_libcassert.h" 34f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn#include "pub_core_libcbase.h" 352c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj#include "pub_core_libcfile.h" 36df14eeae2e6abcd70a35e78321066107bf926227florian#include "pub_core_libcprint.h" 37ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#include "pub_core_libcproc.h" 382c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj#include "pub_core_mallocfree.h" 39f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn#include "pub_core_machine.h" 40e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#include "pub_core_cpuid.h" 411581e745b8991508ef5243fd2d168790caf578e1bart#include "pub_core_libcsignal.h" // for ppc32 messing with SIGILL and SIGFPE 423b0cae743ec228d9f1c2787b303282363c183dc7sewardj#include "pub_core_debuglog.h" 43e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 44f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 45af839f52d74df156d655201a889954133ab01be7njn#define INSTR_PTR(regs) ((regs).vex.VG_INSTR_PTR) 46af839f52d74df156d655201a889954133ab01be7njn#define STACK_PTR(regs) ((regs).vex.VG_STACK_PTR) 47af839f52d74df156d655201a889954133ab01be7njn#define FRAME_PTR(regs) ((regs).vex.VG_FRAME_PTR) 48f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 491dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjAddr VG_(get_IP) ( ThreadId tid ) { 50f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn return INSTR_PTR( VG_(threads)[tid].arch ); 51f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn} 521dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjAddr VG_(get_SP) ( ThreadId tid ) { 531dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj return STACK_PTR( VG_(threads)[tid].arch ); 541dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj} 551dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjAddr VG_(get_FP) ( ThreadId tid ) { 56f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn return FRAME_PTR( VG_(threads)[tid].arch ); 57f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn} 58f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 591dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjvoid VG_(set_IP) ( ThreadId tid, Addr ip ) { 601dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj INSTR_PTR( VG_(threads)[tid].arch ) = ip; 61acaec5fd0a53ebd20fded3651169085bc7e90e78sewardj} 621dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjvoid VG_(set_SP) ( ThreadId tid, Addr sp ) { 63f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn STACK_PTR( VG_(threads)[tid].arch ) = sp; 64f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn} 65f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 6659570ffbe31930ab4d678754daaeec0715117a3dsewardjvoid VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, 6759570ffbe31930ab4d678754daaeec0715117a3dsewardj ThreadId tid ) 6859570ffbe31930ab4d678754daaeec0715117a3dsewardj{ 6959570ffbe31930ab4d678754daaeec0715117a3dsewardj# if defined(VGA_x86) 7059570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_EIP; 7159570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_ESP; 7259570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.X86.r_ebp 7359570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_EBP; 7459570ffbe31930ab4d678754daaeec0715117a3dsewardj# elif defined(VGA_amd64) 7559570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_pc = VG_(threads)[tid].arch.vex.guest_RIP; 7659570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_sp = VG_(threads)[tid].arch.vex.guest_RSP; 7759570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.AMD64.r_rbp 7859570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_RBP; 7959570ffbe31930ab4d678754daaeec0715117a3dsewardj# elif defined(VGA_ppc32) 8059570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_CIA; 81f5f1e12bd89408917c1ffeb22ec23a1fd11b7a23sewardj regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_GPR1; 8259570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.PPC32.r_lr 8359570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_LR; 84cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc64be) || defined(VGA_ppc64le) 8559570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_pc = VG_(threads)[tid].arch.vex.guest_CIA; 86f5f1e12bd89408917c1ffeb22ec23a1fd11b7a23sewardj regs->r_sp = VG_(threads)[tid].arch.vex.guest_GPR1; 8759570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.PPC64.r_lr 8859570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_LR; 8959570ffbe31930ab4d678754daaeec0715117a3dsewardj# elif defined(VGA_arm) 901dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_R15T; 9159570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R13; 9259570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.ARM.r14 9359570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_R14; 9459570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.ARM.r12 9559570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_R12; 9659570ffbe31930ab4d678754daaeec0715117a3dsewardj regs->misc.ARM.r11 9759570ffbe31930ab4d678754daaeec0715117a3dsewardj = VG_(threads)[tid].arch.vex.guest_R11; 98fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj regs->misc.ARM.r7 99fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj = VG_(threads)[tid].arch.vex.guest_R7; 100f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGA_arm64) 101f0c1250e324f6684757c6a15545366447ef1d64fsewardj regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC; 1020345188cc1524a809b8d7fe8785e1da098d9cbe4sewardj regs->r_sp = VG_(threads)[tid].arch.vex.guest_XSP; 103f0c1250e324f6684757c6a15545366447ef1d64fsewardj regs->misc.ARM64.x29 = VG_(threads)[tid].arch.vex.guest_X29; 104f0c1250e324f6684757c6a15545366447ef1d64fsewardj regs->misc.ARM64.x30 = VG_(threads)[tid].arch.vex.guest_X30; 105b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 106b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_IA; 107b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_SP; 108b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj regs->misc.S390X.r_fp 1091672a24fcc4362bf79b9ba994f8726aabf9641bdflorian = VG_(threads)[tid].arch.vex.guest_FP; 110b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj regs->misc.S390X.r_lr 1111672a24fcc4362bf79b9ba994f8726aabf9641bdflorian = VG_(threads)[tid].arch.vex.guest_LR; 1125db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 1135db15403e889d4db339b342bc2a824ef0bfaa654sewardj regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC; 1145db15403e889d4db339b342bc2a824ef0bfaa654sewardj regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29; 1155db15403e889d4db339b342bc2a824ef0bfaa654sewardj regs->misc.MIPS32.r30 1165db15403e889d4db339b342bc2a824ef0bfaa654sewardj = VG_(threads)[tid].arch.vex.guest_r30; 1175db15403e889d4db339b342bc2a824ef0bfaa654sewardj regs->misc.MIPS32.r31 1185db15403e889d4db339b342bc2a824ef0bfaa654sewardj = VG_(threads)[tid].arch.vex.guest_r31; 1195db15403e889d4db339b342bc2a824ef0bfaa654sewardj regs->misc.MIPS32.r28 1205db15403e889d4db339b342bc2a824ef0bfaa654sewardj = VG_(threads)[tid].arch.vex.guest_r28; 1214df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips64) 1224df0bfc0614379192c780c944415dc420d9cfe8epetarj regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC; 1234df0bfc0614379192c780c944415dc420d9cfe8epetarj regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29; 1244df0bfc0614379192c780c944415dc420d9cfe8epetarj regs->misc.MIPS64.r30 1254df0bfc0614379192c780c944415dc420d9cfe8epetarj = VG_(threads)[tid].arch.vex.guest_r30; 1264df0bfc0614379192c780c944415dc420d9cfe8epetarj regs->misc.MIPS64.r31 1274df0bfc0614379192c780c944415dc420d9cfe8epetarj = VG_(threads)[tid].arch.vex.guest_r31; 1284df0bfc0614379192c780c944415dc420d9cfe8epetarj regs->misc.MIPS64.r28 1294df0bfc0614379192c780c944415dc420d9cfe8epetarj = VG_(threads)[tid].arch.vex.guest_r28; 13059570ffbe31930ab4d678754daaeec0715117a3dsewardj# else 13159570ffbe31930ab4d678754daaeec0715117a3dsewardj# error "Unknown arch" 13259570ffbe31930ab4d678754daaeec0715117a3dsewardj# endif 13359570ffbe31930ab4d678754daaeec0715117a3dsewardj} 13459570ffbe31930ab4d678754daaeec0715117a3dsewardj 1357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid 1367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjVG_(get_shadow_regs_area) ( ThreadId tid, 1377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /*DST*/UChar* dst, 138c4431bfe04c7490ea2d74939d222d87f13f30960njn /*SRC*/Int shadowNo, PtrdiffT offset, SizeT size ) 139f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn{ 1407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void* src; 141f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn ThreadState* tst; 1429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2); 143f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(VG_(is_valid_tid)(tid)); 144f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn // Bounds check 145f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(0 <= offset && offset < sizeof(VexGuestArchState)); 146f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(offset + size <= sizeof(VexGuestArchState)); 1477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj // Copy 1487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tst = & VG_(threads)[tid]; 1499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj src = NULL; 1509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj switch (shadowNo) { 1519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 0: src = (void*)(((Addr)&(tst->arch.vex)) + offset); break; 1529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 1: src = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break; 1539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 2: src = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break; 1549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 155e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(src != NULL); 1567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memcpy)( dst, src, size); 157f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn} 158f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 1597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid 1607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjVG_(set_shadow_regs_area) ( ThreadId tid, 161c4431bfe04c7490ea2d74939d222d87f13f30960njn /*DST*/Int shadowNo, PtrdiffT offset, SizeT size, 1627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /*SRC*/const UChar* src ) 163f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn{ 1647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void* dst; 165f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn ThreadState* tst; 1669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2); 167f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(VG_(is_valid_tid)(tid)); 168f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn // Bounds check 169f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(0 <= offset && offset < sizeof(VexGuestArchState)); 170f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn vg_assert(offset + size <= sizeof(VexGuestArchState)); 1717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj // Copy 1727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tst = & VG_(threads)[tid]; 1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dst = NULL; 1749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj switch (shadowNo) { 1759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 0: dst = (void*)(((Addr)&(tst->arch.vex)) + offset); break; 1769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 1: dst = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break; 1779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj case 2: dst = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break; 1789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 179e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(dst != NULL); 1807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memcpy)( dst, src, size); 181f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn} 182f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 183f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn 1846bd9dc18c043927c1196caba20a327238a179c42florianstatic void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId, 1856bd9dc18c043927c1196caba20a327238a179c42florian const HChar*, Addr)) 1866ace3ea69b3f004df3f06c78cf13aa514aaa7460njn{ 187a22f59db02284784a1e5e51587e2ce09db3a2a18philippe VexGuestArchState* vex = &(VG_(get_ThreadState)(tid)->arch.vex); 188a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(debugLog)(2, "machine", "apply_to_GPs_of_tid %u\n", tid); 1896ace3ea69b3f004df3f06c78cf13aa514aaa7460njn#if defined(VGA_x86) 190a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "EAX", vex->guest_EAX); 191a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "ECX", vex->guest_ECX); 192a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "EDX", vex->guest_EDX); 193a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "EBX", vex->guest_EBX); 194a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "ESI", vex->guest_ESI); 195a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "EDI", vex->guest_EDI); 196a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "ESP", vex->guest_ESP); 197a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "EBP", vex->guest_EBP); 1986ace3ea69b3f004df3f06c78cf13aa514aaa7460njn#elif defined(VGA_amd64) 199a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RAX", vex->guest_RAX); 200a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RCX", vex->guest_RCX); 201a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RDX", vex->guest_RDX); 202a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RBX", vex->guest_RBX); 203a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RSI", vex->guest_RSI); 204a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RDI", vex->guest_RDI); 205a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RSP", vex->guest_RSP); 206a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "RBP", vex->guest_RBP); 207a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R8" , vex->guest_R8 ); 208a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R9" , vex->guest_R9 ); 209a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R10", vex->guest_R10); 210a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R11", vex->guest_R11); 211a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R12", vex->guest_R12); 212a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R13", vex->guest_R13); 213a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R14", vex->guest_R14); 214a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R15", vex->guest_R15); 215cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 216a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR0" , vex->guest_GPR0 ); 217a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR1" , vex->guest_GPR1 ); 218a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR2" , vex->guest_GPR2 ); 219a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR3" , vex->guest_GPR3 ); 220a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR4" , vex->guest_GPR4 ); 221a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR5" , vex->guest_GPR5 ); 222a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR6" , vex->guest_GPR6 ); 223a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR7" , vex->guest_GPR7 ); 224a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR8" , vex->guest_GPR8 ); 225a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR9" , vex->guest_GPR9 ); 226a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR10", vex->guest_GPR10); 227a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR11", vex->guest_GPR11); 228a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR12", vex->guest_GPR12); 229a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR13", vex->guest_GPR13); 230a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR14", vex->guest_GPR14); 231a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR15", vex->guest_GPR15); 232a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR16", vex->guest_GPR16); 233a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR17", vex->guest_GPR17); 234a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR18", vex->guest_GPR18); 235a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR19", vex->guest_GPR19); 236a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR20", vex->guest_GPR20); 237a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR21", vex->guest_GPR21); 238a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR22", vex->guest_GPR22); 239a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR23", vex->guest_GPR23); 240a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR24", vex->guest_GPR24); 241a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR25", vex->guest_GPR25); 242a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR26", vex->guest_GPR26); 243a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR27", vex->guest_GPR27); 244a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR28", vex->guest_GPR28); 245a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR29", vex->guest_GPR29); 246a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR30", vex->guest_GPR30); 247a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "GPR31", vex->guest_GPR31); 248a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "CTR" , vex->guest_CTR ); 249a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "LR" , vex->guest_LR ); 25059570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(VGA_arm) 251a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R0" , vex->guest_R0 ); 252a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R1" , vex->guest_R1 ); 253a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R2" , vex->guest_R2 ); 254a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R3" , vex->guest_R3 ); 255a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R4" , vex->guest_R4 ); 256a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R5" , vex->guest_R5 ); 257a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R6" , vex->guest_R6 ); 258a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R8" , vex->guest_R8 ); 259a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R9" , vex->guest_R9 ); 260a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R10", vex->guest_R10); 261a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R11", vex->guest_R11); 262a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R12", vex->guest_R12); 263a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R13", vex->guest_R13); 264a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "R14", vex->guest_R14); 265b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 266a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r0" , vex->guest_r0 ); 267a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r1" , vex->guest_r1 ); 268a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r2" , vex->guest_r2 ); 269a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r3" , vex->guest_r3 ); 270a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r4" , vex->guest_r4 ); 271a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r5" , vex->guest_r5 ); 272a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r6" , vex->guest_r6 ); 273a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r7" , vex->guest_r7 ); 274a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r8" , vex->guest_r8 ); 275a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r9" , vex->guest_r9 ); 276a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r10", vex->guest_r10); 277a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r11", vex->guest_r11); 278a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r12", vex->guest_r12); 279a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r13", vex->guest_r13); 280a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r14", vex->guest_r14); 281a22f59db02284784a1e5e51587e2ce09db3a2a18philippe (*f)(tid, "r15", vex->guest_r15); 2824df0bfc0614379192c780c944415dc420d9cfe8epetarj#elif defined(VGA_mips32) || defined(VGA_mips64) 2835db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r0" , vex->guest_r0 ); 2845db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r1" , vex->guest_r1 ); 2855db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r2" , vex->guest_r2 ); 2865db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r3" , vex->guest_r3 ); 2875db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r4" , vex->guest_r4 ); 2885db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r5" , vex->guest_r5 ); 2895db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r6" , vex->guest_r6 ); 2905db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r7" , vex->guest_r7 ); 2915db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r8" , vex->guest_r8 ); 2925db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r9" , vex->guest_r9 ); 2935db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r10", vex->guest_r10); 2945db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r11", vex->guest_r11); 2955db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r12", vex->guest_r12); 2965db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r13", vex->guest_r13); 2975db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r14", vex->guest_r14); 2985db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r15", vex->guest_r15); 2995db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r16", vex->guest_r16); 3005db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r17", vex->guest_r17); 3015db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r18", vex->guest_r18); 3025db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r19", vex->guest_r19); 3035db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r20", vex->guest_r20); 3045db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r21", vex->guest_r21); 3055db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r22", vex->guest_r22); 3065db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r23", vex->guest_r23); 3075db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r24", vex->guest_r24); 3085db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r25", vex->guest_r25); 3095db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r26", vex->guest_r26); 3105db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r27", vex->guest_r27); 3115db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r28", vex->guest_r28); 3125db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r29", vex->guest_r29); 3135db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r30", vex->guest_r30); 3145db15403e889d4db339b342bc2a824ef0bfaa654sewardj (*f)(tid, "r31", vex->guest_r31); 315f0c1250e324f6684757c6a15545366447ef1d64fsewardj#elif defined(VGA_arm64) 316b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x0" , vex->guest_X0 ); 317b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x1" , vex->guest_X1 ); 318b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x2" , vex->guest_X2 ); 319b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x3" , vex->guest_X3 ); 320b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x4" , vex->guest_X4 ); 321b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x5" , vex->guest_X5 ); 322b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x6" , vex->guest_X6 ); 323b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x7" , vex->guest_X7 ); 324b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x8" , vex->guest_X8 ); 325b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x9" , vex->guest_X9 ); 326b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x10", vex->guest_X10); 327b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x11", vex->guest_X11); 328b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x12", vex->guest_X12); 329b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x13", vex->guest_X13); 330b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x14", vex->guest_X14); 331b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x15", vex->guest_X15); 332b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x16", vex->guest_X16); 333b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x17", vex->guest_X17); 334b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x18", vex->guest_X18); 335b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x19", vex->guest_X19); 336b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x20", vex->guest_X20); 337b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x21", vex->guest_X21); 338b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x22", vex->guest_X22); 339b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x23", vex->guest_X23); 340b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x24", vex->guest_X24); 341b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x25", vex->guest_X25); 342b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x26", vex->guest_X26); 343b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x27", vex->guest_X27); 344b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x28", vex->guest_X28); 345b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x29", vex->guest_X29); 346b8afd6f2a9ba5a9e7d4f1484a905f9a42d464962philippe (*f)(tid, "x30", vex->guest_X30); 3476ace3ea69b3f004df3f06c78cf13aa514aaa7460njn#else 3486ace3ea69b3f004df3f06c78cf13aa514aaa7460njn# error Unknown arch 3496ace3ea69b3f004df3f06c78cf13aa514aaa7460njn#endif 3506ace3ea69b3f004df3f06c78cf13aa514aaa7460njn} 3516ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 3526ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 3536bd9dc18c043927c1196caba20a327238a179c42florianvoid VG_(apply_to_GP_regs)(void (*f)(ThreadId, const HChar*, UWord)) 3546ace3ea69b3f004df3f06c78cf13aa514aaa7460njn{ 3556ace3ea69b3f004df3f06c78cf13aa514aaa7460njn ThreadId tid; 3566ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 3576ace3ea69b3f004df3f06c78cf13aa514aaa7460njn for (tid = 1; tid < VG_N_THREADS; tid++) { 358b8ba0310d94b421f6522f1a816f85653e795f5d8philippe if (VG_(is_valid_tid)(tid) 359b8ba0310d94b421f6522f1a816f85653e795f5d8philippe || VG_(threads)[tid].exitreason == VgSrc_ExitProcess) { 360b8ba0310d94b421f6522f1a816f85653e795f5d8philippe // live thread or thread instructed to die by another thread that 361b8ba0310d94b421f6522f1a816f85653e795f5d8philippe // called exit. 362a22f59db02284784a1e5e51587e2ce09db3a2a18philippe apply_to_GPs_of_tid(tid, f); 3636ace3ea69b3f004df3f06c78cf13aa514aaa7460njn } 3646ace3ea69b3f004df3f06c78cf13aa514aaa7460njn } 3656ace3ea69b3f004df3f06c78cf13aa514aaa7460njn} 3666ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid VG_(thread_stack_reset_iter)(/*OUT*/ThreadId* tid) 3681d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn{ 369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *tid = (ThreadId)(-1); 3701d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn} 3716ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(thread_stack_next)(/*MOD*/ThreadId* tid, 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Addr* stack_min, 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Addr* stack_max) 3751d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn{ 3761d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn ThreadId i; 377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = (*tid)+1; i < VG_N_THREADS; i++) { 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (i == VG_INVALID_THREADID) 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3801d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn if (VG_(threads)[i].status != VgTs_Empty) { 3811d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn *tid = i; 3821d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn *stack_min = VG_(get_SP)(i); 38338a74d2cc4670e3eb559adff51a376cd6ec98005philippe *stack_max = VG_(threads)[i].client_stack_highest_byte; 3841d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn return True; 3851d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn } 386b506bd863e6cab5aea7cc4bea2ac3bc19a781b56njn } 3871d0cb0d000768c01536d61cbb0a2d6e8a9af52ebnjn return False; 388b506bd863e6cab5aea7cc4bea2ac3bc19a781b56njn} 3896ace3ea69b3f004df3f06c78cf13aa514aaa7460njn 390bbec7728efefaa650970dd1f0282b77040287133sewardjAddr VG_(thread_get_stack_max)(ThreadId tid) 391bbec7728efefaa650970dd1f0282b77040287133sewardj{ 392bbec7728efefaa650970dd1f0282b77040287133sewardj vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID); 393bbec7728efefaa650970dd1f0282b77040287133sewardj vg_assert(VG_(threads)[tid].status != VgTs_Empty); 39438a74d2cc4670e3eb559adff51a376cd6ec98005philippe return VG_(threads)[tid].client_stack_highest_byte; 395bbec7728efefaa650970dd1f0282b77040287133sewardj} 396bbec7728efefaa650970dd1f0282b77040287133sewardj 3970fb03204ca433b7d81053a68bbdca11ee6c5fec6bartSizeT VG_(thread_get_stack_size)(ThreadId tid) 3980fb03204ca433b7d81053a68bbdca11ee6c5fec6bart{ 3990fb03204ca433b7d81053a68bbdca11ee6c5fec6bart vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID); 4000fb03204ca433b7d81053a68bbdca11ee6c5fec6bart vg_assert(VG_(threads)[tid].status != VgTs_Empty); 4010fb03204ca433b7d81053a68bbdca11ee6c5fec6bart return VG_(threads)[tid].client_stack_szB; 4020fb03204ca433b7d81053a68bbdca11ee6c5fec6bart} 4030fb03204ca433b7d81053a68bbdca11ee6c5fec6bart 40483c5a921adba406a2bad193d59e22bc77522085fbartAddr VG_(thread_get_altstack_min)(ThreadId tid) 40583c5a921adba406a2bad193d59e22bc77522085fbart{ 40683c5a921adba406a2bad193d59e22bc77522085fbart vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID); 40783c5a921adba406a2bad193d59e22bc77522085fbart vg_assert(VG_(threads)[tid].status != VgTs_Empty); 40883c5a921adba406a2bad193d59e22bc77522085fbart return (Addr)VG_(threads)[tid].altstack.ss_sp; 40983c5a921adba406a2bad193d59e22bc77522085fbart} 41083c5a921adba406a2bad193d59e22bc77522085fbart 41183c5a921adba406a2bad193d59e22bc77522085fbartSizeT VG_(thread_get_altstack_size)(ThreadId tid) 41283c5a921adba406a2bad193d59e22bc77522085fbart{ 41383c5a921adba406a2bad193d59e22bc77522085fbart vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID); 41483c5a921adba406a2bad193d59e22bc77522085fbart vg_assert(VG_(threads)[tid].status != VgTs_Empty); 41583c5a921adba406a2bad193d59e22bc77522085fbart return VG_(threads)[tid].altstack.ss_size; 41683c5a921adba406a2bad193d59e22bc77522085fbart} 41783c5a921adba406a2bad193d59e22bc77522085fbart 418e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj//------------------------------------------------------------- 419e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj/* Details about the capabilities of the underlying (host) CPU. These 420e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj details are acquired by (1) enquiring with the CPU at startup, or 421e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj (2) from the AT_SYSINFO entries the kernel gave us (ppc32 cache 422e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj line size). It's a bit nasty in the sense that there's no obvious 423e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj way to stop uses of some of this info before it's ready to go. 4240daa4e31a3407ce0b0db8a90be8dd14bd8eccb35florian See pub_core_machine.h for more information about that. 425b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 426e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj VG_(machine_get_hwcaps) may use signals (although it attempts to 427e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj leave signal state unchanged) and therefore should only be 428e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj called before m_main sets up the client's signal state. 429e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj*/ 430a48a4939011eb7c09e12d29fe00e792a635b83d6sewardj 431e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj/* --------- State --------- */ 43259570ffbe31930ab4d678754daaeec0715117a3dsewardjstatic Bool hwcaps_done = False; 433e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 434e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj/* --- all archs --- */ 43598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardjstatic VexArch va = VexArch_INVALID; 436e2d1e670d412ff85c824ba5c043161816b9e26bdsewardjstatic VexArchInfo vai; 437e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 438e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#if defined(VGA_x86) 439e2d1e670d412ff85c824ba5c043161816b9e26bdsewardjUInt VG_(machine_x86_have_mxcsr) = 0; 44010f08cf5b84882eebbb6712a7be890577650e8adsewardj#endif 441e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#if defined(VGA_ppc32) 4422c36d4285afacafc10232e2f70978e0519216138sewardjUInt VG_(machine_ppc32_has_FP) = 0; 443e2d1e670d412ff85c824ba5c043161816b9e26bdsewardjUInt VG_(machine_ppc32_has_VMX) = 0; 444e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#endif 445cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGA_ppc64be) || defined(VGA_ppc64le) 4462c48c7b0a453d32375a4df17e153011b797ef28csewardjULong VG_(machine_ppc64_has_VMX) = 0; 4472c48c7b0a453d32375a4df17e153011b797ef28csewardj#endif 4481dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj#if defined(VGA_arm) 4491dbd3376656236debf5d35a9b5d8a507a6c307f0sewardjInt VG_(machine_arm_archlevel) = 4; 4501dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj#endif 451e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 452e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 4532c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj/* For hwcaps detection on ppc32/64, s390x, and arm we'll need to do SIGILL 4546c591e15c1d6402a2a755310f005f795b68e7e38sewardj testing, so we need a VG_MINIMAL_JMP_BUF. */ 455cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ 4565f790e8e33278b242b52c6479c94ce279b88d82cdejanj || defined(VGA_arm) || defined(VGA_s390x) || defined(VGA_mips32) 457c91f58449e6fc2a4ce0851639a342c4277612fbbflorian#include "pub_core_libcsetjmp.h" 45897d3ebba515c00930db4ee3f52af571bc84b2ef6sewardjstatic VG_MINIMAL_JMP_BUF(env_unsup_insn); 4596c591e15c1d6402a2a755310f005f795b68e7e38sewardjstatic void handler_unsup_insn ( Int x ) { 4606c591e15c1d6402a2a755310f005f795b68e7e38sewardj VG_MINIMAL_LONGJMP(env_unsup_insn); 4616c591e15c1d6402a2a755310f005f795b68e7e38sewardj} 4625ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj#endif 4635ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj 464b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 465b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj/* Helper function for VG_(machine_get_hwcaps), assumes the SIGILL/etc 466ad4e979f408239dabbaae955d8ffcb84a51a5c85florian * handlers are installed. Determines the sizes affected by dcbz 467b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * and dcbzl instructions and updates the given VexArchInfo structure 468b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * accordingly. 469b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * 470b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * Not very defensive: assumes that as long as the dcbz/dcbzl 471b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * instructions don't raise a SIGILL, that they will zero an aligned, 472b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * contiguous block of memory of a sensible size. */ 473cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 474b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardjstatic void find_ppc_dcbz_sz(VexArchInfo *arch_info) 475b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj{ 476dcb3a5968fc11a32e82e5e865201de63e50f2a7asewardj Int dcbz_szB = 0; 477b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj Int dcbzl_szB; 4785ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj# define MAX_DCBZL_SZB (128) /* largest known effect of dcbzl */ 479b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj char test_block[4*MAX_DCBZL_SZB]; 480b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj char *aligned = test_block; 481b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj Int i; 482b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 483b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* round up to next max block size, assumes MAX_DCBZL_SZB is pof2 */ 484b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj aligned = (char *)(((HWord)aligned + MAX_DCBZL_SZB) & ~(MAX_DCBZL_SZB - 1)); 485b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj vg_assert((aligned + MAX_DCBZL_SZB) <= &test_block[sizeof(test_block)]); 486b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 487b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* dcbz often clears 32B, although sometimes whatever the native cache 488b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * block size is */ 489b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj VG_(memset)(test_block, 0xff, sizeof(test_block)); 490b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj __asm__ __volatile__("dcbz 0,%0" 491b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : /*out*/ 492b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : "r" (aligned) /*in*/ 493b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : "memory" /*clobber*/); 494b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj for (dcbz_szB = 0, i = 0; i < sizeof(test_block); ++i) { 495b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj if (!test_block[i]) 496b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj ++dcbz_szB; 497b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj } 498643d501b0ac9478a58058952f367aef30e9b80b4sewardj vg_assert(dcbz_szB == 16 || dcbz_szB == 32 || dcbz_szB == 64 || dcbz_szB == 128); 499b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 500b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* dcbzl clears 128B on G5/PPC970, and usually 32B on other platforms */ 5016c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 502b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj dcbzl_szB = 0; /* indicates unsupported */ 503b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj } 504b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj else { 505b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj VG_(memset)(test_block, 0xff, sizeof(test_block)); 506b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* some older assemblers won't understand the dcbzl instruction 507b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * variant, so we directly emit the instruction ourselves */ 508b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj __asm__ __volatile__("mr 9, %0 ; .long 0x7C204FEC" /*dcbzl 0,9*/ 509b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : /*out*/ 510b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : "r" (aligned) /*in*/ 511b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj : "memory", "r9" /*clobber*/); 512b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj for (dcbzl_szB = 0, i = 0; i < sizeof(test_block); ++i) { 513b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj if (!test_block[i]) 514b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj ++dcbzl_szB; 515b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj } 516643d501b0ac9478a58058952f367aef30e9b80b4sewardj vg_assert(dcbzl_szB == 16 || dcbzl_szB == 32 || dcbzl_szB == 64 || dcbzl_szB == 128); 517b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj } 518b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 519b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj arch_info->ppc_dcbz_szB = dcbz_szB; 520b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj arch_info->ppc_dcbzl_szB = dcbzl_szB; 521b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 522b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj VG_(debugLog)(1, "machine", "dcbz_szB=%d dcbzl_szB=%d\n", 523b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj dcbz_szB, dcbzl_szB); 5245ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj# undef MAX_DCBZL_SZB 525b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj} 526cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#endif /* defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) */ 5275ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj 5282c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj#ifdef VGA_s390x 5292c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5302c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj/* Read /proc/cpuinfo. Look for lines like these 5312c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5322c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj processor 0: version = FF, identification = 0117C9, machine = 2064 5332c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5344e63b8eeac4166e70f26a17502621bddf1b01ff9florian and return the machine model. If the machine model could not be determined 5354e63b8eeac4166e70f26a17502621bddf1b01ff9florian or it is an unknown model, return VEX_S390X_MODEL_UNKNOWN. */ 5362c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5372c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardjstatic UInt VG_(get_machine_model)(void) 5382c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj{ 5392c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj static struct model_map { 5403130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar name[5]; 5412c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj UInt id; 5422c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } model_map[] = { 5432c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2064", VEX_S390X_MODEL_Z900 }, 5442c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2066", VEX_S390X_MODEL_Z800 }, 5452c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2084", VEX_S390X_MODEL_Z990 }, 5462c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2086", VEX_S390X_MODEL_Z890 }, 5472c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2094", VEX_S390X_MODEL_Z9_EC }, 5482c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2096", VEX_S390X_MODEL_Z9_BC }, 5492c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2097", VEX_S390X_MODEL_Z10_EC }, 5502c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2098", VEX_S390X_MODEL_Z10_BC }, 5512c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj { "2817", VEX_S390X_MODEL_Z196 }, 552258ede7d62d10597e1551aab0ff5c4abb107444aflorian { "2818", VEX_S390X_MODEL_Z114 }, 55387a25cf59352617f8876b8bdc8d437d4aafe5ae3florian { "2827", VEX_S390X_MODEL_ZEC12 }, 5543b411c169c685099c2fc26d816d4eac29fca6573florian { "2828", VEX_S390X_MODEL_ZBC12 }, 555dd1d372ee14d89793942cea99296853253a664edflorian { "2964", VEX_S390X_MODEL_Z13 }, 556a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { "2965", VEX_S390X_MODEL_Z13S }, 5572c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj }; 5582c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5592c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj Int model, n, fh; 5602c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj SysRes fd; 5612c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj SizeT num_bytes, file_buf_size; 5622c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj HChar *p, *m, *model_name, *file_buf; 5632c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5642c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj /* Slurp contents of /proc/cpuinfo into FILE_BUF */ 5652c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj fd = VG_(open)( "/proc/cpuinfo", 0, VKI_S_IRUSR ); 5664e63b8eeac4166e70f26a17502621bddf1b01ff9florian if ( sr_isError(fd) ) return VEX_S390X_MODEL_UNKNOWN; 5672c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5682c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj fh = sr_Res(fd); 5692c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5702c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj /* Determine the size of /proc/cpuinfo. 5712c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj Work around broken-ness in /proc file system implementation. 5722c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj fstat returns a zero size for /proc/cpuinfo although it is 5732c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj claimed to be a regular file. */ 5742c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj num_bytes = 0; 5752c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj file_buf_size = 1000; 5762c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj file_buf = VG_(malloc)("cpuinfo", file_buf_size + 1); 5772c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj while (42) { 5782c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj n = VG_(read)(fh, file_buf, file_buf_size); 5792c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (n < 0) break; 5802c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5812c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj num_bytes += n; 5822c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (n < file_buf_size) break; /* reached EOF */ 5832c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 5842c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5852c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (n < 0) num_bytes = 0; /* read error; ignore contents */ 5862c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5872c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (num_bytes > file_buf_size) { 5882c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(free)( file_buf ); 5892c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(lseek)( fh, 0, VKI_SEEK_SET ); 5902c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj file_buf = VG_(malloc)( "cpuinfo", num_bytes + 1 ); 5912c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj n = VG_(read)( fh, file_buf, num_bytes ); 5922c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (n < 0) num_bytes = 0; 5932c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 5942c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5952c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj file_buf[num_bytes] = '\0'; 5962c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(close)(fh); 5972c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 5982c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj /* Parse file */ 5994e63b8eeac4166e70f26a17502621bddf1b01ff9florian model = VEX_S390X_MODEL_UNKNOWN; 6002c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj for (p = file_buf; *p; ++p) { 6012c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj /* Beginning of line */ 6022c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (VG_(strncmp)( p, "processor", sizeof "processor" - 1 ) != 0) continue; 6032c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 6042c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj m = VG_(strstr)( p, "machine" ); 6052c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (m == NULL) continue; 6062c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 6072c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj p = m + sizeof "machine" - 1; 6082c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj while ( VG_(isspace)( *p ) || *p == '=') { 6092c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (*p == '\n') goto next_line; 6102c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj ++p; 6112c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 6122c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 6132c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj model_name = p; 6142c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj for (n = 0; n < sizeof model_map / sizeof model_map[0]; ++n) { 6152c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj struct model_map *mm = model_map + n; 6162c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj SizeT len = VG_(strlen)( mm->name ); 6172c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if ( VG_(strncmp)( mm->name, model_name, len ) == 0 && 6182c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(isspace)( model_name[len] )) { 6192c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (mm->id < model) model = mm->id; 6202c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj p = model_name + len; 6212c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj break; 6222c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 6232c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 6242c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj /* Skip until end-of-line */ 6252c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj while (*p != '\n') 6262c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj ++p; 6272c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj next_line: ; 6282c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 6292c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 6302c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(free)( file_buf ); 6310016492d69a0f3cd2b68afe25c9b68911b7b906bflorian VG_(debugLog)(1, "machine", "model = %s\n", 6324e63b8eeac4166e70f26a17502621bddf1b01ff9florian model == VEX_S390X_MODEL_UNKNOWN ? "UNKNOWN" 6330016492d69a0f3cd2b68afe25c9b68911b7b906bflorian : model_map[model].name); 6342c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj return model; 6352c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj} 6365ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj 637ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#endif /* defined(VGA_s390x) */ 6385ae70ce1f365ec09112da924c4e0e7aa673fd9c6sewardj 6394df0bfc0614379192c780c944415dc420d9cfe8epetarj#if defined(VGA_mips32) || defined(VGA_mips64) 6405db15403e889d4db339b342bc2a824ef0bfaa654sewardj 641a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* 642a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * Initialize hwcaps by parsing /proc/cpuinfo . Returns False if it can not 643a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * determine what CPU it is (it searches only for the models that are or may be 644a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * supported by Valgrind). 645a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 646a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic Bool VG_(parse_cpuinfo)(void) 6475db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 648a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_Broadcom_str = "cpu model\t\t: Broadcom"; 649a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_Cavium_str= "cpu model\t\t: Cavium"; 650a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_Ingenic_str= "cpu model\t\t: Ingenic"; 651a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_Loongson_str= "cpu model\t\t: ICT Loongson"; 652a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_MIPS_str = "cpu model\t\t: MIPS"; 653a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char *search_Netlogic_str = "cpu model\t\t: Netlogic"; 654a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 6555db15403e889d4db339b342bc2a824ef0bfaa654sewardj Int n, fh; 6565db15403e889d4db339b342bc2a824ef0bfaa654sewardj SysRes fd; 6575db15403e889d4db339b342bc2a824ef0bfaa654sewardj SizeT num_bytes, file_buf_size; 658a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes HChar *file_buf, *isa; 6595db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6605db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* Slurp contents of /proc/cpuinfo into FILE_BUF */ 6615db15403e889d4db339b342bc2a824ef0bfaa654sewardj fd = VG_(open)( "/proc/cpuinfo", 0, VKI_S_IRUSR ); 662a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if ( sr_isError(fd) ) return False; 6635db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6645db15403e889d4db339b342bc2a824ef0bfaa654sewardj fh = sr_Res(fd); 6655db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6665db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* Determine the size of /proc/cpuinfo. 6675db15403e889d4db339b342bc2a824ef0bfaa654sewardj Work around broken-ness in /proc file system implementation. 6685db15403e889d4db339b342bc2a824ef0bfaa654sewardj fstat returns a zero size for /proc/cpuinfo although it is 6695db15403e889d4db339b342bc2a824ef0bfaa654sewardj claimed to be a regular file. */ 6705db15403e889d4db339b342bc2a824ef0bfaa654sewardj num_bytes = 0; 6715db15403e889d4db339b342bc2a824ef0bfaa654sewardj file_buf_size = 1000; 6725db15403e889d4db339b342bc2a824ef0bfaa654sewardj file_buf = VG_(malloc)("cpuinfo", file_buf_size + 1); 6735db15403e889d4db339b342bc2a824ef0bfaa654sewardj while (42) { 6745db15403e889d4db339b342bc2a824ef0bfaa654sewardj n = VG_(read)(fh, file_buf, file_buf_size); 6755db15403e889d4db339b342bc2a824ef0bfaa654sewardj if (n < 0) break; 6765db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6775db15403e889d4db339b342bc2a824ef0bfaa654sewardj num_bytes += n; 6785db15403e889d4db339b342bc2a824ef0bfaa654sewardj if (n < file_buf_size) break; /* reached EOF */ 6795db15403e889d4db339b342bc2a824ef0bfaa654sewardj } 6805db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6815db15403e889d4db339b342bc2a824ef0bfaa654sewardj if (n < 0) num_bytes = 0; /* read error; ignore contents */ 6825db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6835db15403e889d4db339b342bc2a824ef0bfaa654sewardj if (num_bytes > file_buf_size) { 6845db15403e889d4db339b342bc2a824ef0bfaa654sewardj VG_(free)( file_buf ); 6855db15403e889d4db339b342bc2a824ef0bfaa654sewardj VG_(lseek)( fh, 0, VKI_SEEK_SET ); 6865db15403e889d4db339b342bc2a824ef0bfaa654sewardj file_buf = VG_(malloc)( "cpuinfo", num_bytes + 1 ); 6875db15403e889d4db339b342bc2a824ef0bfaa654sewardj n = VG_(read)( fh, file_buf, num_bytes ); 6885db15403e889d4db339b342bc2a824ef0bfaa654sewardj if (n < 0) num_bytes = 0; 6895db15403e889d4db339b342bc2a824ef0bfaa654sewardj } 6905db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6915db15403e889d4db339b342bc2a824ef0bfaa654sewardj file_buf[num_bytes] = '\0'; 6925db15403e889d4db339b342bc2a824ef0bfaa654sewardj VG_(close)(fh); 6935db15403e889d4db339b342bc2a824ef0bfaa654sewardj 6945db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* Parse file */ 695a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr)(file_buf, search_Broadcom_str) != NULL) 696a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = VEX_PRID_COMP_BROADCOM; 697a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else if (VG_(strstr)(file_buf, search_Netlogic_str) != NULL) 698a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = VEX_PRID_COMP_NETLOGIC; 699a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else if (VG_(strstr)(file_buf, search_Cavium_str) != NULL) 700a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = VEX_PRID_COMP_CAVIUM; 701a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else if (VG_(strstr)(file_buf, search_MIPS_str) != NULL) 702a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = VEX_PRID_COMP_MIPS; 703a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else if (VG_(strstr)(file_buf, search_Ingenic_str) != NULL) 704a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = VEX_PRID_COMP_INGENIC_E1; 705a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else if (VG_(strstr)(file_buf, search_Loongson_str) != NULL) 706a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = (VEX_PRID_COMP_LEGACY | VEX_PRID_IMP_LOONGSON_64); 707a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else { 708a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* Did not find string in the proc file. */ 709a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps = 0; 710a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(file_buf); 711a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return False; 712a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 713a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 714a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes isa = VG_(strstr)(file_buf, "isa\t\t\t: "); 715a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 716a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (NULL != isa) { 717a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips32r1") != NULL) 718a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R1; 719a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips32r2") != NULL) 720a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R2; 721a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips32r6") != NULL) 722a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R6; 723a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips64r1") != NULL) 724a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M64R1; 725a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips64r2") != NULL) 726a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M64R2; 727a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_(strstr) (isa, "mips64r6") != NULL) 728a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M64R6; 729ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 730ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* 731ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes * TODO(petarj): Remove this Cavium workaround once Linux kernel folks 732ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes * decide to change incorrect settings in 733ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes * mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h. 734ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes * The current settings show mips32r1, mips32r2 and mips64r1 as 735ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes * unsupported ISAs by Cavium MIPS CPUs. 736ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes */ 737ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (VEX_MIPS_COMP_ID(vai.hwcaps) == VEX_PRID_COMP_CAVIUM) { 738ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R1 | VEX_MIPS_CPU_ISA_M32R2 | 739ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VEX_MIPS_CPU_ISA_M64R1; 740ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 741a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 742a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* 743a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * Kernel does not provide information about supported ISAs. 744a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * Populate the isa level flags based on the CPU model. That is our 745a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * best guess. 746a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 747a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch VEX_MIPS_COMP_ID(vai.hwcaps) { 748a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_CAVIUM: 749a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_NETLOGIC: 750a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= (VEX_MIPS_CPU_ISA_M64R2 | VEX_MIPS_CPU_ISA_M64R1); 751a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_INGENIC_E1: 752a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_MIPS: 753a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R2; 754a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_BROADCOM: 755a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M32R1; 756a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 757a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case VEX_PRID_COMP_LEGACY: 758a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if ((VEX_MIPS_PROC_ID(vai.hwcaps) == VEX_PRID_IMP_LOONGSON_64)) 759a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_CPU_ISA_M64R2 | VEX_MIPS_CPU_ISA_M64R1 | 760a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VEX_MIPS_CPU_ISA_M32R2 | VEX_MIPS_CPU_ISA_M32R1; 761a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 762a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 763a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 764a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 765a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 766a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(file_buf); 767a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return True; 7685db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 7695db15403e889d4db339b342bc2a824ef0bfaa654sewardj 770ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#endif /* defined(VGA_mips32) || defined(VGA_mips64) */ 771ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 772ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#if defined(VGP_arm64_linux) 773ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 774ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes/* Check to see whether we are running on a Cavium core, and if so auto-enable 775ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes the fallback LLSC implementation. See #369459. */ 776ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 777ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughesstatic Bool VG_(parse_cpuinfo)(void) 778ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes{ 779ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes const char *search_Cavium_str = "CPU implementer\t: 0x43"; 780ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 781ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Int n, fh; 782ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes SysRes fd; 783ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes SizeT num_bytes, file_buf_size; 784ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes HChar *file_buf; 785ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 786ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Slurp contents of /proc/cpuinfo into FILE_BUF */ 787ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes fd = VG_(open)( "/proc/cpuinfo", 0, VKI_S_IRUSR ); 788ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if ( sr_isError(fd) ) return False; 789ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 790ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes fh = sr_Res(fd); 791ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 792ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Determine the size of /proc/cpuinfo. 793ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Work around broken-ness in /proc file system implementation. 794ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes fstat returns a zero size for /proc/cpuinfo although it is 795ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes claimed to be a regular file. */ 796ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes num_bytes = 0; 797ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes file_buf_size = 1000; 798ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes file_buf = VG_(malloc)("cpuinfo", file_buf_size + 1); 799ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes while (42) { 800ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes n = VG_(read)(fh, file_buf, file_buf_size); 801ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (n < 0) break; 802ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 803ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes num_bytes += n; 804ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (n < file_buf_size) break; /* reached EOF */ 805ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 806ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 807ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (n < 0) num_bytes = 0; /* read error; ignore contents */ 808ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 809ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (num_bytes > file_buf_size) { 810ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VG_(free)( file_buf ); 811ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VG_(lseek)( fh, 0, VKI_SEEK_SET ); 812ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes file_buf = VG_(malloc)( "cpuinfo", num_bytes + 1 ); 813ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes n = VG_(read)( fh, file_buf, num_bytes ); 814ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (n < 0) num_bytes = 0; 815ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 816ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 817ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes file_buf[num_bytes] = '\0'; 818ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VG_(close)(fh); 8195db15403e889d4db339b342bc2a824ef0bfaa654sewardj 820ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Parse file */ 821ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (VG_(strstr)(file_buf, search_Cavium_str) != NULL) 822ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes vai.arm64_requires_fallback_LLSC = True; 823ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 824ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VG_(free)(file_buf); 825ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return True; 826ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes} 827ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 828ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#endif /* defined(VGP_arm64_linux) */ 829e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 830e2d1e670d412ff85c824ba5c043161816b9e26bdsewardjBool VG_(machine_get_hwcaps)( void ) 831e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj{ 832e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj vg_assert(hwcaps_done == False); 833e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj hwcaps_done = True; 834e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 835e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj // Whack default settings into vai, so that we only need to fill in 836e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj // any interesting bits. 837e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj LibVEX_default_VexArchInfo(&vai); 838a48a4939011eb7c09e12d29fe00e792a635b83d6sewardj 8397821e2ed55ac6c2303eb51a06bafd5baada2423dsewardj#if defined(VGA_x86) 840732fb4e38991c4f0cef40c5c7e210010360d05ebflorian { Bool have_sse1, have_sse2, have_sse3, have_cx8, have_lzcnt, have_mmxext; 841c7ffc94890e120c72d5802487b1092425323dc02sewardj UInt eax, ebx, ecx, edx, max_extended; 84266826ece25fc70c7437c38170f2a4312504bd7ffsewardj HChar vstr[13]; 84340d91c7dcfd400464d2e1385caad6b31c17823d4sewardj vstr[0] = 0; 844e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 845e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj if (!VG_(has_cpuid)()) 846e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj /* we can't do cpuid at all. Give up. */ 847e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj return False; 848e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 849ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0, 0, &eax, &ebx, &ecx, &edx); 850e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj if (eax < 1) 851e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj /* we can't ask for cpuid(x) for x > 0. Give up. */ 852e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj return False; 853e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 85440d91c7dcfd400464d2e1385caad6b31c17823d4sewardj /* Get processor ID string, and max basic/extended index 85540d91c7dcfd400464d2e1385caad6b31c17823d4sewardj values. */ 85640d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[0], &ebx, 4); 85740d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[4], &edx, 4); 85840d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[8], &ecx, 4); 85940d91c7dcfd400464d2e1385caad6b31c17823d4sewardj vstr[12] = 0; 86040d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 861ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000000, 0, &eax, &ebx, &ecx, &edx); 86240d91c7dcfd400464d2e1385caad6b31c17823d4sewardj max_extended = eax; 86340d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 864e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj /* get capabilities bits into edx */ 865ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(1, 0, &eax, &ebx, &ecx, &edx); 866e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 867e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */ 868e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */ 869732fb4e38991c4f0cef40c5c7e210010360d05ebflorian have_sse3 = (ecx & (1<<0)) != 0; /* True => have sse3 insns */ 870e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 8711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* cmpxchg8b is a minimum requirement now; if we don't have it we 8721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj must simply give up. But all CPUs since Pentium-I have it, so 8731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj that doesn't seem like much of a restriction. */ 8741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */ 8751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (!have_cx8) 8761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return False; 8771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 87837dd8f69405c476b08fadd314817a49e54e767b4sewardj /* Figure out if this is an AMD that can do MMXEXT. */ 8797c6a0003a9466af7099d30205c25db7328bc1332mjw have_mmxext = False; 88040d91c7dcfd400464d2e1385caad6b31c17823d4sewardj if (0 == VG_(strcmp)(vstr, "AuthenticAMD") 88140d91c7dcfd400464d2e1385caad6b31c17823d4sewardj && max_extended >= 0x80000001) { 882ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx); 8837c6a0003a9466af7099d30205c25db7328bc1332mjw /* Some older AMD processors support a sse1 subset (Integer SSE). */ 8847c6a0003a9466af7099d30205c25db7328bc1332mjw have_mmxext = !have_sse1 && ((edx & (1<<22)) != 0); 88540d91c7dcfd400464d2e1385caad6b31c17823d4sewardj } 88640d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 88737dd8f69405c476b08fadd314817a49e54e767b4sewardj /* Figure out if this is an AMD or Intel that can do LZCNT. */ 88837dd8f69405c476b08fadd314817a49e54e767b4sewardj have_lzcnt = False; 88937dd8f69405c476b08fadd314817a49e54e767b4sewardj if ((0 == VG_(strcmp)(vstr, "AuthenticAMD") 89037dd8f69405c476b08fadd314817a49e54e767b4sewardj || 0 == VG_(strcmp)(vstr, "GenuineIntel")) 89137dd8f69405c476b08fadd314817a49e54e767b4sewardj && max_extended >= 0x80000001) { 89237dd8f69405c476b08fadd314817a49e54e767b4sewardj VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx); 89337dd8f69405c476b08fadd314817a49e54e767b4sewardj have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */ 89437dd8f69405c476b08fadd314817a49e54e767b4sewardj } 89537dd8f69405c476b08fadd314817a49e54e767b4sewardj 8967c6a0003a9466af7099d30205c25db7328bc1332mjw /* Intel processors don't define the mmxext extension, but since it 8977c6a0003a9466af7099d30205c25db7328bc1332mjw is just a sse1 subset always define it when we have sse1. */ 8987c6a0003a9466af7099d30205c25db7328bc1332mjw if (have_sse1) 8997c6a0003a9466af7099d30205c25db7328bc1332mjw have_mmxext = True; 9007c6a0003a9466af7099d30205c25db7328bc1332mjw 9017862701c0e3f556e4a0c7ec4074a40526c73a4efflorian va = VexArchX86; 902597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 903732fb4e38991c4f0cef40c5c7e210010360d05ebflorian 904732fb4e38991c4f0cef40c5c7e210010360d05ebflorian if (have_sse3 && have_sse2 && have_sse1 && have_mmxext) { 905732fb4e38991c4f0cef40c5c7e210010360d05ebflorian vai.hwcaps = VEX_HWCAPS_X86_MMXEXT; 906732fb4e38991c4f0cef40c5c7e210010360d05ebflorian vai.hwcaps |= VEX_HWCAPS_X86_SSE1; 907732fb4e38991c4f0cef40c5c7e210010360d05ebflorian vai.hwcaps |= VEX_HWCAPS_X86_SSE2; 908732fb4e38991c4f0cef40c5c7e210010360d05ebflorian vai.hwcaps |= VEX_HWCAPS_X86_SSE3; 909732fb4e38991c4f0cef40c5c7e210010360d05ebflorian if (have_lzcnt) 910732fb4e38991c4f0cef40c5c7e210010360d05ebflorian vai.hwcaps |= VEX_HWCAPS_X86_LZCNT; 911732fb4e38991c4f0cef40c5c7e210010360d05ebflorian VG_(machine_x86_have_mxcsr) = 1; 912732fb4e38991c4f0cef40c5c7e210010360d05ebflorian } else if (have_sse2 && have_sse1 && have_mmxext) { 9137c6a0003a9466af7099d30205c25db7328bc1332mjw vai.hwcaps = VEX_HWCAPS_X86_MMXEXT; 9147c6a0003a9466af7099d30205c25db7328bc1332mjw vai.hwcaps |= VEX_HWCAPS_X86_SSE1; 915e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj vai.hwcaps |= VEX_HWCAPS_X86_SSE2; 91640d91c7dcfd400464d2e1385caad6b31c17823d4sewardj if (have_lzcnt) 91740d91c7dcfd400464d2e1385caad6b31c17823d4sewardj vai.hwcaps |= VEX_HWCAPS_X86_LZCNT; 918e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj VG_(machine_x86_have_mxcsr) = 1; 9197c6a0003a9466af7099d30205c25db7328bc1332mjw } else if (have_sse1 && have_mmxext) { 9207c6a0003a9466af7099d30205c25db7328bc1332mjw vai.hwcaps = VEX_HWCAPS_X86_MMXEXT; 9217c6a0003a9466af7099d30205c25db7328bc1332mjw vai.hwcaps |= VEX_HWCAPS_X86_SSE1; 922e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj VG_(machine_x86_have_mxcsr) = 1; 9237c6a0003a9466af7099d30205c25db7328bc1332mjw } else if (have_mmxext) { 9247c6a0003a9466af7099d30205c25db7328bc1332mjw vai.hwcaps = VEX_HWCAPS_X86_MMXEXT; /*integer only sse1 subset*/ 9257c6a0003a9466af7099d30205c25db7328bc1332mjw VG_(machine_x86_have_mxcsr) = 0; 9267862701c0e3f556e4a0c7ec4074a40526c73a4efflorian } else { 9277862701c0e3f556e4a0c7ec4074a40526c73a4efflorian vai.hwcaps = 0; /*baseline - no sse at all*/ 9287862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_x86_have_mxcsr) = 0; 929e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj } 930e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 9317862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 9327862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 933e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj return True; 934e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj } 935e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 936e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#elif defined(VGA_amd64) 937c7ffc94890e120c72d5802487b1092425323dc02sewardj { Bool have_sse3, have_cx8, have_cx16; 938fda50af388bcb6f7fea519efdf565517f8874ff4sewardj Bool have_lzcnt, have_avx, have_bmi, have_avx2; 939e653b034b9252da55c93980c819814ba597f9c29sewardj Bool have_rdtscp; 940fda50af388bcb6f7fea519efdf565517f8874ff4sewardj UInt eax, ebx, ecx, edx, max_basic, max_extended; 9417c1d0636fff67d62bf05199a4497189bc1befb67sewardj ULong xgetbv_0 = 0; 94219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar vstr[13]; 94340d91c7dcfd400464d2e1385caad6b31c17823d4sewardj vstr[0] = 0; 9441c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 9451c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (!VG_(has_cpuid)()) 9461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* we can't do cpuid at all. Give up. */ 9471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return False; 9481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 949ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0, 0, &eax, &ebx, &ecx, &edx); 950fda50af388bcb6f7fea519efdf565517f8874ff4sewardj max_basic = eax; 951fda50af388bcb6f7fea519efdf565517f8874ff4sewardj if (max_basic < 1) 9521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* we can't ask for cpuid(x) for x > 0. Give up. */ 9531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return False; 9541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 95540d91c7dcfd400464d2e1385caad6b31c17823d4sewardj /* Get processor ID string, and max basic/extended index 95640d91c7dcfd400464d2e1385caad6b31c17823d4sewardj values. */ 95740d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[0], &ebx, 4); 95840d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[4], &edx, 4); 95940d91c7dcfd400464d2e1385caad6b31c17823d4sewardj VG_(memcpy)(&vstr[8], &ecx, 4); 96040d91c7dcfd400464d2e1385caad6b31c17823d4sewardj vstr[12] = 0; 96140d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 962ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000000, 0, &eax, &ebx, &ecx, &edx); 96340d91c7dcfd400464d2e1385caad6b31c17823d4sewardj max_extended = eax; 96440d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 9651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* get capabilities bits into edx */ 966ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(1, 0, &eax, &ebx, &ecx, &edx); 9671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 968c7ffc94890e120c72d5802487b1092425323dc02sewardj // we assume that SSE1 and SSE2 are available by default 969598971eaf64c982788a8ca9eaa75c8cb181acb56sewardj have_sse3 = (ecx & (1<<0)) != 0; /* True => have sse3 insns */ 970ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // ssse3 is ecx:9 971ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // sse41 is ecx:19 972ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // sse42 is ecx:20 973ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj 9747c1d0636fff67d62bf05199a4497189bc1befb67sewardj // xsave is ecx:26 975ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // osxsave is ecx:27 976ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // avx is ecx:28 977ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj // fma is ecx:12 978ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj have_avx = False; 979ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj /* have_fma = False; */ 9807c1d0636fff67d62bf05199a4497189bc1befb67sewardj if ( (ecx & ((1<<28)|(1<<27)|(1<<26))) == ((1<<28)|(1<<27)|(1<<26)) ) { 9817c1d0636fff67d62bf05199a4497189bc1befb67sewardj /* Processor supports AVX instructions and XGETBV is enabled 9827c1d0636fff67d62bf05199a4497189bc1befb67sewardj by OS and AVX instructions are enabled by the OS. */ 983ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj ULong w; 984ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj __asm__ __volatile__("movq $0,%%rcx ; " 985ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj ".byte 0x0F,0x01,0xD0 ; " /* xgetbv */ 986ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj "movq %%rax,%0" 987ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj :/*OUT*/"=r"(w) :/*IN*/ 9887c1d0636fff67d62bf05199a4497189bc1befb67sewardj :/*TRASH*/"rdx","rcx","rax"); 9897c1d0636fff67d62bf05199a4497189bc1befb67sewardj xgetbv_0 = w; 9907c1d0636fff67d62bf05199a4497189bc1befb67sewardj if ((xgetbv_0 & 7) == 7) { 9917c1d0636fff67d62bf05199a4497189bc1befb67sewardj /* Only say we have AVX if the XSAVE-allowable 9927c1d0636fff67d62bf05199a4497189bc1befb67sewardj bitfield-mask allows x87, SSE and AVX state. We could 9937c1d0636fff67d62bf05199a4497189bc1befb67sewardj actually run with a more restrictive XGETBV(0) value, 9947c1d0636fff67d62bf05199a4497189bc1befb67sewardj but VEX's implementation of XSAVE and XRSTOR assumes 9957c1d0636fff67d62bf05199a4497189bc1befb67sewardj that all 3 bits are enabled. 9967c1d0636fff67d62bf05199a4497189bc1befb67sewardj 9977c1d0636fff67d62bf05199a4497189bc1befb67sewardj Also, the VEX implementation of XSAVE/XRSTOR assumes that 9987c1d0636fff67d62bf05199a4497189bc1befb67sewardj state component [2] (the YMM high halves) are located in 9997c1d0636fff67d62bf05199a4497189bc1befb67sewardj the XSAVE image at offsets 576 .. 831. So we have to 10007c1d0636fff67d62bf05199a4497189bc1befb67sewardj check that here before declaring AVX to be supported. */ 10017c1d0636fff67d62bf05199a4497189bc1befb67sewardj UInt eax2, ebx2, ecx2, edx2; 10027c1d0636fff67d62bf05199a4497189bc1befb67sewardj VG_(cpuid)(0xD, 2, &eax2, &ebx2, &ecx2, &edx2); 10037c1d0636fff67d62bf05199a4497189bc1befb67sewardj if (ebx2 == 576 && eax2 == 256) { 10047c1d0636fff67d62bf05199a4497189bc1befb67sewardj have_avx = True; 10057c1d0636fff67d62bf05199a4497189bc1befb67sewardj } 1006ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj /* have_fma = (ecx & (1<<12)) != 0; */ 1007ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj /* have_fma: Probably correct, but gcc complains due to 10087c1d0636fff67d62bf05199a4497189bc1befb67sewardj unusedness. */ 1009ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj } 1010ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj } 1011ee1a897f672cce5583767ed9baf3b0bf0a4c170bsewardj 10121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* cmpxchg8b is a minimum requirement now; if we don't have it we 10131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj must simply give up. But all CPUs since Pentium-I have it, so 10141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj that doesn't seem like much of a restriction. */ 10151c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */ 10161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (!have_cx8) 10171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return False; 10181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 10191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* on amd64 we tolerate older cpus, which don't have cmpxchg16b */ 10201c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj have_cx16 = (ecx & (1<<13)) != 0; /* True => have cmpxchg16b */ 10211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1022fda50af388bcb6f7fea519efdf565517f8874ff4sewardj /* Figure out if this CPU can do LZCNT. */ 102340d91c7dcfd400464d2e1385caad6b31c17823d4sewardj have_lzcnt = False; 1024fda50af388bcb6f7fea519efdf565517f8874ff4sewardj if (max_extended >= 0x80000001) { 1025ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx); 102640d91c7dcfd400464d2e1385caad6b31c17823d4sewardj have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */ 102740d91c7dcfd400464d2e1385caad6b31c17823d4sewardj } 1028fda50af388bcb6f7fea519efdf565517f8874ff4sewardj 1029e653b034b9252da55c93980c819814ba597f9c29sewardj /* Can we do RDTSCP? */ 1030e653b034b9252da55c93980c819814ba597f9c29sewardj have_rdtscp = False; 1031e653b034b9252da55c93980c819814ba597f9c29sewardj if (max_extended >= 0x80000001) { 1032e653b034b9252da55c93980c819814ba597f9c29sewardj VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx); 1033e653b034b9252da55c93980c819814ba597f9c29sewardj have_rdtscp = (edx & (1<<27)) != 0; /* True => have RDTSVCP */ 1034e653b034b9252da55c93980c819814ba597f9c29sewardj } 103540d91c7dcfd400464d2e1385caad6b31c17823d4sewardj 10367c1d0636fff67d62bf05199a4497189bc1befb67sewardj /* Check for BMI1 and AVX2. If we have AVX1 (plus OS support). */ 10377c1d0636fff67d62bf05199a4497189bc1befb67sewardj have_bmi = False; 1038fda50af388bcb6f7fea519efdf565517f8874ff4sewardj have_avx2 = False; 1039787e8dc1fb76106fa17a3e5547d2cc219fab4fc8mjw if (have_avx && max_basic >= 7) { 1040fda50af388bcb6f7fea519efdf565517f8874ff4sewardj VG_(cpuid)(7, 0, &eax, &ebx, &ecx, &edx); 10417c1d0636fff67d62bf05199a4497189bc1befb67sewardj have_bmi = (ebx & (1<<3)) != 0; /* True => have BMI1 */ 1042787e8dc1fb76106fa17a3e5547d2cc219fab4fc8mjw have_avx2 = (ebx & (1<<5)) != 0; /* True => have AVX2 */ 1043fda50af388bcb6f7fea519efdf565517f8874ff4sewardj } 1044fda50af388bcb6f7fea519efdf565517f8874ff4sewardj 1045597314210494248b4fbefd45525a748439629218sewardj va = VexArchAMD64; 1046597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 1047597314210494248b4fbefd45525a748439629218sewardj vai.hwcaps = (have_sse3 ? VEX_HWCAPS_AMD64_SSE3 : 0) 1048597314210494248b4fbefd45525a748439629218sewardj | (have_cx16 ? VEX_HWCAPS_AMD64_CX16 : 0) 1049597314210494248b4fbefd45525a748439629218sewardj | (have_lzcnt ? VEX_HWCAPS_AMD64_LZCNT : 0) 1050597314210494248b4fbefd45525a748439629218sewardj | (have_avx ? VEX_HWCAPS_AMD64_AVX : 0) 1051597314210494248b4fbefd45525a748439629218sewardj | (have_bmi ? VEX_HWCAPS_AMD64_BMI : 0) 1052597314210494248b4fbefd45525a748439629218sewardj | (have_avx2 ? VEX_HWCAPS_AMD64_AVX2 : 0) 1053597314210494248b4fbefd45525a748439629218sewardj | (have_rdtscp ? VEX_HWCAPS_AMD64_RDTSCP : 0); 10547862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 10557862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 10567862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 10571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return True; 10581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 1059e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 1060e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#elif defined(VGA_ppc32) 10611581e745b8991508ef5243fd2d168790caf578e1bart { 10621581e745b8991508ef5243fd2d168790caf578e1bart /* Find out which subset of the ppc32 instruction set is supported by 10631581e745b8991508ef5243fd2d168790caf578e1bart verifying whether various ppc32 instructions generate a SIGILL 10641581e745b8991508ef5243fd2d168790caf578e1bart or a SIGFPE. An alternative approach is to check the AT_HWCAP and 10651581e745b8991508ef5243fd2d168790caf578e1bart AT_PLATFORM entries in the ELF auxiliary table -- see also 10661581e745b8991508ef5243fd2d168790caf578e1bart the_iifii.client_auxv in m_main.c. 10671581e745b8991508ef5243fd2d168790caf578e1bart */ 1068cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigset_t saved_set, tmp_set; 1069cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act; 1070cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act; 1071e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 10725ba075a1b629016370926fceacaf8e9155e1001csewardj volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP; 1073a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes volatile Bool have_isa_2_07, have_isa_3_0; 10747637e9e116e1b92f757993075d9b72ee36be9314sewardj Int r; 1075e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1076cda2f0fbda4c4b2644babc830244be8aed95de1dnjn /* This is a kludge. Really we ought to back-convert saved_act 1077cda2f0fbda4c4b2644babc830244be8aed95de1dnjn into a toK_t using VG_(convert_sigaction_fromK_to_toK), but 1078cda2f0fbda4c4b2644babc830244be8aed95de1dnjn since that's a no-op on all ppc32 platforms so far supported, 1079cda2f0fbda4c4b2644babc830244be8aed95de1dnjn it's not worth the typing effort. At least include most basic 1080cda2f0fbda4c4b2644babc830244be8aed95de1dnjn sanity check: */ 1081cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t)); 1082cda2f0fbda4c4b2644babc830244be8aed95de1dnjn 1083e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj VG_(sigemptyset)(&tmp_set); 1084e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj VG_(sigaddset)(&tmp_set, VKI_SIGILL); 10851581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaddset)(&tmp_set, VKI_SIGFPE); 1086e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 10877637e9e116e1b92f757993075d9b72ee36be9314sewardj r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); 10887637e9e116e1b92f757993075d9b72ee36be9314sewardj vg_assert(r == 0); 1089e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 10901581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); 10917637e9e116e1b92f757993075d9b72ee36be9314sewardj vg_assert(r == 0); 10921581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act = saved_sigill_act; 10931581e745b8991508ef5243fd2d168790caf578e1bart 10941581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act); 10951581e745b8991508ef5243fd2d168790caf578e1bart vg_assert(r == 0); 10961581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act = saved_sigfpe_act; 1097e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 10987637e9e116e1b92f757993075d9b72ee36be9314sewardj /* NODEFER: signal handler does not return (from the kernel's point of 10997637e9e116e1b92f757993075d9b72ee36be9314sewardj view), hence if it is to successfully catch a signal more than once, 11007637e9e116e1b92f757993075d9b72ee36be9314sewardj we need the NODEFER flag. */ 11011581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; 11021581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; 11031581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; 11041581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.ksa_handler = handler_unsup_insn; 11051581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 11061581e745b8991508ef5243fd2d168790caf578e1bart vg_assert(r == 0); 11071581e745b8991508ef5243fd2d168790caf578e1bart 11081581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND; 11091581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO; 11101581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER; 11111581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.ksa_handler = handler_unsup_insn; 11121581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL); 11131581e745b8991508ef5243fd2d168790caf578e1bart vg_assert(r == 0); 1114e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1115e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* standard FP insns */ 1116e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_F = True; 11176c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1118e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_F = False; 1119e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj } else { 1120f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0xFC000090"); /*fmr 0,0 */ 1121e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj } 1122e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1123e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* Altivec insns */ 1124e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_V = True; 11256c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1126e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_V = False; 1127e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj } else { 1128715921220d918dfee1cabe5aa01181d031d84544sewardj /* Unfortunately some older assemblers don't speak Altivec (or 1129715921220d918dfee1cabe5aa01181d031d84544sewardj choose not to), so to be safe we directly emit the 32-bit 1130715921220d918dfee1cabe5aa01181d031d84544sewardj word corresponding to "vor 0,0,0". This fixes a build 1131715921220d918dfee1cabe5aa01181d031d84544sewardj problem that happens on Debian 3.1 (ppc32), and probably 1132715921220d918dfee1cabe5aa01181d031d84544sewardj various other places. */ 113354d0dc768db5e4c90286ee79146b57f249fdb99csewardj __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/ 1134e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj } 1135e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1136e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* General-Purpose optional (fsqrt, fsqrts) */ 1137e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_FX = True; 11386c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1139e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_FX = False; 1140e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } else { 1141f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0 */ 1142e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } 1143e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1144e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* Graphics optional (stfiwx, fres, frsqrte, fsel) */ 1145e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_GX = True; 11466c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1147e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_GX = False; 1148e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } else { 1149f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0xFC000034"); /* frsqrte 0,0 */ 1150e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } 1151e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1152f34eb496099507090f26dcf94bb780da8b3894e5sewardj /* VSX support implies Power ISA 2.06 */ 1153f34eb496099507090f26dcf94bb780da8b3894e5sewardj have_VX = True; 1154f34eb496099507090f26dcf94bb780da8b3894e5sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1155f34eb496099507090f26dcf94bb780da8b3894e5sewardj have_VX = False; 1156f34eb496099507090f26dcf94bb780da8b3894e5sewardj } else { 1157f34eb496099507090f26dcf94bb780da8b3894e5sewardj __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp XT,XB */ 1158f34eb496099507090f26dcf94bb780da8b3894e5sewardj } 1159f34eb496099507090f26dcf94bb780da8b3894e5sewardj 11605ba075a1b629016370926fceacaf8e9155e1001csewardj /* Check for Decimal Floating Point (DFP) support. */ 11615ba075a1b629016370926fceacaf8e9155e1001csewardj have_DFP = True; 11625ba075a1b629016370926fceacaf8e9155e1001csewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 11635ba075a1b629016370926fceacaf8e9155e1001csewardj have_DFP = False; 11645ba075a1b629016370926fceacaf8e9155e1001csewardj } else { 11655ba075a1b629016370926fceacaf8e9155e1001csewardj __asm__ __volatile__(".long 0xee4e8005"); /* dadd FRT,FRA, FRB */ 11665ba075a1b629016370926fceacaf8e9155e1001csewardj } 1167f34eb496099507090f26dcf94bb780da8b3894e5sewardj 1168dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll /* Check for ISA 2.07 support. */ 1169dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll have_isa_2_07 = True; 1170dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1171dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll have_isa_2_07 = False; 1172dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll } else { 1173dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */ 1174dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll } 1175dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll 1176a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* Check for ISA 3.0 support. */ 1177a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_isa_3_0 = True; 1178a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1179a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_isa_3_0 = False; 1180a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 1181a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__(".long 0x7d205434"); /* cnttzw RT, RB */ 1182a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1183a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1184b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* determine dcbz/dcbzl sizes while we still have the signal 1185b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * handlers registered */ 1186b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj find_ppc_dcbz_sz(&vai); 1187b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 11881581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL); 11891581e745b8991508ef5243fd2d168790caf578e1bart vg_assert(r == 0); 11901581e745b8991508ef5243fd2d168790caf578e1bart r = VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL); 11917637e9e116e1b92f757993075d9b72ee36be9314sewardj vg_assert(r == 0); 11927637e9e116e1b92f757993075d9b72ee36be9314sewardj r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); 11937637e9e116e1b92f757993075d9b72ee36be9314sewardj vg_assert(r == 0); 1194a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d ISA3.0 %d\n", 1195f34eb496099507090f26dcf94bb780da8b3894e5sewardj (Int)have_F, (Int)have_V, (Int)have_FX, 1196dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll (Int)have_GX, (Int)have_VX, (Int)have_DFP, 1197a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes (Int)have_isa_2_07, (Int)have_isa_3_0); 1198e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* Make FP a prerequisite for VMX (bogusly so), and for FX and GX. */ 1199e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_V && !have_F) 1200e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_V = False; 1201e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_FX && !have_F) 1202e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_FX = False; 1203e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_GX && !have_F) 1204e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_GX = False; 1205e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1206e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj VG_(machine_ppc32_has_FP) = have_F ? 1 : 0; 1207e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj VG_(machine_ppc32_has_VMX) = have_V ? 1 : 0; 1208e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1209e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj va = VexArchPPC32; 1210597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessBE; 1211e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1212e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj vai.hwcaps = 0; 1213e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_F) vai.hwcaps |= VEX_HWCAPS_PPC32_F; 1214e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_V) vai.hwcaps |= VEX_HWCAPS_PPC32_V; 1215e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC32_FX; 1216e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC32_GX; 1217f34eb496099507090f26dcf94bb780da8b3894e5sewardj if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC32_VX; 12185ba075a1b629016370926fceacaf8e9155e1001csewardj if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC32_DFP; 1219dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA2_07; 1220a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (have_isa_3_0) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA3_0; 12215ba075a1b629016370926fceacaf8e9155e1001csewardj 12227862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 1223e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1224e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj /* But we're not done yet: VG_(machine_ppc32_set_clszB) must be 1225e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj called before we're ready to go. */ 1226e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj return True; 1227e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj } 1228e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 1229cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_ppc64be)|| defined(VGA_ppc64le) 12301581e745b8991508ef5243fd2d168790caf578e1bart { 12311581e745b8991508ef5243fd2d168790caf578e1bart /* Same instruction set detection algorithm as for ppc32. */ 1232cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigset_t saved_set, tmp_set; 1233cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act; 1234cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act; 12352c48c7b0a453d32375a4df17e153011b797ef28csewardj 12365ba075a1b629016370926fceacaf8e9155e1001csewardj volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP; 1237a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes volatile Bool have_isa_2_07, have_isa_3_0; 1238cda2f0fbda4c4b2644babc830244be8aed95de1dnjn Int r; 1239cda2f0fbda4c4b2644babc830244be8aed95de1dnjn 1240cda2f0fbda4c4b2644babc830244be8aed95de1dnjn /* This is a kludge. Really we ought to back-convert saved_act 1241cda2f0fbda4c4b2644babc830244be8aed95de1dnjn into a toK_t using VG_(convert_sigaction_fromK_to_toK), but 1242cda2f0fbda4c4b2644babc830244be8aed95de1dnjn since that's a no-op on all ppc64 platforms so far supported, 1243cda2f0fbda4c4b2644babc830244be8aed95de1dnjn it's not worth the typing effort. At least include most basic 1244cda2f0fbda4c4b2644babc830244be8aed95de1dnjn sanity check: */ 1245cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t)); 12462c48c7b0a453d32375a4df17e153011b797ef28csewardj 12472c48c7b0a453d32375a4df17e153011b797ef28csewardj VG_(sigemptyset)(&tmp_set); 12482c48c7b0a453d32375a4df17e153011b797ef28csewardj VG_(sigaddset)(&tmp_set, VKI_SIGILL); 12491581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaddset)(&tmp_set, VKI_SIGFPE); 12502c48c7b0a453d32375a4df17e153011b797ef28csewardj 1251cda2f0fbda4c4b2644babc830244be8aed95de1dnjn r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); 1252cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(r == 0); 12532c48c7b0a453d32375a4df17e153011b797ef28csewardj 1254cda2f0fbda4c4b2644babc830244be8aed95de1dnjn r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); 1255cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(r == 0); 12561581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act = saved_sigill_act; 12571581e745b8991508ef5243fd2d168790caf578e1bart 12581581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act); 12591581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act = saved_sigfpe_act; 12601581e745b8991508ef5243fd2d168790caf578e1bart 12617637e9e116e1b92f757993075d9b72ee36be9314sewardj /* NODEFER: signal handler does not return (from the kernel's point of 12627637e9e116e1b92f757993075d9b72ee36be9314sewardj view), hence if it is to successfully catch a signal more than once, 12637637e9e116e1b92f757993075d9b72ee36be9314sewardj we need the NODEFER flag. */ 12641581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; 12651581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; 12661581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; 12671581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigill_act.ksa_handler = handler_unsup_insn; 12681581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 12691581e745b8991508ef5243fd2d168790caf578e1bart 12701581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND; 12711581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO; 12721581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER; 12731581e745b8991508ef5243fd2d168790caf578e1bart tmp_sigfpe_act.ksa_handler = handler_unsup_insn; 12741581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL); 12752c48c7b0a453d32375a4df17e153011b797ef28csewardj 1276e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* standard FP insns */ 1277e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_F = True; 12786c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1279e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_F = False; 1280e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } else { 1281e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj __asm__ __volatile__("fmr 0,0"); 1282e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } 12832c48c7b0a453d32375a4df17e153011b797ef28csewardj 1284e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* Altivec insns */ 1285e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_V = True; 12866c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1287e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_V = False; 12882c48c7b0a453d32375a4df17e153011b797ef28csewardj } else { 1289f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/ 12902c48c7b0a453d32375a4df17e153011b797ef28csewardj } 12912c48c7b0a453d32375a4df17e153011b797ef28csewardj 1292e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* General-Purpose optional (fsqrt, fsqrts) */ 1293e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_FX = True; 12946c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1295e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_FX = False; 1296e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } else { 1297f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/ 1298e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } 1299e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1300e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj /* Graphics optional (stfiwx, fres, frsqrte, fsel) */ 1301e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_GX = True; 13026c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1303e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj have_GX = False; 1304e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } else { 1305f1c91e04aa395a74092e26da815dbde4d769ee0asewardj __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/ 1306e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj } 1307e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1308f34eb496099507090f26dcf94bb780da8b3894e5sewardj /* VSX support implies Power ISA 2.06 */ 1309f34eb496099507090f26dcf94bb780da8b3894e5sewardj have_VX = True; 1310f34eb496099507090f26dcf94bb780da8b3894e5sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1311f34eb496099507090f26dcf94bb780da8b3894e5sewardj have_VX = False; 1312f34eb496099507090f26dcf94bb780da8b3894e5sewardj } else { 1313f34eb496099507090f26dcf94bb780da8b3894e5sewardj __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp XT,XB */ 1314f34eb496099507090f26dcf94bb780da8b3894e5sewardj } 1315f34eb496099507090f26dcf94bb780da8b3894e5sewardj 13165ba075a1b629016370926fceacaf8e9155e1001csewardj /* Check for Decimal Floating Point (DFP) support. */ 13175ba075a1b629016370926fceacaf8e9155e1001csewardj have_DFP = True; 13185ba075a1b629016370926fceacaf8e9155e1001csewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 13195ba075a1b629016370926fceacaf8e9155e1001csewardj have_DFP = False; 13205ba075a1b629016370926fceacaf8e9155e1001csewardj } else { 13215ba075a1b629016370926fceacaf8e9155e1001csewardj __asm__ __volatile__(".long 0xee4e8005"); /* dadd FRT,FRA, FRB */ 13225ba075a1b629016370926fceacaf8e9155e1001csewardj } 13235ba075a1b629016370926fceacaf8e9155e1001csewardj 1324dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll /* Check for ISA 2.07 support. */ 1325dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll have_isa_2_07 = True; 1326dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1327dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll have_isa_2_07 = False; 1328dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll } else { 1329dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */ 1330dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll } 1331dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll 1332a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* Check for ISA 3.0 support. */ 1333a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_isa_3_0 = True; 1334a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1335a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_isa_3_0 = False; 1336a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 1337a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__(".long 0x7d205434"); /* cnttzw RT, RB */ 1338a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1339a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1340b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj /* determine dcbz/dcbzl sizes while we still have the signal 1341b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj * handlers registered */ 1342b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj find_ppc_dcbz_sz(&vai); 1343b9c815bb1cd57263ad0f081c27c88120d24ce4c5sewardj 13441581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL); 13451581e745b8991508ef5243fd2d168790caf578e1bart VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL); 13462c48c7b0a453d32375a4df17e153011b797ef28csewardj VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); 1347a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d ISA3.0 %d\n", 1348f34eb496099507090f26dcf94bb780da8b3894e5sewardj (Int)have_F, (Int)have_V, (Int)have_FX, 1349dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll (Int)have_GX, (Int)have_VX, (Int)have_DFP, 1350a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes (Int)have_isa_2_07, (int)have_isa_3_0); 1351cae0cc22b83ffb260ee8379e92099c5a701944cbcarll /* on ppc64be, if we don't even have FP, just give up. */ 1352e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (!have_F) 1353e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj return False; 1354e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1355e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj VG_(machine_ppc64_has_VMX) = have_V ? 1 : 0; 13562c48c7b0a453d32375a4df17e153011b797ef28csewardj 13572c48c7b0a453d32375a4df17e153011b797ef28csewardj va = VexArchPPC64; 1358582d58245637ab05272d89fb94b12fd0f18fa0f8carll# if defined(VKI_LITTLE_ENDIAN) 1359582d58245637ab05272d89fb94b12fd0f18fa0f8carll vai.endness = VexEndnessLE; 1360582d58245637ab05272d89fb94b12fd0f18fa0f8carll# elif defined(VKI_BIG_ENDIAN) 1361597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessBE; 1362582d58245637ab05272d89fb94b12fd0f18fa0f8carll# else 1363582d58245637ab05272d89fb94b12fd0f18fa0f8carll vai.endness = VexEndness_INVALID; 1364582d58245637ab05272d89fb94b12fd0f18fa0f8carll# endif 1365e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj 1366e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj vai.hwcaps = 0; 1367e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_V) vai.hwcaps |= VEX_HWCAPS_PPC64_V; 1368e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC64_FX; 1369e3121f30971a7a9a977a3f7d3649dbddd1a0f960sewardj if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC64_GX; 1370f34eb496099507090f26dcf94bb780da8b3894e5sewardj if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC64_VX; 13715ba075a1b629016370926fceacaf8e9155e1001csewardj if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC64_DFP; 1372dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA2_07; 1373a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (have_isa_3_0) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA3_0; 13742c48c7b0a453d32375a4df17e153011b797ef28csewardj 13757862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 13767862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 13772c48c7b0a453d32375a4df17e153011b797ef28csewardj /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be 13782c48c7b0a453d32375a4df17e153011b797ef28csewardj called before we're ready to go. */ 13792c48c7b0a453d32375a4df17e153011b797ef28csewardj return True; 13802c48c7b0a453d32375a4df17e153011b797ef28csewardj } 13812c48c7b0a453d32375a4df17e153011b797ef28csewardj 1382b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 1383df14eeae2e6abcd70a35e78321066107bf926227florian 1384f0c1250e324f6684757c6a15545366447ef1d64fsewardj# include "libvex_s390x_common.h" 1385df14eeae2e6abcd70a35e78321066107bf926227florian 1386b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 1387b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Instruction set detection code borrowed from ppc above. */ 1388b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vki_sigset_t saved_set, tmp_set; 1389b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vki_sigaction_fromK_t saved_sigill_act; 1390b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vki_sigaction_toK_t tmp_sigill_act; 1391b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1392df14eeae2e6abcd70a35e78321066107bf926227florian volatile Bool have_LDISP, have_STFLE; 1393df14eeae2e6abcd70a35e78321066107bf926227florian Int i, r, model; 1394df14eeae2e6abcd70a35e78321066107bf926227florian 1395df14eeae2e6abcd70a35e78321066107bf926227florian /* If the model is "unknown" don't treat this as an error. Assume 1396df14eeae2e6abcd70a35e78321066107bf926227florian this is a brand-new machine model for which we don't have the 1397df14eeae2e6abcd70a35e78321066107bf926227florian identification yet. Keeping fingers crossed. */ 1398df14eeae2e6abcd70a35e78321066107bf926227florian model = VG_(get_machine_model)(); 1399b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1400b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Unblock SIGILL and stash away the old action for that signal */ 1401b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(sigemptyset)(&tmp_set); 1402b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(sigaddset)(&tmp_set, VKI_SIGILL); 1403b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1404b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); 1405b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vg_assert(r == 0); 1406b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1407b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); 1408b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vg_assert(r == 0); 1409b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp_sigill_act = saved_sigill_act; 1410b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1411b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* NODEFER: signal handler does not return (from the kernel's point of 1412b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj view), hence if it is to successfully catch a signal more than once, 1413b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj we need the NODEFER flag. */ 1414b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; 1415b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; 1416b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; 1417b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp_sigill_act.ksa_handler = handler_unsup_insn; 1418b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 1419b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1420b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Determine hwcaps. Note, we cannot use the stfle insn because it 1421b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is not supported on z900. */ 1422b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1423b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj have_LDISP = True; 14246c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1425b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj have_LDISP = False; 1426b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } else { 1427b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* BASR loads the address of the next insn into r1. Needed to avoid 1428b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj a segfault in XY. */ 1429b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj __asm__ __volatile__("basr %%r1,%%r0\n\t" 1430b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ".long 0xe3001000\n\t" /* XY 0,0(%r1) */ 1431b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ".short 0x0057" : : : "r0", "r1", "cc", "memory"); 1432b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 1433b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 14343130eab8c67d0c720cb1a86906cc057daa9700ccflorian /* Check availability of STFLE. If available store facility bits 1435df14eeae2e6abcd70a35e78321066107bf926227florian in hoststfle. */ 1436df14eeae2e6abcd70a35e78321066107bf926227florian ULong hoststfle[S390_NUM_FACILITY_DW]; 1437b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1438df14eeae2e6abcd70a35e78321066107bf926227florian for (i = 0; i < S390_NUM_FACILITY_DW; ++i) 1439df14eeae2e6abcd70a35e78321066107bf926227florian hoststfle[i] = 0; 14401c6f6ab689f5f0ad3882cc12a4d9dd5a18a0a2a0sewardj 1441d19733c03aa442a5927770f327ee5ec4bd944a60florian have_STFLE = True; 1442d19733c03aa442a5927770f327ee5ec4bd944a60florian if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1443d19733c03aa442a5927770f327ee5ec4bd944a60florian have_STFLE = False; 1444d19733c03aa442a5927770f327ee5ec4bd944a60florian } else { 1445df14eeae2e6abcd70a35e78321066107bf926227florian register ULong reg0 asm("0") = S390_NUM_FACILITY_DW - 1; 1446d19733c03aa442a5927770f327ee5ec4bd944a60florian 1447d19733c03aa442a5927770f327ee5ec4bd944a60florian __asm__ __volatile__(" .insn s,0xb2b00000,%0\n" /* stfle */ 1448d19733c03aa442a5927770f327ee5ec4bd944a60florian : "=m" (hoststfle), "+d"(reg0) 1449d19733c03aa442a5927770f327ee5ec4bd944a60florian : : "cc", "memory"); 1450d19733c03aa442a5927770f327ee5ec4bd944a60florian } 1451d19733c03aa442a5927770f327ee5ec4bd944a60florian 1452b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Restore signals */ 1453b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL); 1454b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vg_assert(r == 0); 1455b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); 1456b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj vg_assert(r == 0); 14572c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj va = VexArchS390X; 1458597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessBE; 1459b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 14602c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj vai.hwcaps = model; 1461df14eeae2e6abcd70a35e78321066107bf926227florian if (have_STFLE) vai.hwcaps |= VEX_HWCAPS_S390X_STFLE; 14622c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (have_LDISP) { 1463df14eeae2e6abcd70a35e78321066107bf926227florian /* Use long displacement only on machines >= z990. For all other 1464df14eeae2e6abcd70a35e78321066107bf926227florian machines it is millicoded and therefore slow. */ 14652c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj if (model >= VEX_S390X_MODEL_Z990) 14662c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj vai.hwcaps |= VEX_HWCAPS_S390X_LDISP; 14672c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj } 1468b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1469df14eeae2e6abcd70a35e78321066107bf926227florian /* Detect presence of certain facilities using the STFLE insn. 1470df14eeae2e6abcd70a35e78321066107bf926227florian Note, that these facilities were introduced at the same time or later 1471df14eeae2e6abcd70a35e78321066107bf926227florian as STFLE, so the absence of STLFE implies the absence of the facility 1472df14eeae2e6abcd70a35e78321066107bf926227florian we're trying to detect. */ 1473df14eeae2e6abcd70a35e78321066107bf926227florian struct fac_hwcaps_map { 1474df14eeae2e6abcd70a35e78321066107bf926227florian UInt installed; 1475df14eeae2e6abcd70a35e78321066107bf926227florian UInt facility_bit; 1476df14eeae2e6abcd70a35e78321066107bf926227florian UInt hwcaps_bit; 1477df14eeae2e6abcd70a35e78321066107bf926227florian const HChar name[6]; // may need adjustment for new facility names 1478df14eeae2e6abcd70a35e78321066107bf926227florian } fac_hwcaps[] = { 1479df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_EIMM, VEX_HWCAPS_S390X_EIMM, "EIMM" }, 1480df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_GIE, VEX_HWCAPS_S390X_GIE, "GIE" }, 1481df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_DFP, VEX_HWCAPS_S390X_DFP, "DFP" }, 1482df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_FPSE, VEX_HWCAPS_S390X_FGX, "FGX" }, 1483df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_ETF2, VEX_HWCAPS_S390X_ETF2, "ETF2" }, 1484df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_ETF3, VEX_HWCAPS_S390X_ETF3, "ETF3" }, 1485df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_STCKF, VEX_HWCAPS_S390X_STCKF, "STCKF" }, 1486df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_FPEXT, VEX_HWCAPS_S390X_FPEXT, "FPEXT" }, 1487df14eeae2e6abcd70a35e78321066107bf926227florian { False, S390_FAC_LSC, VEX_HWCAPS_S390X_LSC, "LSC" }, 14881106692158e71bade4e00a2d21548e74b2ea334eflorian { False, S390_FAC_PFPO, VEX_HWCAPS_S390X_PFPO, "PFPO" }, 1489df14eeae2e6abcd70a35e78321066107bf926227florian }; 1490df14eeae2e6abcd70a35e78321066107bf926227florian 1491df14eeae2e6abcd70a35e78321066107bf926227florian /* Set hwcaps according to the detected facilities */ 1492df14eeae2e6abcd70a35e78321066107bf926227florian for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) { 1493df14eeae2e6abcd70a35e78321066107bf926227florian vg_assert(fac_hwcaps[i].facility_bit <= 63); // for now 1494df14eeae2e6abcd70a35e78321066107bf926227florian if (hoststfle[0] & (1ULL << (63 - fac_hwcaps[i].facility_bit))) { 1495df14eeae2e6abcd70a35e78321066107bf926227florian fac_hwcaps[i].installed = True; 1496df14eeae2e6abcd70a35e78321066107bf926227florian vai.hwcaps |= fac_hwcaps[i].hwcaps_bit; 1497df14eeae2e6abcd70a35e78321066107bf926227florian } 1498df14eeae2e6abcd70a35e78321066107bf926227florian } 1499df14eeae2e6abcd70a35e78321066107bf926227florian 1500df14eeae2e6abcd70a35e78321066107bf926227florian /* Build up a string showing the probed-for facilities */ 1501df14eeae2e6abcd70a35e78321066107bf926227florian HChar fac_str[(sizeof fac_hwcaps / sizeof fac_hwcaps[0]) * 1502df14eeae2e6abcd70a35e78321066107bf926227florian (sizeof fac_hwcaps[0].name + 3) + // %s %d 1503df14eeae2e6abcd70a35e78321066107bf926227florian 7 + 1 + 4 + 2 // machine %4d 1504df14eeae2e6abcd70a35e78321066107bf926227florian + 1]; // \0 1505df14eeae2e6abcd70a35e78321066107bf926227florian HChar *p = fac_str; 1506df14eeae2e6abcd70a35e78321066107bf926227florian p += VG_(sprintf)(p, "machine %4d ", model); 1507df14eeae2e6abcd70a35e78321066107bf926227florian for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) { 1508a7d291dabeedf369af475acec3478c82af33aa98florian p += VG_(sprintf)(p, " %s %1u", fac_hwcaps[i].name, 1509df14eeae2e6abcd70a35e78321066107bf926227florian fac_hwcaps[i].installed); 1510df14eeae2e6abcd70a35e78321066107bf926227florian } 1511df14eeae2e6abcd70a35e78321066107bf926227florian *p++ = '\0'; 1512df14eeae2e6abcd70a35e78321066107bf926227florian 1513df14eeae2e6abcd70a35e78321066107bf926227florian VG_(debugLog)(1, "machine", "%s\n", fac_str); 15142c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps); 15152c3f2ea57308833df5a7d463e9a649c8f6d1766fsewardj 15167862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 15177862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 1518b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return True; 1519b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 1520b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 152159570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(VGA_arm) 152259570ffbe31930ab4d678754daaeec0715117a3dsewardj { 15231dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* Same instruction set detection algorithm as for ppc32. */ 15241dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vki_sigset_t saved_set, tmp_set; 15251dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act; 15261dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act; 15271dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 1528a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes volatile Bool have_VFP, have_VFP2, have_VFP3, have_NEON, have_V8; 15291dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj volatile Int archlevel; 15301dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj Int r; 15311dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15321dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* This is a kludge. Really we ought to back-convert saved_act 15331dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj into a toK_t using VG_(convert_sigaction_fromK_to_toK), but 15341dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj since that's a no-op on all ppc64 platforms so far supported, 15351dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj it's not worth the typing effort. At least include most basic 15361dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj sanity check: */ 15371dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t)); 15381dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15391dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigemptyset)(&tmp_set); 15401dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaddset)(&tmp_set, VKI_SIGILL); 15411dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaddset)(&tmp_set, VKI_SIGFPE); 15421dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15431dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); 15441dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vg_assert(r == 0); 15451dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15461dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); 15471dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vg_assert(r == 0); 15481dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigill_act = saved_sigill_act; 15491dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15501dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act); 15511dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigfpe_act = saved_sigfpe_act; 15521dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15531dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* NODEFER: signal handler does not return (from the kernel's point of 15541dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj view), hence if it is to successfully catch a signal more than once, 15551dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj we need the NODEFER flag. */ 15561dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; 15571dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; 15581dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; 15591dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigill_act.ksa_handler = handler_unsup_insn; 15601dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 15611dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15621dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND; 15631dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO; 15641dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER; 15651dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj tmp_sigfpe_act.ksa_handler = handler_unsup_insn; 15661dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL); 15671dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15681dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* VFP insns */ 15691dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_VFP = True; 15706c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 15711dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_VFP = False; 15721dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } else { 15731dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj __asm__ __volatile__(".word 0xEEB02B42"); /* VMOV.F64 d2, d2 */ 15741dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 15751dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* There are several generation of VFP extension but they differs very 15761dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj little so for now we will not distinguish them. */ 15771dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_VFP2 = have_VFP; 15781dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_VFP3 = have_VFP; 15791dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15801dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* NEON insns */ 15811dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_NEON = True; 15826c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 15831dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj have_NEON = False; 15841dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } else { 15851dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj __asm__ __volatile__(".word 0xF2244154"); /* VMOV q2, q2 */ 15861dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 15871dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 15881dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj /* ARM architecture level */ 15891dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel = 5; /* v5 will be base level */ 15901dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (archlevel < 7) { 15911dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel = 7; 15926c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 15931dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel = 5; 15941dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } else { 15951dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj __asm__ __volatile__(".word 0xF45FF000"); /* PLI [PC,#-0] */ 15961dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 15971dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 15981dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (archlevel < 6) { 15991dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel = 6; 16006c591e15c1d6402a2a755310f005f795b68e7e38sewardj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 16011dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel = 5; 16021dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } else { 16031dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj __asm__ __volatile__(".word 0xE6822012"); /* PKHBT r2, r2, r2 */ 16041dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 16051dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj } 16061dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 1607a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* ARMv8 insns */ 1608a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_V8 = True; 1609a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (archlevel == 7) { 1610a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 1611a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes have_V8 = False; 1612a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 1613a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__(".word 0xF3044F54"); /* VMAXNM.F32 q2,q2,q2 */ 1614a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1615a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (have_V8 && have_NEON && have_VFP3) { 1616a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes archlevel = 8; 1617a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1618a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1619a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 16201dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act); 16211dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(convert_sigaction_fromK_to_toK)(&saved_sigfpe_act, &tmp_sigfpe_act); 16221dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 16231dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL); 16241dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); 16251dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 16261dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(debugLog)(1, "machine", "ARMv%d VFP %d VFP2 %d VFP3 %d NEON %d\n", 16271dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj archlevel, (Int)have_VFP, (Int)have_VFP2, (Int)have_VFP3, 16281dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj (Int)have_NEON); 16291dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 16301dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj VG_(machine_arm_archlevel) = archlevel; 16311dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 163259570ffbe31930ab4d678754daaeec0715117a3dsewardj va = VexArchARM; 1633597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 16341dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 16351dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj vai.hwcaps = VEX_ARM_ARCHLEVEL(archlevel); 16361dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (have_VFP3) vai.hwcaps |= VEX_HWCAPS_ARM_VFP3; 16371dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (have_VFP2) vai.hwcaps |= VEX_HWCAPS_ARM_VFP2; 16381dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (have_VFP) vai.hwcaps |= VEX_HWCAPS_ARM_VFP; 16391dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj if (have_NEON) vai.hwcaps |= VEX_HWCAPS_ARM_NEON; 16401dbd3376656236debf5d35a9b5d8a507a6c307f0sewardj 16417862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 16427862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 164359570ffbe31930ab4d678754daaeec0715117a3dsewardj return True; 164459570ffbe31930ab4d678754daaeec0715117a3dsewardj } 164559570ffbe31930ab4d678754daaeec0715117a3dsewardj 1646f0c1250e324f6684757c6a15545366447ef1d64fsewardj#elif defined(VGA_arm64) 1647f0c1250e324f6684757c6a15545366447ef1d64fsewardj { 1648f0c1250e324f6684757c6a15545366447ef1d64fsewardj va = VexArchARM64; 1649597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 1650f0c1250e324f6684757c6a15545366447ef1d64fsewardj 1651f0c1250e324f6684757c6a15545366447ef1d64fsewardj /* So far there are no variants. */ 1652f0c1250e324f6684757c6a15545366447ef1d64fsewardj vai.hwcaps = 0; 1653f0c1250e324f6684757c6a15545366447ef1d64fsewardj 1654f0c1250e324f6684757c6a15545366447ef1d64fsewardj VG_(machine_get_cache_info)(&vai); 1655f0c1250e324f6684757c6a15545366447ef1d64fsewardj 1656ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Check whether we need to use the fallback LLSC implementation. 1657ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes If the check fails, give up. */ 1658ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (! VG_(parse_cpuinfo)()) 1659ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return False; 1660ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 1661c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj /* 0 denotes 'not set'. The range of legitimate values here, 1662c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj after being set that is, is 2 though 17 inclusive. */ 1663c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj vg_assert(vai.arm64_dMinLine_lg2_szB == 0); 1664c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj vg_assert(vai.arm64_iMinLine_lg2_szB == 0); 1665c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj ULong ctr_el0; 1666c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj __asm__ __volatile__("mrs %0, ctr_el0" : "=r"(ctr_el0)); 1667c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj vai.arm64_dMinLine_lg2_szB = ((ctr_el0 >> 16) & 0xF) + 2; 1668c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj vai.arm64_iMinLine_lg2_szB = ((ctr_el0 >> 0) & 0xF) + 2; 1669c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj VG_(debugLog)(1, "machine", "ARM64: ctr_el0.dMinLine_szB = %d, " 1670c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj "ctr_el0.iMinLine_szB = %d\n", 1671c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj 1 << vai.arm64_dMinLine_lg2_szB, 1672c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj 1 << vai.arm64_iMinLine_lg2_szB); 1673ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VG_(debugLog)(1, "machine", "ARM64: requires_fallback_LLSC: %s\n", 1674ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes vai.arm64_requires_fallback_LLSC ? "yes" : "no"); 1675c76d0e5cf15d9a352c39a72867ae1c41875c6bb0sewardj 1676f0c1250e324f6684757c6a15545366447ef1d64fsewardj return True; 1677f0c1250e324f6684757c6a15545366447ef1d64fsewardj } 1678f0c1250e324f6684757c6a15545366447ef1d64fsewardj 16795db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(VGA_mips32) 16805db15403e889d4db339b342bc2a824ef0bfaa654sewardj { 168124f0c3a8f6ec94f3f374c41aae7ce3a3363300dbdejanj /* Define the position of F64 bit in FIR register. */ 168224f0c3a8f6ec94f3f374c41aae7ce3a3363300dbdejanj# define FP64 22 16835db15403e889d4db339b342bc2a824ef0bfaa654sewardj va = VexArchMIPS32; 1684a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (!VG_(parse_cpuinfo)()) 16855db15403e889d4db339b342bc2a824ef0bfaa654sewardj return False; 16865db15403e889d4db339b342bc2a824ef0bfaa654sewardj 1687597314210494248b4fbefd45525a748439629218sewardj# if defined(VKI_LITTLE_ENDIAN) 1688597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 1689597314210494248b4fbefd45525a748439629218sewardj# elif defined(VKI_BIG_ENDIAN) 1690597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessBE; 1691597314210494248b4fbefd45525a748439629218sewardj# else 1692597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndness_INVALID; 1693597314210494248b4fbefd45525a748439629218sewardj# endif 1694597314210494248b4fbefd45525a748439629218sewardj 16955f790e8e33278b242b52c6479c94ce279b88d82cdejanj /* Same instruction set detection algorithm as for ppc32/arm... */ 16965f790e8e33278b242b52c6479c94ce279b88d82cdejanj vki_sigset_t saved_set, tmp_set; 16975f790e8e33278b242b52c6479c94ce279b88d82cdejanj vki_sigaction_fromK_t saved_sigill_act; 16985f790e8e33278b242b52c6479c94ce279b88d82cdejanj vki_sigaction_toK_t tmp_sigill_act; 16995f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17005f790e8e33278b242b52c6479c94ce279b88d82cdejanj volatile Bool have_DSP, have_DSPr2; 17015f790e8e33278b242b52c6479c94ce279b88d82cdejanj Int r; 17025f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17035f790e8e33278b242b52c6479c94ce279b88d82cdejanj vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t)); 17045f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17055f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(sigemptyset)(&tmp_set); 17065f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(sigaddset)(&tmp_set, VKI_SIGILL); 17075f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17085f790e8e33278b242b52c6479c94ce279b88d82cdejanj r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); 17095f790e8e33278b242b52c6479c94ce279b88d82cdejanj vg_assert(r == 0); 17105f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17115f790e8e33278b242b52c6479c94ce279b88d82cdejanj r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); 17125f790e8e33278b242b52c6479c94ce279b88d82cdejanj vg_assert(r == 0); 17135f790e8e33278b242b52c6479c94ce279b88d82cdejanj tmp_sigill_act = saved_sigill_act; 17145f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17155f790e8e33278b242b52c6479c94ce279b88d82cdejanj /* NODEFER: signal handler does not return (from the kernel's point of 17165f790e8e33278b242b52c6479c94ce279b88d82cdejanj view), hence if it is to successfully catch a signal more than once, 17175f790e8e33278b242b52c6479c94ce279b88d82cdejanj we need the NODEFER flag. */ 17185f790e8e33278b242b52c6479c94ce279b88d82cdejanj tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; 17195f790e8e33278b242b52c6479c94ce279b88d82cdejanj tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; 17205f790e8e33278b242b52c6479c94ce279b88d82cdejanj tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; 17215f790e8e33278b242b52c6479c94ce279b88d82cdejanj tmp_sigill_act.ksa_handler = handler_unsup_insn; 17225f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 17235f790e8e33278b242b52c6479c94ce279b88d82cdejanj 1724a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (VEX_PRID_COMP_MIPS == VEX_MIPS_COMP_ID(vai.hwcaps)) { 172596ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj /* DSPr2 instructions. */ 172696ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj have_DSPr2 = True; 172796ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 172896ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj have_DSPr2 = False; 172996ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } else { 173096ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj __asm__ __volatile__(".word 0x7d095351"); /* precr.qb.ph t2, t0, t1 */ 173196ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } 173296ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj if (have_DSPr2) { 173396ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj /* We assume it's 74K, since it can run DSPr2. */ 173496ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj vai.hwcaps |= VEX_PRID_IMP_74K; 173596ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } else { 173696ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj /* DSP instructions. */ 173796ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj have_DSP = True; 173896ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj if (VG_MINIMAL_SETJMP(env_unsup_insn)) { 173996ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj have_DSP = False; 174096ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } else { 174196ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj __asm__ __volatile__(".word 0x7c3f44b8"); /* rddsp t0, 0x3f */ 174296ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } 174396ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj if (have_DSP) { 174496ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj /* We assume it's 34K, since it has support for DSP. */ 174596ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj vai.hwcaps |= VEX_PRID_IMP_34K; 174696ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } 174796ee38d38d27cf15b33b9f0b2985c0c0a56c3c33petarj } 17485f790e8e33278b242b52c6479c94ce279b88d82cdejanj } 17495f790e8e33278b242b52c6479c94ce279b88d82cdejanj 1750a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# if defined(VGP_mips32_linux) 1751ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Int fpmode = VG_(prctl)(VKI_PR_GET_FP_MODE, 0, 0, 0, 0); 1752a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# else 1753a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes Int fpmode = -1; 1754a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# endif 1755a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1756a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (fpmode < 0) { 1757a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* prctl(PR_GET_FP_MODE) is not supported by Kernel, 1758a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes we are using alternative way to determine FP mode */ 1759a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ULong result = 0; 1760a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1761a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (!VG_MINIMAL_SETJMP(env_unsup_insn)) { 1762a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ volatile ( 1763a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ".set push\n\t" 1764a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ".set noreorder\n\t" 1765a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ".set oddspreg\n\t" 1766a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ".set hardfloat\n\t" 1767a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "lui $t0, 0x3FF0\n\t" 1768a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldc1 $f0, %0\n\t" 1769a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "mtc1 $t0, $f1\n\t" 1770a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "sdc1 $f0, %0\n\t" 1771a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ".set pop\n\t" 1772a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes : "+m"(result) 1773a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes : 1774a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes : "t0", "$f0", "$f1", "memory"); 1775a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1776a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fpmode = (result != 0x3FF0000000000000ull); 1777a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 177824f0c3a8f6ec94f3f374c41aae7ce3a3363300dbdejanj } 177924f0c3a8f6ec94f3f374c41aae7ce3a3363300dbdejanj 1780a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (fpmode != 0) 1781a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_HOST_FR; 1782a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 17835f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act); 17845f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); 17855f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); 17865f790e8e33278b242b52c6479c94ce279b88d82cdejanj 17875f790e8e33278b242b52c6479c94ce279b88d82cdejanj VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps); 17887862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(machine_get_cache_info)(&vai); 17897862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 17905db15403e889d4db339b342bc2a824ef0bfaa654sewardj return True; 17915db15403e889d4db339b342bc2a824ef0bfaa654sewardj } 17925db15403e889d4db339b342bc2a824ef0bfaa654sewardj 17934df0bfc0614379192c780c944415dc420d9cfe8epetarj#elif defined(VGA_mips64) 17944df0bfc0614379192c780c944415dc420d9cfe8epetarj { 17954df0bfc0614379192c780c944415dc420d9cfe8epetarj va = VexArchMIPS64; 1796a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (!VG_(parse_cpuinfo)()) 17974df0bfc0614379192c780c944415dc420d9cfe8epetarj return False; 17984df0bfc0614379192c780c944415dc420d9cfe8epetarj 1799597314210494248b4fbefd45525a748439629218sewardj# if defined(VKI_LITTLE_ENDIAN) 1800597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessLE; 1801597314210494248b4fbefd45525a748439629218sewardj# elif defined(VKI_BIG_ENDIAN) 1802597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndnessBE; 1803597314210494248b4fbefd45525a748439629218sewardj# else 1804597314210494248b4fbefd45525a748439629218sewardj vai.endness = VexEndness_INVALID; 1805597314210494248b4fbefd45525a748439629218sewardj# endif 1806597314210494248b4fbefd45525a748439629218sewardj 1807a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes vai.hwcaps |= VEX_MIPS_HOST_FR; 1808a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 18094df0bfc0614379192c780c944415dc420d9cfe8epetarj VG_(machine_get_cache_info)(&vai); 18104df0bfc0614379192c780c944415dc420d9cfe8epetarj 18114df0bfc0614379192c780c944415dc420d9cfe8epetarj return True; 18124df0bfc0614379192c780c944415dc420d9cfe8epetarj } 18134df0bfc0614379192c780c944415dc420d9cfe8epetarj 1814e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj#else 1815e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj# error "Unknown arch" 18167821e2ed55ac6c2303eb51a06bafd5baada2423dsewardj#endif 1817e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj} 1818e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 18191a59a921dbfe75f7535d9dff6b76ea43a5ed961aflorian/* Notify host cpu instruction cache line size. */ 1820e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj#if defined(VGA_ppc32) 1821e3826cfe34ec9a0caa570a0d15647b28711584a0sewardjvoid VG_(machine_ppc32_set_clszB)( Int szB ) 1822e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj{ 1823e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj vg_assert(hwcaps_done); 1824e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1825e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj /* Either the value must not have been set yet (zero) or we can 1826e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj tolerate it being set to the same value multiple times, as the 1827e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj stack scanning logic in m_main is a bit stupid. */ 1828353d8b829ea1a63c17d94388b1473e5b140e5ba8florian vg_assert(vai.ppc_icache_line_szB == 0 1829353d8b829ea1a63c17d94388b1473e5b140e5ba8florian || vai.ppc_icache_line_szB == szB); 1830e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1831643d501b0ac9478a58058952f367aef30e9b80b4sewardj vg_assert(szB == 16 || szB == 32 || szB == 64 || szB == 128); 1832353d8b829ea1a63c17d94388b1473e5b140e5ba8florian vai.ppc_icache_line_szB = szB; 1833e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj} 1834e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj#endif 1835e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj 1836e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj 18371a59a921dbfe75f7535d9dff6b76ea43a5ed961aflorian/* Notify host cpu instruction cache line size. */ 1838cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGA_ppc64be)|| defined(VGA_ppc64le) 18392c48c7b0a453d32375a4df17e153011b797ef28csewardjvoid VG_(machine_ppc64_set_clszB)( Int szB ) 18402c48c7b0a453d32375a4df17e153011b797ef28csewardj{ 18412c48c7b0a453d32375a4df17e153011b797ef28csewardj vg_assert(hwcaps_done); 18422c48c7b0a453d32375a4df17e153011b797ef28csewardj 18432c48c7b0a453d32375a4df17e153011b797ef28csewardj /* Either the value must not have been set yet (zero) or we can 18442c48c7b0a453d32375a4df17e153011b797ef28csewardj tolerate it being set to the same value multiple times, as the 18452c48c7b0a453d32375a4df17e153011b797ef28csewardj stack scanning logic in m_main is a bit stupid. */ 1846353d8b829ea1a63c17d94388b1473e5b140e5ba8florian vg_assert(vai.ppc_icache_line_szB == 0 1847353d8b829ea1a63c17d94388b1473e5b140e5ba8florian || vai.ppc_icache_line_szB == szB); 18482c48c7b0a453d32375a4df17e153011b797ef28csewardj 1849643d501b0ac9478a58058952f367aef30e9b80b4sewardj vg_assert(szB == 16 || szB == 32 || szB == 64 || szB == 128); 1850353d8b829ea1a63c17d94388b1473e5b140e5ba8florian vai.ppc_icache_line_szB = szB; 18512c48c7b0a453d32375a4df17e153011b797ef28csewardj} 18522c48c7b0a453d32375a4df17e153011b797ef28csewardj#endif 18532c48c7b0a453d32375a4df17e153011b797ef28csewardj 18542c48c7b0a453d32375a4df17e153011b797ef28csewardj 1855a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj/* Notify host's ability to handle NEON instructions. */ 1856a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj#if defined(VGA_arm) 1857a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardjvoid VG_(machine_arm_set_has_NEON)( Bool has_neon ) 1858a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj{ 1859a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj vg_assert(hwcaps_done); 1860a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj /* There's nothing else we can sanity check. */ 1861a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj 1862a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj if (has_neon) { 1863a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj vai.hwcaps |= VEX_HWCAPS_ARM_NEON; 1864a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj } else { 1865a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj vai.hwcaps &= ~VEX_HWCAPS_ARM_NEON; 1866a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj } 1867a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj} 1868a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj#endif 1869a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj 1870a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj 1871e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj/* Fetch host cpu info, once established. */ 1872e2d1e670d412ff85c824ba5c043161816b9e26bdsewardjvoid VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa, 1873e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj /*OUT*/VexArchInfo* pVai ) 1874e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj{ 1875e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj vg_assert(hwcaps_done); 1876e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj if (pVa) *pVa = va; 1877e3826cfe34ec9a0caa570a0d15647b28711584a0sewardj if (pVai) *pVai = vai; 1878e2d1e670d412ff85c824ba5c043161816b9e26bdsewardj} 18797821e2ed55ac6c2303eb51a06bafd5baada2423dsewardj 18807821e2ed55ac6c2303eb51a06bafd5baada2423dsewardj 188198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj/* Returns the size of the largest guest register that we will 188298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj simulate in this run. This depends on both the guest architecture 188398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj and on the specific capabilities we are simulating for that guest 188498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj (eg, AVX or non-AVX ?, for amd64). Should return either 4, 8, 16 188598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj or 32. General rule: if in doubt, return a value larger than 188698763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj reality. 188798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 188898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj This information is needed by Cachegrind and Callgrind to decide 188998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj what the minimum cache line size they are prepared to simulate is. 189098763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj Basically require that the minimum cache line size is at least as 189198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj large as the largest register that might get transferred to/from 189298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj memory, so as to guarantee that any such transaction can straddle 189398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj at most 2 cache lines. 189498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj*/ 189598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardjInt VG_(machine_get_size_of_largest_guest_register) ( void ) 189698763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj{ 189798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj vg_assert(hwcaps_done); 189898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* Once hwcaps_done is True, we can fish around inside va/vai to 189998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj find the information we need. */ 190098763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 190198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# if defined(VGA_x86) 190298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj vg_assert(va == VexArchX86); 190398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* We don't support AVX, so 32 is out. At the other end, even if 190498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj we don't support any SSE, the X87 can generate 10 byte 190598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj transfers, so let's say 16 to be on the safe side. Hence the 190698763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj answer is always 16. */ 190798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return 16; 190898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 190998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# elif defined(VGA_amd64) 191098763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* if AVX then 32 else 16 */ 191198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return (vai.hwcaps & VEX_HWCAPS_AMD64_AVX) ? 32 : 16; 191298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 191398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# elif defined(VGA_ppc32) 191498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* 8 if boring; 16 if signs of Altivec or other exotic stuff */ 191598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC32_V) return 16; 191698763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC32_VX) return 16; 191798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC32_DFP) return 16; 191898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return 8; 191998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 1920cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc64be) || defined(VGA_ppc64le) 192198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* 8 if boring; 16 if signs of Altivec or other exotic stuff */ 192298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC64_V) return 16; 192398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC64_VX) return 16; 192498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj if (vai.hwcaps & VEX_HWCAPS_PPC64_DFP) return 16; 192598763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return 8; 192698763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 192798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# elif defined(VGA_s390x) 192898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return 8; 192998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 193098763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# elif defined(VGA_arm) 193198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj /* Really it depends whether or not we have NEON, but let's just 193298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj assume we always do. */ 193398763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj return 16; 193498763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 1935f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGA_arm64) 1936f0c1250e324f6684757c6a15545366447ef1d64fsewardj /* ARM64 always has Neon, AFAICS. */ 1937f0c1250e324f6684757c6a15545366447ef1d64fsewardj return 16; 1938f0c1250e324f6684757c6a15545366447ef1d64fsewardj 19395db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 19405db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* The guest state implies 4, but that can't really be true, can 19415db15403e889d4db339b342bc2a824ef0bfaa654sewardj it? */ 19425db15403e889d4db339b342bc2a824ef0bfaa654sewardj return 8; 19435db15403e889d4db339b342bc2a824ef0bfaa654sewardj 19444df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips64) 19454df0bfc0614379192c780c944415dc420d9cfe8epetarj return 8; 19464df0bfc0614379192c780c944415dc420d9cfe8epetarj 194798763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# else 194898763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# error "Unknown arch" 194998763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj# endif 195098763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj} 195198763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 195298763d5a6ee3a05ac0ee8340c30ded34c2b08a6dsewardj 195353ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj// Given a pointer to a function as obtained by "& functionname" in C, 1954f1c91e04aa395a74092e26da815dbde4d769ee0asewardj// produce a pointer to the actual entry point for the function. 195553ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardjvoid* VG_(fnptr_to_fnentry)( void* f ) 195653ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj{ 19576e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \ 1958cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGP_arm_linux) || defined(VGO_darwin) \ 1959cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGP_ppc32_linux) || defined(VGP_ppc64le_linux) \ 19604df0bfc0614379192c780c944415dc420d9cfe8epetarj || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \ 1961112711afefcfcd43680c7c4aa8d38ef180e8811esewardj || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ 1962ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) 196353ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj return f; 1964cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGP_ppc64be_linux) 19656e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj /* ppc64-linux uses the AIX scheme, in which f is a pointer to a 19666e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj 3-word function descriptor, of which the first word is the entry 19676e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj address. */ 1968f1c91e04aa395a74092e26da815dbde4d769ee0asewardj UWord* descr = (UWord*)f; 196953ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj return (void*)(descr[0]); 19706e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 19716e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "Unknown platform" 19726e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 197353ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj} 197453ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj 1975f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--------------------------------------------------------------------*/ 1976f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--- end ---*/ 1977f536bbbd4bf2024926574c5ed99b3e6251c6ff44njn/*--------------------------------------------------------------------*/ 1978