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 >> :
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))>>
139 uint32_t
val = std::is_signed<Integer>::value ?
140 sext<sizeof(Integer) * 8>(
i) :
i;
145 template <
typename Integer>
147 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint32_t))>>
156 template <
typename Integer>
158 std::is_integral<Integer>::value && (sizeof(Integer) == sizeof(uint64_t))>>
173 template <
typename Integer>
175 std::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(uint32_t))
188 return loadFromStack<Integer>(tc, state);
192 template <
typename Integer>
194 std::is_integral<Integer>::value && (sizeof(Integer) > sizeof(uint32_t))
200 if (
alignof(Integer) == 8 && (state.
ncrn % 2))
203 if (
sizeof(Integer) ==
sizeof(uint64_t) &&
213 return low | (high << 32);
219 return loadFromStack<Integer>(tc, state);
228 template <
typename Float>
230 std::is_floating_point<Float>::value>>
236 storeResult<Aapcs32, decltype(i)>(tc,
i, state);
240 template <
typename Float>
247 if (
sizeof(Float) ==
sizeof(uint32_t)) {
249 getArgument<Aapcs32, uint32_t>(tc, state));
252 getArgument<Aapcs32, uint64_t>(tc, state));
262 template <
typename Composite>
264 IsAapcs32Composite<Composite>::value>>
270 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
273 memcpy((
void *)&
val, (
void *)&
cp,
sizeof(Composite));
285 if (
sizeof(Composite) >
sizeof(uint32_t))
290 template <
typename Composite>
292 IsAapcs32Composite<Composite>::value>> :
298 size_t bytes =
sizeof(Composite);
299 using Chunk = uint32_t;
301 const int chunk_size =
sizeof(Chunk);
302 const int regs = (bytes + chunk_size - 1) / chunk_size;
304 if (bytes <= chunk_size) {
306 alignas(
alignof(Composite)) uint32_t
val =
313 if (
alignof(Composite) == 8 && (state.
ncrn % 2))
317 alignas(
alignof(Composite)) uint8_t buf[bytes];
318 for (
int i = 0;
i < regs;
i++) {
321 size_t to_copy = std::min<size_t>(bytes, chunk_size);
322 memcpy(buf +
i * chunk_size, &
val, to_copy);
329 alignas(
alignof(Composite)) uint8_t buf[bytes];
335 size_t to_copy = std::min<size_t>(bytes, chunk_size);
354 return loadFromStack<Composite>(tc, state);
373 std::array<bool, 16>
s;
374 std::array<bool, 8>
d;
386 for (
int i = 0;
i <=
s.size() -
count;
i++) {
391 if (
i - last + 1 ==
count) {
394 d[(last +
j) / 2] =
true;
408 for (
int i = 0;
i <=
d.size() -
count;
i++) {
413 if (
i - last + 1 ==
count) {
416 s[(last +
j) * 2] =
true;
417 s[(last +
j) * 2 + 1] =
true;
436 template <
typename Integer>
438 std::is_integral<Integer>::value>> :
public Result<Aapcs32, Integer>
441 template <
typename Integer>
443 std::is_integral<Integer>::value>> :
452 template <
typename Float>
454 std::is_floating_point<Float>::value>>
460 storeResult<Aapcs32, Float>(tc,
f, state);
466 reg.laneView<Float, 0>() =
f;
471 template <
typename Float>
479 return getArgument<Aapcs32, Float>(tc, state);
484 constexpr
int lane_per_reg = 16 /
sizeof(Float);
485 const int reg =
index / lane_per_reg;
486 const int lane =
index % lane_per_reg;
490 return val.laneView<Float>(lane);
493 return loadFromStack<Float>(tc, state);
502 template <
typename Composite>
504 IsAapcs32Composite<Composite>::value &&
505 !IsAapcs32HomogeneousAggregate<Composite>::value>> :
506 public Result<Aapcs32, Composite>
509 template <
typename Composite>
511 IsAapcs32Composite<Composite>::value &&
512 !IsAapcs32HomogeneousAggregate<Composite>::value>> :
521 template <
typename T>
524 template <
typename E,
size_t N>
527 template <
typename HA>
529 IsAapcs32HomogeneousAggregate<HA>::value>> :
536 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
537 return state.
variadic || !std::is_floating_point<Elem>::value ||
545 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
547 if (useBaseABI(state))
548 return getArgument<Aapcs32, HA>(tc, state);
552 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
554 for (
int i = 0;
i < Count;
i++) {
556 const int reg =
index / lane_per_reg;
557 const int lane =
index % lane_per_reg;
561 ha[
i] =
val.laneView<Elem>(lane);
566 return loadFromStack<HA>(tc, state);
572 if (useBaseABI(state))
577 template <
typename HA>
579 typename
std::enable_if_t<IsAapcs32HomogeneousAggregate<HA>::value>>
585 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
586 return state.
variadic || !std::is_floating_point<Elem>::value ||
594 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
596 if (useBaseABI(state)) {
597 storeResult<Aapcs32, HA>(tc,
ha, state);
601 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
602 for (
int i = 0;
i < Count;
i++) {
603 const int reg =
i / lane_per_reg;
604 const int lane =
i % lane_per_reg;
608 val.laneView<Elem>(lane) =
ha[
i];
616 if (useBaseABI(state))
626 template <
typename ...Types>
639 #endif // __ARCH_ARM_AAPCS32_HH__