michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_Registers_h michael@0: #define jit_Registers_h michael@0: michael@0: #include "mozilla/Array.h" michael@0: michael@0: #include "jit/IonTypes.h" michael@0: #if defined(JS_CODEGEN_X86) michael@0: # include "jit/x86/Architecture-x86.h" michael@0: #elif defined(JS_CODEGEN_X64) michael@0: # include "jit/x64/Architecture-x64.h" michael@0: #elif defined(JS_CODEGEN_ARM) michael@0: # include "jit/arm/Architecture-arm.h" michael@0: #elif defined(JS_CODEGEN_MIPS) michael@0: # include "jit/mips/Architecture-mips.h" michael@0: #else michael@0: # error "Unknown architecture!" michael@0: #endif michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: struct Register { michael@0: typedef Registers Codes; michael@0: typedef Codes::Code Code; michael@0: Code code_; michael@0: michael@0: static Register FromCode(uint32_t i) { michael@0: JS_ASSERT(i < Registers::Total); michael@0: Register r = { (Registers::Code)i }; michael@0: return r; michael@0: } michael@0: static Register FromName(const char *name) { michael@0: Registers::Code code = Registers::FromName(name); michael@0: Register r = { code }; michael@0: return r; michael@0: } michael@0: Code code() const { michael@0: JS_ASSERT((uint32_t)code_ < Registers::Total); michael@0: return code_; michael@0: } michael@0: const char *name() const { michael@0: return Registers::GetName(code()); michael@0: } michael@0: bool operator ==(const Register &other) const { michael@0: return code_ == other.code_; michael@0: } michael@0: bool operator !=(const Register &other) const { michael@0: return code_ != other.code_; michael@0: } michael@0: bool volatile_() const { michael@0: return !!((1 << code()) & Registers::VolatileMask); michael@0: } michael@0: }; michael@0: michael@0: struct FloatRegister { michael@0: typedef FloatRegisters Codes; michael@0: typedef Codes::Code Code; michael@0: michael@0: Code code_; michael@0: michael@0: static FloatRegister FromCode(uint32_t i) { michael@0: JS_ASSERT(i < FloatRegisters::Total); michael@0: FloatRegister r = { (FloatRegisters::Code)i }; michael@0: return r; michael@0: } michael@0: static FloatRegister FromName(const char *name) { michael@0: FloatRegisters::Code code = FloatRegisters::FromName(name); michael@0: FloatRegister r = { code }; michael@0: return r; michael@0: } michael@0: Code code() const { michael@0: JS_ASSERT((uint32_t)code_ < FloatRegisters::Total); michael@0: return code_; michael@0: } michael@0: const char *name() const { michael@0: return FloatRegisters::GetName(code()); michael@0: } michael@0: bool operator ==(const FloatRegister &other) const { michael@0: return code_ == other.code_; michael@0: } michael@0: bool operator !=(const FloatRegister &other) const { michael@0: return code_ != other.code_; michael@0: } michael@0: bool volatile_() const { michael@0: return !!((1 << code()) & FloatRegisters::VolatileMask); michael@0: } michael@0: }; michael@0: michael@0: class RegisterDump michael@0: { michael@0: protected: // Silence Clang warning. michael@0: mozilla::Array regs_; michael@0: mozilla::Array fpregs_; michael@0: michael@0: public: michael@0: static size_t offsetOfRegister(Register reg) { michael@0: return offsetof(RegisterDump, regs_) + reg.code() * sizeof(uintptr_t); michael@0: } michael@0: static size_t offsetOfRegister(FloatRegister reg) { michael@0: return offsetof(RegisterDump, fpregs_) + reg.code() * sizeof(double); michael@0: } michael@0: }; michael@0: michael@0: // Information needed to recover machine register state. michael@0: class MachineState michael@0: { michael@0: mozilla::Array regs_; michael@0: mozilla::Array fpregs_; michael@0: michael@0: public: michael@0: static MachineState FromBailout(mozilla::Array ®s, michael@0: mozilla::Array &fpregs); michael@0: michael@0: void setRegisterLocation(Register reg, uintptr_t *up) { michael@0: regs_[reg.code()] = up; michael@0: } michael@0: void setRegisterLocation(FloatRegister reg, double *dp) { michael@0: fpregs_[reg.code()] = dp; michael@0: } michael@0: michael@0: bool has(Register reg) const { michael@0: return regs_[reg.code()] != nullptr; michael@0: } michael@0: bool has(FloatRegister reg) const { michael@0: return fpregs_[reg.code()] != nullptr; michael@0: } michael@0: uintptr_t read(Register reg) const { michael@0: return *regs_[reg.code()]; michael@0: } michael@0: double read(FloatRegister reg) const { michael@0: return *fpregs_[reg.code()]; michael@0: } michael@0: void write(Register reg, uintptr_t value) const { michael@0: *regs_[reg.code()] = value; michael@0: } michael@0: }; michael@0: michael@0: } // namespace jit michael@0: } // namespace js michael@0: michael@0: #endif /* jit_Registers_h */