Annotation of embedaddon/pcre/sljit/sljitLir.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Stack-less Just-In-Time compiler
3: *
4: * Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without modification, are
7: * permitted provided that the following conditions are met:
8: *
9: * 1. Redistributions of source code must retain the above copyright notice, this list of
10: * conditions and the following disclaimer.
11: *
12: * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13: * of conditions and the following disclaimer in the documentation and/or other materials
14: * provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19: * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: #include "sljitLir.h"
28:
29: #define CHECK_ERROR() \
30: do { \
31: if (SLJIT_UNLIKELY(compiler->error)) \
32: return compiler->error; \
33: } while (0)
34:
35: #define CHECK_ERROR_PTR() \
36: do { \
37: if (SLJIT_UNLIKELY(compiler->error)) \
38: return NULL; \
39: } while (0)
40:
41: #define CHECK_ERROR_VOID() \
42: do { \
43: if (SLJIT_UNLIKELY(compiler->error)) \
44: return; \
45: } while (0)
46:
47: #define FAIL_IF(expr) \
48: do { \
49: if (SLJIT_UNLIKELY(expr)) \
50: return compiler->error; \
51: } while (0)
52:
53: #define PTR_FAIL_IF(expr) \
54: do { \
55: if (SLJIT_UNLIKELY(expr)) \
56: return NULL; \
57: } while (0)
58:
59: #define FAIL_IF_NULL(ptr) \
60: do { \
61: if (SLJIT_UNLIKELY(!(ptr))) { \
62: compiler->error = SLJIT_ERR_ALLOC_FAILED; \
63: return SLJIT_ERR_ALLOC_FAILED; \
64: } \
65: } while (0)
66:
67: #define PTR_FAIL_IF_NULL(ptr) \
68: do { \
69: if (SLJIT_UNLIKELY(!(ptr))) { \
70: compiler->error = SLJIT_ERR_ALLOC_FAILED; \
71: return NULL; \
72: } \
73: } while (0)
74:
75: #define PTR_FAIL_WITH_EXEC_IF(ptr) \
76: do { \
77: if (SLJIT_UNLIKELY(!(ptr))) { \
78: compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
79: return NULL; \
80: } \
81: } while (0)
82:
83: #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
84:
85: #define GET_OPCODE(op) \
86: ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
87:
88: #define GET_FLAGS(op) \
89: ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))
90:
91: #define GET_ALL_FLAGS(op) \
92: ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
93:
94: #define BUF_SIZE 4096
95:
96: #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
97: #define ABUF_SIZE 2048
98: #else
99: #define ABUF_SIZE 4096
100: #endif
101:
102: /* Jump flags. */
103: #define JUMP_LABEL 0x1
104: #define JUMP_ADDR 0x2
105: /* SLJIT_REWRITABLE_JUMP is 0x1000. */
106:
107: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
108: #define PATCH_MB 0x4
109: #define PATCH_MW 0x8
110: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
111: #define PATCH_MD 0x10
112: #endif
113: #endif
114:
115: #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
116: #define IS_BL 0x4
117: #define PATCH_B 0x8
118: #endif
119:
120: #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
121: #define CPOOL_SIZE 512
122: #endif
123:
124: #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
125: #define IS_CONDITIONAL 0x04
126: #define IS_BL 0x08
127: /* cannot be encoded as branch */
128: #define B_TYPE0 0x00
129: /* conditional + imm8 */
130: #define B_TYPE1 0x10
131: /* conditional + imm20 */
132: #define B_TYPE2 0x20
133: /* IT + imm24 */
134: #define B_TYPE3 0x30
135: /* imm11 */
136: #define B_TYPE4 0x40
137: /* imm24 */
138: #define B_TYPE5 0x50
139: /* BL + imm24 */
140: #define BL_TYPE6 0x60
141: /* 0xf00 cc code for branches */
142: #endif
143:
144: #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
145: #define UNCOND_B 0x04
146: #define PATCH_B 0x08
147: #define ABSOLUTE_B 0x10
148: #endif
149:
150: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
151: #define IS_MOVABLE 0x04
152: #define IS_JAL 0x08
153: #define IS_BIT26_COND 0x10
154: #define IS_BIT16_COND 0x20
155:
156: #define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
157:
158: #define PATCH_B 0x40
159: #define PATCH_J 0x80
160:
161: /* instruction types */
162: #define UNMOVABLE_INS 0
163: /* 1 - 31 last destination register */
164: #define FCSR_FCC 32
165: /* no destination (i.e: store) */
166: #define MOVABLE_INS 33
167: #endif
168:
169: #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
170:
171: /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
172: #include "sljitUtils.c"
173:
174: #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
175:
176: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
177: #include "sljitExecAllocator.c"
178: #endif
179:
180: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2)
181: #error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2
182: #endif
183:
184: /* --------------------------------------------------------------------- */
185: /* Public functions */
186: /* --------------------------------------------------------------------- */
187:
188: #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)))
189: #define SLJIT_NEEDS_COMPILER_INIT 1
190: static int compiler_initialized = 0;
191: /* A thread safe initialization. */
192: static void init_compiler(void);
193: #endif
194:
195:
196: SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
197: {
198: struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler));
199: if (!compiler)
200: return NULL;
201: SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
202:
203: SLJIT_COMPILE_ASSERT(
204: sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1
205: && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2
206: && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4
207: && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)),
208: invalid_integer_types);
209:
210: /* Only the non-zero members must be set. */
211: compiler->error = SLJIT_SUCCESS;
212:
213: compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
214: compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
215:
216: if (!compiler->buf || !compiler->abuf) {
217: if (compiler->buf)
218: SLJIT_FREE(compiler->buf);
219: if (compiler->abuf)
220: SLJIT_FREE(compiler->abuf);
221: SLJIT_FREE(compiler);
222: return NULL;
223: }
224:
225: compiler->buf->next = NULL;
226: compiler->buf->used_size = 0;
227: compiler->abuf->next = NULL;
228: compiler->abuf->used_size = 0;
229:
230: compiler->temporaries = -1;
231: compiler->generals = -1;
232:
233: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
234: compiler->args = -1;
235: #endif
236:
237: #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
238: compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub));
239: if (!compiler->cpool) {
240: SLJIT_FREE(compiler->buf);
241: SLJIT_FREE(compiler->abuf);
242: SLJIT_FREE(compiler);
243: return NULL;
244: }
245: compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE);
246: compiler->cpool_diff = 0xffffffff;
247: #endif
248:
249: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
250: compiler->delay_slot = UNMOVABLE_INS;
251: #endif
252:
253: #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
254: if (!compiler_initialized) {
255: init_compiler();
256: compiler_initialized = 1;
257: }
258: #endif
259:
260: return compiler;
261: }
262:
263: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
264: {
265: struct sljit_memory_fragment *buf;
266: struct sljit_memory_fragment *curr;
267:
268: buf = compiler->buf;
269: while (buf) {
270: curr = buf;
271: buf = buf->next;
272: SLJIT_FREE(curr);
273: }
274:
275: buf = compiler->abuf;
276: while (buf) {
277: curr = buf;
278: buf = buf->next;
279: SLJIT_FREE(curr);
280: }
281:
282: #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
283: SLJIT_FREE(compiler->cpool);
284: #endif
285: SLJIT_FREE(compiler);
286: }
287:
288: #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
289: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
290: {
291: /* Remove thumb mode flag. */
292: SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
293: }
294: #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
295: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
296: {
297: /* Resolve indirection. */
298: code = (void*)(*(sljit_uw*)code);
299: SLJIT_FREE_EXEC(code);
300: }
301: #else
302: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
303: {
304: SLJIT_FREE_EXEC(code);
305: }
306: #endif
307:
308: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
309: {
310: if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
311: jump->flags &= ~JUMP_ADDR;
312: jump->flags |= JUMP_LABEL;
313: jump->u.label = label;
314: }
315: }
316:
317: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
318: {
319: if (SLJIT_LIKELY(!!jump)) {
320: SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP);
321:
322: jump->flags &= ~JUMP_LABEL;
323: jump->flags |= JUMP_ADDR;
324: jump->u.target = target;
325: }
326: }
327:
328: /* --------------------------------------------------------------------- */
329: /* Private functions */
330: /* --------------------------------------------------------------------- */
331:
332: static void* ensure_buf(struct sljit_compiler *compiler, int size)
333: {
334: sljit_ub *ret;
335: struct sljit_memory_fragment *new_frag;
336:
337: if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
338: ret = compiler->buf->memory + compiler->buf->used_size;
339: compiler->buf->used_size += size;
340: return ret;
341: }
342: new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
343: PTR_FAIL_IF_NULL(new_frag);
344: new_frag->next = compiler->buf;
345: compiler->buf = new_frag;
346: new_frag->used_size = size;
347: return new_frag->memory;
348: }
349:
350: static void* ensure_abuf(struct sljit_compiler *compiler, int size)
351: {
352: sljit_ub *ret;
353: struct sljit_memory_fragment *new_frag;
354:
355: if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
356: ret = compiler->abuf->memory + compiler->abuf->used_size;
357: compiler->abuf->used_size += size;
358: return ret;
359: }
360: new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
361: PTR_FAIL_IF_NULL(new_frag);
362: new_frag->next = compiler->abuf;
363: compiler->abuf = new_frag;
364: new_frag->used_size = size;
365: return new_frag->memory;
366: }
367:
368: SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
369: {
370: CHECK_ERROR_PTR();
371:
372: #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
373: if (size <= 0 || size > 128)
374: return NULL;
375: size = (size + 7) & ~7;
376: #else
377: if (size <= 0 || size > 64)
378: return NULL;
379: size = (size + 3) & ~3;
380: #endif
381: return ensure_abuf(compiler, size);
382: }
383:
384: static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
385: {
386: struct sljit_memory_fragment *buf = compiler->buf;
387: struct sljit_memory_fragment *prev = NULL;
388: struct sljit_memory_fragment *tmp;
389:
390: do {
391: tmp = buf->next;
392: buf->next = prev;
393: prev = buf;
394: buf = tmp;
395: } while (buf != NULL);
396:
397: compiler->buf = prev;
398: }
399:
400: static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
401: {
402: label->next = NULL;
403: label->size = compiler->size;
404: if (compiler->last_label)
405: compiler->last_label->next = label;
406: else
407: compiler->labels = label;
408: compiler->last_label = label;
409: }
410:
411: static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags)
412: {
413: jump->next = NULL;
414: jump->flags = flags;
415: if (compiler->last_jump)
416: compiler->last_jump->next = jump;
417: else
418: compiler->jumps = jump;
419: compiler->last_jump = jump;
420: }
421:
422: static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
423: {
424: const_->next = NULL;
425: const_->addr = compiler->size;
426: if (compiler->last_const)
427: compiler->last_const->next = const_;
428: else
429: compiler->consts = const_;
430: compiler->last_const = const_;
431: }
432:
433: #define ADDRESSING_DEPENDS_ON(exp, reg) \
434: (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg))
435:
436: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
437: #define FUNCTION_CHECK_OP() \
438: SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
439: switch (GET_OPCODE(op)) { \
440: case SLJIT_NOT: \
441: case SLJIT_CLZ: \
442: case SLJIT_AND: \
443: case SLJIT_OR: \
444: case SLJIT_XOR: \
445: case SLJIT_SHL: \
446: case SLJIT_LSHR: \
447: case SLJIT_ASHR: \
448: SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \
449: break; \
450: case SLJIT_NEG: \
451: SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
452: break; \
453: case SLJIT_MUL: \
454: SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
455: break; \
456: case SLJIT_FCMP: \
457: SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
458: SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
459: break; \
460: case SLJIT_ADD: \
461: SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \
462: break; \
463: case SLJIT_SUB: \
464: break; \
465: case SLJIT_ADDC: \
466: case SLJIT_SUBC: \
467: SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \
468: break; \
469: default: \
470: /* Nothing allowed */ \
471: SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
472: break; \
473: }
474:
475: #define FUNCTION_CHECK_IS_REG(r) \
476: ((r) == SLJIT_UNUSED || (r) == SLJIT_LOCALS_REG || \
477: ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG3 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
478: ((r) >= SLJIT_GENERAL_REG1 && (r) <= SLJIT_GENERAL_REG3 && (r) <= SLJIT_GENERAL_REG1 - 1 + compiler->generals)) \
479:
480: #define FUNCTION_CHECK_SRC(p, i) \
481: SLJIT_ASSERT(compiler->temporaries != -1 && compiler->generals != -1); \
482: if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
483: ((p) >= SLJIT_GENERAL_REG1 && (p) <= SLJIT_GENERAL_REG1 - 1 + compiler->generals) || \
484: (p) == SLJIT_LOCALS_REG) \
485: SLJIT_ASSERT(i == 0); \
486: else if ((p) == SLJIT_IMM) \
487: ; \
488: else if ((p) & SLJIT_MEM) { \
489: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
490: if ((p) & 0xf0) { \
491: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
492: SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
493: } else \
494: SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
495: SLJIT_ASSERT(((p) >> 9) == 0); \
496: } \
497: else \
498: SLJIT_ASSERT_STOP();
499:
500: #define FUNCTION_CHECK_DST(p, i) \
501: SLJIT_ASSERT(compiler->temporaries != -1 && compiler->generals != -1); \
502: if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
503: ((p) >= SLJIT_GENERAL_REG1 && (p) <= SLJIT_GENERAL_REG1 - 1 + compiler->generals) || \
504: (p) == SLJIT_UNUSED) \
505: SLJIT_ASSERT(i == 0); \
506: else if ((p) & SLJIT_MEM) { \
507: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
508: if ((p) & 0xf0) { \
509: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
510: SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
511: } else \
512: SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
513: SLJIT_ASSERT(((p) >> 9) == 0); \
514: } \
515: else \
516: SLJIT_ASSERT_STOP();
517:
518: #define FUNCTION_FCHECK(p, i) \
519: if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \
520: SLJIT_ASSERT(i == 0); \
521: else if ((p) & SLJIT_MEM) { \
522: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
523: if ((p) & 0xf0) { \
524: SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
525: SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
526: } else \
527: SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
528: SLJIT_ASSERT(((p) >> 9) == 0); \
529: } \
530: else \
531: SLJIT_ASSERT_STOP();
532:
533: #define FUNCTION_CHECK_OP1() \
534: if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
535: SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \
536: } \
537: if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
538: SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \
539: SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \
540: if ((src & SLJIT_MEM) && (src & 0xf)) \
541: SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \
542: }
543:
544: #endif
545:
546: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
547:
548: SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
549: {
550: compiler->verbose = verbose;
551: }
552:
553: static char* reg_names[] = {
554: (char*)"<noreg>", (char*)"tmp_r1", (char*)"tmp_r2", (char*)"tmp_r3",
555: (char*)"tmp_er1", (char*)"tmp_er2", (char*)"gen_r1", (char*)"gen_r2",
556: (char*)"gen_r3", (char*)"gen_er1", (char*)"gen_er2", (char*)"stack_r"
557: };
558:
559: static char* freg_names[] = {
560: (char*)"<noreg>", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4"
561: };
562:
563: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
564: #ifdef _WIN64
565: #define SLJIT_PRINT_D "I64"
566: #else
567: #define SLJIT_PRINT_D "l"
568: #endif
569: #else
570: #define SLJIT_PRINT_D ""
571: #endif
572:
573: #define sljit_verbose_param(p, i) \
574: if ((p) & SLJIT_IMM) \
575: fprintf(compiler->verbose, "#%"SLJIT_PRINT_D"d", (i)); \
576: else if ((p) & SLJIT_MEM) { \
577: if ((p) & 0xf) { \
578: if (i) { \
579: if (((p) >> 4) & 0xf) \
580: fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
581: else \
582: fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
583: } \
584: else { \
585: if (((p) >> 4) & 0xf) \
586: fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
587: else \
588: fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
589: } \
590: } \
591: else \
592: fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
593: } else \
594: fprintf(compiler->verbose, "%s", reg_names[p]);
595: #define sljit_verbose_fparam(p, i) \
596: if ((p) & SLJIT_MEM) { \
597: if ((p) & 0xf) { \
598: if (i) { \
599: if (((p) >> 4) & 0xf) \
600: fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
601: else \
602: fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
603: } \
604: else { \
605: if (((p) >> 4) & 0xF) \
606: fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
607: else \
608: fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
609: } \
610: } \
611: else \
612: fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
613: } else \
614: fprintf(compiler->verbose, "%s", freg_names[p]);
615:
616: static SLJIT_CONST char* op_names[] = {
617: /* op0 */
618: (char*)"breakpoint", (char*)"nop",
619: /* op1 */
620: (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh",
621: (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu",
622: (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh",
623: (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg",
624: (char*)"clz",
625: /* op2 */
626: (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
627: (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
628: (char*)"shl", (char*)"lshr", (char*)"ashr",
629: /* fop1 */
630: (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs",
631: /* fop2 */
632: (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv"
633: };
634:
635: static char* jump_names[] = {
636: (char*)"c_equal", (char*)"c_not_equal",
637: (char*)"c_less", (char*)"c_greater_equal",
638: (char*)"c_greater", (char*)"c_less_equal",
639: (char*)"c_sig_less", (char*)"c_sig_greater_equal",
640: (char*)"c_sig_greater", (char*)"c_sig_less_equal",
641: (char*)"c_overflow", (char*)"c_not_overflow",
642: (char*)"c_mul_overflow", (char*)"c_mul_not_overflow",
643: (char*)"c_float_equal", (char*)"c_float_not_equal",
644: (char*)"c_float_less", (char*)"c_float_greater_equal",
645: (char*)"c_float_greater", (char*)"c_float_less_equal",
646: (char*)"c_float_nan", (char*)"c_float_not_nan",
647: (char*)"jump", (char*)"fast_call",
648: (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
649: };
650:
651: #endif
652:
653: /* --------------------------------------------------------------------- */
654: /* Arch dependent */
655: /* --------------------------------------------------------------------- */
656:
657: static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler)
658: {
659: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
660: struct sljit_jump *jump;
661: #endif
662: /* If debug and verbose are disabled, all arguments are unused. */
663: SLJIT_UNUSED_ARG(compiler);
664:
665: SLJIT_ASSERT(compiler->size > 0);
666: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
667: jump = compiler->jumps;
668: while (jump) {
669: /* All jumps have target. */
670: SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
671: jump = jump->next;
672: }
673: #endif
674: }
675:
676: static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
677: {
678: /* If debug and verbose are disabled, all arguments are unused. */
679: SLJIT_UNUSED_ARG(compiler);
680: SLJIT_UNUSED_ARG(args);
681: SLJIT_UNUSED_ARG(temporaries);
682: SLJIT_UNUSED_ARG(generals);
683: SLJIT_UNUSED_ARG(local_size);
684:
685: SLJIT_ASSERT(args >= 0 && args <= 3);
686: SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
687: SLJIT_ASSERT(generals >= 0 && generals <= SLJIT_NO_GEN_REGISTERS);
688: SLJIT_ASSERT(args <= generals);
689: SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
690: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
691: if (SLJIT_UNLIKELY(!!compiler->verbose))
692: fprintf(compiler->verbose, " enter args=%d temporaries=%d generals=%d local_size=%d\n", args, temporaries, generals, local_size);
693: #endif
694: }
695:
696: static SLJIT_INLINE void check_sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
697: {
698: /* If debug and verbose are disabled, all arguments are unused. */
699: SLJIT_UNUSED_ARG(compiler);
700: SLJIT_UNUSED_ARG(args);
701: SLJIT_UNUSED_ARG(temporaries);
702: SLJIT_UNUSED_ARG(generals);
703: SLJIT_UNUSED_ARG(local_size);
704:
705: SLJIT_ASSERT(args >= 0 && args <= 3);
706: SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
707: SLJIT_ASSERT(generals >= 0 && generals <= SLJIT_NO_GEN_REGISTERS);
708: SLJIT_ASSERT(args <= generals);
709: SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
710: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
711: if (SLJIT_UNLIKELY(!!compiler->verbose))
712: fprintf(compiler->verbose, " fake_enter args=%d temporaries=%d generals=%d local_size=%d\n", args, temporaries, generals, local_size);
713: #endif
714: }
715:
716: static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
717: {
718: /* If debug and verbose are disabled, all arguments are unused. */
719: SLJIT_UNUSED_ARG(compiler);
720: SLJIT_UNUSED_ARG(src);
721: SLJIT_UNUSED_ARG(srcw);
722:
723: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
724: if (src != SLJIT_UNUSED) {
725: FUNCTION_CHECK_SRC(src, srcw);
726: }
727: else
728: SLJIT_ASSERT(srcw == 0);
729: #endif
730: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
731: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
732: fprintf(compiler->verbose, " return ");
733: sljit_verbose_param(src, srcw);
734: fprintf(compiler->verbose, "\n");
735: }
736: #endif
737: }
738:
739: static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int generals, int local_size)
740: {
741: /* If debug and verbose are disabled, all arguments are unused. */
742: SLJIT_UNUSED_ARG(compiler);
743: SLJIT_UNUSED_ARG(dst);
744: SLJIT_UNUSED_ARG(dstw);
745: SLJIT_UNUSED_ARG(args);
746: SLJIT_UNUSED_ARG(temporaries);
747: SLJIT_UNUSED_ARG(generals);
748: SLJIT_UNUSED_ARG(local_size);
749:
750: SLJIT_ASSERT(args >= 0 && args <= 3);
751: SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
752: SLJIT_ASSERT(generals >= 0 && generals <= SLJIT_NO_GEN_REGISTERS);
753: SLJIT_ASSERT(args <= generals);
754: SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
755: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
756: compiler->temporaries = temporaries;
757: compiler->generals = generals;
758: FUNCTION_CHECK_DST(dst, dstw);
759: compiler->temporaries = -1;
760: compiler->generals = -1;
761: #endif
762: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
763: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
764: fprintf(compiler->verbose, " fast_enter ");
765: sljit_verbose_param(dst, dstw);
766: fprintf(compiler->verbose, " args=%d temporaries=%d generals=%d local_size=%d\n", args, temporaries, generals, local_size);
767: }
768: #endif
769: }
770:
771: static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
772: {
773: /* If debug and verbose are disabled, all arguments are unused. */
774: SLJIT_UNUSED_ARG(compiler);
775: SLJIT_UNUSED_ARG(src);
776: SLJIT_UNUSED_ARG(srcw);
777:
778: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
779: FUNCTION_CHECK_SRC(src, srcw);
780: #endif
781: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
782: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
783: fprintf(compiler->verbose, " fast_return ");
784: sljit_verbose_param(src, srcw);
785: fprintf(compiler->verbose, "\n");
786: }
787: #endif
788: }
789:
790: static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op)
791: {
792: /* If debug and verbose are disabled, all arguments are unused. */
793: SLJIT_UNUSED_ARG(compiler);
794: SLJIT_UNUSED_ARG(op);
795:
796: SLJIT_ASSERT(op >= SLJIT_BREAKPOINT && op <= SLJIT_NOP);
797: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
798: if (SLJIT_UNLIKELY(!!compiler->verbose))
799: fprintf(compiler->verbose, " %s\n", op_names[op]);
800: #endif
801: }
802:
803: static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op,
804: int dst, sljit_w dstw,
805: int src, sljit_w srcw)
806: {
807: /* If debug and verbose are disabled, all arguments are unused. */
808: SLJIT_UNUSED_ARG(compiler);
809: SLJIT_UNUSED_ARG(op);
810: SLJIT_UNUSED_ARG(dst);
811: SLJIT_UNUSED_ARG(dstw);
812: SLJIT_UNUSED_ARG(src);
813: SLJIT_UNUSED_ARG(srcw);
814:
815: SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
816: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
817: FUNCTION_CHECK_OP();
818: FUNCTION_CHECK_SRC(src, srcw);
819: FUNCTION_CHECK_DST(dst, dstw);
820: FUNCTION_CHECK_OP1();
821: #endif
822: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
823: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
824: fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
825: !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
826: sljit_verbose_param(dst, dstw);
827: fprintf(compiler->verbose, ", ");
828: sljit_verbose_param(src, srcw);
829: fprintf(compiler->verbose, "\n");
830: }
831: #endif
832: }
833:
834: static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op,
835: int dst, sljit_w dstw,
836: int src1, sljit_w src1w,
837: int src2, sljit_w src2w)
838: {
839: /* If debug and verbose are disabled, all arguments are unused. */
840: SLJIT_UNUSED_ARG(compiler);
841: SLJIT_UNUSED_ARG(op);
842: SLJIT_UNUSED_ARG(dst);
843: SLJIT_UNUSED_ARG(dstw);
844: SLJIT_UNUSED_ARG(src1);
845: SLJIT_UNUSED_ARG(src1w);
846: SLJIT_UNUSED_ARG(src2);
847: SLJIT_UNUSED_ARG(src2w);
848:
849: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
850: if (SLJIT_UNLIKELY(compiler->skip_checks)) {
851: compiler->skip_checks = 0;
852: return;
853: }
854: #endif
855:
856: SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
857: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
858: FUNCTION_CHECK_OP();
859: FUNCTION_CHECK_SRC(src1, src1w);
860: FUNCTION_CHECK_SRC(src2, src2w);
861: FUNCTION_CHECK_DST(dst, dstw);
862: #endif
863: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
864: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
865: fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
866: !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
867: sljit_verbose_param(dst, dstw);
868: fprintf(compiler->verbose, ", ");
869: sljit_verbose_param(src1, src1w);
870: fprintf(compiler->verbose, ", ");
871: sljit_verbose_param(src2, src2w);
872: fprintf(compiler->verbose, "\n");
873: }
874: #endif
875: }
876:
877: static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op,
878: int dst, sljit_w dstw,
879: int src, sljit_w srcw)
880: {
881: /* If debug and verbose are disabled, all arguments are unused. */
882: SLJIT_UNUSED_ARG(compiler);
883: SLJIT_UNUSED_ARG(op);
884: SLJIT_UNUSED_ARG(dst);
885: SLJIT_UNUSED_ARG(dstw);
886: SLJIT_UNUSED_ARG(src);
887: SLJIT_UNUSED_ARG(srcw);
888:
889: SLJIT_ASSERT(sljit_is_fpu_available());
890: SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS);
891: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
892: FUNCTION_CHECK_OP();
893: FUNCTION_FCHECK(src, srcw);
894: FUNCTION_FCHECK(dst, dstw);
895: #endif
896: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
897: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
898: fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)],
899: !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S");
900: sljit_verbose_fparam(dst, dstw);
901: fprintf(compiler->verbose, ", ");
902: sljit_verbose_fparam(src, srcw);
903: fprintf(compiler->verbose, "\n");
904: }
905: #endif
906: }
907:
908: static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op,
909: int dst, sljit_w dstw,
910: int src1, sljit_w src1w,
911: int src2, sljit_w src2w)
912: {
913: /* If debug and verbose are disabled, all arguments are unused. */
914: SLJIT_UNUSED_ARG(compiler);
915: SLJIT_UNUSED_ARG(op);
916: SLJIT_UNUSED_ARG(dst);
917: SLJIT_UNUSED_ARG(dstw);
918: SLJIT_UNUSED_ARG(src1);
919: SLJIT_UNUSED_ARG(src1w);
920: SLJIT_UNUSED_ARG(src2);
921: SLJIT_UNUSED_ARG(src2w);
922:
923: SLJIT_ASSERT(sljit_is_fpu_available());
924: SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV);
925: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
926: FUNCTION_CHECK_OP();
927: FUNCTION_FCHECK(src1, src1w);
928: FUNCTION_FCHECK(src2, src2w);
929: FUNCTION_FCHECK(dst, dstw);
930: #endif
931: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
932: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
933: fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]);
934: sljit_verbose_fparam(dst, dstw);
935: fprintf(compiler->verbose, ", ");
936: sljit_verbose_fparam(src1, src1w);
937: fprintf(compiler->verbose, ", ");
938: sljit_verbose_fparam(src2, src2w);
939: fprintf(compiler->verbose, "\n");
940: }
941: #endif
942: }
943:
944: static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler)
945: {
946: /* If debug and verbose are disabled, all arguments are unused. */
947: SLJIT_UNUSED_ARG(compiler);
948:
949: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
950: if (SLJIT_UNLIKELY(!!compiler->verbose))
951: fprintf(compiler->verbose, "label:\n");
952: #endif
953: }
954:
955: static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type)
956: {
957: /* If debug and verbose are disabled, all arguments are unused. */
958: SLJIT_UNUSED_ARG(compiler);
959: SLJIT_UNUSED_ARG(type);
960:
961: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
962: if (SLJIT_UNLIKELY(compiler->skip_checks)) {
963: compiler->skip_checks = 0;
964: return;
965: }
966: #endif
967:
968: SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
969: SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
970: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
971: if (SLJIT_UNLIKELY(!!compiler->verbose))
972: fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
973: #endif
974: }
975:
976: static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type,
977: int src1, sljit_w src1w,
978: int src2, sljit_w src2w)
979: {
980: SLJIT_UNUSED_ARG(compiler);
981: SLJIT_UNUSED_ARG(type);
982: SLJIT_UNUSED_ARG(src1);
983: SLJIT_UNUSED_ARG(src1w);
984: SLJIT_UNUSED_ARG(src2);
985: SLJIT_UNUSED_ARG(src2w);
986:
987: SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)));
988: SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL);
989: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
990: FUNCTION_CHECK_SRC(src1, src1w);
991: FUNCTION_CHECK_SRC(src2, src2w);
992: #endif
993: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
994: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
995: fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
996: sljit_verbose_param(src1, src1w);
997: fprintf(compiler->verbose, ", ");
998: sljit_verbose_param(src2, src2w);
999: fprintf(compiler->verbose, "\n");
1000: }
1001: #endif
1002: }
1003:
1004: static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
1005: {
1006: /* If debug and verbose are disabled, all arguments are unused. */
1007: SLJIT_UNUSED_ARG(compiler);
1008: SLJIT_UNUSED_ARG(type);
1009: SLJIT_UNUSED_ARG(src);
1010: SLJIT_UNUSED_ARG(srcw);
1011:
1012: SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
1013: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1014: FUNCTION_CHECK_SRC(src, srcw);
1015: #endif
1016: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1017: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1018: fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]);
1019: sljit_verbose_param(src, srcw);
1020: fprintf(compiler->verbose, "\n");
1021: }
1022: #endif
1023: }
1024:
1025: static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
1026: {
1027: /* If debug and verbose are disabled, all arguments are unused. */
1028: SLJIT_UNUSED_ARG(compiler);
1029: SLJIT_UNUSED_ARG(op);
1030: SLJIT_UNUSED_ARG(dst);
1031: SLJIT_UNUSED_ARG(dstw);
1032: SLJIT_UNUSED_ARG(type);
1033:
1034: SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP);
1035: SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR);
1036: SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS);
1037: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1038: FUNCTION_CHECK_DST(dst, dstw);
1039: #endif
1040: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1041: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1042: fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E",
1043: !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]);
1044: sljit_verbose_param(dst, dstw);
1045: fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
1046: }
1047: #endif
1048: }
1049:
1050: static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
1051: {
1052: /* If debug and verbose are disabled, all arguments are unused. */
1053: SLJIT_UNUSED_ARG(compiler);
1054: SLJIT_UNUSED_ARG(dst);
1055: SLJIT_UNUSED_ARG(dstw);
1056: SLJIT_UNUSED_ARG(init_value);
1057:
1058: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1059: FUNCTION_CHECK_DST(dst, dstw);
1060: #endif
1061: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1062: if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1063: fprintf(compiler->verbose, " const ");
1064: sljit_verbose_param(dst, dstw);
1065: fprintf(compiler->verbose, ", #%"SLJIT_PRINT_D"d\n", init_value);
1066: }
1067: #endif
1068: }
1069:
1070: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1071: #include "sljitNativeX86_common.c"
1072: #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1073: #include "sljitNativeX86_common.c"
1074: #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1075: #include "sljitNativeARM_v5.c"
1076: #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
1077: #include "sljitNativeARM_v5.c"
1078: #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1079: #include "sljitNativeARM_Thumb2.c"
1080: #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1081: #include "sljitNativePPC_common.c"
1082: #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1083: #include "sljitNativePPC_common.c"
1084: #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1085: #include "sljitNativeMIPS_common.c"
1086: #endif
1087:
1088: #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1089: SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
1090: int src1, sljit_w src1w,
1091: int src2, sljit_w src2w)
1092: {
1093: /* Default compare for most architectures. */
1094: int flags, tmp_src, condition;
1095: sljit_w tmp_srcw;
1096:
1097: CHECK_ERROR_PTR();
1098: check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
1099:
1100: condition = type & 0xff;
1101: if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
1102: /* Immediate is prefered as second argument by most architectures. */
1103: switch (condition) {
1104: case SLJIT_C_LESS:
1105: condition = SLJIT_C_GREATER;
1106: break;
1107: case SLJIT_C_GREATER_EQUAL:
1108: condition = SLJIT_C_LESS_EQUAL;
1109: break;
1110: case SLJIT_C_GREATER:
1111: condition = SLJIT_C_LESS;
1112: break;
1113: case SLJIT_C_LESS_EQUAL:
1114: condition = SLJIT_C_GREATER_EQUAL;
1115: break;
1116: case SLJIT_C_SIG_LESS:
1117: condition = SLJIT_C_SIG_GREATER;
1118: break;
1119: case SLJIT_C_SIG_GREATER_EQUAL:
1120: condition = SLJIT_C_SIG_LESS_EQUAL;
1121: break;
1122: case SLJIT_C_SIG_GREATER:
1123: condition = SLJIT_C_SIG_LESS;
1124: break;
1125: case SLJIT_C_SIG_LESS_EQUAL:
1126: condition = SLJIT_C_SIG_GREATER_EQUAL;
1127: break;
1128: }
1129: type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP));
1130: tmp_src = src1;
1131: src1 = src2;
1132: src2 = tmp_src;
1133: tmp_srcw = src1w;
1134: src1w = src2w;
1135: src2w = tmp_srcw;
1136: }
1137:
1138: if (condition <= SLJIT_C_NOT_ZERO)
1139: flags = SLJIT_SET_E;
1140: else if (condition <= SLJIT_C_LESS_EQUAL)
1141: flags = SLJIT_SET_U;
1142: else
1143: flags = SLJIT_SET_S;
1144:
1145: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1146: compiler->skip_checks = 1;
1147: #endif
1148: PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP),
1149: SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
1150: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1151: compiler->skip_checks = 1;
1152: #endif
1153: return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
1154: }
1155: #endif
1156:
1157: #else /* SLJIT_CONFIG_UNSUPPORTED */
1158:
1159: /* Empty function bodies for those machines, which are not (yet) supported. */
1160:
1161: SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
1162: {
1163: return "unsupported";
1164: }
1165:
1166: SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
1167: {
1168: SLJIT_ASSERT_STOP();
1169: return NULL;
1170: }
1171:
1172: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
1173: {
1174: SLJIT_UNUSED_ARG(compiler);
1175: SLJIT_ASSERT_STOP();
1176: }
1177:
1178: SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
1179: {
1180: SLJIT_UNUSED_ARG(compiler);
1181: SLJIT_UNUSED_ARG(size);
1182: SLJIT_ASSERT_STOP();
1183: return NULL;
1184: }
1185:
1186: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1187: SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
1188: {
1189: SLJIT_UNUSED_ARG(compiler);
1190: SLJIT_UNUSED_ARG(verbose);
1191: SLJIT_ASSERT_STOP();
1192: }
1193: #endif
1194:
1195: SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
1196: {
1197: SLJIT_UNUSED_ARG(compiler);
1198: SLJIT_ASSERT_STOP();
1199: return NULL;
1200: }
1201:
1202: SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
1203: {
1204: SLJIT_UNUSED_ARG(code);
1205: SLJIT_ASSERT_STOP();
1206: }
1207:
1208: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
1209: {
1210: SLJIT_UNUSED_ARG(compiler);
1211: SLJIT_UNUSED_ARG(args);
1212: SLJIT_UNUSED_ARG(temporaries);
1213: SLJIT_UNUSED_ARG(generals);
1214: SLJIT_UNUSED_ARG(local_size);
1215: SLJIT_ASSERT_STOP();
1216: return SLJIT_ERR_UNSUPPORTED;
1217: }
1218:
1219: SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
1220: {
1221: SLJIT_UNUSED_ARG(compiler);
1222: SLJIT_UNUSED_ARG(args);
1223: SLJIT_UNUSED_ARG(temporaries);
1224: SLJIT_UNUSED_ARG(generals);
1225: SLJIT_UNUSED_ARG(local_size);
1226: SLJIT_ASSERT_STOP();
1227: }
1228:
1229: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
1230: {
1231: SLJIT_UNUSED_ARG(compiler);
1232: SLJIT_UNUSED_ARG(src);
1233: SLJIT_UNUSED_ARG(srcw);
1234: SLJIT_ASSERT_STOP();
1235: return SLJIT_ERR_UNSUPPORTED;
1236: }
1237:
1238: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int generals, int local_size)
1239: {
1240: SLJIT_UNUSED_ARG(compiler);
1241: SLJIT_UNUSED_ARG(dst);
1242: SLJIT_UNUSED_ARG(dstw);
1243: SLJIT_UNUSED_ARG(args);
1244: SLJIT_UNUSED_ARG(temporaries);
1245: SLJIT_UNUSED_ARG(generals);
1246: SLJIT_UNUSED_ARG(local_size);
1247: SLJIT_ASSERT_STOP();
1248: return SLJIT_ERR_UNSUPPORTED;
1249: }
1250:
1251: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
1252: {
1253: SLJIT_UNUSED_ARG(compiler);
1254: SLJIT_UNUSED_ARG(src);
1255: SLJIT_UNUSED_ARG(srcw);
1256: SLJIT_ASSERT_STOP();
1257: return SLJIT_ERR_UNSUPPORTED;
1258: }
1259:
1260: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
1261: {
1262: SLJIT_UNUSED_ARG(compiler);
1263: SLJIT_UNUSED_ARG(op);
1264: SLJIT_ASSERT_STOP();
1265: return SLJIT_ERR_UNSUPPORTED;
1266: }
1267:
1268: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
1269: int dst, sljit_w dstw,
1270: int src, sljit_w srcw)
1271: {
1272: SLJIT_UNUSED_ARG(compiler);
1273: SLJIT_UNUSED_ARG(op);
1274: SLJIT_UNUSED_ARG(dst);
1275: SLJIT_UNUSED_ARG(dstw);
1276: SLJIT_UNUSED_ARG(src);
1277: SLJIT_UNUSED_ARG(srcw);
1278: SLJIT_ASSERT_STOP();
1279: return SLJIT_ERR_UNSUPPORTED;
1280: }
1281:
1282: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
1283: int dst, sljit_w dstw,
1284: int src1, sljit_w src1w,
1285: int src2, sljit_w src2w)
1286: {
1287: SLJIT_UNUSED_ARG(compiler);
1288: SLJIT_UNUSED_ARG(op);
1289: SLJIT_UNUSED_ARG(dst);
1290: SLJIT_UNUSED_ARG(dstw);
1291: SLJIT_UNUSED_ARG(src1);
1292: SLJIT_UNUSED_ARG(src1w);
1293: SLJIT_UNUSED_ARG(src2);
1294: SLJIT_UNUSED_ARG(src2w);
1295: SLJIT_ASSERT_STOP();
1296: return SLJIT_ERR_UNSUPPORTED;
1297: }
1298:
1299: SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
1300: {
1301: SLJIT_ASSERT_STOP();
1302: return 0;
1303: }
1304:
1305: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
1306: int dst, sljit_w dstw,
1307: int src, sljit_w srcw)
1308: {
1309: SLJIT_UNUSED_ARG(compiler);
1310: SLJIT_UNUSED_ARG(op);
1311: SLJIT_UNUSED_ARG(dst);
1312: SLJIT_UNUSED_ARG(dstw);
1313: SLJIT_UNUSED_ARG(src);
1314: SLJIT_UNUSED_ARG(srcw);
1315: SLJIT_ASSERT_STOP();
1316: return SLJIT_ERR_UNSUPPORTED;
1317: }
1318:
1319: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
1320: int dst, sljit_w dstw,
1321: int src1, sljit_w src1w,
1322: int src2, sljit_w src2w)
1323: {
1324: SLJIT_UNUSED_ARG(compiler);
1325: SLJIT_UNUSED_ARG(op);
1326: SLJIT_UNUSED_ARG(dst);
1327: SLJIT_UNUSED_ARG(dstw);
1328: SLJIT_UNUSED_ARG(src1);
1329: SLJIT_UNUSED_ARG(src1w);
1330: SLJIT_UNUSED_ARG(src2);
1331: SLJIT_UNUSED_ARG(src2w);
1332: SLJIT_ASSERT_STOP();
1333: return SLJIT_ERR_UNSUPPORTED;
1334: }
1335:
1336: SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1337: {
1338: SLJIT_UNUSED_ARG(compiler);
1339: SLJIT_ASSERT_STOP();
1340: return NULL;
1341: }
1342:
1343: SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
1344: {
1345: SLJIT_UNUSED_ARG(compiler);
1346: SLJIT_UNUSED_ARG(type);
1347: SLJIT_ASSERT_STOP();
1348: return NULL;
1349: }
1350:
1351: SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
1352: int src1, sljit_w src1w,
1353: int src2, sljit_w src2w)
1354: {
1355: SLJIT_UNUSED_ARG(compiler);
1356: SLJIT_UNUSED_ARG(type);
1357: SLJIT_UNUSED_ARG(src1);
1358: SLJIT_UNUSED_ARG(src1w);
1359: SLJIT_UNUSED_ARG(src2);
1360: SLJIT_UNUSED_ARG(src2w);
1361: SLJIT_ASSERT_STOP();
1362: return NULL;
1363: }
1364:
1365: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
1366: {
1367: SLJIT_UNUSED_ARG(jump);
1368: SLJIT_UNUSED_ARG(label);
1369: SLJIT_ASSERT_STOP();
1370: }
1371:
1372: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
1373: {
1374: SLJIT_UNUSED_ARG(jump);
1375: SLJIT_UNUSED_ARG(target);
1376: SLJIT_ASSERT_STOP();
1377: }
1378:
1379: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
1380: {
1381: SLJIT_UNUSED_ARG(compiler);
1382: SLJIT_UNUSED_ARG(type);
1383: SLJIT_UNUSED_ARG(src);
1384: SLJIT_UNUSED_ARG(srcw);
1385: SLJIT_ASSERT_STOP();
1386: return SLJIT_ERR_UNSUPPORTED;
1387: }
1388:
1389: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
1390: {
1391: SLJIT_UNUSED_ARG(compiler);
1392: SLJIT_UNUSED_ARG(op);
1393: SLJIT_UNUSED_ARG(dst);
1394: SLJIT_UNUSED_ARG(dstw);
1395: SLJIT_UNUSED_ARG(type);
1396: SLJIT_ASSERT_STOP();
1397: return SLJIT_ERR_UNSUPPORTED;
1398: }
1399:
1400: SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval)
1401: {
1402: SLJIT_UNUSED_ARG(compiler);
1403: SLJIT_UNUSED_ARG(dst);
1404: SLJIT_UNUSED_ARG(dstw);
1405: SLJIT_UNUSED_ARG(initval);
1406: SLJIT_ASSERT_STOP();
1407: return NULL;
1408: }
1409:
1410: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
1411: {
1412: SLJIT_UNUSED_ARG(addr);
1413: SLJIT_UNUSED_ARG(new_addr);
1414: SLJIT_ASSERT_STOP();
1415: }
1416:
1417: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
1418: {
1419: SLJIT_UNUSED_ARG(addr);
1420: SLJIT_UNUSED_ARG(new_constant);
1421: SLJIT_ASSERT_STOP();
1422: }
1423:
1424: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>