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_arm_Architecture_arm_h
8 #define jit_arm_Architecture_arm_h
10 #include <limits.h>
11 #include <stdint.h>
13 #include "js/Utility.h"
15 // gcc appears to use __ARM_PCS_VFP to denote that the target is a hard-float target.
16 #if defined(__ARM_PCS_VFP)
17 #define JS_CODEGEN_ARM_HARDFP
18 #endif
20 namespace js {
21 namespace jit {
23 // In bytes: slots needed for potential memory->memory move spills.
24 // +8 for cycles
25 // +4 for gpr spills
26 // +8 for double spills
27 static const uint32_t ION_FRAME_SLACK_SIZE = 20;
29 // These offsets are specific to nunboxing, and capture offsets into the
30 // components of a js::Value.
31 static const int32_t NUNBOX32_TYPE_OFFSET = 4;
32 static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0;
34 static const uint32_t ShadowStackSpace = 0;
35 ////
36 // These offsets are related to bailouts.
37 ////
39 // Size of each bailout table entry. On arm, this is presently
40 // a single call (which is wrong!). the call clobbers lr.
41 // For now, I've dealt with this by ensuring that we never allocate to lr.
42 // it should probably be 8 bytes, a mov of an immediate into r12 (not
43 // allocated presently, or ever) followed by a branch to the apropriate code.
44 static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 4;
46 class Registers
47 {
48 public:
49 enum RegisterID {
50 r0 = 0,
51 r1,
52 r2,
53 r3,
54 S0 = r3,
55 r4,
56 r5,
57 r6,
58 r7,
59 r8,
60 S1 = r8,
61 r9,
62 r10,
63 r11,
64 r12,
65 ip = r12,
66 r13,
67 sp = r13,
68 r14,
69 lr = r14,
70 r15,
71 pc = r15,
72 invalid_reg
73 };
74 typedef RegisterID Code;
76 static const char *GetName(Code code) {
77 static const char * const Names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "sp", "r14", "pc"};
79 return Names[code];
80 }
81 static const char *GetName(uint32_t i) {
82 MOZ_ASSERT(i < Total);
83 return GetName(Code(i));
84 }
86 static Code FromName(const char *name);
88 static const Code StackPointer = sp;
89 static const Code Invalid = invalid_reg;
91 static const uint32_t Total = 16;
92 static const uint32_t Allocatable = 13;
94 static const uint32_t AllMask = (1 << Total) - 1;
95 static const uint32_t ArgRegMask = (1 << r0) | (1 << r1) | (1 << r2) | (1 << r3);
97 static const uint32_t VolatileMask =
98 (1 << r0) |
99 (1 << r1) |
100 (1 << Registers::r2) |
101 (1 << Registers::r3);
103 static const uint32_t NonVolatileMask =
104 (1 << Registers::r4) |
105 (1 << Registers::r5) |
106 (1 << Registers::r6) |
107 (1 << Registers::r7) |
108 (1 << Registers::r8) |
109 (1 << Registers::r9) |
110 (1 << Registers::r10) |
111 (1 << Registers::r11) |
112 (1 << Registers::r12) |
113 (1 << Registers::r14);
115 static const uint32_t WrapperMask =
116 VolatileMask | // = arguments
117 (1 << Registers::r4) | // = outReg
118 (1 << Registers::r5); // = argBase
120 static const uint32_t SingleByteRegs =
121 VolatileMask | NonVolatileMask;
123 static const uint32_t NonAllocatableMask =
124 (1 << Registers::sp) |
125 (1 << Registers::r12) | // r12 = ip = scratch
126 (1 << Registers::lr) |
127 (1 << Registers::pc);
129 // Registers that can be allocated without being saved, generally.
130 static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
132 // Registers returned from a JS -> JS call.
133 static const uint32_t JSCallMask =
134 (1 << Registers::r2) |
135 (1 << Registers::r3);
137 // Registers returned from a JS -> C call.
138 static const uint32_t CallMask =
139 (1 << Registers::r0) |
140 (1 << Registers::r1); // used for double-size returns
142 static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
143 };
145 // Smallest integer type that can hold a register bitmask.
146 typedef uint16_t PackedRegisterMask;
148 class FloatRegisters
149 {
150 public:
151 enum FPRegisterID {
152 d0,
153 d1,
154 d2,
155 d3,
156 d4,
157 d5,
158 d6,
159 d7,
160 d8,
161 d9,
162 d10,
163 d11,
164 d12,
165 d13,
166 d14,
167 d15,
168 d16,
169 d17,
170 d18,
171 d19,
172 d20,
173 d21,
174 d22,
175 d23,
176 d24,
177 d25,
178 d26,
179 d27,
180 d28,
181 d29,
182 d30,
183 invalid_freg
184 };
185 typedef FPRegisterID Code;
187 static const char *GetName(Code code) {
188 static const char * const Names[] = { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
189 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"};
190 return Names[code];
191 }
192 static const char *GetName(uint32_t i) {
193 JS_ASSERT(i < Total);
194 return GetName(Code(i));
195 }
197 static Code FromName(const char *name);
199 static const Code Invalid = invalid_freg;
201 static const uint32_t Total = 16;
202 static const uint32_t Allocatable = 15;
204 static const uint32_t AllMask = (1 << Total) - 1;
206 // d15 is the ScratchFloatReg.
207 static const uint32_t NonVolatileMask =
208 (1 << d8) |
209 (1 << d9) |
210 (1 << d10) |
211 (1 << d11) |
212 (1 << d12) |
213 (1 << d13) |
214 (1 << d14);
216 static const uint32_t VolatileMask = AllMask & ~NonVolatileMask;
218 static const uint32_t WrapperMask = VolatileMask;
220 // d15 is the ARM scratch float register.
221 static const uint32_t NonAllocatableMask = (1 << d15) | (1 << invalid_freg);
223 // Registers that can be allocated without being saved, generally.
224 static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
226 static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
227 };
229 uint32_t GetARMFlags();
230 bool hasMOVWT();
231 bool hasVFPv3();
232 bool hasVFP();
233 bool has16DP();
234 bool hasIDIV();
236 // If the simulator is used then the ABI choice is dynamic. Otherwise the ABI is static
237 // and useHardFpABI is inlined so that unused branches can be optimized away.
238 #if defined(JS_ARM_SIMULATOR)
239 bool useHardFpABI();
240 #else
241 static inline bool useHardFpABI()
242 {
243 #if defined(JS_CODEGEN_ARM_HARDFP)
244 return true;
245 #else
246 return false;
247 #endif
248 }
249 #endif
251 } // namespace jit
252 } // namespace js
254 #endif /* jit_arm_Architecture_arm_h */