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