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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 777 - (hide annotations) (download)
Thu Dec 1 15:15:31 2011 UTC (2 years, 10 months ago) by zherczeg
File MIME type: text/plain
File size: 74939 byte(s)
Retrieve executable code size support for the JIT compiler and fixing some warnings.
1 ph10 662 /*
2     * Stack-less Just-In-Time compiler
3     *
4     * Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5     *
6     * Redistribution and use in source and binary forms, with or without modification, are
7     * permitted provided that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright notice, this list of
10     * conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13     * of conditions and the following disclaimer in the documentation and/or other materials
14     * provided with the distribution.
15     *
16     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19     * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21     * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22     * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24     * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25     */
26    
27 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
28 ph10 662 {
29     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
30     return "x86-32";
31     #else
32     return "x86-64";
33     #endif
34     }
35    
36     /*
37     32b register indexes:
38     0 - EAX
39     1 - ECX
40     2 - EDX
41     3 - EBX
42     4 - none
43     5 - EBP
44     6 - ESI
45     7 - EDI
46     */
47    
48     /*
49     64b register indexes:
50     0 - RAX
51     1 - RCX
52     2 - RDX
53     3 - RBX
54     4 - none
55     5 - RBP
56     6 - RSI
57     7 - RDI
58     8 - R8 - From now on REX prefix is required
59     9 - R9
60     10 - R10
61     11 - R11
62     12 - R12
63     13 - R13
64     14 - R14
65     15 - R15
66     */
67    
68     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
69    
70     /* Last register + 1. */
71     #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
72    
73     static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
74     0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
75     };
76    
77     #define CHECK_EXTRA_REGS(p, w, do) \
78     if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
79     w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \
80     p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
81     do; \
82     } \
83     else if (p >= SLJIT_GENERAL_EREG1 && p <= SLJIT_GENERAL_EREG2) { \
84     w = compiler->generals_start + (p - SLJIT_GENERAL_EREG1) * sizeof(sljit_w); \
85     p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
86     do; \
87     }
88    
89     #else /* SLJIT_CONFIG_X86_32 */
90    
91     /* Last register + 1. */
92     #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
93     #define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
94     #define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
95    
96     /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
97     Note: avoid to use r12 and r13 for memory addessing
98     therefore r12 is better for GENERAL_EREG than GENERAL_REG. */
99     #ifndef _WIN64
100     /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
101     static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
102     0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
103     };
104     /* low-map. reg_map & 0x7. */
105     static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
106     0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
107     };
108     #else
109     /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
110     static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
111     0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 12, 15, 10, 8, 9
112     };
113     /* low-map. reg_map & 0x7. */
114     static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
115     0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 4, 7, 2, 0, 1
116     };
117     #endif
118    
119     #define REX_W 0x48
120     #define REX_R 0x44
121     #define REX_X 0x42
122     #define REX_B 0x41
123     #define REX 0x40
124    
125     typedef unsigned int sljit_uhw;
126     typedef int sljit_hw;
127    
128     #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
129     #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
130    
131     #define CHECK_EXTRA_REGS(p, w, do)
132    
133     #endif /* SLJIT_CONFIG_X86_32 */
134    
135     #if (defined SLJIT_SSE2 && SLJIT_SSE2)
136     #define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
137     #endif
138    
139     /* Size flags for emit_x86_instruction: */
140     #define EX86_BIN_INS 0x0010
141     #define EX86_SHIFT_INS 0x0020
142     #define EX86_REX 0x0040
143     #define EX86_NO_REXW 0x0080
144     #define EX86_BYTE_ARG 0x0100
145     #define EX86_HALF_ARG 0x0200
146     #define EX86_PREF_66 0x0400
147    
148     #if (defined SLJIT_SSE2 && SLJIT_SSE2)
149     #define EX86_PREF_F2 0x0800
150     #define EX86_SSE2 0x1000
151     #endif
152    
153     #define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
154     #define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
155    
156     #define PUSH_REG(r) (*buf++ = (0x50 + (r)))
157     #define POP_REG(r) (*buf++ = (0x58 + (r)))
158     #define RET() (*buf++ = (0xc3))
159     #define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0)
160     /* r32, r/m32 */
161     #define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
162    
163     static sljit_ub get_jump_code(int type)
164     {
165     switch (type) {
166     case SLJIT_C_EQUAL:
167     case SLJIT_C_FLOAT_EQUAL:
168     return 0x84;
169    
170     case SLJIT_C_NOT_EQUAL:
171     case SLJIT_C_FLOAT_NOT_EQUAL:
172     return 0x85;
173    
174     case SLJIT_C_LESS:
175     case SLJIT_C_FLOAT_LESS:
176     return 0x82;
177    
178     case SLJIT_C_GREATER_EQUAL:
179     case SLJIT_C_FLOAT_GREATER_EQUAL:
180     return 0x83;
181    
182     case SLJIT_C_GREATER:
183     case SLJIT_C_FLOAT_GREATER:
184     return 0x87;
185    
186     case SLJIT_C_LESS_EQUAL:
187     case SLJIT_C_FLOAT_LESS_EQUAL:
188     return 0x86;
189    
190     case SLJIT_C_SIG_LESS:
191     return 0x8c;
192    
193     case SLJIT_C_SIG_GREATER_EQUAL:
194     return 0x8d;
195    
196     case SLJIT_C_SIG_GREATER:
197     return 0x8f;
198    
199     case SLJIT_C_SIG_LESS_EQUAL:
200     return 0x8e;
201    
202     case SLJIT_C_OVERFLOW:
203     case SLJIT_C_MUL_OVERFLOW:
204     return 0x80;
205    
206     case SLJIT_C_NOT_OVERFLOW:
207     case SLJIT_C_MUL_NOT_OVERFLOW:
208     return 0x81;
209    
210     case SLJIT_C_FLOAT_NAN:
211     return 0x8a;
212    
213     case SLJIT_C_FLOAT_NOT_NAN:
214     return 0x8b;
215     }
216     return 0;
217     }
218    
219     static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
220    
221     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
222     static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type);
223     #endif
224    
225     static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
226     {
227     int short_jump;
228     sljit_uw label_addr;
229    
230     if (jump->flags & JUMP_LABEL)
231     label_addr = (sljit_uw)(code + jump->u.label->size);
232     else
233     label_addr = jump->u.target;
234     short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127;
235    
236     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
237     if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll)
238     return generate_far_jump_code(jump, code_ptr, type);
239     #endif
240    
241     if (type == SLJIT_JUMP) {
242     if (short_jump)
243     *code_ptr++ = 0xeb;
244     else
245     *code_ptr++ = 0xe9;
246     jump->addr++;
247     }
248 zherczeg 722 else if (type >= SLJIT_FAST_CALL) {
249 ph10 662 short_jump = 0;
250     *code_ptr++ = 0xe8;
251     jump->addr++;
252     }
253     else if (short_jump) {
254     *code_ptr++ = get_jump_code(type) - 0x10;
255     jump->addr++;
256     }
257     else {
258     *code_ptr++ = 0x0f;
259     *code_ptr++ = get_jump_code(type);
260     jump->addr += 2;
261     }
262    
263     if (short_jump) {
264     jump->flags |= PATCH_MB;
265     code_ptr += sizeof(sljit_b);
266     } else {
267     jump->flags |= PATCH_MW;
268     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
269     code_ptr += sizeof(sljit_w);
270     #else
271     code_ptr += sizeof(sljit_hw);
272     #endif
273     }
274    
275     return code_ptr;
276     }
277    
278 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
279 ph10 662 {
280     struct sljit_memory_fragment *buf;
281     sljit_ub *code;
282     sljit_ub *code_ptr;
283     sljit_ub *buf_ptr;
284     sljit_ub *buf_end;
285     sljit_ub len;
286    
287     struct sljit_label *label;
288     struct sljit_jump *jump;
289     struct sljit_const *const_;
290    
291     CHECK_ERROR_PTR();
292     check_sljit_generate_code(compiler);
293     reverse_buf(compiler);
294    
295     /* Second code generation pass. */
296     code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
297     PTR_FAIL_WITH_EXEC_IF(code);
298     buf = compiler->buf;
299    
300     code_ptr = code;
301     label = compiler->labels;
302     jump = compiler->jumps;
303     const_ = compiler->consts;
304     do {
305     buf_ptr = buf->memory;
306     buf_end = buf_ptr + buf->used_size;
307     do {
308     len = *buf_ptr++;
309     if (len > 0) {
310     /* The code is already generated. */
311     SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
312     code_ptr += len;
313     buf_ptr += len;
314     }
315     else {
316     if (*buf_ptr >= 4) {
317     jump->addr = (sljit_uw)code_ptr;
318     if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
319     code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
320     else
321     code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
322     jump = jump->next;
323     }
324     else if (*buf_ptr == 0) {
325     label->addr = (sljit_uw)code_ptr;
326     label->size = code_ptr - code;
327     label = label->next;
328     }
329     else if (*buf_ptr == 1) {
330     const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
331     const_ = const_->next;
332     }
333     else {
334     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
335     *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
336     buf_ptr++;
337     *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w));
338     code_ptr += sizeof(sljit_w);
339     buf_ptr += sizeof(sljit_w) - 1;
340     #else
341     code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
342     buf_ptr += sizeof(sljit_w);
343     #endif
344     }
345     buf_ptr++;
346     }
347     } while (buf_ptr < buf_end);
348     SLJIT_ASSERT(buf_ptr == buf_end);
349     buf = buf->next;
350     } while (buf);
351    
352     SLJIT_ASSERT(!label);
353     SLJIT_ASSERT(!jump);
354     SLJIT_ASSERT(!const_);
355    
356     jump = compiler->jumps;
357     while (jump) {
358     if (jump->flags & PATCH_MB) {
359     SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);
360 zherczeg 777 *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
361 ph10 662 } else if (jump->flags & PATCH_MW) {
362     if (jump->flags & JUMP_LABEL) {
363     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
364 zherczeg 777 *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
365 ph10 662 #else
366     SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
367 zherczeg 777 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
368 ph10 662 #endif
369     }
370     else {
371     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
372 zherczeg 777 *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
373 ph10 662 #else
374     SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
375 zherczeg 777 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
376 ph10 662 #endif
377     }
378     }
379     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
380     else if (jump->flags & PATCH_MD)
381     *(sljit_w*)jump->addr = jump->u.label->addr;
382     #endif
383    
384     jump = jump->next;
385     }
386    
387     /* Maybe we waste some space because of short jumps. */
388     SLJIT_ASSERT(code_ptr <= code + compiler->size);
389     compiler->error = SLJIT_ERR_COMPILED;
390 zherczeg 777 compiler->executable_size = compiler->size;
391 ph10 662 return (void*)code;
392     }
393    
394     /* --------------------------------------------------------------------- */
395     /* Operators */
396     /* --------------------------------------------------------------------- */
397    
398     static int emit_cum_binary(struct sljit_compiler *compiler,
399     sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
400     int dst, sljit_w dstw,
401     int src1, sljit_w src1w,
402     int src2, sljit_w src2w);
403    
404     static int emit_non_cum_binary(struct sljit_compiler *compiler,
405     sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
406     int dst, sljit_w dstw,
407     int src1, sljit_w src1w,
408     int src2, sljit_w src2w);
409    
410     static int emit_mov(struct sljit_compiler *compiler,
411     int dst, sljit_w dstw,
412     int src, sljit_w srcw);
413    
414     static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
415     {
416     sljit_ub *buf;
417    
418     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
419     buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
420     FAIL_IF(!buf);
421     INC_SIZE(5);
422     *buf++ = 0x9c; /* pushfd */
423     #else
424     buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
425     FAIL_IF(!buf);
426     INC_SIZE(6);
427     *buf++ = 0x9c; /* pushfq */
428     *buf++ = 0x48;
429     #endif
430     *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
431     *buf++ = 0x64;
432     *buf++ = 0x24;
433     *buf++ = sizeof(sljit_w);
434     compiler->flags_saved = 1;
435     return SLJIT_SUCCESS;
436     }
437    
438     static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
439     {
440     sljit_ub *buf;
441    
442     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
443     buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
444     FAIL_IF(!buf);
445     INC_SIZE(5);
446     #else
447     buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
448     FAIL_IF(!buf);
449     INC_SIZE(6);
450     *buf++ = 0x48;
451     #endif
452     *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
453     *buf++ = 0x64;
454     *buf++ = 0x24;
455     *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
456     *buf++ = 0x9d; /* popfd / popfq */
457     compiler->flags_saved = keep_flags;
458     return SLJIT_SUCCESS;
459     }
460    
461     #ifdef _WIN32
462     #include <malloc.h>
463    
464     static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
465     {
466     /* Workaround for calling _chkstk. */
467     alloca(local_size);
468     }
469     #endif
470    
471     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
472     #include "sljitNativeX86_32.c"
473     #else
474     #include "sljitNativeX86_64.c"
475     #endif
476    
477 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
478 ph10 662 {
479     sljit_ub *buf;
480    
481     CHECK_ERROR();
482     check_sljit_emit_op0(compiler, op);
483    
484     op = GET_OPCODE(op);
485     switch (op) {
486     case SLJIT_BREAKPOINT:
487     buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
488     FAIL_IF(!buf);
489     INC_SIZE(1);
490     *buf = 0xcc;
491     break;
492     case SLJIT_NOP:
493     buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
494     FAIL_IF(!buf);
495     INC_SIZE(1);
496     *buf = 0x90;
497     break;
498     }
499    
500     return SLJIT_SUCCESS;
501     }
502    
503     static int emit_mov(struct sljit_compiler *compiler,
504     int dst, sljit_w dstw,
505     int src, sljit_w srcw)
506     {
507     sljit_ub* code;
508    
509     if (dst == SLJIT_UNUSED) {
510     /* No destination, doesn't need to setup flags. */
511     if (src & SLJIT_MEM) {
512     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
513     FAIL_IF(!code);
514     *code = 0x8b;
515     }
516     return SLJIT_SUCCESS;
517     }
518     if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
519     code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
520     FAIL_IF(!code);
521     *code = 0x89;
522     return SLJIT_SUCCESS;
523     }
524     if (src & SLJIT_IMM) {
525     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
526     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
527     return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
528     #else
529     if (!compiler->mode32) {
530     if (NOT_HALFWORD(srcw))
531     return emit_load_imm64(compiler, dst, srcw);
532     }
533     else
534     return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
535     #endif
536     }
537     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
538     if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
539     FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
540     code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
541     FAIL_IF(!code);
542     *code = 0x89;
543     return SLJIT_SUCCESS;
544     }
545     #endif
546     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
547     FAIL_IF(!code);
548     *code = 0xc7;
549     return SLJIT_SUCCESS;
550     }
551     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
552     code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
553     FAIL_IF(!code);
554     *code = 0x8b;
555     return SLJIT_SUCCESS;
556     }
557    
558     /* Memory to memory move. Requires two instruction. */
559     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
560     FAIL_IF(!code);
561     *code = 0x8b;
562     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
563     FAIL_IF(!code);
564     *code = 0x89;
565     return SLJIT_SUCCESS;
566     }
567    
568     #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
569     FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
570    
571     #define ENCODE_PREFIX(prefix) \
572     do { \
573     code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
574     FAIL_IF(!code); \
575     INC_CSIZE(1); \
576     *code = (prefix); \
577     } while (0)
578    
579     static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
580     int dst, sljit_w dstw,
581     int src, sljit_w srcw)
582     {
583     sljit_ub* code;
584     int dst_r;
585     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
586     int work_r;
587     #endif
588    
589     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
590     compiler->mode32 = 0;
591     #endif
592    
593     if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
594     return SLJIT_SUCCESS; /* Empty instruction. */
595    
596     if (src & SLJIT_IMM) {
597     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
598     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
599     return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
600     #else
601     return emit_load_imm64(compiler, dst, srcw);
602     #endif
603     }
604     code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
605     FAIL_IF(!code);
606     *code = 0xc6;
607     return SLJIT_SUCCESS;
608     }
609    
610     dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
611    
612     if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
613     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
614     if (reg_map[src] >= 4) {
615     SLJIT_ASSERT(dst_r == TMP_REGISTER);
616     EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
617     } else
618     dst_r = src;
619     #else
620     dst_r = src;
621     #endif
622     }
623     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
624     else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) {
625     /* src, dst are registers. */
626     SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER);
627     if (reg_map[dst] < 4) {
628     if (dst != src)
629     EMIT_MOV(compiler, dst, 0, src, 0);
630     code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
631     FAIL_IF(!code);
632     *code++ = 0x0f;
633     *code = sign ? 0xbe : 0xb6;
634     }
635     else {
636     if (dst != src)
637     EMIT_MOV(compiler, dst, 0, src, 0);
638     if (sign) {
639     /* shl reg, 24 */
640     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
641     FAIL_IF(!code);
642     *code |= 0x4 << 3;
643     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
644     FAIL_IF(!code);
645     /* shr/sar reg, 24 */
646     *code |= 0x7 << 3;
647     }
648     else {
649     /* and dst, 0xff */
650     code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
651     FAIL_IF(!code);
652     *(code + 1) |= 0x4 << 3;
653     }
654     }
655     return SLJIT_SUCCESS;
656     }
657     #endif
658     else {
659     /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
660     code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
661     FAIL_IF(!code);
662     *code++ = 0x0f;
663     *code = sign ? 0xbe : 0xb6;
664     }
665    
666     if (dst & SLJIT_MEM) {
667     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
668     if (dst_r == TMP_REGISTER) {
669     /* Find a non-used register, whose reg_map[src] < 4. */
670     if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) {
671     if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4))
672     work_r = SLJIT_TEMPORARY_REG3;
673     else
674     work_r = SLJIT_TEMPORARY_REG2;
675     }
676     else {
677     if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
678     work_r = SLJIT_TEMPORARY_REG1;
679     else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2)
680     work_r = SLJIT_TEMPORARY_REG3;
681     else
682     work_r = SLJIT_TEMPORARY_REG2;
683     }
684    
685     if (work_r == SLJIT_TEMPORARY_REG1) {
686     ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
687     }
688     else {
689     code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
690     FAIL_IF(!code);
691     *code = 0x87;
692     }
693    
694     code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
695     FAIL_IF(!code);
696     *code = 0x88;
697    
698     if (work_r == SLJIT_TEMPORARY_REG1) {
699     ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
700     }
701     else {
702     code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
703     FAIL_IF(!code);
704     *code = 0x87;
705     }
706     }
707     else {
708     code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
709     FAIL_IF(!code);
710     *code = 0x88;
711     }
712     #else
713     code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
714     FAIL_IF(!code);
715     *code = 0x88;
716     #endif
717     }
718    
719     return SLJIT_SUCCESS;
720     }
721    
722     static int emit_mov_half(struct sljit_compiler *compiler, int sign,
723     int dst, sljit_w dstw,
724     int src, sljit_w srcw)
725     {
726     sljit_ub* code;
727     int dst_r;
728    
729     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
730     compiler->mode32 = 0;
731     #endif
732    
733     if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
734     return SLJIT_SUCCESS; /* Empty instruction. */
735    
736     if (src & SLJIT_IMM) {
737     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
738     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
739     return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
740     #else
741     return emit_load_imm64(compiler, dst, srcw);
742     #endif
743     }
744     code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
745     FAIL_IF(!code);
746     *code = 0xc7;
747     return SLJIT_SUCCESS;
748     }
749    
750     dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
751    
752     if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
753     dst_r = src;
754     else {
755     code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
756     FAIL_IF(!code);
757     *code++ = 0x0f;
758     *code = sign ? 0xbf : 0xb7;
759     }
760    
761     if (dst & SLJIT_MEM) {
762     code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
763     FAIL_IF(!code);
764     *code = 0x89;
765     }
766    
767     return SLJIT_SUCCESS;
768     }
769    
770     static int emit_unary(struct sljit_compiler *compiler, int un_index,
771     int dst, sljit_w dstw,
772     int src, sljit_w srcw)
773     {
774     sljit_ub* code;
775    
776     if (dst == SLJIT_UNUSED) {
777     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
778     code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
779     FAIL_IF(!code);
780     *code++ = 0xf7;
781     *code |= (un_index) << 3;
782     return SLJIT_SUCCESS;
783     }
784     if (dst == src && dstw == srcw) {
785     /* Same input and output */
786     code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
787     FAIL_IF(!code);
788     *code++ = 0xf7;
789     *code |= (un_index) << 3;
790     return SLJIT_SUCCESS;
791     }
792     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
793     EMIT_MOV(compiler, dst, 0, src, srcw);
794     code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
795     FAIL_IF(!code);
796     *code++ = 0xf7;
797     *code |= (un_index) << 3;
798     return SLJIT_SUCCESS;
799     }
800     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
801     code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
802     FAIL_IF(!code);
803     *code++ = 0xf7;
804     *code |= (un_index) << 3;
805     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
806     return SLJIT_SUCCESS;
807     }
808    
809     static int emit_not_with_flags(struct sljit_compiler *compiler,
810     int dst, sljit_w dstw,
811     int src, sljit_w srcw)
812     {
813     sljit_ub* code;
814    
815     if (dst == SLJIT_UNUSED) {
816     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
817     code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
818     FAIL_IF(!code);
819     *code++ = 0xf7;
820     *code |= 0x2 << 3;
821     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
822     FAIL_IF(!code);
823     *code = 0x0b;
824     return SLJIT_SUCCESS;
825     }
826     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
827     EMIT_MOV(compiler, dst, 0, src, srcw);
828     code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
829     FAIL_IF(!code);
830     *code++ = 0xf7;
831     *code |= 0x2 << 3;
832     code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
833     FAIL_IF(!code);
834     *code = 0x0b;
835     return SLJIT_SUCCESS;
836     }
837     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
838     code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
839     FAIL_IF(!code);
840     *code++ = 0xf7;
841     *code |= 0x2 << 3;
842     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
843     FAIL_IF(!code);
844     *code = 0x0b;
845     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
846     return SLJIT_SUCCESS;
847     }
848    
849     static int emit_clz(struct sljit_compiler *compiler, int op,
850     int dst, sljit_w dstw,
851     int src, sljit_w srcw)
852     {
853     sljit_ub* code;
854     int dst_r;
855    
856     if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
857     /* Just set the zero flag. */
858     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
859     code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
860     FAIL_IF(!code);
861     *code++ = 0xf7;
862     *code |= 0x2 << 3;
863     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
864     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0);
865     #else
866     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
867     #endif
868     FAIL_IF(!code);
869     *code |= 0x5 << 3;
870     return SLJIT_SUCCESS;
871     }
872    
873     if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
874     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
875     src = TMP_REGISTER;
876     srcw = 0;
877     }
878    
879     code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
880     FAIL_IF(!code);
881     *code++ = 0x0f;
882     *code = 0xbd;
883    
884     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
885     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
886     dst_r = dst;
887     else {
888     /* Find an unused temporary register. */
889     if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
890     dst_r = SLJIT_TEMPORARY_REG1;
891     else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4))
892     dst_r = SLJIT_TEMPORARY_REG2;
893     else
894     dst_r = SLJIT_TEMPORARY_REG3;
895     EMIT_MOV(compiler, dst, dstw, dst_r, 0);
896     }
897     EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
898     #else
899     dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2;
900     compiler->mode32 = 0;
901     EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31);
902     compiler->mode32 = op & SLJIT_INT_OP;
903     #endif
904    
905     code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
906     FAIL_IF(!code);
907     *code++ = 0x0f;
908     *code = 0x45;
909    
910     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
911     code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
912     #else
913     code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
914     #endif
915     FAIL_IF(!code);
916     *(code + 1) |= 0x6 << 3;
917    
918     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
919     if (dst & SLJIT_MEM) {
920     code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
921     FAIL_IF(!code);
922     *code = 0x87;
923     }
924     #else
925     if (dst & SLJIT_MEM)
926     EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
927     #endif
928     return SLJIT_SUCCESS;
929     }
930    
931 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
932 ph10 662 int dst, sljit_w dstw,
933     int src, sljit_w srcw)
934     {
935     sljit_ub* code;
936     int update = 0;
937     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
938     int dst_is_ereg = 0;
939     int src_is_ereg = 0;
940     #else
941     #define src_is_ereg 0
942     #endif
943    
944     CHECK_ERROR();
945     check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
946    
947     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
948     compiler->mode32 = op & SLJIT_INT_OP;
949     #endif
950     CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
951     CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
952    
953     if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
954     op = GET_OPCODE(op);
955     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
956     compiler->mode32 = 0;
957     #endif
958    
959 zherczeg 740 SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
960 ph10 662 if (op >= SLJIT_MOVU) {
961     update = 1;
962     op -= 7;
963     }
964    
965     if (src & SLJIT_IMM) {
966     switch (op) {
967     case SLJIT_MOV_UB:
968     srcw = (unsigned char)srcw;
969     break;
970     case SLJIT_MOV_SB:
971     srcw = (signed char)srcw;
972     break;
973     case SLJIT_MOV_UH:
974     srcw = (unsigned short)srcw;
975     break;
976     case SLJIT_MOV_SH:
977     srcw = (signed short)srcw;
978     break;
979     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
980     case SLJIT_MOV_UI:
981     srcw = (unsigned int)srcw;
982     break;
983     case SLJIT_MOV_SI:
984     srcw = (signed int)srcw;
985     break;
986     #endif
987     }
988     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
989     if (SLJIT_UNLIKELY(dst_is_ereg))
990     return emit_mov(compiler, dst, dstw, src, srcw);
991     #endif
992     }
993    
994     if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) {
995     code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw);
996     FAIL_IF(!code);
997     *code = 0x8d;
998     src &= SLJIT_MEM | 0xf;
999     srcw = 0;
1000     }
1001    
1002     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1003     if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) {
1004     SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
1005     dst = TMP_REGISTER;
1006     }
1007     #endif
1008    
1009     switch (op) {
1010     case SLJIT_MOV:
1011     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1012     case SLJIT_MOV_UI:
1013     case SLJIT_MOV_SI:
1014     #endif
1015     FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
1016     break;
1017     case SLJIT_MOV_UB:
1018     FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
1019     break;
1020     case SLJIT_MOV_SB:
1021     FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
1022     break;
1023     case SLJIT_MOV_UH:
1024     FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
1025     break;
1026     case SLJIT_MOV_SH:
1027     FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
1028     break;
1029     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1030     case SLJIT_MOV_UI:
1031     FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
1032     break;
1033     case SLJIT_MOV_SI:
1034     FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
1035     break;
1036     #endif
1037     }
1038    
1039     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1040     if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER)
1041     return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0);
1042     #endif
1043    
1044     if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) {
1045     code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw);
1046     FAIL_IF(!code);
1047     *code = 0x8d;
1048     }
1049     return SLJIT_SUCCESS;
1050     }
1051    
1052     if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1053     compiler->flags_saved = 0;
1054    
1055     switch (GET_OPCODE(op)) {
1056     case SLJIT_NOT:
1057     if (SLJIT_UNLIKELY(op & SLJIT_SET_E))
1058     return emit_not_with_flags(compiler, dst, dstw, src, srcw);
1059     return emit_unary(compiler, 0x2, dst, dstw, src, srcw);
1060    
1061     case SLJIT_NEG:
1062     if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1063     FAIL_IF(emit_save_flags(compiler));
1064     return emit_unary(compiler, 0x3, dst, dstw, src, srcw);
1065    
1066     case SLJIT_CLZ:
1067     if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1068     FAIL_IF(emit_save_flags(compiler));
1069     return emit_clz(compiler, op, dst, dstw, src, srcw);
1070     }
1071    
1072     return SLJIT_SUCCESS;
1073    
1074     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1075     #undef src_is_ereg
1076     #endif
1077     }
1078    
1079     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1080    
1081     #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1082     if (IS_HALFWORD(immw) || compiler->mode32) { \
1083     code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1084     FAIL_IF(!code); \
1085     *(code + 1) |= (_op_imm_); \
1086     } \
1087     else { \
1088     FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
1089     code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
1090     FAIL_IF(!code); \
1091     *code = (_op_mr_); \
1092     }
1093    
1094     #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1095     FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw))
1096    
1097     #else
1098    
1099     #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1100     code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1101     FAIL_IF(!code); \
1102     *(code + 1) |= (_op_imm_);
1103    
1104     #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1105     FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
1106    
1107     #endif
1108    
1109     static int emit_cum_binary(struct sljit_compiler *compiler,
1110     sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1111     int dst, sljit_w dstw,
1112     int src1, sljit_w src1w,
1113     int src2, sljit_w src2w)
1114     {
1115     sljit_ub* code;
1116    
1117     if (dst == SLJIT_UNUSED) {
1118     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1119     if (src2 & SLJIT_IMM) {
1120     BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1121     }
1122     else {
1123     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1124     FAIL_IF(!code);
1125     *code = op_rm;
1126     }
1127     return SLJIT_SUCCESS;
1128     }
1129    
1130     if (dst == src1 && dstw == src1w) {
1131     if (src2 & SLJIT_IMM) {
1132     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1133     if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1134     #else
1135     if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1136     #endif
1137     BINARY_EAX_IMM(op_eax_imm, src2w);
1138     }
1139     else {
1140     BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1141     }
1142     }
1143     else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1144     code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1145     FAIL_IF(!code);
1146     *code = op_rm;
1147     }
1148     else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) {
1149     /* Special exception for sljit_emit_cond_value. */
1150     code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1151     FAIL_IF(!code);
1152     *code = op_mr;
1153     }
1154     else {
1155     EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1156     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1157     FAIL_IF(!code);
1158     *code = op_mr;
1159     }
1160     return SLJIT_SUCCESS;
1161     }
1162    
1163     /* Only for cumulative operations. */
1164     if (dst == src2 && dstw == src2w) {
1165     if (src1 & SLJIT_IMM) {
1166     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1167     if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1168     #else
1169     if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
1170     #endif
1171     BINARY_EAX_IMM(op_eax_imm, src1w);
1172     }
1173     else {
1174     BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
1175     }
1176     }
1177     else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1178     code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
1179     FAIL_IF(!code);
1180     *code = op_rm;
1181     }
1182     else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1183     code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
1184     FAIL_IF(!code);
1185     *code = op_mr;
1186     }
1187     else {
1188     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1189     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1190     FAIL_IF(!code);
1191     *code = op_mr;
1192     }
1193     return SLJIT_SUCCESS;
1194     }
1195    
1196     /* General version. */
1197     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1198     EMIT_MOV(compiler, dst, 0, src1, src1w);
1199     if (src2 & SLJIT_IMM) {
1200     BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1201     }
1202     else {
1203     code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1204     FAIL_IF(!code);
1205     *code = op_rm;
1206     }
1207     }
1208     else {
1209     /* This version requires less memory writing. */
1210     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1211     if (src2 & SLJIT_IMM) {
1212     BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1213     }
1214     else {
1215     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1216     FAIL_IF(!code);
1217     *code = op_rm;
1218     }
1219     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1220     }
1221    
1222     return SLJIT_SUCCESS;
1223     }
1224    
1225     static int emit_non_cum_binary(struct sljit_compiler *compiler,
1226     sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1227     int dst, sljit_w dstw,
1228     int src1, sljit_w src1w,
1229     int src2, sljit_w src2w)
1230     {
1231     sljit_ub* code;
1232    
1233     if (dst == SLJIT_UNUSED) {
1234     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1235     if (src2 & SLJIT_IMM) {
1236     BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1237     }
1238     else {
1239     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1240     FAIL_IF(!code);
1241     *code = op_rm;
1242     }
1243     return SLJIT_SUCCESS;
1244     }
1245    
1246     if (dst == src1 && dstw == src1w) {
1247     if (src2 & SLJIT_IMM) {
1248     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1249     if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1250     #else
1251     if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1252     #endif
1253     BINARY_EAX_IMM(op_eax_imm, src2w);
1254     }
1255     else {
1256     BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1257     }
1258     }
1259     else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1260     code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1261     FAIL_IF(!code);
1262     *code = op_rm;
1263     }
1264     else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1265     code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1266     FAIL_IF(!code);
1267     *code = op_mr;
1268     }
1269     else {
1270     EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1271     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1272     FAIL_IF(!code);
1273     *code = op_mr;
1274     }
1275     return SLJIT_SUCCESS;
1276     }
1277    
1278     /* General version. */
1279     if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) {
1280     EMIT_MOV(compiler, dst, 0, src1, src1w);
1281     if (src2 & SLJIT_IMM) {
1282     BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1283     }
1284     else {
1285     code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1286     FAIL_IF(!code);
1287     *code = op_rm;
1288     }
1289     }
1290     else {
1291     /* This version requires less memory writing. */
1292     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1293     if (src2 & SLJIT_IMM) {
1294     BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1295     }
1296     else {
1297     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1298     FAIL_IF(!code);
1299     *code = op_rm;
1300     }
1301     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1302     }
1303    
1304     return SLJIT_SUCCESS;
1305     }
1306    
1307     static int emit_mul(struct sljit_compiler *compiler,
1308     int dst, sljit_w dstw,
1309     int src1, sljit_w src1w,
1310     int src2, sljit_w src2w)
1311     {
1312     sljit_ub* code;
1313     int dst_r;
1314    
1315     dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1316    
1317     /* Register destination. */
1318     if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
1319     code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1320     FAIL_IF(!code);
1321     *code++ = 0x0f;
1322     *code = 0xaf;
1323     }
1324     else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
1325     code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
1326     FAIL_IF(!code);
1327     *code++ = 0x0f;
1328     *code = 0xaf;
1329     }
1330     else if (src1 & SLJIT_IMM) {
1331     if (src2 & SLJIT_IMM) {
1332     EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
1333     src2 = dst_r;
1334     src2w = 0;
1335     }
1336    
1337     if (src1w <= 127 && src1w >= -128) {
1338     code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1339     FAIL_IF(!code);
1340     *code = 0x6b;
1341     code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1342     FAIL_IF(!code);
1343     INC_CSIZE(1);
1344     *code = (sljit_b)src1w;
1345     }
1346     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1347     else {
1348     code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1349     FAIL_IF(!code);
1350     *code = 0x69;
1351     code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1352     FAIL_IF(!code);
1353     INC_CSIZE(4);
1354     *(sljit_w*)code = src1w;
1355     }
1356     #else
1357     else if (IS_HALFWORD(src1w)) {
1358     code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1359     FAIL_IF(!code);
1360     *code = 0x69;
1361     code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1362     FAIL_IF(!code);
1363     INC_CSIZE(4);
1364 zherczeg 777 *(sljit_hw*)code = (sljit_hw)src1w;
1365 ph10 662 }
1366     else {
1367     EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1368     if (dst_r != src2)
1369     EMIT_MOV(compiler, dst_r, 0, src2, src2w);
1370     code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1371     FAIL_IF(!code);
1372     *code++ = 0x0f;
1373     *code = 0xaf;
1374     }
1375     #endif
1376     }
1377     else if (src2 & SLJIT_IMM) {
1378     /* Note: src1 is NOT immediate. */
1379    
1380     if (src2w <= 127 && src2w >= -128) {
1381     code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1382     FAIL_IF(!code);
1383     *code = 0x6b;
1384     code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1385     FAIL_IF(!code);
1386     INC_CSIZE(1);
1387     *code = (sljit_b)src2w;
1388     }
1389     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1390     else {
1391     code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1392     FAIL_IF(!code);
1393     *code = 0x69;
1394     code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1395     FAIL_IF(!code);
1396     INC_CSIZE(4);
1397     *(sljit_w*)code = src2w;
1398     }
1399     #else
1400     else if (IS_HALFWORD(src2w)) {
1401     code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1402     FAIL_IF(!code);
1403     *code = 0x69;
1404     code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1405     FAIL_IF(!code);
1406     INC_CSIZE(4);
1407 zherczeg 777 *(sljit_hw*)code = (sljit_hw)src2w;
1408 ph10 662 }
1409     else {
1410     EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1411     if (dst_r != src1)
1412     EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1413     code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1414     FAIL_IF(!code);
1415     *code++ = 0x0f;
1416     *code = 0xaf;
1417     }
1418     #endif
1419     }
1420     else {
1421     /* Neither argument is immediate. */
1422 zherczeg 740 if (ADDRESSING_DEPENDS_ON(src2, dst_r))
1423 ph10 662 dst_r = TMP_REGISTER;
1424     EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1425     code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1426     FAIL_IF(!code);
1427     *code++ = 0x0f;
1428     *code = 0xaf;
1429     }
1430    
1431     if (dst_r == TMP_REGISTER)
1432     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1433    
1434     return SLJIT_SUCCESS;
1435     }
1436    
1437     static int emit_lea_binary(struct sljit_compiler *compiler,
1438     int dst, sljit_w dstw,
1439     int src1, sljit_w src1w,
1440     int src2, sljit_w src2w)
1441     {
1442     sljit_ub* code;
1443     int dst_r, done = 0;
1444    
1445     /* These cases better be left to handled by normal way. */
1446     if (dst == src1 && dstw == src1w)
1447     return SLJIT_ERR_UNSUPPORTED;
1448     if (dst == src2 && dstw == src2w)
1449     return SLJIT_ERR_UNSUPPORTED;
1450    
1451     dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1452    
1453     if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1454     if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1455     /* It is not possible to be both SLJIT_LOCALS_REG. */
1456     if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {
1457     code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
1458     FAIL_IF(!code);
1459     *code = 0x8d;
1460     done = 1;
1461     }
1462     }
1463     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1464     if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1465     code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w);
1466     #else
1467     if (src2 & SLJIT_IMM) {
1468     code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
1469     #endif
1470     FAIL_IF(!code);
1471     *code = 0x8d;
1472     done = 1;
1473     }
1474     }
1475     else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1476     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1477     if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1478     code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w);
1479     #else
1480     if (src1 & SLJIT_IMM) {
1481     code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
1482     #endif
1483     FAIL_IF(!code);
1484     *code = 0x8d;
1485     done = 1;
1486     }
1487     }
1488    
1489     if (done) {
1490     if (dst_r == TMP_REGISTER)
1491     return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
1492     return SLJIT_SUCCESS;
1493     }
1494     return SLJIT_ERR_UNSUPPORTED;
1495     }
1496    
1497     static int emit_cmp_binary(struct sljit_compiler *compiler,
1498     int src1, sljit_w src1w,
1499     int src2, sljit_w src2w)
1500     {
1501     sljit_ub* code;
1502    
1503     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1504     if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1505     #else
1506     if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1507     #endif
1508     BINARY_EAX_IMM(0x3d, src2w);
1509     return SLJIT_SUCCESS;
1510     }
1511    
1512     if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1513     if (src2 & SLJIT_IMM) {
1514     BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
1515     }
1516     else {
1517     code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1518     FAIL_IF(!code);
1519     *code = 0x3b;
1520     }
1521     return SLJIT_SUCCESS;
1522     }
1523    
1524     if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
1525     code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1526     FAIL_IF(!code);
1527     *code = 0x39;
1528     return SLJIT_SUCCESS;
1529     }
1530    
1531     if (src2 & SLJIT_IMM) {
1532     if (src1 & SLJIT_IMM) {
1533     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1534     src1 = TMP_REGISTER;
1535     src1w = 0;
1536     }
1537     BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
1538     }
1539     else {
1540     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1541     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1542     FAIL_IF(!code);
1543     *code = 0x3b;
1544     }
1545     return SLJIT_SUCCESS;
1546     }
1547    
1548     static int emit_test_binary(struct sljit_compiler *compiler,
1549     int src1, sljit_w src1w,
1550     int src2, sljit_w src2w)
1551     {
1552     sljit_ub* code;
1553    
1554     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1555     if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1556     #else
1557     if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1558     #endif
1559     BINARY_EAX_IMM(0xa9, src2w);
1560     return SLJIT_SUCCESS;
1561     }
1562    
1563     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1564     if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1565     #else
1566     if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
1567     #endif
1568     BINARY_EAX_IMM(0xa9, src1w);
1569     return SLJIT_SUCCESS;
1570     }
1571    
1572     if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1573     if (src2 & SLJIT_IMM) {
1574     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1575     if (IS_HALFWORD(src2w) || compiler->mode32) {
1576     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1577     FAIL_IF(!code);
1578     *code = 0xf7;
1579     }
1580     else {
1581     FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1582     code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
1583     FAIL_IF(!code);
1584     *code = 0x85;
1585     }
1586     #else
1587     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1588     FAIL_IF(!code);
1589     *code = 0xf7;
1590     #endif
1591     }
1592     else {
1593     code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1594     FAIL_IF(!code);
1595     *code = 0x85;
1596     }
1597     return SLJIT_SUCCESS;
1598     }
1599    
1600     if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1601     if (src1 & SLJIT_IMM) {
1602     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1603     if (IS_HALFWORD(src1w) || compiler->mode32) {
1604     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
1605     FAIL_IF(!code);
1606     *code = 0xf7;
1607     }
1608     else {
1609     FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
1610     code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
1611     FAIL_IF(!code);
1612     *code = 0x85;
1613     }
1614     #else
1615     code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
1616     FAIL_IF(!code);
1617     *code = 0xf7;
1618     #endif
1619     }
1620     else {
1621     code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1622     FAIL_IF(!code);
1623     *code = 0x85;
1624     }
1625     return SLJIT_SUCCESS;
1626     }
1627    
1628     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1629     if (src2 & SLJIT_IMM) {
1630     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1631     if (IS_HALFWORD(src2w) || compiler->mode32) {
1632     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1633     FAIL_IF(!code);
1634     *code = 0xf7;
1635     }
1636     else {
1637     FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1638     code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
1639     FAIL_IF(!code);
1640     *code = 0x85;
1641     }
1642     #else
1643     code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1644     FAIL_IF(!code);
1645     *code = 0xf7;
1646     #endif
1647     }
1648     else {
1649     code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1650     FAIL_IF(!code);
1651     *code = 0x85;
1652     }
1653     return SLJIT_SUCCESS;
1654     }
1655    
1656     static int emit_shift(struct sljit_compiler *compiler,
1657     sljit_ub mode,
1658     int dst, sljit_w dstw,
1659     int src1, sljit_w src1w,
1660     int src2, sljit_w src2w)
1661     {
1662     sljit_ub* code;
1663    
1664     if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
1665     if (dst == src1 && dstw == src1w) {
1666     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
1667     FAIL_IF(!code);
1668     *code |= mode;
1669     return SLJIT_SUCCESS;
1670     }
1671     if (dst == SLJIT_UNUSED) {
1672     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1673     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1674     FAIL_IF(!code);
1675     *code |= mode;
1676     return SLJIT_SUCCESS;
1677     }
1678     if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
1679     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1680     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1681     FAIL_IF(!code);
1682     *code |= mode;
1683     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1684     return SLJIT_SUCCESS;
1685     }
1686     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1687     EMIT_MOV(compiler, dst, 0, src1, src1w);
1688     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
1689     FAIL_IF(!code);
1690     *code |= mode;
1691     return SLJIT_SUCCESS;
1692     }
1693    
1694     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1695     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1696     FAIL_IF(!code);
1697     *code |= mode;
1698     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1699     return SLJIT_SUCCESS;
1700     }
1701    
1702     if (dst == SLJIT_PREF_SHIFT_REG) {
1703     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1704     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1705     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1706     FAIL_IF(!code);
1707     *code |= mode;
1708     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1709     }
1710 zherczeg 740 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
1711 ph10 662 if (src1 != dst)
1712     EMIT_MOV(compiler, dst, 0, src1, src1w);
1713     EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
1714     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1715     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
1716     FAIL_IF(!code);
1717     *code |= mode;
1718     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1719     }
1720     else {
1721     /* This case is really difficult, since ecx can be used for
1722     addressing as well, and we must ensure to work even in that case. */
1723     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1724     EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1725     #else
1726     /* [esp - 4] is reserved for eflags. */
1727     EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
1728     #endif
1729    
1730     EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1731     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1732     code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1733     FAIL_IF(!code);
1734     *code |= mode;
1735    
1736     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1737     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1738     #else
1739     /* [esp - 4] is reserved for eflags. */
1740     EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)));
1741     #endif
1742     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1743     }
1744    
1745     return SLJIT_SUCCESS;
1746     }
1747    
1748 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
1749 ph10 662 int dst, sljit_w dstw,
1750     int src1, sljit_w src1w,
1751     int src2, sljit_w src2w)
1752     {
1753     CHECK_ERROR();
1754     check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1755    
1756     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1757     compiler->mode32 = op & SLJIT_INT_OP;
1758     #endif
1759     CHECK_EXTRA_REGS(dst, dstw, (void)0);
1760     CHECK_EXTRA_REGS(src1, src1w, (void)0);
1761     CHECK_EXTRA_REGS(src2, src2w, (void)0);
1762    
1763     if (GET_OPCODE(op) >= SLJIT_MUL) {
1764     if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1765     compiler->flags_saved = 0;
1766     else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1767     FAIL_IF(emit_save_flags(compiler));
1768     }
1769    
1770     switch (GET_OPCODE(op)) {
1771     case SLJIT_ADD:
1772     if (!GET_FLAGS(op)) {
1773     if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
1774     return compiler->error;
1775     }
1776     else
1777     compiler->flags_saved = 0;
1778     if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1779     FAIL_IF(emit_save_flags(compiler));
1780     return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
1781     dst, dstw, src1, src1w, src2, src2w);
1782     case SLJIT_ADDC:
1783     if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1784     FAIL_IF(emit_restore_flags(compiler, 1));
1785     else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1786     FAIL_IF(emit_save_flags(compiler));
1787     if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1788     compiler->flags_saved = 0;
1789     return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15,
1790     dst, dstw, src1, src1w, src2, src2w);
1791     case SLJIT_SUB:
1792     if (!GET_FLAGS(op)) {
1793     if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
1794     return compiler->error;
1795     }
1796     else
1797     compiler->flags_saved = 0;
1798     if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1799     FAIL_IF(emit_save_flags(compiler));
1800     if (dst == SLJIT_UNUSED)
1801     return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
1802     return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
1803     dst, dstw, src1, src1w, src2, src2w);
1804     case SLJIT_SUBC:
1805     if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1806     FAIL_IF(emit_restore_flags(compiler, 1));
1807     else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1808     FAIL_IF(emit_save_flags(compiler));
1809     if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1810     compiler->flags_saved = 0;
1811     return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d,
1812     dst, dstw, src1, src1w, src2, src2w);
1813     case SLJIT_MUL:
1814     return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
1815     case SLJIT_AND:
1816     if (dst == SLJIT_UNUSED)
1817     return emit_test_binary(compiler, src1, src1w, src2, src2w);
1818     return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25,
1819     dst, dstw, src1, src1w, src2, src2w);
1820     case SLJIT_OR:
1821     return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1822     dst, dstw, src1, src1w, src2, src2w);
1823     case SLJIT_XOR:
1824     return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1825     dst, dstw, src1, src1w, src2, src2w);
1826     case SLJIT_SHL:
1827     return emit_shift(compiler, 0x4 << 3,
1828     dst, dstw, src1, src1w, src2, src2w);
1829     case SLJIT_LSHR:
1830     return emit_shift(compiler, 0x5 << 3,
1831     dst, dstw, src1, src1w, src2, src2w);
1832     case SLJIT_ASHR:
1833     return emit_shift(compiler, 0x7 << 3,
1834     dst, dstw, src1, src1w, src2, src2w);
1835     }
1836    
1837     return SLJIT_SUCCESS;
1838     }
1839    
1840     /* --------------------------------------------------------------------- */
1841     /* Floating point operators */
1842     /* --------------------------------------------------------------------- */
1843    
1844     #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1845     static int sse2_available = 0;
1846     #endif
1847    
1848     #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1849    
1850     /* Alignment + 2 * 16 bytes. */
1851 zherczeg 704 static sljit_i sse2_data[3 + 4 + 4];
1852     static sljit_i *sse2_buffer;
1853 ph10 662
1854     static void init_compiler()
1855     {
1856     #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1857     int features = 0;
1858     #endif
1859    
1860 zherczeg 704 sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
1861 ph10 662 sse2_buffer[0] = 0;
1862     sse2_buffer[1] = 0x80000000;
1863     sse2_buffer[4] = 0xffffffff;
1864     sse2_buffer[5] = 0x7fffffff;
1865    
1866     #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1867     #ifdef __GNUC__
1868     /* AT&T syntax. */
1869     asm (
1870     "pushl %%ebx\n"
1871     "movl $0x1, %%eax\n"
1872     "cpuid\n"
1873     "popl %%ebx\n"
1874     "movl %%edx, %0\n"
1875     : "=g" (features)
1876     :
1877     : "%eax", "%ecx", "%edx"
1878     );
1879 zherczeg 704 #elif defined(_MSC_VER) || defined(__BORLANDC__)
1880 ph10 662 /* Intel syntax. */
1881     __asm {
1882     mov eax, 1
1883     push ebx
1884     cpuid
1885     pop ebx
1886     mov features, edx
1887     }
1888     #else
1889     #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
1890     #endif
1891     sse2_available = (features >> 26) & 0x1;
1892     #endif
1893     }
1894    
1895     #endif
1896    
1897 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
1898 ph10 662 {
1899     /* Always available. */
1900     return 1;
1901     }
1902    
1903     #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1904    
1905     static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
1906     int xmm1, int xmm2, sljit_w xmm2w)
1907     {
1908     sljit_ub *buf;
1909    
1910     buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
1911     FAIL_IF(!buf);
1912     *buf++ = 0x0f;
1913     *buf = opcode;
1914     return SLJIT_SUCCESS;
1915     }
1916    
1917     static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
1918     int xmm1, int xmm2, sljit_w xmm2w)
1919     {
1920     sljit_ub *buf;
1921    
1922     buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
1923     FAIL_IF(!buf);
1924     *buf++ = 0x0f;
1925     *buf = opcode;
1926     return SLJIT_SUCCESS;
1927     }
1928    
1929     static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
1930     int dst, int src, sljit_w srcw)
1931     {
1932     return emit_sse2(compiler, 0x10, dst, src, srcw);
1933     }
1934    
1935     static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
1936     int dst, sljit_w dstw, int src)
1937     {
1938     return emit_sse2(compiler, 0x11, src, dst, dstw);
1939     }
1940    
1941     #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1942 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
1943 ph10 662 #else
1944     static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
1945     #endif
1946     int dst, sljit_w dstw,
1947     int src, sljit_w srcw)
1948     {
1949     int dst_r;
1950    
1951     CHECK_ERROR();
1952     check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
1953    
1954     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1955     compiler->mode32 = 1;
1956     #endif
1957    
1958     if (GET_OPCODE(op) == SLJIT_FCMP) {
1959     compiler->flags_saved = 0;
1960     if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
1961     dst_r = dst;
1962     else {
1963     dst_r = TMP_FREG;
1964     FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
1965     }
1966     return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
1967     }
1968    
1969     if (op == SLJIT_FMOV) {
1970     if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
1971     return emit_sse2_load(compiler, dst, src, srcw);
1972     if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
1973     return emit_sse2_store(compiler, dst, dstw, src);
1974     FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
1975     return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
1976     }
1977    
1978     if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
1979     dst_r = dst;
1980     if (dst != src)
1981     FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
1982     }
1983     else {
1984     dst_r = TMP_FREG;
1985     FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
1986     }
1987    
1988     switch (op) {
1989     case SLJIT_FNEG:
1990     FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
1991     break;
1992    
1993     case SLJIT_FABS:
1994     FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
1995     break;
1996     }
1997    
1998     if (dst_r == TMP_FREG)
1999     return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2000     return SLJIT_SUCCESS;
2001     }
2002    
2003     #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2004 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2005 ph10 662 #else
2006     static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
2007     #endif
2008     int dst, sljit_w dstw,
2009     int src1, sljit_w src1w,
2010     int src2, sljit_w src2w)
2011     {
2012     int dst_r;
2013    
2014     CHECK_ERROR();
2015     check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2016    
2017     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2018     compiler->mode32 = 1;
2019     #endif
2020    
2021     if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2022     dst_r = dst;
2023     if (dst == src1)
2024     ; /* Do nothing here. */
2025     else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
2026     /* Swap arguments. */
2027     src2 = src1;
2028     src2w = src1w;
2029     }
2030     else if (dst != src2)
2031     FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
2032     else {
2033     dst_r = TMP_FREG;
2034     FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2035     }
2036     }
2037     else {
2038     dst_r = TMP_FREG;
2039     FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2040     }
2041    
2042     switch (op) {
2043     case SLJIT_FADD:
2044     FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
2045     break;
2046    
2047     case SLJIT_FSUB:
2048     FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
2049     break;
2050    
2051     case SLJIT_FMUL:
2052     FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
2053     break;
2054    
2055     case SLJIT_FDIV:
2056     FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
2057     break;
2058     }
2059    
2060     if (dst_r == TMP_FREG)
2061     return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2062     return SLJIT_SUCCESS;
2063     }
2064    
2065     #endif
2066    
2067     #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
2068    
2069     static int emit_fld(struct sljit_compiler *compiler,
2070     int src, sljit_w srcw)
2071     {
2072     sljit_ub *buf;
2073    
2074     if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2075     buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2076     FAIL_IF(!buf);
2077     INC_SIZE(2);
2078     *buf++ = 0xd9;
2079     *buf = 0xc0 + src - 1;
2080     return SLJIT_SUCCESS;
2081     }
2082    
2083     buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2084     FAIL_IF(!buf);
2085     *buf = 0xdd;
2086     return SLJIT_SUCCESS;
2087     }
2088    
2089     static int emit_fop(struct sljit_compiler *compiler,
2090     sljit_ub st_arg, sljit_ub st_arg2,
2091     sljit_ub m64fp_arg, sljit_ub m64fp_arg2,
2092     int src, sljit_w srcw)
2093     {
2094     sljit_ub *buf;
2095    
2096     if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2097     buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2098     FAIL_IF(!buf);
2099     INC_SIZE(2);
2100     *buf++ = st_arg;
2101     *buf = st_arg2 + src;
2102     return SLJIT_SUCCESS;
2103     }
2104    
2105     buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2106     FAIL_IF(!buf);
2107     *buf++ = m64fp_arg;
2108     *buf |= m64fp_arg2;
2109     return SLJIT_SUCCESS;
2110     }
2111    
2112     static int emit_fop_regs(struct sljit_compiler *compiler,
2113     sljit_ub st_arg, sljit_ub st_arg2,
2114     int src)
2115     {
2116     sljit_ub *buf;
2117    
2118     buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2119     FAIL_IF(!buf);
2120     INC_SIZE(2);
2121     *buf++ = st_arg;
2122     *buf = st_arg2 + src;
2123     return SLJIT_SUCCESS;
2124     }
2125    
2126     #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2127 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2128 ph10 662 #else
2129     static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
2130     #endif
2131     int dst, sljit_w dstw,
2132     int src, sljit_w srcw)
2133     {
2134     #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2135     sljit_ub *buf;
2136     #endif
2137    
2138     CHECK_ERROR();
2139     check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2140    
2141     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2142     compiler->mode32 = 1;
2143     #endif
2144    
2145     if (GET_OPCODE(op) == SLJIT_FCMP) {
2146     compiler->flags_saved = 0;
2147     #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2148     FAIL_IF(emit_fld(compiler, dst, dstw));
2149     FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw));
2150    
2151     /* Copy flags. */
2152     EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2153     buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2154     FAIL_IF(!buf);
2155     INC_SIZE(3);
2156     *buf++ = 0xdf;
2157     *buf++ = 0xe0;
2158     /* Note: lahf is not supported on all x86-64 architectures. */
2159     *buf++ = 0x9e;
2160     EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2161     #else
2162     if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2163     FAIL_IF(emit_fld(compiler, dst, dstw));
2164     FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2165     } else {
2166     FAIL_IF(emit_fld(compiler, src, srcw));
2167     FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw));
2168     FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2169     FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0));
2170     }
2171     #endif
2172     return SLJIT_SUCCESS;
2173     }
2174    
2175     FAIL_IF(emit_fld(compiler, src, srcw));
2176    
2177     switch (op) {
2178     case SLJIT_FNEG:
2179     FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
2180     break;
2181     case SLJIT_FABS:
2182     FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
2183     break;
2184     }
2185    
2186     FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2187    
2188     return SLJIT_SUCCESS;
2189     }
2190    
2191     #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2192 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2193 ph10 662 #else
2194     static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
2195     #endif
2196     int dst, sljit_w dstw,
2197     int src1, sljit_w src1w,
2198     int src2, sljit_w src2w)
2199     {
2200     CHECK_ERROR();
2201     check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2202    
2203     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2204     compiler->mode32 = 1;
2205     #endif
2206    
2207     if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
2208     FAIL_IF(emit_fld(compiler, src2, src2w));
2209    
2210     switch (op) {
2211     case SLJIT_FADD:
2212     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
2213     break;
2214     case SLJIT_FSUB:
2215     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
2216     break;
2217     case SLJIT_FMUL:
2218     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
2219     break;
2220     case SLJIT_FDIV:
2221     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
2222     break;
2223     }
2224     return SLJIT_SUCCESS;
2225     }
2226    
2227     FAIL_IF(emit_fld(compiler, src1, src1w));
2228    
2229     if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
2230     switch (op) {
2231     case SLJIT_FADD:
2232     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
2233     break;
2234     case SLJIT_FSUB:
2235     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
2236     break;
2237     case SLJIT_FMUL:
2238     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
2239     break;
2240     case SLJIT_FDIV:
2241     FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
2242     break;
2243     }
2244     return SLJIT_SUCCESS;
2245     }
2246    
2247     switch (op) {
2248     case SLJIT_FADD:
2249     FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
2250     break;
2251     case SLJIT_FSUB:
2252     FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
2253     break;
2254     case SLJIT_FMUL:
2255     FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
2256     break;
2257     case SLJIT_FDIV:
2258     FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
2259     break;
2260     }
2261    
2262     FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2263    
2264     return SLJIT_SUCCESS;
2265     }
2266     #endif
2267    
2268     #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2269    
2270 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2271 ph10 662 int dst, sljit_w dstw,
2272     int src, sljit_w srcw)
2273     {
2274     if (sse2_available)
2275     return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
2276     else
2277     return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
2278     }
2279    
2280 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2281 ph10 662 int dst, sljit_w dstw,
2282     int src1, sljit_w src1w,
2283     int src2, sljit_w src2w)
2284     {
2285     if (sse2_available)
2286     return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2287     else
2288     return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2289     }
2290    
2291     #endif
2292    
2293     /* --------------------------------------------------------------------- */
2294     /* Conditional instructions */
2295     /* --------------------------------------------------------------------- */
2296    
2297 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2298 ph10 662 {
2299     sljit_ub *buf;
2300     struct sljit_label *label;
2301    
2302     CHECK_ERROR_PTR();
2303     check_sljit_emit_label(compiler);
2304    
2305     /* We should restore the flags before the label,
2306     since other taken jumps has their own flags as well. */
2307     if (SLJIT_UNLIKELY(compiler->flags_saved))
2308     PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2309    
2310     if (compiler->last_label && compiler->last_label->size == compiler->size)
2311     return compiler->last_label;
2312    
2313     label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2314     PTR_FAIL_IF(!label);
2315     set_label(label, compiler);
2316    
2317     buf = (sljit_ub*)ensure_buf(compiler, 2);
2318     PTR_FAIL_IF(!buf);
2319    
2320     *buf++ = 0;
2321     *buf++ = 0;
2322    
2323     return label;
2324     }
2325    
2326 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2327 ph10 662 {
2328     sljit_ub *buf;
2329     struct sljit_jump *jump;
2330    
2331     CHECK_ERROR_PTR();
2332     check_sljit_emit_jump(compiler, type);
2333    
2334     if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2335     if ((type & 0xff) <= SLJIT_JUMP)
2336     PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2337     compiler->flags_saved = 0;
2338     }
2339    
2340     jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2341     PTR_FAIL_IF_NULL(jump);
2342     set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2343     type &= 0xff;
2344    
2345     if (type >= SLJIT_CALL1)
2346     PTR_FAIL_IF(call_with_args(compiler, type));
2347    
2348     /* Worst case size. */
2349     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2350     compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
2351     #else
2352     compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
2353     #endif
2354    
2355     buf = (sljit_ub*)ensure_buf(compiler, 2);
2356     PTR_FAIL_IF_NULL(buf);
2357    
2358     *buf++ = 0;
2359     *buf++ = type + 4;
2360     return jump;
2361     }
2362    
2363 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2364 ph10 662 {
2365     sljit_ub *code;
2366     struct sljit_jump *jump;
2367    
2368     CHECK_ERROR();
2369     check_sljit_emit_ijump(compiler, type, src, srcw);
2370    
2371     CHECK_EXTRA_REGS(src, srcw, (void)0);
2372     if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2373     if (type <= SLJIT_JUMP)
2374     FAIL_IF(emit_restore_flags(compiler, 0));
2375     compiler->flags_saved = 0;
2376     }
2377    
2378     if (type >= SLJIT_CALL1) {
2379     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2380     #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
2381     if (src == SLJIT_TEMPORARY_REG3) {
2382     EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2383     src = TMP_REGISTER;
2384     }
2385     if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
2386     if (src & 0xf0) {
2387     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2388     src = TMP_REGISTER;
2389     }
2390     else
2391     srcw += sizeof(sljit_w);
2392     }
2393     #else
2394     if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
2395     if (src & 0xf0) {
2396     EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2397     src = TMP_REGISTER;
2398     }
2399     else
2400     srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
2401     }
2402     #endif
2403     #endif
2404     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
2405     if (src == SLJIT_TEMPORARY_REG3) {
2406     EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2407     src = TMP_REGISTER;
2408     }
2409     #endif
2410     FAIL_IF(call_with_args(compiler, type));
2411     }
2412    
2413     if (src == SLJIT_IMM) {
2414     jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2415     FAIL_IF_NULL(jump);
2416     set_jump(jump, compiler, JUMP_ADDR);
2417     jump->u.target = srcw;
2418    
2419     /* Worst case size. */
2420     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2421     compiler->size += 5;
2422     #else
2423     compiler->size += 10 + 3;
2424     #endif
2425    
2426     code = (sljit_ub*)ensure_buf(compiler, 2);
2427     FAIL_IF_NULL(code);
2428    
2429     *code++ = 0;
2430     *code++ = type + 4;
2431     }
2432     else {
2433     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2434     /* REX_W is not necessary (src is not immediate). */
2435     compiler->mode32 = 1;
2436     #endif
2437     code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2438     FAIL_IF(!code);
2439     *code++ = 0xff;
2440 zherczeg 722 *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2441 ph10 662 }
2442     return SLJIT_SUCCESS;
2443     }
2444    
2445 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2446 ph10 662 {
2447     sljit_ub *buf;
2448     sljit_ub cond_set = 0;
2449     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2450     int reg;
2451     #endif
2452    
2453     CHECK_ERROR();
2454     check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
2455    
2456     if (dst == SLJIT_UNUSED)
2457     return SLJIT_SUCCESS;
2458    
2459     CHECK_EXTRA_REGS(dst, dstw, (void)0);
2460     if (SLJIT_UNLIKELY(compiler->flags_saved))
2461     FAIL_IF(emit_restore_flags(compiler, 0));
2462    
2463     switch (type) {
2464     case SLJIT_C_EQUAL:
2465     case SLJIT_C_FLOAT_EQUAL:
2466     cond_set = 0x94;
2467     break;
2468    
2469     case SLJIT_C_NOT_EQUAL:
2470     case SLJIT_C_FLOAT_NOT_EQUAL:
2471     cond_set = 0x95;
2472     break;
2473    
2474     case SLJIT_C_LESS:
2475     case SLJIT_C_FLOAT_LESS:
2476     cond_set = 0x92;
2477     break;
2478    
2479     case SLJIT_C_GREATER_EQUAL:
2480     case SLJIT_C_FLOAT_GREATER_EQUAL:
2481     cond_set = 0x93;
2482     break;
2483    
2484     case SLJIT_C_GREATER:
2485     case SLJIT_C_FLOAT_GREATER:
2486     cond_set = 0x97;
2487     break;
2488    
2489     case SLJIT_C_LESS_EQUAL:
2490     case SLJIT_C_FLOAT_LESS_EQUAL:
2491     cond_set = 0x96;
2492     break;
2493    
2494     case SLJIT_C_SIG_LESS:
2495     cond_set = 0x9c;
2496     break;
2497    
2498     case SLJIT_C_SIG_GREATER_EQUAL:
2499     cond_set = 0x9d;
2500     break;
2501    
2502     case SLJIT_C_SIG_GREATER:
2503     cond_set = 0x9f;
2504     break;
2505    
2506     case SLJIT_C_SIG_LESS_EQUAL:
2507     cond_set = 0x9e;
2508     break;
2509    
2510     case SLJIT_C_OVERFLOW:
2511     case SLJIT_C_MUL_OVERFLOW:
2512     cond_set = 0x90;
2513     break;
2514    
2515     case SLJIT_C_NOT_OVERFLOW:
2516     case SLJIT_C_MUL_NOT_OVERFLOW:
2517     cond_set = 0x91;
2518     break;
2519    
2520     case SLJIT_C_FLOAT_NAN:
2521     cond_set = 0x9a;
2522     break;
2523    
2524     case SLJIT_C_FLOAT_NOT_NAN:
2525     cond_set = 0x9b;
2526     break;
2527     }
2528    
2529     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2530     reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2531    
2532     buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
2533     FAIL_IF(!buf);
2534     INC_SIZE(4 + 4);
2535     /* Set low register to conditional flag. */
2536     *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
2537     *buf++ = 0x0f;
2538     *buf++ = cond_set;
2539     *buf++ = 0xC0 | reg_lmap[reg];
2540     *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
2541     *buf++ = 0x0f;
2542     *buf++ = 0xb6;
2543     *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
2544    
2545     if (reg == TMP_REGISTER) {
2546     if (op == SLJIT_MOV) {
2547     compiler->mode32 = 0;
2548     EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
2549     }
2550     else {
2551     #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2552     compiler->skip_checks = 1;
2553     #endif
2554     return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2555     }
2556     }
2557     #else
2558     if (op == SLJIT_MOV) {
2559     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2560     buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2561     FAIL_IF(!buf);
2562     INC_SIZE(3 + 3);
2563     /* Set low byte to conditional flag. */
2564     *buf++ = 0x0f;
2565     *buf++ = cond_set;
2566     *buf++ = 0xC0 | reg_map[dst];
2567    
2568     *buf++ = 0x0f;
2569     *buf++ = 0xb6;
2570     *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
2571     }
2572     else {
2573     EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2574    
2575     buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2576     FAIL_IF(!buf);
2577     INC_SIZE(3 + 3);
2578     /* Set al to conditional flag. */
2579     *buf++ = 0x0f;
2580     *buf++ = cond_set;
2581     *buf++ = 0xC0;
2582    
2583     *buf++ = 0x0f;
2584     *buf++ = 0xb6;
2585     if (dst >= SLJIT_GENERAL_REG1 && dst <= SLJIT_NO_REGISTERS)
2586     *buf = 0xC0 | (reg_map[dst] << 3);
2587     else {
2588     *buf = 0xC0;
2589     EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
2590     }
2591    
2592     EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2593     }
2594     }
2595     else {
2596     if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2597     EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
2598     buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2599     FAIL_IF(!buf);
2600     INC_SIZE(3);
2601    
2602     *buf++ = 0x0f;
2603     *buf++ = cond_set;
2604     *buf++ = 0xC0 | reg_map[dst];
2605     }
2606     else {
2607     EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2608    
2609     buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
2610     FAIL_IF(!buf);
2611     INC_SIZE(3 + 3 + 1);
2612     /* Set al to conditional flag. */
2613     *buf++ = 0x0f;
2614     *buf++ = cond_set;
2615     *buf++ = 0xC0;
2616    
2617     *buf++ = 0x0f;
2618     *buf++ = 0xb6;
2619     *buf++ = 0xC0;
2620    
2621     *buf++ = 0x90 + reg_map[TMP_REGISTER];
2622     }
2623     #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2624     compiler->skip_checks = 1;
2625     #endif
2626     return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2627     }
2628     #endif
2629    
2630     return SLJIT_SUCCESS;
2631     }
2632    
2633 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
2634 ph10 662 {
2635     sljit_ub *buf;
2636     struct sljit_const *const_;
2637     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2638     int reg;
2639     #endif
2640    
2641     CHECK_ERROR_PTR();
2642     check_sljit_emit_const(compiler, dst, dstw, init_value);
2643    
2644     CHECK_EXTRA_REGS(dst, dstw, (void)0);
2645    
2646     const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2647     PTR_FAIL_IF(!const_);
2648     set_const(const_, compiler);
2649    
2650     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2651     compiler->mode32 = 0;
2652     reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2653    
2654     if (emit_load_imm64(compiler, reg, init_value))
2655     return NULL;
2656     #else
2657     if (dst == SLJIT_UNUSED)
2658     dst = TMP_REGISTER;
2659    
2660     if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
2661     return NULL;
2662     #endif
2663    
2664     buf = (sljit_ub*)ensure_buf(compiler, 2);
2665     PTR_FAIL_IF(!buf);
2666    
2667     *buf++ = 0;
2668     *buf++ = 1;
2669    
2670     #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2671     if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
2672     if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
2673     return NULL;
2674     #endif
2675    
2676     return const_;
2677     }
2678    
2679 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2680 ph10 662 {
2681     #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2682     *(sljit_w*)addr = new_addr - (addr + 4);
2683     #else
2684     *(sljit_uw*)addr = new_addr;
2685     #endif
2686     }
2687    
2688 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2689 ph10 662 {
2690     *(sljit_w*)addr = new_constant;
2691     }

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12