mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 991153: Make the types for sets of registers a per-type quantity (r=jandem)
This commit is contained in:
parent
610472250c
commit
8652148c96
@ -500,6 +500,15 @@ class TypedRegisterSet
|
||||
bool operator ==(const TypedRegisterSet<T> &other) const {
|
||||
return other.bits_ == bits_;
|
||||
}
|
||||
TypedRegisterSet<T> reduceSetForPush() const {
|
||||
return T::ReduceSetForPush(*this);
|
||||
}
|
||||
uint32_t getSizeInBytes() const {
|
||||
return T::GetSizeInBytes(*this);
|
||||
}
|
||||
uint32_t getPushSizeInBytes() const {
|
||||
return T::GetPushSizeInBytes(*this);
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedRegisterSet<Register> GeneralRegisterSet;
|
||||
|
@ -308,5 +308,52 @@ FloatRegisters::FromName(const char *name)
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
FloatRegisterSet
|
||||
VFPRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
FloatRegisterSet mod;
|
||||
for (TypedRegisterIterator<FloatRegister> iter(s); iter.more(); iter++) {
|
||||
if ((*iter).isSingle()) {
|
||||
// add in just this float
|
||||
mod.addUnchecked(*iter);
|
||||
} else if ((*iter).id() < 16) {
|
||||
// a double with an overlay, add in both floats
|
||||
mod.addUnchecked((*iter).singleOverlay(0));
|
||||
mod.addUnchecked((*iter).singleOverlay(1));
|
||||
} else {
|
||||
// add in the lone double in the range 16-31
|
||||
mod.addUnchecked(*iter);
|
||||
}
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
VFPRegister::GetSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
uint64_t bits = s.bits();
|
||||
uint32_t ret = mozilla::CountPopulation32(bits&0xffffffff) * sizeof(float);
|
||||
ret += mozilla::CountPopulation32(bits >> 32) * sizeof(double);
|
||||
return ret;
|
||||
}
|
||||
uint32_t
|
||||
VFPRegister::GetPushSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
FloatRegisterSet ss = s.reduceSetForPush();
|
||||
uint64_t bits = ss.bits();
|
||||
uint32_t ret = mozilla::CountPopulation32(bits&0xffffffff) * sizeof(float);
|
||||
ret += mozilla::CountPopulation32(bits >> 32) * sizeof(double);
|
||||
return ret;
|
||||
}
|
||||
uint32_t
|
||||
VFPRegister::getRegisterDumpOffsetInBytes()
|
||||
{
|
||||
if (isSingle())
|
||||
return id() * sizeof(float);
|
||||
if (isDouble())
|
||||
return id() * sizeof(double);
|
||||
MOZ_ASSUME_UNREACHABLE();
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef jit_arm_Architecture_arm_h
|
||||
#define jit_arm_Architecture_arm_h
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -140,6 +142,11 @@ class Registers
|
||||
(1 << Registers::r1); // used for double-size returns
|
||||
|
||||
static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
|
||||
typedef uint32_t SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
};
|
||||
|
||||
// Smallest integer type that can hold a register bitmask.
|
||||
@ -224,8 +231,12 @@ class FloatRegisters
|
||||
static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
|
||||
|
||||
static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
|
||||
typedef uint32_t SetType;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedRegisterSet;
|
||||
|
||||
class VFPRegister
|
||||
{
|
||||
public:
|
||||
@ -395,9 +406,19 @@ class VFPRegister
|
||||
*ret = doubleOverlay(aliasIdx - 1);
|
||||
return;
|
||||
}
|
||||
typedef FloatRegisters::SetType SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
static Code FromName(const char *name) {
|
||||
return FloatRegisters::FromName(name);
|
||||
}
|
||||
static TypedRegisterSet<VFPRegister> ReduceSetForPush(const TypedRegisterSet<VFPRegister> &s);
|
||||
static uint32_t GetSizeInBytes(const TypedRegisterSet<VFPRegister> &s);
|
||||
static uint32_t GetPushSizeInBytes(const TypedRegisterSet<VFPRegister> &s);
|
||||
uint32_t getRegisterDumpOffsetInBytes();
|
||||
|
||||
};
|
||||
|
||||
// The only floating point register set that we work with
|
||||
|
@ -27,7 +27,11 @@ static const uint32_t ShadowStackSpace = 0;
|
||||
class Registers {
|
||||
public:
|
||||
typedef JSC::X86Registers::RegisterID Code;
|
||||
|
||||
typedef uint32_t SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
static const char *GetName(Code code) {
|
||||
static const char * const Names[] = { "rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
@ -48,6 +52,7 @@ class Registers {
|
||||
static const Code Invalid = JSC::X86Registers::invalid_reg;
|
||||
|
||||
static const uint32_t Total = 16;
|
||||
static const uint32_t TotalPhys = 16;
|
||||
static const uint32_t Allocatable = 14;
|
||||
|
||||
static const uint32_t AllMask = (1 << Total) - 1;
|
||||
@ -115,7 +120,7 @@ typedef uint16_t PackedRegisterMask;
|
||||
class FloatRegisters {
|
||||
public:
|
||||
typedef JSC::X86Registers::XMMRegisterID Code;
|
||||
|
||||
typedef uint32_t SetType;
|
||||
static const char *GetName(Code code) {
|
||||
static const char * const Names[] = { "xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
@ -135,10 +140,12 @@ class FloatRegisters {
|
||||
static const Code Invalid = JSC::X86Registers::invalid_xmm;
|
||||
|
||||
static const uint32_t Total = 16;
|
||||
static const uint32_t TotalPhys = 16;
|
||||
|
||||
static const uint32_t Allocatable = 15;
|
||||
|
||||
static const uint32_t AllMask = (1 << Total) - 1;
|
||||
|
||||
static const uint32_t AllDoubleMask = AllMask;
|
||||
static const uint32_t VolatileMask =
|
||||
#if defined(_WIN64)
|
||||
(1 << JSC::X86Registers::xmm0) |
|
||||
@ -159,11 +166,20 @@ class FloatRegisters {
|
||||
(1 << JSC::X86Registers::xmm15); // This is ScratchFloatReg.
|
||||
|
||||
static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedRegisterSet;
|
||||
|
||||
struct FloatRegister {
|
||||
typedef FloatRegisters Codes;
|
||||
typedef Codes::Code Code;
|
||||
typedef Codes::SetType SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
|
||||
Code code_;
|
||||
|
||||
@ -215,6 +231,11 @@ struct FloatRegister {
|
||||
JS_ASSERT(aliasIdx == 0);
|
||||
*ret = *this;
|
||||
}
|
||||
static TypedRegisterSet<FloatRegister> ReduceSetForPush(const TypedRegisterSet<FloatRegister> &s);
|
||||
static uint32_t GetSizeInBytes(const TypedRegisterSet<FloatRegister> &s);
|
||||
static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister> &s);
|
||||
uint32_t getRegisterDumpOffsetInBytes();
|
||||
|
||||
};
|
||||
|
||||
// Arm/D32 has double registers that can NOT be treated as float32
|
||||
|
@ -263,3 +263,24 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade
|
||||
}
|
||||
}
|
||||
|
||||
FloatRegisterSet
|
||||
FloatRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
uint32_t
|
||||
FloatRegister::GetSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
uint32_t ret = s.size() * sizeof(double);
|
||||
return ret;
|
||||
}
|
||||
uint32_t
|
||||
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
return s.size() * sizeof(double);
|
||||
}
|
||||
uint32_t
|
||||
FloatRegister::getRegisterDumpOffsetInBytes()
|
||||
{
|
||||
return code() * sizeof(double);
|
||||
}
|
||||
|
@ -36,7 +36,11 @@ static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 5;
|
||||
class Registers {
|
||||
public:
|
||||
typedef JSC::X86Registers::RegisterID Code;
|
||||
|
||||
typedef uint8_t SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 1, "SetType must be 8 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
static const char *GetName(Code code) {
|
||||
static const char * const Names[] = { "eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi" };
|
||||
@ -55,6 +59,7 @@ class Registers {
|
||||
static const Code Invalid = JSC::X86Registers::invalid_reg;
|
||||
|
||||
static const uint32_t Total = 8;
|
||||
static const uint32_t TotalPhys = 8;
|
||||
static const uint32_t Allocatable = 7;
|
||||
|
||||
static const uint32_t AllMask = (1 << Total) - 1;
|
||||
@ -106,7 +111,7 @@ typedef uint8_t PackedRegisterMask;
|
||||
class FloatRegisters {
|
||||
public:
|
||||
typedef JSC::X86Registers::XMMRegisterID Code;
|
||||
|
||||
typedef uint32_t SetType;
|
||||
static const char *GetName(Code code) {
|
||||
static const char * const Names[] = { "xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7" };
|
||||
@ -124,10 +129,11 @@ class FloatRegisters {
|
||||
static const Code Invalid = JSC::X86Registers::invalid_xmm;
|
||||
|
||||
static const uint32_t Total = 8;
|
||||
static const uint32_t TotalPhys = 8;
|
||||
static const uint32_t Allocatable = 7;
|
||||
|
||||
static const uint32_t AllMask = (1 << Total) - 1;
|
||||
|
||||
static const uint32_t AllDoubleMask = AllMask;
|
||||
static const uint32_t VolatileMask = AllMask;
|
||||
static const uint32_t NonVolatileMask = 0;
|
||||
|
||||
@ -139,9 +145,17 @@ class FloatRegisters {
|
||||
static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedRegisterSet;
|
||||
|
||||
struct FloatRegister {
|
||||
typedef FloatRegisters Codes;
|
||||
typedef Codes::Code Code;
|
||||
typedef Codes::SetType SetType;
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
|
||||
Code code_;
|
||||
|
||||
@ -193,6 +207,11 @@ struct FloatRegister {
|
||||
JS_ASSERT(aliasIdx == 0);
|
||||
*ret = *this;
|
||||
}
|
||||
static TypedRegisterSet<FloatRegister> ReduceSetForPush(const TypedRegisterSet<FloatRegister> &s);
|
||||
static uint32_t GetSizeInBytes(const TypedRegisterSet<FloatRegister> &s);
|
||||
static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister> &s);
|
||||
uint32_t getRegisterDumpOffsetInBytes();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -90,3 +90,25 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FloatRegister::GetSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
uint32_t ret = s.size() * sizeof(double);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FloatRegisterSet
|
||||
FloatRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
uint32_t
|
||||
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
return s.size() * sizeof(double);
|
||||
}
|
||||
uint32_t
|
||||
FloatRegister::getRegisterDumpOffsetInBytes()
|
||||
{
|
||||
return code() * sizeof(double);
|
||||
}
|
||||
|
@ -188,6 +188,12 @@ CountPopulation32(uint32_t aValue)
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
return (((x + (x >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
|
||||
}
|
||||
inline uint_fast8_t
|
||||
CountPopulation64(uint64_t aValue)
|
||||
{
|
||||
return uint_fast8_t(CountPopulation32(aValue & 0xffffffff) +
|
||||
CountPopulation32(aValue >> 32));
|
||||
}
|
||||
|
||||
inline uint_fast8_t
|
||||
CountLeadingZeroes64(uint64_t aValue)
|
||||
@ -253,6 +259,12 @@ CountPopulation32(uint32_t aValue)
|
||||
return __builtin_popcount(aValue);
|
||||
}
|
||||
|
||||
inline uint_fast8_t
|
||||
CountPopulation64(uint64_t aValue)
|
||||
{
|
||||
return __builtin_popcountll(aValue);
|
||||
}
|
||||
|
||||
inline uint_fast8_t
|
||||
CountLeadingZeroes64(uint64_t aValue)
|
||||
{
|
||||
@ -270,6 +282,7 @@ CountTrailingZeroes64(uint64_t aValue)
|
||||
inline uint_fast8_t CountLeadingZeroes32(uint32_t aValue) MOZ_DELETE;
|
||||
inline uint_fast8_t CountTrailingZeroes32(uint32_t aValue) MOZ_DELETE;
|
||||
inline uint_fast8_t CountPopulation32(uint32_t aValue) MOZ_DELETE;
|
||||
inline uint_fast8_t CountPopulation64(uint64_t aValue) MOZ_DELETE;
|
||||
inline uint_fast8_t CountLeadingZeroes64(uint64_t aValue) MOZ_DELETE;
|
||||
inline uint_fast8_t CountTrailingZeroes64(uint64_t aValue) MOZ_DELETE;
|
||||
#endif
|
||||
@ -321,6 +334,13 @@ CountPopulation32(uint32_t aValue)
|
||||
return detail::CountPopulation32(aValue);
|
||||
}
|
||||
|
||||
/** Analogous to CoutPopulation32, but for 64-bit numbers */
|
||||
inline uint_fast8_t
|
||||
CountPopulation64(uint64_t aValue)
|
||||
{
|
||||
return detail::CountPopulation64(aValue);
|
||||
}
|
||||
|
||||
/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */
|
||||
inline uint_fast8_t
|
||||
CountLeadingZeroes64(uint64_t aValue)
|
||||
|
Loading…
Reference in New Issue
Block a user