28 #ifndef __ARCH_ARM_AAPCS32_HH__
29 #define __ARCH_ARM_AAPCS32_HH__
33 #include <type_traits>
73 template <
typename T,
typename Enabled=
void>
78 (std::is_array<T>::value ||
79 std::is_class<T>::value ||
80 std::is_union<T>::value) &&
83 >
::type> :
public std::true_type
91 template <
typename T, std::
size_t count,
typename Enabled=
void>
97 template <
typename E,
size_t N>
102 template <
typename T>
109 size_t align = std::max<size_t>(4,
alignof(T));
111 size_t size =
roundUp(
sizeof(T), 4);
132 template <
typename Integer>
134 std::is_integral<Integer>::value && (sizeof(Integer) < sizeof(uint32_t))
140 uint32_t
val = std::is_signed<Integer>::value ?
141 sext<sizeof(Integer) * 8>(
i) :
i;
146 template <
typename Integer>
148 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint32_t))
158 template <
typename Integer>
160 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint64_t))
166 if (std::is_same<Integer, Addr>::value) {
178 template <
typename Integer>
180 std::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(uint32_t))
193 return loadFromStack<Integer>(tc, state);
197 template <
typename Integer>
199 std::is_integral<Integer>::value && (sizeof(Integer) > sizeof(uint32_t))
205 if (std::is_same<Integer, Addr>::value &&
210 if (
alignof(Integer) == 8 && (state.
ncrn % 2))
213 if (
sizeof(Integer) ==
sizeof(uint64_t) &&
223 return low | (high << 32);
229 return loadFromStack<Integer>(tc, state);
238 template <
typename Float>
240 std::is_floating_point<Float>::value>
::type>
246 storeResult<Aapcs32, decltype(i)>(tc,
i, state);
250 template <
typename Float>
257 if (
sizeof(Float) ==
sizeof(uint32_t)) {
259 getArgument<Aapcs32, uint32_t>(tc, state));
262 getArgument<Aapcs32, uint64_t>(tc, state));
272 template <
typename Composite>
274 IsAapcs32Composite<Composite>::value>
::type>
280 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
283 memcpy((
void *)&
val, (
void *)&
cp,
sizeof(Composite));
295 if (
sizeof(Composite) >
sizeof(uint32_t))
300 template <
typename Composite>
302 IsAapcs32Composite<Composite>::value>
::type> :
308 size_t bytes =
sizeof(Composite);
309 using Chunk = uint32_t;
311 const int chunk_size =
sizeof(Chunk);
312 const int regs = (bytes + chunk_size - 1) / chunk_size;
314 if (bytes <= chunk_size) {
316 alignas(
alignof(Composite)) uint32_t
val =
323 if (
alignof(Composite) == 8 && (state.
ncrn % 2))
327 alignas(
alignof(Composite)) uint8_t buf[bytes];
328 for (
int i = 0;
i < regs;
i++) {
331 size_t to_copy = std::min<size_t>(bytes, chunk_size);
332 memcpy(buf +
i * chunk_size, &
val, to_copy);
339 alignas(
alignof(Composite)) uint8_t buf[bytes];
345 size_t to_copy = std::min<size_t>(bytes, chunk_size);
364 return loadFromStack<Composite>(tc, state);
383 std::array<bool, 16>
s;
384 std::array<bool, 8>
d;
396 for (
int i = 0;
i <=
s.size() -
count;
i++) {
401 if (
i - last + 1 ==
count) {
404 d[(last +
j) / 2] =
true;
418 for (
int i = 0;
i <=
d.size() -
count;
i++) {
423 if (
i - last + 1 ==
count) {
426 s[(last +
j) * 2] =
true;
427 s[(last +
j) * 2 + 1] =
true;
446 template <
typename Integer>
448 std::is_integral<Integer>::value>
::type> :
public Result<Aapcs32, Integer>
451 template <
typename Integer>
453 std::is_integral<Integer>::value>
::type> :
462 template <
typename Float>
464 std::is_floating_point<Float>::value>
::type>
470 storeResult<Aapcs32, Float>(tc,
f, state);
476 reg.laneView<Float, 0>() =
f;
481 template <
typename Float>
489 return getArgument<Aapcs32, Float>(tc, state);
494 constexpr
int lane_per_reg = 16 /
sizeof(Float);
495 const int reg =
index / lane_per_reg;
496 const int lane =
index % lane_per_reg;
500 return val.laneView<Float>(lane);
503 return loadFromStack<Float>(tc, state);
512 template <
typename Composite>
514 IsAapcs32Composite<Composite>::value &&
515 !IsAapcs32HomogeneousAggregate<Composite>::value>
::type> :
516 public Result<Aapcs32, Composite>
519 template <
typename Composite>
521 IsAapcs32Composite<Composite>::value &&
522 !IsAapcs32HomogeneousAggregate<Composite>::value>
::type> :
531 template <
typename T>
534 template <
typename E,
size_t N>
537 template <
typename HA>
539 IsAapcs32HomogeneousAggregate<HA>::value>
::type> :
546 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
547 return state.
variadic || !std::is_floating_point<Elem>::value ||
555 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
557 if (useBaseABI(state))
558 return getArgument<Aapcs32, HA>(tc, state);
562 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
564 for (
int i = 0;
i < Count;
i++) {
566 const int reg =
index / lane_per_reg;
567 const int lane =
index % lane_per_reg;
571 ha[
i] =
val.laneView<Elem>(lane);
576 return loadFromStack<HA>(tc, state);
582 if (useBaseABI(state))
587 template <
typename HA>
589 typename
std::enable_if<IsAapcs32HomogeneousAggregate<HA>::value>
::type>
595 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
596 return state.
variadic || !std::is_floating_point<Elem>::value ||
604 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
606 if (useBaseABI(state)) {
607 storeResult<Aapcs32, HA>(tc,
ha, state);
611 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
612 for (
int i = 0;
i < Count;
i++) {
613 const int reg =
i / lane_per_reg;
614 const int lane =
i % lane_per_reg;
618 val.laneView<Elem>(lane) =
ha[
i];
626 if (useBaseABI(state))
636 template <
typename ...Types>
649 #endif // __ARCH_ARM_AAPCS32_HH__