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