28 #ifndef __ARCH_ARM_AAPCS32_HH__
29 #define __ARCH_ARM_AAPCS32_HH__
33 #include <type_traits>
81 template <
typename T,
typename Enabled=
void>
86 (std::is_array_v<T> || std::is_class_v<T> || std::is_union_v<T>) &&
89 >> :
public std::true_type
100 template <
typename T, std::
size_t count,
typename Enabled=
void>
103 template <
typename T>
106 template <
typename E,
size_t N>
109 template <
typename T>
115 template <
typename T>
119 state.stackUsed =
true;
122 size_t align = std::max<size_t>(4,
alignof(T));
124 size_t size =
roundUp(
sizeof(T), 4);
145 template <
typename Integer>
147 std::is_integral_v<Integer> && (sizeof(Integer) < sizeof(uint32_t))>>
152 uint32_t
val = std::is_signed_v<Integer> ?
153 sext<sizeof(Integer) * 8>(
i) :
i;
158 template <
typename Integer>
160 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint32_t))>>
169 template <
typename Integer>
171 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint64_t))>>
186 template <
typename Integer>
188 std::is_integral_v<Integer> && (sizeof(Integer) <= sizeof(uint32_t))
201 return loadFromStack<Integer>(tc,
state);
205 template <
typename Integer>
207 std::is_integral_v<Integer> && (sizeof(Integer) > sizeof(uint32_t))
213 if (
alignof(Integer) == 8 && (
state.ncrn % 2))
216 if (
sizeof(Integer) ==
sizeof(uint64_t) &&
228 return low | (
high << 32);
234 return loadFromStack<Integer>(tc,
state);
243 template <
typename Float>
245 std::is_floating_point_v<Float>>>
251 storeResult<Aapcs32, decltype(i)>(tc,
i,
state);
255 template <
typename Float>
262 if (
sizeof(Float) ==
sizeof(uint32_t)) {
264 getArgument<Aapcs32, uint32_t>(tc,
state));
267 getArgument<Aapcs32, uint64_t>(tc,
state));
277 template <
typename Composite>
279 IsAapcs32CompositeV<Composite>>>
285 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
288 memcpy((
void *)&
val, (
void *)&cp,
sizeof(Composite));
300 if (
sizeof(Composite) >
sizeof(uint32_t))
305 template <
typename Composite>
307 IsAapcs32CompositeV<Composite>>> :
313 size_t bytes =
sizeof(Composite);
314 using Chunk = uint32_t;
316 const int chunk_size =
sizeof(Chunk);
317 const int regs = (bytes + chunk_size - 1) / chunk_size;
319 if (bytes <= chunk_size) {
321 alignas(
alignof(Composite)) uint32_t
val =
328 if (
alignof(Composite) == 8 && (
state.ncrn % 2))
332 alignas(
alignof(Composite)) uint8_t buf[bytes];
333 for (
int i = 0;
i < regs;
i++) {
336 size_t to_copy = std::min<size_t>(bytes, chunk_size);
337 memcpy(buf +
i * chunk_size, &
val, to_copy);
344 alignas(
alignof(Composite)) uint8_t buf[bytes];
350 size_t to_copy = std::min<size_t>(bytes, chunk_size);
362 state.nsaa, buf, bytes);
364 state.stackUsed =
true;
374 return loadFromStack<Composite>(tc,
state);
393 std::array<bool, 16>
s;
394 std::array<bool, 8>
d;
406 for (
int i = 0;
i <=
s.size() -
count;
i++) {
411 if (
i - last + 1 ==
count) {
414 d[(last +
j) / 2] =
true;
428 for (
int i = 0;
i <=
d.size() -
count;
i++) {
433 if (
i - last + 1 ==
count) {
436 s[(last +
j) * 2] =
true;
437 s[(last +
j) * 2 + 1] =
true;
457 template <
typename Integer>
459 std::is_integral_v<Integer>>> :
public Result<Aapcs32, Integer>
462 template <
typename Integer>
464 std::is_integral_v<Integer>>> :
public Argument<Aapcs32, Integer>
472 template <
typename Float>
474 std::is_floating_point_v<Float>>>
479 if (
state.variadic) {
480 storeResult<Aapcs32, Float>(tc,
f,
state);
487 for (
int chunk = 0; chunk < chunks; chunk++)
492 template <
typename Float>
500 return getArgument<Aapcs32, Float>(tc,
state);
505 return loadFromStack<Float>(tc,
state);
511 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);
577 const int reg =
index / lane_per_reg;
578 const int lane =
index % lane_per_reg;
583 ha[
i] =
val.as<Elem>()[lane];
588 return loadFromStack<HA>(tc,
state);
594 if (useBaseABI(
state))
599 template <
typename HA>
601 typename
std::enable_if_t<IsAapcs32HomogeneousAggregateV<HA>>>
607 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
608 return state.variadic || !std::is_floating_point_v<Elem> ||
616 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
618 if (useBaseABI(
state)) {
619 storeResult<Aapcs32, HA>(tc,
ha,
state);
623 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
625 const int reg =
i / lane_per_reg;
626 const int lane =
i % lane_per_reg;
631 val.as<Elem>()[lane] =
ha[
i];
639 if (useBaseABI(
state))
649 template <
typename ...Types>
655 state.variadic =
true;
This object is a proxy for a port or other object which implements the functional response protocol,...
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Register ID: describe an architectural register with its class and index.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId ®) const
virtual void setReg(const RegId ®, RegVal val)
This proxy attempts to translate virtual addresses using the TLBs.
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
ByteOrder byteOrder(const ThreadContext *tc)
constexpr RegClass vecElemClass
constexpr RegClass intRegClass
constexpr RegClass vecRegClass
T[count] Aapcs32HomogeneousAggregate
constexpr bool IsAapcs32CompositeV
struct IsAapcs64Hfa< E[N], typename std::enable_if_t< std::is_floating_point_v< E > &&N<=4 > > :public std::true_type{};template< typename T >constexpr bool IsAapcs64HfaV=IsAapcs64Hfa< T >::value;template< typename T, typename Enabled=void >struct IsAapcs64Hva :public std::false_type {};template< typename E, size_t N >struct IsAapcs64Hva< E[N], typename std::enable_if_t< IsAapcs64ShortVectorV< E > &&N<=4 > > :public std::true_type{};template< typename T >constexpr bool IsAapcs64HvaV=IsAapcs64Hva< T >::value;template< typename T, typename Enabled=void >struct IsAapcs64Hxa :public std::false_type {};template< typename T >struct IsAapcs64Hxa< T, typename std::enable_if_t< IsAapcs64HfaV< T >||IsAapcs64HvaV< T > > > :public std::true_type{};template< typename T >constexpr bool IsAapcs64HxaV=IsAapcs64Hxa< T >::value;struct Aapcs64ArgumentBase{ template< typename T > static T loadFromStack(ThreadContext *tc, Aapcs64::State &state) { size_t align=std::max< size_t >(8, alignof(T));size_t size=roundUp(sizeof(T), 8);state.nsaa=roundUp(state.nsaa, align);ConstVPtr< T > val(state.nsaa, tc);state.nsaa+=size;return gtoh(*val, ArmISA::byteOrder(tc));}};template< typename Float >struct Argument< Aapcs64, Float, typename std::enable_if_t< std::is_floating_point_v< Float >||IsAapcs64ShortVectorV< Float > > > :public Aapcs64ArgumentBase{ static Float get(ThreadContext *tc, Aapcs64::State &state) { if(state.nsrn<=state.MAX_SRN) { RegId id=ArmISA::vecRegClass[state.nsrn++];ArmISA::VecRegContainer vc;tc->getReg(id, &vc);return vc.as< Float >()[0];} return loadFromStack< Float >(tc, state);}};template< typename Float >struct Result< Aapcs64, Float, typename std::enable_if_t< std::is_floating_point_v< Float >||IsAapcs64ShortVectorV< Float > > >{ static void store(ThreadContext *tc, const Float &f) { RegId id=ArmISA::vecRegClass[0];ArmISA::VecRegContainer reg;tc-> getReg(id, ®)
constexpr bool IsAapcs32HomogeneousAggregateV
static Arg getArgument(ThreadContext *tc, typename ABI::State &state)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static uint64_t floatToBits(double val)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
T gtoh(T value, ByteOrder guest_byte_order)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
static double bitsToFloat(uint64_t val)
T htog(T value, ByteOrder guest_byte_order)
static double bitsToFloat64(uint64_t val)
static float bitsToFloat32(uint32_t val)
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
Overload hash function for BasicBlockRange type.
PortProxy Object Declaration.
State(const ThreadContext *tc)
int allocate(double, int count)
int allocate(float, int count)
State(const ThreadContext *tc)
static T loadFromStack(ThreadContext *tc, Aapcs32::State &state)
static Float get(ThreadContext *tc, Aapcs32Vfp::State &state)
static HA get(ThreadContext *tc, Aapcs32Vfp::State &state)
static bool useBaseABI(Aapcs32Vfp::State &state)
static void prepare(ThreadContext *tc, Aapcs32Vfp::State &state)
static VarArgs< Types... > get(ThreadContext *tc, typename Aapcs32Vfp::State &state)
static Composite get(ThreadContext *tc, Aapcs32::State &state)
static Float get(ThreadContext *tc, Aapcs32::State &state)
static Integer get(ThreadContext *tc, Aapcs32::State &state)
static Integer get(ThreadContext *tc, Aapcs32::State &state)
static void store(ThreadContext *tc, const Float &f, Aapcs32Vfp::State &state)
static void prepare(ThreadContext *tc, Aapcs32Vfp::State &state)
static bool useBaseABI(Aapcs32Vfp::State &state)
static HA store(ThreadContext *tc, const HA &ha, Aapcs32Vfp::State &state)
static void store(ThreadContext *tc, const Composite &composite, Aapcs32::State &state)
static void prepare(ThreadContext *tc, Aapcs32::State &state)
static void store(ThreadContext *tc, const Float &f, Aapcs32::State &state)
static void store(ThreadContext *tc, const Integer &i)
static void store(ThreadContext *tc, const Integer &i)
static void store(ThreadContext *tc, const Integer &i)