1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit/x64/Architecture-x64.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jit_x64_Architecture_x64_h 1.11 +#define jit_x64_Architecture_x64_h 1.12 + 1.13 +#include "assembler/assembler/MacroAssembler.h" 1.14 + 1.15 +namespace js { 1.16 +namespace jit { 1.17 + 1.18 +// In bytes: slots needed for potential memory->memory move spills. 1.19 +// +8 for cycles 1.20 +// +8 for gpr spills 1.21 +// +8 for double spills 1.22 +static const uint32_t ION_FRAME_SLACK_SIZE = 24; 1.23 + 1.24 +#ifdef _WIN64 1.25 +static const uint32_t ShadowStackSpace = 32; 1.26 +#else 1.27 +static const uint32_t ShadowStackSpace = 0; 1.28 +#endif 1.29 + 1.30 +class Registers { 1.31 + public: 1.32 + typedef JSC::X86Registers::RegisterID Code; 1.33 + 1.34 + static const char *GetName(Code code) { 1.35 + static const char * const Names[] = { "rax", "rcx", "rdx", "rbx", 1.36 + "rsp", "rbp", "rsi", "rdi", 1.37 + "r8", "r9", "r10", "r11", 1.38 + "r12", "r13", "r14", "r15" }; 1.39 + return Names[code]; 1.40 + } 1.41 + 1.42 + static Code FromName(const char *name) { 1.43 + for (size_t i = 0; i < Total; i++) { 1.44 + if (strcmp(GetName(Code(i)), name) == 0) 1.45 + return Code(i); 1.46 + } 1.47 + return Invalid; 1.48 + } 1.49 + 1.50 + static const Code StackPointer = JSC::X86Registers::esp; 1.51 + static const Code Invalid = JSC::X86Registers::invalid_reg; 1.52 + 1.53 + static const uint32_t Total = 16; 1.54 + static const uint32_t Allocatable = 14; 1.55 + 1.56 + static const uint32_t AllMask = (1 << Total) - 1; 1.57 + 1.58 + static const uint32_t ArgRegMask = 1.59 +# if !defined(_WIN64) 1.60 + (1 << JSC::X86Registers::edi) | 1.61 + (1 << JSC::X86Registers::esi) | 1.62 +# endif 1.63 + (1 << JSC::X86Registers::edx) | 1.64 + (1 << JSC::X86Registers::ecx) | 1.65 + (1 << JSC::X86Registers::r8) | 1.66 + (1 << JSC::X86Registers::r9); 1.67 + 1.68 + static const uint32_t VolatileMask = 1.69 + (1 << JSC::X86Registers::eax) | 1.70 + (1 << JSC::X86Registers::ecx) | 1.71 + (1 << JSC::X86Registers::edx) | 1.72 +# if !defined(_WIN64) 1.73 + (1 << JSC::X86Registers::esi) | 1.74 + (1 << JSC::X86Registers::edi) | 1.75 +# endif 1.76 + (1 << JSC::X86Registers::r8) | 1.77 + (1 << JSC::X86Registers::r9) | 1.78 + (1 << JSC::X86Registers::r10) | 1.79 + (1 << JSC::X86Registers::r11); 1.80 + 1.81 + static const uint32_t NonVolatileMask = 1.82 + (1 << JSC::X86Registers::ebx) | 1.83 +#if defined(_WIN64) 1.84 + (1 << JSC::X86Registers::esi) | 1.85 + (1 << JSC::X86Registers::edi) | 1.86 +#endif 1.87 + (1 << JSC::X86Registers::ebp) | 1.88 + (1 << JSC::X86Registers::r12) | 1.89 + (1 << JSC::X86Registers::r13) | 1.90 + (1 << JSC::X86Registers::r14) | 1.91 + (1 << JSC::X86Registers::r15); 1.92 + 1.93 + static const uint32_t WrapperMask = VolatileMask; 1.94 + 1.95 + static const uint32_t SingleByteRegs = VolatileMask | NonVolatileMask; 1.96 + 1.97 + static const uint32_t NonAllocatableMask = 1.98 + (1 << JSC::X86Registers::esp) | 1.99 + (1 << JSC::X86Registers::r11); // This is ScratchReg. 1.100 + 1.101 + // Registers that can be allocated without being saved, generally. 1.102 + static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask; 1.103 + 1.104 + static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask; 1.105 + 1.106 + // Registers returned from a JS -> JS call. 1.107 + static const uint32_t JSCallMask = 1.108 + (1 << JSC::X86Registers::ecx); 1.109 + 1.110 + // Registers returned from a JS -> C call. 1.111 + static const uint32_t CallMask = 1.112 + (1 << JSC::X86Registers::eax); 1.113 +}; 1.114 + 1.115 +// Smallest integer type that can hold a register bitmask. 1.116 +typedef uint16_t PackedRegisterMask; 1.117 + 1.118 +class FloatRegisters { 1.119 + public: 1.120 + typedef JSC::X86Registers::XMMRegisterID Code; 1.121 + 1.122 + static const char *GetName(Code code) { 1.123 + static const char * const Names[] = { "xmm0", "xmm1", "xmm2", "xmm3", 1.124 + "xmm4", "xmm5", "xmm6", "xmm7", 1.125 + "xmm8", "xmm9", "xmm10", "xmm11", 1.126 + "xmm12", "xmm13", "xmm14", "xmm15" }; 1.127 + return Names[code]; 1.128 + } 1.129 + 1.130 + static Code FromName(const char *name) { 1.131 + for (size_t i = 0; i < Total; i++) { 1.132 + if (strcmp(GetName(Code(i)), name) == 0) 1.133 + return Code(i); 1.134 + } 1.135 + return Invalid; 1.136 + } 1.137 + 1.138 + static const Code Invalid = JSC::X86Registers::invalid_xmm; 1.139 + 1.140 + static const uint32_t Total = 16; 1.141 + static const uint32_t Allocatable = 15; 1.142 + 1.143 + static const uint32_t AllMask = (1 << Total) - 1; 1.144 + 1.145 + static const uint32_t VolatileMask = 1.146 +#if defined(_WIN64) 1.147 + (1 << JSC::X86Registers::xmm0) | 1.148 + (1 << JSC::X86Registers::xmm1) | 1.149 + (1 << JSC::X86Registers::xmm2) | 1.150 + (1 << JSC::X86Registers::xmm3) | 1.151 + (1 << JSC::X86Registers::xmm4) | 1.152 + (1 << JSC::X86Registers::xmm5); 1.153 +#else 1.154 + AllMask; 1.155 +#endif 1.156 + 1.157 + static const uint32_t NonVolatileMask = AllMask & ~VolatileMask; 1.158 + 1.159 + static const uint32_t WrapperMask = VolatileMask; 1.160 + 1.161 + static const uint32_t NonAllocatableMask = 1.162 + (1 << JSC::X86Registers::xmm15); // This is ScratchFloatReg. 1.163 + 1.164 + static const uint32_t AllocatableMask = AllMask & ~NonAllocatableMask; 1.165 +}; 1.166 + 1.167 +} // namespace jit 1.168 +} // namespace js 1.169 + 1.170 +#endif /* jit_x64_Architecture_x64_h */