1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is [Open Source Virtual Machine].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2007
21 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
45 #ifdef FEATURE_NANOJIT
47 #if defined AVMPLUS_IA32
49 #elif defined AVMPLUS_ARM
51 #elif defined AVMPLUS_PPC
53 #elif defined AVMPLUS_SPARC
55 #elif defined AVMPLUS_AMD64
57 #elif defined VMCFG_SH4
59 #elif defined AVMPLUS_MIPS
62 #error "unknown nanojit architecture"
69 #if defined NANOJIT_64BIT
70 #define IF_64BIT(...) __VA_ARGS__
71 #define UNLESS_64BIT(...)
73 #define CASE64(x) case x
76 #define UNLESS_64BIT(...) __VA_ARGS__
77 #define CASE32(x) case x
81 #if defined NANOJIT_IA32 || defined NANOJIT_X64
82 #define CASE86(x) case x
87 // Embed no-op macros that let Valgrind work with the JIT.
92 # include <valgrind/valgrind.h>
93 #elif !defined(VALGRIND_DISCARD_TRANSLATIONS)
94 # define VALGRIND_DISCARD_TRANSLATIONS(addr, szB)
100 * -------------------------------------------
101 * START AVM bridging definitions
102 * -------------------------------------------
104 typedef avmplus::AvmCore AvmCore
;
106 const uint32_t MAXARGS
= 8;
108 #ifdef NJ_NO_VARIADIC_MACROS
109 inline void NanoAssertMsgf(bool a
,const char *f
,...) {}
110 inline void NanoAssertMsg(bool a
,const char *m
) {}
111 inline void NanoAssert(bool a
) {}
112 #elif defined(_DEBUG)
114 #define __NanoAssertMsgf(a, file_, line_, f, ...) \
116 avmplus::AvmLog("Assertion failure: " f "%s (%s:%d)\n", __VA_ARGS__, #a, file_, line_); \
117 avmplus::AvmAssertFail(""); \
120 #define _NanoAssertMsgf(a, file_, line_, f, ...) __NanoAssertMsgf(a, file_, line_, f, __VA_ARGS__)
122 #define NanoAssertMsgf(a,f,...) do { __NanoAssertMsgf(a, __FILE__, __LINE__, f ": ", __VA_ARGS__); } while (0)
123 #define NanoAssertMsg(a,m) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "\"%s\": ", m); } while (0)
124 #define NanoAssert(a) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "%s", ""); } while (0)
126 #define NanoAssertMsgf(a,f,...) do { } while (0) /* no semi */
127 #define NanoAssertMsg(a,m) do { } while (0) /* no semi */
128 #define NanoAssert(a) do { } while (0) /* no semi */
132 * Sun Studio C++ compiler has a bug
133 * "sizeof expression not accepted as size of array parameter"
134 * The bug number is 6688515. It is not public yet.
135 * Turn off this assert for Sun Studio until this bug is fixed.
138 #define NanoStaticAssert(condition)
140 #define NanoStaticAssert(condition) \
141 extern void nano_static_assert(int arg[(condition) ? 1 : -1])
146 * -------------------------------------------
147 * END AVM bridging definitions
148 * -------------------------------------------
152 #ifdef AVMPLUS_VERBOSE
156 #ifdef NJ_NO_VARIADIC_MACROS
158 #define verbose_outputf if (_logc->lcbits & LC_Native) \
160 #define verbose_only(x) x
161 #elif defined(NJ_VERBOSE)
163 #define verbose_outputf if (_logc->lcbits & LC_Native) \
165 #define verbose_only(...) __VA_ARGS__
167 #define verbose_outputf
168 #define verbose_only(...)
169 #endif /*NJ_VERBOSE*/
172 #define debug_only(x) x
174 #define debug_only(x)
177 #define isS8(i) ( int32_t(i) == int8_t(i) )
178 #define isU8(i) ( int32_t(i) == uint8_t(i) )
179 #define isS16(i) ( int32_t(i) == int16_t(i) )
180 #define isU16(i) ( int32_t(i) == uint16_t(i) )
181 #define isS24(i) ( (int32_t((i)<<8)>>8) == (i) )
183 static inline bool isS32(intptr_t i
) {
184 return int32_t(i
) == i
;
187 static inline bool isU32(uintptr_t i
) {
188 return uint32_t(i
) == i
;
191 #define alignTo(x,s) ((((uintptr_t)(x)))&~(((uintptr_t)s)-1))
192 #define alignUp(x,s) ((((uintptr_t)(x))+(((uintptr_t)s)-1))&~(((uintptr_t)s)-1))
194 #define NJ_MIN(x, y) ((x) < (y) ? (x) : (y))
195 #define NJ_MAX(x, y) ((x) > (y) ? (x) : (y))
199 // Define msbSet32(), lsbSet32(), msbSet64(), and lsbSet64() functions using
200 // fast find-first-bit instructions intrinsics when available.
201 // The fall-back implementations use iteration.
202 #if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
204 extern "C" unsigned char _BitScanForward(unsigned long * Index
, unsigned long Mask
);
205 extern "C" unsigned char _BitScanReverse(unsigned long * Index
, unsigned long Mask
);
206 # pragma intrinsic(_BitScanForward)
207 # pragma intrinsic(_BitScanReverse)
209 // Returns the index of the most significant bit that is set.
210 static inline int msbSet32(uint32_t x
) {
212 _BitScanReverse(&idx
, (unsigned long)(x
| 1)); // the '| 1' ensures a 0 result when x==0
216 // Returns the index of the least significant bit that is set.
217 static inline int lsbSet32(uint32_t x
) {
219 _BitScanForward(&idx
, (unsigned long)(x
| 0x80000000)); // the '| 0x80000000' ensures a 0 result when x==0
223 #if defined(_M_AMD64) || defined(_M_X64)
224 extern "C" unsigned char _BitScanForward64(unsigned long * Index
, unsigned __int64 Mask
);
225 extern "C" unsigned char _BitScanReverse64(unsigned long * Index
, unsigned __int64 Mask
);
226 # pragma intrinsic(_BitScanForward64)
227 # pragma intrinsic(_BitScanReverse64)
229 // Returns the index of the most significant bit that is set.
230 static inline int msbSet64(uint64_t x
) {
232 _BitScanReverse64(&idx
, (unsigned __int64
)(x
| 1)); // the '| 1' ensures a 0 result when x==0
236 // Returns the index of the least significant bit that is set.
237 static inline int lsbSet64(uint64_t x
) {
239 _BitScanForward64(&idx
, (unsigned __int64
)(x
| 0x8000000000000000LL
)); // the '| 0x80000000' ensures a 0 result when x==0
243 // Returns the index of the most significant bit that is set.
244 static int msbSet64(uint64_t x
) {
245 return (x
& 0xffffffff00000000LL
) ? msbSet32(uint32_t(x
>> 32)) + 32 : msbSet32(uint32_t(x
));
247 // Returns the index of the least significant bit that is set.
248 static int lsbSet64(uint64_t x
) {
249 return (x
& 0x00000000ffffffffLL
) ? lsbSet32(uint32_t(x
)) : lsbSet32(uint32_t(x
>> 32)) + 32;
253 #elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
255 // Returns the index of the most significant bit that is set.
256 static inline int msbSet32(uint32_t x
) {
257 return 31 - __builtin_clz(x
| 1);
260 // Returns the index of the least significant bit that is set.
261 static inline int lsbSet32(uint32_t x
) {
262 return __builtin_ctz(x
| 0x80000000);
265 // Returns the index of the most significant bit that is set.
266 static inline int msbSet64(uint64_t x
) {
267 return 63 - __builtin_clzll(x
| 1);
270 // Returns the index of the least significant bit that is set.
271 static inline int lsbSet64(uint64_t x
) {
272 return __builtin_ctzll(x
| 0x8000000000000000LL
);
277 // Slow fall-back: return most significant bit set by searching iteratively.
278 static int msbSet32(uint32_t x
) {
279 for (int i
= 31; i
>= 0; i
--)
285 // Slow fall-back: return least significant bit set by searching iteratively.
286 static int lsbSet32(uint32_t x
) {
287 for (int i
= 0; i
< 32; i
++)
293 // Slow fall-back: return most significant bit set by searching iteratively.
294 static int msbSet64(uint64_t x
) {
295 for (int i
= 63; i
>= 0; i
--)
301 // Slow fall-back: return least significant bit set by searching iteratively.
302 static int lsbSet64(uint64_t x
) {
303 for (int i
= 0; i
< 64; i
++)
309 #endif // select compiler
310 } // namespace nanojit
312 // -------------------------------------------------------------------
313 // START debug-logging definitions
314 // -------------------------------------------------------------------
316 /* Debug printing stuff. All Nanojit and jstracer debug printing
317 should be routed through LogControl::printf. Don't use
318 ad-hoc calls to printf, fprintf(stderr, ...) etc.
320 Similarly, don't use ad-hoc getenvs etc to decide whether or not to
321 print debug output. Instead consult the relevant control bit in
322 LogControl::lcbits in the LogControl object you are supplied with.
325 # if defined(__GNUC__)
326 # define PRINTF_CHECK(x, y) __attribute__((format(__printf__, x, y)))
328 # define PRINTF_CHECK(x, y)
333 // LogControl, a class for controlling and routing debug output
336 /* Output control bits for Nanojit code. Only use bits 15
337 and below, so that callers can use bits 16 and above for
339 // TODO: add entries for the writer pipeline
340 LC_FragProfile
= 1<<7, // collect per-frag usage counts
341 LC_Liveness
= 1<<6, // show LIR liveness analysis
342 LC_ReadLIR
= 1<<5, // as read from LirBuffer
343 LC_AfterSF
= 1<<4, // after StackFilter
344 LC_AfterDCE
= 1<<3, // after dead code elimination
345 LC_Native
= 1<<2, // final native code
346 LC_RegAlloc
= 1<<1, // stuff to do with reg alloc
347 LC_Activation
= 1<<0 // enable printActivationState
353 // All Nanojit and jstracer printing should be routed through
355 virtual ~LogControl() {}
357 virtual void printf( const char* format
, ... ) PRINTF_CHECK(2,3);
360 // An OR of LC_Bits values, indicating what should be output
365 // -------------------------------------------------------------------
366 // END debug-logging definitions
367 // -------------------------------------------------------------------
370 #include "njconfig.h"
371 #include "Allocator.h"
372 #include "Containers.h"
374 #include "CodeAlloc.h"
376 #include "RegAlloc.h"
377 #include "Fragmento.h"
378 #include "Assembler.h"
380 #endif // FEATURE_NANOJIT
381 #endif // __nanojit_h__