Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2008-2017, Petr Kobalicek 3 : 4 : This software is provided 'as-is', without any express or implied 5 : warranty. In no event will the authors be held liable for any damages 6 : arising from the use of this software. 7 : 8 : Permission is granted to anyone to use this software for any purpose, 9 : including commercial applications, and to alter it and redistribute it 10 : freely, subject to the following restrictions: 11 : 12 : 1. The origin of this software must not be misrepresented; you must not 13 : claim that you wrote the original software. If you use this software 14 : in a product, an acknowledgment in the product documentation would be 15 : appreciated but is not required. 16 : 2. Altered source versions must be plainly marked as such, and must not be 17 : misrepresented as being the original software. 18 : 3. This notice may not be removed or altered from any source distribution. 19 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 20 : #ifdef __PLUMED_HAS_ASMJIT 21 : #pragma GCC diagnostic push 22 : #pragma GCC diagnostic ignored "-Wpedantic" 23 : // [AsmJit] 24 : // Complete x86/x64 JIT and Remote Assembler for C++. 25 : // 26 : // [License] 27 : // Zlib - See LICENSE.md file in the package. 28 : 29 : // [Export] 30 : #define ASMJIT_EXPORTS 31 : 32 : // [Dependencies] 33 : #include "./arch.h" 34 : 35 : #if defined(ASMJIT_BUILD_X86) 36 : #include "./x86operand.h" 37 : #endif // ASMJIT_BUILD_X86 38 : 39 : // [Api-Begin] 40 : #include "./asmjit_apibegin.h" 41 : 42 : namespace PLMD { 43 : namespace asmjit { 44 : 45 : // ============================================================================ 46 : // [asmjit::ArchInfo] 47 : // ============================================================================ 48 : 49 : static const uint32_t archInfoTable[] = { 50 : // <-------------+---------------------+-----------------------+-------+ 51 : // | Type | SubType | GPInfo| 52 : // <-------------+---------------------+-----------------------+-------+ 53 : ASMJIT_PACK32_4x8(ArchInfo::kTypeNone , ArchInfo::kSubTypeNone, 0, 0), 54 : ASMJIT_PACK32_4x8(ArchInfo::kTypeX86 , ArchInfo::kSubTypeNone, 4, 8), 55 : ASMJIT_PACK32_4x8(ArchInfo::kTypeX64 , ArchInfo::kSubTypeNone, 8, 16), 56 : ASMJIT_PACK32_4x8(ArchInfo::kTypeX32 , ArchInfo::kSubTypeNone, 8, 16), 57 : ASMJIT_PACK32_4x8(ArchInfo::kTypeA32 , ArchInfo::kSubTypeNone, 4, 16), 58 : ASMJIT_PACK32_4x8(ArchInfo::kTypeA64 , ArchInfo::kSubTypeNone, 8, 32) 59 : }; 60 : 61 69 : ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept { 62 69 : uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0); 63 : 64 : // Make sure the `archInfoTable` array is correctly indexed. 65 69 : _signature = archInfoTable[index]; 66 : ASMJIT_ASSERT(_type == index); 67 : 68 : // Even if the architecture is not known we setup its type and sub-type, 69 : // however, such architecture is not really useful. 70 69 : _type = type; 71 69 : _subType = subType; 72 69 : } 73 : 74 : // ============================================================================ 75 : // [asmjit::ArchUtils] 76 : // ============================================================================ 77 : 78 23740 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept { 79 23740 : uint32_t typeId = typeIdInOut; 80 : 81 : // Zero the signature so it's clear in case that typeId is not invalid. 82 23740 : regInfo._signature = 0; 83 : 84 : #if defined(ASMJIT_BUILD_X86) 85 23740 : if (ArchInfo::isX86Family(archType)) { 86 : // Passed RegType instead of TypeId? 87 23740 : if (typeId <= Reg::kRegMax) 88 0 : typeId = x86OpData.archRegs.regTypeToTypeId[typeId]; 89 : 90 23740 : if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId))) 91 : return DebugUtils::errored(kErrorInvalidTypeId); 92 : 93 : // First normalize architecture dependent types. 94 23740 : if (TypeId::isAbstract(typeId)) { 95 7248 : if (typeId == TypeId::kIntPtr) 96 7248 : typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kI32 : TypeId::kI64; 97 : else 98 0 : typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kU32 : TypeId::kU64; 99 : } 100 : 101 : // Type size helps to construct all kinds of registers. If the size is zero 102 : // then the TypeId is invalid. 103 : uint32_t size = TypeId::sizeOf(typeId); 104 23740 : if (ASMJIT_UNLIKELY(!size)) 105 : return DebugUtils::errored(kErrorInvalidTypeId); 106 : 107 23740 : if (ASMJIT_UNLIKELY(typeId == TypeId::kF80)) 108 : return DebugUtils::errored(kErrorInvalidUseOfF80); 109 : 110 : uint32_t regType = 0; 111 : 112 23740 : switch (typeId) { 113 : case TypeId::kI8: 114 : case TypeId::kU8: 115 : regType = X86Reg::kRegGpbLo; 116 : break; 117 : 118 0 : case TypeId::kI16: 119 : case TypeId::kU16: 120 : regType = X86Reg::kRegGpw; 121 0 : break; 122 : 123 0 : case TypeId::kI32: 124 : case TypeId::kU32: 125 : regType = X86Reg::kRegGpd; 126 0 : break; 127 : 128 7248 : case TypeId::kI64: 129 : case TypeId::kU64: 130 7248 : if (archType == ArchInfo::kTypeX86) 131 : return DebugUtils::errored(kErrorInvalidUseOfGpq); 132 : 133 : regType = X86Reg::kRegGpq; 134 : break; 135 : 136 : // F32 and F64 are always promoted to use vector registers. 137 0 : case TypeId::kF32: 138 : typeId = TypeId::kF32x1; 139 : regType = X86Reg::kRegXmm; 140 0 : break; 141 : 142 0 : case TypeId::kF64: 143 : typeId = TypeId::kF64x1; 144 : regType = X86Reg::kRegXmm; 145 0 : break; 146 : 147 : // Mask registers {k}. 148 0 : case TypeId::kMask8: 149 : case TypeId::kMask16: 150 : case TypeId::kMask32: 151 : case TypeId::kMask64: 152 : regType = X86Reg::kRegK; 153 0 : break; 154 : 155 : // MMX registers. 156 0 : case TypeId::kMmx32: 157 : case TypeId::kMmx64: 158 : regType = X86Reg::kRegMm; 159 0 : break; 160 : 161 : // XMM|YMM|ZMM registers. 162 16492 : default: 163 16492 : if (size <= 16) 164 : regType = X86Reg::kRegXmm; 165 0 : else if (size == 32) 166 : regType = X86Reg::kRegYmm; 167 : else 168 : regType = X86Reg::kRegZmm; 169 : break; 170 : } 171 : 172 23740 : typeIdInOut = typeId; 173 23740 : regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature(); 174 23740 : return kErrorOk; 175 : } 176 : #endif // ASMJIT_BUILD_X86 177 : 178 : return DebugUtils::errored(kErrorInvalidArch); 179 : } 180 : 181 : } // asmjit namespace 182 : } // namespace PLMD 183 : 184 : // [Api-End] 185 : #include "./asmjit_apiend.h" 186 : #pragma GCC diagnostic pop 187 : #endif // __PLUMED_HAS_ASMJIT