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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1222 - (show annotations)
Mon Nov 19 08:04:03 2012 UTC (6 years, 9 months ago) by zherczeg
File MIME type: text/plain
File size: 54430 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*)"<noreg>", (char*)"t1", (char*)"t2", (char*)"t3",
656 (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2",
657 (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr"
658 };
659
660 static char* freg_names[] = {
661 (char*)"<noreg>", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3",
662 (char*)"float_r4", (char*)"float_r5", (char*)"float_r6"
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*)"c_equal", (char*)"c_not_equal",
740 (char*)"c_less", (char*)"c_greater_equal",
741 (char*)"c_greater", (char*)"c_less_equal",
742 (char*)"c_sig_less", (char*)"c_sig_greater_equal",
743 (char*)"c_sig_greater", (char*)"c_sig_less_equal",
744 (char*)"c_overflow", (char*)"c_not_overflow",
745 (char*)"c_mul_overflow", (char*)"c_mul_not_overflow",
746 (char*)"c_float_equal", (char*)"c_float_not_equal",
747 (char*)"c_float_less", (char*)"c_float_greater_equal",
748 (char*)"c_float_greater", (char*)"c_float_less_equal",
749 (char*)"c_float_unordered", (char*)"c_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_emit_op_custom(struct sljit_compiler *compiler,
997 void *instruction, sljit_si size)
998 {
999 SLJIT_UNUSED_ARG(compiler);
1000 SLJIT_UNUSED_ARG(instruction);
1001 SLJIT_UNUSED_ARG(size);
1002 SLJIT_ASSERT(instruction);
1003 }
1004
1005 static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1006 sljit_si dst, sljit_sw dstw,
1007 sljit_si src, sljit_sw srcw)
1008 {
1009 /* If debug and verbose are disabled, all arguments are unused. */
1010 SLJIT_UNUSED_ARG(compiler);
1011 SLJIT_UNUSED_ARG(op);
1012 SLJIT_UNUSED_ARG(dst);
1013 SLJIT_UNUSED_ARG(dstw);
1014 SLJIT_UNUSED_ARG(src);
1015 SLJIT_UNUSED_ARG(srcw);
1016
1017 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1018 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1019 compiler->skip_checks = 0;
1020 return;
1021 }
1022 #endif
1023
1024 SLJIT_ASSERT(sljit_is_fpu_available());
1025 SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_CMPD && GET_OPCODE(op) <= SLJIT_ABSD);
1026 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1027 FUNCTION_CHECK_OP();
1028 FUNCTION_FCHECK(src, srcw);
1029 FUNCTION_FCHECK(dst, dstw);
1030 #endif
1031 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1032 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1033 fprintf(compiler->verbose, " %s%s%s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d",
1034 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s");
1035 sljit_verbose_fparam(dst, dstw);
1036 fprintf(compiler->verbose, ", ");
1037 sljit_verbose_fparam(src, srcw);
1038 fprintf(compiler->verbose, "\n");
1039 }
1040 #endif
1041 }
1042
1043 static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1044 sljit_si dst, sljit_sw dstw,
1045 sljit_si src1, sljit_sw src1w,
1046 sljit_si src2, sljit_sw src2w)
1047 {
1048 /* If debug and verbose are disabled, all arguments are unused. */
1049 SLJIT_UNUSED_ARG(compiler);
1050 SLJIT_UNUSED_ARG(op);
1051 SLJIT_UNUSED_ARG(dst);
1052 SLJIT_UNUSED_ARG(dstw);
1053 SLJIT_UNUSED_ARG(src1);
1054 SLJIT_UNUSED_ARG(src1w);
1055 SLJIT_UNUSED_ARG(src2);
1056 SLJIT_UNUSED_ARG(src2w);
1057
1058 SLJIT_ASSERT(sljit_is_fpu_available());
1059 SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADDD && GET_OPCODE(op) <= SLJIT_DIVD);
1060 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1061 FUNCTION_CHECK_OP();
1062 FUNCTION_FCHECK(src1, src1w);
1063 FUNCTION_FCHECK(src2, src2w);
1064 FUNCTION_FCHECK(dst, dstw);
1065 #endif
1066 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1067 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1068 fprintf(compiler->verbose, " %s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d");
1069 sljit_verbose_fparam(dst, dstw);
1070 fprintf(compiler->verbose, ", ");
1071 sljit_verbose_fparam(src1, src1w);
1072 fprintf(compiler->verbose, ", ");
1073 sljit_verbose_fparam(src2, src2w);
1074 fprintf(compiler->verbose, "\n");
1075 }
1076 #endif
1077 }
1078
1079 static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler)
1080 {
1081 /* If debug and verbose are disabled, all arguments are unused. */
1082 SLJIT_UNUSED_ARG(compiler);
1083
1084 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1085 if (SLJIT_UNLIKELY(!!compiler->verbose))
1086 fprintf(compiler->verbose, "label:\n");
1087 #endif
1088 }
1089
1090 static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1091 {
1092 /* If debug and verbose are disabled, all arguments are unused. */
1093 SLJIT_UNUSED_ARG(compiler);
1094 SLJIT_UNUSED_ARG(type);
1095
1096 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1097 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1098 compiler->skip_checks = 0;
1099 return;
1100 }
1101 #endif
1102
1103 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
1104 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
1105 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1106 if (SLJIT_UNLIKELY(!!compiler->verbose))
1107 fprintf(compiler->verbose, " jump%s<%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1108 #endif
1109 }
1110
1111 static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1112 sljit_si src1, sljit_sw src1w,
1113 sljit_si src2, sljit_sw src2w)
1114 {
1115 SLJIT_UNUSED_ARG(compiler);
1116 SLJIT_UNUSED_ARG(type);
1117 SLJIT_UNUSED_ARG(src1);
1118 SLJIT_UNUSED_ARG(src1w);
1119 SLJIT_UNUSED_ARG(src2);
1120 SLJIT_UNUSED_ARG(src2w);
1121
1122 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP)));
1123 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL);
1124 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1125 FUNCTION_CHECK_SRC(src1, src1w);
1126 FUNCTION_CHECK_SRC(src2, src2w);
1127 #endif
1128 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1129 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1130 fprintf(compiler->verbose, " %scmp%s<%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1131 sljit_verbose_param(src1, src1w);
1132 fprintf(compiler->verbose, ", ");
1133 sljit_verbose_param(src2, src2w);
1134 fprintf(compiler->verbose, "\n");
1135 }
1136 #endif
1137 }
1138
1139 static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1140 sljit_si src1, sljit_sw src1w,
1141 sljit_si src2, sljit_sw src2w)
1142 {
1143 SLJIT_UNUSED_ARG(compiler);
1144 SLJIT_UNUSED_ARG(type);
1145 SLJIT_UNUSED_ARG(src1);
1146 SLJIT_UNUSED_ARG(src1w);
1147 SLJIT_UNUSED_ARG(src2);
1148 SLJIT_UNUSED_ARG(src2w);
1149
1150 SLJIT_ASSERT(sljit_is_fpu_available());
1151 SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP)));
1152 SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_ORDERED);
1153 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1154 FUNCTION_FCHECK(src1, src1w);
1155 FUNCTION_FCHECK(src2, src2w);
1156 #endif
1157 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1158 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1159 fprintf(compiler->verbose, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
1160 !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
1161 sljit_verbose_fparam(src1, src1w);
1162 fprintf(compiler->verbose, ", ");
1163 sljit_verbose_fparam(src2, src2w);
1164 fprintf(compiler->verbose, "\n");
1165 }
1166 #endif
1167 }
1168
1169 static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1170 {
1171 /* If debug and verbose are disabled, all arguments are unused. */
1172 SLJIT_UNUSED_ARG(compiler);
1173 SLJIT_UNUSED_ARG(type);
1174 SLJIT_UNUSED_ARG(src);
1175 SLJIT_UNUSED_ARG(srcw);
1176
1177 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1178 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1179 compiler->skip_checks = 0;
1180 return;
1181 }
1182 #endif
1183
1184 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
1185 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1186 FUNCTION_CHECK_SRC(src, srcw);
1187 #endif
1188 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1189 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1190 fprintf(compiler->verbose, " ijump<%s> ", jump_names[type]);
1191 sljit_verbose_param(src, srcw);
1192 fprintf(compiler->verbose, "\n");
1193 }
1194 #endif
1195 }
1196
1197 static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1198 sljit_si dst, sljit_sw dstw,
1199 sljit_si src, sljit_sw srcw,
1200 sljit_si type)
1201 {
1202 /* If debug and verbose are disabled, all arguments are unused. */
1203 SLJIT_UNUSED_ARG(compiler);
1204 SLJIT_UNUSED_ARG(op);
1205 SLJIT_UNUSED_ARG(dst);
1206 SLJIT_UNUSED_ARG(dstw);
1207 SLJIT_UNUSED_ARG(src);
1208 SLJIT_UNUSED_ARG(srcw);
1209 SLJIT_UNUSED_ARG(type);
1210
1211 SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP);
1212 SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI
1213 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
1214 SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0);
1215 SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS));
1216 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1217 if (GET_OPCODE(op) < SLJIT_ADD) {
1218 SLJIT_ASSERT(src == SLJIT_UNUSED && srcw == 0);
1219 } else {
1220 SLJIT_ASSERT(src == dst && srcw == dstw);
1221 }
1222 FUNCTION_CHECK_DST(dst, dstw);
1223 #endif
1224 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1225 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1226 fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i",
1227 op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
1228 sljit_verbose_param(dst, dstw);
1229 if (src != SLJIT_UNUSED) {
1230 fprintf(compiler->verbose, ", ");
1231 sljit_verbose_param(src, srcw);
1232 }
1233 fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
1234 }
1235 #endif
1236 }
1237
1238 static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1239 {
1240 SLJIT_UNUSED_ARG(compiler);
1241 SLJIT_UNUSED_ARG(dst);
1242 SLJIT_UNUSED_ARG(dstw);
1243 SLJIT_UNUSED_ARG(offset);
1244
1245 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1246 FUNCTION_CHECK_DST(dst, dstw);
1247 #endif
1248 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1249 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1250 fprintf(compiler->verbose, " local_base ");
1251 sljit_verbose_param(dst, dstw);
1252 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
1253 }
1254 #endif
1255 }
1256
1257 static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
1258 {
1259 /* If debug and verbose are disabled, all arguments are unused. */
1260 SLJIT_UNUSED_ARG(compiler);
1261 SLJIT_UNUSED_ARG(dst);
1262 SLJIT_UNUSED_ARG(dstw);
1263 SLJIT_UNUSED_ARG(init_value);
1264
1265 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1266 FUNCTION_CHECK_DST(dst, dstw);
1267 #endif
1268 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1269 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1270 fprintf(compiler->verbose, " const ");
1271 sljit_verbose_param(dst, dstw);
1272 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
1273 }
1274 #endif
1275 }
1276
1277 static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1278 {
1279 /* Return if don't need to do anything. */
1280 if (op == SLJIT_UNUSED)
1281 return SLJIT_SUCCESS;
1282
1283 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1284 /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
1285 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
1286 return SLJIT_SUCCESS;
1287 #else
1288 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P))
1289 return SLJIT_SUCCESS;
1290 #endif
1291
1292 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1293 compiler->skip_checks = 1;
1294 #endif
1295 return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
1296 }
1297
1298 /* CPU description section */
1299
1300 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
1301 #define SLJIT_CPUINFO_PART1 " 32bit ("
1302 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1303 #define SLJIT_CPUINFO_PART1 " 64bit ("
1304 #else
1305 #error "Internal error: CPU type info missing"
1306 #endif
1307
1308 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1309 #define SLJIT_CPUINFO_PART2 "little endian + "
1310 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
1311 #define SLJIT_CPUINFO_PART2 "big endian + "
1312 #else
1313 #error "Internal error: CPU type info missing"
1314 #endif
1315
1316 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
1317 #define SLJIT_CPUINFO_PART3 "unaligned)"
1318 #else
1319 #define SLJIT_CPUINFO_PART3 "aligned)"
1320 #endif
1321
1322 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
1323
1324 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1325 # include "sljitNativeX86_common.c"
1326 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1327 # include "sljitNativeX86_common.c"
1328 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1329 # include "sljitNativeARM_v5.c"
1330 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
1331 # include "sljitNativeARM_v5.c"
1332 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1333 # include "sljitNativeARM_Thumb2.c"
1334 #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1335 # include "sljitNativePPC_common.c"
1336 #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1337 # include "sljitNativePPC_common.c"
1338 #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1339 # include "sljitNativeMIPS_common.c"
1340 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
1341 # include "sljitNativeSPARC_common.c"
1342 #endif
1343
1344 #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1345
1346 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1347 sljit_si src1, sljit_sw src1w,
1348 sljit_si src2, sljit_sw src2w)
1349 {
1350 /* Default compare for most architectures. */
1351 sljit_si flags, tmp_src, condition;
1352 sljit_sw tmp_srcw;
1353
1354 CHECK_ERROR_PTR();
1355 check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
1356
1357 condition = type & 0xff;
1358 if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
1359 /* Immediate is prefered as second argument by most architectures. */
1360 switch (condition) {
1361 case SLJIT_C_LESS:
1362 condition = SLJIT_C_GREATER;
1363 break;
1364 case SLJIT_C_GREATER_EQUAL:
1365 condition = SLJIT_C_LESS_EQUAL;
1366 break;
1367 case SLJIT_C_GREATER:
1368 condition = SLJIT_C_LESS;
1369 break;
1370 case SLJIT_C_LESS_EQUAL:
1371 condition = SLJIT_C_GREATER_EQUAL;
1372 break;
1373 case SLJIT_C_SIG_LESS:
1374 condition = SLJIT_C_SIG_GREATER;
1375 break;
1376 case SLJIT_C_SIG_GREATER_EQUAL:
1377 condition = SLJIT_C_SIG_LESS_EQUAL;
1378 break;
1379 case SLJIT_C_SIG_GREATER:
1380 condition = SLJIT_C_SIG_LESS;
1381 break;
1382 case SLJIT_C_SIG_LESS_EQUAL:
1383 condition = SLJIT_C_SIG_GREATER_EQUAL;
1384 break;
1385 }
1386 type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP));
1387 tmp_src = src1;
1388 src1 = src2;
1389 src2 = tmp_src;
1390 tmp_srcw = src1w;
1391 src1w = src2w;
1392 src2w = tmp_srcw;
1393 }
1394
1395 if (condition <= SLJIT_C_NOT_ZERO)
1396 flags = SLJIT_SET_E;
1397 else if (condition <= SLJIT_C_LESS_EQUAL)
1398 flags = SLJIT_SET_U;
1399 else
1400 flags = SLJIT_SET_S;
1401
1402 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1403 compiler->skip_checks = 1;
1404 #endif
1405 PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP),
1406 SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
1407 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1408 compiler->skip_checks = 1;
1409 #endif
1410 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
1411 }
1412
1413 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1414 sljit_si src1, sljit_sw src1w,
1415 sljit_si src2, sljit_sw src2w)
1416 {
1417 sljit_si flags, condition;
1418
1419 check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
1420
1421 condition = type & 0xff;
1422 flags = (condition <= SLJIT_C_FLOAT_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S;
1423 if (type & SLJIT_SINGLE_OP)
1424 flags |= SLJIT_SINGLE_OP;
1425
1426 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1427 compiler->skip_checks = 1;
1428 #endif
1429 sljit_emit_fop1(compiler, SLJIT_CMPD | flags, src1, src1w, src2, src2w);
1430
1431 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1432 compiler->skip_checks = 1;
1433 #endif
1434 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
1435 }
1436
1437 #endif
1438
1439 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1440
1441 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1442 {
1443 CHECK_ERROR();
1444 check_sljit_get_local_base(compiler, dst, dstw, offset);
1445
1446 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
1447 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1448 compiler->skip_checks = 1;
1449 #endif
1450 if (offset != 0)
1451 return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
1452 return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_LOCALS_REG, 0);
1453 }
1454
1455 #endif
1456
1457 #else /* SLJIT_CONFIG_UNSUPPORTED */
1458
1459 /* Empty function bodies for those machines, which are not (yet) supported. */
1460
1461 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
1462 {
1463 return "unsupported";
1464 }
1465
1466 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
1467 {
1468 SLJIT_ASSERT_STOP();
1469 return NULL;
1470 }
1471
1472 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
1473 {
1474 SLJIT_UNUSED_ARG(compiler);
1475 SLJIT_ASSERT_STOP();
1476 }
1477
1478 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size)
1479 {
1480 SLJIT_UNUSED_ARG(compiler);
1481 SLJIT_UNUSED_ARG(size);
1482 SLJIT_ASSERT_STOP();
1483 return NULL;
1484 }
1485
1486 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1487 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
1488 {
1489 SLJIT_UNUSED_ARG(compiler);
1490 SLJIT_UNUSED_ARG(verbose);
1491 SLJIT_ASSERT_STOP();
1492 }
1493 #endif
1494
1495 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
1496 {
1497 SLJIT_UNUSED_ARG(compiler);
1498 SLJIT_ASSERT_STOP();
1499 return NULL;
1500 }
1501
1502 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
1503 {
1504 SLJIT_UNUSED_ARG(code);
1505 SLJIT_ASSERT_STOP();
1506 }
1507
1508 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)
1509 {
1510 SLJIT_UNUSED_ARG(compiler);
1511 SLJIT_UNUSED_ARG(args);
1512 SLJIT_UNUSED_ARG(scratches);
1513 SLJIT_UNUSED_ARG(saveds);
1514 SLJIT_UNUSED_ARG(local_size);
1515 SLJIT_ASSERT_STOP();
1516 return SLJIT_ERR_UNSUPPORTED;
1517 }
1518
1519 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)
1520 {
1521 SLJIT_UNUSED_ARG(compiler);
1522 SLJIT_UNUSED_ARG(args);
1523 SLJIT_UNUSED_ARG(scratches);
1524 SLJIT_UNUSED_ARG(saveds);
1525 SLJIT_UNUSED_ARG(local_size);
1526 SLJIT_ASSERT_STOP();
1527 }
1528
1529 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1530 {
1531 SLJIT_UNUSED_ARG(compiler);
1532 SLJIT_UNUSED_ARG(op);
1533 SLJIT_UNUSED_ARG(src);
1534 SLJIT_UNUSED_ARG(srcw);
1535 SLJIT_ASSERT_STOP();
1536 return SLJIT_ERR_UNSUPPORTED;
1537 }
1538
1539 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1540 {
1541 SLJIT_UNUSED_ARG(compiler);
1542 SLJIT_UNUSED_ARG(dst);
1543 SLJIT_UNUSED_ARG(dstw);
1544 SLJIT_ASSERT_STOP();
1545 return SLJIT_ERR_UNSUPPORTED;
1546 }
1547
1548 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1549 {
1550 SLJIT_UNUSED_ARG(compiler);
1551 SLJIT_UNUSED_ARG(src);
1552 SLJIT_UNUSED_ARG(srcw);
1553 SLJIT_ASSERT_STOP();
1554 return SLJIT_ERR_UNSUPPORTED;
1555 }
1556
1557 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1558 {
1559 SLJIT_UNUSED_ARG(compiler);
1560 SLJIT_UNUSED_ARG(op);
1561 SLJIT_ASSERT_STOP();
1562 return SLJIT_ERR_UNSUPPORTED;
1563 }
1564
1565 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1566 sljit_si dst, sljit_sw dstw,
1567 sljit_si src, sljit_sw srcw)
1568 {
1569 SLJIT_UNUSED_ARG(compiler);
1570 SLJIT_UNUSED_ARG(op);
1571 SLJIT_UNUSED_ARG(dst);
1572 SLJIT_UNUSED_ARG(dstw);
1573 SLJIT_UNUSED_ARG(src);
1574 SLJIT_UNUSED_ARG(srcw);
1575 SLJIT_ASSERT_STOP();
1576 return SLJIT_ERR_UNSUPPORTED;
1577 }
1578
1579 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1580 sljit_si dst, sljit_sw dstw,
1581 sljit_si src1, sljit_sw src1w,
1582 sljit_si src2, sljit_sw src2w)
1583 {
1584 SLJIT_UNUSED_ARG(compiler);
1585 SLJIT_UNUSED_ARG(op);
1586 SLJIT_UNUSED_ARG(dst);
1587 SLJIT_UNUSED_ARG(dstw);
1588 SLJIT_UNUSED_ARG(src1);
1589 SLJIT_UNUSED_ARG(src1w);
1590 SLJIT_UNUSED_ARG(src2);
1591 SLJIT_UNUSED_ARG(src2w);
1592 SLJIT_ASSERT_STOP();
1593 return SLJIT_ERR_UNSUPPORTED;
1594 }
1595
1596 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1597 {
1598 SLJIT_ASSERT_STOP();
1599 return reg;
1600 }
1601
1602 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1603 void *instruction, sljit_si size)
1604 {
1605 SLJIT_UNUSED_ARG(compiler);
1606 SLJIT_UNUSED_ARG(instruction);
1607 SLJIT_UNUSED_ARG(size);
1608 SLJIT_ASSERT_STOP();
1609 return SLJIT_ERR_UNSUPPORTED;
1610 }
1611
1612 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
1613 {
1614 SLJIT_ASSERT_STOP();
1615 return 0;
1616 }
1617
1618 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1619 sljit_si dst, sljit_sw dstw,
1620 sljit_si src, sljit_sw srcw)
1621 {
1622 SLJIT_UNUSED_ARG(compiler);
1623 SLJIT_UNUSED_ARG(op);
1624 SLJIT_UNUSED_ARG(dst);
1625 SLJIT_UNUSED_ARG(dstw);
1626 SLJIT_UNUSED_ARG(src);
1627 SLJIT_UNUSED_ARG(srcw);
1628 SLJIT_ASSERT_STOP();
1629 return SLJIT_ERR_UNSUPPORTED;
1630 }
1631
1632 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1633 sljit_si dst, sljit_sw dstw,
1634 sljit_si src1, sljit_sw src1w,
1635 sljit_si src2, sljit_sw src2w)
1636 {
1637 SLJIT_UNUSED_ARG(compiler);
1638 SLJIT_UNUSED_ARG(op);
1639 SLJIT_UNUSED_ARG(dst);
1640 SLJIT_UNUSED_ARG(dstw);
1641 SLJIT_UNUSED_ARG(src1);
1642 SLJIT_UNUSED_ARG(src1w);
1643 SLJIT_UNUSED_ARG(src2);
1644 SLJIT_UNUSED_ARG(src2w);
1645 SLJIT_ASSERT_STOP();
1646 return SLJIT_ERR_UNSUPPORTED;
1647 }
1648
1649 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1650 {
1651 SLJIT_UNUSED_ARG(compiler);
1652 SLJIT_ASSERT_STOP();
1653 return NULL;
1654 }
1655
1656 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1657 {
1658 SLJIT_UNUSED_ARG(compiler);
1659 SLJIT_UNUSED_ARG(type);
1660 SLJIT_ASSERT_STOP();
1661 return NULL;
1662 }
1663
1664 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
1665 sljit_si src1, sljit_sw src1w,
1666 sljit_si src2, sljit_sw src2w)
1667 {
1668 SLJIT_UNUSED_ARG(compiler);
1669 SLJIT_UNUSED_ARG(type);
1670 SLJIT_UNUSED_ARG(src1);
1671 SLJIT_UNUSED_ARG(src1w);
1672 SLJIT_UNUSED_ARG(src2);
1673 SLJIT_UNUSED_ARG(src2w);
1674 SLJIT_ASSERT_STOP();
1675 return NULL;
1676 }
1677
1678 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
1679 sljit_si src1, sljit_sw src1w,
1680 sljit_si src2, sljit_sw src2w)
1681 {
1682 SLJIT_UNUSED_ARG(compiler);
1683 SLJIT_UNUSED_ARG(type);
1684 SLJIT_UNUSED_ARG(src1);
1685 SLJIT_UNUSED_ARG(src1w);
1686 SLJIT_UNUSED_ARG(src2);
1687 SLJIT_UNUSED_ARG(src2w);
1688 SLJIT_ASSERT_STOP();
1689 return NULL;
1690 }
1691
1692 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
1693 {
1694 SLJIT_UNUSED_ARG(jump);
1695 SLJIT_UNUSED_ARG(label);
1696 SLJIT_ASSERT_STOP();
1697 }
1698
1699 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
1700 {
1701 SLJIT_UNUSED_ARG(jump);
1702 SLJIT_UNUSED_ARG(target);
1703 SLJIT_ASSERT_STOP();
1704 }
1705
1706 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1707 {
1708 SLJIT_UNUSED_ARG(compiler);
1709 SLJIT_UNUSED_ARG(type);
1710 SLJIT_UNUSED_ARG(src);
1711 SLJIT_UNUSED_ARG(srcw);
1712 SLJIT_ASSERT_STOP();
1713 return SLJIT_ERR_UNSUPPORTED;
1714 }
1715
1716 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1717 sljit_si dst, sljit_sw dstw,
1718 sljit_si src, sljit_sw srcw,
1719 sljit_si type)
1720 {
1721 SLJIT_UNUSED_ARG(compiler);
1722 SLJIT_UNUSED_ARG(op);
1723 SLJIT_UNUSED_ARG(dst);
1724 SLJIT_UNUSED_ARG(dstw);
1725 SLJIT_UNUSED_ARG(src);
1726 SLJIT_UNUSED_ARG(srcw);
1727 SLJIT_UNUSED_ARG(type);
1728 SLJIT_ASSERT_STOP();
1729 return SLJIT_ERR_UNSUPPORTED;
1730 }
1731
1732 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
1733 {
1734 SLJIT_UNUSED_ARG(compiler);
1735 SLJIT_UNUSED_ARG(dst);
1736 SLJIT_UNUSED_ARG(dstw);
1737 SLJIT_UNUSED_ARG(offset);
1738 SLJIT_ASSERT_STOP();
1739 return SLJIT_ERR_UNSUPPORTED;
1740 }
1741
1742 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval)
1743 {
1744 SLJIT_UNUSED_ARG(compiler);
1745 SLJIT_UNUSED_ARG(dst);
1746 SLJIT_UNUSED_ARG(dstw);
1747 SLJIT_UNUSED_ARG(initval);
1748 SLJIT_ASSERT_STOP();
1749 return NULL;
1750 }
1751
1752 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
1753 {
1754 SLJIT_UNUSED_ARG(addr);
1755 SLJIT_UNUSED_ARG(new_addr);
1756 SLJIT_ASSERT_STOP();
1757 }
1758
1759 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
1760 {
1761 SLJIT_UNUSED_ARG(addr);
1762 SLJIT_UNUSED_ARG(new_constant);
1763 SLJIT_ASSERT_STOP();
1764 }
1765
1766 #endif

  ViewVC Help
Powered by ViewVC 1.1.5