tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Architecture-mips-shared.h (7863B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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_mips_shared_Architecture_mips_shared_h
      8 #define jit_mips_shared_Architecture_mips_shared_h
      9 
     10 #include "mozilla/MathAlgorithms.h"
     11 
     12 #include <algorithm>
     13 #include <limits.h>
     14 #include <stdint.h>
     15 
     16 #include "jit/shared/Architecture-shared.h"
     17 
     18 #include "js/Utility.h"
     19 
     20 #if defined(_MIPS_SIM)
     21 #  if (_MIPS_SIM != _ABI64)
     22 #    error "Unsupported ABI"
     23 #  endif
     24 #elif !defined(JS_SIMULATOR_MIPS64)
     25 #  error "Unknown ABI"
     26 #endif
     27 
     28 #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 6))
     29 #  define MIPSR6
     30 #endif
     31 
     32 namespace js {
     33 namespace jit {
     34 
     35 // How far forward/back can a jump go? Provide a generous buffer for thunks.
     36 static const uint32_t JumpImmediateRange = UINT32_MAX;
     37 
     38 class Registers {
     39 public:
     40  enum RegisterID {
     41    r0 = 0,
     42    r1,
     43    r2,
     44    r3,
     45    r4,
     46    r5,
     47    r6,
     48    r7,
     49    r8,
     50    r9,
     51    r10,
     52    r11,
     53    r12,
     54    r13,
     55    r14,
     56    r15,
     57    r16,
     58    r17,
     59    r18,
     60    r19,
     61    r20,
     62    r21,
     63    r22,
     64    r23,
     65    r24,
     66    r25,
     67    r26,
     68    r27,
     69    r28,
     70    r29,
     71    r30,
     72    r31,
     73    zero = r0,
     74    at = r1,
     75    v0 = r2,
     76    v1 = r3,
     77    a0 = r4,
     78    a1 = r5,
     79    a2 = r6,
     80    a3 = r7,
     81    a4 = r8,
     82    a5 = r9,
     83    a6 = r10,
     84    a7 = r11,
     85    t4 = r12,
     86    t5 = r13,
     87    t6 = r14,
     88    t7 = r15,
     89    ta0 = a4,
     90    ta1 = a5,
     91    ta2 = a6,
     92    ta3 = a7,
     93    s0 = r16,
     94    s1 = r17,
     95    s2 = r18,
     96    s3 = r19,
     97    s4 = r20,
     98    s5 = r21,
     99    s6 = r22,
    100    s7 = r23,
    101    t8 = r24,
    102    t9 = r25,
    103    k0 = r26,
    104    k1 = r27,
    105    gp = r28,
    106    sp = r29,
    107    fp = r30,
    108    ra = r31,
    109    invalid_reg
    110  };
    111  typedef uint8_t Code;
    112  typedef RegisterID Encoding;
    113 
    114  // Content spilled during bailouts.
    115  union RegisterContent {
    116    uintptr_t r;
    117  };
    118 
    119  static const char* const RegNames[];
    120  static const char* GetName(Code code) {
    121    MOZ_ASSERT(code < Total);
    122    return RegNames[code];
    123  }
    124  static const char* GetName(Encoding i) { return GetName(Code(i)); }
    125 
    126  static Code FromName(const char* name);
    127 
    128  static const Encoding StackPointer = sp;
    129  static const Encoding Invalid = invalid_reg;
    130 
    131  static const uint32_t Total = 32;
    132  static const uint32_t Allocatable;
    133 
    134  typedef uint32_t SetType;
    135  static const SetType AllMask = 0xffffffff;
    136  static const SetType SharedArgRegMask =
    137      (1 << a0) | (1 << a1) | (1 << a2) | (1 << a3);
    138  static const SetType ArgRegMask;
    139 
    140  static const SetType VolatileMask =
    141      (1 << Registers::v0) | (1 << Registers::v1) | (1 << Registers::a0) |
    142      (1 << Registers::a1) | (1 << Registers::a2) | (1 << Registers::a3) |
    143      (1 << Registers::a4) | (1 << Registers::a5) | (1 << Registers::a6) |
    144      (1 << Registers::a7) | (1 << Registers::t4) | (1 << Registers::t5) |
    145      (1 << Registers::t6) | (1 << Registers::t7) | (1 << Registers::t8) |
    146      (1 << Registers::t9);
    147 
    148  // We use this constant to save registers when entering functions. This
    149  // is why $ra is added here even though it is not "Non Volatile".
    150  static const SetType NonVolatileMask =
    151      (1 << Registers::s0) | (1 << Registers::s1) | (1 << Registers::s2) |
    152      (1 << Registers::s3) | (1 << Registers::s4) | (1 << Registers::s5) |
    153      (1 << Registers::s6) | (1 << Registers::s7) | (1 << Registers::fp) |
    154      (1 << Registers::ra);
    155 
    156  static const SetType WrapperMask = VolatileMask |          // = arguments
    157                                     (1 << Registers::t4) |  // = outReg
    158                                     (1 << Registers::t5);   // = argBase
    159 
    160  static const SetType NonAllocatableMask =
    161      (1 << Registers::zero) | (1 << Registers::at) |  // at = scratch
    162      (1 << Registers::t8) |                           // t8 = scratch
    163      (1 << Registers::t9) |                           // t9 = scratch or call
    164      (1 << Registers::k0) | (1 << Registers::k1) | (1 << Registers::gp) |
    165      (1 << Registers::sp) | (1 << Registers::ra) | (1 << Registers::fp);
    166 
    167  // Registers returned from a JS -> JS call.
    168  static const SetType JSCallMask;
    169 
    170  // Registers returned from a JS -> C call.
    171  static const SetType SharedCallMask = (1 << Registers::v0);
    172  static const SetType CallMask;
    173 
    174  static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
    175 
    176  static uint32_t SetSize(SetType x) {
    177    static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
    178    return mozilla::CountPopulation32(x);
    179  }
    180  static uint32_t FirstBit(SetType x) {
    181    return mozilla::CountTrailingZeroes32(x);
    182  }
    183  static uint32_t LastBit(SetType x) {
    184    return 31 - mozilla::CountLeadingZeroes32(x);
    185  }
    186 };
    187 
    188 // Smallest integer type that can hold a register bitmask.
    189 typedef uint32_t PackedRegisterMask;
    190 
    191 class FloatRegistersMIPSShared {
    192 public:
    193  enum FPRegisterID {
    194    f0 = 0,
    195    f1,
    196    f2,
    197    f3,
    198    f4,
    199    f5,
    200    f6,
    201    f7,
    202    f8,
    203    f9,
    204    f10,
    205    f11,
    206    f12,
    207    f13,
    208    f14,
    209    f15,
    210    f16,
    211    f17,
    212    f18,
    213    f19,
    214    f20,
    215    f21,
    216    f22,
    217    f23,
    218    f24,
    219    f25,
    220    f26,
    221    f27,
    222    f28,
    223    f29,
    224    f30,
    225    f31,
    226    invalid_freg
    227  };
    228  typedef uint32_t Code;
    229  typedef FPRegisterID Encoding;
    230 
    231  // Content spilled during bailouts.
    232  union RegisterContent {
    233    double d;
    234  };
    235 
    236  static const char* GetName(Encoding code) {
    237    static const char* const Names[] = {
    238        "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
    239        "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
    240        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
    241        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
    242    return Names[code];
    243  }
    244 
    245  static const Encoding Invalid = invalid_freg;
    246 
    247  typedef uint64_t SetType;
    248 };
    249 
    250 static const uint32_t SpillSlotSize =
    251    std::max(sizeof(Registers::RegisterContent),
    252             sizeof(FloatRegistersMIPSShared::RegisterContent));
    253 
    254 template <typename T>
    255 class TypedRegisterSet;
    256 
    257 class FloatRegisterMIPSShared {
    258 public:
    259  bool isSimd128() const { return false; }
    260 
    261  typedef FloatRegistersMIPSShared::SetType SetType;
    262 
    263  static uint32_t SetSize(SetType x) {
    264    static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
    265    return mozilla::CountPopulation64(x);
    266  }
    267  static uint32_t FirstBit(SetType x) {
    268    static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
    269    return mozilla::CountTrailingZeroes64(x);
    270  }
    271  static uint32_t LastBit(SetType x) {
    272    static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
    273    return 63 - mozilla::CountLeadingZeroes64(x);
    274  }
    275 };
    276 
    277 class MIPSFlags final {
    278  static inline bool initialized = false;
    279 
    280  static inline uint32_t flags = 0;
    281  static inline bool hasFPU = false;
    282  static inline bool hasR2 = false;
    283  static inline bool isLoongson = false;
    284 
    285 public:
    286  MIPSFlags() = delete;
    287 
    288  // MIPSFlags::Init is called from the JitContext constructor to read the
    289  // hardware flags. This method must only be called exactly once.
    290  static void Init();
    291 
    292  static bool IsInitialized() { return initialized; }
    293 
    294  static uint32_t GetFlags() {
    295    MOZ_ASSERT(IsInitialized());
    296    return flags;
    297  }
    298 
    299  static bool HasFPU() { return hasFPU; }
    300  static bool HasR2() { return hasR2; }
    301  static bool IsLoongson() { return isLoongson; }
    302 };
    303 
    304 inline uint32_t GetMIPSFlags() { return MIPSFlags::GetFlags(); }
    305 inline bool hasFPU() { return MIPSFlags::HasFPU(); }
    306 inline bool isLoongson() { return MIPSFlags::IsLoongson(); }
    307 inline bool hasR2() { return MIPSFlags::HasR2(); }
    308 
    309 // MIPS doesn't have double registers that can NOT be treated as float32.
    310 inline bool hasUnaliasedDouble() { return false; }
    311 
    312 // MIPS64 doesn't support it.
    313 inline bool hasMultiAlias() { return false; }
    314 
    315 }  // namespace jit
    316 }  // namespace js
    317 
    318 #endif /* jit_mips_shared_Architecture_mips_shared_h */