tor-browser

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

Architecture-arm64.cpp (5045B)


      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 #include "jit/arm64/Architecture-arm64.h"
      8 
      9 #include <cstring>
     10 
     11 #include "jit/arm64/vixl/Cpu-vixl.h"
     12 #include "jit/FlushICache.h"  // js::jit::FlushICache
     13 #include "jit/RegisterSets.h"
     14 
     15 namespace js {
     16 namespace jit {
     17 
     18 Registers::Code Registers::FromName(const char* name) {
     19  // Check for some register aliases first.
     20  if (strcmp(name, "ip0") == 0) {
     21    return ip0;
     22  }
     23  if (strcmp(name, "ip1") == 0) {
     24    return ip1;
     25  }
     26  if (strcmp(name, "fp") == 0) {
     27    return fp;
     28  }
     29 
     30  for (uint32_t i = 0; i < Total; i++) {
     31    if (strcmp(GetName(i), name) == 0) {
     32      return Code(i);
     33    }
     34  }
     35 
     36  return Invalid;
     37 }
     38 
     39 FloatRegisters::Code FloatRegisters::FromName(const char* name) {
     40  for (size_t i = 0; i < Total; i++) {
     41    if (strcmp(GetName(i), name) == 0) {
     42      return Code(i);
     43    }
     44  }
     45 
     46  return Invalid;
     47 }
     48 
     49 // This must sync with GetPushSizeInBytes just below and also with
     50 // MacroAssembler::PushRegsInMask.
     51 FloatRegisterSet FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) {
     52  SetType all = s.bits();
     53  SetType set128b =
     54      (all & FloatRegisters::AllSimd128Mask) >> FloatRegisters::ShiftSimd128;
     55  SetType doubleSet =
     56      (all & FloatRegisters::AllDoubleMask) >> FloatRegisters::ShiftDouble;
     57  SetType singleSet =
     58      (all & FloatRegisters::AllSingleMask) >> FloatRegisters::ShiftSingle;
     59 
     60  // See GetPushSizeInBytes.
     61  SetType set64b = (singleSet | doubleSet) & ~set128b;
     62 
     63  SetType reduced = (set128b << FloatRegisters::ShiftSimd128) |
     64                    (set64b << FloatRegisters::ShiftDouble);
     65  return FloatRegisterSet(reduced);
     66 }
     67 
     68 // Compute the size of the dump area for |s.ReduceSetForPush()|, as defined by
     69 // MacroAssembler::PushRegsInMask for this target.
     70 uint32_t FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) {
     71  SetType all = s.bits();
     72  SetType set128b =
     73      (all & FloatRegisters::AllSimd128Mask) >> FloatRegisters::ShiftSimd128;
     74  SetType doubleSet =
     75      (all & FloatRegisters::AllDoubleMask) >> FloatRegisters::ShiftDouble;
     76  SetType singleSet =
     77      (all & FloatRegisters::AllSingleMask) >> FloatRegisters::ShiftSingle;
     78 
     79  // PushRegsInMask pushes singles as if they were doubles.  Also we need to
     80  // remove singles or doubles which are also pushed as part of a vector
     81  // register.
     82  SetType set64b = (singleSet | doubleSet) & ~set128b;
     83 
     84  // The "+ 1) & ~1" is to take into account the alignment hole below the
     85  // double-reg dump area.  See MacroAssembler::PushRegsInMaskSizeInBytes.
     86  return ((set64b.size() + 1) & ~1) * sizeof(double) +
     87         set128b.size() * SizeOfSimd128;
     88 }
     89 
     90 uint32_t FloatRegister::getRegisterDumpOffsetInBytes() {
     91  // See block comment in MacroAssembler.h for further required invariants.
     92  static_assert(sizeof(jit::FloatRegisters::RegisterContent) == 16);
     93  return encoding() * sizeof(jit::FloatRegisters::RegisterContent);
     94 }
     95 
     96 // For N in 0..31, if any of sN, dN or qN is a member of `s`, the returned set
     97 // will contain all of sN, dN and qN.
     98 FloatRegisterSet FloatRegister::BroadcastToAllSizes(const FloatRegisterSet& s) {
     99  SetType all = s.bits();
    100  SetType set128b =
    101      (all & FloatRegisters::AllSimd128Mask) >> FloatRegisters::ShiftSimd128;
    102  SetType doubleSet =
    103      (all & FloatRegisters::AllDoubleMask) >> FloatRegisters::ShiftDouble;
    104  SetType singleSet =
    105      (all & FloatRegisters::AllSingleMask) >> FloatRegisters::ShiftSingle;
    106 
    107  SetType merged = set128b | doubleSet | singleSet;
    108  SetType broadcasted = (merged << FloatRegisters::ShiftSimd128) |
    109                        (merged << FloatRegisters::ShiftDouble) |
    110                        (merged << FloatRegisters::ShiftSingle);
    111 
    112  return FloatRegisterSet(broadcasted);
    113 }
    114 
    115 void ARM64Flags::Init() {
    116  MOZ_RELEASE_ASSERT(!IsInitialized());
    117 
    118 #ifdef JS_SIMULATOR_ARM64
    119  // Enable all features for the Simulator.
    120  vixl::CPUFeatures cpu_features = vixl::CPUFeatures::All();
    121 #else
    122  vixl::CPUFeatures cpu_features = vixl::CPUFeatures::AArch64LegacyBaseline();
    123 
    124  // Enable all features reported as present by the operating system.
    125  cpu_features.Combine(vixl::CPUFeatures::InferFromOS());
    126 #endif
    127 
    128  // FP and Neon are required features and shouldn't be disabled.
    129  MOZ_ASSERT(!disabledFeatures.Has(vixl::CPUFeatures::kFP),
    130             "Disabling FP not allowed");
    131  MOZ_ASSERT(!disabledFeatures.Has(vixl::CPUFeatures::kNEON),
    132             "Disabling Neon not allowed");
    133 
    134  // Remove all features from |disabledFeatures|.
    135  features = cpu_features.Without(disabledFeatures);
    136 }
    137 
    138 bool CPUFlagsHaveBeenComputed() { return ARM64Flags::IsInitialized(); }
    139 
    140 void FlushICache(void* code, size_t size) {
    141  vixl::CPU::EnsureIAndDCacheCoherency(code, size);
    142 }
    143 
    144 void FlushExecutionContext() { vixl::CPU::FlushExecutionContext(); }
    145 
    146 }  // namespace jit
    147 }  // namespace js