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