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>