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

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12