gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
37 namespace gem5
38 {
39 
40 class ThreadContext;
41 
42 namespace 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.
69 template <typename ...Types>
71 
72 template <typename First, typename ...Types>
73 class 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.
87 template <>
88 class VarArgsBase<>
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.
104 template <typename ABI, typename Base, typename ...Types>
106 
107 template <typename ABI, typename Base, typename First, typename ...Types>
108 class 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.
127 template <typename ABI, typename Base>
128 class 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.
148 template <typename ...Types>
149 class VarArgs
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
164  get()
165  {
166  Arg arg;
167  _ptr->_getImpl(arg);
168  return arg;
169  }
170 };
171 
172 template <typename T>
173 struct IsVarArgs : public std::false_type {};
174 
175 template <typename ...Types>
176 struct IsVarArgs<VarArgs<Types...>> : public std::true_type {};
177 
178 template <typename T>
180 
181 template <typename ...Types>
182 std::ostream &
183 operator << (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.
193 template <typename ABI, typename ...Types>
194 struct 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__
definition.hh
gem5::guest_abi::operator<<
std::ostream & operator<<(std::ostream &os, const VarArgs< Types... > &va)
Definition: varargs.hh:183
gem5::guest_abi::VarArgs::get
Arg get()
Definition: varargs.hh:164
gem5::guest_abi::Argument< ABI, VarArgs< Types... > >::get
static VarArgs< Types... > get(ThreadContext *tc, typename ABI::State &state)
Definition: varargs.hh:197
gem5::guest_abi::VarArgs::VarArgs
VarArgs(VarArgsBase< Types... > *ptr)
Definition: varargs.hh:157
gem5::auxv::Base
@ Base
Definition: aux_vector.hh:74
gem5::guest_abi::VarArgsImpl
Definition: varargs.hh:105
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
gem5::guest_abi::VarArgs::_ptr
std::shared_ptr< VarArgsBase< Types... > > _ptr
Definition: varargs.hh:154
gem5::guest_abi::VarArgsImpl< ABI, Base >::VarArgsImpl
VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state)
Definition: varargs.hh:141
gem5::guest_abi::IsVarArgsV
constexpr bool IsVarArgsV
Definition: varargs.hh:179
gem5::guest_abi::VarArgsBase
Definition: varargs.hh:70
gem5::guest_abi::VarArgsImpl< ABI, Base >::tc
ThreadContext * tc
Definition: varargs.hh:132
gem5::ArmISA::va
Bitfield< 8 > va
Definition: misc_types.hh:330
state
atomic_var_t state
Definition: helpers.cc:188
gem5::guest_abi::IsVarArgs
Definition: varargs.hh:173
gem5::X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:810
gem5::guest_abi::Argument
Definition: definition.hh:98
gem5::guest_abi::VarArgs
Definition: varargs.hh:149
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::guest_abi::VarArgsImpl< ABI, Base >::state
ABI::State state
Definition: varargs.hh:133
gem5::guest_abi::VarArgsImpl< ABI, Base, First, Types... >::_getImpl
void _getImpl(First &first) override
Definition: varargs.hh:120

Generated on Sun Jul 30 2023 01:56:59 for gem5 by doxygen 1.8.17