Annotation of embedaddon/pcre/sljit/sljitNativeX86_common.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Stack-less Just-In-Time compiler
3: *
1.1.1.2 ! misho 4: * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
1.1 misho 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: {
1.1.1.2 ! misho 29: return "x86" SLJIT_CPUINFO;
1.1 misho 30: }
31:
32: /*
33: 32b register indexes:
34: 0 - EAX
35: 1 - ECX
36: 2 - EDX
37: 3 - EBX
38: 4 - none
39: 5 - EBP
40: 6 - ESI
41: 7 - EDI
42: */
43:
44: /*
45: 64b register indexes:
46: 0 - RAX
47: 1 - RCX
48: 2 - RDX
49: 3 - RBX
50: 4 - none
51: 5 - RBP
52: 6 - RSI
53: 7 - RDI
54: 8 - R8 - From now on REX prefix is required
55: 9 - R9
56: 10 - R10
57: 11 - R11
58: 12 - R12
59: 13 - R13
60: 14 - R14
61: 15 - R15
62: */
63:
64: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
65:
66: /* Last register + 1. */
67: #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
68:
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
71: };
72:
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); \
77: do; \
78: } \
1.1.1.2 ! misho 79: else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
! 80: w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
1.1 misho 81: p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
82: do; \
83: }
84:
85: #else /* SLJIT_CONFIG_X86_32 */
86:
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)
91:
92: /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
93: Note: avoid to use r12 and r13 for memory addessing
1.1.1.2 ! misho 94: therefore r12 is better for SAVED_EREG than SAVED_REG. */
1.1 misho 95: #ifndef _WIN64
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
99: };
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
103: };
104: #else
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
108: };
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
112: };
113: #endif
114:
115: #define REX_W 0x48
116: #define REX_R 0x44
117: #define REX_X 0x42
118: #define REX_B 0x41
119: #define REX 0x40
120:
121: typedef unsigned int sljit_uhw;
122: typedef int sljit_hw;
123:
124: #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
125: #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
126:
127: #define CHECK_EXTRA_REGS(p, w, do)
128:
129: #endif /* SLJIT_CONFIG_X86_32 */
130:
131: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
132: #define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
133: #endif
134:
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
143:
144: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
145: #define EX86_PREF_F2 0x0800
146: #define EX86_SSE2 0x1000
147: #endif
148:
149: #define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
150: #define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
151:
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)
156: /* r32, r/m32 */
157: #define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
158:
159: static sljit_ub get_jump_code(int type)
160: {
161: switch (type) {
162: case SLJIT_C_EQUAL:
163: case SLJIT_C_FLOAT_EQUAL:
164: return 0x84;
165:
166: case SLJIT_C_NOT_EQUAL:
167: case SLJIT_C_FLOAT_NOT_EQUAL:
168: return 0x85;
169:
170: case SLJIT_C_LESS:
171: case SLJIT_C_FLOAT_LESS:
172: return 0x82;
173:
174: case SLJIT_C_GREATER_EQUAL:
175: case SLJIT_C_FLOAT_GREATER_EQUAL:
176: return 0x83;
177:
178: case SLJIT_C_GREATER:
179: case SLJIT_C_FLOAT_GREATER:
180: return 0x87;
181:
182: case SLJIT_C_LESS_EQUAL:
183: case SLJIT_C_FLOAT_LESS_EQUAL:
184: return 0x86;
185:
186: case SLJIT_C_SIG_LESS:
187: return 0x8c;
188:
189: case SLJIT_C_SIG_GREATER_EQUAL:
190: return 0x8d;
191:
192: case SLJIT_C_SIG_GREATER:
193: return 0x8f;
194:
195: case SLJIT_C_SIG_LESS_EQUAL:
196: return 0x8e;
197:
198: case SLJIT_C_OVERFLOW:
199: case SLJIT_C_MUL_OVERFLOW:
200: return 0x80;
201:
202: case SLJIT_C_NOT_OVERFLOW:
203: case SLJIT_C_MUL_NOT_OVERFLOW:
204: return 0x81;
205:
206: case SLJIT_C_FLOAT_NAN:
207: return 0x8a;
208:
209: case SLJIT_C_FLOAT_NOT_NAN:
210: return 0x8b;
211: }
212: return 0;
213: }
214:
215: static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
216:
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);
219: #endif
220:
221: static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
222: {
223: int short_jump;
224: sljit_uw label_addr;
225:
226: if (jump->flags & JUMP_LABEL)
227: label_addr = (sljit_uw)(code + jump->u.label->size);
228: else
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;
231:
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);
235: #endif
236:
237: if (type == SLJIT_JUMP) {
238: if (short_jump)
239: *code_ptr++ = 0xeb;
240: else
241: *code_ptr++ = 0xe9;
242: jump->addr++;
243: }
244: else if (type >= SLJIT_FAST_CALL) {
245: short_jump = 0;
246: *code_ptr++ = 0xe8;
247: jump->addr++;
248: }
249: else if (short_jump) {
250: *code_ptr++ = get_jump_code(type) - 0x10;
251: jump->addr++;
252: }
253: else {
254: *code_ptr++ = 0x0f;
255: *code_ptr++ = get_jump_code(type);
256: jump->addr += 2;
257: }
258:
259: if (short_jump) {
260: jump->flags |= PATCH_MB;
261: code_ptr += sizeof(sljit_b);
262: } else {
263: jump->flags |= PATCH_MW;
264: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
265: code_ptr += sizeof(sljit_w);
266: #else
267: code_ptr += sizeof(sljit_hw);
268: #endif
269: }
270:
271: return code_ptr;
272: }
273:
274: SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
275: {
276: struct sljit_memory_fragment *buf;
277: sljit_ub *code;
278: sljit_ub *code_ptr;
279: sljit_ub *buf_ptr;
280: sljit_ub *buf_end;
281: sljit_ub len;
282:
283: struct sljit_label *label;
284: struct sljit_jump *jump;
285: struct sljit_const *const_;
286:
287: CHECK_ERROR_PTR();
288: check_sljit_generate_code(compiler);
289: reverse_buf(compiler);
290:
291: /* Second code generation pass. */
292: code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
293: PTR_FAIL_WITH_EXEC_IF(code);
294: buf = compiler->buf;
295:
296: code_ptr = code;
297: label = compiler->labels;
298: jump = compiler->jumps;
299: const_ = compiler->consts;
300: do {
301: buf_ptr = buf->memory;
302: buf_end = buf_ptr + buf->used_size;
303: do {
304: len = *buf_ptr++;
305: if (len > 0) {
306: /* The code is already generated. */
307: SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
308: code_ptr += len;
309: buf_ptr += len;
310: }
311: else {
312: if (*buf_ptr >= 4) {
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);
316: else
317: code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
318: jump = jump->next;
319: }
320: else if (*buf_ptr == 0) {
321: label->addr = (sljit_uw)code_ptr;
322: label->size = code_ptr - code;
323: label = label->next;
324: }
325: else if (*buf_ptr == 1) {
326: const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
327: const_ = const_->next;
328: }
329: else {
330: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
331: *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
332: buf_ptr++;
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;
336: #else
337: code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
338: buf_ptr += sizeof(sljit_w);
339: #endif
340: }
341: buf_ptr++;
342: }
343: } while (buf_ptr < buf_end);
344: SLJIT_ASSERT(buf_ptr == buf_end);
345: buf = buf->next;
346: } while (buf);
347:
348: SLJIT_ASSERT(!label);
349: SLJIT_ASSERT(!jump);
350: SLJIT_ASSERT(!const_);
351:
352: jump = compiler->jumps;
353: while (jump) {
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)));
361: #else
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)));
364: #endif
365: }
366: else {
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)));
369: #else
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)));
372: #endif
373: }
374: }
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;
378: #endif
379:
380: jump = jump->next;
381: }
382:
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;
387: return (void*)code;
388: }
389:
390: /* --------------------------------------------------------------------- */
391: /* Operators */
392: /* --------------------------------------------------------------------- */
393:
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);
399:
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);
405:
406: static int emit_mov(struct sljit_compiler *compiler,
407: int dst, sljit_w dstw,
408: int src, sljit_w srcw);
409:
410: static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
411: {
412: sljit_ub *buf;
413:
414: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
415: buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
416: FAIL_IF(!buf);
417: INC_SIZE(5);
418: *buf++ = 0x9c; /* pushfd */
419: #else
420: buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
421: FAIL_IF(!buf);
422: INC_SIZE(6);
423: *buf++ = 0x9c; /* pushfq */
424: *buf++ = 0x48;
425: #endif
426: *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
427: *buf++ = 0x64;
428: *buf++ = 0x24;
429: *buf++ = sizeof(sljit_w);
430: compiler->flags_saved = 1;
431: return SLJIT_SUCCESS;
432: }
433:
434: static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
435: {
436: sljit_ub *buf;
437:
438: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
439: buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
440: FAIL_IF(!buf);
441: INC_SIZE(5);
442: #else
443: buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
444: FAIL_IF(!buf);
445: INC_SIZE(6);
446: *buf++ = 0x48;
447: #endif
448: *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
449: *buf++ = 0x64;
450: *buf++ = 0x24;
451: *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
452: *buf++ = 0x9d; /* popfd / popfq */
453: compiler->flags_saved = keep_flags;
454: return SLJIT_SUCCESS;
455: }
456:
457: #ifdef _WIN32
458: #include <malloc.h>
459:
460: static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
461: {
462: /* Workaround for calling _chkstk. */
463: alloca(local_size);
464: }
465: #endif
466:
467: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
468: #include "sljitNativeX86_32.c"
469: #else
470: #include "sljitNativeX86_64.c"
471: #endif
472:
473: static int emit_mov(struct sljit_compiler *compiler,
474: int dst, sljit_w dstw,
475: int src, sljit_w srcw)
476: {
477: sljit_ub* code;
478:
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);
483: FAIL_IF(!code);
484: *code = 0x8b;
485: }
486: return SLJIT_SUCCESS;
487: }
488: if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
489: code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
490: FAIL_IF(!code);
491: *code = 0x89;
492: return SLJIT_SUCCESS;
493: }
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);
498: #else
499: if (!compiler->mode32) {
500: if (NOT_HALFWORD(srcw))
501: return emit_load_imm64(compiler, dst, srcw);
502: }
503: else
504: return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
505: #endif
506: }
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);
511: FAIL_IF(!code);
512: *code = 0x89;
513: return SLJIT_SUCCESS;
514: }
515: #endif
516: code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
517: FAIL_IF(!code);
518: *code = 0xc7;
519: return SLJIT_SUCCESS;
520: }
521: if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
522: code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
523: FAIL_IF(!code);
524: *code = 0x8b;
525: return SLJIT_SUCCESS;
526: }
527:
528: /* Memory to memory move. Requires two instruction. */
529: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
530: FAIL_IF(!code);
531: *code = 0x8b;
532: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
533: FAIL_IF(!code);
534: *code = 0x89;
535: return SLJIT_SUCCESS;
536: }
537:
538: #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
539: FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
540:
1.1.1.2 ! misho 541: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
! 542: {
! 543: sljit_ub *buf;
! 544: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
! 545: int size;
! 546: #endif
! 547:
! 548: CHECK_ERROR();
! 549: check_sljit_emit_op0(compiler, op);
! 550:
! 551: switch (GET_OPCODE(op)) {
! 552: case SLJIT_BREAKPOINT:
! 553: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 554: FAIL_IF(!buf);
! 555: INC_SIZE(1);
! 556: *buf = 0xcc;
! 557: break;
! 558: case SLJIT_NOP:
! 559: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 560: FAIL_IF(!buf);
! 561: INC_SIZE(1);
! 562: *buf = 0x90;
! 563: break;
! 564: case SLJIT_UMUL:
! 565: case SLJIT_SMUL:
! 566: case SLJIT_UDIV:
! 567: case SLJIT_SDIV:
! 568: compiler->flags_saved = 0;
! 569: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
! 570: #ifdef _WIN64
! 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);
! 576: #else
! 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);
! 582: #endif
! 583: compiler->mode32 = op & SLJIT_INT_OP;
! 584: #endif
! 585:
! 586: op = GET_OPCODE(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);
! 591: #else
! 592: buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
! 593: #endif
! 594: FAIL_IF(!buf);
! 595: *buf = 0x33;
! 596: }
! 597:
! 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);
! 601: #endif
! 602:
! 603: /* CDQ instruction */
! 604: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
! 605: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 606: FAIL_IF(!buf);
! 607: INC_SIZE(1);
! 608: *buf = 0x99;
! 609: #else
! 610: if (compiler->mode32) {
! 611: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 612: FAIL_IF(!buf);
! 613: INC_SIZE(1);
! 614: *buf = 0x99;
! 615: } else {
! 616: buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
! 617: FAIL_IF(!buf);
! 618: INC_SIZE(2);
! 619: *buf++ = REX_W;
! 620: *buf = 0x99;
! 621: }
! 622: #endif
! 623: }
! 624:
! 625: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
! 626: buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
! 627: FAIL_IF(!buf);
! 628: INC_SIZE(2);
! 629: *buf++ = 0xf7;
! 630: *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
! 631: #else
! 632: #ifdef _WIN64
! 633: size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
! 634: #else
! 635: size = (!compiler->mode32) ? 3 : 2;
! 636: #endif
! 637: buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
! 638: FAIL_IF(!buf);
! 639: INC_SIZE(size);
! 640: #ifdef _WIN64
! 641: if (!compiler->mode32)
! 642: *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
! 643: else if (op >= SLJIT_UDIV)
! 644: *buf++ = REX_B;
! 645: *buf++ = 0xf7;
! 646: *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
! 647: #else
! 648: if (!compiler->mode32)
! 649: *buf++ = REX_W;
! 650: *buf++ = 0xf7;
! 651: *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
! 652: #endif
! 653: #endif
! 654: switch (op) {
! 655: case SLJIT_UMUL:
! 656: *buf |= 4 << 3;
! 657: break;
! 658: case SLJIT_SMUL:
! 659: *buf |= 5 << 3;
! 660: break;
! 661: case SLJIT_UDIV:
! 662: *buf |= 6 << 3;
! 663: break;
! 664: case SLJIT_SDIV:
! 665: *buf |= 7 << 3;
! 666: break;
! 667: }
! 668: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
! 669: EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
! 670: #endif
! 671: break;
! 672: }
! 673:
! 674: return SLJIT_SUCCESS;
! 675: }
! 676:
1.1 misho 677: #define ENCODE_PREFIX(prefix) \
678: do { \
679: code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
680: FAIL_IF(!code); \
681: INC_CSIZE(1); \
682: *code = (prefix); \
683: } while (0)
684:
685: static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
686: int dst, sljit_w dstw,
687: int src, sljit_w srcw)
688: {
689: sljit_ub* code;
690: int dst_r;
691: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
692: int work_r;
693: #endif
694:
695: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
696: compiler->mode32 = 0;
697: #endif
698:
699: if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
700: return SLJIT_SUCCESS; /* Empty instruction. */
701:
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);
706: #else
707: return emit_load_imm64(compiler, dst, srcw);
708: #endif
709: }
710: code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
711: FAIL_IF(!code);
712: *code = 0xc6;
713: return SLJIT_SUCCESS;
714: }
715:
716: dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
717:
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);
723: } else
724: dst_r = src;
725: #else
726: dst_r = src;
727: #endif
728: }
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) {
734: if (dst != src)
735: EMIT_MOV(compiler, dst, 0, src, 0);
736: code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
737: FAIL_IF(!code);
738: *code++ = 0x0f;
739: *code = sign ? 0xbe : 0xb6;
740: }
741: else {
742: if (dst != src)
743: EMIT_MOV(compiler, dst, 0, src, 0);
744: if (sign) {
745: /* shl reg, 24 */
746: code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
747: FAIL_IF(!code);
748: *code |= 0x4 << 3;
749: code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
750: FAIL_IF(!code);
751: /* shr/sar reg, 24 */
752: *code |= 0x7 << 3;
753: }
754: else {
755: /* and dst, 0xff */
756: code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
757: FAIL_IF(!code);
758: *(code + 1) |= 0x4 << 3;
759: }
760: }
761: return SLJIT_SUCCESS;
762: }
763: #endif
764: else {
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);
767: FAIL_IF(!code);
768: *code++ = 0x0f;
769: *code = sign ? 0xbe : 0xb6;
770: }
771:
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;
779: else
780: work_r = SLJIT_TEMPORARY_REG2;
781: }
782: else {
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;
787: else
788: work_r = SLJIT_TEMPORARY_REG2;
789: }
790:
791: if (work_r == SLJIT_TEMPORARY_REG1) {
792: ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
793: }
794: else {
795: code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
796: FAIL_IF(!code);
797: *code = 0x87;
798: }
799:
800: code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
801: FAIL_IF(!code);
802: *code = 0x88;
803:
804: if (work_r == SLJIT_TEMPORARY_REG1) {
805: ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
806: }
807: else {
808: code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
809: FAIL_IF(!code);
810: *code = 0x87;
811: }
812: }
813: else {
814: code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
815: FAIL_IF(!code);
816: *code = 0x88;
817: }
818: #else
819: code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
820: FAIL_IF(!code);
821: *code = 0x88;
822: #endif
823: }
824:
825: return SLJIT_SUCCESS;
826: }
827:
828: static int emit_mov_half(struct sljit_compiler *compiler, int sign,
829: int dst, sljit_w dstw,
830: int src, sljit_w srcw)
831: {
832: sljit_ub* code;
833: int dst_r;
834:
835: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
836: compiler->mode32 = 0;
837: #endif
838:
839: if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
840: return SLJIT_SUCCESS; /* Empty instruction. */
841:
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);
846: #else
847: return emit_load_imm64(compiler, dst, srcw);
848: #endif
849: }
850: code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
851: FAIL_IF(!code);
852: *code = 0xc7;
853: return SLJIT_SUCCESS;
854: }
855:
856: dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
857:
858: if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
859: dst_r = src;
860: else {
861: code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
862: FAIL_IF(!code);
863: *code++ = 0x0f;
864: *code = sign ? 0xbf : 0xb7;
865: }
866:
867: if (dst & SLJIT_MEM) {
868: code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
869: FAIL_IF(!code);
870: *code = 0x89;
871: }
872:
873: return SLJIT_SUCCESS;
874: }
875:
876: static int emit_unary(struct sljit_compiler *compiler, int un_index,
877: int dst, sljit_w dstw,
878: int src, sljit_w srcw)
879: {
880: sljit_ub* code;
881:
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);
885: FAIL_IF(!code);
886: *code++ = 0xf7;
887: *code |= (un_index) << 3;
888: return SLJIT_SUCCESS;
889: }
890: if (dst == src && dstw == srcw) {
891: /* Same input and output */
892: code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
893: FAIL_IF(!code);
894: *code++ = 0xf7;
895: *code |= (un_index) << 3;
896: return SLJIT_SUCCESS;
897: }
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);
901: FAIL_IF(!code);
902: *code++ = 0xf7;
903: *code |= (un_index) << 3;
904: return SLJIT_SUCCESS;
905: }
906: EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
907: code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
908: FAIL_IF(!code);
909: *code++ = 0xf7;
910: *code |= (un_index) << 3;
911: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
912: return SLJIT_SUCCESS;
913: }
914:
915: static int emit_not_with_flags(struct sljit_compiler *compiler,
916: int dst, sljit_w dstw,
917: int src, sljit_w srcw)
918: {
919: sljit_ub* code;
920:
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);
924: FAIL_IF(!code);
925: *code++ = 0xf7;
926: *code |= 0x2 << 3;
927: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
928: FAIL_IF(!code);
929: *code = 0x0b;
930: return SLJIT_SUCCESS;
931: }
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);
935: FAIL_IF(!code);
936: *code++ = 0xf7;
937: *code |= 0x2 << 3;
938: code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
939: FAIL_IF(!code);
940: *code = 0x0b;
941: return SLJIT_SUCCESS;
942: }
943: EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
944: code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
945: FAIL_IF(!code);
946: *code++ = 0xf7;
947: *code |= 0x2 << 3;
948: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
949: FAIL_IF(!code);
950: *code = 0x0b;
951: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
952: return SLJIT_SUCCESS;
953: }
954:
955: static int emit_clz(struct sljit_compiler *compiler, int op,
956: int dst, sljit_w dstw,
957: int src, sljit_w srcw)
958: {
959: sljit_ub* code;
960: int dst_r;
961:
1.1.1.2 ! misho 962: SLJIT_UNUSED_ARG(op);
1.1 misho 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);
967: FAIL_IF(!code);
968: *code++ = 0xf7;
969: *code |= 0x2 << 3;
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);
972: #else
973: code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
974: #endif
975: FAIL_IF(!code);
976: *code |= 0x5 << 3;
977: return SLJIT_SUCCESS;
978: }
979:
980: if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
981: EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
982: src = TMP_REGISTER;
983: srcw = 0;
984: }
985:
986: code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
987: FAIL_IF(!code);
988: *code++ = 0x0f;
989: *code = 0xbd;
990:
991: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
992: if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
993: dst_r = dst;
994: else {
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;
1000: else
1001: dst_r = SLJIT_TEMPORARY_REG3;
1002: EMIT_MOV(compiler, dst, dstw, dst_r, 0);
1003: }
1004: EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
1005: #else
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;
1010: #endif
1011:
1012: code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
1013: FAIL_IF(!code);
1014: *code++ = 0x0f;
1015: *code = 0x45;
1016:
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);
1019: #else
1020: code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
1021: #endif
1022: FAIL_IF(!code);
1023: *(code + 1) |= 0x6 << 3;
1024:
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);
1028: FAIL_IF(!code);
1029: *code = 0x87;
1030: }
1031: #else
1032: if (dst & SLJIT_MEM)
1033: EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
1034: #endif
1035: return SLJIT_SUCCESS;
1036: }
1037:
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)
1041: {
1042: sljit_ub* code;
1043: int update = 0;
1044: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1045: int dst_is_ereg = 0;
1046: int src_is_ereg = 0;
1047: #else
1048: #define src_is_ereg 0
1049: #endif
1050:
1051: CHECK_ERROR();
1052: check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1053:
1054: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1055: compiler->mode32 = op & SLJIT_INT_OP;
1056: #endif
1057: CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
1058: CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
1059:
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;
1064: #endif
1065:
1066: SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
1067: if (op >= SLJIT_MOVU) {
1068: update = 1;
1069: op -= 7;
1070: }
1071:
1072: if (src & SLJIT_IMM) {
1073: switch (op) {
1074: case SLJIT_MOV_UB:
1075: srcw = (unsigned char)srcw;
1076: break;
1077: case SLJIT_MOV_SB:
1078: srcw = (signed char)srcw;
1079: break;
1080: case SLJIT_MOV_UH:
1081: srcw = (unsigned short)srcw;
1082: break;
1083: case SLJIT_MOV_SH:
1084: srcw = (signed short)srcw;
1085: break;
1086: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1087: case SLJIT_MOV_UI:
1088: srcw = (unsigned int)srcw;
1089: break;
1090: case SLJIT_MOV_SI:
1091: srcw = (signed int)srcw;
1092: break;
1093: #endif
1094: }
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);
1098: #endif
1099: }
1100:
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);
1103: FAIL_IF(!code);
1104: *code = 0x8d;
1105: src &= SLJIT_MEM | 0xf;
1106: srcw = 0;
1107: }
1108:
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));
1112: dst = TMP_REGISTER;
1113: }
1114: #endif
1115:
1116: switch (op) {
1117: case SLJIT_MOV:
1118: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1119: case SLJIT_MOV_UI:
1120: case SLJIT_MOV_SI:
1121: #endif
1122: FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
1123: break;
1124: case SLJIT_MOV_UB:
1125: FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
1126: break;
1127: case SLJIT_MOV_SB:
1128: FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
1129: break;
1130: case SLJIT_MOV_UH:
1131: FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
1132: break;
1133: case SLJIT_MOV_SH:
1134: FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
1135: break;
1136: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1137: case SLJIT_MOV_UI:
1138: FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
1139: break;
1140: case SLJIT_MOV_SI:
1141: FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
1142: break;
1143: #endif
1144: }
1145:
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);
1149: #endif
1150:
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);
1153: FAIL_IF(!code);
1154: *code = 0x8d;
1155: }
1156: return SLJIT_SUCCESS;
1157: }
1158:
1159: if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1160: compiler->flags_saved = 0;
1161:
1162: switch (GET_OPCODE(op)) {
1163: case SLJIT_NOT:
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);
1167:
1168: case SLJIT_NEG:
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);
1172:
1173: case SLJIT_CLZ:
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);
1177: }
1178:
1179: return SLJIT_SUCCESS;
1180:
1181: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1182: #undef src_is_ereg
1183: #endif
1184: }
1185:
1186: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1187:
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); \
1191: FAIL_IF(!code); \
1192: *(code + 1) |= (_op_imm_); \
1193: } \
1194: else { \
1195: FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
1196: code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
1197: FAIL_IF(!code); \
1198: *code = (_op_mr_); \
1199: }
1200:
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))
1203:
1204: #else
1205:
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); \
1208: FAIL_IF(!code); \
1209: *(code + 1) |= (_op_imm_);
1210:
1211: #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1212: FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
1213:
1214: #endif
1215:
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)
1221: {
1222: sljit_ub* code;
1223:
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);
1228: }
1229: else {
1230: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1231: FAIL_IF(!code);
1232: *code = op_rm;
1233: }
1234: return SLJIT_SUCCESS;
1235: }
1236:
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))) {
1241: #else
1242: if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1243: #endif
1244: BINARY_EAX_IMM(op_eax_imm, src2w);
1245: }
1246: else {
1247: BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1248: }
1249: }
1250: else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1251: code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1252: FAIL_IF(!code);
1253: *code = op_rm;
1254: }
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);
1258: FAIL_IF(!code);
1259: *code = op_mr;
1260: }
1261: else {
1262: EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1263: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1264: FAIL_IF(!code);
1265: *code = op_mr;
1266: }
1267: return SLJIT_SUCCESS;
1268: }
1269:
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))) {
1275: #else
1276: if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
1277: #endif
1278: BINARY_EAX_IMM(op_eax_imm, src1w);
1279: }
1280: else {
1281: BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
1282: }
1283: }
1284: else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1285: code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
1286: FAIL_IF(!code);
1287: *code = op_rm;
1288: }
1289: else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1290: code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
1291: FAIL_IF(!code);
1292: *code = op_mr;
1293: }
1294: else {
1295: EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1296: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1297: FAIL_IF(!code);
1298: *code = op_mr;
1299: }
1300: return SLJIT_SUCCESS;
1301: }
1302:
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);
1308: }
1309: else {
1310: code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1311: FAIL_IF(!code);
1312: *code = op_rm;
1313: }
1314: }
1315: else {
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);
1320: }
1321: else {
1322: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1323: FAIL_IF(!code);
1324: *code = op_rm;
1325: }
1326: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1327: }
1328:
1329: return SLJIT_SUCCESS;
1330: }
1331:
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)
1337: {
1338: sljit_ub* code;
1339:
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);
1344: }
1345: else {
1346: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1347: FAIL_IF(!code);
1348: *code = op_rm;
1349: }
1350: return SLJIT_SUCCESS;
1351: }
1352:
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))) {
1357: #else
1358: if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1359: #endif
1360: BINARY_EAX_IMM(op_eax_imm, src2w);
1361: }
1362: else {
1363: BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1364: }
1365: }
1366: else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1367: code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1368: FAIL_IF(!code);
1369: *code = op_rm;
1370: }
1371: else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1372: code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1373: FAIL_IF(!code);
1374: *code = op_mr;
1375: }
1376: else {
1377: EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1378: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1379: FAIL_IF(!code);
1380: *code = op_mr;
1381: }
1382: return SLJIT_SUCCESS;
1383: }
1384:
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);
1390: }
1391: else {
1392: code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1393: FAIL_IF(!code);
1394: *code = op_rm;
1395: }
1396: }
1397: else {
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);
1402: }
1403: else {
1404: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1405: FAIL_IF(!code);
1406: *code = op_rm;
1407: }
1408: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1409: }
1410:
1411: return SLJIT_SUCCESS;
1412: }
1413:
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)
1418: {
1419: sljit_ub* code;
1420: int dst_r;
1421:
1422: dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1423:
1424: /* Register destination. */
1425: if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
1426: code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1427: FAIL_IF(!code);
1428: *code++ = 0x0f;
1429: *code = 0xaf;
1430: }
1431: else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
1432: code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
1433: FAIL_IF(!code);
1434: *code++ = 0x0f;
1435: *code = 0xaf;
1436: }
1437: else if (src1 & SLJIT_IMM) {
1438: if (src2 & SLJIT_IMM) {
1439: EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
1440: src2 = dst_r;
1441: src2w = 0;
1442: }
1443:
1444: if (src1w <= 127 && src1w >= -128) {
1445: code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1446: FAIL_IF(!code);
1447: *code = 0x6b;
1448: code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1449: FAIL_IF(!code);
1450: INC_CSIZE(1);
1451: *code = (sljit_b)src1w;
1452: }
1453: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1454: else {
1455: code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1456: FAIL_IF(!code);
1457: *code = 0x69;
1458: code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1459: FAIL_IF(!code);
1460: INC_CSIZE(4);
1461: *(sljit_w*)code = src1w;
1462: }
1463: #else
1464: else if (IS_HALFWORD(src1w)) {
1465: code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1466: FAIL_IF(!code);
1467: *code = 0x69;
1468: code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1469: FAIL_IF(!code);
1470: INC_CSIZE(4);
1471: *(sljit_hw*)code = (sljit_hw)src1w;
1472: }
1473: else {
1474: EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1475: if (dst_r != src2)
1476: EMIT_MOV(compiler, dst_r, 0, src2, src2w);
1477: code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1478: FAIL_IF(!code);
1479: *code++ = 0x0f;
1480: *code = 0xaf;
1481: }
1482: #endif
1483: }
1484: else if (src2 & SLJIT_IMM) {
1485: /* Note: src1 is NOT immediate. */
1486:
1487: if (src2w <= 127 && src2w >= -128) {
1488: code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1489: FAIL_IF(!code);
1490: *code = 0x6b;
1491: code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1492: FAIL_IF(!code);
1493: INC_CSIZE(1);
1494: *code = (sljit_b)src2w;
1495: }
1496: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1497: else {
1498: code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1499: FAIL_IF(!code);
1500: *code = 0x69;
1501: code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1502: FAIL_IF(!code);
1503: INC_CSIZE(4);
1504: *(sljit_w*)code = src2w;
1505: }
1506: #else
1507: else if (IS_HALFWORD(src2w)) {
1508: code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1509: FAIL_IF(!code);
1510: *code = 0x69;
1511: code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1512: FAIL_IF(!code);
1513: INC_CSIZE(4);
1514: *(sljit_hw*)code = (sljit_hw)src2w;
1515: }
1516: else {
1517: EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1518: if (dst_r != src1)
1519: EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1520: code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1521: FAIL_IF(!code);
1522: *code++ = 0x0f;
1523: *code = 0xaf;
1524: }
1525: #endif
1526: }
1527: else {
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);
1533: FAIL_IF(!code);
1534: *code++ = 0x0f;
1535: *code = 0xaf;
1536: }
1537:
1538: if (dst_r == TMP_REGISTER)
1539: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1540:
1541: return SLJIT_SUCCESS;
1542: }
1543:
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)
1548: {
1549: sljit_ub* code;
1550: int dst_r, done = 0;
1551:
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;
1557:
1558: dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1559:
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);
1565: FAIL_IF(!code);
1566: *code = 0x8d;
1567: done = 1;
1568: }
1569: }
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);
1573: #else
1574: if (src2 & SLJIT_IMM) {
1575: code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
1576: #endif
1577: FAIL_IF(!code);
1578: *code = 0x8d;
1579: done = 1;
1580: }
1581: }
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);
1586: #else
1587: if (src1 & SLJIT_IMM) {
1588: code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
1589: #endif
1590: FAIL_IF(!code);
1591: *code = 0x8d;
1592: done = 1;
1593: }
1594: }
1595:
1596: if (done) {
1597: if (dst_r == TMP_REGISTER)
1598: return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
1599: return SLJIT_SUCCESS;
1600: }
1601: return SLJIT_ERR_UNSUPPORTED;
1602: }
1603:
1604: static int emit_cmp_binary(struct sljit_compiler *compiler,
1605: int src1, sljit_w src1w,
1606: int src2, sljit_w src2w)
1607: {
1608: sljit_ub* code;
1609:
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))) {
1612: #else
1613: if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1614: #endif
1615: BINARY_EAX_IMM(0x3d, src2w);
1616: return SLJIT_SUCCESS;
1617: }
1618:
1619: if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1620: if (src2 & SLJIT_IMM) {
1621: BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
1622: }
1623: else {
1624: code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1625: FAIL_IF(!code);
1626: *code = 0x3b;
1627: }
1628: return SLJIT_SUCCESS;
1629: }
1630:
1631: if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
1632: code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1633: FAIL_IF(!code);
1634: *code = 0x39;
1635: return SLJIT_SUCCESS;
1636: }
1637:
1638: if (src2 & SLJIT_IMM) {
1639: if (src1 & SLJIT_IMM) {
1640: EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1641: src1 = TMP_REGISTER;
1642: src1w = 0;
1643: }
1644: BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
1645: }
1646: else {
1647: EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1648: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1649: FAIL_IF(!code);
1650: *code = 0x3b;
1651: }
1652: return SLJIT_SUCCESS;
1653: }
1654:
1655: static int emit_test_binary(struct sljit_compiler *compiler,
1656: int src1, sljit_w src1w,
1657: int src2, sljit_w src2w)
1658: {
1659: sljit_ub* code;
1660:
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))) {
1663: #else
1664: if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1665: #endif
1666: BINARY_EAX_IMM(0xa9, src2w);
1667: return SLJIT_SUCCESS;
1668: }
1669:
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))) {
1672: #else
1673: if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
1674: #endif
1675: BINARY_EAX_IMM(0xa9, src1w);
1676: return SLJIT_SUCCESS;
1677: }
1678:
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);
1684: FAIL_IF(!code);
1685: *code = 0xf7;
1686: }
1687: else {
1688: FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1689: code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
1690: FAIL_IF(!code);
1691: *code = 0x85;
1692: }
1693: #else
1694: code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1695: FAIL_IF(!code);
1696: *code = 0xf7;
1697: #endif
1698: }
1699: else {
1700: code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1701: FAIL_IF(!code);
1702: *code = 0x85;
1703: }
1704: return SLJIT_SUCCESS;
1705: }
1706:
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);
1712: FAIL_IF(!code);
1713: *code = 0xf7;
1714: }
1715: else {
1716: FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
1717: code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
1718: FAIL_IF(!code);
1719: *code = 0x85;
1720: }
1721: #else
1722: code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
1723: FAIL_IF(!code);
1724: *code = 0xf7;
1725: #endif
1726: }
1727: else {
1728: code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1729: FAIL_IF(!code);
1730: *code = 0x85;
1731: }
1732: return SLJIT_SUCCESS;
1733: }
1734:
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);
1740: FAIL_IF(!code);
1741: *code = 0xf7;
1742: }
1743: else {
1744: FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1745: code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
1746: FAIL_IF(!code);
1747: *code = 0x85;
1748: }
1749: #else
1750: code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1751: FAIL_IF(!code);
1752: *code = 0xf7;
1753: #endif
1754: }
1755: else {
1756: code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1757: FAIL_IF(!code);
1758: *code = 0x85;
1759: }
1760: return SLJIT_SUCCESS;
1761: }
1762:
1763: static int emit_shift(struct sljit_compiler *compiler,
1764: sljit_ub mode,
1765: int dst, sljit_w dstw,
1766: int src1, sljit_w src1w,
1767: int src2, sljit_w src2w)
1768: {
1769: sljit_ub* code;
1770:
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);
1774: FAIL_IF(!code);
1775: *code |= mode;
1776: return SLJIT_SUCCESS;
1777: }
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);
1781: FAIL_IF(!code);
1782: *code |= mode;
1783: return SLJIT_SUCCESS;
1784: }
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);
1788: FAIL_IF(!code);
1789: *code |= mode;
1790: EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1791: return SLJIT_SUCCESS;
1792: }
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);
1796: FAIL_IF(!code);
1797: *code |= mode;
1798: return SLJIT_SUCCESS;
1799: }
1800:
1801: EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1802: code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1803: FAIL_IF(!code);
1804: *code |= mode;
1805: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1806: return SLJIT_SUCCESS;
1807: }
1808:
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);
1813: FAIL_IF(!code);
1814: *code |= mode;
1815: EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1816: }
1817: else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
1818: if (src1 != 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);
1823: FAIL_IF(!code);
1824: *code |= mode;
1825: EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1826: }
1827: else {
1.1.1.2 ! misho 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);
1.1 misho 1831: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1832: EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1833: #else
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);
1836: #endif
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);
1839: FAIL_IF(!code);
1840: *code |= mode;
1841: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1842: EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1843: #else
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)));
1846: #endif
1847: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1848: }
1849:
1850: return SLJIT_SUCCESS;
1851: }
1852:
1.1.1.2 ! misho 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)
! 1858: {
! 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);
! 1864: #else
! 1865: if ((src2w & 0x1f) != 0)
! 1866: return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
! 1867: #endif
! 1868: if (!set_flags)
! 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);
! 1873: }
! 1874:
! 1875: if (!set_flags)
! 1876: return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
! 1877:
! 1878: if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
! 1879: FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
! 1880:
! 1881: FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
! 1882:
! 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;
! 1886: }
! 1887:
1.1 misho 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)
1892: {
1893: CHECK_ERROR();
1894: check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1895:
1896: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1897: compiler->mode32 = op & SLJIT_INT_OP;
1898: #endif
1899: CHECK_EXTRA_REGS(dst, dstw, (void)0);
1900: CHECK_EXTRA_REGS(src1, src1w, (void)0);
1901: CHECK_EXTRA_REGS(src2, src2w, (void)0);
1902:
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));
1908: }
1909:
1910: switch (GET_OPCODE(op)) {
1911: case SLJIT_ADD:
1912: if (!GET_FLAGS(op)) {
1913: if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
1914: return compiler->error;
1915: }
1916: else
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);
1922: case SLJIT_ADDC:
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);
1931: case SLJIT_SUB:
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;
1935: }
1936: else
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);
1944: case SLJIT_SUBC:
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);
1953: case SLJIT_MUL:
1954: return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
1955: case SLJIT_AND:
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);
1960: case SLJIT_OR:
1961: return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1962: dst, dstw, src1, src1w, src2, src2w);
1963: case SLJIT_XOR:
1964: return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1965: dst, dstw, src1, src1w, src2, src2w);
1966: case SLJIT_SHL:
1.1.1.2 ! misho 1967: return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
1.1 misho 1968: dst, dstw, src1, src1w, src2, src2w);
1969: case SLJIT_LSHR:
1.1.1.2 ! misho 1970: return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
1.1 misho 1971: dst, dstw, src1, src1w, src2, src2w);
1972: case SLJIT_ASHR:
1.1.1.2 ! misho 1973: return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
1.1 misho 1974: dst, dstw, src1, src1w, src2, src2w);
1975: }
1976:
1977: return SLJIT_SUCCESS;
1978: }
1979:
1.1.1.2 ! misho 1980: SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
! 1981: {
! 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)
! 1986: return -1;
! 1987: #endif
! 1988: return reg_map[reg];
! 1989: }
! 1990:
! 1991: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
! 1992: void *instruction, int size)
! 1993: {
! 1994: sljit_ub *buf;
! 1995:
! 1996: CHECK_ERROR();
! 1997: check_sljit_emit_op_custom(compiler, instruction, size);
! 1998: SLJIT_ASSERT(size > 0 && size < 16);
! 1999:
! 2000: buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
! 2001: FAIL_IF(!buf);
! 2002: INC_SIZE(size);
! 2003: SLJIT_MEMMOVE(buf, instruction, size);
! 2004: return SLJIT_SUCCESS;
! 2005: }
! 2006:
1.1 misho 2007: /* --------------------------------------------------------------------- */
2008: /* Floating point operators */
2009: /* --------------------------------------------------------------------- */
2010:
2011: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2012: static int sse2_available = 0;
2013: #endif
2014:
2015: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2016:
2017: /* Alignment + 2 * 16 bytes. */
2018: static sljit_i sse2_data[3 + 4 + 4];
2019: static sljit_i *sse2_buffer;
2020:
2021: static void init_compiler()
2022: {
2023: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2024: int features = 0;
2025: #endif
2026:
2027: sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
2028: sse2_buffer[0] = 0;
2029: sse2_buffer[1] = 0x80000000;
2030: sse2_buffer[4] = 0xffffffff;
2031: sse2_buffer[5] = 0x7fffffff;
2032:
2033: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2034: #ifdef __GNUC__
2035: /* AT&T syntax. */
2036: asm (
2037: "pushl %%ebx\n"
2038: "movl $0x1, %%eax\n"
2039: "cpuid\n"
2040: "popl %%ebx\n"
2041: "movl %%edx, %0\n"
2042: : "=g" (features)
2043: :
2044: : "%eax", "%ecx", "%edx"
2045: );
2046: #elif defined(_MSC_VER) || defined(__BORLANDC__)
2047: /* Intel syntax. */
2048: __asm {
2049: mov eax, 1
2050: push ebx
2051: cpuid
2052: pop ebx
2053: mov features, edx
2054: }
2055: #else
2056: #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
2057: #endif
2058: sse2_available = (features >> 26) & 0x1;
2059: #endif
2060: }
2061:
2062: #endif
2063:
2064: SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2065: {
2066: /* Always available. */
2067: return 1;
2068: }
2069:
2070: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2071:
2072: static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
2073: int xmm1, int xmm2, sljit_w xmm2w)
2074: {
2075: sljit_ub *buf;
2076:
2077: buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2078: FAIL_IF(!buf);
2079: *buf++ = 0x0f;
2080: *buf = opcode;
2081: return SLJIT_SUCCESS;
2082: }
2083:
2084: static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
2085: int xmm1, int xmm2, sljit_w xmm2w)
2086: {
2087: sljit_ub *buf;
2088:
2089: buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2090: FAIL_IF(!buf);
2091: *buf++ = 0x0f;
2092: *buf = opcode;
2093: return SLJIT_SUCCESS;
2094: }
2095:
2096: static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
2097: int dst, int src, sljit_w srcw)
2098: {
2099: return emit_sse2(compiler, 0x10, dst, src, srcw);
2100: }
2101:
2102: static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
2103: int dst, sljit_w dstw, int src)
2104: {
2105: return emit_sse2(compiler, 0x11, src, dst, dstw);
2106: }
2107:
2108: #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2109: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2110: #else
2111: static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
2112: #endif
2113: int dst, sljit_w dstw,
2114: int src, sljit_w srcw)
2115: {
2116: int dst_r;
2117:
2118: CHECK_ERROR();
2119: check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2120:
2121: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2122: compiler->mode32 = 1;
2123: #endif
2124:
2125: if (GET_OPCODE(op) == SLJIT_FCMP) {
2126: compiler->flags_saved = 0;
2127: if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
2128: dst_r = dst;
2129: else {
2130: dst_r = TMP_FREG;
2131: FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
2132: }
2133: return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
2134: }
2135:
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);
2143: }
2144:
2145: if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2146: dst_r = dst;
2147: if (dst != src)
2148: FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2149: }
2150: else {
2151: dst_r = TMP_FREG;
2152: FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2153: }
2154:
2155: switch (op) {
2156: case SLJIT_FNEG:
2157: FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
2158: break;
2159:
2160: case SLJIT_FABS:
2161: FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
2162: break;
2163: }
2164:
2165: if (dst_r == TMP_FREG)
2166: return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2167: return SLJIT_SUCCESS;
2168: }
2169:
2170: #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2171: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2172: #else
2173: static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
2174: #endif
2175: int dst, sljit_w dstw,
2176: int src1, sljit_w src1w,
2177: int src2, sljit_w src2w)
2178: {
2179: int dst_r;
2180:
2181: CHECK_ERROR();
2182: check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2183:
2184: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2185: compiler->mode32 = 1;
2186: #endif
2187:
2188: if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2189: dst_r = dst;
2190: if (dst == src1)
2191: ; /* Do nothing here. */
2192: else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
2193: /* Swap arguments. */
2194: src2 = src1;
2195: src2w = src1w;
2196: }
2197: else if (dst != src2)
2198: FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
2199: else {
2200: dst_r = TMP_FREG;
2201: FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2202: }
2203: }
2204: else {
2205: dst_r = TMP_FREG;
2206: FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2207: }
2208:
2209: switch (op) {
2210: case SLJIT_FADD:
2211: FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
2212: break;
2213:
2214: case SLJIT_FSUB:
2215: FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
2216: break;
2217:
2218: case SLJIT_FMUL:
2219: FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
2220: break;
2221:
2222: case SLJIT_FDIV:
2223: FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
2224: break;
2225: }
2226:
2227: if (dst_r == TMP_FREG)
2228: return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2229: return SLJIT_SUCCESS;
2230: }
2231:
2232: #endif
2233:
2234: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
2235:
2236: static int emit_fld(struct sljit_compiler *compiler,
2237: int src, sljit_w srcw)
2238: {
2239: sljit_ub *buf;
2240:
2241: if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2242: buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2243: FAIL_IF(!buf);
2244: INC_SIZE(2);
2245: *buf++ = 0xd9;
2246: *buf = 0xc0 + src - 1;
2247: return SLJIT_SUCCESS;
2248: }
2249:
2250: buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2251: FAIL_IF(!buf);
2252: *buf = 0xdd;
2253: return SLJIT_SUCCESS;
2254: }
2255:
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)
2260: {
2261: sljit_ub *buf;
2262:
2263: if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2264: buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2265: FAIL_IF(!buf);
2266: INC_SIZE(2);
2267: *buf++ = st_arg;
2268: *buf = st_arg2 + src;
2269: return SLJIT_SUCCESS;
2270: }
2271:
2272: buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2273: FAIL_IF(!buf);
2274: *buf++ = m64fp_arg;
2275: *buf |= m64fp_arg2;
2276: return SLJIT_SUCCESS;
2277: }
2278:
2279: static int emit_fop_regs(struct sljit_compiler *compiler,
2280: sljit_ub st_arg, sljit_ub st_arg2,
2281: int src)
2282: {
2283: sljit_ub *buf;
2284:
2285: buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2286: FAIL_IF(!buf);
2287: INC_SIZE(2);
2288: *buf++ = st_arg;
2289: *buf = st_arg2 + src;
2290: return SLJIT_SUCCESS;
2291: }
2292:
2293: #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2294: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2295: #else
2296: static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
2297: #endif
2298: int dst, sljit_w dstw,
2299: int src, sljit_w srcw)
2300: {
2301: #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2302: sljit_ub *buf;
2303: #endif
2304:
2305: CHECK_ERROR();
2306: check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2307:
2308: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2309: compiler->mode32 = 1;
2310: #endif
2311:
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));
2317:
2318: /* Copy flags. */
2319: EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2320: buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2321: FAIL_IF(!buf);
2322: INC_SIZE(3);
2323: *buf++ = 0xdf;
2324: *buf++ = 0xe0;
2325: /* Note: lahf is not supported on all x86-64 architectures. */
2326: *buf++ = 0x9e;
2327: EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2328: #else
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));
2332: } else {
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));
2337: }
2338: #endif
2339: return SLJIT_SUCCESS;
2340: }
2341:
2342: FAIL_IF(emit_fld(compiler, src, srcw));
2343:
2344: switch (op) {
2345: case SLJIT_FNEG:
2346: FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
2347: break;
2348: case SLJIT_FABS:
2349: FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
2350: break;
2351: }
2352:
2353: FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2354:
2355: return SLJIT_SUCCESS;
2356: }
2357:
2358: #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2359: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2360: #else
2361: static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
2362: #endif
2363: int dst, sljit_w dstw,
2364: int src1, sljit_w src1w,
2365: int src2, sljit_w src2w)
2366: {
2367: CHECK_ERROR();
2368: check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2369:
2370: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2371: compiler->mode32 = 1;
2372: #endif
2373:
2374: if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
2375: FAIL_IF(emit_fld(compiler, src2, src2w));
2376:
2377: switch (op) {
2378: case SLJIT_FADD:
2379: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
2380: break;
2381: case SLJIT_FSUB:
2382: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
2383: break;
2384: case SLJIT_FMUL:
2385: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
2386: break;
2387: case SLJIT_FDIV:
2388: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
2389: break;
2390: }
2391: return SLJIT_SUCCESS;
2392: }
2393:
2394: FAIL_IF(emit_fld(compiler, src1, src1w));
2395:
2396: if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
2397: switch (op) {
2398: case SLJIT_FADD:
2399: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
2400: break;
2401: case SLJIT_FSUB:
2402: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
2403: break;
2404: case SLJIT_FMUL:
2405: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
2406: break;
2407: case SLJIT_FDIV:
2408: FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
2409: break;
2410: }
2411: return SLJIT_SUCCESS;
2412: }
2413:
2414: switch (op) {
2415: case SLJIT_FADD:
2416: FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
2417: break;
2418: case SLJIT_FSUB:
2419: FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
2420: break;
2421: case SLJIT_FMUL:
2422: FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
2423: break;
2424: case SLJIT_FDIV:
2425: FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
2426: break;
2427: }
2428:
2429: FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2430:
2431: return SLJIT_SUCCESS;
2432: }
2433: #endif
2434:
2435: #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2436:
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)
2440: {
2441: if (sse2_available)
2442: return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
2443: else
2444: return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
2445: }
2446:
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)
2451: {
2452: if (sse2_available)
2453: return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2454: else
2455: return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2456: }
2457:
2458: #endif
2459:
2460: /* --------------------------------------------------------------------- */
2461: /* Conditional instructions */
2462: /* --------------------------------------------------------------------- */
2463:
2464: SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2465: {
2466: sljit_ub *buf;
2467: struct sljit_label *label;
2468:
2469: CHECK_ERROR_PTR();
2470: check_sljit_emit_label(compiler);
2471:
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));
2476:
2477: if (compiler->last_label && compiler->last_label->size == compiler->size)
2478: return compiler->last_label;
2479:
2480: label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2481: PTR_FAIL_IF(!label);
2482: set_label(label, compiler);
2483:
2484: buf = (sljit_ub*)ensure_buf(compiler, 2);
2485: PTR_FAIL_IF(!buf);
2486:
2487: *buf++ = 0;
2488: *buf++ = 0;
2489:
2490: return label;
2491: }
2492:
2493: SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2494: {
2495: sljit_ub *buf;
2496: struct sljit_jump *jump;
2497:
2498: CHECK_ERROR_PTR();
2499: check_sljit_emit_jump(compiler, type);
2500:
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;
2505: }
2506:
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);
2510: type &= 0xff;
2511:
2512: if (type >= SLJIT_CALL1)
2513: PTR_FAIL_IF(call_with_args(compiler, type));
2514:
2515: /* Worst case size. */
2516: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2517: compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
2518: #else
2519: compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
2520: #endif
2521:
2522: buf = (sljit_ub*)ensure_buf(compiler, 2);
2523: PTR_FAIL_IF_NULL(buf);
2524:
2525: *buf++ = 0;
2526: *buf++ = type + 4;
2527: return jump;
2528: }
2529:
2530: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2531: {
2532: sljit_ub *code;
2533: struct sljit_jump *jump;
2534:
2535: CHECK_ERROR();
2536: check_sljit_emit_ijump(compiler, type, src, srcw);
2537:
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;
2543: }
2544:
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);
2550: src = TMP_REGISTER;
2551: }
2552: if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
2553: if (src & 0xf0) {
2554: EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2555: src = TMP_REGISTER;
2556: }
2557: else
2558: srcw += sizeof(sljit_w);
2559: }
2560: #else
2561: if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
2562: if (src & 0xf0) {
2563: EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2564: src = TMP_REGISTER;
2565: }
2566: else
2567: srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
2568: }
2569: #endif
2570: #endif
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);
2574: src = TMP_REGISTER;
2575: }
2576: #endif
2577: FAIL_IF(call_with_args(compiler, type));
2578: }
2579:
2580: if (src == SLJIT_IMM) {
2581: jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2582: FAIL_IF_NULL(jump);
2583: set_jump(jump, compiler, JUMP_ADDR);
2584: jump->u.target = srcw;
2585:
2586: /* Worst case size. */
2587: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2588: compiler->size += 5;
2589: #else
2590: compiler->size += 10 + 3;
2591: #endif
2592:
2593: code = (sljit_ub*)ensure_buf(compiler, 2);
2594: FAIL_IF_NULL(code);
2595:
2596: *code++ = 0;
2597: *code++ = type + 4;
2598: }
2599: else {
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;
2603: #endif
2604: code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2605: FAIL_IF(!code);
2606: *code++ = 0xff;
2607: *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2608: }
2609: return SLJIT_SUCCESS;
2610: }
2611:
2612: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2613: {
2614: sljit_ub *buf;
2615: sljit_ub cond_set = 0;
2616: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2617: int reg;
2618: #endif
2619:
2620: CHECK_ERROR();
2621: check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
2622:
2623: if (dst == SLJIT_UNUSED)
2624: return SLJIT_SUCCESS;
2625:
2626: CHECK_EXTRA_REGS(dst, dstw, (void)0);
2627: if (SLJIT_UNLIKELY(compiler->flags_saved))
2628: FAIL_IF(emit_restore_flags(compiler, 0));
2629:
2630: switch (type) {
2631: case SLJIT_C_EQUAL:
2632: case SLJIT_C_FLOAT_EQUAL:
2633: cond_set = 0x94;
2634: break;
2635:
2636: case SLJIT_C_NOT_EQUAL:
2637: case SLJIT_C_FLOAT_NOT_EQUAL:
2638: cond_set = 0x95;
2639: break;
2640:
2641: case SLJIT_C_LESS:
2642: case SLJIT_C_FLOAT_LESS:
2643: cond_set = 0x92;
2644: break;
2645:
2646: case SLJIT_C_GREATER_EQUAL:
2647: case SLJIT_C_FLOAT_GREATER_EQUAL:
2648: cond_set = 0x93;
2649: break;
2650:
2651: case SLJIT_C_GREATER:
2652: case SLJIT_C_FLOAT_GREATER:
2653: cond_set = 0x97;
2654: break;
2655:
2656: case SLJIT_C_LESS_EQUAL:
2657: case SLJIT_C_FLOAT_LESS_EQUAL:
2658: cond_set = 0x96;
2659: break;
2660:
2661: case SLJIT_C_SIG_LESS:
2662: cond_set = 0x9c;
2663: break;
2664:
2665: case SLJIT_C_SIG_GREATER_EQUAL:
2666: cond_set = 0x9d;
2667: break;
2668:
2669: case SLJIT_C_SIG_GREATER:
2670: cond_set = 0x9f;
2671: break;
2672:
2673: case SLJIT_C_SIG_LESS_EQUAL:
2674: cond_set = 0x9e;
2675: break;
2676:
2677: case SLJIT_C_OVERFLOW:
2678: case SLJIT_C_MUL_OVERFLOW:
2679: cond_set = 0x90;
2680: break;
2681:
2682: case SLJIT_C_NOT_OVERFLOW:
2683: case SLJIT_C_MUL_NOT_OVERFLOW:
2684: cond_set = 0x91;
2685: break;
2686:
2687: case SLJIT_C_FLOAT_NAN:
2688: cond_set = 0x9a;
2689: break;
2690:
2691: case SLJIT_C_FLOAT_NOT_NAN:
2692: cond_set = 0x9b;
2693: break;
2694: }
2695:
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;
2698:
2699: buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
2700: FAIL_IF(!buf);
2701: INC_SIZE(4 + 4);
2702: /* Set low register to conditional flag. */
2703: *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
2704: *buf++ = 0x0f;
2705: *buf++ = cond_set;
2706: *buf++ = 0xC0 | reg_lmap[reg];
2707: *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
2708: *buf++ = 0x0f;
2709: *buf++ = 0xb6;
2710: *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
2711:
2712: if (reg == TMP_REGISTER) {
2713: if (op == SLJIT_MOV) {
2714: compiler->mode32 = 0;
2715: EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
2716: }
2717: else {
2718: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2719: compiler->skip_checks = 1;
2720: #endif
2721: return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2722: }
2723: }
2724: #else
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);
2728: FAIL_IF(!buf);
2729: INC_SIZE(3 + 3);
2730: /* Set low byte to conditional flag. */
2731: *buf++ = 0x0f;
2732: *buf++ = cond_set;
2733: *buf++ = 0xC0 | reg_map[dst];
2734:
2735: *buf++ = 0x0f;
2736: *buf++ = 0xb6;
2737: *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
2738: }
2739: else {
2740: EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2741:
2742: buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2743: FAIL_IF(!buf);
2744: INC_SIZE(3 + 3);
2745: /* Set al to conditional flag. */
2746: *buf++ = 0x0f;
2747: *buf++ = cond_set;
2748: *buf++ = 0xC0;
2749:
2750: *buf++ = 0x0f;
2751: *buf++ = 0xb6;
1.1.1.2 ! misho 2752: if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
1.1 misho 2753: *buf = 0xC0 | (reg_map[dst] << 3);
2754: else {
2755: *buf = 0xC0;
2756: EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
2757: }
2758:
2759: EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2760: }
2761: }
2762: else {
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);
2766: FAIL_IF(!buf);
2767: INC_SIZE(3);
2768:
2769: *buf++ = 0x0f;
2770: *buf++ = cond_set;
2771: *buf++ = 0xC0 | reg_map[dst];
2772: }
2773: else {
2774: EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2775:
2776: buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
2777: FAIL_IF(!buf);
2778: INC_SIZE(3 + 3 + 1);
2779: /* Set al to conditional flag. */
2780: *buf++ = 0x0f;
2781: *buf++ = cond_set;
2782: *buf++ = 0xC0;
2783:
2784: *buf++ = 0x0f;
2785: *buf++ = 0xb6;
2786: *buf++ = 0xC0;
2787:
2788: *buf++ = 0x90 + reg_map[TMP_REGISTER];
2789: }
2790: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2791: compiler->skip_checks = 1;
2792: #endif
2793: return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2794: }
2795: #endif
2796:
2797: return SLJIT_SUCCESS;
2798: }
2799:
2800: SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
2801: {
2802: sljit_ub *buf;
2803: struct sljit_const *const_;
2804: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2805: int reg;
2806: #endif
2807:
2808: CHECK_ERROR_PTR();
2809: check_sljit_emit_const(compiler, dst, dstw, init_value);
2810:
2811: CHECK_EXTRA_REGS(dst, dstw, (void)0);
2812:
2813: const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2814: PTR_FAIL_IF(!const_);
2815: set_const(const_, compiler);
2816:
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;
2820:
2821: if (emit_load_imm64(compiler, reg, init_value))
2822: return NULL;
2823: #else
2824: if (dst == SLJIT_UNUSED)
2825: dst = TMP_REGISTER;
2826:
2827: if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
2828: return NULL;
2829: #endif
2830:
2831: buf = (sljit_ub*)ensure_buf(compiler, 2);
2832: PTR_FAIL_IF(!buf);
2833:
2834: *buf++ = 0;
2835: *buf++ = 1;
2836:
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))
2840: return NULL;
2841: #endif
2842:
2843: return const_;
2844: }
2845:
2846: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2847: {
2848: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2849: *(sljit_w*)addr = new_addr - (addr + 4);
2850: #else
2851: *(sljit_uw*)addr = new_addr;
2852: #endif
2853: }
2854:
2855: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2856: {
2857: *(sljit_w*)addr = new_constant;
2858: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>