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

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12