|
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 #ifndef jit_Registers_h |
|
8 #define jit_Registers_h |
|
9 |
|
10 #include "mozilla/Array.h" |
|
11 |
|
12 #include "jit/IonTypes.h" |
|
13 #if defined(JS_CODEGEN_X86) |
|
14 # include "jit/x86/Architecture-x86.h" |
|
15 #elif defined(JS_CODEGEN_X64) |
|
16 # include "jit/x64/Architecture-x64.h" |
|
17 #elif defined(JS_CODEGEN_ARM) |
|
18 # include "jit/arm/Architecture-arm.h" |
|
19 #elif defined(JS_CODEGEN_MIPS) |
|
20 # include "jit/mips/Architecture-mips.h" |
|
21 #else |
|
22 # error "Unknown architecture!" |
|
23 #endif |
|
24 |
|
25 namespace js { |
|
26 namespace jit { |
|
27 |
|
28 struct Register { |
|
29 typedef Registers Codes; |
|
30 typedef Codes::Code Code; |
|
31 Code code_; |
|
32 |
|
33 static Register FromCode(uint32_t i) { |
|
34 JS_ASSERT(i < Registers::Total); |
|
35 Register r = { (Registers::Code)i }; |
|
36 return r; |
|
37 } |
|
38 static Register FromName(const char *name) { |
|
39 Registers::Code code = Registers::FromName(name); |
|
40 Register r = { code }; |
|
41 return r; |
|
42 } |
|
43 Code code() const { |
|
44 JS_ASSERT((uint32_t)code_ < Registers::Total); |
|
45 return code_; |
|
46 } |
|
47 const char *name() const { |
|
48 return Registers::GetName(code()); |
|
49 } |
|
50 bool operator ==(const Register &other) const { |
|
51 return code_ == other.code_; |
|
52 } |
|
53 bool operator !=(const Register &other) const { |
|
54 return code_ != other.code_; |
|
55 } |
|
56 bool volatile_() const { |
|
57 return !!((1 << code()) & Registers::VolatileMask); |
|
58 } |
|
59 }; |
|
60 |
|
61 struct FloatRegister { |
|
62 typedef FloatRegisters Codes; |
|
63 typedef Codes::Code Code; |
|
64 |
|
65 Code code_; |
|
66 |
|
67 static FloatRegister FromCode(uint32_t i) { |
|
68 JS_ASSERT(i < FloatRegisters::Total); |
|
69 FloatRegister r = { (FloatRegisters::Code)i }; |
|
70 return r; |
|
71 } |
|
72 static FloatRegister FromName(const char *name) { |
|
73 FloatRegisters::Code code = FloatRegisters::FromName(name); |
|
74 FloatRegister r = { code }; |
|
75 return r; |
|
76 } |
|
77 Code code() const { |
|
78 JS_ASSERT((uint32_t)code_ < FloatRegisters::Total); |
|
79 return code_; |
|
80 } |
|
81 const char *name() const { |
|
82 return FloatRegisters::GetName(code()); |
|
83 } |
|
84 bool operator ==(const FloatRegister &other) const { |
|
85 return code_ == other.code_; |
|
86 } |
|
87 bool operator !=(const FloatRegister &other) const { |
|
88 return code_ != other.code_; |
|
89 } |
|
90 bool volatile_() const { |
|
91 return !!((1 << code()) & FloatRegisters::VolatileMask); |
|
92 } |
|
93 }; |
|
94 |
|
95 class RegisterDump |
|
96 { |
|
97 protected: // Silence Clang warning. |
|
98 mozilla::Array<uintptr_t, Registers::Total> regs_; |
|
99 mozilla::Array<double, FloatRegisters::Total> fpregs_; |
|
100 |
|
101 public: |
|
102 static size_t offsetOfRegister(Register reg) { |
|
103 return offsetof(RegisterDump, regs_) + reg.code() * sizeof(uintptr_t); |
|
104 } |
|
105 static size_t offsetOfRegister(FloatRegister reg) { |
|
106 return offsetof(RegisterDump, fpregs_) + reg.code() * sizeof(double); |
|
107 } |
|
108 }; |
|
109 |
|
110 // Information needed to recover machine register state. |
|
111 class MachineState |
|
112 { |
|
113 mozilla::Array<uintptr_t *, Registers::Total> regs_; |
|
114 mozilla::Array<double *, FloatRegisters::Total> fpregs_; |
|
115 |
|
116 public: |
|
117 static MachineState FromBailout(mozilla::Array<uintptr_t, Registers::Total> ®s, |
|
118 mozilla::Array<double, FloatRegisters::Total> &fpregs); |
|
119 |
|
120 void setRegisterLocation(Register reg, uintptr_t *up) { |
|
121 regs_[reg.code()] = up; |
|
122 } |
|
123 void setRegisterLocation(FloatRegister reg, double *dp) { |
|
124 fpregs_[reg.code()] = dp; |
|
125 } |
|
126 |
|
127 bool has(Register reg) const { |
|
128 return regs_[reg.code()] != nullptr; |
|
129 } |
|
130 bool has(FloatRegister reg) const { |
|
131 return fpregs_[reg.code()] != nullptr; |
|
132 } |
|
133 uintptr_t read(Register reg) const { |
|
134 return *regs_[reg.code()]; |
|
135 } |
|
136 double read(FloatRegister reg) const { |
|
137 return *fpregs_[reg.code()]; |
|
138 } |
|
139 void write(Register reg, uintptr_t value) const { |
|
140 *regs_[reg.code()] = value; |
|
141 } |
|
142 }; |
|
143 |
|
144 } // namespace jit |
|
145 } // namespace js |
|
146 |
|
147 #endif /* jit_Registers_h */ |