28 #ifndef __ARCH_ARM_AAPCS32_HH__
29 #define __ARCH_ARM_AAPCS32_HH__
33 #include <type_traits>
64 nsaa(tc->readIntReg(ArmISA::INTREG_SPX))
77 template <
typename T,
typename Enabled=
void>
82 (std::is_array<T>::value ||
83 std::is_class<T>::value ||
84 std::is_union<T>::value) &&
87 >> :
public std::true_type
95 template <
typename T, std::
size_t count,
typename Enabled=
void>
101 template <
typename E,
size_t N>
106 template <
typename T>
113 size_t align = std::max<size_t>(4,
alignof(T));
115 size_t size =
roundUp(
sizeof(T), 4);
136 template <
typename Integer>
138 std::is_integral<Integer>::value && (sizeof(Integer) < sizeof(uint32_t))>>
143 uint32_t
val = std::is_signed<Integer>::value ?
144 sext<sizeof(Integer) * 8>(
i) :
i;
149 template <
typename Integer>
151 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint32_t))>>
156 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)
i);
160 template <
typename Integer>
162 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint64_t))>>
168 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)(
i >> 0));
169 tc->
setIntReg(ArmISA::INTREG_R1, (uint32_t)(
i >> 32));
171 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)(
i >> 32));
172 tc->
setIntReg(ArmISA::INTREG_R1, (uint32_t)(
i >> 0));
177 template <
typename Integer>
179 std::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(uint32_t))
192 return loadFromStack<Integer>(tc, state);
196 template <
typename Integer>
198 std::is_integral<Integer>::value && (sizeof(Integer) > sizeof(uint32_t))
204 if (
alignof(Integer) == 8 && (state.
ncrn % 2))
207 if (
sizeof(Integer) ==
sizeof(uint64_t) &&
217 return low | (
high << 32);
223 return loadFromStack<Integer>(tc, state);
232 template <
typename Float>
234 std::is_floating_point<Float>::value>>
240 storeResult<Aapcs32, decltype(i)>(tc,
i, state);
244 template <
typename Float>
251 if (
sizeof(Float) ==
sizeof(uint32_t)) {
253 getArgument<Aapcs32, uint32_t>(tc, state));
256 getArgument<Aapcs32, uint64_t>(tc, state));
266 template <
typename Composite>
268 IsAapcs32Composite<Composite>::value>>
274 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
277 memcpy((
void *)&
val, (
void *)&cp,
sizeof(Composite));
289 if (
sizeof(Composite) >
sizeof(uint32_t))
294 template <
typename Composite>
296 IsAapcs32Composite<Composite>::value>> :
302 size_t bytes =
sizeof(Composite);
303 using Chunk = uint32_t;
305 const int chunk_size =
sizeof(Chunk);
306 const int regs = (bytes + chunk_size - 1) / chunk_size;
308 if (bytes <= chunk_size) {
310 alignas(
alignof(Composite)) uint32_t
val =
317 if (
alignof(Composite) == 8 && (state.
ncrn % 2))
321 alignas(
alignof(Composite)) uint8_t buf[bytes];
322 for (
int i = 0;
i < regs;
i++) {
325 size_t to_copy = std::min<size_t>(bytes, chunk_size);
326 memcpy(buf +
i * chunk_size, &
val, to_copy);
333 alignas(
alignof(Composite)) uint8_t buf[bytes];
339 size_t to_copy = std::min<size_t>(bytes, chunk_size);
358 return loadFromStack<Composite>(tc, state);
377 std::array<bool, 16>
s;
378 std::array<bool, 8>
d;
390 for (
int i = 0;
i <=
s.size() -
count;
i++) {
395 if (
i - last + 1 ==
count) {
398 d[(last +
j) / 2] =
true;
412 for (
int i = 0;
i <=
d.size() -
count;
i++) {
417 if (
i - last + 1 ==
count) {
420 s[(last +
j) * 2] =
true;
421 s[(last +
j) * 2 + 1] =
true;
441 template <
typename Integer>
443 std::is_integral<Integer>::value>> :
public Result<Aapcs32, Integer>
446 template <
typename Integer>
448 std::is_integral<Integer>::value>> :
457 template <
typename Float>
459 std::is_floating_point<Float>::value>>
465 storeResult<Aapcs32, Float>(tc,
f, state);
471 reg.as<Float>()[0] =
f;
476 template <
typename Float>
484 return getArgument<Aapcs32, Float>(tc, state);
489 constexpr
int lane_per_reg = 16 /
sizeof(Float);
490 const int reg =
index / lane_per_reg;
491 const int lane =
index % lane_per_reg;
495 return val.as<Float>()[lane];
498 return loadFromStack<Float>(tc, state);
507 template <
typename Composite>
509 IsAapcs32Composite<Composite>::value &&
510 !IsAapcs32HomogeneousAggregate<Composite>::value>> :
511 public Result<Aapcs32, Composite>
514 template <
typename Composite>
516 IsAapcs32Composite<Composite>::value &&
517 !IsAapcs32HomogeneousAggregate<Composite>::value>> :
526 template <
typename T>
529 template <
typename E,
size_t N>
532 template <
typename HA>
534 IsAapcs32HomogeneousAggregate<HA>::value>> :
541 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
542 return state.
variadic || !std::is_floating_point<Elem>::value ||
550 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
552 if (useBaseABI(state))
553 return getArgument<Aapcs32, HA>(tc, state);
557 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
559 for (
int i = 0;
i < Count;
i++) {
561 const int reg =
index / lane_per_reg;
562 const int lane =
index % lane_per_reg;
566 ha[
i] =
val.as<Elem>()[lane];
571 return loadFromStack<HA>(tc, state);
577 if (useBaseABI(state))
582 template <
typename HA>
584 typename
std::enable_if_t<IsAapcs32HomogeneousAggregate<HA>::value>>
590 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
591 return state.
variadic || !std::is_floating_point<Elem>::value ||
599 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
601 if (useBaseABI(state)) {
602 storeResult<Aapcs32, HA>(tc,
ha, state);
606 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
607 for (
int i = 0;
i < Count;
i++) {
608 const int reg =
i / lane_per_reg;
609 const int lane =
i % lane_per_reg;
613 val.as<Elem>()[lane] =
ha[
i];
621 if (useBaseABI(state))
631 template <
typename ...Types>
645 #endif // __ARCH_ARM_AAPCS32_HH__