xref: /aosp_15_r20/external/swiftshader/src/Reactor/Print.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #ifndef rr_Print_hpp
16*03ce13f7SAndroid Build Coastguard Worker #define rr_Print_hpp
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #ifdef ENABLE_RR_PRINT
19*03ce13f7SAndroid Build Coastguard Worker 
20*03ce13f7SAndroid Build Coastguard Worker #	include "Reactor.hpp"
21*03ce13f7SAndroid Build Coastguard Worker #	include "SIMD.hpp"
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker #	include <string>
24*03ce13f7SAndroid Build Coastguard Worker #	include <vector>
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker namespace rr {
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker // PrintValue holds the printf format and value(s) for a single argument
29*03ce13f7SAndroid Build Coastguard Worker // to Print(). A single argument can be expanded into multiple printf
30*03ce13f7SAndroid Build Coastguard Worker // values - for example a Float4 will expand to "%f %f %f %f" and four
31*03ce13f7SAndroid Build Coastguard Worker // scalar values.
32*03ce13f7SAndroid Build Coastguard Worker // The PrintValue constructor accepts the following:
33*03ce13f7SAndroid Build Coastguard Worker //   * Reactor LValues, RValues, Pointers.
34*03ce13f7SAndroid Build Coastguard Worker //   * Standard Plain-Old-Value types (int, float, bool, etc)
35*03ce13f7SAndroid Build Coastguard Worker //   * Custom types that specialize the PrintValue::Ty template struct.
36*03ce13f7SAndroid Build Coastguard Worker //   * Static arrays in the form T[N] where T can be any of the above.
37*03ce13f7SAndroid Build Coastguard Worker class PrintValue
38*03ce13f7SAndroid Build Coastguard Worker {
39*03ce13f7SAndroid Build Coastguard Worker public:
40*03ce13f7SAndroid Build Coastguard Worker 	// Ty is a template that can be specialized for printing type T.
41*03ce13f7SAndroid Build Coastguard Worker 	// Each specialization must expose:
42*03ce13f7SAndroid Build Coastguard Worker 	//  * A 'static std::string fmt(const T& v)' method that provides the
43*03ce13f7SAndroid Build Coastguard Worker 	//    printf format specifier.
44*03ce13f7SAndroid Build Coastguard Worker 	//  * A 'static std::vector<rr::Value*> val(const T& v)' method that
45*03ce13f7SAndroid Build Coastguard Worker 	//    returns all the printf format values.
46*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
47*03ce13f7SAndroid Build Coastguard Worker 	struct Ty
48*03ce13f7SAndroid Build Coastguard Worker 	{
49*03ce13f7SAndroid Build Coastguard Worker 		// static std::string fmt(const T& v);
50*03ce13f7SAndroid Build Coastguard Worker 		// static std::vector<rr::Value*> val(const T& v);
51*03ce13f7SAndroid Build Coastguard Worker 	};
52*03ce13f7SAndroid Build Coastguard Worker 
53*03ce13f7SAndroid Build Coastguard Worker 	// returns the printf values for all the values in the given array.
54*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
val(const T * list,int count)55*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const T *list, int count)
56*03ce13f7SAndroid Build Coastguard Worker 	{
57*03ce13f7SAndroid Build Coastguard Worker 		std::vector<Value *> values;
58*03ce13f7SAndroid Build Coastguard Worker 		values.reserve(count);
59*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 0; i < count; i++)
60*03ce13f7SAndroid Build Coastguard Worker 		{
61*03ce13f7SAndroid Build Coastguard Worker 			auto v = val(list[i]);
62*03ce13f7SAndroid Build Coastguard Worker 			values.insert(values.end(), v.begin(), v.end());
63*03ce13f7SAndroid Build Coastguard Worker 		}
64*03ce13f7SAndroid Build Coastguard Worker 		return values;
65*03ce13f7SAndroid Build Coastguard Worker 	}
66*03ce13f7SAndroid Build Coastguard Worker 
67*03ce13f7SAndroid Build Coastguard Worker 	// fmt returns the comma-delimited list of printf format strings for
68*03ce13f7SAndroid Build Coastguard Worker 	// every element in the provided list, all enclosed in square brackets.
69*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
fmt(const T * list,int count)70*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const T *list, int count)
71*03ce13f7SAndroid Build Coastguard Worker 	{
72*03ce13f7SAndroid Build Coastguard Worker 		std::string out = "[";
73*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 0; i < count; i++)
74*03ce13f7SAndroid Build Coastguard Worker 		{
75*03ce13f7SAndroid Build Coastguard Worker 			if(i > 0) { out += ", "; }
76*03ce13f7SAndroid Build Coastguard Worker 			out += fmt(list[i]);
77*03ce13f7SAndroid Build Coastguard Worker 		}
78*03ce13f7SAndroid Build Coastguard Worker 		return out + "]";
79*03ce13f7SAndroid Build Coastguard Worker 	}
80*03ce13f7SAndroid Build Coastguard Worker 
addr(const void * ptr)81*03ce13f7SAndroid Build Coastguard Worker 	static std::string addr(const void *ptr)
82*03ce13f7SAndroid Build Coastguard Worker 	{
83*03ce13f7SAndroid Build Coastguard Worker 		char buf[32];
84*03ce13f7SAndroid Build Coastguard Worker 		snprintf(buf, sizeof(buf), "%p", ptr);
85*03ce13f7SAndroid Build Coastguard Worker 		return buf;
86*03ce13f7SAndroid Build Coastguard Worker 	}
87*03ce13f7SAndroid Build Coastguard Worker 
88*03ce13f7SAndroid Build Coastguard Worker 	const std::string format;
89*03ce13f7SAndroid Build Coastguard Worker 	const std::vector<Value *> values;
90*03ce13f7SAndroid Build Coastguard Worker 
91*03ce13f7SAndroid Build Coastguard Worker 	// Constructs a PrintValue for the given value.
92*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
PrintValue(const T & v)93*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(const T &v)
94*03ce13f7SAndroid Build Coastguard Worker 	    : format(fmt(v))
95*03ce13f7SAndroid Build Coastguard Worker 	    , values(val(v))
96*03ce13f7SAndroid Build Coastguard Worker 	{}
97*03ce13f7SAndroid Build Coastguard Worker 
98*03ce13f7SAndroid Build Coastguard Worker 	// Constructs a PrintValue for the given static array.
99*03ce13f7SAndroid Build Coastguard Worker 	template<typename T, int N>
PrintValue(const T (& v)[N])100*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(const T (&v)[N])
101*03ce13f7SAndroid Build Coastguard Worker 	    : format(fmt(&v[0], N))
102*03ce13f7SAndroid Build Coastguard Worker 	    , values(val(&v[0], N))
103*03ce13f7SAndroid Build Coastguard Worker 	{}
104*03ce13f7SAndroid Build Coastguard Worker 
105*03ce13f7SAndroid Build Coastguard Worker 	// Constructs a PrintValue for the given array starting at arr of length
106*03ce13f7SAndroid Build Coastguard Worker 	// len.
107*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
PrintValue(const T * arr,int len)108*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(const T *arr, int len)
109*03ce13f7SAndroid Build Coastguard Worker 	    : format(fmt(arr, len))
110*03ce13f7SAndroid Build Coastguard Worker 	    , values(val(arr, len))
111*03ce13f7SAndroid Build Coastguard Worker 	{}
112*03ce13f7SAndroid Build Coastguard Worker 
113*03ce13f7SAndroid Build Coastguard Worker 	// PrintValue constructors for plain-old-data values.
PrintValue(bool v)114*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(bool v)
115*03ce13f7SAndroid Build Coastguard Worker 	    : format(v ? "true" : "false")
116*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(int8_t v)117*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(int8_t v)
118*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
119*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(uint8_t v)120*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(uint8_t v)
121*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
122*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(int16_t v)123*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(int16_t v)
124*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
125*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(uint16_t v)126*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(uint16_t v)
127*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
128*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(int32_t v)129*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(int32_t v)
130*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
131*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(uint32_t v)132*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(uint32_t v)
133*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
134*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(int64_t v)135*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(int64_t v)
136*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
137*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(uint64_t v)138*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(uint64_t v)
139*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
140*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(float v)141*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(float v)
142*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
143*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(double v)144*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(double v)
145*03ce13f7SAndroid Build Coastguard Worker 	    : format(std::to_string(v))
146*03ce13f7SAndroid Build Coastguard Worker 	{}
PrintValue(const char * v)147*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(const char *v)
148*03ce13f7SAndroid Build Coastguard Worker 	    : format(v)
149*03ce13f7SAndroid Build Coastguard Worker 	{}
150*03ce13f7SAndroid Build Coastguard Worker 
151*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
PrintValue(T * v)152*03ce13f7SAndroid Build Coastguard Worker 	PrintValue(T *v)
153*03ce13f7SAndroid Build Coastguard Worker 	    : format(addr(v))
154*03ce13f7SAndroid Build Coastguard Worker 	{}
155*03ce13f7SAndroid Build Coastguard Worker 
156*03ce13f7SAndroid Build Coastguard Worker 	// vals is a helper to build composite value lists.
157*03ce13f7SAndroid Build Coastguard Worker 	// vals returns the full, sequential list of printf argument values used
158*03ce13f7SAndroid Build Coastguard Worker 	// to print all the provided variadic values.
159*03ce13f7SAndroid Build Coastguard Worker 	// vals() is intended to be used by implementations of
160*03ce13f7SAndroid Build Coastguard Worker 	// PrintValue::Ty<>::vals() to help declare aggregate types.
161*03ce13f7SAndroid Build Coastguard Worker 	// For example, if you were declaring a PrintValue::Ty<> specialization
162*03ce13f7SAndroid Build Coastguard Worker 	// for a custom Mat4x4 matrix formed from four Vector4 values, you'd
163*03ce13f7SAndroid Build Coastguard Worker 	// write:
164*03ce13f7SAndroid Build Coastguard Worker 	//
165*03ce13f7SAndroid Build Coastguard Worker 	// namespace rr
166*03ce13f7SAndroid Build Coastguard Worker 	// {
167*03ce13f7SAndroid Build Coastguard Worker 	//		template <> struct PrintValue::Ty<Mat4x4>
168*03ce13f7SAndroid Build Coastguard Worker 	//		{
169*03ce13f7SAndroid Build Coastguard Worker 	//			static std::string fmt(const Mat4x4& v)
170*03ce13f7SAndroid Build Coastguard Worker 	//			{
171*03ce13f7SAndroid Build Coastguard Worker 	//				return	"[a: <%f, %f, %f, %f>,"
172*03ce13f7SAndroid Build Coastguard Worker 	//				        " b: <%f, %f, %f, %f>,"
173*03ce13f7SAndroid Build Coastguard Worker 	//				        " c: <%f, %f, %f, %f>,"
174*03ce13f7SAndroid Build Coastguard Worker 	//				        " d: <%f, %f, %f, %f>]";
175*03ce13f7SAndroid Build Coastguard Worker 	//			}
176*03ce13f7SAndroid Build Coastguard Worker 	//			static std::vector<rr::Value*> val(const Mat4x4& v)
177*03ce13f7SAndroid Build Coastguard Worker 	//			{
178*03ce13f7SAndroid Build Coastguard Worker 	//				return PrintValue::vals(v.a, v.b, v.c, v.d);
179*03ce13f7SAndroid Build Coastguard Worker 	//			}
180*03ce13f7SAndroid Build Coastguard Worker 	//		};
181*03ce13f7SAndroid Build Coastguard Worker 	//	}
182*03ce13f7SAndroid Build Coastguard Worker 	template<typename... ARGS>
vals(ARGS...v)183*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> vals(ARGS... v)
184*03ce13f7SAndroid Build Coastguard Worker 	{
185*03ce13f7SAndroid Build Coastguard Worker 		std::vector<std::vector<Value *>> lists = { val(v)... };
186*03ce13f7SAndroid Build Coastguard Worker 		std::vector<Value *> joined;
187*03ce13f7SAndroid Build Coastguard Worker 		for(const auto &list : lists)
188*03ce13f7SAndroid Build Coastguard Worker 		{
189*03ce13f7SAndroid Build Coastguard Worker 			joined.insert(joined.end(), list.begin(), list.end());
190*03ce13f7SAndroid Build Coastguard Worker 		}
191*03ce13f7SAndroid Build Coastguard Worker 		return joined;
192*03ce13f7SAndroid Build Coastguard Worker 	}
193*03ce13f7SAndroid Build Coastguard Worker 
194*03ce13f7SAndroid Build Coastguard Worker 	// returns the printf format specifier for the given type via the
195*03ce13f7SAndroid Build Coastguard Worker 	// PrintValue::Ty<T> specialization.
196*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
fmt(const T & v)197*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const T &v)
198*03ce13f7SAndroid Build Coastguard Worker 	{
199*03ce13f7SAndroid Build Coastguard Worker 		return Ty<T>::fmt(v);
200*03ce13f7SAndroid Build Coastguard Worker 	}
201*03ce13f7SAndroid Build Coastguard Worker 
202*03ce13f7SAndroid Build Coastguard Worker 	// returns the printf value for the given type with a
203*03ce13f7SAndroid Build Coastguard Worker 	// PrintValue::Ty<T> specialization.
204*03ce13f7SAndroid Build Coastguard Worker 	template<typename T>
val(const T & v)205*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const T &v)
206*03ce13f7SAndroid Build Coastguard Worker 	{
207*03ce13f7SAndroid Build Coastguard Worker 		return Ty<T>::val(v);
208*03ce13f7SAndroid Build Coastguard Worker 	}
209*03ce13f7SAndroid Build Coastguard Worker };
210*03ce13f7SAndroid Build Coastguard Worker 
211*03ce13f7SAndroid Build Coastguard Worker // PrintValue::Ty<T> specializations for basic types.
212*03ce13f7SAndroid Build Coastguard Worker template<>
213*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<const char *>
214*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty215*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const char *v) { return "%s"; }
216*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const char *v);
217*03ce13f7SAndroid Build Coastguard Worker };
218*03ce13f7SAndroid Build Coastguard Worker template<>
219*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<std::string>
220*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty221*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const std::string &v) { return PrintValue::Ty<const char *>::fmt(v.c_str()); }
valrr::PrintValue::Ty222*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const std::string &v) { return PrintValue::Ty<const char *>::val(v.c_str()); }
223*03ce13f7SAndroid Build Coastguard Worker };
224*03ce13f7SAndroid Build Coastguard Worker 
225*03ce13f7SAndroid Build Coastguard Worker // PrintValue::Ty<T> specializations for standard Reactor types.
226*03ce13f7SAndroid Build Coastguard Worker template<>
227*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Bool>
228*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty229*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Bool> &v) { return "%s"; }
230*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Bool> &v);
231*03ce13f7SAndroid Build Coastguard Worker };
232*03ce13f7SAndroid Build Coastguard Worker template<>
233*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Byte>
234*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty235*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Byte> &v) { return "%d"; }
236*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Byte> &v);
237*03ce13f7SAndroid Build Coastguard Worker };
238*03ce13f7SAndroid Build Coastguard Worker template<>
239*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Byte4>
240*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty241*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Byte4> &v) { return "[%d, %d, %d, %d]"; }
242*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Byte4> &v);
243*03ce13f7SAndroid Build Coastguard Worker };
244*03ce13f7SAndroid Build Coastguard Worker template<>
245*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Int>
246*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty247*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Int> &v) { return "%d"; }
248*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Int> &v);
249*03ce13f7SAndroid Build Coastguard Worker };
250*03ce13f7SAndroid Build Coastguard Worker template<>
251*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Int2>
252*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty253*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Int2> &v) { return "[%d, %d]"; }
254*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Int2> &v);
255*03ce13f7SAndroid Build Coastguard Worker };
256*03ce13f7SAndroid Build Coastguard Worker template<>
257*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Int4>
258*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty259*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Int4> &v) { return "[%d, %d, %d, %d]"; }
260*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Int4> &v);
261*03ce13f7SAndroid Build Coastguard Worker };
262*03ce13f7SAndroid Build Coastguard Worker template<>
263*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<UInt>
264*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty265*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<UInt> &v) { return "%u"; }
266*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<UInt> &v);
267*03ce13f7SAndroid Build Coastguard Worker };
268*03ce13f7SAndroid Build Coastguard Worker template<>
269*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<UInt2>
270*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty271*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<UInt2> &v) { return "[%u, %u]"; }
272*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<UInt2> &v);
273*03ce13f7SAndroid Build Coastguard Worker };
274*03ce13f7SAndroid Build Coastguard Worker template<>
275*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<UInt4>
276*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty277*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<UInt4> &v) { return "[%u, %u, %u, %u]"; }
278*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<UInt4> &v);
279*03ce13f7SAndroid Build Coastguard Worker };
280*03ce13f7SAndroid Build Coastguard Worker template<>
281*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Short>
282*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty283*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Short> &v) { return "%d"; }
284*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Short> &v);
285*03ce13f7SAndroid Build Coastguard Worker };
286*03ce13f7SAndroid Build Coastguard Worker template<>
287*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Short4>
288*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty289*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Short4> &v) { return "[%d, %d, %d, %d]"; }
290*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Short4> &v);
291*03ce13f7SAndroid Build Coastguard Worker };
292*03ce13f7SAndroid Build Coastguard Worker template<>
293*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<UShort>
294*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty295*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<UShort> &v) { return "%u"; }
296*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<UShort> &v);
297*03ce13f7SAndroid Build Coastguard Worker };
298*03ce13f7SAndroid Build Coastguard Worker template<>
299*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<UShort4>
300*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty301*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<UShort4> &v) { return "[%u, %u, %u, %u]"; }
302*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<UShort4> &v);
303*03ce13f7SAndroid Build Coastguard Worker };
304*03ce13f7SAndroid Build Coastguard Worker template<>
305*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Float>
306*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty307*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Float> &v) { return "%f"; }
308*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Float> &v);
309*03ce13f7SAndroid Build Coastguard Worker };
310*03ce13f7SAndroid Build Coastguard Worker template<>
311*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Float4>
312*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty313*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Float4> &v) { return "[%f, %f, %f, %f]"; }
314*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Float4> &v);
315*03ce13f7SAndroid Build Coastguard Worker };
316*03ce13f7SAndroid Build Coastguard Worker template<>
317*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Long>
318*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty319*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Long> &v) { return "%lld"; }
valrr::PrintValue::Ty320*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Long> &v) { return { v.value() }; }
321*03ce13f7SAndroid Build Coastguard Worker };
322*03ce13f7SAndroid Build Coastguard Worker template<typename T>
323*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Pointer<T>>
324*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty325*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<Pointer<T>> &v) { return "%p"; }
valrr::PrintValue::Ty326*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<Pointer<T>> &v) { return { v.value() }; }
327*03ce13f7SAndroid Build Coastguard Worker };
328*03ce13f7SAndroid Build Coastguard Worker template<>
329*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<SIMD::Pointer>
330*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty331*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const SIMD::Pointer &v)
332*03ce13f7SAndroid Build Coastguard Worker 	{
333*03ce13f7SAndroid Build Coastguard Worker 		if(v.isBasePlusOffset)
334*03ce13f7SAndroid Build Coastguard Worker 		{
335*03ce13f7SAndroid Build Coastguard Worker 			std::string format;
336*03ce13f7SAndroid Build Coastguard Worker 			for(int i = 1; i < SIMD::Width; i++) { format += ", %d"; }
337*03ce13f7SAndroid Build Coastguard Worker 			return "{%p + [%d" + format + "]}";
338*03ce13f7SAndroid Build Coastguard Worker 		}
339*03ce13f7SAndroid Build Coastguard Worker 		else
340*03ce13f7SAndroid Build Coastguard Worker 		{
341*03ce13f7SAndroid Build Coastguard Worker 			std::string format;
342*03ce13f7SAndroid Build Coastguard Worker 			for(int i = 1; i < SIMD::Width; i++) { format += ", %p"; }
343*03ce13f7SAndroid Build Coastguard Worker 			return "{%p" + format + "}";
344*03ce13f7SAndroid Build Coastguard Worker 		}
345*03ce13f7SAndroid Build Coastguard Worker 	}
346*03ce13f7SAndroid Build Coastguard Worker 
valrr::PrintValue::Ty347*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const SIMD::Pointer &v)
348*03ce13f7SAndroid Build Coastguard Worker 	{
349*03ce13f7SAndroid Build Coastguard Worker 		return v.getPrintValues();
350*03ce13f7SAndroid Build Coastguard Worker 	}
351*03ce13f7SAndroid Build Coastguard Worker };
352*03ce13f7SAndroid Build Coastguard Worker template<>
353*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<SIMD::Int>
354*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty355*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<SIMD::Int> &v)
356*03ce13f7SAndroid Build Coastguard Worker 	{
357*03ce13f7SAndroid Build Coastguard Worker 		std::string format;
358*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 1; i < SIMD::Width; i++) { format += ", %d"; }
359*03ce13f7SAndroid Build Coastguard Worker 		return "[%d" + format + "]";
360*03ce13f7SAndroid Build Coastguard Worker 	}
361*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<SIMD::Int> &v);
362*03ce13f7SAndroid Build Coastguard Worker };
363*03ce13f7SAndroid Build Coastguard Worker template<>
364*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<SIMD::UInt>
365*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty366*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<SIMD::UInt> &v)
367*03ce13f7SAndroid Build Coastguard Worker 	{
368*03ce13f7SAndroid Build Coastguard Worker 		std::string format;
369*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 1; i < SIMD::Width; i++) { format += ", %u"; }
370*03ce13f7SAndroid Build Coastguard Worker 		return "[%u" + format + "]";
371*03ce13f7SAndroid Build Coastguard Worker 	}
372*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<SIMD::UInt> &v);
373*03ce13f7SAndroid Build Coastguard Worker };
374*03ce13f7SAndroid Build Coastguard Worker template<>
375*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<SIMD::Float>
376*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty377*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<SIMD::Float> &v)
378*03ce13f7SAndroid Build Coastguard Worker 	{
379*03ce13f7SAndroid Build Coastguard Worker 		std::string format;
380*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 1; i < SIMD::Width; i++) { format += ", %f"; }
381*03ce13f7SAndroid Build Coastguard Worker 		return "[%f" + format + "]";
382*03ce13f7SAndroid Build Coastguard Worker 	}
383*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<SIMD::Float> &v);
384*03ce13f7SAndroid Build Coastguard Worker };
385*03ce13f7SAndroid Build Coastguard Worker template<typename T>
386*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<Reference<T>>
387*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty388*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const Reference<T> &v) { return PrintValue::Ty<T>::fmt(v); }
valrr::PrintValue::Ty389*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const Reference<T> &v) { return PrintValue::Ty<T>::val(v); }
390*03ce13f7SAndroid Build Coastguard Worker };
391*03ce13f7SAndroid Build Coastguard Worker template<typename T>
392*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<RValue<T>>
393*03ce13f7SAndroid Build Coastguard Worker {
fmtrr::PrintValue::Ty394*03ce13f7SAndroid Build Coastguard Worker 	static std::string fmt(const RValue<T> &v) { return PrintValue::Ty<T>::fmt(v); }
valrr::PrintValue::Ty395*03ce13f7SAndroid Build Coastguard Worker 	static std::vector<Value *> val(const RValue<T> &v) { return PrintValue::Ty<T>::val(v); }
396*03ce13f7SAndroid Build Coastguard Worker };
397*03ce13f7SAndroid Build Coastguard Worker 
398*03ce13f7SAndroid Build Coastguard Worker // VPrintf emits a call to printf() using vals[0] as the format string,
399*03ce13f7SAndroid Build Coastguard Worker // and vals[1..n] as the args.
400*03ce13f7SAndroid Build Coastguard Worker void VPrintf(const std::vector<Value *> &vals);
401*03ce13f7SAndroid Build Coastguard Worker 
402*03ce13f7SAndroid Build Coastguard Worker // Printv emits a call to printf() using the function, file and line,
403*03ce13f7SAndroid Build Coastguard Worker // message and optional values.
404*03ce13f7SAndroid Build Coastguard Worker // See Printv below.
405*03ce13f7SAndroid Build Coastguard Worker void Printv(const char *function, const char *file, int line, const char *msg, std::initializer_list<PrintValue> vals);
406*03ce13f7SAndroid Build Coastguard Worker 
407*03ce13f7SAndroid Build Coastguard Worker // Printv emits a call to printf() using the provided message and optional
408*03ce13f7SAndroid Build Coastguard Worker // values.
409*03ce13f7SAndroid Build Coastguard Worker // Printf replaces any bracketed indices in the message with string
410*03ce13f7SAndroid Build Coastguard Worker // representations of the corresponding value in vals.
411*03ce13f7SAndroid Build Coastguard Worker // For example:
412*03ce13f7SAndroid Build Coastguard Worker //   Printv("{0} and {1}", "red", "green");
413*03ce13f7SAndroid Build Coastguard Worker // Would print the string:
414*03ce13f7SAndroid Build Coastguard Worker //   "red and green"
415*03ce13f7SAndroid Build Coastguard Worker // Arguments can be indexed in any order.
416*03ce13f7SAndroid Build Coastguard Worker // Invalid indices are not substituted.
Printv(const char * msg,std::initializer_list<PrintValue> vals)417*03ce13f7SAndroid Build Coastguard Worker inline void Printv(const char *msg, std::initializer_list<PrintValue> vals)
418*03ce13f7SAndroid Build Coastguard Worker {
419*03ce13f7SAndroid Build Coastguard Worker 	Printv(nullptr, nullptr, 0, msg, vals);
420*03ce13f7SAndroid Build Coastguard Worker }
421*03ce13f7SAndroid Build Coastguard Worker 
422*03ce13f7SAndroid Build Coastguard Worker // Print is a wrapper over Printv that wraps the variadic arguments into an
423*03ce13f7SAndroid Build Coastguard Worker // initializer_list before calling Printv.
424*03ce13f7SAndroid Build Coastguard Worker template<typename... ARGS>
Print(const char * msg,const ARGS &...vals)425*03ce13f7SAndroid Build Coastguard Worker void Print(const char *msg, const ARGS &...vals)
426*03ce13f7SAndroid Build Coastguard Worker {
427*03ce13f7SAndroid Build Coastguard Worker 	Printv(msg, { vals... });
428*03ce13f7SAndroid Build Coastguard Worker }
429*03ce13f7SAndroid Build Coastguard Worker 
430*03ce13f7SAndroid Build Coastguard Worker // Print is a wrapper over Printv that wraps the variadic arguments into an
431*03ce13f7SAndroid Build Coastguard Worker // initializer_list before calling Printv.
432*03ce13f7SAndroid Build Coastguard Worker template<typename... ARGS>
Print(const char * function,const char * file,int line,const char * msg,const ARGS &...vals)433*03ce13f7SAndroid Build Coastguard Worker void Print(const char *function, const char *file, int line, const char *msg, const ARGS &...vals)
434*03ce13f7SAndroid Build Coastguard Worker {
435*03ce13f7SAndroid Build Coastguard Worker 	Printv(function, file, line, msg, { vals... });
436*03ce13f7SAndroid Build Coastguard Worker }
437*03ce13f7SAndroid Build Coastguard Worker 
438*03ce13f7SAndroid Build Coastguard Worker // RR_LOG is a macro that calls Print(), automatically populating the
439*03ce13f7SAndroid Build Coastguard Worker // function, file and line parameters and appending a newline to the string.
440*03ce13f7SAndroid Build Coastguard Worker //
441*03ce13f7SAndroid Build Coastguard Worker // RR_LOG() is intended to be used for debugging JIT compiled code, and is
442*03ce13f7SAndroid Build Coastguard Worker // not intended for production use.
443*03ce13f7SAndroid Build Coastguard Worker #	if defined(_WIN32)
444*03ce13f7SAndroid Build Coastguard Worker #		define RR_LOG(msg, ...) Print(__FUNCSIG__, __FILE__, static_cast<int>(__LINE__), msg "\n", ##__VA_ARGS__)
445*03ce13f7SAndroid Build Coastguard Worker #	else
446*03ce13f7SAndroid Build Coastguard Worker #		define RR_LOG(msg, ...) Print(__PRETTY_FUNCTION__, __FILE__, static_cast<int>(__LINE__), msg "\n", ##__VA_ARGS__)
447*03ce13f7SAndroid Build Coastguard Worker #	endif
448*03ce13f7SAndroid Build Coastguard Worker 
449*03ce13f7SAndroid Build Coastguard Worker // Macro magic to perform variadic dispatch.
450*03ce13f7SAndroid Build Coastguard Worker // See: https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/preprocessor/macros/__VA_ARGS__/count-arguments
451*03ce13f7SAndroid Build Coastguard Worker // Note, this doesn't attempt to use the ##__VA_ARGS__ trick to handle 0
452*03ce13f7SAndroid Build Coastguard Worker #	define RR_MSVC_EXPAND_BUG(X) X  // Helper macro to force expanding __VA_ARGS__ to satisfy MSVC compiler.
453*03ce13f7SAndroid Build Coastguard Worker #	define RR_GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
454*03ce13f7SAndroid Build Coastguard Worker #	define RR_COUNT_ARGUMENTS(...) RR_MSVC_EXPAND_BUG(RR_GET_NTH_ARG(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
455*03ce13f7SAndroid Build Coastguard Worker static_assert(1 == RR_COUNT_ARGUMENTS(a), "RR_COUNT_ARGUMENTS broken");  // Sanity checks.
456*03ce13f7SAndroid Build Coastguard Worker static_assert(2 == RR_COUNT_ARGUMENTS(a, b), "RR_COUNT_ARGUMENTS broken");
457*03ce13f7SAndroid Build Coastguard Worker static_assert(3 == RR_COUNT_ARGUMENTS(a, b, c), "RR_COUNT_ARGUMENTS broken");
458*03ce13f7SAndroid Build Coastguard Worker 
459*03ce13f7SAndroid Build Coastguard Worker // RR_WATCH_FMT(...) resolves to a string literal that lists all the
460*03ce13f7SAndroid Build Coastguard Worker // arguments by name. This string can be passed to LOG() to print each of
461*03ce13f7SAndroid Build Coastguard Worker // the arguments with their name and value.
462*03ce13f7SAndroid Build Coastguard Worker //
463*03ce13f7SAndroid Build Coastguard Worker // RR_WATCH_FMT(...) uses the RR_COUNT_ARGUMENTS helper macro to delegate to a
464*03ce13f7SAndroid Build Coastguard Worker // corresponding RR_WATCH_FMT_n specialization macro below.
465*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_CONCAT(a, b) a##b
466*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_CONCAT2(a, b) RR_WATCH_CONCAT(a, b)
467*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT(...) RR_MSVC_EXPAND_BUG(RR_WATCH_CONCAT2(RR_WATCH_FMT_, RR_COUNT_ARGUMENTS(__VA_ARGS__))(__VA_ARGS__))
468*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_1(_1) "\n  " #    _1 ": {0}"
469*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_2(_1, _2) \
470*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_1(_1)         \
471*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_2 ": {1}"
472*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_3(_1, _2, _3) \
473*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_2(_1, _2)         \
474*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_3 ": {2}"
475*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_4(_1, _2, _3, _4) \
476*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_3(_1, _2, _3)         \
477*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_4 ": {3}"
478*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_5(_1, _2, _3, _4, _5) \
479*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_4(_1, _2, _3, _4)         \
480*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_5 ": {4}"
481*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6) \
482*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_5(_1, _2, _3, _4, _5)         \
483*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_6 ": {5}"
484*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_7(_1, _2, _3, _4, _5, _6, _7) \
485*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6)         \
486*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_7 ": {6}"
487*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_8(_1, _2, _3, _4, _5, _6, _7, _8) \
488*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_7(_1, _2, _3, _4, _5, _6, _7)         \
489*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_8 ": {7}"
490*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \
491*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_8(_1, _2, _3, _4, _5, _6, _7, _8)         \
492*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_9 ": {8}"
493*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
494*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9)           \
495*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_10 ": {9}"
496*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
497*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)          \
498*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_11 ": {10}"
499*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
500*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)          \
501*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_12 ": {11}"
502*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_13(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
503*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)          \
504*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_13 ": {12}"
505*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_14(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
506*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_13(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)          \
507*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_14 ": {13}"
508*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
509*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_14(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14)          \
510*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_15 ": {14}"
511*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
512*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)          \
513*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_16 ": {15}"
514*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_17(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
515*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)          \
516*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_17 ": {16}"
517*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH_FMT_18(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
518*03ce13f7SAndroid Build Coastguard Worker 		RR_WATCH_FMT_17(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17)          \
519*03ce13f7SAndroid Build Coastguard Worker 		"\n  " #_18 ": {17}"
520*03ce13f7SAndroid Build Coastguard Worker 
521*03ce13f7SAndroid Build Coastguard Worker // RR_WATCH() is a helper that prints the name and value of all the supplied
522*03ce13f7SAndroid Build Coastguard Worker // arguments.
523*03ce13f7SAndroid Build Coastguard Worker // For example, if you had the Int and bool variables 'foo' and 'bar' that
524*03ce13f7SAndroid Build Coastguard Worker // you want to print, you can simply write:
525*03ce13f7SAndroid Build Coastguard Worker //    RR_WATCH(foo, bar)
526*03ce13f7SAndroid Build Coastguard Worker // When this JIT compiled code is executed, it will print the string
527*03ce13f7SAndroid Build Coastguard Worker // "foo: 1, bar: true" to stdout.
528*03ce13f7SAndroid Build Coastguard Worker //
529*03ce13f7SAndroid Build Coastguard Worker // RR_WATCH() is intended to be used for debugging JIT compiled code, and
530*03ce13f7SAndroid Build Coastguard Worker // is not intended for production use.
531*03ce13f7SAndroid Build Coastguard Worker #	define RR_WATCH(...) RR_LOG(RR_WATCH_FMT(__VA_ARGS__), __VA_ARGS__)
532*03ce13f7SAndroid Build Coastguard Worker 
533*03ce13f7SAndroid Build Coastguard Worker }  // namespace rr
534*03ce13f7SAndroid Build Coastguard Worker 
535*03ce13f7SAndroid Build Coastguard Worker #	define RR_PRINT_ONLY(x) x
536*03ce13f7SAndroid Build Coastguard Worker #else
537*03ce13f7SAndroid Build Coastguard Worker #	define RR_PRINT_ONLY(x)
538*03ce13f7SAndroid Build Coastguard Worker #endif  // ENABLE_RR_PRINT
539*03ce13f7SAndroid Build Coastguard Worker 
540*03ce13f7SAndroid Build Coastguard Worker #endif  // rr_Print_hpp
541