/[pcre]/code/trunk/sljit/sljitNativeX86_common.c
ViewVC logotype

Contents of /code/trunk/sljit/sljitNativeX86_common.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 839 - (show annotations)
Fri Dec 30 13:22:28 2011 UTC (7 years, 9 months ago) by zherczeg
File MIME type: text/plain
File size: 75668 byte(s)
endianness fixes and JIT compiler update
1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright 2009-2012 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 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
1841 {
1842 check_sljit_get_register_index(reg);
1843 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1844 if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1845 || reg == SLJIT_GENERAL_EREG1 || reg == SLJIT_GENERAL_EREG2)
1846 return -1;
1847 #endif
1848 return reg_map[reg];
1849 }
1850
1851 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
1852 void *instruction, int size)
1853 {
1854 sljit_ub *buf;
1855
1856 CHECK_ERROR();
1857 check_sljit_emit_op_custom(compiler, instruction, size);
1858 SLJIT_ASSERT(size > 0 && size < 16);
1859
1860 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
1861 FAIL_IF(!buf);
1862 INC_SIZE(size);
1863 SLJIT_MEMMOVE(buf, instruction, size);
1864 return SLJIT_SUCCESS;
1865 }
1866
1867 /* --------------------------------------------------------------------- */
1868 /* Floating point operators */
1869 /* --------------------------------------------------------------------- */
1870
1871 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1872 static int sse2_available = 0;
1873 #endif
1874
1875 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1876
1877 /* Alignment + 2 * 16 bytes. */
1878 static sljit_i sse2_data[3 + 4 + 4];
1879 static sljit_i *sse2_buffer;
1880
1881 static void init_compiler()
1882 {
1883 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1884 int features = 0;
1885 #endif
1886
1887 sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
1888 sse2_buffer[0] = 0;
1889 sse2_buffer[1] = 0x80000000;
1890 sse2_buffer[4] = 0xffffffff;
1891 sse2_buffer[5] = 0x7fffffff;
1892
1893 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1894 #ifdef __GNUC__
1895 /* AT&T syntax. */
1896 asm (
1897 "pushl %%ebx\n"
1898 "movl $0x1, %%eax\n"
1899 "cpuid\n"
1900 "popl %%ebx\n"
1901 "movl %%edx, %0\n"
1902 : "=g" (features)
1903 :
1904 : "%eax", "%ecx", "%edx"
1905 );
1906 #elif defined(_MSC_VER) || defined(__BORLANDC__)
1907 /* Intel syntax. */
1908 __asm {
1909 mov eax, 1
1910 push ebx
1911 cpuid
1912 pop ebx
1913 mov features, edx
1914 }
1915 #else
1916 #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
1917 #endif
1918 sse2_available = (features >> 26) & 0x1;
1919 #endif
1920 }
1921
1922 #endif
1923
1924 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
1925 {
1926 /* Always available. */
1927 return 1;
1928 }
1929
1930 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1931
1932 static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
1933 int xmm1, int xmm2, sljit_w xmm2w)
1934 {
1935 sljit_ub *buf;
1936
1937 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
1938 FAIL_IF(!buf);
1939 *buf++ = 0x0f;
1940 *buf = opcode;
1941 return SLJIT_SUCCESS;
1942 }
1943
1944 static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
1945 int xmm1, int xmm2, sljit_w xmm2w)
1946 {
1947 sljit_ub *buf;
1948
1949 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
1950 FAIL_IF(!buf);
1951 *buf++ = 0x0f;
1952 *buf = opcode;
1953 return SLJIT_SUCCESS;
1954 }
1955
1956 static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
1957 int dst, int src, sljit_w srcw)
1958 {
1959 return emit_sse2(compiler, 0x10, dst, src, srcw);
1960 }
1961
1962 static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
1963 int dst, sljit_w dstw, int src)
1964 {
1965 return emit_sse2(compiler, 0x11, src, dst, dstw);
1966 }
1967
1968 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
1969 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
1970 #else
1971 static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
1972 #endif
1973 int dst, sljit_w dstw,
1974 int src, sljit_w srcw)
1975 {
1976 int dst_r;
1977
1978 CHECK_ERROR();
1979 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
1980
1981 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1982 compiler->mode32 = 1;
1983 #endif
1984
1985 if (GET_OPCODE(op) == SLJIT_FCMP) {
1986 compiler->flags_saved = 0;
1987 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
1988 dst_r = dst;
1989 else {
1990 dst_r = TMP_FREG;
1991 FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
1992 }
1993 return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
1994 }
1995
1996 if (op == SLJIT_FMOV) {
1997 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
1998 return emit_sse2_load(compiler, dst, src, srcw);
1999 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
2000 return emit_sse2_store(compiler, dst, dstw, src);
2001 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
2002 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2003 }
2004
2005 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2006 dst_r = dst;
2007 if (dst != src)
2008 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2009 }
2010 else {
2011 dst_r = TMP_FREG;
2012 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2013 }
2014
2015 switch (op) {
2016 case SLJIT_FNEG:
2017 FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
2018 break;
2019
2020 case SLJIT_FABS:
2021 FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
2022 break;
2023 }
2024
2025 if (dst_r == TMP_FREG)
2026 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2027 return SLJIT_SUCCESS;
2028 }
2029
2030 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2031 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2032 #else
2033 static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
2034 #endif
2035 int dst, sljit_w dstw,
2036 int src1, sljit_w src1w,
2037 int src2, sljit_w src2w)
2038 {
2039 int dst_r;
2040
2041 CHECK_ERROR();
2042 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2043
2044 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2045 compiler->mode32 = 1;
2046 #endif
2047
2048 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2049 dst_r = dst;
2050 if (dst == src1)
2051 ; /* Do nothing here. */
2052 else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
2053 /* Swap arguments. */
2054 src2 = src1;
2055 src2w = src1w;
2056 }
2057 else if (dst != src2)
2058 FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
2059 else {
2060 dst_r = TMP_FREG;
2061 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2062 }
2063 }
2064 else {
2065 dst_r = TMP_FREG;
2066 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2067 }
2068
2069 switch (op) {
2070 case SLJIT_FADD:
2071 FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
2072 break;
2073
2074 case SLJIT_FSUB:
2075 FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
2076 break;
2077
2078 case SLJIT_FMUL:
2079 FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
2080 break;
2081
2082 case SLJIT_FDIV:
2083 FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
2084 break;
2085 }
2086
2087 if (dst_r == TMP_FREG)
2088 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2089 return SLJIT_SUCCESS;
2090 }
2091
2092 #endif
2093
2094 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
2095
2096 static int emit_fld(struct sljit_compiler *compiler,
2097 int src, sljit_w srcw)
2098 {
2099 sljit_ub *buf;
2100
2101 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2102 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2103 FAIL_IF(!buf);
2104 INC_SIZE(2);
2105 *buf++ = 0xd9;
2106 *buf = 0xc0 + src - 1;
2107 return SLJIT_SUCCESS;
2108 }
2109
2110 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2111 FAIL_IF(!buf);
2112 *buf = 0xdd;
2113 return SLJIT_SUCCESS;
2114 }
2115
2116 static int emit_fop(struct sljit_compiler *compiler,
2117 sljit_ub st_arg, sljit_ub st_arg2,
2118 sljit_ub m64fp_arg, sljit_ub m64fp_arg2,
2119 int src, sljit_w srcw)
2120 {
2121 sljit_ub *buf;
2122
2123 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2124 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2125 FAIL_IF(!buf);
2126 INC_SIZE(2);
2127 *buf++ = st_arg;
2128 *buf = st_arg2 + src;
2129 return SLJIT_SUCCESS;
2130 }
2131
2132 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2133 FAIL_IF(!buf);
2134 *buf++ = m64fp_arg;
2135 *buf |= m64fp_arg2;
2136 return SLJIT_SUCCESS;
2137 }
2138
2139 static int emit_fop_regs(struct sljit_compiler *compiler,
2140 sljit_ub st_arg, sljit_ub st_arg2,
2141 int src)
2142 {
2143 sljit_ub *buf;
2144
2145 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
2146 FAIL_IF(!buf);
2147 INC_SIZE(2);
2148 *buf++ = st_arg;
2149 *buf = st_arg2 + src;
2150 return SLJIT_SUCCESS;
2151 }
2152
2153 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2154 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2155 #else
2156 static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
2157 #endif
2158 int dst, sljit_w dstw,
2159 int src, sljit_w srcw)
2160 {
2161 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2162 sljit_ub *buf;
2163 #endif
2164
2165 CHECK_ERROR();
2166 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2167
2168 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2169 compiler->mode32 = 1;
2170 #endif
2171
2172 if (GET_OPCODE(op) == SLJIT_FCMP) {
2173 compiler->flags_saved = 0;
2174 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2175 FAIL_IF(emit_fld(compiler, dst, dstw));
2176 FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw));
2177
2178 /* Copy flags. */
2179 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2180 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2181 FAIL_IF(!buf);
2182 INC_SIZE(3);
2183 *buf++ = 0xdf;
2184 *buf++ = 0xe0;
2185 /* Note: lahf is not supported on all x86-64 architectures. */
2186 *buf++ = 0x9e;
2187 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2188 #else
2189 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
2190 FAIL_IF(emit_fld(compiler, dst, dstw));
2191 FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2192 } else {
2193 FAIL_IF(emit_fld(compiler, src, srcw));
2194 FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw));
2195 FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
2196 FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0));
2197 }
2198 #endif
2199 return SLJIT_SUCCESS;
2200 }
2201
2202 FAIL_IF(emit_fld(compiler, src, srcw));
2203
2204 switch (op) {
2205 case SLJIT_FNEG:
2206 FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
2207 break;
2208 case SLJIT_FABS:
2209 FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
2210 break;
2211 }
2212
2213 FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2214
2215 return SLJIT_SUCCESS;
2216 }
2217
2218 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2219 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2220 #else
2221 static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
2222 #endif
2223 int dst, sljit_w dstw,
2224 int src1, sljit_w src1w,
2225 int src2, sljit_w src2w)
2226 {
2227 CHECK_ERROR();
2228 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2229
2230 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2231 compiler->mode32 = 1;
2232 #endif
2233
2234 if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
2235 FAIL_IF(emit_fld(compiler, src2, src2w));
2236
2237 switch (op) {
2238 case SLJIT_FADD:
2239 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
2240 break;
2241 case SLJIT_FSUB:
2242 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
2243 break;
2244 case SLJIT_FMUL:
2245 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
2246 break;
2247 case SLJIT_FDIV:
2248 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
2249 break;
2250 }
2251 return SLJIT_SUCCESS;
2252 }
2253
2254 FAIL_IF(emit_fld(compiler, src1, src1w));
2255
2256 if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
2257 switch (op) {
2258 case SLJIT_FADD:
2259 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
2260 break;
2261 case SLJIT_FSUB:
2262 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
2263 break;
2264 case SLJIT_FMUL:
2265 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
2266 break;
2267 case SLJIT_FDIV:
2268 FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
2269 break;
2270 }
2271 return SLJIT_SUCCESS;
2272 }
2273
2274 switch (op) {
2275 case SLJIT_FADD:
2276 FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
2277 break;
2278 case SLJIT_FSUB:
2279 FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
2280 break;
2281 case SLJIT_FMUL:
2282 FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
2283 break;
2284 case SLJIT_FDIV:
2285 FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
2286 break;
2287 }
2288
2289 FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
2290
2291 return SLJIT_SUCCESS;
2292 }
2293 #endif
2294
2295 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2296
2297 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2298 int dst, sljit_w dstw,
2299 int src, sljit_w srcw)
2300 {
2301 if (sse2_available)
2302 return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
2303 else
2304 return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
2305 }
2306
2307 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2308 int dst, sljit_w dstw,
2309 int src1, sljit_w src1w,
2310 int src2, sljit_w src2w)
2311 {
2312 if (sse2_available)
2313 return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2314 else
2315 return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2316 }
2317
2318 #endif
2319
2320 /* --------------------------------------------------------------------- */
2321 /* Conditional instructions */
2322 /* --------------------------------------------------------------------- */
2323
2324 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2325 {
2326 sljit_ub *buf;
2327 struct sljit_label *label;
2328
2329 CHECK_ERROR_PTR();
2330 check_sljit_emit_label(compiler);
2331
2332 /* We should restore the flags before the label,
2333 since other taken jumps has their own flags as well. */
2334 if (SLJIT_UNLIKELY(compiler->flags_saved))
2335 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2336
2337 if (compiler->last_label && compiler->last_label->size == compiler->size)
2338 return compiler->last_label;
2339
2340 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2341 PTR_FAIL_IF(!label);
2342 set_label(label, compiler);
2343
2344 buf = (sljit_ub*)ensure_buf(compiler, 2);
2345 PTR_FAIL_IF(!buf);
2346
2347 *buf++ = 0;
2348 *buf++ = 0;
2349
2350 return label;
2351 }
2352
2353 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2354 {
2355 sljit_ub *buf;
2356 struct sljit_jump *jump;
2357
2358 CHECK_ERROR_PTR();
2359 check_sljit_emit_jump(compiler, type);
2360
2361 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2362 if ((type & 0xff) <= SLJIT_JUMP)
2363 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2364 compiler->flags_saved = 0;
2365 }
2366
2367 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2368 PTR_FAIL_IF_NULL(jump);
2369 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2370 type &= 0xff;
2371
2372 if (type >= SLJIT_CALL1)
2373 PTR_FAIL_IF(call_with_args(compiler, type));
2374
2375 /* Worst case size. */
2376 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2377 compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
2378 #else
2379 compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
2380 #endif
2381
2382 buf = (sljit_ub*)ensure_buf(compiler, 2);
2383 PTR_FAIL_IF_NULL(buf);
2384
2385 *buf++ = 0;
2386 *buf++ = type + 4;
2387 return jump;
2388 }
2389
2390 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2391 {
2392 sljit_ub *code;
2393 struct sljit_jump *jump;
2394
2395 CHECK_ERROR();
2396 check_sljit_emit_ijump(compiler, type, src, srcw);
2397
2398 CHECK_EXTRA_REGS(src, srcw, (void)0);
2399 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2400 if (type <= SLJIT_JUMP)
2401 FAIL_IF(emit_restore_flags(compiler, 0));
2402 compiler->flags_saved = 0;
2403 }
2404
2405 if (type >= SLJIT_CALL1) {
2406 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2407 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
2408 if (src == SLJIT_TEMPORARY_REG3) {
2409 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2410 src = TMP_REGISTER;
2411 }
2412 if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
2413 if (src & 0xf0) {
2414 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2415 src = TMP_REGISTER;
2416 }
2417 else
2418 srcw += sizeof(sljit_w);
2419 }
2420 #else
2421 if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
2422 if (src & 0xf0) {
2423 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
2424 src = TMP_REGISTER;
2425 }
2426 else
2427 srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
2428 }
2429 #endif
2430 #endif
2431 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
2432 if (src == SLJIT_TEMPORARY_REG3) {
2433 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2434 src = TMP_REGISTER;
2435 }
2436 #endif
2437 FAIL_IF(call_with_args(compiler, type));
2438 }
2439
2440 if (src == SLJIT_IMM) {
2441 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2442 FAIL_IF_NULL(jump);
2443 set_jump(jump, compiler, JUMP_ADDR);
2444 jump->u.target = srcw;
2445
2446 /* Worst case size. */
2447 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2448 compiler->size += 5;
2449 #else
2450 compiler->size += 10 + 3;
2451 #endif
2452
2453 code = (sljit_ub*)ensure_buf(compiler, 2);
2454 FAIL_IF_NULL(code);
2455
2456 *code++ = 0;
2457 *code++ = type + 4;
2458 }
2459 else {
2460 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2461 /* REX_W is not necessary (src is not immediate). */
2462 compiler->mode32 = 1;
2463 #endif
2464 code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2465 FAIL_IF(!code);
2466 *code++ = 0xff;
2467 *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2468 }
2469 return SLJIT_SUCCESS;
2470 }
2471
2472 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2473 {
2474 sljit_ub *buf;
2475 sljit_ub cond_set = 0;
2476 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2477 int reg;
2478 #endif
2479
2480 CHECK_ERROR();
2481 check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
2482
2483 if (dst == SLJIT_UNUSED)
2484 return SLJIT_SUCCESS;
2485
2486 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2487 if (SLJIT_UNLIKELY(compiler->flags_saved))
2488 FAIL_IF(emit_restore_flags(compiler, 0));
2489
2490 switch (type) {
2491 case SLJIT_C_EQUAL:
2492 case SLJIT_C_FLOAT_EQUAL:
2493 cond_set = 0x94;
2494 break;
2495
2496 case SLJIT_C_NOT_EQUAL:
2497 case SLJIT_C_FLOAT_NOT_EQUAL:
2498 cond_set = 0x95;
2499 break;
2500
2501 case SLJIT_C_LESS:
2502 case SLJIT_C_FLOAT_LESS:
2503 cond_set = 0x92;
2504 break;
2505
2506 case SLJIT_C_GREATER_EQUAL:
2507 case SLJIT_C_FLOAT_GREATER_EQUAL:
2508 cond_set = 0x93;
2509 break;
2510
2511 case SLJIT_C_GREATER:
2512 case SLJIT_C_FLOAT_GREATER:
2513 cond_set = 0x97;
2514 break;
2515
2516 case SLJIT_C_LESS_EQUAL:
2517 case SLJIT_C_FLOAT_LESS_EQUAL:
2518 cond_set = 0x96;
2519 break;
2520
2521 case SLJIT_C_SIG_LESS:
2522 cond_set = 0x9c;
2523 break;
2524
2525 case SLJIT_C_SIG_GREATER_EQUAL:
2526 cond_set = 0x9d;
2527 break;
2528
2529 case SLJIT_C_SIG_GREATER:
2530 cond_set = 0x9f;
2531 break;
2532
2533 case SLJIT_C_SIG_LESS_EQUAL:
2534 cond_set = 0x9e;
2535 break;
2536
2537 case SLJIT_C_OVERFLOW:
2538 case SLJIT_C_MUL_OVERFLOW:
2539 cond_set = 0x90;
2540 break;
2541
2542 case SLJIT_C_NOT_OVERFLOW:
2543 case SLJIT_C_MUL_NOT_OVERFLOW:
2544 cond_set = 0x91;
2545 break;
2546
2547 case SLJIT_C_FLOAT_NAN:
2548 cond_set = 0x9a;
2549 break;
2550
2551 case SLJIT_C_FLOAT_NOT_NAN:
2552 cond_set = 0x9b;
2553 break;
2554 }
2555
2556 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2557 reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2558
2559 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
2560 FAIL_IF(!buf);
2561 INC_SIZE(4 + 4);
2562 /* Set low register to conditional flag. */
2563 *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
2564 *buf++ = 0x0f;
2565 *buf++ = cond_set;
2566 *buf++ = 0xC0 | reg_lmap[reg];
2567 *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
2568 *buf++ = 0x0f;
2569 *buf++ = 0xb6;
2570 *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
2571
2572 if (reg == TMP_REGISTER) {
2573 if (op == SLJIT_MOV) {
2574 compiler->mode32 = 0;
2575 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
2576 }
2577 else {
2578 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2579 compiler->skip_checks = 1;
2580 #endif
2581 return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2582 }
2583 }
2584 #else
2585 if (op == SLJIT_MOV) {
2586 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2587 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2588 FAIL_IF(!buf);
2589 INC_SIZE(3 + 3);
2590 /* Set low byte to conditional flag. */
2591 *buf++ = 0x0f;
2592 *buf++ = cond_set;
2593 *buf++ = 0xC0 | reg_map[dst];
2594
2595 *buf++ = 0x0f;
2596 *buf++ = 0xb6;
2597 *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
2598 }
2599 else {
2600 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2601
2602 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2603 FAIL_IF(!buf);
2604 INC_SIZE(3 + 3);
2605 /* Set al to conditional flag. */
2606 *buf++ = 0x0f;
2607 *buf++ = cond_set;
2608 *buf++ = 0xC0;
2609
2610 *buf++ = 0x0f;
2611 *buf++ = 0xb6;
2612 if (dst >= SLJIT_GENERAL_REG1 && dst <= SLJIT_NO_REGISTERS)
2613 *buf = 0xC0 | (reg_map[dst] << 3);
2614 else {
2615 *buf = 0xC0;
2616 EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
2617 }
2618
2619 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2620 }
2621 }
2622 else {
2623 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2624 EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
2625 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2626 FAIL_IF(!buf);
2627 INC_SIZE(3);
2628
2629 *buf++ = 0x0f;
2630 *buf++ = cond_set;
2631 *buf++ = 0xC0 | reg_map[dst];
2632 }
2633 else {
2634 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2635
2636 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
2637 FAIL_IF(!buf);
2638 INC_SIZE(3 + 3 + 1);
2639 /* Set al to conditional flag. */
2640 *buf++ = 0x0f;
2641 *buf++ = cond_set;
2642 *buf++ = 0xC0;
2643
2644 *buf++ = 0x0f;
2645 *buf++ = 0xb6;
2646 *buf++ = 0xC0;
2647
2648 *buf++ = 0x90 + reg_map[TMP_REGISTER];
2649 }
2650 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2651 compiler->skip_checks = 1;
2652 #endif
2653 return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
2654 }
2655 #endif
2656
2657 return SLJIT_SUCCESS;
2658 }
2659
2660 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
2661 {
2662 sljit_ub *buf;
2663 struct sljit_const *const_;
2664 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2665 int reg;
2666 #endif
2667
2668 CHECK_ERROR_PTR();
2669 check_sljit_emit_const(compiler, dst, dstw, init_value);
2670
2671 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2672
2673 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2674 PTR_FAIL_IF(!const_);
2675 set_const(const_, compiler);
2676
2677 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2678 compiler->mode32 = 0;
2679 reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2680
2681 if (emit_load_imm64(compiler, reg, init_value))
2682 return NULL;
2683 #else
2684 if (dst == SLJIT_UNUSED)
2685 dst = TMP_REGISTER;
2686
2687 if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
2688 return NULL;
2689 #endif
2690
2691 buf = (sljit_ub*)ensure_buf(compiler, 2);
2692 PTR_FAIL_IF(!buf);
2693
2694 *buf++ = 0;
2695 *buf++ = 1;
2696
2697 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2698 if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
2699 if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
2700 return NULL;
2701 #endif
2702
2703 return const_;
2704 }
2705
2706 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2707 {
2708 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2709 *(sljit_w*)addr = new_addr - (addr + 4);
2710 #else
2711 *(sljit_uw*)addr = new_addr;
2712 #endif
2713 }
2714
2715 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2716 {
2717 *(sljit_w*)addr = new_constant;
2718 }

  ViewVC Help
Powered by ViewVC 1.1.5