Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
7 #ifndef jit_mips_Architecture_mips_h
8 #define jit_mips_Architecture_mips_h
10 #include <limits.h>
11 #include <stdint.h>
13 #include "js/Utility.h"
15 // gcc appears to use _mips_hard_float to denote
16 // that the target is a hard-float target.
17 #ifdef _mips_hard_float
18 #define JS_CODEGEN_MIPS_HARDFP
19 #endif
20 namespace js {
21 namespace jit {
23 // Shadow stack space is not required on MIPS.
24 static const uint32_t ShadowStackSpace = 0;
26 // These offsets are specific to nunboxing, and capture offsets into the
27 // components of a js::Value.
28 // Size of MIPS32 general purpose registers is 32 bits.
29 static const int32_t NUNBOX32_TYPE_OFFSET = 4;
30 static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0;
32 // Size of each bailout table entry.
33 // For MIPS this is 2 instructions relative call.
34 static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 2 * sizeof(void *);
36 class Registers
37 {
38 public:
39 enum RegisterID {
40 r0 = 0,
41 r1,
42 r2,
43 r3,
44 r4,
45 r5,
46 r6,
47 r7,
48 r8,
49 r9,
50 r10,
51 r11,
52 r12,
53 r13,
54 r14,
55 r15,
56 r16,
57 r17,
58 r18,
59 r19,
60 r20,
61 r21,
62 r22,
63 r23,
64 r24,
65 r25,
66 r26,
67 r27,
68 r28,
69 r29,
70 r30,
71 r31,
72 zero = r0,
73 at = r1,
74 v0 = r2,
75 v1 = r3,
76 a0 = r4,
77 a1 = r5,
78 a2 = r6,
79 a3 = r7,
80 t0 = r8,
81 t1 = r9,
82 t2 = r10,
83 t3 = r11,
84 t4 = r12,
85 t5 = r13,
86 t6 = r14,
87 t7 = r15,
88 s0 = r16,
89 s1 = r17,
90 s2 = r18,
91 s3 = r19,
92 s4 = r20,
93 s5 = r21,
94 s6 = r22,
95 s7 = r23,
96 t8 = r24,
97 t9 = r25,
98 k0 = r26,
99 k1 = r27,
100 gp = r28,
101 sp = r29,
102 fp = r30,
103 ra = r31,
104 invalid_reg
105 };
106 typedef RegisterID Code;
108 static const char *GetName(Code code) {
109 static const char * const Names[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
110 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
111 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
112 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"};
113 return Names[code];
114 }
115 static const char *GetName(uint32_t i) {
116 JS_ASSERT(i < Total);
117 return GetName(Code(i));
118 }
120 static Code FromName(const char *name);
122 static const Code StackPointer = sp;
123 static const Code Invalid = invalid_reg;
125 static const uint32_t Total = 32;
126 static const uint32_t Allocatable = 14;
128 static const uint32_t AllMask = 0xffffffff;
129 static const uint32_t ArgRegMask = (1 << a0) | (1 << a1) | (1 << a2) | (1 << a3);
131 static const uint32_t VolatileMask =
132 (1 << Registers::v0) |
133 (1 << Registers::v1) |
134 (1 << Registers::a0) |
135 (1 << Registers::a1) |
136 (1 << Registers::a2) |
137 (1 << Registers::a3) |
138 (1 << Registers::t0) |
139 (1 << Registers::t1) |
140 (1 << Registers::t2) |
141 (1 << Registers::t3) |
142 (1 << Registers::t4) |
143 (1 << Registers::t5) |
144 (1 << Registers::t6) |
145 (1 << Registers::t7);
147 static const uint32_t NonVolatileMask =
148 (1 << Registers::s0) |
149 (1 << Registers::s1) |
150 (1 << Registers::s2) |
151 (1 << Registers::s3) |
152 (1 << Registers::s4) |
153 (1 << Registers::s5) |
154 (1 << Registers::s6) |
155 (1 << Registers::s7);
157 static const uint32_t WrapperMask =
158 VolatileMask | // = arguments
159 (1 << Registers::t0) | // = outReg
160 (1 << Registers::t1); // = argBase
162 static const uint32_t NonAllocatableMask =
163 (1 << Registers::zero) |
164 (1 << Registers::at) | // at = scratch
165 (1 << Registers::t8) | // t8 = scratch
166 (1 << Registers::t9) | // t9 = scratch
167 (1 << Registers::k0) |
168 (1 << Registers::k1) |
169 (1 << Registers::gp) |
170 (1 << Registers::sp) |
171 (1 << Registers::fp) |
172 (1 << Registers::ra);
174 // Registers that can be allocated without being saved, generally.
175 static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
177 // Registers returned from a JS -> JS call.
178 static const uint32_t JSCallMask =
179 (1 << Registers::v0) |
180 (1 << Registers::v1);
182 // Registers returned from a JS -> C call.
183 static const uint32_t CallMask =
184 (1 << Registers::v0) |
185 (1 << Registers::v1); // used for double-size returns
187 static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
188 };
190 // Smallest integer type that can hold a register bitmask.
191 typedef uint32_t PackedRegisterMask;
194 // MIPS32 can have two types of floating-point coprocessors:
195 // - 32 bit floating-point coprocessor - In this case, there are 32 single
196 // precision registers and pairs of even and odd float registers are used as
197 // double precision registers. Example: f0 (double) is composed of
198 // f0 and f1 (single).
199 // - 64 bit floating-point coprocessor - In this case, there are 32 double
200 // precision register which can also be used as single precision registers.
202 // When using O32 ABI, floating-point coprocessor is 32 bit
203 // When using N32 ABI, floating-point coprocessor is 64 bit.
204 class FloatRegisters
205 {
206 public:
207 enum FPRegisterID {
208 f0 = 0,
209 f1,
210 f2,
211 f3,
212 f4,
213 f5,
214 f6,
215 f7,
216 f8,
217 f9,
218 f10,
219 f11,
220 f12,
221 f13,
222 f14,
223 f15,
224 f16,
225 f17,
226 f18,
227 f19,
228 f20,
229 f21,
230 f22,
231 f23,
232 f24,
233 f25,
234 f26,
235 f27,
236 f28,
237 f29,
238 f30,
239 f31,
240 invalid_freg
241 };
242 typedef FPRegisterID Code;
244 static const char *GetName(Code code) {
245 static const char * const Names[] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
246 "f8", "f9", "f10", "f11", "f12", "f13",
247 "f14", "f15", "f16", "f17", "f18", "f19",
248 "f20", "f21", "f22", "f23", "f24", "f25",
249 "f26", "f27", "f28", "f29", "f30", "f31"};
250 return Names[code];
251 }
252 static const char *GetName(uint32_t i) {
253 JS_ASSERT(i < Total);
254 return GetName(Code(i));
255 }
257 static Code FromName(const char *name);
259 static const Code Invalid = invalid_freg;
261 static const uint32_t Total = 32;
262 // :TODO: (Bug 972836) // Fix this once odd regs can be used as float32
263 // only. For now we don't allocate odd regs for O32 ABI.
264 static const uint32_t Allocatable = 14;
266 static const uint32_t AllMask = 0xffffffff;
268 static const uint32_t VolatileMask =
269 (1 << FloatRegisters::f0) |
270 (1 << FloatRegisters::f2) |
271 (1 << FloatRegisters::f4) |
272 (1 << FloatRegisters::f6) |
273 (1 << FloatRegisters::f8) |
274 (1 << FloatRegisters::f10) |
275 (1 << FloatRegisters::f12) |
276 (1 << FloatRegisters::f14) |
277 (1 << FloatRegisters::f16) |
278 (1 << FloatRegisters::f18);
279 static const uint32_t NonVolatileMask =
280 (1 << FloatRegisters::f20) |
281 (1 << FloatRegisters::f22) |
282 (1 << FloatRegisters::f24) |
283 (1 << FloatRegisters::f26) |
284 (1 << FloatRegisters::f28) |
285 (1 << FloatRegisters::f30);
287 static const uint32_t WrapperMask = VolatileMask;
289 // :TODO: (Bug 972836) // Fix this once odd regs can be used as float32
290 // only. For now we don't allocate odd regs for O32 ABI.
291 static const uint32_t NonAllocatableMask =
292 (1 << FloatRegisters::f1) |
293 (1 << FloatRegisters::f3) |
294 (1 << FloatRegisters::f5) |
295 (1 << FloatRegisters::f7) |
296 (1 << FloatRegisters::f9) |
297 (1 << FloatRegisters::f11) |
298 (1 << FloatRegisters::f13) |
299 (1 << FloatRegisters::f15) |
300 (1 << FloatRegisters::f17) |
301 (1 << FloatRegisters::f19) |
302 (1 << FloatRegisters::f21) |
303 (1 << FloatRegisters::f23) |
304 (1 << FloatRegisters::f25) |
305 (1 << FloatRegisters::f27) |
306 (1 << FloatRegisters::f29) |
307 (1 << FloatRegisters::f31) |
308 // f18 and f16 are MIPS scratch float registers.
309 (1 << FloatRegisters::f16) |
310 (1 << FloatRegisters::f18);
312 // Registers that can be allocated without being saved, generally.
313 static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
315 static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
316 };
318 uint32_t GetMIPSFlags();
319 bool hasFPU();
321 } // namespace jit
322 } // namespace js
324 #endif /* jit_mips_Architecture_mips_h */