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
init(uint32_t type,uint32_t subType)61 ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
62 uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
63
64 // Make sure the `archInfoTable` array is correctly indexed.
65 _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 _type = type;
71 _subType = subType;
72 }
73
74 // ============================================================================
75 // [asmjit::ArchUtils]
76 // ============================================================================
77
typeIdToRegInfo(uint32_t archType,uint32_t & typeIdInOut,RegInfo & regInfo)78 ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
79 uint32_t typeId = typeIdInOut;
80
81 // Zero the signature so it's clear in case that typeId is not invalid.
82 regInfo._signature = 0;
83
84 #if defined(ASMJIT_BUILD_X86)
85 if (ArchInfo::isX86Family(archType)) {
86 // Passed RegType instead of TypeId?
87 if (typeId <= Reg::kRegMax)
88 typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
89
90 if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
91 return DebugUtils::errored(kErrorInvalidTypeId);
92
93 // First normalize architecture dependent types.
94 if (TypeId::isAbstract(typeId)) {
95 if (typeId == TypeId::kIntPtr)
96 typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kI32 : TypeId::kI64;
97 else
98 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 if (ASMJIT_UNLIKELY(!size))
105 return DebugUtils::errored(kErrorInvalidTypeId);
106
107 if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
108 return DebugUtils::errored(kErrorInvalidUseOfF80);
109
110 uint32_t regType = 0;
111
112 switch (typeId) {
113 case TypeId::kI8:
114 case TypeId::kU8:
115 regType = X86Reg::kRegGpbLo;
116 break;
117
118 case TypeId::kI16:
119 case TypeId::kU16:
120 regType = X86Reg::kRegGpw;
121 break;
122
123 case TypeId::kI32:
124 case TypeId::kU32:
125 regType = X86Reg::kRegGpd;
126 break;
127
128 case TypeId::kI64:
129 case TypeId::kU64:
130 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 case TypeId::kF32:
138 typeId = TypeId::kF32x1;
139 regType = X86Reg::kRegXmm;
140 break;
141
142 case TypeId::kF64:
143 typeId = TypeId::kF64x1;
144 regType = X86Reg::kRegXmm;
145 break;
146
147 // Mask registers {k}.
148 case TypeId::kMask8:
149 case TypeId::kMask16:
150 case TypeId::kMask32:
151 case TypeId::kMask64:
152 regType = X86Reg::kRegK;
153 break;
154
155 // MMX registers.
156 case TypeId::kMmx32:
157 case TypeId::kMmx64:
158 regType = X86Reg::kRegMm;
159 break;
160
161 // XMM|YMM|ZMM registers.
162 default:
163 if (size <= 16)
164 regType = X86Reg::kRegXmm;
165 else if (size == 32)
166 regType = X86Reg::kRegYmm;
167 else
168 regType = X86Reg::kRegZmm;
169 break;
170 }
171
172 typeIdInOut = typeId;
173 regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
174 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
188