Annotation of embedaddon/pcre/sljit/sljitNativeX86_common.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>