Line data Source code
1 : #ifdef __PLUMED_HAS_ASMJIT
2 : // This file is part of AsmJit project <https://asmjit.com>
3 : //
4 : // See asmjit.h or LICENSE.md for license and copyright information
5 : // SPDX-License-Identifier: Zlib
6 :
7 : #include "api-build_p.h"
8 : #include "archtraits.h"
9 : #include "misc_p.h"
10 :
11 : #if !defined(ASMJIT_NO_X86)
12 : #include "x86archtraits_p.h"
13 : #endif
14 :
15 : #if !defined(ASMJIT_NO_AARCH64)
16 : #include "a64archtraits_p.h"
17 : #endif
18 :
19 : ASMJIT_BEGIN_NAMESPACE
20 :
21 : static const constexpr ArchTraits noArchTraits = {
22 : // SP/FP/LR/PC.
23 : 0xFF, 0xFF, 0xFF, 0xFF,
24 :
25 : // Reserved,
26 : { 0, 0, 0 },
27 :
28 : // HW stack alignment.
29 : 0,
30 :
31 : // Min/Max stack offset.
32 : 0, 0,
33 :
34 : // ISA features [Gp, Vec, Other0, Other1].
35 : {{
36 : InstHints::kNoHints,
37 : InstHints::kNoHints,
38 : InstHints::kNoHints,
39 : InstHints::kNoHints
40 : }},
41 :
42 : // RegTypeToSignature.
43 : #define V(index) OperandSignature{0}
44 : {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
45 : #undef V
46 :
47 : // RegTypeToTypeId.
48 : #define V(index) TypeId::kVoid
49 : {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
50 : #undef V
51 :
52 : // TypeIdToRegType.
53 : #define V(index) RegType::kNone
54 : {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
55 : #undef V
56 :
57 : // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
58 : {
59 : ArchTypeNameId::kByte,
60 : ArchTypeNameId::kHalf,
61 : ArchTypeNameId::kWord,
62 : ArchTypeNameId::kQuad
63 : }
64 : };
65 :
66 : ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1] = {
67 : // No architecture.
68 : noArchTraits,
69 :
70 : // X86/X86 architectures.
71 : #if !defined(ASMJIT_NO_X86)
72 : x86::x86ArchTraits,
73 : x86::x64ArchTraits,
74 : #else
75 : noArchTraits,
76 : noArchTraits,
77 : #endif
78 :
79 : // RISCV32/RISCV64 architectures.
80 : noArchTraits,
81 : noArchTraits,
82 :
83 : // ARM architecture
84 : noArchTraits,
85 :
86 : // AArch64 architecture.
87 : #if !defined(ASMJIT_NO_AARCH64)
88 : a64::a64ArchTraits,
89 : #else
90 : noArchTraits,
91 : #endif
92 :
93 : // ARM/Thumb architecture.
94 : noArchTraits,
95 :
96 : // Reserved.
97 : noArchTraits,
98 :
99 : // MIPS32/MIPS64
100 : noArchTraits,
101 : noArchTraits
102 : };
103 :
104 273777 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept {
105 : const ArchTraits& archTraits = ArchTraits::byArch(arch);
106 :
107 : // TODO: Remove this, should never be used like this.
108 : // Passed RegType instead of TypeId?
109 273777 : if (uint32_t(typeId) <= uint32_t(RegType::kMaxValue))
110 : typeId = archTraits.regTypeToTypeId(RegType(uint32_t(typeId)));
111 :
112 273777 : if (ASMJIT_UNLIKELY(!TypeUtils::isValid(typeId)))
113 : return DebugUtils::errored(kErrorInvalidTypeId);
114 :
115 : // First normalize architecture dependent types.
116 273777 : if (TypeUtils::isAbstract(typeId)) {
117 : bool is32Bit = Environment::is32Bit(arch);
118 78651 : if (typeId == TypeId::kIntPtr)
119 78651 : typeId = is32Bit ? TypeId::kInt32 : TypeId::kInt64;
120 : else
121 0 : typeId = is32Bit ? TypeId::kUInt32 : TypeId::kUInt64;
122 : }
123 :
124 : // Type size helps to construct all groups of registers.
125 : // TypeId is invalid if the size is zero.
126 : uint32_t size = TypeUtils::sizeOf(typeId);
127 273777 : if (ASMJIT_UNLIKELY(!size))
128 : return DebugUtils::errored(kErrorInvalidTypeId);
129 :
130 273777 : if (ASMJIT_UNLIKELY(typeId == TypeId::kFloat80))
131 : return DebugUtils::errored(kErrorInvalidUseOfF80);
132 :
133 : RegType regType = RegType::kNone;
134 : if (TypeUtils::isBetween(typeId, TypeId::_kBaseStart, TypeId::_kVec32Start)) {
135 78839 : regType = archTraits._typeIdToRegType[uint32_t(typeId) - uint32_t(TypeId::_kBaseStart)];
136 78839 : if (regType == RegType::kNone) {
137 0 : if (typeId == TypeId::kInt64 || typeId == TypeId::kUInt64)
138 : return DebugUtils::errored(kErrorInvalidUseOfGpq);
139 : else
140 : return DebugUtils::errored(kErrorInvalidTypeId);
141 : }
142 : }
143 : else {
144 194938 : if (size <= 8 && archTraits._regSignature[RegType::kVec64].isValid())
145 : regType = RegType::kVec64;
146 194938 : else if (size <= 16 && archTraits._regSignature[RegType::kVec128].isValid())
147 : regType = RegType::kVec128;
148 0 : else if (size == 32 && archTraits._regSignature[RegType::kVec256].isValid())
149 : regType = RegType::kVec256;
150 0 : else if (archTraits._regSignature[RegType::kVec512].isValid())
151 : regType = RegType::kVec512;
152 : else
153 : return DebugUtils::errored(kErrorInvalidTypeId);
154 : }
155 :
156 273777 : *typeIdOut = typeId;
157 273777 : *regSignatureOut = archTraits.regTypeToSignature(regType);
158 273777 : return kErrorOk;
159 : }
160 :
161 : ASMJIT_END_NAMESPACE
162 :
163 : #endif // __PLUMED_HAS_ASMJIT
|