1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit/Registers.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,147 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jit_Registers_h 1.11 +#define jit_Registers_h 1.12 + 1.13 +#include "mozilla/Array.h" 1.14 + 1.15 +#include "jit/IonTypes.h" 1.16 +#if defined(JS_CODEGEN_X86) 1.17 +# include "jit/x86/Architecture-x86.h" 1.18 +#elif defined(JS_CODEGEN_X64) 1.19 +# include "jit/x64/Architecture-x64.h" 1.20 +#elif defined(JS_CODEGEN_ARM) 1.21 +# include "jit/arm/Architecture-arm.h" 1.22 +#elif defined(JS_CODEGEN_MIPS) 1.23 +# include "jit/mips/Architecture-mips.h" 1.24 +#else 1.25 +# error "Unknown architecture!" 1.26 +#endif 1.27 + 1.28 +namespace js { 1.29 +namespace jit { 1.30 + 1.31 +struct Register { 1.32 + typedef Registers Codes; 1.33 + typedef Codes::Code Code; 1.34 + Code code_; 1.35 + 1.36 + static Register FromCode(uint32_t i) { 1.37 + JS_ASSERT(i < Registers::Total); 1.38 + Register r = { (Registers::Code)i }; 1.39 + return r; 1.40 + } 1.41 + static Register FromName(const char *name) { 1.42 + Registers::Code code = Registers::FromName(name); 1.43 + Register r = { code }; 1.44 + return r; 1.45 + } 1.46 + Code code() const { 1.47 + JS_ASSERT((uint32_t)code_ < Registers::Total); 1.48 + return code_; 1.49 + } 1.50 + const char *name() const { 1.51 + return Registers::GetName(code()); 1.52 + } 1.53 + bool operator ==(const Register &other) const { 1.54 + return code_ == other.code_; 1.55 + } 1.56 + bool operator !=(const Register &other) const { 1.57 + return code_ != other.code_; 1.58 + } 1.59 + bool volatile_() const { 1.60 + return !!((1 << code()) & Registers::VolatileMask); 1.61 + } 1.62 +}; 1.63 + 1.64 +struct FloatRegister { 1.65 + typedef FloatRegisters Codes; 1.66 + typedef Codes::Code Code; 1.67 + 1.68 + Code code_; 1.69 + 1.70 + static FloatRegister FromCode(uint32_t i) { 1.71 + JS_ASSERT(i < FloatRegisters::Total); 1.72 + FloatRegister r = { (FloatRegisters::Code)i }; 1.73 + return r; 1.74 + } 1.75 + static FloatRegister FromName(const char *name) { 1.76 + FloatRegisters::Code code = FloatRegisters::FromName(name); 1.77 + FloatRegister r = { code }; 1.78 + return r; 1.79 + } 1.80 + Code code() const { 1.81 + JS_ASSERT((uint32_t)code_ < FloatRegisters::Total); 1.82 + return code_; 1.83 + } 1.84 + const char *name() const { 1.85 + return FloatRegisters::GetName(code()); 1.86 + } 1.87 + bool operator ==(const FloatRegister &other) const { 1.88 + return code_ == other.code_; 1.89 + } 1.90 + bool operator !=(const FloatRegister &other) const { 1.91 + return code_ != other.code_; 1.92 + } 1.93 + bool volatile_() const { 1.94 + return !!((1 << code()) & FloatRegisters::VolatileMask); 1.95 + } 1.96 +}; 1.97 + 1.98 +class RegisterDump 1.99 +{ 1.100 + protected: // Silence Clang warning. 1.101 + mozilla::Array<uintptr_t, Registers::Total> regs_; 1.102 + mozilla::Array<double, FloatRegisters::Total> fpregs_; 1.103 + 1.104 + public: 1.105 + static size_t offsetOfRegister(Register reg) { 1.106 + return offsetof(RegisterDump, regs_) + reg.code() * sizeof(uintptr_t); 1.107 + } 1.108 + static size_t offsetOfRegister(FloatRegister reg) { 1.109 + return offsetof(RegisterDump, fpregs_) + reg.code() * sizeof(double); 1.110 + } 1.111 +}; 1.112 + 1.113 +// Information needed to recover machine register state. 1.114 +class MachineState 1.115 +{ 1.116 + mozilla::Array<uintptr_t *, Registers::Total> regs_; 1.117 + mozilla::Array<double *, FloatRegisters::Total> fpregs_; 1.118 + 1.119 + public: 1.120 + static MachineState FromBailout(mozilla::Array<uintptr_t, Registers::Total> ®s, 1.121 + mozilla::Array<double, FloatRegisters::Total> &fpregs); 1.122 + 1.123 + void setRegisterLocation(Register reg, uintptr_t *up) { 1.124 + regs_[reg.code()] = up; 1.125 + } 1.126 + void setRegisterLocation(FloatRegister reg, double *dp) { 1.127 + fpregs_[reg.code()] = dp; 1.128 + } 1.129 + 1.130 + bool has(Register reg) const { 1.131 + return regs_[reg.code()] != nullptr; 1.132 + } 1.133 + bool has(FloatRegister reg) const { 1.134 + return fpregs_[reg.code()] != nullptr; 1.135 + } 1.136 + uintptr_t read(Register reg) const { 1.137 + return *regs_[reg.code()]; 1.138 + } 1.139 + double read(FloatRegister reg) const { 1.140 + return *fpregs_[reg.code()]; 1.141 + } 1.142 + void write(Register reg, uintptr_t value) const { 1.143 + *regs_[reg.code()] = value; 1.144 + } 1.145 +}; 1.146 + 1.147 +} // namespace jit 1.148 +} // namespace js 1.149 + 1.150 +#endif /* jit_Registers_h */