js/src/jit/mips/Architecture-mips.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial