tor-browser

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

Architecture-mips-shared.cpp (2768B)


      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/mips-shared/Architecture-mips-shared.h"
      8 
      9 #include "jit/FlushICache.h"  // js::jit::FlushICache
     10 #include "jit/mips64/Simulator-mips64.h"
     11 #include "jit/RegisterSets.h"
     12 
     13 #if defined(__linux__)
     14 #  include <fcntl.h>
     15 #  include <unistd.h>
     16 
     17 #  if !defined(JS_SIMULATOR)
     18 #    include <sys/cachectl.h>
     19 #  endif
     20 #endif
     21 
     22 #define HWCAP_LOONGSON (1 << 27)
     23 #define HWCAP_R2 (1 << 26)
     24 #define HWCAP_FPU (1 << 0)
     25 
     26 namespace js {
     27 namespace jit {
     28 
     29 static uint32_t get_mips_flags() {
     30  uint32_t flags = 0;
     31 
     32 #if defined(JS_SIMULATOR_MIPS64)
     33  flags |= HWCAP_FPU;
     34  if (!getenv("MIPS_PRE_R2")) {
     35    flags |= HWCAP_R2;
     36  }
     37 #else
     38 #  ifdef __linux__
     39  FILE* fp = fopen("/proc/cpuinfo", "r");
     40  if (fp) {
     41    char buf[1024] = {};
     42    size_t len = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
     43    fclose(fp);
     44    buf[len] = 0;
     45    if (strstr(buf, "FPU")) {
     46      flags |= HWCAP_FPU;
     47    }
     48    if (strstr(buf, "Loongson")) {
     49      flags |= HWCAP_LOONGSON;
     50    }
     51    if (strstr(buf, "mips32r2") || strstr(buf, "mips64r2")) {
     52      flags |= HWCAP_R2;
     53    }
     54  }
     55 #  endif
     56 #endif  // JS_SIMULATOR_MIPS64
     57  return flags;
     58 }
     59 
     60 void MIPSFlags::Init() {
     61  MOZ_ASSERT(!IsInitialized());
     62 
     63  flags = get_mips_flags();
     64  hasFPU = flags & HWCAP_FPU;
     65  hasR2 = flags & HWCAP_R2;
     66  isLoongson = flags & HWCAP_LOONGSON;
     67  initialized = true;
     68 }
     69 
     70 bool CPUFlagsHaveBeenComputed() { return MIPSFlags::IsInitialized(); }
     71 
     72 Registers::Code Registers::FromName(const char* name) {
     73  for (size_t i = 0; i < Total; i++) {
     74    if (strcmp(GetName(i), name) == 0) {
     75      return Code(i);
     76    }
     77  }
     78 
     79  return Invalid;
     80 }
     81 
     82 void FlushICache(void* code, size_t size) {
     83 #if defined(JS_SIMULATOR)
     84  js::jit::SimulatorProcess::FlushICache(code, size);
     85 
     86 #elif defined(_MIPS_ARCH_LOONGSON3A)
     87  // On Loongson3-CPUs, The cache flushed automatically
     88  // by hardware. Just need to execute an instruction hazard.
     89  uintptr_t tmp;
     90  asm volatile(
     91      ".set   push \n"
     92      ".set   noreorder \n"
     93      "move   %[tmp], $ra \n"
     94      "bal    1f \n"
     95      "daddiu $ra, 8 \n"
     96      "1: \n"
     97      "jr.hb  $ra \n"
     98      "move   $ra, %[tmp] \n"
     99      ".set   pop\n"
    100      : [tmp] "=&r"(tmp));
    101 
    102 #elif defined(__GNUC__)
    103  intptr_t end = reinterpret_cast<intptr_t>(code) + size;
    104  __builtin___clear_cache(reinterpret_cast<char*>(code),
    105                          reinterpret_cast<char*>(end));
    106 
    107 #else
    108  _flush_cache(reinterpret_cast<char*>(code), size, BCACHE);
    109 
    110 #endif
    111 }
    112 
    113 }  // namespace jit
    114 }  // namespace js