Architecture-x86-shared.cpp (3654B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "jit/x86-shared/Architecture-x86-shared.h" 8 #if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64) 9 # error "Wrong architecture. Only x86 and x64 should build this file!" 10 #endif 11 12 #include "jit/RegisterSets.h" 13 14 const char* js::jit::FloatRegister::name() const { 15 static const char* const names[] = { 16 17 #ifdef JS_CODEGEN_X64 18 # define FLOAT_REGS_(TYPE) \ 19 "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, "%xmm4" TYPE, \ 20 "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, "%xmm8" TYPE, "%xmm9" TYPE, \ 21 "%xmm10" TYPE, "%xmm11" TYPE, "%xmm12" TYPE, "%xmm13" TYPE, \ 22 "%xmm14" TYPE, "%xmm15" TYPE 23 #else 24 # define FLOAT_REGS_(TYPE) \ 25 "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, "%xmm4" TYPE, \ 26 "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE 27 #endif 28 29 // These should be enumerated in the same order as in 30 // FloatRegisters::ContentType. 31 FLOAT_REGS_(".s"), FLOAT_REGS_(".d"), FLOAT_REGS_(".i4"), 32 FLOAT_REGS_(".s4") 33 #undef FLOAT_REGS_ 34 35 }; 36 MOZ_ASSERT(size_t(code()) < std::size(names)); 37 return names[size_t(code())]; 38 } 39 40 js::jit::FloatRegisterSet js::jit::FloatRegister::ReduceSetForPush( 41 const FloatRegisterSet& s) { 42 SetType bits = s.bits(); 43 44 // Ignore all SIMD register, if not supported. 45 #ifndef ENABLE_WASM_SIMD 46 bits &= Codes::AllPhysMask * Codes::SpreadScalar; 47 #endif 48 49 // Exclude registers which are already pushed with a larger type. High bits 50 // are associated with larger register types. Thus we keep the set of 51 // registers which are not included in larger type. 52 bits &= ~(bits >> (1 * Codes::TotalPhys)); 53 bits &= ~(bits >> (2 * Codes::TotalPhys)); 54 bits &= ~(bits >> (3 * Codes::TotalPhys)); 55 56 return FloatRegisterSet(bits); 57 } 58 59 uint32_t js::jit::FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) { 60 SetType all = s.bits(); 61 SetType set128b = (all >> (uint32_t(Codes::Simd128) * Codes::TotalPhys)) & 62 Codes::AllPhysMask; 63 SetType doubleSet = (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & 64 Codes::AllPhysMask; 65 SetType singleSet = (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & 66 Codes::AllPhysMask; 67 68 // PushRegsInMask pushes the largest register first, and thus avoids pushing 69 // aliased registers. So we have to filter out the physical registers which 70 // are already pushed as part of larger registers. 71 SetType set64b = doubleSet & ~set128b; 72 SetType set32b = singleSet & ~set64b & ~set128b; 73 74 static_assert(Codes::AllPhysMask <= 0xffff, 75 "We can safely use CountPopulation32"); 76 uint32_t count32b = mozilla::CountPopulation32(set32b); 77 78 #if defined(JS_CODEGEN_X64) 79 // If we have an odd number of 32 bits values, then we increase the size to 80 // keep the stack aligned on 8 bytes. Note: Keep in sync with 81 // PushRegsInMask, and PopRegsInMaskIgnore. 82 count32b += count32b & 1; 83 #endif 84 85 return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t)) + 86 mozilla::CountPopulation32(set64b) * sizeof(double) + 87 count32b * sizeof(float); 88 } 89 uint32_t js::jit::FloatRegister::getRegisterDumpOffsetInBytes() { 90 return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent); 91 }