Bug 991153: Make the types for sets of registers a per-type quantity (r=jandem)

This commit is contained in:
Marty Rosenberg 2014-06-25 12:54:34 -04:00
parent 610472250c
commit 8652148c96
8 changed files with 186 additions and 6 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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();
};

View File

@ -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);
}

View File

@ -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)