/[pcre]/code/trunk/sljit/sljitLir.c
ViewVC logotype

Contents of /code/trunk/sljit/sljitLir.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1280 - (show annotations)
Fri Mar 15 06:58:31 2013 UTC (6 years, 6 months ago) by zherczeg
File MIME type: text/plain
File size: 54501 byte(s)
JIT compiler update.
1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright 2009-2012 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_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
93
94 #define TYPE_CAST_NEEDED(op) \
95 (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH))
96
97 #define BUF_SIZE 4096
98
99 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
100 #define ABUF_SIZE 2048
101 #else
102 #define ABUF_SIZE 4096
103 #endif
104
105 /* Jump flags. */
106 #define JUMP_LABEL 0x1
107 #define JUMP_ADDR 0x2
108 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
109
110 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
111 # define PATCH_MB 0x4
112 # define PATCH_MW 0x8
113 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
114 # define PATCH_MD 0x10
115 #endif
116 #endif
117
118 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
119 # define IS_BL 0x4
120 # define PATCH_B 0x8
121 #endif
122
123 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
124 # define CPOOL_SIZE 512
125 #endif
126
127 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
128 # define IS_COND 0x04
129 # define IS_BL 0x08
130 /* cannot be encoded as branch */
131 # define B_TYPE0 0x00
132 /* conditional + imm8 */
133 # define B_TYPE1 0x10
134 /* conditional + imm20 */
135 # define B_TYPE2 0x20
136 /* IT + imm24 */
137 # define B_TYPE3 0x30
138 /* imm11 */
139 # define B_TYPE4 0x40
140 /* imm24 */
141 # define B_TYPE5 0x50
142 /* BL + imm24 */
143 # define BL_TYPE6 0x60
144 /* 0xf00 cc code for branches */
145 #endif
146
147 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
148 # define UNCOND_B 0x04
149 # define PATCH_B 0x08
150 # define ABSOLUTE_B 0x10
151 #endif
152
153 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
154 # define IS_MOVABLE 0x04
155 # define IS_JAL 0x08
156 # define IS_BIT26_COND 0x10
157 # define IS_BIT16_COND 0x20
158
159 # define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
160
161 # define PATCH_B 0x40
162 # define PATCH_J 0x80
163
164 /* instruction types */
165 # define MOVABLE_INS 0
166 /* 1 - 31 last destination register */
167 /* no destination (i.e: store) */
168 # define UNMOVABLE_INS 32
169 /* FPU status register */
170 # define FCSR_FCC 33
171 #endif
172
173 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
174 # define IS_MOVABLE 0x04
175 # define IS_COND 0x08
176 # define IS_CALL 0x10
177
178 # define PATCH_B 0x20
179 # define PATCH_CALL 0x40
180
181 /* instruction types */
182 # define MOVABLE_INS 0
183 /* 1 - 31 last destination register */
184 /* no destination (i.e: store) */
185 # define UNMOVABLE_INS 32
186
187 # define DST_INS_MASK 0xff
188
189 /* ICC_SET is the same as SET_FLAGS. */
190 # define ICC_IS_SET (1 << 23)
191 # define FCC_IS_SET (1 << 24)
192 #endif
193
194 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
195 #define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1
196 #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
197 #define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw))
198 #endif
199 #endif
200
201 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
202 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
203 #ifdef _WIN64
204 #define FIXED_LOCALS_OFFSET ((4 + 2) * sizeof(sljit_sw))
205 #else
206 #define FIXED_LOCALS_OFFSET (sizeof(sljit_sw))
207 #endif
208 #endif
209
210 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
211 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
212 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
213 #define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw))
214 #else
215 #define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_sw))
216 #endif
217 #endif
218
219 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
220 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
221 #define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw))
222 #endif
223
224 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
225 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
226 #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_sw))
227 #endif
228
229 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
230 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
231 #define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw))
232 #endif
233
234 #if (defined SLJIT_HAS_VARIABLE_LOCALS_OFFSET && SLJIT_HAS_VARIABLE_LOCALS_OFFSET)
235
236 #define ADJUST_LOCAL_OFFSET(p, i) \
237 if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
238 (i) += compiler->locals_offset;
239
240 #elif (defined SLJIT_HAS_FIXED_LOCALS_OFFSET && SLJIT_HAS_FIXED_LOCALS_OFFSET)
241
242 #define ADJUST_LOCAL_OFFSET(p, i) \
243 if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
244 (i) += FIXED_LOCALS_OFFSET;
245
246 #else
247
248 #define ADJUST_LOCAL_OFFSET(p, i)
249
250 #endif
251
252 #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
253
254 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
255 #include "sljitUtils.c"
256
257 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
258
259 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
260 #include "sljitExecAllocator.c"
261 #endif
262
263 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2)
264 #error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2
265 #endif
266
267 /* --------------------------------------------------------------------- */
268 /* Public functions */
269 /* --------------------------------------------------------------------- */
270
271 #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)))
272 #define SLJIT_NEEDS_COMPILER_INIT 1
273 static sljit_si compiler_initialized = 0;
274 /* A thread safe initialization. */
275 static void init_compiler(void);
276 #endif
277
278 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
279 {
280 struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler));
281 if (!compiler)
282 return NULL;
283 SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
284
285 SLJIT_COMPILE_ASSERT(
286 sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1
287 && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2
288 && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4
289 && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
290 && sizeof(sljit_p) <= sizeof(sljit_sw)
291 && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
292 && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
293 invalid_integer_types);
294 SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP,
295 int_op_and_single_op_must_be_the_same);
296 SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP,
297 rewritable_jump_and_single_op_must_not_be_the_same);
298
299 /* Only the non-zero members must be set. */
300 compiler->error = SLJIT_SUCCESS;
301
302 compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
303 compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
304
305 if (!compiler->buf || !compiler->abuf) {
306 if (compiler->buf)
307 SLJIT_FREE(compiler->buf);
308 if (compiler->abuf)
309 SLJIT_FREE(compiler->abuf);
310 SLJIT_FREE(compiler);
311 return NULL;
312 }
313
314 compiler->buf->next = NULL;
315 compiler->buf->used_size = 0;
316 compiler->abuf->next = NULL;
317 compiler->abuf->used_size = 0;
318
319 compiler->scratches = -1;
320 compiler->saveds = -1;
321
322 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
323 compiler->args = -1;
324 #endif
325
326 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
327 compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub));
328 if (!compiler->cpool) {
329 SLJIT_FREE(compiler->buf);
330 SLJIT_FREE(compiler->abuf);
331 SLJIT_FREE(compiler);
332 return NULL;
333 }
334 compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE);
335 compiler->cpool_diff = 0xffffffff;
336 #endif
337
338 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
339 compiler->delay_slot = UNMOVABLE_INS;
340 #endif
341
342 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
343 compiler->delay_slot = UNMOVABLE_INS;
344 #endif
345
346 #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
347 if (!compiler_initialized) {
348 init_compiler();
349 compiler_initialized = 1;
350 }
351 #endif
352
353 return compiler;
354 }
355
356 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
357 {
358 struct sljit_memory_fragment *buf;
359 struct sljit_memory_fragment *curr;
360
361 buf = compiler->buf;
362 while (buf) {
363 curr = buf;
364 buf = buf->next;
365 SLJIT_FREE(curr);
366 }
367
368 buf = compiler->abuf;
369 while (buf) {
370 curr = buf;
371 buf = buf->next;
372 SLJIT_FREE(curr);
373 }
374
375 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
376 SLJIT_FREE(compiler->cpool);
377 #endif
378 SLJIT_FREE(compiler);
379 }
380
381 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
382 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
383 {
384 /* Remove thumb mode flag. */
385 SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
386 }
387 #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
388 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
389 {
390 /* Resolve indirection. */
391 code = (void*)(*(sljit_uw*)code);
392 SLJIT_FREE_EXEC(code);
393 }
394 #else
395 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
396 {
397 SLJIT_FREE_EXEC(code);
398 }
399 #endif
400
401 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
402 {
403 if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
404 jump->flags &= ~JUMP_ADDR;
405 jump->flags |= JUMP_LABEL;
406 jump->u.label = label;
407 }
408 }
409
410 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
411 {
412 if (SLJIT_LIKELY(!!jump)) {
413 SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP);
414
415 jump->flags &= ~JUMP_LABEL;
416 jump->flags |= JUMP_ADDR;
417 jump->u.target = target;
418 }
419 }
420
421 /* --------------------------------------------------------------------- */
422 /* Private functions */
423 /* --------------------------------------------------------------------- */
424
425 static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
426 {
427 sljit_ub *ret;
428 struct sljit_memory_fragment *new_frag;
429
430 SLJIT_ASSERT(size <= 256);
431 if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
432 ret = compiler->buf->memory + compiler->buf->used_size;
433 compiler->buf->used_size += size;
434 return ret;
435 }
436 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
437 PTR_FAIL_IF_NULL(new_frag);
438 new_frag->next = compiler->buf;
439 compiler->buf = new_frag;
440 new_frag->used_size = size;
441 return new_frag->memory;
442 }
443
444 static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
445 {
446 sljit_ub *ret;
447 struct sljit_memory_fragment *new_frag;
448
449 SLJIT_ASSERT(size <= 256);
450 if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
451 ret = compiler->abuf->memory + compiler->abuf->used_size;
452 compiler->abuf->used_size += size;
453 return ret;
454 }
455 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
456 PTR_FAIL_IF_NULL(new_frag);
457 new_frag->next = compiler->abuf;
458 compiler->abuf = new_frag;
459 new_frag->used_size = size;
460 return new_frag->memory;
461 }
462
463 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size)
464 {
465 CHECK_ERROR_PTR();
466
467 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
468 if (size <= 0 || size > 128)
469 return NULL;
470 size = (size + 7) & ~7;
471 #else
472 if (size <= 0 || size > 64)
473 return NULL;
474 size = (size + 3) & ~3;
475 #endif
476 return ensure_abuf(compiler, size);
477 }
478
479 static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
480 {
481 struct sljit_memory_fragment *buf = compiler->buf;
482 struct sljit_memory_fragment *prev = NULL;
483 struct sljit_memory_fragment *tmp;
484
485 do {
486 tmp = buf->next;
487 buf->next = prev;
488 prev = buf;
489 buf = tmp;
490 } while (buf != NULL);
491
492 compiler->buf = prev;
493 }
494
495 static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
496 {
497 label->next = NULL;
498 label->size = compiler->size;
499 if (compiler->last_label)
500 compiler->last_label->next = label;
501 else
502 compiler->labels = label;
503 compiler->last_label = label;
504 }
505
506 static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags)
507 {
508 jump->next = NULL;
509 jump->flags = flags;
510 if (compiler->last_jump)
511 compiler->last_jump->next = jump;
512 else
513 compiler->jumps = jump;
514 compiler->last_jump = jump;
515 }
516
517 static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
518 {
519 const_->next = NULL;
520 const_->addr = compiler->size;
521 if (compiler->last_const)
522 compiler->last_const->next = const_;
523 else
524 compiler->consts = const_;
525 compiler->last_const = const_;
526 }
527
528 #define ADDRESSING_DEPENDS_ON(exp, reg) \
529 (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg))
530
531 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
532 #define FUNCTION_CHECK_OP() \
533 SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
534 switch (GET_OPCODE(op)) { \
535 case SLJIT_NOT: \
536 case SLJIT_CLZ: \
537 case SLJIT_AND: \
538 case SLJIT_OR: \
539 case SLJIT_XOR: \
540 case SLJIT_SHL: \
541 case SLJIT_LSHR: \
542 case SLJIT_ASHR: \
543 SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \
544 break; \
545 case SLJIT_NEG: \
546 SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
547 break; \
548 case SLJIT_MUL: \
549 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
550 break; \
551 case SLJIT_CMPD: \
552 SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
553 SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
554 break; \
555 case SLJIT_ADD: \
556 SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \
557 break; \
558 case SLJIT_SUB: \
559 break; \
560 case SLJIT_ADDC: \
561 case SLJIT_SUBC: \
562 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \
563 break; \
564 case SLJIT_BREAKPOINT: \
565 case SLJIT_NOP: \
566 case SLJIT_UMUL: \
567 case SLJIT_SMUL: \
568 case SLJIT_MOV: \
569 case SLJIT_MOV_P: \
570 case SLJIT_MOVU: \
571 case SLJIT_MOVU_P: \
572 /* Nothing allowed */ \
573 SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
574 break; \
575 default: \
576 /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \
577 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
578 break; \
579 }
580
581 #define FUNCTION_CHECK_IS_REG(r) \
582 ((r) == SLJIT_UNUSED || \
583 ((r) >= SLJIT_SCRATCH_REG1 && (r) <= SLJIT_SCRATCH_REG1 - 1 + compiler->scratches) || \
584 ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds))
585
586 #define FUNCTION_CHECK_SRC(p, i) \
587 SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \
588 if (FUNCTION_CHECK_IS_REG(p)) \
589 SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \
590 else if ((p) == SLJIT_IMM) \
591 ; \
592 else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
593 SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \
594 else if ((p) & SLJIT_MEM) { \
595 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
596 if ((p) & 0xf0) { \
597 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
598 SLJIT_ASSERT(!((i) & ~0x3)); \
599 } \
600 SLJIT_ASSERT(((p) >> 9) == 0); \
601 } \
602 else \
603 SLJIT_ASSERT_STOP();
604
605 #define FUNCTION_CHECK_DST(p, i) \
606 SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \
607 if (FUNCTION_CHECK_IS_REG(p)) \
608 SLJIT_ASSERT((i) == 0); \
609 else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
610 SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \
611 else if ((p) & SLJIT_MEM) { \
612 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
613 if ((p) & 0xf0) { \
614 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
615 SLJIT_ASSERT(!((i) & ~0x3)); \
616 } \
617 SLJIT_ASSERT(((p) >> 9) == 0); \
618 } \
619 else \
620 SLJIT_ASSERT_STOP();
621
622 #define FUNCTION_FCHECK(p, i) \
623 if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG6) \
624 SLJIT_ASSERT(i == 0); \
625 else if ((p) & SLJIT_MEM) { \
626 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
627 if ((p) & 0xf0) { \
628 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
629 SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
630 } else \
631 SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
632 SLJIT_ASSERT(((p) >> 9) == 0); \
633 } \
634 else \
635 SLJIT_ASSERT_STOP();
636
637 #define FUNCTION_CHECK_OP1() \
638 if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \
639 SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \
640 SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \
641 if ((src & SLJIT_MEM) && (src & 0xf)) \
642 SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \
643 }
644
645 #endif
646
647 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
648
649 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
650 {
651 compiler->verbose = verbose;
652 }
653
654 static char* reg_names[] = {
655 (char*)"unused", (char*)"s1", (char*)"s2", (char*)"s3",
656 (char*)"se1", (char*)"se2", (char*)"p1", (char*)"p2",
657 (char*)"p3", (char*)"pe1", (char*)"pe2", (char*)"lc"
658 };
659
660 static char* freg_names[] = {
661 (char*)"unused", (char*)"f1", (char*)"f2", (char*)"f3",
662 (char*)"f4", (char*)"f5", (char*)"f6"
663 };
664
665 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
666 #ifdef _WIN64
667 # define SLJIT_PRINT_D "I64"
668 #else
669 # define SLJIT_PRINT_D "l"
670 #endif
671 #else
672 # define SLJIT_PRINT_D ""
673 #endif
674
675 #define sljit_verbose_param(p, i) \
676 if ((p) & SLJIT_IMM) \
677 fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \
678 else if ((p) & SLJIT_MEM) { \
679 if ((p) & 0xf) { \
680 if (i) { \
681 if (((p) >> 4) & 0xf) \
682 fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
683 else \
684 fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \
685 } \
686 else { \
687 if (((p) >> 4) & 0xf) \
688 fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
689 else \
690 fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
691 } \
692 } \
693 else \
694 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
695 } else \
696 fprintf(compiler->verbose, "%s", reg_names[p]);
697 #define sljit_verbose_fparam(p, i) \
698 if ((p) & SLJIT_MEM) { \
699 if ((p) & 0xf) { \
700 if (i) { \
701 if (((p) >> 4) & 0xf) \
702 fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
703 else \
704 fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \
705 } \
706 else { \
707 if (((p) >> 4) & 0xF) \
708 fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
709 else \
710 fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
711 } \
712 } \
713 else \
714 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
715 } else \
716 fprintf(compiler->verbose, "%s", freg_names[p]);
717
718 static SLJIT_CONST char* op_names[] = {
719 /* op0 */
720 (char*)"breakpoint", (char*)"nop",
721 (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv",
722 /* op1 */
723 (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh",
724 (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"mov.p",
725 (char*)"movu", (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh",
726 (char*)"movu.sh", (char*)"movu.ui", (char*)"movu.si", (char*)"movu.p",
727 (char*)"not", (char*)"neg", (char*)"clz",
728 /* op2 */
729 (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
730 (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
731 (char*)"shl", (char*)"lshr", (char*)"ashr",
732 /* fop1 */
733 (char*)"cmp", (char*)"mov", (char*)"neg", (char*)"abs",
734 /* fop2 */
735 (char*)"add", (char*)"sub", (char*)"mul", (char*)"div"
736 };
737
738 static char* jump_names[] = {
739 (char*)"equal", (char*)"not_equal",
740 (char*)"less", (char*)"greater_equal",
741 (char*)"greater", (char*)"less_equal",
742 (char*)"sig_less", (char*)"sig_greater_equal",
743 (char*)"sig_greater", (char*)"sig_less_equal",
744 (char*)"overflow", (char*)"not_overflow",
745 (char*)"mul_overflow", (char*)"mul_not_overflow",
746 (char*)"float_equal", (char*)"float_not_equal",
747 (char*)"float_less", (char*)"float_greater_equal",
748 (char*)"float_greater", (char*)"float_less_equal",
749 (char*)"float_unordered", (char*)"float_ordered",
750 (char*)"jump", (char*)"fast_call",
751 (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
752 };
753
754 #endif
755
756 /* --------------------------------------------------------------------- */
757 /* Arch dependent */
758 /* --------------------------------------------------------------------- */
759
760 static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler)
761 {
762 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
763 struct sljit_jump *jump;
764 #endif
765 /* If debug and verbose are disabled, all arguments are unused. */
766 SLJIT_UNUSED_ARG(compiler);
767
768 SLJIT_ASSERT(compiler->size > 0);
769 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
770 jump = compiler->jumps;
771 while (jump) {
772 /* All jumps have target. */
773 SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
774 jump = jump->next;
775 }
776 #endif
777 }
778
779 static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
780 {
781 /* If debug and verbose are disabled, all arguments are unused. */
782 SLJIT_UNUSED_ARG(compiler);
783 SLJIT_UNUSED_ARG(args);
784 SLJIT_UNUSED_ARG(scratches);
785 SLJIT_UNUSED_ARG(saveds);
786 SLJIT_UNUSED_ARG(local_size);
787
788 SLJIT_ASSERT(args >= 0 && args <= 3);
789 SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS);
790 SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
791 SLJIT_ASSERT(args <= saveds);
792 SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
793 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
794 if (SLJIT_UNLIKELY(!!compiler->verbose))
795 fprintf(compiler->verbose, " enter args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size);
796 #endif
797 }
798
799 static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
800 {
801 /* If debug and verbose are disabled, all arguments are unused. */
802 SLJIT_UNUSED_ARG(compiler);
803 SLJIT_UNUSED_ARG(args);
804 SLJIT_UNUSED_ARG(scratches);
805 SLJIT_UNUSED_ARG(saveds);
806 SLJIT_UNUSED_ARG(local_size);
807
808 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
809 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
810 compiler->skip_checks = 0;
811 return;
812 }
813 #endif
814
815 SLJIT_ASSERT(args >= 0 && args <= 3);
816 SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS);
817 SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
818 SLJIT_ASSERT(args <= saveds);
819 SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
820 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
821 if (SLJIT_UNLIKELY(!!compiler->verbose))
822 fprintf(compiler->verbose, " set_context args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size);
823 #endif
824 }
825
826 static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
827 {
828 /* If debug and verbose are disabled, all arguments are unused. */
829 SLJIT_UNUSED_ARG(compiler);
830 SLJIT_UNUSED_ARG(op);
831 SLJIT_UNUSED_ARG(src);
832 SLJIT_UNUSED_ARG(srcw);
833
834 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
835 if (op != SLJIT_UNUSED) {
836 SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_P);
837 FUNCTION_CHECK_SRC(src, srcw);
838 }
839 else
840 SLJIT_ASSERT(src == 0 && srcw == 0);
841 #endif
842 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
843 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
844 if (op == SLJIT_UNUSED)
845 fprintf(compiler->verbose, " return\n");
846 else {
847 fprintf(compiler->verbose, " return %s ", op_names[op]);
848 sljit_verbose_param(src, srcw);
849 fprintf(compiler->verbose, "\n");
850 }
851 }
852 #endif
853 }
854
855 static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
856 {
857 /* If debug and verbose are disabled, all arguments are unused. */
858 SLJIT_UNUSED_ARG(compiler);
859 SLJIT_UNUSED_ARG(dst);
860 SLJIT_UNUSED_ARG(dstw);
861
862 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
863 FUNCTION_CHECK_DST(dst, dstw);
864 #endif
865 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
866 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
867 fprintf(compiler->verbose, " fast_enter ");
868 sljit_verbose_param(dst, dstw);
869 fprintf(compiler->verbose, "\n");
870 }
871 #endif
872 }
873
874 static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
875 {
876 /* If debug and verbose are disabled, all arguments are unused. */
877 SLJIT_UNUSED_ARG(compiler);
878 SLJIT_UNUSED_ARG(src);
879 SLJIT_UNUSED_ARG(srcw);
880
881 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
882 FUNCTION_CHECK_SRC(src, srcw);
883 #endif
884 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
885 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
886 fprintf(compiler->verbose, " fast_return ");
887 sljit_verbose_param(src, srcw);
888 fprintf(compiler->verbose, "\n");
889 }
890 #endif
891 }
892
893 static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
894 {
895 /* If debug and verbose are disabled, all arguments are unused. */
896 SLJIT_UNUSED_ARG(compiler);
897 SLJIT_UNUSED_ARG(op);
898
899 SLJIT_ASSERT((op >= SLJIT_BREAKPOINT && op <= SLJIT_SMUL)
900 || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV));
901 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
902 if (SLJIT_UNLIKELY(!!compiler->verbose))
903 fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]);
904 #endif
905 }
906
907 static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
908 sljit_si dst, sljit_sw dstw,
909 sljit_si src, sljit_sw srcw)
910 {
911 /* If debug and verbose are disabled, all arguments are unused. */
912 SLJIT_UNUSED_ARG(compiler);
913 SLJIT_UNUSED_ARG(op);
914 SLJIT_UNUSED_ARG(dst);
915 SLJIT_UNUSED_ARG(dstw);
916 SLJIT_UNUSED_ARG(src);
917 SLJIT_UNUSED_ARG(srcw);
918
919 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
920 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
921 compiler->skip_checks = 0;
922 return;
923 }
924 #endif
925
926 SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
927 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
928 FUNCTION_CHECK_OP();
929 FUNCTION_CHECK_SRC(src, srcw);
930 FUNCTION_CHECK_DST(dst, dstw);
931 FUNCTION_CHECK_OP1();
932 #endif
933 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
934 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
935 fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
936 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u",
937 !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
938 sljit_verbose_param(dst, dstw);
939 fprintf(compiler->verbose, ", ");
940 sljit_verbose_param(src, srcw);
941 fprintf(compiler->verbose, "\n");
942 }
943 #endif
944 }
945
946 static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
947 sljit_si dst, sljit_sw dstw,
948 sljit_si src1, sljit_sw src1w,
949 sljit_si src2, sljit_sw src2w)
950 {
951 /* If debug and verbose are disabled, all arguments are unused. */
952 SLJIT_UNUSED_ARG(compiler);
953 SLJIT_UNUSED_ARG(op);
954 SLJIT_UNUSED_ARG(dst);
955 SLJIT_UNUSED_ARG(dstw);
956 SLJIT_UNUSED_ARG(src1);
957 SLJIT_UNUSED_ARG(src1w);
958 SLJIT_UNUSED_ARG(src2);
959 SLJIT_UNUSED_ARG(src2w);
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(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
969 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
970 FUNCTION_CHECK_OP();
971 FUNCTION_CHECK_SRC(src1, src1w);
972 FUNCTION_CHECK_SRC(src2, src2w);
973 FUNCTION_CHECK_DST(dst, dstw);
974 #endif
975 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
976 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
977 fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
978 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u",
979 !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
980 sljit_verbose_param(dst, dstw);
981 fprintf(compiler->verbose, ", ");
982 sljit_verbose_param(src1, src1w);
983 fprintf(compiler->verbose, ", ");
984 sljit_verbose_param(src2, src2w);
985 fprintf(compiler->verbose, "\n");
986 }
987 #endif
988 }
989
990 static SLJIT_INLINE void check_sljit_get_register_index(sljit_si reg)
991 {
992 SLJIT_UNUSED_ARG(reg);
993 SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS);
994 }
995
996 static SLJIT_INLINE void check_sljit_get_float_register_index(sljit_si reg)
997 {
998 SLJIT_UNUSED_ARG(reg);
999 SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_FLOAT_REGISTERS);
1000 }
1001
1002 static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler,
1003 void *instruction, sljit_si size)
1004 {
1005 SLJIT_UNUSED_ARG(compiler);
1006 SLJIT_UNUSED_ARG(instruction);
1007 SLJIT_UNUSED_ARG(size);
1008 SLJIT_ASSERT(instruction);
1009 }
1010
1011 static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1012 sljit_si dst, sljit_sw dstw,
1013 sljit_si src, sljit_sw srcw)
1014 {
1015 /* If debug and verbose are disabled, all arguments are unused. */
1016 SLJIT_UNUSED_ARG(compiler);
1017 SLJIT_UNUSED_ARG(op);
1018 SLJIT_UNUSED_ARG(dst);
1019 SLJIT_UNUSED_ARG(dstw);
1020 SLJIT_UNUSED_ARG(src);
1021 SLJIT_UNUSED_ARG(srcw);
1022
1023 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1024 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1025 compiler->skip_checks = 0;
1026 return;
1027 }
1028 #endif
1029
1030 SLJIT_ASSERT(sljit_is_fpu_available());
1031 SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_CMPD && GET_OPCODE(op) <= SLJIT_ABSD);
1032 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1033 FUNCTION_CHECK_OP();
1034 FUNCTION_FCHECK(src, srcw);
1035 FUNCTION_FCHECK(dst, dstw);
1036 #endif
1037 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1038 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1039 fprintf(compiler->verbose, " %s%s%s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d",
1040 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s");
1041 sljit_verbose_fparam(dst, dstw);
1042 fprintf(compiler->verbose, ", ");
1043 sljit_verbose_fparam(src, srcw);
1044 fprintf(compiler->verbose, "\n");
1045 }
1046 #endif
1047 }
1048
1049 static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1050 sljit_si dst, sljit_sw dstw,
1051 sljit_si src1, sljit_sw src1w,
1052 sljit_si src2, sljit_sw src2w)
1053 {
1054 /* If debug and verbose are disabled, all arguments are unused. */
1055 SLJIT_UNUSED_ARG(compiler);
1056 SLJIT_UNUSED_ARG(op);
1057 SLJIT_UNUSED_ARG(dst);
1058 SLJIT_UNUSED_ARG(dstw);
1059 SLJIT_UNUSED_ARG(src1);
1060 SLJIT_UNUSED_ARG(src1w);
1061 SLJIT_UNUSED_ARG(src2);
1062 SLJIT_UNUSED_ARG(src2w);
1063
1064 SLJIT_ASSERT(sljit_is_fpu_available());
1065 SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADDD && GET_OPCODE(op) <= SLJIT_DIVD);
1066 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1067 FUNCTION_CHECK_OP();
1068 FUNCTION_FCHECK(src1, src1w);
1069 FUNCTION_FCHECK(src2, src2w);
1070 FUNCTION_FCHECK(dst, dstw);
1071 #endif
1072 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1073 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1074 fprintf(compiler->verbose, " %s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d");
1075 sljit_verbose_fparam(dst, dstw);
1076 fprintf(compiler->verbose, ", ");
1077 sljit_verbose_fparam(src1, src1w);
1078 fprintf(compiler->verbose, ", ");
1079 sljit_verbose_fparam(src2, src2w);
1080 fprintf(compiler->verbose, "\n");
1081 }
1082 #endif
1083 }
1084
1085 static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler)
1086 {
1087 /* If debug and verbose are disabled, all arguments are unused. */
1088 SLJIT_UNUSED_ARG(compiler);
1089
1090 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1091 if (SLJIT_UNLIKELY(!!compiler->verbose))
1092 fprintf(compiler->verbose, "label:\n");
1093 #endif
1094 }
1095
1096 static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1097 {
1098 /* If debug and verbose are disabled, all arguments are unused. */
1099 SLJIT_UNUSED_ARG(compiler);
1100 SLJIT_UNUSED_ARG(type);
1101
1102 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1103 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1104 compiler->skip_checks = 0;
1105 return;
1106 }
1107 #endif
1108
1109 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
1110 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
1111 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1112 if (SLJIT_UNLIKELY(!!compiler->verbose))
1113 fprintf(compiler->verbose, " jump%s.%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1114 #endif
1115 }
1116
1117 static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1118 sljit_si src1, sljit_sw src1w,
1119 sljit_si src2, sljit_sw src2w)
1120 {
1121 SLJIT_UNUSED_ARG(compiler);
1122 SLJIT_UNUSED_ARG(type);
1123 SLJIT_UNUSED_ARG(src1);
1124 SLJIT_UNUSED_ARG(src1w);
1125 SLJIT_UNUSED_ARG(src2);
1126 SLJIT_UNUSED_ARG(src2w);
1127
1128 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP)));
1129 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL);
1130 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1131 FUNCTION_CHECK_SRC(src1, src1w);
1132 FUNCTION_CHECK_SRC(src2, src2w);
1133 #endif
1134 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1135 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1136 fprintf(compiler->verbose, " %scmp%s.%s ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1137 sljit_verbose_param(src1, src1w);
1138 fprintf(compiler->verbose, ", ");
1139 sljit_verbose_param(src2, src2w);
1140 fprintf(compiler->verbose, "\n");
1141 }
1142 #endif
1143 }
1144
1145 static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1146 sljit_si src1, sljit_sw src1w,
1147 sljit_si src2, sljit_sw src2w)
1148 {
1149 SLJIT_UNUSED_ARG(compiler);
1150 SLJIT_UNUSED_ARG(type);
1151 SLJIT_UNUSED_ARG(src1);
1152 SLJIT_UNUSED_ARG(src1w);
1153 SLJIT_UNUSED_ARG(src2);
1154 SLJIT_UNUSED_ARG(src2w);
1155
1156 SLJIT_ASSERT(sljit_is_fpu_available());
1157 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP)));
1158 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_ORDERED);
1159 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1160 FUNCTION_FCHECK(src1, src1w);
1161 FUNCTION_FCHECK(src2, src2w);
1162 #endif
1163 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1164 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1165 fprintf(compiler->verbose, " %scmp%s.%s ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
1166 !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1167 sljit_verbose_fparam(src1, src1w);
1168 fprintf(compiler->verbose, ", ");
1169 sljit_verbose_fparam(src2, src2w);
1170 fprintf(compiler->verbose, "\n");
1171 }
1172 #endif
1173 }
1174
1175 static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1176 {
1177 /* If debug and verbose are disabled, all arguments are unused. */
1178 SLJIT_UNUSED_ARG(compiler);
1179 SLJIT_UNUSED_ARG(type);
1180 SLJIT_UNUSED_ARG(src);
1181 SLJIT_UNUSED_ARG(srcw);
1182
1183 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1184 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1185 compiler->skip_checks = 0;
1186 return;
1187 }
1188 #endif
1189
1190 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
1191 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1192 FUNCTION_CHECK_SRC(src, srcw);
1193 #endif
1194 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1195 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1196 fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
1197 sljit_verbose_param(src, srcw);
1198 fprintf(compiler->verbose, "\n");
1199 }
1200 #endif
1201 }
1202
1203 static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1204 sljit_si dst, sljit_sw dstw,
1205 sljit_si src, sljit_sw srcw,
1206 sljit_si type)
1207 {
1208 /* If debug and verbose are disabled, all arguments are unused. */
1209 SLJIT_UNUSED_ARG(compiler);
1210 SLJIT_UNUSED_ARG(op);
1211 SLJIT_UNUSED_ARG(dst);
1212 SLJIT_UNUSED_ARG(dstw);
1213 SLJIT_UNUSED_ARG(src);
1214 SLJIT_UNUSED_ARG(srcw);
1215 SLJIT_UNUSED_ARG(type);
1216
1217 SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP);
1218 SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI
1219 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
1220 SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0);
1221 SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS));
1222 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1223 if (GET_OPCODE(op) < SLJIT_ADD) {
1224 SLJIT_ASSERT(src == SLJIT_UNUSED && srcw == 0);
1225 } else {
1226 SLJIT_ASSERT(src == dst && srcw == dstw);
1227 }
1228 FUNCTION_CHECK_DST(dst, dstw);
1229 #endif
1230 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1231 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1232 fprintf(compiler->verbose, " %sflags.%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i",
1233 op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
1234 sljit_verbose_param(dst, dstw);
1235 if (src != SLJIT_UNUSED) {
1236 fprintf(compiler->verbose, ", ");
1237 sljit_verbose_param(src, srcw);
1238 }
1239 fprintf(compiler->verbose, ", %s\n", jump_names[type]);
1240 }
1241 #endif
1242 }
1243
1244 static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1245 {
1246 SLJIT_UNUSED_ARG(compiler);
1247 SLJIT_UNUSED_ARG(dst);
1248 SLJIT_UNUSED_ARG(dstw);
1249 SLJIT_UNUSED_ARG(offset);
1250
1251 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1252 FUNCTION_CHECK_DST(dst, dstw);
1253 #endif
1254 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1255 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1256 fprintf(compiler->verbose, " local_base ");
1257 sljit_verbose_param(dst, dstw);
1258 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
1259 }
1260 #endif
1261 }
1262
1263 static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
1264 {
1265 /* If debug and verbose are disabled, all arguments are unused. */
1266 SLJIT_UNUSED_ARG(compiler);
1267 SLJIT_UNUSED_ARG(dst);
1268 SLJIT_UNUSED_ARG(dstw);
1269 SLJIT_UNUSED_ARG(init_value);
1270
1271 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1272 FUNCTION_CHECK_DST(dst, dstw);
1273 #endif
1274 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1275 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1276 fprintf(compiler->verbose, " const ");
1277 sljit_verbose_param(dst, dstw);
1278 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
1279 }
1280 #endif
1281 }
1282
1283 static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1284 {
1285 /* Return if don't need to do anything. */
1286 if (op == SLJIT_UNUSED)
1287 return SLJIT_SUCCESS;
1288
1289 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1290 /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
1291 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
1292 return SLJIT_SUCCESS;
1293 #else
1294 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P))
1295 return SLJIT_SUCCESS;
1296 #endif
1297
1298 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1299 compiler->skip_checks = 1;
1300 #endif
1301 return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
1302 }
1303
1304 /* CPU description section */
1305
1306 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
1307 #define SLJIT_CPUINFO_PART1 " 32bit ("
1308 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1309 #define SLJIT_CPUINFO_PART1 " 64bit ("
1310 #else
1311 #error "Internal error: CPU type info missing"
1312 #endif
1313
1314 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1315 #define SLJIT_CPUINFO_PART2 "little endian + "
1316 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
1317 #define SLJIT_CPUINFO_PART2 "big endian + "
1318 #else
1319 #error "Internal error: CPU type info missing"
1320 #endif
1321
1322 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
1323 #define SLJIT_CPUINFO_PART3 "unaligned)"
1324 #else
1325 #define SLJIT_CPUINFO_PART3 "aligned)"
1326 #endif
1327
1328 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
1329
1330 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1331 # include "sljitNativeX86_common.c"
1332 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1333 # include "sljitNativeX86_common.c"
1334 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1335 # include "sljitNativeARM_v5.c"
1336 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
1337 # include "sljitNativeARM_v5.c"
1338 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1339 # include "sljitNativeARM_Thumb2.c"
1340 #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1341 # include "sljitNativePPC_common.c"
1342 #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1343 # include "sljitNativePPC_common.c"
1344 #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1345 # include "sljitNativeMIPS_common.c"
1346 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
1347 # include "sljitNativeSPARC_common.c"
1348 #endif
1349
1350 #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1351
1352 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1353 sljit_si src1, sljit_sw src1w,
1354 sljit_si src2, sljit_sw src2w)
1355 {
1356 /* Default compare for most architectures. */
1357 sljit_si flags, tmp_src, condition;
1358 sljit_sw tmp_srcw;
1359
1360 CHECK_ERROR_PTR();
1361 check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
1362
1363 condition = type & 0xff;
1364 if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
1365 /* Immediate is prefered as second argument by most architectures. */
1366 switch (condition) {
1367 case SLJIT_C_LESS:
1368 condition = SLJIT_C_GREATER;
1369 break;
1370 case SLJIT_C_GREATER_EQUAL:
1371 condition = SLJIT_C_LESS_EQUAL;
1372 break;
1373 case SLJIT_C_GREATER:
1374 condition = SLJIT_C_LESS;
1375 break;
1376 case SLJIT_C_LESS_EQUAL:
1377 condition = SLJIT_C_GREATER_EQUAL;
1378 break;
1379 case SLJIT_C_SIG_LESS:
1380 condition = SLJIT_C_SIG_GREATER;
1381 break;
1382 case SLJIT_C_SIG_GREATER_EQUAL:
1383 condition = SLJIT_C_SIG_LESS_EQUAL;
1384 break;
1385 case SLJIT_C_SIG_GREATER:
1386 condition = SLJIT_C_SIG_LESS;
1387 break;
1388 case SLJIT_C_SIG_LESS_EQUAL:
1389 condition = SLJIT_C_SIG_GREATER_EQUAL;
1390 break;
1391 }
1392 type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP));
1393 tmp_src = src1;
1394 src1 = src2;
1395 src2 = tmp_src;
1396 tmp_srcw = src1w;
1397 src1w = src2w;
1398 src2w = tmp_srcw;
1399 }
1400
1401 if (condition <= SLJIT_C_NOT_ZERO)
1402 flags = SLJIT_SET_E;
1403 else if (condition <= SLJIT_C_LESS_EQUAL)
1404 flags = SLJIT_SET_U;
1405 else
1406 flags = SLJIT_SET_S;
1407
1408 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1409 compiler->skip_checks = 1;
1410 #endif
1411 PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP),
1412 SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
1413 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1414 compiler->skip_checks = 1;
1415 #endif
1416 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
1417 }
1418
1419 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1420 sljit_si src1, sljit_sw src1w,
1421 sljit_si src2, sljit_sw src2w)
1422 {
1423 sljit_si flags, condition;
1424
1425 check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
1426
1427 condition = type & 0xff;
1428 flags = (condition <= SLJIT_C_FLOAT_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S;
1429 if (type & SLJIT_SINGLE_OP)
1430 flags |= SLJIT_SINGLE_OP;
1431
1432 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1433 compiler->skip_checks = 1;
1434 #endif
1435 sljit_emit_fop1(compiler, SLJIT_CMPD | flags, src1, src1w, src2, src2w);
1436
1437 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1438 compiler->skip_checks = 1;
1439 #endif
1440 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
1441 }
1442
1443 #endif
1444
1445 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1446
1447 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1448 {
1449 CHECK_ERROR();
1450 check_sljit_get_local_base(compiler, dst, dstw, offset);
1451
1452 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
1453 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1454 compiler->skip_checks = 1;
1455 #endif
1456 if (offset != 0)
1457 return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
1458 return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_LOCALS_REG, 0);
1459 }
1460
1461 #endif
1462
1463 #else /* SLJIT_CONFIG_UNSUPPORTED */
1464
1465 /* Empty function bodies for those machines, which are not (yet) supported. */
1466
1467 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
1468 {
1469 return "unsupported";
1470 }
1471
1472 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
1473 {
1474 SLJIT_ASSERT_STOP();
1475 return NULL;
1476 }
1477
1478 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
1479 {
1480 SLJIT_UNUSED_ARG(compiler);
1481 SLJIT_ASSERT_STOP();
1482 }
1483
1484 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size)
1485 {
1486 SLJIT_UNUSED_ARG(compiler);
1487 SLJIT_UNUSED_ARG(size);
1488 SLJIT_ASSERT_STOP();
1489 return NULL;
1490 }
1491
1492 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1493 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
1494 {
1495 SLJIT_UNUSED_ARG(compiler);
1496 SLJIT_UNUSED_ARG(verbose);
1497 SLJIT_ASSERT_STOP();
1498 }
1499 #endif
1500
1501 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
1502 {
1503 SLJIT_UNUSED_ARG(compiler);
1504 SLJIT_ASSERT_STOP();
1505 return NULL;
1506 }
1507
1508 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
1509 {
1510 SLJIT_UNUSED_ARG(code);
1511 SLJIT_ASSERT_STOP();
1512 }
1513
1514 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
1515 {
1516 SLJIT_UNUSED_ARG(compiler);
1517 SLJIT_UNUSED_ARG(args);
1518 SLJIT_UNUSED_ARG(scratches);
1519 SLJIT_UNUSED_ARG(saveds);
1520 SLJIT_UNUSED_ARG(local_size);
1521 SLJIT_ASSERT_STOP();
1522 return SLJIT_ERR_UNSUPPORTED;
1523 }
1524
1525 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
1526 {
1527 SLJIT_UNUSED_ARG(compiler);
1528 SLJIT_UNUSED_ARG(args);
1529 SLJIT_UNUSED_ARG(scratches);
1530 SLJIT_UNUSED_ARG(saveds);
1531 SLJIT_UNUSED_ARG(local_size);
1532 SLJIT_ASSERT_STOP();
1533 }
1534
1535 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1536 {
1537 SLJIT_UNUSED_ARG(compiler);
1538 SLJIT_UNUSED_ARG(op);
1539 SLJIT_UNUSED_ARG(src);
1540 SLJIT_UNUSED_ARG(srcw);
1541 SLJIT_ASSERT_STOP();
1542 return SLJIT_ERR_UNSUPPORTED;
1543 }
1544
1545 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1546 {
1547 SLJIT_UNUSED_ARG(compiler);
1548 SLJIT_UNUSED_ARG(dst);
1549 SLJIT_UNUSED_ARG(dstw);
1550 SLJIT_ASSERT_STOP();
1551 return SLJIT_ERR_UNSUPPORTED;
1552 }
1553
1554 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1555 {
1556 SLJIT_UNUSED_ARG(compiler);
1557 SLJIT_UNUSED_ARG(src);
1558 SLJIT_UNUSED_ARG(srcw);
1559 SLJIT_ASSERT_STOP();
1560 return SLJIT_ERR_UNSUPPORTED;
1561 }
1562
1563 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1564 {
1565 SLJIT_UNUSED_ARG(compiler);
1566 SLJIT_UNUSED_ARG(op);
1567 SLJIT_ASSERT_STOP();
1568 return SLJIT_ERR_UNSUPPORTED;
1569 }
1570
1571 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1572 sljit_si dst, sljit_sw dstw,
1573 sljit_si src, sljit_sw srcw)
1574 {
1575 SLJIT_UNUSED_ARG(compiler);
1576 SLJIT_UNUSED_ARG(op);
1577 SLJIT_UNUSED_ARG(dst);
1578 SLJIT_UNUSED_ARG(dstw);
1579 SLJIT_UNUSED_ARG(src);
1580 SLJIT_UNUSED_ARG(srcw);
1581 SLJIT_ASSERT_STOP();
1582 return SLJIT_ERR_UNSUPPORTED;
1583 }
1584
1585 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1586 sljit_si dst, sljit_sw dstw,
1587 sljit_si src1, sljit_sw src1w,
1588 sljit_si src2, sljit_sw src2w)
1589 {
1590 SLJIT_UNUSED_ARG(compiler);
1591 SLJIT_UNUSED_ARG(op);
1592 SLJIT_UNUSED_ARG(dst);
1593 SLJIT_UNUSED_ARG(dstw);
1594 SLJIT_UNUSED_ARG(src1);
1595 SLJIT_UNUSED_ARG(src1w);
1596 SLJIT_UNUSED_ARG(src2);
1597 SLJIT_UNUSED_ARG(src2w);
1598 SLJIT_ASSERT_STOP();
1599 return SLJIT_ERR_UNSUPPORTED;
1600 }
1601
1602 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1603 {
1604 SLJIT_ASSERT_STOP();
1605 return reg;
1606 }
1607
1608 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1609 void *instruction, sljit_si size)
1610 {
1611 SLJIT_UNUSED_ARG(compiler);
1612 SLJIT_UNUSED_ARG(instruction);
1613 SLJIT_UNUSED_ARG(size);
1614 SLJIT_ASSERT_STOP();
1615 return SLJIT_ERR_UNSUPPORTED;
1616 }
1617
1618 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
1619 {
1620 SLJIT_ASSERT_STOP();
1621 return 0;
1622 }
1623
1624 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1625 sljit_si dst, sljit_sw dstw,
1626 sljit_si src, sljit_sw srcw)
1627 {
1628 SLJIT_UNUSED_ARG(compiler);
1629 SLJIT_UNUSED_ARG(op);
1630 SLJIT_UNUSED_ARG(dst);
1631 SLJIT_UNUSED_ARG(dstw);
1632 SLJIT_UNUSED_ARG(src);
1633 SLJIT_UNUSED_ARG(srcw);
1634 SLJIT_ASSERT_STOP();
1635 return SLJIT_ERR_UNSUPPORTED;
1636 }
1637
1638 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1639 sljit_si dst, sljit_sw dstw,
1640 sljit_si src1, sljit_sw src1w,
1641 sljit_si src2, sljit_sw src2w)
1642 {
1643 SLJIT_UNUSED_ARG(compiler);
1644 SLJIT_UNUSED_ARG(op);
1645 SLJIT_UNUSED_ARG(dst);
1646 SLJIT_UNUSED_ARG(dstw);
1647 SLJIT_UNUSED_ARG(src1);
1648 SLJIT_UNUSED_ARG(src1w);
1649 SLJIT_UNUSED_ARG(src2);
1650 SLJIT_UNUSED_ARG(src2w);
1651 SLJIT_ASSERT_STOP();
1652 return SLJIT_ERR_UNSUPPORTED;
1653 }
1654
1655 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1656 {
1657 SLJIT_UNUSED_ARG(compiler);
1658 SLJIT_ASSERT_STOP();
1659 return NULL;
1660 }
1661
1662 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1663 {
1664 SLJIT_UNUSED_ARG(compiler);
1665 SLJIT_UNUSED_ARG(type);
1666 SLJIT_ASSERT_STOP();
1667 return NULL;
1668 }
1669
1670 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1671 sljit_si src1, sljit_sw src1w,
1672 sljit_si src2, sljit_sw src2w)
1673 {
1674 SLJIT_UNUSED_ARG(compiler);
1675 SLJIT_UNUSED_ARG(type);
1676 SLJIT_UNUSED_ARG(src1);
1677 SLJIT_UNUSED_ARG(src1w);
1678 SLJIT_UNUSED_ARG(src2);
1679 SLJIT_UNUSED_ARG(src2w);
1680 SLJIT_ASSERT_STOP();
1681 return NULL;
1682 }
1683
1684 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1685 sljit_si src1, sljit_sw src1w,
1686 sljit_si src2, sljit_sw src2w)
1687 {
1688 SLJIT_UNUSED_ARG(compiler);
1689 SLJIT_UNUSED_ARG(type);
1690 SLJIT_UNUSED_ARG(src1);
1691 SLJIT_UNUSED_ARG(src1w);
1692 SLJIT_UNUSED_ARG(src2);
1693 SLJIT_UNUSED_ARG(src2w);
1694 SLJIT_ASSERT_STOP();
1695 return NULL;
1696 }
1697
1698 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
1699 {
1700 SLJIT_UNUSED_ARG(jump);
1701 SLJIT_UNUSED_ARG(label);
1702 SLJIT_ASSERT_STOP();
1703 }
1704
1705 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
1706 {
1707 SLJIT_UNUSED_ARG(jump);
1708 SLJIT_UNUSED_ARG(target);
1709 SLJIT_ASSERT_STOP();
1710 }
1711
1712 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1713 {
1714 SLJIT_UNUSED_ARG(compiler);
1715 SLJIT_UNUSED_ARG(type);
1716 SLJIT_UNUSED_ARG(src);
1717 SLJIT_UNUSED_ARG(srcw);
1718 SLJIT_ASSERT_STOP();
1719 return SLJIT_ERR_UNSUPPORTED;
1720 }
1721
1722 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1723 sljit_si dst, sljit_sw dstw,
1724 sljit_si src, sljit_sw srcw,
1725 sljit_si type)
1726 {
1727 SLJIT_UNUSED_ARG(compiler);
1728 SLJIT_UNUSED_ARG(op);
1729 SLJIT_UNUSED_ARG(dst);
1730 SLJIT_UNUSED_ARG(dstw);
1731 SLJIT_UNUSED_ARG(src);
1732 SLJIT_UNUSED_ARG(srcw);
1733 SLJIT_UNUSED_ARG(type);
1734 SLJIT_ASSERT_STOP();
1735 return SLJIT_ERR_UNSUPPORTED;
1736 }
1737
1738 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1739 {
1740 SLJIT_UNUSED_ARG(compiler);
1741 SLJIT_UNUSED_ARG(dst);
1742 SLJIT_UNUSED_ARG(dstw);
1743 SLJIT_UNUSED_ARG(offset);
1744 SLJIT_ASSERT_STOP();
1745 return SLJIT_ERR_UNSUPPORTED;
1746 }
1747
1748 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval)
1749 {
1750 SLJIT_UNUSED_ARG(compiler);
1751 SLJIT_UNUSED_ARG(dst);
1752 SLJIT_UNUSED_ARG(dstw);
1753 SLJIT_UNUSED_ARG(initval);
1754 SLJIT_ASSERT_STOP();
1755 return NULL;
1756 }
1757
1758 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
1759 {
1760 SLJIT_UNUSED_ARG(addr);
1761 SLJIT_UNUSED_ARG(new_addr);
1762 SLJIT_ASSERT_STOP();
1763 }
1764
1765 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
1766 {
1767 SLJIT_UNUSED_ARG(addr);
1768 SLJIT_UNUSED_ARG(new_constant);
1769 SLJIT_ASSERT_STOP();
1770 }
1771
1772 #endif

  ViewVC Help
Powered by ViewVC 1.1.5