diff options
Diffstat (limited to 'js/src/jit/x86-shared/Architecture-x86-shared.cpp')
-rw-r--r-- | js/src/jit/x86-shared/Architecture-x86-shared.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/js/src/jit/x86-shared/Architecture-x86-shared.cpp b/js/src/jit/x86-shared/Architecture-x86-shared.cpp new file mode 100644 index 0000000000..f000b09c77 --- /dev/null +++ b/js/src/jit/x86-shared/Architecture-x86-shared.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/x86-shared/Architecture-x86-shared.h" +#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64) +# error "Wrong architecture. Only x86 and x64 should build this file!" +#endif + +#include <iterator> + +#include "jit/RegisterSets.h" + +const char* js::jit::FloatRegister::name() const { + static const char* const names[] = { + +#ifdef JS_CODEGEN_X64 +# define FLOAT_REGS_(TYPE) \ + "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, "%xmm4" TYPE, \ + "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, "%xmm8" TYPE, "%xmm9" TYPE, \ + "%xmm10" TYPE, "%xmm11" TYPE, "%xmm12" TYPE, "%xmm13" TYPE, \ + "%xmm14" TYPE, "%xmm15" TYPE +#else +# define FLOAT_REGS_(TYPE) \ + "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, "%xmm4" TYPE, \ + "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE +#endif + + // These should be enumerated in the same order as in + // FloatRegisters::ContentType. + FLOAT_REGS_(".s"), FLOAT_REGS_(".d"), FLOAT_REGS_(".i4"), + FLOAT_REGS_(".s4") +#undef FLOAT_REGS_ + + }; + MOZ_ASSERT(size_t(code()) < std::size(names)); + return names[size_t(code())]; +} + +js::jit::FloatRegisterSet js::jit::FloatRegister::ReduceSetForPush( + const FloatRegisterSet& s) { + SetType bits = s.bits(); + + // Ignore all SIMD register, if not supported. +#ifndef ENABLE_WASM_SIMD + bits &= Codes::AllPhysMask * Codes::SpreadScalar; +#endif + + // Exclude registers which are already pushed with a larger type. High bits + // are associated with larger register types. Thus we keep the set of + // registers which are not included in larger type. + bits &= ~(bits >> (1 * Codes::TotalPhys)); + bits &= ~(bits >> (2 * Codes::TotalPhys)); + bits &= ~(bits >> (3 * Codes::TotalPhys)); + + return FloatRegisterSet(bits); +} + +uint32_t js::jit::FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) { + SetType all = s.bits(); + SetType set128b = (all >> (uint32_t(Codes::Simd128) * Codes::TotalPhys)) & + Codes::AllPhysMask; + SetType doubleSet = (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & + Codes::AllPhysMask; + SetType singleSet = (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & + Codes::AllPhysMask; + + // PushRegsInMask pushes the largest register first, and thus avoids pushing + // aliased registers. So we have to filter out the physical registers which + // are already pushed as part of larger registers. + SetType set64b = doubleSet & ~set128b; + SetType set32b = singleSet & ~set64b & ~set128b; + + static_assert(Codes::AllPhysMask <= 0xffff, + "We can safely use CountPopulation32"); + uint32_t count32b = mozilla::CountPopulation32(set32b); + +#if defined(JS_CODEGEN_X64) + // If we have an odd number of 32 bits values, then we increase the size to + // keep the stack aligned on 8 bytes. Note: Keep in sync with + // PushRegsInMask, and PopRegsInMaskIgnore. + count32b += count32b & 1; +#endif + + return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t)) + + mozilla::CountPopulation32(set64b) * sizeof(double) + + count32b * sizeof(float); +} +uint32_t js::jit::FloatRegister::getRegisterDumpOffsetInBytes() { + return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent); +} |