gem5 v24.0.0.0
Loading...
Searching...
No Matches
varargs.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 __SIM_GUEST_ABI_VARARGS_HH__
29#define __SIM_GUEST_ABI_VARARGS_HH__
30
31#include <memory>
32#include <sstream>
33#include <type_traits>
34
36
37namespace gem5
38{
39
40class ThreadContext;
41
42namespace guest_abi
43{
44
45/*
46 * These templates implement a variadic argument mechanism for guest ABI
47 * functions. A function might be written like this:
48 *
49 * void
50 * func(ThreadContext *tc, VarArgs<Addr, int> varargs)
51 * {
52 * warn("Address = %#x, int = %d.",
53 * varargs.get<Addr>(), varargs.get<int>());
54 * }
55 *
56 * where an object of type VarArgs<...> is its last argument. The types given
57 * to the template specify what types the function might need to retrieve from
58 * varargs. The varargs object will then have get<> methods for each of those
59 * types.
60 *
61 * Note that each get<> will happen live. If you modify values through the
62 * ThreadContext *tc and then run get<>(), you may alter one of your arguments.
63 * If you're going to use tc to modify state, it would be a good idea to use
64 * get<>() as soon as possible to avoid corrupting the functions arguments.
65 */
66
67// A recursive template which defines virtual functions to retrieve each of the
68// requested types. This provides the ABI agnostic interface the function uses.
69template <typename ...Types>
71
72template <typename First, typename ...Types>
73class VarArgsBase<First, Types...> : public VarArgsBase<Types...>
74{
75 public:
76 virtual ~VarArgsBase() = default;
77
78 // The virtual function takes a reference parameter so that the different
79 // _getImpl methods can co-exist through overloading.
80 virtual void _getImpl(First &) = 0;
81
82 // Make sure base class _getImpl-es aren't hidden by this one.
83 using VarArgsBase<Types...>::_getImpl;
84};
85
86// The base case of the recursion.
87template <>
89{
90 protected:
91 // This just gives the "using" statement in the non base case something to
92 // refer to.
93 void _getImpl();
94};
95
96
97// A recursive template which defines the ABI specific implementation of the
98// interface defined above.
99//
100// The types in Types are consumed one by one, and by
101// the time we get down to the base case we'd have lost track of the complete
102// set we need to know what interface to inherit. The Base parameter keeps
103// track of that through the recursion.
104template <typename ABI, typename Base, typename ...Types>
106
107template <typename ABI, typename Base, typename First, typename ...Types>
108class VarArgsImpl<ABI, Base, First, Types...> :
109 public VarArgsImpl<ABI, Base, Types...>
110{
111 protected:
112 // Bring forward the base class constructor.
113 using VarArgsImpl<ABI, Base, Types...>::VarArgsImpl;
114 // Make sure base class _getImpl-es don't get hidden by ours.
115 using VarArgsImpl<ABI, Base, Types...>::_getImpl;
116
117 // Implement a version of _getImple, using the ABI specialized version of
118 // the Argument class.
119 void
120 _getImpl(First &first) override
121 {
122 first = Argument<ABI, First>::get(this->tc, this->state);
123 }
124};
125
126// The base case of the recursion, which inherits from the interface class.
127template <typename ABI, typename Base>
128class VarArgsImpl<ABI, Base> : public Base
129{
130 protected:
131 // Declare state to pass to the Argument<>::get methods.
133 typename ABI::State state;
134 // Make sure base class _getImpl-es don't get hidden by ours.
135 using Base::_getImpl;
136
137 // Give the "using" statement in our subclass something to refer to.
138 void _getImpl();
139
140 public:
141 VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state) :
142 tc(_tc), state(_state)
143 {}
144};
145
146// A wrapper which provides a nice interface to the virtual functions, and a
147// hook for the Argument template mechanism.
148template <typename ...Types>
150{
151 private:
152 // This points to the implementation which knows how to read arguments
153 // based on the ABI being used.
154 std::shared_ptr<VarArgsBase<Types...>> _ptr;
155
156 public:
158
159 // This template is a friendlier wrapper around the virtual functions the
160 // raw interface provides. This version lets you pick a type which it then
161 // returns, instead of having to pre-declare a variable to pass in.
162 template <typename Arg>
163 Arg
165 {
166 Arg arg;
167 _ptr->_getImpl(arg);
168 return arg;
169 }
170};
171
172template <typename T>
173struct IsVarArgs : public std::false_type {};
174
175template <typename ...Types>
176struct IsVarArgs<VarArgs<Types...>> : public std::true_type {};
177
178template <typename T>
180
181template <typename ...Types>
182std::ostream &
183operator << (std::ostream &os, const VarArgs<Types...> &va)
184{
185 os << "...";
186 return os;
187}
188
189// The ABI independent hook which tells the guest_abi mechanism what to do with
190// a VarArgs argument. It constructs the underlying implementation which knows
191// about the ABI, and installs it in the VarArgs wrapper to give to the
192// function.
193template <typename ABI, typename ...Types>
194struct Argument<ABI, VarArgs<Types...>>
195{
196 static VarArgs<Types...>
197 get(ThreadContext *tc, typename ABI::State &state)
198 {
199 using Base = VarArgsBase<Types...>;
200 using Impl = VarArgsImpl<ABI, Base, Types...>;
201 return VarArgs<Types...>(new Impl(tc, state));
202 }
203};
204
205} // namespace guest_abi
206} // namespace gem5
207
208#endif // __SIM_GUEST_ABI_VARARGS_HH__
ThreadContext is the external interface to all thread state for anything outside of the CPU.
VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state)
Definition varargs.hh:141
VarArgs(VarArgsBase< Types... > *ptr)
Definition varargs.hh:157
std::shared_ptr< VarArgsBase< Types... > > _ptr
Definition varargs.hh:154
atomic_var_t state
Definition helpers.cc:211
Bitfield< 8 > va
Bitfield< 17 > os
Definition misc.hh:838
constexpr bool IsVarArgsV
Definition varargs.hh:179
std::ostream & operator<<(std::ostream &os, const VarArgs< Types... > &va)
Definition varargs.hh:183
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
static VarArgs< Types... > get(ThreadContext *tc, typename ABI::State &state)
Definition varargs.hh:197

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0