2 * Stack-less Just-In-Time compiler
4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
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.
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.
27 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
29 return "x86" SLJIT_CPUINFO;
54 8 - R8 - From now on REX prefix is required
64 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
66 /* Last register + 1. */
67 #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
69 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
70 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
73 #define CHECK_EXTRA_REGS(p, w, do) \
74 if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
75 w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \
76 p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
79 else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
80 w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
81 p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
85 #else /* SLJIT_CONFIG_X86_32 */
87 /* Last register + 1. */
88 #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
89 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
90 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
92 /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
93 Note: avoid to use r12 and r13 for memory addessing
94 therefore r12 is better for SAVED_EREG than SAVED_REG. */
96 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
97 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
98 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
100 /* low-map. reg_map & 0x7. */
101 static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
102 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
105 /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
106 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
107 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 12, 15, 10, 8, 9
109 /* low-map. reg_map & 0x7. */
110 static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
111 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 4, 7, 2, 0, 1
121 typedef unsigned int sljit_uhw;
122 typedef int sljit_hw;
124 #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
125 #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
127 #define CHECK_EXTRA_REGS(p, w, do)
129 #endif /* SLJIT_CONFIG_X86_32 */
131 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
132 #define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
135 /* Size flags for emit_x86_instruction: */
136 #define EX86_BIN_INS 0x0010
137 #define EX86_SHIFT_INS 0x0020
138 #define EX86_REX 0x0040
139 #define EX86_NO_REXW 0x0080
140 #define EX86_BYTE_ARG 0x0100
141 #define EX86_HALF_ARG 0x0200
142 #define EX86_PREF_66 0x0400
144 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
145 #define EX86_PREF_F2 0x0800
146 #define EX86_SSE2 0x1000
149 #define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
150 #define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
152 #define PUSH_REG(r) (*buf++ = (0x50 + (r)))
153 #define POP_REG(r) (*buf++ = (0x58 + (r)))
154 #define RET() (*buf++ = (0xc3))
155 #define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0)
157 #define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
159 static sljit_ub get_jump_code(int type)
163 case SLJIT_C_FLOAT_EQUAL:
166 case SLJIT_C_NOT_EQUAL:
167 case SLJIT_C_FLOAT_NOT_EQUAL:
171 case SLJIT_C_FLOAT_LESS:
174 case SLJIT_C_GREATER_EQUAL:
175 case SLJIT_C_FLOAT_GREATER_EQUAL:
178 case SLJIT_C_GREATER:
179 case SLJIT_C_FLOAT_GREATER:
182 case SLJIT_C_LESS_EQUAL:
183 case SLJIT_C_FLOAT_LESS_EQUAL:
186 case SLJIT_C_SIG_LESS:
189 case SLJIT_C_SIG_GREATER_EQUAL:
192 case SLJIT_C_SIG_GREATER:
195 case SLJIT_C_SIG_LESS_EQUAL:
198 case SLJIT_C_OVERFLOW:
199 case SLJIT_C_MUL_OVERFLOW:
202 case SLJIT_C_NOT_OVERFLOW:
203 case SLJIT_C_MUL_NOT_OVERFLOW:
206 case SLJIT_C_FLOAT_NAN:
209 case SLJIT_C_FLOAT_NOT_NAN:
215 static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
217 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
218 static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type);
221 static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
226 if (jump->flags & JUMP_LABEL)
227 label_addr = (sljit_uw)(code + jump->u.label->size);
229 label_addr = jump->u.target;
230 short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127;
232 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
233 if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll)
234 return generate_far_jump_code(jump, code_ptr, type);
237 if (type == SLJIT_JUMP) {
244 else if (type >= SLJIT_FAST_CALL) {
249 else if (short_jump) {
250 *code_ptr++ = get_jump_code(type) - 0x10;
255 *code_ptr++ = get_jump_code(type);
260 jump->flags |= PATCH_MB;
261 code_ptr += sizeof(sljit_b);
263 jump->flags |= PATCH_MW;
264 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
265 code_ptr += sizeof(sljit_w);
267 code_ptr += sizeof(sljit_hw);
274 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
276 struct sljit_memory_fragment *buf;
283 struct sljit_label *label;
284 struct sljit_jump *jump;
285 struct sljit_const *const_;
288 check_sljit_generate_code(compiler);
289 reverse_buf(compiler);
291 /* Second code generation pass. */
292 code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
293 PTR_FAIL_WITH_EXEC_IF(code);
297 label = compiler->labels;
298 jump = compiler->jumps;
299 const_ = compiler->consts;
301 buf_ptr = buf->memory;
302 buf_end = buf_ptr + buf->used_size;
306 /* The code is already generated. */
307 SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
313 jump->addr = (sljit_uw)code_ptr;
314 if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
315 code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
317 code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
320 else if (*buf_ptr == 0) {
321 label->addr = (sljit_uw)code_ptr;
322 label->size = code_ptr - code;
325 else if (*buf_ptr == 1) {
326 const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
327 const_ = const_->next;
330 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
331 *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
333 *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w));
334 code_ptr += sizeof(sljit_w);
335 buf_ptr += sizeof(sljit_w) - 1;
337 code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
338 buf_ptr += sizeof(sljit_w);
343 } while (buf_ptr < buf_end);
344 SLJIT_ASSERT(buf_ptr == buf_end);
348 SLJIT_ASSERT(!label);
350 SLJIT_ASSERT(!const_);
352 jump = compiler->jumps;
354 if (jump->flags & PATCH_MB) {
355 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);
356 *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
357 } else if (jump->flags & PATCH_MW) {
358 if (jump->flags & JUMP_LABEL) {
359 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
360 *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
362 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);
363 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
367 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
368 *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
370 SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
371 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
375 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
376 else if (jump->flags & PATCH_MD)
377 *(sljit_w*)jump->addr = jump->u.label->addr;
383 /* Maybe we waste some space because of short jumps. */
384 SLJIT_ASSERT(code_ptr <= code + compiler->size);
385 compiler->error = SLJIT_ERR_COMPILED;
386 compiler->executable_size = compiler->size;
390 /* --------------------------------------------------------------------- */
392 /* --------------------------------------------------------------------- */
394 static int emit_cum_binary(struct sljit_compiler *compiler,
395 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
396 int dst, sljit_w dstw,
397 int src1, sljit_w src1w,
398 int src2, sljit_w src2w);
400 static int emit_non_cum_binary(struct sljit_compiler *compiler,
401 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
402 int dst, sljit_w dstw,
403 int src1, sljit_w src1w,
404 int src2, sljit_w src2w);
406 static int emit_mov(struct sljit_compiler *compiler,
407 int dst, sljit_w dstw,
408 int src, sljit_w srcw);
410 static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
414 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
415 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
418 *buf++ = 0x9c; /* pushfd */
420 buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
423 *buf++ = 0x9c; /* pushfq */
426 *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
429 *buf++ = sizeof(sljit_w);
430 compiler->flags_saved = 1;
431 return SLJIT_SUCCESS;
434 static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
438 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
439 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
443 buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
448 *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
451 *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
452 *buf++ = 0x9d; /* popfd / popfq */
453 compiler->flags_saved = keep_flags;
454 return SLJIT_SUCCESS;
460 static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
462 /* Workaround for calling _chkstk. */
467 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
468 #include "sljitNativeX86_32.c"
470 #include "sljitNativeX86_64.c"
473 static int emit_mov(struct sljit_compiler *compiler,
474 int dst, sljit_w dstw,
475 int src, sljit_w srcw)
479 if (dst == SLJIT_UNUSED) {
480 /* No destination, doesn't need to setup flags. */
481 if (src & SLJIT_MEM) {
482 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
486 return SLJIT_SUCCESS;
488 if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
489 code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
492 return SLJIT_SUCCESS;
494 if (src & SLJIT_IMM) {
495 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
496 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
497 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
499 if (!compiler->mode32) {
500 if (NOT_HALFWORD(srcw))
501 return emit_load_imm64(compiler, dst, srcw);
504 return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
507 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
508 if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
509 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
510 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
513 return SLJIT_SUCCESS;
516 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
519 return SLJIT_SUCCESS;
521 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
522 code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
525 return SLJIT_SUCCESS;
528 /* Memory to memory move. Requires two instruction. */
529 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
532 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
535 return SLJIT_SUCCESS;
538 #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
539 FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
541 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
544 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
549 check_sljit_emit_op0(compiler, op);
551 switch (GET_OPCODE(op)) {
552 case SLJIT_BREAKPOINT:
553 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
559 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
568 compiler->flags_saved = 0;
569 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
571 SLJIT_COMPILE_ASSERT(
572 reg_map[SLJIT_TEMPORARY_REG1] == 0
573 && reg_map[SLJIT_TEMPORARY_REG2] == 2
574 && reg_map[TMP_REGISTER] > 7,
575 invalid_register_assignment_for_div_mul);
577 SLJIT_COMPILE_ASSERT(
578 reg_map[SLJIT_TEMPORARY_REG1] == 0
579 && reg_map[SLJIT_TEMPORARY_REG2] < 7
580 && reg_map[TMP_REGISTER] == 2,
581 invalid_register_assignment_for_div_mul);
583 compiler->mode32 = op & SLJIT_INT_OP;
587 if (op == SLJIT_UDIV) {
588 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
589 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
590 buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
592 buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
598 if (op == SLJIT_SDIV) {
599 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
600 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
603 /* CDQ instruction */
604 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
605 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
610 if (compiler->mode32) {
611 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
616 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
625 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
626 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
630 *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
633 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
635 size = (!compiler->mode32) ? 3 : 2;
637 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
641 if (!compiler->mode32)
642 *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
643 else if (op >= SLJIT_UDIV)
646 *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
648 if (!compiler->mode32)
651 *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
668 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
669 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
674 return SLJIT_SUCCESS;
677 #define ENCODE_PREFIX(prefix) \
679 code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
685 static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
686 int dst, sljit_w dstw,
687 int src, sljit_w srcw)
691 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
695 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
696 compiler->mode32 = 0;
699 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
700 return SLJIT_SUCCESS; /* Empty instruction. */
702 if (src & SLJIT_IMM) {
703 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
704 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
705 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
707 return emit_load_imm64(compiler, dst, srcw);
710 code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
713 return SLJIT_SUCCESS;
716 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
718 if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
719 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
720 if (reg_map[src] >= 4) {
721 SLJIT_ASSERT(dst_r == TMP_REGISTER);
722 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
729 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
730 else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) {
731 /* src, dst are registers. */
732 SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER);
733 if (reg_map[dst] < 4) {
735 EMIT_MOV(compiler, dst, 0, src, 0);
736 code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
739 *code = sign ? 0xbe : 0xb6;
743 EMIT_MOV(compiler, dst, 0, src, 0);
746 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
749 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
751 /* shr/sar reg, 24 */
756 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
758 *(code + 1) |= 0x4 << 3;
761 return SLJIT_SUCCESS;
765 /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
766 code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
769 *code = sign ? 0xbe : 0xb6;
772 if (dst & SLJIT_MEM) {
773 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
774 if (dst_r == TMP_REGISTER) {
775 /* Find a non-used register, whose reg_map[src] < 4. */
776 if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) {
777 if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4))
778 work_r = SLJIT_TEMPORARY_REG3;
780 work_r = SLJIT_TEMPORARY_REG2;
783 if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
784 work_r = SLJIT_TEMPORARY_REG1;
785 else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2)
786 work_r = SLJIT_TEMPORARY_REG3;
788 work_r = SLJIT_TEMPORARY_REG2;
791 if (work_r == SLJIT_TEMPORARY_REG1) {
792 ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
795 code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
800 code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
804 if (work_r == SLJIT_TEMPORARY_REG1) {
805 ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
808 code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
814 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
819 code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
825 return SLJIT_SUCCESS;
828 static int emit_mov_half(struct sljit_compiler *compiler, int sign,
829 int dst, sljit_w dstw,
830 int src, sljit_w srcw)
835 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
836 compiler->mode32 = 0;
839 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
840 return SLJIT_SUCCESS; /* Empty instruction. */
842 if (src & SLJIT_IMM) {
843 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
844 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
845 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
847 return emit_load_imm64(compiler, dst, srcw);
850 code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
853 return SLJIT_SUCCESS;
856 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
858 if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
861 code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
864 *code = sign ? 0xbf : 0xb7;
867 if (dst & SLJIT_MEM) {
868 code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
873 return SLJIT_SUCCESS;
876 static int emit_unary(struct sljit_compiler *compiler, int un_index,
877 int dst, sljit_w dstw,
878 int src, sljit_w srcw)
882 if (dst == SLJIT_UNUSED) {
883 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
884 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
887 *code |= (un_index) << 3;
888 return SLJIT_SUCCESS;
890 if (dst == src && dstw == srcw) {
891 /* Same input and output */
892 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
895 *code |= (un_index) << 3;
896 return SLJIT_SUCCESS;
898 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
899 EMIT_MOV(compiler, dst, 0, src, srcw);
900 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
903 *code |= (un_index) << 3;
904 return SLJIT_SUCCESS;
906 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
907 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
910 *code |= (un_index) << 3;
911 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
912 return SLJIT_SUCCESS;
915 static int emit_not_with_flags(struct sljit_compiler *compiler,
916 int dst, sljit_w dstw,
917 int src, sljit_w srcw)
921 if (dst == SLJIT_UNUSED) {
922 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
923 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
927 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
930 return SLJIT_SUCCESS;
932 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
933 EMIT_MOV(compiler, dst, 0, src, srcw);
934 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
938 code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
941 return SLJIT_SUCCESS;
943 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
944 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
948 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
951 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
952 return SLJIT_SUCCESS;
955 static int emit_clz(struct sljit_compiler *compiler, int op,
956 int dst, sljit_w dstw,
957 int src, sljit_w srcw)
962 SLJIT_UNUSED_ARG(op);
963 if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
964 /* Just set the zero flag. */
965 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
966 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
970 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
971 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0);
973 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
977 return SLJIT_SUCCESS;
980 if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
981 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
986 code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
991 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
992 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
995 /* Find an unused temporary register. */
996 if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
997 dst_r = SLJIT_TEMPORARY_REG1;
998 else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4))
999 dst_r = SLJIT_TEMPORARY_REG2;
1001 dst_r = SLJIT_TEMPORARY_REG3;
1002 EMIT_MOV(compiler, dst, dstw, dst_r, 0);
1004 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
1006 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2;
1007 compiler->mode32 = 0;
1008 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31);
1009 compiler->mode32 = op & SLJIT_INT_OP;
1012 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
1017 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1018 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
1020 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
1023 *(code + 1) |= 0x6 << 3;
1025 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1026 if (dst & SLJIT_MEM) {
1027 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
1032 if (dst & SLJIT_MEM)
1033 EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
1035 return SLJIT_SUCCESS;
1038 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
1039 int dst, sljit_w dstw,
1040 int src, sljit_w srcw)
1044 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1045 int dst_is_ereg = 0;
1046 int src_is_ereg = 0;
1048 #define src_is_ereg 0
1052 check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1054 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1055 compiler->mode32 = op & SLJIT_INT_OP;
1057 CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
1058 CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
1060 if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
1061 op = GET_OPCODE(op);
1062 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1063 compiler->mode32 = 0;
1066 SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
1067 if (op >= SLJIT_MOVU) {
1072 if (src & SLJIT_IMM) {
1075 srcw = (unsigned char)srcw;
1078 srcw = (signed char)srcw;
1081 srcw = (unsigned short)srcw;
1084 srcw = (signed short)srcw;
1086 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1088 srcw = (unsigned int)srcw;
1091 srcw = (signed int)srcw;
1095 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1096 if (SLJIT_UNLIKELY(dst_is_ereg))
1097 return emit_mov(compiler, dst, dstw, src, srcw);
1101 if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) {
1102 code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw);
1105 src &= SLJIT_MEM | 0xf;
1109 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1110 if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) {
1111 SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
1118 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1122 FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
1125 FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
1128 FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
1131 FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
1134 FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
1136 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1138 FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
1141 FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
1146 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1147 if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER)
1148 return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0);
1151 if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) {
1152 code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw);
1156 return SLJIT_SUCCESS;
1159 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1160 compiler->flags_saved = 0;
1162 switch (GET_OPCODE(op)) {
1164 if (SLJIT_UNLIKELY(op & SLJIT_SET_E))
1165 return emit_not_with_flags(compiler, dst, dstw, src, srcw);
1166 return emit_unary(compiler, 0x2, dst, dstw, src, srcw);
1169 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1170 FAIL_IF(emit_save_flags(compiler));
1171 return emit_unary(compiler, 0x3, dst, dstw, src, srcw);
1174 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1175 FAIL_IF(emit_save_flags(compiler));
1176 return emit_clz(compiler, op, dst, dstw, src, srcw);
1179 return SLJIT_SUCCESS;
1181 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1186 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1188 #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1189 if (IS_HALFWORD(immw) || compiler->mode32) { \
1190 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1192 *(code + 1) |= (_op_imm_); \
1195 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
1196 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
1198 *code = (_op_mr_); \
1201 #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1202 FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw))
1206 #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1207 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1209 *(code + 1) |= (_op_imm_);
1211 #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1212 FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
1216 static int emit_cum_binary(struct sljit_compiler *compiler,
1217 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1218 int dst, sljit_w dstw,
1219 int src1, sljit_w src1w,
1220 int src2, sljit_w src2w)
1224 if (dst == SLJIT_UNUSED) {
1225 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1226 if (src2 & SLJIT_IMM) {
1227 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1230 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1234 return SLJIT_SUCCESS;
1237 if (dst == src1 && dstw == src1w) {
1238 if (src2 & SLJIT_IMM) {
1239 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1240 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1242 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1244 BINARY_EAX_IMM(op_eax_imm, src2w);
1247 BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1250 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1251 code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1255 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) {
1256 /* Special exception for sljit_emit_cond_value. */
1257 code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1262 EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1263 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1267 return SLJIT_SUCCESS;
1270 /* Only for cumulative operations. */
1271 if (dst == src2 && dstw == src2w) {
1272 if (src1 & SLJIT_IMM) {
1273 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1274 if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1276 if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
1278 BINARY_EAX_IMM(op_eax_imm, src1w);
1281 BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
1284 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1285 code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
1289 else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1290 code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
1295 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1296 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1300 return SLJIT_SUCCESS;
1303 /* General version. */
1304 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1305 EMIT_MOV(compiler, dst, 0, src1, src1w);
1306 if (src2 & SLJIT_IMM) {
1307 BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1310 code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1316 /* This version requires less memory writing. */
1317 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1318 if (src2 & SLJIT_IMM) {
1319 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1322 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1326 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1329 return SLJIT_SUCCESS;
1332 static int emit_non_cum_binary(struct sljit_compiler *compiler,
1333 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1334 int dst, sljit_w dstw,
1335 int src1, sljit_w src1w,
1336 int src2, sljit_w src2w)
1340 if (dst == SLJIT_UNUSED) {
1341 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1342 if (src2 & SLJIT_IMM) {
1343 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1346 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1350 return SLJIT_SUCCESS;
1353 if (dst == src1 && dstw == src1w) {
1354 if (src2 & SLJIT_IMM) {
1355 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1356 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1358 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1360 BINARY_EAX_IMM(op_eax_imm, src2w);
1363 BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1366 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1367 code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1371 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1372 code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1377 EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1378 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1382 return SLJIT_SUCCESS;
1385 /* General version. */
1386 if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) {
1387 EMIT_MOV(compiler, dst, 0, src1, src1w);
1388 if (src2 & SLJIT_IMM) {
1389 BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1392 code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1398 /* This version requires less memory writing. */
1399 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1400 if (src2 & SLJIT_IMM) {
1401 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1404 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1408 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1411 return SLJIT_SUCCESS;
1414 static int emit_mul(struct sljit_compiler *compiler,
1415 int dst, sljit_w dstw,
1416 int src1, sljit_w src1w,
1417 int src2, sljit_w src2w)
1422 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1424 /* Register destination. */
1425 if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
1426 code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1431 else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
1432 code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
1437 else if (src1 & SLJIT_IMM) {
1438 if (src2 & SLJIT_IMM) {
1439 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
1444 if (src1w <= 127 && src1w >= -128) {
1445 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1448 code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1451 *code = (sljit_b)src1w;
1453 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1455 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1458 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1461 *(sljit_w*)code = src1w;
1464 else if (IS_HALFWORD(src1w)) {
1465 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1468 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1471 *(sljit_hw*)code = (sljit_hw)src1w;
1474 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1476 EMIT_MOV(compiler, dst_r, 0, src2, src2w);
1477 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1484 else if (src2 & SLJIT_IMM) {
1485 /* Note: src1 is NOT immediate. */
1487 if (src2w <= 127 && src2w >= -128) {
1488 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1491 code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1494 *code = (sljit_b)src2w;
1496 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1498 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1501 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1504 *(sljit_w*)code = src2w;
1507 else if (IS_HALFWORD(src2w)) {
1508 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1511 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1514 *(sljit_hw*)code = (sljit_hw)src2w;
1517 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1519 EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1520 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1528 /* Neither argument is immediate. */
1529 if (ADDRESSING_DEPENDS_ON(src2, dst_r))
1530 dst_r = TMP_REGISTER;
1531 EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1532 code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1538 if (dst_r == TMP_REGISTER)
1539 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1541 return SLJIT_SUCCESS;
1544 static int emit_lea_binary(struct sljit_compiler *compiler,
1545 int dst, sljit_w dstw,
1546 int src1, sljit_w src1w,
1547 int src2, sljit_w src2w)
1550 int dst_r, done = 0;
1552 /* These cases better be left to handled by normal way. */
1553 if (dst == src1 && dstw == src1w)
1554 return SLJIT_ERR_UNSUPPORTED;
1555 if (dst == src2 && dstw == src2w)
1556 return SLJIT_ERR_UNSUPPORTED;
1558 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1560 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1561 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1562 /* It is not possible to be both SLJIT_LOCALS_REG. */
1563 if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {
1564 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
1570 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1571 if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1572 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w);
1574 if (src2 & SLJIT_IMM) {
1575 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
1582 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1583 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1584 if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1585 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w);
1587 if (src1 & SLJIT_IMM) {
1588 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
1597 if (dst_r == TMP_REGISTER)
1598 return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
1599 return SLJIT_SUCCESS;
1601 return SLJIT_ERR_UNSUPPORTED;
1604 static int emit_cmp_binary(struct sljit_compiler *compiler,
1605 int src1, sljit_w src1w,
1606 int src2, sljit_w src2w)
1610 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1611 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1613 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1615 BINARY_EAX_IMM(0x3d, src2w);
1616 return SLJIT_SUCCESS;
1619 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1620 if (src2 & SLJIT_IMM) {
1621 BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
1624 code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1628 return SLJIT_SUCCESS;
1631 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
1632 code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1635 return SLJIT_SUCCESS;
1638 if (src2 & SLJIT_IMM) {
1639 if (src1 & SLJIT_IMM) {
1640 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1641 src1 = TMP_REGISTER;
1644 BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
1647 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1648 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1652 return SLJIT_SUCCESS;
1655 static int emit_test_binary(struct sljit_compiler *compiler,
1656 int src1, sljit_w src1w,
1657 int src2, sljit_w src2w)
1661 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1662 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1664 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1666 BINARY_EAX_IMM(0xa9, src2w);
1667 return SLJIT_SUCCESS;
1670 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1671 if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1673 if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
1675 BINARY_EAX_IMM(0xa9, src1w);
1676 return SLJIT_SUCCESS;
1679 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1680 if (src2 & SLJIT_IMM) {
1681 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1682 if (IS_HALFWORD(src2w) || compiler->mode32) {
1683 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1688 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1689 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
1694 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1700 code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1704 return SLJIT_SUCCESS;
1707 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1708 if (src1 & SLJIT_IMM) {
1709 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1710 if (IS_HALFWORD(src1w) || compiler->mode32) {
1711 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
1716 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
1717 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
1722 code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
1728 code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1732 return SLJIT_SUCCESS;
1735 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1736 if (src2 & SLJIT_IMM) {
1737 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1738 if (IS_HALFWORD(src2w) || compiler->mode32) {
1739 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1744 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1745 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
1750 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1756 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1760 return SLJIT_SUCCESS;
1763 static int emit_shift(struct sljit_compiler *compiler,
1765 int dst, sljit_w dstw,
1766 int src1, sljit_w src1w,
1767 int src2, sljit_w src2w)
1771 if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
1772 if (dst == src1 && dstw == src1w) {
1773 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
1776 return SLJIT_SUCCESS;
1778 if (dst == SLJIT_UNUSED) {
1779 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1780 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1783 return SLJIT_SUCCESS;
1785 if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
1786 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1787 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1790 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1791 return SLJIT_SUCCESS;
1793 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1794 EMIT_MOV(compiler, dst, 0, src1, src1w);
1795 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
1798 return SLJIT_SUCCESS;
1801 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1802 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1805 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1806 return SLJIT_SUCCESS;
1809 if (dst == SLJIT_PREF_SHIFT_REG) {
1810 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1811 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1812 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1815 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1817 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
1819 EMIT_MOV(compiler, dst, 0, src1, src1w);
1820 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
1821 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1822 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
1825 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1828 /* This case is really difficult, since ecx itself may used for
1829 addressing, and we must ensure to work even in that case. */
1830 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1831 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1832 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1834 /* [esp - 4] is reserved for eflags. */
1835 EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
1837 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1838 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1841 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1842 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1844 /* [esp - 4] is reserved for eflags. */
1845 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)));
1847 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1850 return SLJIT_SUCCESS;
1853 static int emit_shift_with_flags(struct sljit_compiler *compiler,
1854 sljit_ub mode, int set_flags,
1855 int dst, sljit_w dstw,
1856 int src1, sljit_w src1w,
1857 int src2, sljit_w src2w)
1859 /* The CPU does not set flags if the shift count is 0. */
1860 if (src2 & SLJIT_IMM) {
1861 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1862 if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
1863 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1865 if ((src2w & 0x1f) != 0)
1866 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1869 return emit_mov(compiler, dst, dstw, src1, src1w);
1870 /* OR dst, src, 0 */
1871 return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1872 dst, dstw, src1, src1w, SLJIT_IMM, 0);
1876 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1878 if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
1879 FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
1881 FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
1883 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
1884 return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
1885 return SLJIT_SUCCESS;
1888 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
1889 int dst, sljit_w dstw,
1890 int src1, sljit_w src1w,
1891 int src2, sljit_w src2w)
1894 check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1896 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1897 compiler->mode32 = op & SLJIT_INT_OP;
1899 CHECK_EXTRA_REGS(dst, dstw, (void)0);
1900 CHECK_EXTRA_REGS(src1, src1w, (void)0);
1901 CHECK_EXTRA_REGS(src2, src2w, (void)0);
1903 if (GET_OPCODE(op) >= SLJIT_MUL) {
1904 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1905 compiler->flags_saved = 0;
1906 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1907 FAIL_IF(emit_save_flags(compiler));
1910 switch (GET_OPCODE(op)) {
1912 if (!GET_FLAGS(op)) {
1913 if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
1914 return compiler->error;
1917 compiler->flags_saved = 0;
1918 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1919 FAIL_IF(emit_save_flags(compiler));
1920 return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
1921 dst, dstw, src1, src1w, src2, src2w);
1923 if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1924 FAIL_IF(emit_restore_flags(compiler, 1));
1925 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1926 FAIL_IF(emit_save_flags(compiler));
1927 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1928 compiler->flags_saved = 0;
1929 return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15,
1930 dst, dstw, src1, src1w, src2, src2w);
1932 if (!GET_FLAGS(op)) {
1933 if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
1934 return compiler->error;
1937 compiler->flags_saved = 0;
1938 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1939 FAIL_IF(emit_save_flags(compiler));
1940 if (dst == SLJIT_UNUSED)
1941 return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
1942 return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
1943 dst, dstw, src1, src1w, src2, src2w);
1945 if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1946 FAIL_IF(emit_restore_flags(compiler, 1));
1947 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1948 FAIL_IF(emit_save_flags(compiler));
1949 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1950 compiler->flags_saved = 0;
1951 return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d,
1952 dst, dstw, src1, src1w, src2, src2w);
1954 return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
1956 if (dst == SLJIT_UNUSED)
1957 return emit_test_binary(compiler, src1, src1w, src2, src2w);
1958 return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25,
1959 dst, dstw, src1, src1w, src2, src2w);
1961 return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1962 dst, dstw, src1, src1w, src2, src2w);
1964 return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1965 dst, dstw, src1, src1w, src2, src2w);
1967 return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
1968 dst, dstw, src1, src1w, src2, src2w);
1970 return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
1971 dst, dstw, src1, src1w, src2, src2w);
1973 return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
1974 dst, dstw, src1, src1w, src2, src2w);
1977 return SLJIT_SUCCESS;
1980 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
1982 check_sljit_get_register_index(reg);
1983 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1984 if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1985 || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
1988 return reg_map[reg];
1991 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
1992 void *instruction, int size)
1997 check_sljit_emit_op_custom(compiler, instruction, size);
1998 SLJIT_ASSERT(size > 0 && size < 16);
2000 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
2003 SLJIT_MEMMOVE(buf, instruction, size);
2004 return SLJIT_SUCCESS;
2007 /* --------------------------------------------------------------------- */
2008 /* Floating point operators */
2009 /* --------------------------------------------------------------------- */
2011 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2012 static int sse2_available = 0;
2015 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2017 /* Alignment + 2 * 16 bytes. */
2018 static sljit_i sse2_data[3 + 4 + 4];
2019 static sljit_i *sse2_buffer;
2021 static void init_compiler()
2023 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2027 sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
2029 sse2_buffer[1] = 0x80000000;
2030 sse2_buffer[4] = 0xffffffff;
2031 sse2_buffer[5] = 0x7fffffff;
2033 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2038 "movl $0x1, %%eax\n"
2044 : "%eax", "%ecx", "%edx"
2046 #elif defined(_MSC_VER) || defined(__BORLANDC__)
2056 #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
2058 sse2_available = (features >> 26) & 0x1;
2064 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2066 /* Always available. */
2070 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2072 static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
2073 int xmm1, int xmm2, sljit_w xmm2w)
2077 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2081 return SLJIT_SUCCESS;
2084 static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
2085 int xmm1, int xmm2, sljit_w xmm2w)
2089 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2093 return SLJIT_SUCCESS;
2096 static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
2097 int dst, int src, sljit_w srcw)
2099 return emit_sse2(compiler, 0x10, dst, src, srcw);
2102 static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
2103 int dst, sljit_w dstw, int src)
2105 return emit_sse2(compiler, 0x11, src, dst, dstw);
2108 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2109 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2111 static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
2113 int dst, sljit_w dstw,
2114 int src, sljit_w srcw)
2119 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2121 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2122 compiler->mode32 = 1;
2125 if (GET_OPCODE(op) == SLJIT_FCMP) {
2126 compiler->flags_saved = 0;
2127 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
2131 FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
2133 return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
2136 if (op == SLJIT_FMOV) {
2137 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
2138 return emit_sse2_load(compiler, dst, src, srcw);
2139 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
2140 return emit_sse2_store(compiler, dst, dstw, src);
2141 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
2142 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2145 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2148 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2152 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2157 FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
2161 FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
2165 if (dst_r == TMP_FREG)
2166 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2167 return SLJIT_SUCCESS;
2170 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2171 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2173 static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
2175 int dst, sljit_w dstw,
2176 int src1, sljit_w src1w,
2177 int src2, sljit_w src2w)
2182 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2184 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2185 compiler->mode32 = 1;
2188 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2191 ; /* Do nothing here. */
2192 else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
2193 /* Swap arguments. */
2197 else if (dst != src2)
2198 FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
2201 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2206 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2211 FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
2215 FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
2219 FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
2223 FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
2227 if (dst_r == TMP_FREG)
2228 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2229 return SLJIT_SUCCESS;
2234 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
2236 static int emit_fld(struct sljit_compiler *compiler,
2237 int src, sljit_w srcw)
2241 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2242 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2246 *buf = 0xc0 + src - 1;
2247 return SLJIT_SUCCESS;
2250 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2253 return SLJIT_SUCCESS;
2256 static int emit_fop(struct sljit_compiler *compiler,
2257 sljit_ub st_arg, sljit_ub st_arg2,
2258 sljit_ub m64fp_arg, sljit_ub m64fp_arg2,
2259 int src, sljit_w srcw)
2263 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2264 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2268 *buf = st_arg2 + src;
2269 return SLJIT_SUCCESS;
2272 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2276 return SLJIT_SUCCESS;
2279 static int emit_fop_regs(struct sljit_compiler *compiler,
2280 sljit_ub st_arg, sljit_ub st_arg2,
2285 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2289 *buf = st_arg2 + src;
2290 return SLJIT_SUCCESS;
2293 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2294 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2296 static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
2298 int dst, sljit_w dstw,
2299 int src, sljit_w srcw)
2301 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2306 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2308 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2309 compiler->mode32 = 1;
2312 if (GET_OPCODE(op) == SLJIT_FCMP) {
2313 compiler->flags_saved = 0;
2314 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2315 FAIL_IF(emit_fld(compiler, dst, dstw));
2316 FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw));
2319 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2320 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2325 /* Note: lahf is not supported on all x86-64 architectures. */
2327 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2329 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2330 FAIL_IF(emit_fld(compiler, dst, dstw));
2331 FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2333 FAIL_IF(emit_fld(compiler, src, srcw));
2334 FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw));
2335 FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2336 FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0));
2339 return SLJIT_SUCCESS;
2342 FAIL_IF(emit_fld(compiler, src, srcw));
2346 FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
2349 FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
2353 FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2355 return SLJIT_SUCCESS;
2358 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2359 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2361 static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
2363 int dst, sljit_w dstw,
2364 int src1, sljit_w src1w,
2365 int src2, sljit_w src2w)
2368 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2370 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2371 compiler->mode32 = 1;
2374 if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
2375 FAIL_IF(emit_fld(compiler, src2, src2w));
2379 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
2382 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
2385 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
2388 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
2391 return SLJIT_SUCCESS;
2394 FAIL_IF(emit_fld(compiler, src1, src1w));
2396 if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
2399 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
2402 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
2405 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
2408 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
2411 return SLJIT_SUCCESS;
2416 FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
2419 FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
2422 FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
2425 FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
2429 FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2431 return SLJIT_SUCCESS;
2435 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2437 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2438 int dst, sljit_w dstw,
2439 int src, sljit_w srcw)
2442 return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
2444 return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
2447 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2448 int dst, sljit_w dstw,
2449 int src1, sljit_w src1w,
2450 int src2, sljit_w src2w)
2453 return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2455 return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2460 /* --------------------------------------------------------------------- */
2461 /* Conditional instructions */
2462 /* --------------------------------------------------------------------- */
2464 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2467 struct sljit_label *label;
2470 check_sljit_emit_label(compiler);
2472 /* We should restore the flags before the label,
2473 since other taken jumps has their own flags as well. */
2474 if (SLJIT_UNLIKELY(compiler->flags_saved))
2475 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2477 if (compiler->last_label && compiler->last_label->size == compiler->size)
2478 return compiler->last_label;
2480 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2481 PTR_FAIL_IF(!label);
2482 set_label(label, compiler);
2484 buf = (sljit_ub*)ensure_buf(compiler, 2);
2493 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2496 struct sljit_jump *jump;
2499 check_sljit_emit_jump(compiler, type);
2501 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2502 if ((type & 0xff) <= SLJIT_JUMP)
2503 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2504 compiler->flags_saved = 0;
2507 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2508 PTR_FAIL_IF_NULL(jump);
2509 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2512 if (type >= SLJIT_CALL1)
2513 PTR_FAIL_IF(call_with_args(compiler, type));
2515 /* Worst case size. */
2516 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2517 compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
2519 compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
2522 buf = (sljit_ub*)ensure_buf(compiler, 2);
2523 PTR_FAIL_IF_NULL(buf);
2530 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2533 struct sljit_jump *jump;
2536 check_sljit_emit_ijump(compiler, type, src, srcw);
2538 CHECK_EXTRA_REGS(src, srcw, (void)0);
2539 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2540 if (type <= SLJIT_JUMP)
2541 FAIL_IF(emit_restore_flags(compiler, 0));
2542 compiler->flags_saved = 0;
2545 if (type >= SLJIT_CALL1) {
2546 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2547 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
2548 if (src == SLJIT_TEMPORARY_REG3) {
2549 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2552 if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
2554 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2558 srcw += sizeof(sljit_w);
2561 if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
2563 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2567 srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
2571 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
2572 if (src == SLJIT_TEMPORARY_REG3) {
2573 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2577 FAIL_IF(call_with_args(compiler, type));
2580 if (src == SLJIT_IMM) {
2581 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2583 set_jump(jump, compiler, JUMP_ADDR);
2584 jump->u.target = srcw;
2586 /* Worst case size. */
2587 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2588 compiler->size += 5;
2590 compiler->size += 10 + 3;
2593 code = (sljit_ub*)ensure_buf(compiler, 2);
2600 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2601 /* REX_W is not necessary (src is not immediate). */
2602 compiler->mode32 = 1;
2604 code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2607 *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2609 return SLJIT_SUCCESS;
2612 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2615 sljit_ub cond_set = 0;
2616 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2621 check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
2623 if (dst == SLJIT_UNUSED)
2624 return SLJIT_SUCCESS;
2626 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2627 if (SLJIT_UNLIKELY(compiler->flags_saved))
2628 FAIL_IF(emit_restore_flags(compiler, 0));
2632 case SLJIT_C_FLOAT_EQUAL:
2636 case SLJIT_C_NOT_EQUAL:
2637 case SLJIT_C_FLOAT_NOT_EQUAL:
2642 case SLJIT_C_FLOAT_LESS:
2646 case SLJIT_C_GREATER_EQUAL:
2647 case SLJIT_C_FLOAT_GREATER_EQUAL:
2651 case SLJIT_C_GREATER:
2652 case SLJIT_C_FLOAT_GREATER:
2656 case SLJIT_C_LESS_EQUAL:
2657 case SLJIT_C_FLOAT_LESS_EQUAL:
2661 case SLJIT_C_SIG_LESS:
2665 case SLJIT_C_SIG_GREATER_EQUAL:
2669 case SLJIT_C_SIG_GREATER:
2673 case SLJIT_C_SIG_LESS_EQUAL:
2677 case SLJIT_C_OVERFLOW:
2678 case SLJIT_C_MUL_OVERFLOW:
2682 case SLJIT_C_NOT_OVERFLOW:
2683 case SLJIT_C_MUL_NOT_OVERFLOW:
2687 case SLJIT_C_FLOAT_NAN:
2691 case SLJIT_C_FLOAT_NOT_NAN:
2696 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2697 reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2699 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
2702 /* Set low register to conditional flag. */
2703 *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
2706 *buf++ = 0xC0 | reg_lmap[reg];
2707 *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
2710 *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
2712 if (reg == TMP_REGISTER) {
2713 if (op == SLJIT_MOV) {
2714 compiler->mode32 = 0;
2715 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
2718 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2719 compiler->skip_checks = 1;
2721 return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2725 if (op == SLJIT_MOV) {
2726 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2727 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2730 /* Set low byte to conditional flag. */
2733 *buf++ = 0xC0 | reg_map[dst];
2737 *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
2740 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2742 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2745 /* Set al to conditional flag. */
2752 if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
2753 *buf = 0xC0 | (reg_map[dst] << 3);
2756 EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
2759 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2763 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2764 EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
2765 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2771 *buf++ = 0xC0 | reg_map[dst];
2774 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2776 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
2778 INC_SIZE(3 + 3 + 1);
2779 /* Set al to conditional flag. */
2788 *buf++ = 0x90 + reg_map[TMP_REGISTER];
2790 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2791 compiler->skip_checks = 1;
2793 return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2797 return SLJIT_SUCCESS;
2800 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
2803 struct sljit_const *const_;
2804 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2809 check_sljit_emit_const(compiler, dst, dstw, init_value);
2811 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2813 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2814 PTR_FAIL_IF(!const_);
2815 set_const(const_, compiler);
2817 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2818 compiler->mode32 = 0;
2819 reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2821 if (emit_load_imm64(compiler, reg, init_value))
2824 if (dst == SLJIT_UNUSED)
2827 if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
2831 buf = (sljit_ub*)ensure_buf(compiler, 2);
2837 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2838 if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
2839 if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
2846 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2848 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2849 *(sljit_w*)addr = new_addr - (addr + 4);
2851 *(sljit_uw*)addr = new_addr;
2855 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2857 *(sljit_w*)addr = new_constant;