Bug 969375 - MIPS port: Added Architecture-mips files. r=nbp
☠☠ backed out by ba7c33c222c0 ☠ ☠
authorBranislav Rankov <branislav.rankov@imgtec.com>
Mon, 10 Feb 2014 11:13:06 +0100
changeset 167904 6ada8ee0e208c65c0c46ab5cad071db1f7798c9e
parent 167903 6f724675d1bcbefe7dc514513d17d27c8f3c0aba
child 167905 ba7c33c222c086bf1fc0ca0dc5f22ecef7a948d9
push id26191
push userryanvm@gmail.com
push dateMon, 10 Feb 2014 20:42:58 +0000
treeherdermozilla-central@d812f80a0f1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs969375
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 969375 - MIPS port: Added Architecture-mips files. r=nbp
js/src/jit/mips/Architecture-mips.cpp
js/src/jit/mips/Architecture-mips.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit/mips/Architecture-mips.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jit/mips/Architecture-mips.h"
+
+#include <elf.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "jit/mips/Assembler-mips.h"
+
+#define HWCAP_MIPS (1 << 31)
+#define HWCAP_FPU (1 << 0)
+
+namespace js {
+namespace jit {
+
+uint32_t GetMIPSFlags()
+{
+    static bool isSet = false;
+    static uint32_t flags = 0;
+    if (isSet)
+        return flags;
+#if WTF_OS_LINUX
+    FILE *fp = fopen("/proc/cpuinfo", "r");
+    if (!fp)
+        return false;
+
+    char buf[1024];
+    memset(buf, 0, sizeof(buf));
+    fread(buf, sizeof(char), sizeof(buf)-1, fp);
+    fclose(fp);
+    if (strstr(buf, "FPU"))
+        flags |= HWCAP_FPU;
+
+    isSet = true;
+    return flags;
+#endif
+
+    return false;
+}
+
+bool hasFPU()
+{
+    return js::jit::GetMIPSFlags() & HWCAP_FPU;
+}
+
+Registers::Code
+Registers::FromName(const char *name)
+{
+    for (size_t i = 0; i < Total; i++) {
+        if (strcmp(GetName(i), name) == 0)
+            return Code(i);
+    }
+
+    return Invalid;
+}
+
+FloatRegisters::Code
+FloatRegisters::FromName(const char *name)
+{
+    for (size_t i = 0; i < Total; i++) {
+        if (strcmp(GetName(i), name) == 0)
+            return Code(i);
+    }
+
+    return Invalid;
+}
+
+
+
+} // namespace ion
+} // namespace js
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit/mips/Architecture-mips.h
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef jit_mips_Architecture_mips_h
+#define jit_mips_Architecture_mips_h
+
+#include <limits.h>
+#include <stdint.h>
+
+#include "js/Utility.h"
+
+// gcc appears to use _mips_hard_float to denote
+// that the target is a hard-float target.
+#ifdef _mips_hard_float
+#define JS_CODEGEN_MIPS_HARDFP
+#endif
+namespace js {
+namespace jit {
+
+// Shadow stack space is not required on MIPS.
+static const uint32_t ShadowStackSpace = 0;
+
+// These offsets are specific to nunboxing, and capture offsets into the
+// components of a js::Value.
+// Size of MIPS32 general purpose registers is 32 bits.
+static const int32_t NUNBOX32_TYPE_OFFSET = 4;
+static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0;
+
+// Size of each bailout table entry.
+// For MIPS this is 2 instructions relative call.
+static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 2 * sizeof(void *);
+
+class Registers
+{
+  public:
+    enum RegisterID {
+        r0 = 0,
+        r1,
+        r2,
+        r3,
+        r4,
+        r5,
+        r6,
+        r7,
+        r8,
+        r9,
+        r10,
+        r11,
+        r12,
+        r13,
+        r14,
+        r15,
+        r16,
+        r17,
+        r18,
+        r19,
+        r20,
+        r21,
+        r22,
+        r23,
+        r24,
+        r25,
+        r26,
+        r27,
+        r28,
+        r29,
+        r30,
+        r31,
+        zero = r0,
+        at = r1,
+        v0 = r2,
+        v1 = r3,
+        a0 = r4,
+        a1 = r5,
+        a2 = r6,
+        a3 = r7,
+        t0 = r8,
+        t1 = r9,
+        t2 = r10,
+        t3 = r11,
+        t4 = r12,
+        t5 = r13,
+        t6 = r14,
+        t7 = r15,
+        s0 = r16,
+        s1 = r17,
+        s2 = r18,
+        s3 = r19,
+        s4 = r20,
+        s5 = r21,
+        s6 = r22,
+        s7 = r23,
+        t8 = r24,
+        t9 = r25,
+        k0 = r26,
+        k1 = r27,
+        gp = r28,
+        sp = r29,
+        fp = r30,
+        ra = r31,
+        invalid_reg
+    };
+    typedef RegisterID Code;
+
+    static const char *GetName(Code code) {
+        static const char * const Names[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+                                              "t0",   "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+                                              "s0",   "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+                                              "t8",   "t9", "k0", "k1", "gp", "sp", "fp", "ra"};
+        return Names[code];
+    }
+    static const char *GetName(uint32_t i) {
+        MOZ_ASSERT(i < Total);
+        return GetName(Code(i));
+    }
+
+    static Code FromName(const char *name);
+
+    static const Code StackPointer = sp;
+    static const Code Invalid = invalid_reg;
+
+    static const uint32_t Total = 32;
+    static const uint32_t Allocatable = 14;
+
+    static const uint32_t AllMask = 0xffffffff;
+    static const uint32_t ArgRegMask = (1 << a0) | (1 << a1) | (1 << a2) | (1 << a3);
+
+    static const uint32_t VolatileMask =
+        (1 << Registers::v0) |
+        (1 << Registers::v1) |
+        (1 << Registers::a0) |
+        (1 << Registers::a1) |
+        (1 << Registers::a2) |
+        (1 << Registers::a3) |
+        (1 << Registers::t0) |
+        (1 << Registers::t1) |
+        (1 << Registers::t2) |
+        (1 << Registers::t3) |
+        (1 << Registers::t4) |
+        (1 << Registers::t5) |
+        (1 << Registers::t6) |
+        (1 << Registers::t7);
+
+    static const uint32_t NonVolatileMask =
+        (1 << Registers::s0) |
+        (1 << Registers::s1) |
+        (1 << Registers::s2) |
+        (1 << Registers::s3) |
+        (1 << Registers::s4) |
+        (1 << Registers::s5) |
+        (1 << Registers::s6) |
+        (1 << Registers::s7);
+
+    static const uint32_t WrapperMask =
+        VolatileMask |         // = arguments
+        (1 << Registers::t0) | // = outReg
+        (1 << Registers::t1);  // = argBase
+
+    static const uint32_t NonAllocatableMask =
+        (1 << Registers::zero) |
+        (1 << Registers::at) | // at = scratch
+        (1 << Registers::t8) | // t8 = scratch
+        (1 << Registers::t9) | // t9 = scratch
+        (1 << Registers::k0) |
+        (1 << Registers::k1) |
+        (1 << Registers::gp) |
+        (1 << Registers::sp) |
+        (1 << Registers::fp) |
+        (1 << Registers::ra);
+
+    // Registers that can be allocated without being saved, generally.
+    static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
+
+    // Registers returned from a JS -> JS call.
+    static const uint32_t JSCallMask =
+        (1 << Registers::v0) |
+        (1 << Registers::v1);
+
+    // Registers returned from a JS -> C call.
+    static const uint32_t CallMask =
+        (1 << Registers::v0) |
+        (1 << Registers::v1);  // used for double-size returns
+
+    static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
+};
+
+// Smallest integer type that can hold a register bitmask.
+typedef uint32_t PackedRegisterMask;
+
+
+// MIPS32 uses pairs of even and odd float registers as double precision
+// registers. Example: f0 (double) is composed of f0 and f1 (single).
+// This port only uses even registers to avoid allocation problems.
+class FloatRegisters
+{
+  public:
+    enum FPRegisterID {
+        f0 = 0, // f0, f2 - Return values
+        f2,
+        f4, // f4 - f10, f16, f18 - Temporaries
+        f6,
+        f8,
+        f10,
+        f12, // f12, f14 - Arguments
+        f14,
+        f16,
+        f18,
+        f20, // f20 - f30 - Saved registers
+        f22,
+        f24,
+        f26,
+        f28,
+        f30,
+        invalid_freg
+    };
+    typedef FPRegisterID Code;
+
+    static const char *GetName(Code code) {
+        static const char * const Names[] = { "f0",  "f2",  "f4",  "f6",
+                                              "f8",  "f10", "f12", "f14",
+                                              "f16", "f18", "f20", "f22",
+                                              "f24", "f26", "f28", "f30"};
+        return Names[code];
+    }
+    static const char *GetName(uint32_t i) {
+        JS_ASSERT(i < Total);
+        return GetName(Code(i));
+    }
+
+    static Code FromName(const char *name);
+
+    static const Code Invalid = invalid_freg;
+
+    static const uint32_t Total = 16;
+    static const uint32_t Allocatable = 14;
+
+    static const uint32_t AllMask = 0xffff;
+
+    static const uint32_t VolatileMask =
+        (1 << FloatRegisters::f0) |
+        (1 << FloatRegisters::f2) |
+        (1 << FloatRegisters::f4) |
+        (1 << FloatRegisters::f6) |
+        (1 << FloatRegisters::f8) |
+        (1 << FloatRegisters::f10) |
+        (1 << FloatRegisters::f12) |
+        (1 << FloatRegisters::f14) |
+        (1 << FloatRegisters::f16) |
+        (1 << FloatRegisters::f18);
+    static const uint32_t NonVolatileMask =
+        (1 << FloatRegisters::f20) |
+        (1 << FloatRegisters::f22) |
+        (1 << FloatRegisters::f24) |
+        (1 << FloatRegisters::f26) |
+        (1 << FloatRegisters::f28) |
+        (1 << FloatRegisters::f30);
+
+    static const uint32_t WrapperMask = VolatileMask;
+
+    // f18 and f16 are MIPS scratch float registers.
+    static const uint32_t NonAllocatableMask =
+        (1 << f16) |
+        (1 << f18);
+
+    // Registers that can be allocated without being saved, generally.
+    static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
+
+    static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask;
+};
+
+uint32_t GetMIPSFlags();
+bool hasFPU();
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_mips_Architecture_mips_h */