gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
aapcs32.hh
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef __ARCH_ARM_AAPCS32_HH__
29#define __ARCH_ARM_AAPCS32_HH__
30
31#include <algorithm>
32#include <array>
33#include <type_traits>
34#include <utility>
35
36#include "arch/arm/regs/int.hh"
37#include "arch/arm/regs/vec.hh"
38#include "arch/arm/utility.hh"
39#include "base/intmath.hh"
40#include "cpu/thread_context.hh"
41#include "mem/port_proxy.hh"
44#include "sim/full_system.hh"
45#include "sim/guest_abi.hh"
46#include "sim/proxy_ptr.hh"
47
48namespace gem5
49{
50
51class ThreadContext;
52
53struct Aapcs32
54{
55 struct State
56 {
57 bool stackUsed=false; // Whether anything has been put on the stack.
58
59 int ncrn=0; // Next general purpose register number.
60 Addr nsaa; // Next stacked argument address.
61
62 // The maximum allowed general purpose register number.
63 static const int MAX_CRN = 3;
64
66
67 explicit State(const ThreadContext *tc) :
68 nsaa(tc->getReg(ArmISA::int_reg::Spx))
69 {}
70 };
71};
72
73namespace guest_abi
74{
75
76/*
77 * Composite Types
78 */
79
80template <typename T, typename Enabled=void>
81struct IsAapcs32Composite : public std::false_type {};
82
83template <typename T>
84struct IsAapcs32Composite<T, typename std::enable_if_t<
85 (std::is_array_v<T> || std::is_class_v<T> || std::is_union_v<T>) &&
86 // VarArgs is technically a composite type, but it's not a normal argument.
87 !IsVarArgsV<T>
88 >> : public std::true_type
89{};
90
91template <typename T>
93
94// Homogeneous Aggregates
95// These *should* be any aggregate type which has only one type of member, but
96// we can't actually detect that or manipulate that with templates. Instead,
97// we approximate that by detecting only arrays with that property.
98
99template <typename T, std::size_t count, typename Enabled=void>
101
102template <typename T>
103struct IsAapcs32HomogeneousAggregate : public std::false_type {};
104
105template <typename E, size_t N>
106struct IsAapcs32HomogeneousAggregate<E[N]> : public std::true_type {};
107
108template <typename T>
111
113{
114 template <typename T>
115 static T
117 {
118 state.stackUsed = true;
119
120 // The alignment is the larger of 4 or the natural alignment of T.
121 size_t align = std::max<size_t>(4, alignof(T));
122 // Increase the size to the next multiple of 4.
123 size_t size = roundUp(sizeof(T), 4);
124
125 // Align the stack.
126 state.nsaa = roundUp(state.nsaa, align);
127
128 // Extract the value from it.
129 ConstVPtr<T> val(state.nsaa, tc);
130
131 // Move the nsaa past this argument.
132 state.nsaa += size;
133
134 // Return the value we extracted.
135 return gtoh(*val, ArmISA::byteOrder(tc));
136 }
137};
138
139
140/*
141 * Integer arguments and return values.
142 */
143
144template <typename Integer>
145struct Result<Aapcs32, Integer, typename std::enable_if_t<
146 std::is_integral_v<Integer> && (sizeof(Integer) < sizeof(uint32_t))>>
147{
148 static void
149 store(ThreadContext *tc, const Integer &i)
150 {
151 uint32_t val = std::is_signed_v<Integer> ?
154 }
155};
156
157template <typename Integer>
158struct Result<Aapcs32, Integer, typename std::enable_if_t<
159 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint32_t))>>
160{
161 static void
162 store(ThreadContext *tc, const Integer &i)
163 {
164 tc->setReg(ArmISA::int_reg::R0, (uint32_t)i);
165 }
166};
167
168template <typename Integer>
169struct Result<Aapcs32, Integer, typename std::enable_if_t<
170 std::is_integral_v<Integer> && (sizeof(Integer) == sizeof(uint64_t))>>
171{
172 static void
173 store(ThreadContext *tc, const Integer &i)
174 {
175 if (ArmISA::byteOrder(tc) == ByteOrder::little) {
176 tc->setReg(ArmISA::int_reg::R0, (uint32_t)(i >> 0));
177 tc->setReg(ArmISA::int_reg::R1, (uint32_t)(i >> 32));
178 } else {
179 tc->setReg(ArmISA::int_reg::R0, (uint32_t)(i >> 32));
180 tc->setReg(ArmISA::int_reg::R1, (uint32_t)(i >> 0));
181 }
182 }
183};
184
185template <typename Integer>
186struct Argument<Aapcs32, Integer, typename std::enable_if_t<
187 std::is_integral_v<Integer> && (sizeof(Integer) <= sizeof(uint32_t))
188 >> : public Aapcs32ArgumentBase
189{
190 static Integer
192 {
193 if (state.ncrn <= state.MAX_CRN) {
194 return tc->getReg(ArmISA::intRegClass[state.ncrn++]);
195 }
196
197 // Max out the ncrn since we effectively exhausted it.
198 state.ncrn = state.MAX_CRN + 1;
199
200 return loadFromStack<Integer>(tc, state);
201 }
202};
203
204template <typename Integer>
205struct Argument<Aapcs32, Integer, typename std::enable_if_t<
206 std::is_integral_v<Integer> && (sizeof(Integer) > sizeof(uint32_t))
207 >> : public Aapcs32ArgumentBase
208{
209 static Integer
211 {
212 if (alignof(Integer) == 8 && (state.ncrn % 2))
213 state.ncrn++;
214
215 if (sizeof(Integer) == sizeof(uint64_t) &&
216 state.ncrn + 1 <= state.MAX_CRN) {
217 Integer low, high;
218 if (ArmISA::byteOrder(tc) == ByteOrder::little) {
219 low = tc->getReg(ArmISA::intRegClass[state.ncrn++]) & mask(32);
220 high = tc->getReg(ArmISA::intRegClass[state.ncrn++]) &
221 mask(32);
222 } else {
223 high = tc->getReg(ArmISA::intRegClass[state.ncrn++]) &
224 mask(32);
225 low = tc->getReg(ArmISA::intRegClass[state.ncrn++]) & mask(32);
226 }
227 return low | (high << 32);
228 }
229
230 // Max out the ncrn since we effectively exhausted it.
231 state.ncrn = state.MAX_CRN + 1;
232
233 return loadFromStack<Integer>(tc, state);
234 }
235};
236
237
238/*
239 * Floating point and Short-Vector arguments and return values.
240 */
241
242template <typename Float>
243struct Result<Aapcs32, Float, typename std::enable_if_t<
244 std::is_floating_point_v<Float>>>
245{
246 static void
247 store(ThreadContext *tc, const Float &f, Aapcs32::State &state)
248 {
249 auto i = floatToBits(f);
251 };
252};
253
254template <typename Float>
255struct Argument<Aapcs32, Float, typename std::enable_if_t<
256 std::is_floating_point_v<Float>>> : public Aapcs32ArgumentBase
257{
258 static Float
260 {
261 if (sizeof(Float) == sizeof(uint32_t)) {
262 return bitsToFloat32(
264 } else {
265 return bitsToFloat64(
267 }
268 }
269};
270
271
272/*
273 * Composite arguments and return values.
274 */
275
276template <typename Composite>
277struct Result<Aapcs32, Composite, typename std::enable_if_t<
278 IsAapcs32CompositeV<Composite>>>
279{
280 static void
281 store(ThreadContext *tc, const Composite &composite,
282 Aapcs32::State &state)
283 {
284 if (sizeof(Composite) <= sizeof(uint32_t)) {
285 Composite cp = htog(composite, ArmISA::byteOrder(tc));
286 uint32_t val;
287 memcpy((void *)&val, (void *)&cp, sizeof(Composite));
290 } else {
291 VPtr<Composite> cp(state.retAddr, tc);
292 *cp = htog(composite, ArmISA::byteOrder(tc));
293 }
294 }
295
296 static void
298 {
299 if (sizeof(Composite) > sizeof(uint32_t))
300 state.retAddr = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
301 }
302};
303
304template <typename Composite>
305struct Argument<Aapcs32, Composite, typename std::enable_if_t<
306 IsAapcs32CompositeV<Composite>>> :
308{
309 static Composite
311 {
312 size_t bytes = sizeof(Composite);
313 using Chunk = uint32_t;
314
315 const size_t chunk_size = sizeof(Chunk);
316 const size_t regs = (bytes + chunk_size - 1) / chunk_size;
317
318 if (bytes <= chunk_size) {
319 if (state.ncrn++ <= state.MAX_CRN) {
320 alignas(alignof(Composite)) uint32_t val =
321 tc->getReg(ArmISA::intRegClass[state.ncrn++]);
323 return gtoh(*(Composite *)&val, ArmISA::byteOrder(tc));
324 }
325 }
326
327 if (alignof(Composite) == 8 && (state.ncrn % 2))
328 state.ncrn++;
329
330 if (state.ncrn + regs - 1 <= state.MAX_CRN) {
331 std::align_val_t align{alignof(Composite)};
332 auto buf = std::unique_ptr<uint8_t[]>(new (align) uint8_t[bytes]);
333 for (int i = 0; i < regs; i++) {
334 Chunk val = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
336 size_t to_copy = std::min(bytes, chunk_size);
337 memcpy(buf.get() + i * chunk_size, &val, to_copy);
338 bytes -= to_copy;
339 }
340 return gtoh(*(Composite *)buf.get(), ArmISA::byteOrder(tc));
341 }
342
343 if (!state.stackUsed && state.ncrn <= state.MAX_CRN) {
344 std::align_val_t align{alignof(Composite)};
345 auto buf = std::unique_ptr<uint8_t[]>(new (align) uint8_t[bytes]);
346
347 int offset = 0;
348 while (state.ncrn <= state.MAX_CRN) {
349 Chunk val = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
351 size_t to_copy = std::min(bytes, chunk_size);
352 memcpy(buf.get() + offset, &val, to_copy);
353 offset += to_copy;
354 bytes -= to_copy;
355 }
356
357 if (bytes) {
358 TranslatingPortProxy fs_proxy(tc);
359 SETranslatingPortProxy se_proxy(tc);
360 PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
361
362 virt_proxy.readBlob(
363 state.nsaa, buf.get(), bytes);
364
365 state.stackUsed = true;
366 state.nsaa += roundUp(bytes, 4);
367 state.ncrn = state.MAX_CRN + 1;
368 }
369
370 return gtoh(*(Composite *)buf, ArmISA::byteOrder(tc));
371 }
372
373 state.ncrn = state.MAX_CRN + 1;
374
375 return loadFromStack<Composite>(tc, state);
376 }
377};
378
379} // namespace guest_abi
380
381
382/*
383 * VFP ABI variant.
384 */
385
386struct Aapcs32Vfp : public Aapcs32
387{
388 struct State : public Aapcs32::State
389 {
390 bool variadic=false; // Whether this function is variadic.
391
392 // Whether the various single and double precision registers have
393 // been allocated.
394 std::array<bool, 16> s;
395 std::array<bool, 8> d;
396
397 explicit State(const ThreadContext *tc) : Aapcs32::State(tc)
398 {
399 s.fill(false);
400 d.fill(false);
401 }
402
403 int
404 allocate(float, int count)
405 {
406 int last = 0;
407 for (int i = 0; i <= s.size() - count; i++) {
408 if (s[i]) {
409 last = i + 1;
410 continue;
411 }
412 if (i - last + 1 == count) {
413 for (int j = 0; j < count; j++) {
414 s[last + j] = true;
415 d[(last + j) / 2] = true;
416 }
417 return last;
418 }
419 }
420 s.fill(true);
421 d.fill(true);
422 return -1;
423 }
424
425 int
426 allocate(double, int count)
427 {
428 int last = 0;
429 for (int i = 0; i <= d.size() - count; i++) {
430 if (d[i]) {
431 last = i + 1;
432 continue;
433 }
434 if (i - last + 1 == count) {
435 for (int j = 0; j < count; j++) {
436 d[last + j] = true;
437 s[(last + j) * 2] = true;
438 s[(last + j) * 2 + 1] = true;
439 }
440 return last;
441 }
442 }
443 s.fill(true);
444 d.fill(true);
445 return -1;
446 }
447 };
448};
449
450namespace guest_abi
451{
452
453/*
454 * Integer arguments and return values.
455 */
456
457template <typename Integer>
458struct Result<Aapcs32Vfp, Integer, typename std::enable_if_t<
459 std::is_integral_v<Integer>>> : public Result<Aapcs32, Integer>
460{};
461
462template <typename Integer>
463struct Argument<Aapcs32Vfp, Integer, typename std::enable_if_t<
464 std::is_integral_v<Integer>>> : public Argument<Aapcs32, Integer>
465{};
466
467
468/*
469 * Floating point arguments and return values.
470 */
471
472template <typename Float>
473struct Result<Aapcs32Vfp, Float, typename std::enable_if_t<
474 std::is_floating_point_v<Float>>>
475{
476 static void
477 store(ThreadContext *tc, const Float &f, Aapcs32Vfp::State &state)
478 {
479 if (state.variadic) {
480 storeResult<Aapcs32, Float>(tc, f, state);
481 return;
482 }
483
484 auto bytes = floatToBits(f);
485 auto *vec_elems = static_cast<ArmISA::VecElem *>(&bytes);
486 constexpr int chunks = sizeof(Float) / sizeof(ArmISA::VecElem);
487 for (int chunk = 0; chunk < chunks; chunk++)
488 tc->setReg(ArmISA::vecElemClass[chunk], vec_elems[chunk]);
489 };
490};
491
492template <typename Float>
493struct Argument<Aapcs32Vfp, Float, typename std::enable_if_t<
494 std::is_floating_point_v<Float>>> : public Aapcs32ArgumentBase
495{
496 static Float
498 {
499 if (state.variadic)
500 return getArgument<Aapcs32, Float>(tc, state);
501
502 const int index = state.allocate(Float{}, 1);
503
504 if (index < 0)
505 return loadFromStack<Float>(tc, state);
506
507 decltype(floatToBits(Float{})) result;
508 auto *vec_elems = static_cast<ArmISA::VecElem *>(&result);
509
510 constexpr int chunks = sizeof(Float) / sizeof(ArmISA::VecElem);
511 for (int chunk = 0; chunk < chunks; chunk++)
512 vec_elems[chunk] = tc->getReg(ArmISA::vecElemClass[chunk]);
513
514 return bitsToFloat(result);
515 }
516};
517
518
519/*
520 * Composite arguments and return values which are not Homogeneous Aggregates.
521 */
522
523template <typename Composite>
524struct Result<Aapcs32Vfp, Composite, typename std::enable_if_t<
525 IsAapcs32CompositeV<Composite> &&
526 !IsAapcs32HomogeneousAggregateV<Composite>>> :
527 public Result<Aapcs32, Composite>
528{};
529
530template <typename Composite>
531struct Argument<Aapcs32Vfp, Composite, typename std::enable_if_t<
532 IsAapcs32CompositeV<Composite> &&
533 !IsAapcs32HomogeneousAggregateV<Composite>>> :
534 public Argument<Aapcs32, Composite>
535{};
536
537
538/*
539 * Homogeneous Aggregate argument and return values.
540 */
541
542template <typename T>
543struct Aapcs32ArrayType { using Type = void; };
544
545template <typename E, size_t N>
546struct Aapcs32ArrayType<E[N]> { using Type = E; };
547
548template <typename HA>
549struct Argument<Aapcs32Vfp, HA, typename std::enable_if_t<
550 IsAapcs32HomogeneousAggregateV<HA>>> :
552{
553 static bool
555 {
556 using Elem = typename Aapcs32ArrayType<HA>::Type;
557 constexpr size_t Count = sizeof(HA) / sizeof(Elem);
558 return state.variadic || !std::is_floating_point_v<Elem> ||
559 Count > 4;
560 }
561
562 static HA
564 {
565 using Elem = typename Aapcs32ArrayType<HA>::Type;
566 constexpr size_t Count = sizeof(HA) / sizeof(Elem);
567
568 if (useBaseABI(state))
569 return getArgument<Aapcs32, HA>(tc, state);
570
571 const int base = state.allocate(Elem{}, Count);
572 if (base >= 0) {
573 constexpr int lane_per_reg = 16 / sizeof(Elem);
574 HA ha;
575 for (int i = 0; i < Count; i++) {
576 const int index = base + i;
577 const int reg = index / lane_per_reg;
578 const int lane = index % lane_per_reg;
579
582 tc->getReg(id, &val);
583 ha[i] = val.as<Elem>()[lane];
584 }
585 return ha;
586 }
587
588 return loadFromStack<HA>(tc, state);
589 }
590
591 static void
593 {
594 if (useBaseABI(state))
595 return Argument<Aapcs32, HA>::prepare(tc, state);
596 }
597};
598
599template <typename HA>
601 typename std::enable_if_t<IsAapcs32HomogeneousAggregateV<HA>>>
602{
603 static bool
605 {
606 using Elem = typename Aapcs32ArrayType<HA>::Type;
607 constexpr size_t Count = sizeof(HA) / sizeof(Elem);
608 return state.variadic || !std::is_floating_point_v<Elem> ||
609 Count > 4;
610 }
611
612 static HA
613 store(ThreadContext *tc, const HA &ha, Aapcs32Vfp::State &state)
614 {
615 using Elem = typename Aapcs32ArrayType<HA>::Type;
616 constexpr size_t Count = sizeof(HA) / sizeof(Elem);
617
618 if (useBaseABI(state)) {
619 storeResult<Aapcs32, HA>(tc, ha, state);
620 return;
621 }
622
623 constexpr int lane_per_reg = 16 / sizeof(Elem);
624 for (int i = 0; i < Count; i++) {
625 const int reg = i / lane_per_reg;
626 const int lane = i % lane_per_reg;
627
630 tc->getReg(id, &val);
631 val.as<Elem>()[lane] = ha[i];
632 tc->setReg(id, &val);
633 }
634 }
635
636 static void
638 {
639 if (useBaseABI(state))
640 return Result<Aapcs32, HA>::prepare(tc, state);
641 }
642};
643
644
645/*
646 * Varargs
647 */
648
649template <typename ...Types>
650struct Argument<Aapcs32Vfp, VarArgs<Types...>>
651{
652 static VarArgs<Types...>
653 get(ThreadContext *tc, typename Aapcs32Vfp::State &state)
654 {
655 state.variadic = true;
656 return getArgument<Aapcs32, VarArgs<Types...>>(tc, state);
657 }
658};
659
660} // namespace guest_abi
661} // namespace gem5
662
663#endif // __ARCH_ARM_AAPCS32_HH__
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition port_proxy.hh:87
void readBlob(Addr addr, void *p, uint64_t size) const
Higher level interfaces based on the above.
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId &reg) const
virtual void setReg(const RegId &reg, RegVal val)
This proxy attempts to translate virtual addresses using the TLBs.
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:260
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition bitfield.hh:129
constexpr RegId R1
Definition int.hh:187
constexpr RegId R0
Definition int.hh:186
ByteOrder byteOrder(const ThreadContext *tc)
Definition utility.hh:359
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
constexpr RegClass vecElemClass
Definition vec.hh:105
constexpr RegClass intRegClass
Definition int.hh:173
gem5::VecRegContainer< NumVecElemPerVecReg *sizeof(VecElem)> VecRegContainer
Definition vec.hh:64
Bitfield< 6 > f
Definition misc_types.hh:68
Bitfield< 39 > ha
uint32_t VecElem
Definition vec.hh:63
constexpr RegClass vecRegClass
Definition vec.hh:101
Bitfield< 30, 0 > index
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 31, 0 > E
Definition int.hh:56
Bitfield< 63 > val
Definition misc.hh:804
constexpr bool IsAapcs32CompositeV
Definition aapcs32.hh:92
constexpr bool IsAapcs32HomogeneousAggregateV
Definition aapcs32.hh:109
static void storeResult(ThreadContext *tc, const Ret &ret, typename ABI::State &state)
Definition layout.hh:163
T[count] Aapcs32HomogeneousAggregate
Definition aapcs32.hh:100
static Arg getArgument(ThreadContext *tc, typename ABI::State &state)
Definition layout.hh:170
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
static uint64_t floatToBits(double val)
Definition types.hh:202
ProxyPtr< T, SETranslatingPortProxy > VPtr
Definition proxy_ptr.hh:400
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
T gtoh(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:194
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
static double bitsToFloat(uint64_t val)
Definition types.hh:229
T htog(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:187
static double bitsToFloat64(uint64_t val)
Definition types.hh:218
static float bitsToFloat32(uint32_t val)
Definition types.hh:206
ConstProxyPtr< T, SETranslatingPortProxy > ConstVPtr
Definition proxy_ptr.hh:398
Overload hash function for BasicBlockRange type.
Definition binary32.hh:81
PortProxy Object Declaration.
std::array< bool, 16 > s
Definition aapcs32.hh:394
State(const ThreadContext *tc)
Definition aapcs32.hh:397
int allocate(double, int count)
Definition aapcs32.hh:426
int allocate(float, int count)
Definition aapcs32.hh:404
std::array< bool, 8 > d
Definition aapcs32.hh:395
static const int MAX_CRN
Definition aapcs32.hh:63
State(const ThreadContext *tc)
Definition aapcs32.hh:67
static T loadFromStack(ThreadContext *tc, Aapcs32::State &state)
Definition aapcs32.hh:116
static VarArgs< Types... > get(ThreadContext *tc, typename Aapcs32Vfp::State &state)
Definition aapcs32.hh:653
static void store(ThreadContext *tc, const Float &f, Aapcs32Vfp::State &state)
Definition aapcs32.hh:477
static void store(ThreadContext *tc, const Composite &composite, Aapcs32::State &state)
Definition aapcs32.hh:281
static void store(ThreadContext *tc, const Float &f, Aapcs32::State &state)
Definition aapcs32.hh:247

Generated on Mon May 26 2025 09:18:57 for gem5 by doxygen 1.13.2