Go to the documentation of this file.
28 #ifndef __ARCH_ARM_AAPCS32_HH__
29 #define __ARCH_ARM_AAPCS32_HH__
33 #include <type_traits>
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>
118 state.stackUsed =
true;
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))>>
168 template <
typename Integer>
170 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint64_t))>>
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) &&
227 return low | (
high << 32);
233 return loadFromStack<Integer>(tc,
state);
242 template <
typename Float>
244 std::is_floating_point_v<Float>>>
250 storeResult<Aapcs32, decltype(i)>(tc,
i,
state);
254 template <
typename Float>
261 if (
sizeof(Float) ==
sizeof(uint32_t)) {
263 getArgument<Aapcs32, uint32_t>(tc,
state));
266 getArgument<Aapcs32, uint64_t>(tc,
state));
276 template <
typename Composite>
278 IsAapcs32CompositeV<Composite>>>
284 if (
sizeof(Composite) <=
sizeof(uint32_t)) {
287 memcpy((
void *)&
val, (
void *)&cp,
sizeof(Composite));
299 if (
sizeof(Composite) >
sizeof(uint32_t))
304 template <
typename Composite>
306 IsAapcs32CompositeV<Composite>>> :
312 size_t bytes =
sizeof(Composite);
313 using Chunk = uint32_t;
315 const int chunk_size =
sizeof(Chunk);
316 const int regs = (bytes + chunk_size - 1) / chunk_size;
318 if (bytes <= chunk_size) {
320 alignas(
alignof(Composite)) uint32_t
val =
327 if (
alignof(Composite) == 8 && (
state.ncrn % 2))
331 alignas(
alignof(Composite)) uint8_t buf[bytes];
332 for (
int i = 0;
i < regs;
i++) {
335 size_t to_copy = std::min<size_t>(bytes, chunk_size);
336 memcpy(buf +
i * chunk_size, &
val, to_copy);
343 alignas(
alignof(Composite)) uint8_t buf[bytes];
349 size_t to_copy = std::min<size_t>(bytes, chunk_size);
361 state.nsaa, buf, bytes);
363 state.stackUsed =
true;
373 return loadFromStack<Composite>(tc,
state);
392 std::array<bool, 16>
s;
393 std::array<bool, 8>
d;
405 for (
int i = 0;
i <=
s.size() -
count;
i++) {
410 if (
i - last + 1 ==
count) {
413 d[(last +
j) / 2] =
true;
427 for (
int i = 0;
i <=
d.size() -
count;
i++) {
432 if (
i - last + 1 ==
count) {
435 s[(last +
j) * 2] =
true;
436 s[(last +
j) * 2 + 1] =
true;
455 template <
typename Integer>
457 std::is_integral_v<Integer>>> :
public Result<Aapcs32, Integer>
460 template <
typename Integer>
462 std::is_integral_v<Integer>>> :
public Argument<Aapcs32, Integer>
470 template <
typename Float>
472 std::is_floating_point_v<Float>>>
477 if (
state.variadic) {
478 storeResult<Aapcs32, Float>(tc,
f,
state);
485 for (
int chunk = 0; chunk < chunks; chunk++)
490 template <
typename Float>
498 return getArgument<Aapcs32, Float>(tc,
state);
503 return loadFromStack<Float>(tc,
state);
509 for (
int chunk = 0; chunk < chunks; chunk++)
521 template <
typename Composite>
523 IsAapcs32CompositeV<Composite> &&
524 !IsAapcs32HomogeneousAggregateV<Composite>>> :
525 public Result<Aapcs32, Composite>
528 template <
typename Composite>
530 IsAapcs32CompositeV<Composite> &&
531 !IsAapcs32HomogeneousAggregateV<Composite>>> :
540 template <
typename T>
543 template <
typename E,
size_t N>
546 template <
typename HA>
548 IsAapcs32HomogeneousAggregateV<HA>>> :
555 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
556 return state.variadic || !std::is_floating_point_v<Elem> ||
564 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
566 if (useBaseABI(
state))
567 return getArgument<Aapcs32, HA>(tc,
state);
571 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
575 const int reg =
index / lane_per_reg;
576 const int lane =
index % lane_per_reg;
581 ha[
i] =
val.as<Elem>()[lane];
586 return loadFromStack<HA>(tc,
state);
592 if (useBaseABI(
state))
597 template <
typename HA>
599 typename
std::enable_if_t<IsAapcs32HomogeneousAggregateV<HA>>>
605 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
606 return state.variadic || !std::is_floating_point_v<Elem> ||
614 constexpr
size_t Count =
sizeof(HA) /
sizeof(Elem);
616 if (useBaseABI(
state)) {
617 storeResult<Aapcs32, HA>(tc,
ha,
state);
621 constexpr
int lane_per_reg = 16 /
sizeof(Elem);
623 const int reg =
i / lane_per_reg;
624 const int lane =
i % lane_per_reg;
629 val.as<Elem>()[lane] =
ha[
i];
637 if (useBaseABI(
state))
647 template <
typename ...Types>
653 state.variadic =
true;
661 #endif // __ARCH_ARM_AAPCS32_HH__
int allocate(double, int count)
State(const ThreadContext *tc)
static void prepare(ThreadContext *tc, Aapcs32Vfp::State &state)
static float bitsToFloat32(uint32_t val)
static Arg getArgument(ThreadContext *tc, typename ABI::State &state)
virtual RegVal getReg(const RegId ®) const
static Float get(ThreadContext *tc, Aapcs32::State &state)
static double bitsToFloat64(uint64_t val)
static Integer get(ThreadContext *tc, Aapcs32::State &state)
static void prepare(ThreadContext *tc, Aapcs32Vfp::State &state)
static void store(ThreadContext *tc, const Integer &i)
static void store(ThreadContext *tc, const Composite &composite, Aapcs32::State &state)
ByteOrder byteOrder(const ThreadContext *tc)
static T loadFromStack(ThreadContext *tc, Aapcs32::State &state)
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)
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
static void store(ThreadContext *tc, const Integer &i)
This proxy attempts to translate virtual addresses using the TLBs.
static void store(ThreadContext *tc, const Float &f, Aapcs32::State &state)
static HA store(ThreadContext *tc, const HA &ha, Aapcs32Vfp::State &state)
static Composite get(ThreadContext *tc, Aapcs32::State &state)
State(const ThreadContext *tc)
static uint64_t floatToBits(double val)
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
ThreadContext is the external interface to all thread state for anything outside of the CPU.
static HA get(ThreadContext *tc, Aapcs32Vfp::State &state)
T gtoh(T value, ByteOrder guest_byte_order)
This object is a proxy for a port or other object which implements the functional response protocol,...
static bool useBaseABI(Aapcs32Vfp::State &state)
int allocate(float, int count)
constexpr RegClass intRegClass
T htog(T value, ByteOrder guest_byte_order)
static double bitsToFloat(uint64_t val)
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr RegClass vecRegClass
static VarArgs< Types... > get(ThreadContext *tc, typename Aapcs32Vfp::State &state)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
static void prepare(ThreadContext *tc, Aapcs32::State &state)
static Float get(ThreadContext *tc, Aapcs32Vfp::State &state)
constexpr bool IsAapcs32HomogeneousAggregateV
constexpr bool IsAapcs32CompositeV
constexpr RegClass vecElemClass
Overload hash function for BasicBlockRange type.
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, ®)
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
static bool useBaseABI(Aapcs32Vfp::State &state)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static void store(ThreadContext *tc, const Integer &i)
T[count] Aapcs32HomogeneousAggregate
Register ID: describe an architectural register with its class and index.
static void store(ThreadContext *tc, const Float &f, Aapcs32Vfp::State &state)
virtual void setReg(const RegId ®, RegVal val)
Generated on Sun Jul 30 2023 01:56:47 for gem5 by doxygen 1.8.17