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

Generated on Tue Sep 21 2021 12:25:48 for gem5 by doxygen 1.8.17