gem5
v24.0.0.0
Loading...
Searching...
No Matches
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
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>
70
class
VarArgsBase
;
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>
105
class
VarArgsImpl
;
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.
132
ThreadContext
*
tc
;
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
:
157
VarArgs
(
VarArgsBase<Types...>
*ptr) :
_ptr
(ptr) {}
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>
179
constexpr
bool
IsVarArgsV
=
IsVarArgs<T>::value
;
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__
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition
guest_abi.test.cc:41
gem5::guest_abi::VarArgsBase< First, Types... >::~VarArgsBase
virtual ~VarArgsBase()=default
gem5::guest_abi::VarArgsBase< First, Types... >::_getImpl
virtual void _getImpl(First &)=0
gem5::guest_abi::VarArgsBase<>::_getImpl
void _getImpl()
gem5::guest_abi::VarArgsBase
Definition
varargs.hh:70
gem5::guest_abi::VarArgsImpl< ABI, Base, First, Types... >::_getImpl
void _getImpl(First &first) override
Definition
varargs.hh:120
gem5::guest_abi::VarArgsImpl< ABI, Base >::VarArgsImpl
VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state)
Definition
varargs.hh:141
gem5::guest_abi::VarArgsImpl< ABI, Base >::_getImpl
void _getImpl()
gem5::guest_abi::VarArgsImpl< ABI, Base >::tc
ThreadContext * tc
Definition
varargs.hh:132
gem5::guest_abi::VarArgsImpl< ABI, Base >::state
ABI::State state
Definition
varargs.hh:133
gem5::guest_abi::VarArgsImpl
Definition
varargs.hh:105
gem5::guest_abi::VarArgs
Definition
varargs.hh:150
gem5::guest_abi::VarArgs::VarArgs
VarArgs(VarArgsBase< Types... > *ptr)
Definition
varargs.hh:157
gem5::guest_abi::VarArgs::get
Arg get()
Definition
varargs.hh:164
gem5::guest_abi::VarArgs::_ptr
std::shared_ptr< VarArgsBase< Types... > > _ptr
Definition
varargs.hh:154
definition.hh
state
atomic_var_t state
Definition
helpers.cc:211
gem5::ArmISA::va
Bitfield< 8 > va
Definition
misc_types.hh:356
gem5::X86ISA::os
Bitfield< 17 > os
Definition
misc.hh:838
gem5::guest_abi::IsVarArgsV
constexpr bool IsVarArgsV
Definition
varargs.hh:179
gem5::guest_abi::operator<<
std::ostream & operator<<(std::ostream &os, const VarArgs< Types... > &va)
Definition
varargs.hh:183
gem5
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition
binary32.hh:36
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::Argument
Definition
definition.hh:99
gem5::guest_abi::IsVarArgs
Definition
varargs.hh:173
Generated on Tue Jun 18 2024 16:24:06 for gem5 by
doxygen
1.11.0