28 #ifndef __ARCH_ARM_AAPCS32_HH__
29 #define __ARCH_ARM_AAPCS32_HH__
33 #include <type_traits>
67 nsaa(tc->readIntReg(ArmISA::INTREG_SPX))
80 template <
typename T,
typename Enabled=
void>
85 (std::is_array_v<T> || std::is_class_v<T> || std::is_union_v<T>) &&
88 >> :
public std::true_type
99 template <
typename T, std::
size_t count,
typename Enabled=
void>
102 template <
typename T>
105 template <
typename E,
size_t N>
108 template <
typename T>
114 template <
typename T>
121 size_t align = std::max<size_t>(4,
alignof(T));
123 size_t size =
roundUp(
sizeof(T), 4);
144 template <
typename Integer>
146 std::is_integral_v<Integer> && (sizeof(Integer) < sizeof(uint32_t))>>
151 uint32_t
val = std::is_signed_v<Integer> ?
152 sext<sizeof(Integer) * 8>(
i) :
i;
157 template <
typename Integer>
159 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint32_t))>>
164 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)
i);
168 template <
typename Integer>
170 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint64_t))>>
176 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)(
i >> 0));
177 tc->
setIntReg(ArmISA::INTREG_R1, (uint32_t)(
i >> 32));
179 tc->
setIntReg(ArmISA::INTREG_R0, (uint32_t)(
i >> 32));
180 tc->
setIntReg(ArmISA::INTREG_R1, (uint32_t)(
i >> 0));
185 template <
typename Integer>
187 std::is_integral_v<Integer> && (sizeof(Integer) <= sizeof(uint32_t))
200 return loadFromStack<Integer>(tc, state);
204 template <
typename Integer>
206 std::is_integral_v<Integer> && (sizeof(Integer) > sizeof(uint32_t))
212 if (
alignof(Integer) == 8 && (state.
ncrn % 2))
215 if (
sizeof(Integer) ==
sizeof(uint64_t) &&
225 return low | (
high << 32);
231 return loadFromStack<Integer>(tc, state);
240 template <
typename Float>
242 std::is_floating_point_v<Float>>>
248 storeResult<Aapcs32, decltype(i)>(tc,
i, state);
252 template <
typename Float>
259 if (
sizeof(Float) ==
sizeof(uint32_t)) {
261 getArgument<Aapcs32, uint32_t>(tc, state));
264 getArgument<Aapcs32, uint64_t>(tc, state));
274 template <
typename Composite>
276 IsAapcs32CompositeV<Composite>>>
282 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
285 memcpy((
void *)&
val, (
void *)&cp,
sizeof(Composite));
297 if (
sizeof(Composite) >
sizeof(uint32_t))
302 template <
typename Composite>
304 IsAapcs32CompositeV<Composite>>> :
310 size_t bytes =
sizeof(Composite);
311 using Chunk = uint32_t;
313 const int chunk_size =
sizeof(Chunk);
314 const int regs = (bytes + chunk_size - 1) / chunk_size;
316 if (bytes <= chunk_size) {
318 alignas(
alignof(Composite)) uint32_t
val =
325 if (
alignof(Composite) == 8 && (state.
ncrn % 2))
329 alignas(
alignof(Composite)) uint8_t buf[bytes];
330 for (
int i = 0;
i < regs;
i++) {
333 size_t to_copy = std::min<size_t>(bytes, chunk_size);
334 memcpy(buf +
i * chunk_size, &
val, to_copy);
341 alignas(
alignof(Composite)) uint8_t buf[bytes];
347 size_t to_copy = std::min<size_t>(bytes, chunk_size);
356 state.
nsaa, buf, bytes);
368 return loadFromStack<Composite>(tc, state);
387 std::array<bool, 16>
s;
388 std::array<bool, 8>
d;
400 for (
int i = 0;
i <=
s.size() -
count;
i++) {
405 if (
i - last + 1 ==
count) {
408 d[(last +
j) / 2] =
true;
422 for (
int i = 0;
i <=
d.size() -
count;
i++) {
427 if (
i - last + 1 ==
count) {
430 s[(last +
j) * 2] =
true;
431 s[(last +
j) * 2 + 1] =
true;
451 template <
typename Integer>
453 std::is_integral_v<Integer>>> :
public Result<Aapcs32, Integer>
456 template <
typename Integer>
458 std::is_integral_v<Integer>>> :
public Argument<Aapcs32, Integer>
466 template <
typename Float>
468 std::is_floating_point_v<Float>>>
474 storeResult<Aapcs32, Float>(tc,
f, state);
481 for (
int chunk = 0; chunk < chunks; chunk++) {
489 template <
typename Float>
497 return getArgument<Aapcs32, Float>(tc, state);
502 return loadFromStack<Float>(tc, state);
508 for (
int chunk = 0; chunk < chunks; chunk++) {
523 template <
typename Composite>
525 IsAapcs32CompositeV<Composite> &&
526 !IsAapcs32HomogeneousAggregateV<Composite>>> :
527 public Result<Aapcs32, Composite>
530 template <
typename Composite>
532 IsAapcs32CompositeV<Composite> &&
533 !IsAapcs32HomogeneousAggregateV<Composite>>> :
542 template <
typename T>
545 template <
typename E,
size_t N>
548 template <
typename HA>
550 IsAapcs32HomogeneousAggregateV<HA>>> :
557 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
558 return state.
variadic || !std::is_floating_point_v<Elem> ||
566 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
568 if (useBaseABI(state))
569 return getArgument<Aapcs32, HA>(tc, state);
573 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
575 for (
int i = 0;
i < Count;
i++) {
577 const int reg =
index / lane_per_reg;
578 const int lane =
index % lane_per_reg;
582 ha[
i] =
val.as<Elem>()[lane];
587 return loadFromStack<HA>(tc, state);
593 if (useBaseABI(state))
598 template <
typename HA>
600 typename
std::enable_if_t<IsAapcs32HomogeneousAggregateV<HA>>>
606 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
607 return state.
variadic || !std::is_floating_point_v<Elem> ||
615 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
617 if (useBaseABI(state)) {
618 storeResult<Aapcs32, HA>(tc,
ha, state);
622 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
623 for (
int i = 0;
i < Count;
i++) {
624 const int reg =
i / lane_per_reg;
625 const int lane =
i % lane_per_reg;
629 val.as<Elem>()[lane] =
ha[
i];
637 if (useBaseABI(state))
647 template <
typename ...Types>
661 #endif // __ARCH_ARM_AAPCS32_HH__