28 #ifndef __ARCH_ARM_AAPCS64_HH__
29 #define __ARCH_ARM_AAPCS64_HH__
33 #include <type_traits>
82 template <
typename T,
typename Enabled=
void>
85 template <
typename E,
size_t N>
87 typename
std::enable_if_t<
88 (std::is_integral_v<E> || std::is_floating_point_v<E>) &&
89 (sizeof(E) * N == 8 || sizeof(E) * N == 16)>> :
100 template <
typename T,
typename Enabled=
void>
103 template <
typename T>
105 (std::is_array_v<T> || std::is_class_v<T> || std::is_union_v<T>) &&
109 !IsAapcs64ShortVectorV<T>
110 >> :
public std::true_type
113 template <
typename T>
125 template <
typename T,
typename Enabled=
void>
128 template <
typename E,
size_t N>
130 typename
std::enable_if_t<std::is_floating_point_v<E> && N <= 4>> :
131 public std::true_type
134 template <
typename T>
135 constexpr
bool IsAapcs64HfaV = IsAapcs64Hfa<T>::value;
141 template <
typename T,
typename Enabled=
void>
142 struct IsAapcs64Hva :
public std::false_type {};
144 template <
typename E,
size_t N>
145 struct IsAapcs64Hva<
E[N],
146 typename
std::enable_if_t<IsAapcs64ShortVectorV<E> && N <= 4>> :
147 public std::true_type
150 template <
typename T>
151 constexpr
bool IsAapcs64HvaV = IsAapcs64Hva<T>::value;
154 template <
typename T,
typename Enabled=
void>
155 struct IsAapcs64Hxa :
public std::false_type {};
157 template <
typename T>
158 struct IsAapcs64Hxa<T, typename
std::enable_if_t<
159 IsAapcs64HfaV<T> || IsAapcs64HvaV<T>>> :
160 public std::true_type
163 template <
typename T>
164 constexpr
bool IsAapcs64HxaV = IsAapcs64Hxa<T>::value;
166 struct Aapcs64ArgumentBase
168 template <
typename T>
170 loadFromStack(ThreadContext *tc, Aapcs64::State &
state)
173 size_t align = std::max<size_t>(8,
alignof(T));
175 size_t size =
roundUp(
sizeof(T), 8);
196 template <
typename Float>
197 struct Argument<Aapcs64, Float, typename
std::enable_if_t<
198 std::is_floating_point_v<Float> || IsAapcs64ShortVectorV<Float>>> :
199 public Aapcs64ArgumentBase
202 get(ThreadContext *tc, Aapcs64::State &
state)
208 return vc.as<Float>()[0];
211 return loadFromStack<Float>(tc,
state);
215 template <
typename Float>
216 struct Result<Aapcs64, Float, typename
std::enable_if_t<
217 std::is_floating_point_v<Float> || IsAapcs64ShortVectorV<Float>>>
220 store(ThreadContext *tc,
const Float &
f)
224 tc->getReg(
id, &
reg);
236 template <
typename Integer>
238 std::is_integral_v<Integer> && (sizeof(Integer) <= 8)>> :
239 public Aapcs64ArgumentBase
250 return loadFromStack<Integer>(tc,
state);
254 template <
typename Integer>
256 std::is_integral_v<Integer> && (sizeof(Integer) > 8)>> :
257 public Aapcs64ArgumentBase
262 if (
alignof(Integer) == 16 && (
state.ngrn % 2))
265 if (
sizeof(Integer) == 16 &&
state.ngrn + 1 <=
state.MAX_GRN) {
275 return loadFromStack<Integer>(tc,
state);
279 template <
typename Integer>
281 std::is_integral_v<Integer> && (sizeof(Integer) <= 8)>>
290 template <
typename Integer>
292 std::is_integral_v<Integer> && (sizeof(Integer) > 8)>>
308 template <
typename T>
311 template <
typename E,
size_t N>
314 template <
typename HA>
316 IsAapcs64HxaV<HA>>> :
public Aapcs64ArgumentBase
322 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
334 return loadFromStack<HA>(tc,
state);
338 template <
typename HA>
345 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
357 template <
typename Composite>
359 IsAapcs64CompositeV<Composite> && !IsAapcs64HxaV<Composite>>> :
360 public Aapcs64ArgumentBase
365 if (
sizeof(Composite) > 16) {
376 size_t bytes =
sizeof(Composite);
377 using Chunk = uint64_t;
379 const int chunk_size =
sizeof(Chunk);
380 const int regs = (bytes + chunk_size - 1) / chunk_size;
384 alignas(
alignof(Composite)) uint8_t buf[bytes];
385 for (
int i = 0;
i < regs;
i++) {
388 size_t to_copy = std::min<size_t>(bytes, chunk_size);
389 memcpy(buf +
i * chunk_size, &
val, to_copy);
398 return loadFromStack<Composite>(tc,
state);
402 template <
typename Composite>
404 IsAapcs64CompositeV<Composite> && !IsAapcs64HxaV<Composite>>>
409 if (
sizeof(Composite) > 16) {
418 size_t bytes =
sizeof(Composite);
419 using Chunk = uint64_t;
421 const int chunk_size =
sizeof(Chunk);
422 const int regs = (bytes + chunk_size - 1) / chunk_size;
425 uint8_t *buf = (uint8_t *)&cp;
426 for (
int i = 0;
i < regs;
i++) {
427 size_t to_copy = std::min<size_t>(bytes, chunk_size);
430 memcpy(&
val, buf, to_copy);
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)
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
static RegId x(unsigned index)
ByteOrder byteOrder(const ThreadContext *tc)
gem5::VecRegContainer< NumVecElemPerVecReg *sizeof(VecElem)> VecRegContainer
constexpr RegClass intRegClass
constexpr RegClass vecRegClass
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 IsAapcs64CompositeV
constexpr bool IsAapcs64ShortVectorV
double Result
All results are doubles.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
T gtoh(T value, ByteOrder guest_byte_order)
T htog(T value, ByteOrder guest_byte_order)
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.
State(const ThreadContext *tc)
static Composite get(ThreadContext *tc, Aapcs64::State &state)
static HA get(ThreadContext *tc, Aapcs64::State &state)
static Integer get(ThreadContext *tc, Aapcs64::State &state)
static Integer get(ThreadContext *tc, Aapcs64::State &state)
static void store(ThreadContext *tc, const Composite &c)
static HA store(ThreadContext *tc, const HA &ha)
static void store(ThreadContext *tc, const Integer &i)
static void store(ThreadContext *tc, const Integer &i)