/[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 955 - (show annotations)
Tue Apr 3 15:32:36 2012 UTC (7 years, 6 months ago) by zherczeg
File MIME type: text/plain
File size: 75261 byte(s)
Error occurred while calculating annotation data.
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 return "x86" SLJIT_CPUINFO;
30 }
31
32 /*
33 32b register indexes:
34 0 - EAX
35 1 - ECX
36 2 - EDX
37 3 - EBX
38 4 - none
39 5 - EBP
40 6 - ESI
41 7 - EDI
42 */
43
44 /*
45 64b register indexes:
46 0 - RAX
47 1 - RCX
48 2 - RDX
49 3 - RBX
50 4 - none
51 5 - RBP
52 6 - RSI
53 7 - RDI
54 8 - R8 - From now on REX prefix is required
55 9 - R9
56 10 - R10
57 11 - R11
58 12 - R12
59 13 - R13
60 14 - R14
61 15 - R15
62 */
63
64 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
65
66 /* Last register + 1. */
67 #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
68
69 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
70 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
71 };
72
73 #define CHECK_EXTRA_REGS(p, w, do) \
74 if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
75 w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \
76 p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
77 do; \
78 } \
79 else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
80 w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
81 p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
82 do; \
83 }
84
85 #else /* SLJIT_CONFIG_X86_32 */
86
87 /* Last register + 1. */
88 #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
89 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
90 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
91
92 /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
93 Note: avoid to use r12 and r13 for memory addessing
94 therefore r12 is better for SAVED_EREG than SAVED_REG. */
95 #ifndef _WIN64
96 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
97 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
98 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
99 };
100 /* low-map. reg_map & 0x7. */
101 static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
102 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
103 };
104 #else
105 /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
106 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
107 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9
108 };
109 /* low-map. reg_map & 0x7. */
110 static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
111 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1
112 };
113 #endif
114
115 #define REX_W 0x48
116 #define REX_R 0x44
117 #define REX_X 0x42
118 #define REX_B 0x41
119 #define REX 0x40
120
121 typedef unsigned int sljit_uhw;
122 typedef int sljit_hw;
123
124 #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
125 #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
126
127 #define CHECK_EXTRA_REGS(p, w, do)
128
129 #endif /* SLJIT_CONFIG_X86_32 */
130
131 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
132 #define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
133 #endif
134
135 /* Size flags for emit_x86_instruction: */
136 #define EX86_BIN_INS 0x0010
137 #define EX86_SHIFT_INS 0x0020
138 #define EX86_REX 0x0040
139 #define EX86_NO_REXW 0x0080
140 #define EX86_BYTE_ARG 0x0100
141 #define EX86_HALF_ARG 0x0200
142 #define EX86_PREF_66 0x0400
143
144 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
145 #define EX86_PREF_F2 0x0800
146 #define EX86_SSE2 0x1000
147 #endif
148
149 #define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
150 #define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
151
152 #define PUSH_REG(r) (*buf++ = (0x50 + (r)))
153 #define POP_REG(r) (*buf++ = (0x58 + (r)))
154 #define RET() (*buf++ = (0xc3))
155 #define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0)
156 /* r32, r/m32 */
157 #define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
158
159 static sljit_ub get_jump_code(int type)
160 {
161 switch (type) {
162 case SLJIT_C_EQUAL:
163 case SLJIT_C_FLOAT_EQUAL:
164 return 0x84;
165
166 case SLJIT_C_NOT_EQUAL:
167 case SLJIT_C_FLOAT_NOT_EQUAL:
168 return 0x85;
169
170 case SLJIT_C_LESS:
171 case SLJIT_C_FLOAT_LESS:
172 return 0x82;
173
174 case SLJIT_C_GREATER_EQUAL:
175 case SLJIT_C_FLOAT_GREATER_EQUAL:
176 return 0x83;
177
178 case SLJIT_C_GREATER:
179 case SLJIT_C_FLOAT_GREATER:
180 return 0x87;
181
182 case SLJIT_C_LESS_EQUAL:
183 case SLJIT_C_FLOAT_LESS_EQUAL:
184 return 0x86;
185
186 case SLJIT_C_SIG_LESS:
187 return 0x8c;
188
189 case SLJIT_C_SIG_GREATER_EQUAL:
190 return 0x8d;
191
192 case SLJIT_C_SIG_GREATER:
193 return 0x8f;
194
195 case SLJIT_C_SIG_LESS_EQUAL:
196 return 0x8e;
197
198 case SLJIT_C_OVERFLOW:
199 case SLJIT_C_MUL_OVERFLOW:
200 return 0x80;
201
202 case SLJIT_C_NOT_OVERFLOW:
203 case SLJIT_C_MUL_NOT_OVERFLOW:
204 return 0x81;
205
206 case SLJIT_C_FLOAT_NAN:
207 return 0x8a;
208
209 case SLJIT_C_FLOAT_NOT_NAN:
210 return 0x8b;
211 }
212 return 0;
213 }
214
215 static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
216
217 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
218 static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type);
219 #endif
220
221 static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
222 {
223 int short_jump;
224 sljit_uw label_addr;
225
226 if (jump->flags & JUMP_LABEL)
227 label_addr = (sljit_uw)(code + jump->u.label->size);
228 else
229 label_addr = jump->u.target;
230 short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127;
231
232 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
233 if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll)
234 return generate_far_jump_code(jump, code_ptr, type);
235 #endif
236
237 if (type == SLJIT_JUMP) {
238 if (short_jump)
239 *code_ptr++ = 0xeb;
240 else
241 *code_ptr++ = 0xe9;
242 jump->addr++;
243 }
244 else if (type >= SLJIT_FAST_CALL) {
245 short_jump = 0;
246 *code_ptr++ = 0xe8;
247 jump->addr++;
248 }
249 else if (short_jump) {
250 *code_ptr++ = get_jump_code(type) - 0x10;
251 jump->addr++;
252 }
253 else {
254 *code_ptr++ = 0x0f;
255 *code_ptr++ = get_jump_code(type);
256 jump->addr += 2;
257 }
258
259 if (short_jump) {
260 jump->flags |= PATCH_MB;
261 code_ptr += sizeof(sljit_b);
262 } else {
263 jump->flags |= PATCH_MW;
264 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
265 code_ptr += sizeof(sljit_w);
266 #else
267 code_ptr += sizeof(sljit_hw);
268 #endif
269 }
270
271 return code_ptr;
272 }
273
274 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
275 {
276 struct sljit_memory_fragment *buf;
277 sljit_ub *code;
278 sljit_ub *code_ptr;
279 sljit_ub *buf_ptr;
280 sljit_ub *buf_end;
281 sljit_ub len;
282
283 struct sljit_label *label;
284 struct sljit_jump *jump;
285 struct sljit_const *const_;
286
287 CHECK_ERROR_PTR();
288 check_sljit_generate_code(compiler);
289 reverse_buf(compiler);
290
291 /* Second code generation pass. */
292 code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
293 PTR_FAIL_WITH_EXEC_IF(code);
294 buf = compiler->buf;
295
296 code_ptr = code;
297 label = compiler->labels;
298 jump = compiler->jumps;
299 const_ = compiler->consts;
300 do {
301 buf_ptr = buf->memory;
302 buf_end = buf_ptr + buf->used_size;
303 do {
304 len = *buf_ptr++;
305 if (len > 0) {
306 /* The code is already generated. */
307 SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
308 code_ptr += len;
309 buf_ptr += len;
310 }
311 else {
312 if (*buf_ptr >= 4) {
313 jump->addr = (sljit_uw)code_ptr;
314 if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
315 code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
316 else
317 code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
318 jump = jump->next;
319 }
320 else if (*buf_ptr == 0) {
321 label->addr = (sljit_uw)code_ptr;
322 label->size = code_ptr - code;
323 label = label->next;
324 }
325 else if (*buf_ptr == 1) {
326 const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
327 const_ = const_->next;
328 }
329 else {
330 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
331 *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
332 buf_ptr++;
333 *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w));
334 code_ptr += sizeof(sljit_w);
335 buf_ptr += sizeof(sljit_w) - 1;
336 #else
337 code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
338 buf_ptr += sizeof(sljit_w);
339 #endif
340 }
341 buf_ptr++;
342 }
343 } while (buf_ptr < buf_end);
344 SLJIT_ASSERT(buf_ptr == buf_end);
345 buf = buf->next;
346 } while (buf);
347
348 SLJIT_ASSERT(!label);
349 SLJIT_ASSERT(!jump);
350 SLJIT_ASSERT(!const_);
351
352 jump = compiler->jumps;
353 while (jump) {
354 if (jump->flags & PATCH_MB) {
355 SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);
356 *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
357 } else if (jump->flags & PATCH_MW) {
358 if (jump->flags & JUMP_LABEL) {
359 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
360 *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
361 #else
362 SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
363 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
364 #endif
365 }
366 else {
367 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
368 *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
369 #else
370 SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
371 *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
372 #endif
373 }
374 }
375 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
376 else if (jump->flags & PATCH_MD)
377 *(sljit_w*)jump->addr = jump->u.label->addr;
378 #endif
379
380 jump = jump->next;
381 }
382
383 /* Maybe we waste some space because of short jumps. */
384 SLJIT_ASSERT(code_ptr <= code + compiler->size);
385 compiler->error = SLJIT_ERR_COMPILED;
386 compiler->executable_size = compiler->size;
387 return (void*)code;
388 }
389
390 /* --------------------------------------------------------------------- */
391 /* Operators */
392 /* --------------------------------------------------------------------- */
393
394 static int emit_cum_binary(struct sljit_compiler *compiler,
395 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
396 int dst, sljit_w dstw,
397 int src1, sljit_w src1w,
398 int src2, sljit_w src2w);
399
400 static int emit_non_cum_binary(struct sljit_compiler *compiler,
401 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
402 int dst, sljit_w dstw,
403 int src1, sljit_w src1w,
404 int src2, sljit_w src2w);
405
406 static int emit_mov(struct sljit_compiler *compiler,
407 int dst, sljit_w dstw,
408 int src, sljit_w srcw);
409
410 static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
411 {
412 sljit_ub *buf;
413
414 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
415 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
416 FAIL_IF(!buf);
417 INC_SIZE(5);
418 #else
419 buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
420 FAIL_IF(!buf);
421 INC_SIZE(6);
422 *buf++ = REX_W;
423 #endif
424 *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
425 *buf++ = 0x64;
426 *buf++ = 0x24;
427 *buf++ = (sljit_ub)sizeof(sljit_w);
428 *buf++ = 0x9c; /* pushfd / pushfq */
429 compiler->flags_saved = 1;
430 return SLJIT_SUCCESS;
431 }
432
433 static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
434 {
435 sljit_ub *buf;
436
437 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
438 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
439 FAIL_IF(!buf);
440 INC_SIZE(5);
441 *buf++ = 0x9d; /* popfd */
442 #else
443 buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
444 FAIL_IF(!buf);
445 INC_SIZE(6);
446 *buf++ = 0x9d; /* popfq */
447 *buf++ = REX_W;
448 #endif
449 *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
450 *buf++ = 0x64;
451 *buf++ = 0x24;
452 *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
453 compiler->flags_saved = keep_flags;
454 return SLJIT_SUCCESS;
455 }
456
457 #ifdef _WIN32
458 #include <malloc.h>
459
460 static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
461 {
462 /* Workaround for calling _chkstk. */
463 alloca(local_size);
464 }
465 #endif
466
467 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
468 #include "sljitNativeX86_32.c"
469 #else
470 #include "sljitNativeX86_64.c"
471 #endif
472
473 static int emit_mov(struct sljit_compiler *compiler,
474 int dst, sljit_w dstw,
475 int src, sljit_w srcw)
476 {
477 sljit_ub* code;
478
479 if (dst == SLJIT_UNUSED) {
480 /* No destination, doesn't need to setup flags. */
481 if (src & SLJIT_MEM) {
482 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
483 FAIL_IF(!code);
484 *code = 0x8b;
485 }
486 return SLJIT_SUCCESS;
487 }
488 if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
489 code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
490 FAIL_IF(!code);
491 *code = 0x89;
492 return SLJIT_SUCCESS;
493 }
494 if (src & SLJIT_IMM) {
495 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
496 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
497 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
498 #else
499 if (!compiler->mode32) {
500 if (NOT_HALFWORD(srcw))
501 return emit_load_imm64(compiler, dst, srcw);
502 }
503 else
504 return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
505 #endif
506 }
507 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
508 if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
509 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
510 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
511 FAIL_IF(!code);
512 *code = 0x89;
513 return SLJIT_SUCCESS;
514 }
515 #endif
516 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
517 FAIL_IF(!code);
518 *code = 0xc7;
519 return SLJIT_SUCCESS;
520 }
521 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
522 code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
523 FAIL_IF(!code);
524 *code = 0x8b;
525 return SLJIT_SUCCESS;
526 }
527
528 /* Memory to memory move. Requires two instruction. */
529 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
530 FAIL_IF(!code);
531 *code = 0x8b;
532 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
533 FAIL_IF(!code);
534 *code = 0x89;
535 return SLJIT_SUCCESS;
536 }
537
538 #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
539 FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
540
541 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
542 {
543 sljit_ub *buf;
544 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
545 int size;
546 #endif
547
548 CHECK_ERROR();
549 check_sljit_emit_op0(compiler, op);
550
551 switch (GET_OPCODE(op)) {
552 case SLJIT_BREAKPOINT:
553 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
554 FAIL_IF(!buf);
555 INC_SIZE(1);
556 *buf = 0xcc;
557 break;
558 case SLJIT_NOP:
559 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
560 FAIL_IF(!buf);
561 INC_SIZE(1);
562 *buf = 0x90;
563 break;
564 case SLJIT_UMUL:
565 case SLJIT_SMUL:
566 case SLJIT_UDIV:
567 case SLJIT_SDIV:
568 compiler->flags_saved = 0;
569 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
570 #ifdef _WIN64
571 SLJIT_COMPILE_ASSERT(
572 reg_map[SLJIT_TEMPORARY_REG1] == 0
573 && reg_map[SLJIT_TEMPORARY_REG2] == 2
574 && reg_map[TMP_REGISTER] > 7,
575 invalid_register_assignment_for_div_mul);
576 #else
577 SLJIT_COMPILE_ASSERT(
578 reg_map[SLJIT_TEMPORARY_REG1] == 0
579 && reg_map[SLJIT_TEMPORARY_REG2] < 7
580 && reg_map[TMP_REGISTER] == 2,
581 invalid_register_assignment_for_div_mul);
582 #endif
583 compiler->mode32 = op & SLJIT_INT_OP;
584 #endif
585
586 op = GET_OPCODE(op);
587 if (op == SLJIT_UDIV) {
588 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
589 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
590 buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
591 #else
592 buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
593 #endif
594 FAIL_IF(!buf);
595 *buf = 0x33;
596 }
597
598 if (op == SLJIT_SDIV) {
599 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
600 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
601 #endif
602
603 /* CDQ instruction */
604 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
605 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
606 FAIL_IF(!buf);
607 INC_SIZE(1);
608 *buf = 0x99;
609 #else
610 if (compiler->mode32) {
611 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
612 FAIL_IF(!buf);
613 INC_SIZE(1);
614 *buf = 0x99;
615 } else {
616 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
617 FAIL_IF(!buf);
618 INC_SIZE(2);
619 *buf++ = REX_W;
620 *buf = 0x99;
621 }
622 #endif
623 }
624
625 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
626 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
627 FAIL_IF(!buf);
628 INC_SIZE(2);
629 *buf++ = 0xf7;
630 *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
631 #else
632 #ifdef _WIN64
633 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
634 #else
635 size = (!compiler->mode32) ? 3 : 2;
636 #endif
637 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
638 FAIL_IF(!buf);
639 INC_SIZE(size);
640 #ifdef _WIN64
641 if (!compiler->mode32)
642 *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
643 else if (op >= SLJIT_UDIV)
644 *buf++ = REX_B;
645 *buf++ = 0xf7;
646 *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
647 #else
648 if (!compiler->mode32)
649 *buf++ = REX_W;
650 *buf++ = 0xf7;
651 *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
652 #endif
653 #endif
654 switch (op) {
655 case SLJIT_UMUL:
656 *buf |= 4 << 3;
657 break;
658 case SLJIT_SMUL:
659 *buf |= 5 << 3;
660 break;
661 case SLJIT_UDIV:
662 *buf |= 6 << 3;
663 break;
664 case SLJIT_SDIV:
665 *buf |= 7 << 3;
666 break;
667 }
668 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
669 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
670 #endif
671 break;
672 }
673
674 return SLJIT_SUCCESS;
675 }
676
677 #define ENCODE_PREFIX(prefix) \
678 do { \
679 code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
680 FAIL_IF(!code); \
681 INC_CSIZE(1); \
682 *code = (prefix); \
683 } while (0)
684
685 static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
686 int dst, sljit_w dstw,
687 int src, sljit_w srcw)
688 {
689 sljit_ub* code;
690 int dst_r;
691 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
692 int work_r;
693 #endif
694
695 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
696 compiler->mode32 = 0;
697 #endif
698
699 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
700 return SLJIT_SUCCESS; /* Empty instruction. */
701
702 if (src & SLJIT_IMM) {
703 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
704 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
705 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
706 #else
707 return emit_load_imm64(compiler, dst, srcw);
708 #endif
709 }
710 code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
711 FAIL_IF(!code);
712 *code = 0xc6;
713 return SLJIT_SUCCESS;
714 }
715
716 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
717
718 if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
719 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
720 if (reg_map[src] >= 4) {
721 SLJIT_ASSERT(dst_r == TMP_REGISTER);
722 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
723 } else
724 dst_r = src;
725 #else
726 dst_r = src;
727 #endif
728 }
729 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
730 else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) {
731 /* src, dst are registers. */
732 SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER);
733 if (reg_map[dst] < 4) {
734 if (dst != src)
735 EMIT_MOV(compiler, dst, 0, src, 0);
736 code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
737 FAIL_IF(!code);
738 *code++ = 0x0f;
739 *code = sign ? 0xbe : 0xb6;
740 }
741 else {
742 if (dst != src)
743 EMIT_MOV(compiler, dst, 0, src, 0);
744 if (sign) {
745 /* shl reg, 24 */
746 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
747 FAIL_IF(!code);
748 *code |= 0x4 << 3;
749 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
750 FAIL_IF(!code);
751 /* shr/sar reg, 24 */
752 *code |= 0x7 << 3;
753 }
754 else {
755 /* and dst, 0xff */
756 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
757 FAIL_IF(!code);
758 *(code + 1) |= 0x4 << 3;
759 }
760 }
761 return SLJIT_SUCCESS;
762 }
763 #endif
764 else {
765 /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
766 code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
767 FAIL_IF(!code);
768 *code++ = 0x0f;
769 *code = sign ? 0xbe : 0xb6;
770 }
771
772 if (dst & SLJIT_MEM) {
773 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
774 if (dst_r == TMP_REGISTER) {
775 /* Find a non-used register, whose reg_map[src] < 4. */
776 if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) {
777 if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4))
778 work_r = SLJIT_TEMPORARY_REG3;
779 else
780 work_r = SLJIT_TEMPORARY_REG2;
781 }
782 else {
783 if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
784 work_r = SLJIT_TEMPORARY_REG1;
785 else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2)
786 work_r = SLJIT_TEMPORARY_REG3;
787 else
788 work_r = SLJIT_TEMPORARY_REG2;
789 }
790
791 if (work_r == SLJIT_TEMPORARY_REG1) {
792 ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
793 }
794 else {
795 code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
796 FAIL_IF(!code);
797 *code = 0x87;
798 }
799
800 code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
801 FAIL_IF(!code);
802 *code = 0x88;
803
804 if (work_r == SLJIT_TEMPORARY_REG1) {
805 ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
806 }
807 else {
808 code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
809 FAIL_IF(!code);
810 *code = 0x87;
811 }
812 }
813 else {
814 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
815 FAIL_IF(!code);
816 *code = 0x88;
817 }
818 #else
819 code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
820 FAIL_IF(!code);
821 *code = 0x88;
822 #endif
823 }
824
825 return SLJIT_SUCCESS;
826 }
827
828 static int emit_mov_half(struct sljit_compiler *compiler, int sign,
829 int dst, sljit_w dstw,
830 int src, sljit_w srcw)
831 {
832 sljit_ub* code;
833 int dst_r;
834
835 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
836 compiler->mode32 = 0;
837 #endif
838
839 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
840 return SLJIT_SUCCESS; /* Empty instruction. */
841
842 if (src & SLJIT_IMM) {
843 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
844 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
845 return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
846 #else
847 return emit_load_imm64(compiler, dst, srcw);
848 #endif
849 }
850 code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
851 FAIL_IF(!code);
852 *code = 0xc7;
853 return SLJIT_SUCCESS;
854 }
855
856 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
857
858 if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
859 dst_r = src;
860 else {
861 code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
862 FAIL_IF(!code);
863 *code++ = 0x0f;
864 *code = sign ? 0xbf : 0xb7;
865 }
866
867 if (dst & SLJIT_MEM) {
868 code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
869 FAIL_IF(!code);
870 *code = 0x89;
871 }
872
873 return SLJIT_SUCCESS;
874 }
875
876 static int emit_unary(struct sljit_compiler *compiler, int un_index,
877 int dst, sljit_w dstw,
878 int src, sljit_w srcw)
879 {
880 sljit_ub* code;
881
882 if (dst == SLJIT_UNUSED) {
883 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
884 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
885 FAIL_IF(!code);
886 *code++ = 0xf7;
887 *code |= (un_index) << 3;
888 return SLJIT_SUCCESS;
889 }
890 if (dst == src && dstw == srcw) {
891 /* Same input and output */
892 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
893 FAIL_IF(!code);
894 *code++ = 0xf7;
895 *code |= (un_index) << 3;
896 return SLJIT_SUCCESS;
897 }
898 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
899 EMIT_MOV(compiler, dst, 0, src, srcw);
900 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
901 FAIL_IF(!code);
902 *code++ = 0xf7;
903 *code |= (un_index) << 3;
904 return SLJIT_SUCCESS;
905 }
906 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
907 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
908 FAIL_IF(!code);
909 *code++ = 0xf7;
910 *code |= (un_index) << 3;
911 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
912 return SLJIT_SUCCESS;
913 }
914
915 static int emit_not_with_flags(struct sljit_compiler *compiler,
916 int dst, sljit_w dstw,
917 int src, sljit_w srcw)
918 {
919 sljit_ub* code;
920
921 if (dst == SLJIT_UNUSED) {
922 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
923 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
924 FAIL_IF(!code);
925 *code++ = 0xf7;
926 *code |= 0x2 << 3;
927 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
928 FAIL_IF(!code);
929 *code = 0x0b;
930 return SLJIT_SUCCESS;
931 }
932 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
933 EMIT_MOV(compiler, dst, 0, src, srcw);
934 code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
935 FAIL_IF(!code);
936 *code++ = 0xf7;
937 *code |= 0x2 << 3;
938 code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
939 FAIL_IF(!code);
940 *code = 0x0b;
941 return SLJIT_SUCCESS;
942 }
943 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
944 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
945 FAIL_IF(!code);
946 *code++ = 0xf7;
947 *code |= 0x2 << 3;
948 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
949 FAIL_IF(!code);
950 *code = 0x0b;
951 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
952 return SLJIT_SUCCESS;
953 }
954
955 static int emit_clz(struct sljit_compiler *compiler, int op,
956 int dst, sljit_w dstw,
957 int src, sljit_w srcw)
958 {
959 sljit_ub* code;
960 int dst_r;
961
962 SLJIT_UNUSED_ARG(op);
963 if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
964 /* Just set the zero flag. */
965 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
966 code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
967 FAIL_IF(!code);
968 *code++ = 0xf7;
969 *code |= 0x2 << 3;
970 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
971 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0);
972 #else
973 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
974 #endif
975 FAIL_IF(!code);
976 *code |= 0x5 << 3;
977 return SLJIT_SUCCESS;
978 }
979
980 if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
981 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
982 src = TMP_REGISTER;
983 srcw = 0;
984 }
985
986 code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
987 FAIL_IF(!code);
988 *code++ = 0x0f;
989 *code = 0xbd;
990
991 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
992 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
993 dst_r = dst;
994 else {
995 /* Find an unused temporary register. */
996 if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
997 dst_r = SLJIT_TEMPORARY_REG1;
998 else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4))
999 dst_r = SLJIT_TEMPORARY_REG2;
1000 else
1001 dst_r = SLJIT_TEMPORARY_REG3;
1002 EMIT_MOV(compiler, dst, dstw, dst_r, 0);
1003 }
1004 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
1005 #else
1006 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2;
1007 compiler->mode32 = 0;
1008 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31);
1009 compiler->mode32 = op & SLJIT_INT_OP;
1010 #endif
1011
1012 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
1013 FAIL_IF(!code);
1014 *code++ = 0x0f;
1015 *code = 0x45;
1016
1017 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1018 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
1019 #else
1020 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
1021 #endif
1022 FAIL_IF(!code);
1023 *(code + 1) |= 0x6 << 3;
1024
1025 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1026 if (dst & SLJIT_MEM) {
1027 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
1028 FAIL_IF(!code);
1029 *code = 0x87;
1030 }
1031 #else
1032 if (dst & SLJIT_MEM)
1033 EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
1034 #endif
1035 return SLJIT_SUCCESS;
1036 }
1037
1038 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
1039 int dst, sljit_w dstw,
1040 int src, sljit_w srcw)
1041 {
1042 sljit_ub* code;
1043 int update = 0;
1044 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1045 int dst_is_ereg = 0;
1046 int src_is_ereg = 0;
1047 #else
1048 #define src_is_ereg 0
1049 #endif
1050
1051 CHECK_ERROR();
1052 check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1053 ADJUST_LOCAL_OFFSET(dst, dstw);
1054 ADJUST_LOCAL_OFFSET(src, srcw);
1055
1056 CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
1057 CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
1058 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1059 compiler->mode32 = op & SLJIT_INT_OP;
1060 #endif
1061
1062 if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
1063 op = GET_OPCODE(op);
1064 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1065 compiler->mode32 = 0;
1066 #endif
1067
1068 SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
1069 if (op >= SLJIT_MOVU) {
1070 update = 1;
1071 op -= 7;
1072 }
1073
1074 if (src & SLJIT_IMM) {
1075 switch (op) {
1076 case SLJIT_MOV_UB:
1077 srcw = (unsigned char)srcw;
1078 break;
1079 case SLJIT_MOV_SB:
1080 srcw = (signed char)srcw;
1081 break;
1082 case SLJIT_MOV_UH:
1083 srcw = (unsigned short)srcw;
1084 break;
1085 case SLJIT_MOV_SH:
1086 srcw = (signed short)srcw;
1087 break;
1088 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1089 case SLJIT_MOV_UI:
1090 srcw = (unsigned int)srcw;
1091 break;
1092 case SLJIT_MOV_SI:
1093 srcw = (signed int)srcw;
1094 break;
1095 #endif
1096 }
1097 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1098 if (SLJIT_UNLIKELY(dst_is_ereg))
1099 return emit_mov(compiler, dst, dstw, src, srcw);
1100 #endif
1101 }
1102
1103 if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) {
1104 code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw);
1105 FAIL_IF(!code);
1106 *code = 0x8d;
1107 src &= SLJIT_MEM | 0xf;
1108 srcw = 0;
1109 }
1110
1111 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1112 if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) {
1113 SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
1114 dst = TMP_REGISTER;
1115 }
1116 #endif
1117
1118 switch (op) {
1119 case SLJIT_MOV:
1120 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1121 case SLJIT_MOV_UI:
1122 case SLJIT_MOV_SI:
1123 #endif
1124 FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
1125 break;
1126 case SLJIT_MOV_UB:
1127 FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
1128 break;
1129 case SLJIT_MOV_SB:
1130 FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
1131 break;
1132 case SLJIT_MOV_UH:
1133 FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
1134 break;
1135 case SLJIT_MOV_SH:
1136 FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
1137 break;
1138 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1139 case SLJIT_MOV_UI:
1140 FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
1141 break;
1142 case SLJIT_MOV_SI:
1143 FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
1144 break;
1145 #endif
1146 }
1147
1148 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1149 if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER)
1150 return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0);
1151 #endif
1152
1153 if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) {
1154 code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw);
1155 FAIL_IF(!code);
1156 *code = 0x8d;
1157 }
1158 return SLJIT_SUCCESS;
1159 }
1160
1161 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1162 compiler->flags_saved = 0;
1163
1164 switch (GET_OPCODE(op)) {
1165 case SLJIT_NOT:
1166 if (SLJIT_UNLIKELY(op & SLJIT_SET_E))
1167 return emit_not_with_flags(compiler, dst, dstw, src, srcw);
1168 return emit_unary(compiler, 0x2, dst, dstw, src, srcw);
1169
1170 case SLJIT_NEG:
1171 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1172 FAIL_IF(emit_save_flags(compiler));
1173 return emit_unary(compiler, 0x3, dst, dstw, src, srcw);
1174
1175 case SLJIT_CLZ:
1176 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1177 FAIL_IF(emit_save_flags(compiler));
1178 return emit_clz(compiler, op, dst, dstw, src, srcw);
1179 }
1180
1181 return SLJIT_SUCCESS;
1182
1183 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1184 #undef src_is_ereg
1185 #endif
1186 }
1187
1188 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1189
1190 #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1191 if (IS_HALFWORD(immw) || compiler->mode32) { \
1192 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1193 FAIL_IF(!code); \
1194 *(code + 1) |= (_op_imm_); \
1195 } \
1196 else { \
1197 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
1198 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
1199 FAIL_IF(!code); \
1200 *code = (_op_mr_); \
1201 }
1202
1203 #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1204 FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw))
1205
1206 #else
1207
1208 #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
1209 code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
1210 FAIL_IF(!code); \
1211 *(code + 1) |= (_op_imm_);
1212
1213 #define BINARY_EAX_IMM(_op_eax_imm_, immw) \
1214 FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
1215
1216 #endif
1217
1218 static int emit_cum_binary(struct sljit_compiler *compiler,
1219 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1220 int dst, sljit_w dstw,
1221 int src1, sljit_w src1w,
1222 int src2, sljit_w src2w)
1223 {
1224 sljit_ub* code;
1225
1226 if (dst == SLJIT_UNUSED) {
1227 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1228 if (src2 & SLJIT_IMM) {
1229 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1230 }
1231 else {
1232 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1233 FAIL_IF(!code);
1234 *code = op_rm;
1235 }
1236 return SLJIT_SUCCESS;
1237 }
1238
1239 if (dst == src1 && dstw == src1w) {
1240 if (src2 & SLJIT_IMM) {
1241 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1242 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1243 #else
1244 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1245 #endif
1246 BINARY_EAX_IMM(op_eax_imm, src2w);
1247 }
1248 else {
1249 BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1250 }
1251 }
1252 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1253 code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1254 FAIL_IF(!code);
1255 *code = op_rm;
1256 }
1257 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) {
1258 /* Special exception for sljit_emit_cond_value. */
1259 code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1260 FAIL_IF(!code);
1261 *code = op_mr;
1262 }
1263 else {
1264 EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1265 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1266 FAIL_IF(!code);
1267 *code = op_mr;
1268 }
1269 return SLJIT_SUCCESS;
1270 }
1271
1272 /* Only for cumulative operations. */
1273 if (dst == src2 && dstw == src2w) {
1274 if (src1 & SLJIT_IMM) {
1275 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1276 if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1277 #else
1278 if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
1279 #endif
1280 BINARY_EAX_IMM(op_eax_imm, src1w);
1281 }
1282 else {
1283 BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
1284 }
1285 }
1286 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1287 code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
1288 FAIL_IF(!code);
1289 *code = op_rm;
1290 }
1291 else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1292 code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
1293 FAIL_IF(!code);
1294 *code = op_mr;
1295 }
1296 else {
1297 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1298 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1299 FAIL_IF(!code);
1300 *code = op_mr;
1301 }
1302 return SLJIT_SUCCESS;
1303 }
1304
1305 /* General version. */
1306 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1307 EMIT_MOV(compiler, dst, 0, src1, src1w);
1308 if (src2 & SLJIT_IMM) {
1309 BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1310 }
1311 else {
1312 code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1313 FAIL_IF(!code);
1314 *code = op_rm;
1315 }
1316 }
1317 else {
1318 /* This version requires less memory writing. */
1319 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1320 if (src2 & SLJIT_IMM) {
1321 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1322 }
1323 else {
1324 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1325 FAIL_IF(!code);
1326 *code = op_rm;
1327 }
1328 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1329 }
1330
1331 return SLJIT_SUCCESS;
1332 }
1333
1334 static int emit_non_cum_binary(struct sljit_compiler *compiler,
1335 sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
1336 int dst, sljit_w dstw,
1337 int src1, sljit_w src1w,
1338 int src2, sljit_w src2w)
1339 {
1340 sljit_ub* code;
1341
1342 if (dst == SLJIT_UNUSED) {
1343 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1344 if (src2 & SLJIT_IMM) {
1345 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1346 }
1347 else {
1348 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1349 FAIL_IF(!code);
1350 *code = op_rm;
1351 }
1352 return SLJIT_SUCCESS;
1353 }
1354
1355 if (dst == src1 && dstw == src1w) {
1356 if (src2 & SLJIT_IMM) {
1357 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1358 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1359 #else
1360 if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
1361 #endif
1362 BINARY_EAX_IMM(op_eax_imm, src2w);
1363 }
1364 else {
1365 BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
1366 }
1367 }
1368 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1369 code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
1370 FAIL_IF(!code);
1371 *code = op_rm;
1372 }
1373 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1374 code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
1375 FAIL_IF(!code);
1376 *code = op_mr;
1377 }
1378 else {
1379 EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
1380 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
1381 FAIL_IF(!code);
1382 *code = op_mr;
1383 }
1384 return SLJIT_SUCCESS;
1385 }
1386
1387 /* General version. */
1388 if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) {
1389 EMIT_MOV(compiler, dst, 0, src1, src1w);
1390 if (src2 & SLJIT_IMM) {
1391 BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
1392 }
1393 else {
1394 code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
1395 FAIL_IF(!code);
1396 *code = op_rm;
1397 }
1398 }
1399 else {
1400 /* This version requires less memory writing. */
1401 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1402 if (src2 & SLJIT_IMM) {
1403 BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
1404 }
1405 else {
1406 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1407 FAIL_IF(!code);
1408 *code = op_rm;
1409 }
1410 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1411 }
1412
1413 return SLJIT_SUCCESS;
1414 }
1415
1416 static int emit_mul(struct sljit_compiler *compiler,
1417 int dst, sljit_w dstw,
1418 int src1, sljit_w src1w,
1419 int src2, sljit_w src2w)
1420 {
1421 sljit_ub* code;
1422 int dst_r;
1423
1424 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1425
1426 /* Register destination. */
1427 if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
1428 code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1429 FAIL_IF(!code);
1430 *code++ = 0x0f;
1431 *code = 0xaf;
1432 }
1433 else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
1434 code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
1435 FAIL_IF(!code);
1436 *code++ = 0x0f;
1437 *code = 0xaf;
1438 }
1439 else if (src1 & SLJIT_IMM) {
1440 if (src2 & SLJIT_IMM) {
1441 EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
1442 src2 = dst_r;
1443 src2w = 0;
1444 }
1445
1446 if (src1w <= 127 && src1w >= -128) {
1447 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1448 FAIL_IF(!code);
1449 *code = 0x6b;
1450 code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1451 FAIL_IF(!code);
1452 INC_CSIZE(1);
1453 *code = (sljit_b)src1w;
1454 }
1455 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1456 else {
1457 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1458 FAIL_IF(!code);
1459 *code = 0x69;
1460 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1461 FAIL_IF(!code);
1462 INC_CSIZE(4);
1463 *(sljit_w*)code = src1w;
1464 }
1465 #else
1466 else if (IS_HALFWORD(src1w)) {
1467 code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
1468 FAIL_IF(!code);
1469 *code = 0x69;
1470 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1471 FAIL_IF(!code);
1472 INC_CSIZE(4);
1473 *(sljit_hw*)code = (sljit_hw)src1w;
1474 }
1475 else {
1476 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1477 if (dst_r != src2)
1478 EMIT_MOV(compiler, dst_r, 0, src2, src2w);
1479 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1480 FAIL_IF(!code);
1481 *code++ = 0x0f;
1482 *code = 0xaf;
1483 }
1484 #endif
1485 }
1486 else if (src2 & SLJIT_IMM) {
1487 /* Note: src1 is NOT immediate. */
1488
1489 if (src2w <= 127 && src2w >= -128) {
1490 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1491 FAIL_IF(!code);
1492 *code = 0x6b;
1493 code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
1494 FAIL_IF(!code);
1495 INC_CSIZE(1);
1496 *code = (sljit_b)src2w;
1497 }
1498 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1499 else {
1500 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1501 FAIL_IF(!code);
1502 *code = 0x69;
1503 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1504 FAIL_IF(!code);
1505 INC_CSIZE(4);
1506 *(sljit_w*)code = src2w;
1507 }
1508 #else
1509 else if (IS_HALFWORD(src2w)) {
1510 code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
1511 FAIL_IF(!code);
1512 *code = 0x69;
1513 code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1514 FAIL_IF(!code);
1515 INC_CSIZE(4);
1516 *(sljit_hw*)code = (sljit_hw)src2w;
1517 }
1518 else {
1519 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
1520 if (dst_r != src1)
1521 EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1522 code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
1523 FAIL_IF(!code);
1524 *code++ = 0x0f;
1525 *code = 0xaf;
1526 }
1527 #endif
1528 }
1529 else {
1530 /* Neither argument is immediate. */
1531 if (ADDRESSING_DEPENDS_ON(src2, dst_r))
1532 dst_r = TMP_REGISTER;
1533 EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1534 code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
1535 FAIL_IF(!code);
1536 *code++ = 0x0f;
1537 *code = 0xaf;
1538 }
1539
1540 if (dst_r == TMP_REGISTER)
1541 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1542
1543 return SLJIT_SUCCESS;
1544 }
1545
1546 static int emit_lea_binary(struct sljit_compiler *compiler,
1547 int dst, sljit_w dstw,
1548 int src1, sljit_w src1w,
1549 int src2, sljit_w src2w)
1550 {
1551 sljit_ub* code;
1552 int dst_r, done = 0;
1553
1554 /* These cases better be left to handled by normal way. */
1555 if (dst == src1 && dstw == src1w)
1556 return SLJIT_ERR_UNSUPPORTED;
1557 if (dst == src2 && dstw == src2w)
1558 return SLJIT_ERR_UNSUPPORTED;
1559
1560 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
1561
1562 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1563 if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) {
1564 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
1565 FAIL_IF(!code);
1566 *code = 0x8d;
1567 done = 1;
1568 }
1569 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1570 if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1571 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w);
1572 #else
1573 if (src2 & SLJIT_IMM) {
1574 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
1575 #endif
1576 FAIL_IF(!code);
1577 *code = 0x8d;
1578 done = 1;
1579 }
1580 }
1581 else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1582 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1583 if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1584 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w);
1585 #else
1586 if (src1 & SLJIT_IMM) {
1587 code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
1588 #endif
1589 FAIL_IF(!code);
1590 *code = 0x8d;
1591 done = 1;
1592 }
1593 }
1594
1595 if (done) {
1596 if (dst_r == TMP_REGISTER)
1597 return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
1598 return SLJIT_SUCCESS;
1599 }
1600 return SLJIT_ERR_UNSUPPORTED;
1601 }
1602
1603 static int emit_cmp_binary(struct sljit_compiler *compiler,
1604 int src1, sljit_w src1w,
1605 int src2, sljit_w src2w)
1606 {
1607 sljit_ub* code;
1608
1609 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1610 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1611 #else
1612 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1613 #endif
1614 BINARY_EAX_IMM(0x3d, src2w);
1615 return SLJIT_SUCCESS;
1616 }
1617
1618 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1619 if (src2 & SLJIT_IMM) {
1620 BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
1621 }
1622 else {
1623 code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1624 FAIL_IF(!code);
1625 *code = 0x3b;
1626 }
1627 return SLJIT_SUCCESS;
1628 }
1629
1630 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
1631 code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1632 FAIL_IF(!code);
1633 *code = 0x39;
1634 return SLJIT_SUCCESS;
1635 }
1636
1637 if (src2 & SLJIT_IMM) {
1638 if (src1 & SLJIT_IMM) {
1639 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1640 src1 = TMP_REGISTER;
1641 src1w = 0;
1642 }
1643 BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
1644 }
1645 else {
1646 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1647 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1648 FAIL_IF(!code);
1649 *code = 0x3b;
1650 }
1651 return SLJIT_SUCCESS;
1652 }
1653
1654 static int emit_test_binary(struct sljit_compiler *compiler,
1655 int src1, sljit_w src1w,
1656 int src2, sljit_w src2w)
1657 {
1658 sljit_ub* code;
1659
1660 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1661 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
1662 #else
1663 if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
1664 #endif
1665 BINARY_EAX_IMM(0xa9, src2w);
1666 return SLJIT_SUCCESS;
1667 }
1668
1669 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1670 if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
1671 #else
1672 if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
1673 #endif
1674 BINARY_EAX_IMM(0xa9, src1w);
1675 return SLJIT_SUCCESS;
1676 }
1677
1678 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1679 if (src2 & SLJIT_IMM) {
1680 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1681 if (IS_HALFWORD(src2w) || compiler->mode32) {
1682 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1683 FAIL_IF(!code);
1684 *code = 0xf7;
1685 }
1686 else {
1687 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1688 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
1689 FAIL_IF(!code);
1690 *code = 0x85;
1691 }
1692 #else
1693 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
1694 FAIL_IF(!code);
1695 *code = 0xf7;
1696 #endif
1697 }
1698 else {
1699 code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
1700 FAIL_IF(!code);
1701 *code = 0x85;
1702 }
1703 return SLJIT_SUCCESS;
1704 }
1705
1706 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
1707 if (src1 & SLJIT_IMM) {
1708 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1709 if (IS_HALFWORD(src1w) || compiler->mode32) {
1710 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
1711 FAIL_IF(!code);
1712 *code = 0xf7;
1713 }
1714 else {
1715 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
1716 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
1717 FAIL_IF(!code);
1718 *code = 0x85;
1719 }
1720 #else
1721 code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
1722 FAIL_IF(!code);
1723 *code = 0xf7;
1724 #endif
1725 }
1726 else {
1727 code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
1728 FAIL_IF(!code);
1729 *code = 0x85;
1730 }
1731 return SLJIT_SUCCESS;
1732 }
1733
1734 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1735 if (src2 & SLJIT_IMM) {
1736 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1737 if (IS_HALFWORD(src2w) || compiler->mode32) {
1738 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1739 FAIL_IF(!code);
1740 *code = 0xf7;
1741 }
1742 else {
1743 FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
1744 code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
1745 FAIL_IF(!code);
1746 *code = 0x85;
1747 }
1748 #else
1749 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
1750 FAIL_IF(!code);
1751 *code = 0xf7;
1752 #endif
1753 }
1754 else {
1755 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
1756 FAIL_IF(!code);
1757 *code = 0x85;
1758 }
1759 return SLJIT_SUCCESS;
1760 }
1761
1762 static int emit_shift(struct sljit_compiler *compiler,
1763 sljit_ub mode,
1764 int dst, sljit_w dstw,
1765 int src1, sljit_w src1w,
1766 int src2, sljit_w src2w)
1767 {
1768 sljit_ub* code;
1769
1770 if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
1771 if (dst == src1 && dstw == src1w) {
1772 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
1773 FAIL_IF(!code);
1774 *code |= mode;
1775 return SLJIT_SUCCESS;
1776 }
1777 if (dst == SLJIT_UNUSED) {
1778 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1779 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1780 FAIL_IF(!code);
1781 *code |= mode;
1782 return SLJIT_SUCCESS;
1783 }
1784 if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
1785 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1786 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1787 FAIL_IF(!code);
1788 *code |= mode;
1789 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1790 return SLJIT_SUCCESS;
1791 }
1792 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
1793 EMIT_MOV(compiler, dst, 0, src1, src1w);
1794 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
1795 FAIL_IF(!code);
1796 *code |= mode;
1797 return SLJIT_SUCCESS;
1798 }
1799
1800 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1801 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
1802 FAIL_IF(!code);
1803 *code |= mode;
1804 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1805 return SLJIT_SUCCESS;
1806 }
1807
1808 if (dst == SLJIT_PREF_SHIFT_REG) {
1809 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1810 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1811 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1812 FAIL_IF(!code);
1813 *code |= mode;
1814 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1815 }
1816 else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
1817 if (src1 != dst)
1818 EMIT_MOV(compiler, dst, 0, src1, src1w);
1819 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
1820 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1821 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
1822 FAIL_IF(!code);
1823 *code |= mode;
1824 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1825 }
1826 else {
1827 /* This case is really difficult, since ecx itself may used for
1828 addressing, and we must ensure to work even in that case. */
1829 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1830 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1831 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1832 #else
1833 /* [esp+0] contains the flags. */
1834 EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w), SLJIT_PREF_SHIFT_REG, 0);
1835 #endif
1836 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1837 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1838 FAIL_IF(!code);
1839 *code |= mode;
1840 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1841 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1842 #else
1843 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w));
1844 #endif
1845 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1846 }
1847
1848 return SLJIT_SUCCESS;
1849 }
1850
1851 static int emit_shift_with_flags(struct sljit_compiler *compiler,
1852 sljit_ub mode, int set_flags,
1853 int dst, sljit_w dstw,
1854 int src1, sljit_w src1w,
1855 int src2, sljit_w src2w)
1856 {
1857 /* The CPU does not set flags if the shift count is 0. */
1858 if (src2 & SLJIT_IMM) {
1859 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1860 if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
1861 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1862 #else
1863 if ((src2w & 0x1f) != 0)
1864 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1865 #endif
1866 if (!set_flags)
1867 return emit_mov(compiler, dst, dstw, src1, src1w);
1868 /* OR dst, src, 0 */
1869 return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1870 dst, dstw, src1, src1w, SLJIT_IMM, 0);
1871 }
1872
1873 if (!set_flags)
1874 return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1875
1876 if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
1877 FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
1878
1879 FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
1880
1881 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
1882 return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
1883 return SLJIT_SUCCESS;
1884 }
1885
1886 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
1887 int dst, sljit_w dstw,
1888 int src1, sljit_w src1w,
1889 int src2, sljit_w src2w)
1890 {
1891 CHECK_ERROR();
1892 check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1893 ADJUST_LOCAL_OFFSET(dst, dstw);
1894 ADJUST_LOCAL_OFFSET(src1, src1w);
1895 ADJUST_LOCAL_OFFSET(src2, src2w);
1896
1897 CHECK_EXTRA_REGS(dst, dstw, (void)0);
1898 CHECK_EXTRA_REGS(src1, src1w, (void)0);
1899 CHECK_EXTRA_REGS(src2, src2w, (void)0);
1900 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1901 compiler->mode32 = op & SLJIT_INT_OP;
1902 #endif
1903
1904 if (GET_OPCODE(op) >= SLJIT_MUL) {
1905 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1906 compiler->flags_saved = 0;
1907 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1908 FAIL_IF(emit_save_flags(compiler));
1909 }
1910
1911 switch (GET_OPCODE(op)) {
1912 case SLJIT_ADD:
1913 if (!GET_FLAGS(op)) {
1914 if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
1915 return compiler->error;
1916 }
1917 else
1918 compiler->flags_saved = 0;
1919 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1920 FAIL_IF(emit_save_flags(compiler));
1921 return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
1922 dst, dstw, src1, src1w, src2, src2w);
1923 case SLJIT_ADDC:
1924 if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1925 FAIL_IF(emit_restore_flags(compiler, 1));
1926 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1927 FAIL_IF(emit_save_flags(compiler));
1928 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1929 compiler->flags_saved = 0;
1930 return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15,
1931 dst, dstw, src1, src1w, src2, src2w);
1932 case SLJIT_SUB:
1933 if (!GET_FLAGS(op)) {
1934 if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
1935 return compiler->error;
1936 }
1937 else
1938 compiler->flags_saved = 0;
1939 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
1940 FAIL_IF(emit_save_flags(compiler));
1941 if (dst == SLJIT_UNUSED)
1942 return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
1943 return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
1944 dst, dstw, src1, src1w, src2, src2w);
1945 case SLJIT_SUBC:
1946 if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
1947 FAIL_IF(emit_restore_flags(compiler, 1));
1948 else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
1949 FAIL_IF(emit_save_flags(compiler));
1950 if (SLJIT_UNLIKELY(GET_FLAGS(op)))
1951 compiler->flags_saved = 0;
1952 return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d,
1953 dst, dstw, src1, src1w, src2, src2w);
1954 case SLJIT_MUL:
1955 return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
1956 case SLJIT_AND:
1957 if (dst == SLJIT_UNUSED)
1958 return emit_test_binary(compiler, src1, src1w, src2, src2w);
1959 return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25,
1960 dst, dstw, src1, src1w, src2, src2w);
1961 case SLJIT_OR:
1962 return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1963 dst, dstw, src1, src1w, src2, src2w);
1964 case SLJIT_XOR:
1965 return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1966 dst, dstw, src1, src1w, src2, src2w);
1967 case SLJIT_SHL:
1968 return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
1969 dst, dstw, src1, src1w, src2, src2w);
1970 case SLJIT_LSHR:
1971 return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
1972 dst, dstw, src1, src1w, src2, src2w);
1973 case SLJIT_ASHR:
1974 return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
1975 dst, dstw, src1, src1w, src2, src2w);
1976 }
1977
1978 return SLJIT_SUCCESS;
1979 }
1980
1981 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
1982 {
1983 check_sljit_get_register_index(reg);
1984 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1985 if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1986 || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
1987 return -1;
1988 #endif
1989 return reg_map[reg];
1990 }
1991
1992 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
1993 void *instruction, int size)
1994 {
1995 sljit_ub *buf;
1996
1997 CHECK_ERROR();
1998 check_sljit_emit_op_custom(compiler, instruction, size);
1999 SLJIT_ASSERT(size > 0 && size < 16);
2000
2001 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
2002 FAIL_IF(!buf);
2003 INC_SIZE(size);
2004 SLJIT_MEMMOVE(buf, instruction, size);
2005 return SLJIT_SUCCESS;
2006 }
2007
2008 /* --------------------------------------------------------------------- */
2009 /* Floating point operators */
2010 /* --------------------------------------------------------------------- */
2011
2012 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2013
2014 /* Alignment + 2 * 16 bytes. */
2015 static sljit_i sse2_data[3 + 4 + 4];
2016 static sljit_i *sse2_buffer;
2017
2018 static void init_compiler()
2019 {
2020 sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
2021 sse2_buffer[0] = 0;
2022 sse2_buffer[1] = 0x80000000;
2023 sse2_buffer[4] = 0xffffffff;
2024 sse2_buffer[5] = 0x7fffffff;
2025 }
2026
2027 #endif
2028
2029 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2030 {
2031 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2032 #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
2033 static int sse2_available = -1;
2034 int features;
2035
2036 if (sse2_available != -1)
2037 return sse2_available;
2038
2039 #ifdef __GNUC__
2040 /* AT&T syntax. */
2041 asm (
2042 "pushl %%ebx\n"
2043 "movl $0x1, %%eax\n"
2044 "cpuid\n"
2045 "popl %%ebx\n"
2046 "movl %%edx, %0\n"
2047 : "=g" (features)
2048 :
2049 : "%eax", "%ecx", "%edx"
2050 );
2051 #elif defined(_MSC_VER) || defined(__BORLANDC__)
2052 /* Intel syntax. */
2053 __asm {
2054 mov eax, 1
2055 push ebx
2056 cpuid
2057 pop ebx
2058 mov features, edx
2059 }
2060 #else
2061 #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
2062 #endif
2063 sse2_available = (features >> 26) & 0x1;
2064 return sse2_available;
2065 #else
2066 return 1;
2067 #endif
2068 #else
2069 return 0;
2070 #endif
2071 }
2072
2073 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2074
2075 static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
2076 int xmm1, int xmm2, sljit_w xmm2w)
2077 {
2078 sljit_ub *buf;
2079
2080 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2081 FAIL_IF(!buf);
2082 *buf++ = 0x0f;
2083 *buf = opcode;
2084 return SLJIT_SUCCESS;
2085 }
2086
2087 static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
2088 int xmm1, int xmm2, sljit_w xmm2w)
2089 {
2090 sljit_ub *buf;
2091
2092 buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
2093 FAIL_IF(!buf);
2094 *buf++ = 0x0f;
2095 *buf = opcode;
2096 return SLJIT_SUCCESS;
2097 }
2098
2099 static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
2100 int dst, int src, sljit_w srcw)
2101 {
2102 return emit_sse2(compiler, 0x10, dst, src, srcw);
2103 }
2104
2105 static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
2106 int dst, sljit_w dstw, int src)
2107 {
2108 return emit_sse2(compiler, 0x11, src, dst, dstw);
2109 }
2110
2111 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2112 int dst, sljit_w dstw,
2113 int src, sljit_w srcw)
2114 {
2115 int dst_r;
2116
2117 CHECK_ERROR();
2118 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2119
2120 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2121 compiler->mode32 = 1;
2122 #endif
2123
2124 if (GET_OPCODE(op) == SLJIT_FCMP) {
2125 compiler->flags_saved = 0;
2126 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
2127 dst_r = dst;
2128 else {
2129 dst_r = TMP_FREG;
2130 FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
2131 }
2132 return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
2133 }
2134
2135 if (op == SLJIT_FMOV) {
2136 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
2137 return emit_sse2_load(compiler, dst, src, srcw);
2138 if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
2139 return emit_sse2_store(compiler, dst, dstw, src);
2140 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
2141 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2142 }
2143
2144 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2145 dst_r = dst;
2146 if (dst != src)
2147 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2148 }
2149 else {
2150 dst_r = TMP_FREG;
2151 FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
2152 }
2153
2154 switch (op) {
2155 case SLJIT_FNEG:
2156 FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
2157 break;
2158
2159 case SLJIT_FABS:
2160 FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
2161 break;
2162 }
2163
2164 if (dst_r == TMP_FREG)
2165 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2166 return SLJIT_SUCCESS;
2167 }
2168
2169 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2170 int dst, sljit_w dstw,
2171 int src1, sljit_w src1w,
2172 int src2, sljit_w src2w)
2173 {
2174 int dst_r;
2175
2176 CHECK_ERROR();
2177 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2178
2179 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2180 compiler->mode32 = 1;
2181 #endif
2182
2183 if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
2184 dst_r = dst;
2185 if (dst == src1)
2186 ; /* Do nothing here. */
2187 else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
2188 /* Swap arguments. */
2189 src2 = src1;
2190 src2w = src1w;
2191 }
2192 else if (dst != src2)
2193 FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
2194 else {
2195 dst_r = TMP_FREG;
2196 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2197 }
2198 }
2199 else {
2200 dst_r = TMP_FREG;
2201 FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
2202 }
2203
2204 switch (op) {
2205 case SLJIT_FADD:
2206 FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
2207 break;
2208
2209 case SLJIT_FSUB:
2210 FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
2211 break;
2212
2213 case SLJIT_FMUL:
2214 FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
2215 break;
2216
2217 case SLJIT_FDIV:
2218 FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
2219 break;
2220 }
2221
2222 if (dst_r == TMP_FREG)
2223 return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
2224 return SLJIT_SUCCESS;
2225 }
2226
2227 #else
2228
2229 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2230 int dst, sljit_w dstw,
2231 int src, sljit_w srcw)
2232 {
2233 CHECK_ERROR();
2234 /* Should cause an assertion fail. */
2235 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2236 compiler->error = SLJIT_ERR_UNSUPPORTED;
2237 return SLJIT_ERR_UNSUPPORTED;
2238 }
2239
2240 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2241 int dst, sljit_w dstw,
2242 int src1, sljit_w src1w,
2243 int src2, sljit_w src2w)
2244 {
2245 CHECK_ERROR();
2246 /* Should cause an assertion fail. */
2247 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2248 compiler->error = SLJIT_ERR_UNSUPPORTED;
2249 return SLJIT_ERR_UNSUPPORTED;
2250 }
2251
2252 #endif
2253
2254 /* --------------------------------------------------------------------- */
2255 /* Conditional instructions */
2256 /* --------------------------------------------------------------------- */
2257
2258 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2259 {
2260 sljit_ub *buf;
2261 struct sljit_label *label;
2262
2263 CHECK_ERROR_PTR();
2264 check_sljit_emit_label(compiler);
2265
2266 /* We should restore the flags before the label,
2267 since other taken jumps has their own flags as well. */
2268 if (SLJIT_UNLIKELY(compiler->flags_saved))
2269 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2270
2271 if (compiler->last_label && compiler->last_label->size == compiler->size)
2272 return compiler->last_label;
2273
2274 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2275 PTR_FAIL_IF(!label);
2276 set_label(label, compiler);
2277
2278 buf = (sljit_ub*)ensure_buf(compiler, 2);
2279 PTR_FAIL_IF(!buf);
2280
2281 *buf++ = 0;
2282 *buf++ = 0;
2283
2284 return label;
2285 }
2286
2287 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2288 {
2289 sljit_ub *buf;
2290 struct sljit_jump *jump;
2291
2292 CHECK_ERROR_PTR();
2293 check_sljit_emit_jump(compiler, type);
2294
2295 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2296 if ((type & 0xff) <= SLJIT_JUMP)
2297 PTR_FAIL_IF(emit_restore_flags(compiler, 0));
2298 compiler->flags_saved = 0;
2299 }
2300
2301 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2302 PTR_FAIL_IF_NULL(jump);
2303 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2304 type &= 0xff;
2305
2306 if (type >= SLJIT_CALL1)
2307 PTR_FAIL_IF(call_with_args(compiler, type));
2308
2309 /* Worst case size. */
2310 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2311 compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
2312 #else
2313 compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
2314 #endif
2315
2316 buf = (sljit_ub*)ensure_buf(compiler, 2);
2317 PTR_FAIL_IF_NULL(buf);
2318
2319 *buf++ = 0;
2320 *buf++ = type + 4;
2321 return jump;
2322 }
2323
2324 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2325 {
2326 sljit_ub *code;
2327 struct sljit_jump *jump;
2328
2329 CHECK_ERROR();
2330 check_sljit_emit_ijump(compiler, type, src, srcw);
2331 ADJUST_LOCAL_OFFSET(src, srcw);
2332
2333 CHECK_EXTRA_REGS(src, srcw, (void)0);
2334
2335 if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2336 if (type <= SLJIT_JUMP)
2337 FAIL_IF(emit_restore_flags(compiler, 0));
2338 compiler->flags_saved = 0;
2339 }
2340
2341 if (type >= SLJIT_CALL1) {
2342 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2343 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
2344 if (src == SLJIT_TEMPORARY_REG3) {
2345 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2346 src = TMP_REGISTER;
2347 }
2348 if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
2349 srcw += sizeof(sljit_w);
2350 #else
2351 if (src == SLJIT_MEM1(SLJIT_LOCALS_REG))
2352 srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
2353 #endif
2354 #endif
2355 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
2356 if (src == SLJIT_TEMPORARY_REG3) {
2357 EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2358 src = TMP_REGISTER;
2359 }
2360 #endif
2361 FAIL_IF(call_with_args(compiler, type));
2362 }
2363
2364 if (src == SLJIT_IMM) {
2365 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2366 FAIL_IF_NULL(jump);
2367 set_jump(jump, compiler, JUMP_ADDR);
2368 jump->u.target = srcw;
2369
2370 /* Worst case size. */
2371 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2372 compiler->size += 5;
2373 #else
2374 compiler->size += 10 + 3;
2375 #endif
2376
2377 code = (sljit_ub*)ensure_buf(compiler, 2);
2378 FAIL_IF_NULL(code);
2379
2380 *code++ = 0;
2381 *code++ = type + 4;
2382 }
2383 else {
2384 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2385 /* REX_W is not necessary (src is not immediate). */
2386 compiler->mode32 = 1;
2387 #endif
2388 code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2389 FAIL_IF(!code);
2390 *code++ = 0xff;
2391 *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2392 }
2393 return SLJIT_SUCCESS;
2394 }
2395
2396 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2397 {
2398 sljit_ub *buf;
2399 sljit_ub cond_set = 0;
2400 int dst_save = dst;
2401 sljit_w dstw_save = dstw;
2402 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2403 int reg;
2404 #endif
2405
2406 CHECK_ERROR();
2407 check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
2408
2409 if (dst == SLJIT_UNUSED)
2410 return SLJIT_SUCCESS;
2411
2412 ADJUST_LOCAL_OFFSET(dst, dstw);
2413 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2414 if (SLJIT_UNLIKELY(compiler->flags_saved))
2415 FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
2416
2417 switch (type) {
2418 case SLJIT_C_EQUAL:
2419 case SLJIT_C_FLOAT_EQUAL:
2420 cond_set = 0x94;
2421 break;
2422
2423 case SLJIT_C_NOT_EQUAL:
2424 case SLJIT_C_FLOAT_NOT_EQUAL:
2425 cond_set = 0x95;
2426 break;
2427
2428 case SLJIT_C_LESS:
2429 case SLJIT_C_FLOAT_LESS:
2430 cond_set = 0x92;
2431 break;
2432
2433 case SLJIT_C_GREATER_EQUAL:
2434 case SLJIT_C_FLOAT_GREATER_EQUAL:
2435 cond_set = 0x93;
2436 break;
2437
2438 case SLJIT_C_GREATER:
2439 case SLJIT_C_FLOAT_GREATER:
2440 cond_set = 0x97;
2441 break;
2442
2443 case SLJIT_C_LESS_EQUAL:
2444 case SLJIT_C_FLOAT_LESS_EQUAL:
2445 cond_set = 0x96;
2446 break;
2447
2448 case SLJIT_C_SIG_LESS:
2449 cond_set = 0x9c;
2450 break;
2451
2452 case SLJIT_C_SIG_GREATER_EQUAL:
2453 cond_set = 0x9d;
2454 break;
2455
2456 case SLJIT_C_SIG_GREATER:
2457 cond_set = 0x9f;
2458 break;
2459
2460 case SLJIT_C_SIG_LESS_EQUAL:
2461 cond_set = 0x9e;
2462 break;
2463
2464 case SLJIT_C_OVERFLOW:
2465 case SLJIT_C_MUL_OVERFLOW:
2466 cond_set = 0x90;
2467 break;
2468
2469 case SLJIT_C_NOT_OVERFLOW:
2470 case SLJIT_C_MUL_NOT_OVERFLOW:
2471 cond_set = 0x91;
2472 break;
2473
2474 case SLJIT_C_FLOAT_NAN:
2475 cond_set = 0x9a;
2476 break;
2477
2478 case SLJIT_C_FLOAT_NOT_NAN:
2479 cond_set = 0x9b;
2480 break;
2481 }
2482
2483 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2484 reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2485
2486 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
2487 FAIL_IF(!buf);
2488 INC_SIZE(4 + 4);
2489 /* Set low register to conditional flag. */
2490 *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
2491 *buf++ = 0x0f;
2492 *buf++ = cond_set;
2493 *buf++ = 0xC0 | reg_lmap[reg];
2494 *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
2495 *buf++ = 0x0f;
2496 *buf++ = 0xb6;
2497 *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
2498
2499 if (reg == TMP_REGISTER) {
2500 if (op == SLJIT_MOV) {
2501 compiler->mode32 = 0;
2502 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
2503 }
2504 else {
2505 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2506 compiler->skip_checks = 1;
2507 #endif
2508 return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0);
2509 }
2510 }
2511 #else
2512 if (op == SLJIT_MOV) {
2513 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2514 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2515 FAIL_IF(!buf);
2516 INC_SIZE(3 + 3);
2517 /* Set low byte to conditional flag. */
2518 *buf++ = 0x0f;
2519 *buf++ = cond_set;
2520 *buf++ = 0xC0 | reg_map[dst];
2521
2522 *buf++ = 0x0f;
2523 *buf++ = 0xb6;
2524 *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
2525 }
2526 else {
2527 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2528
2529 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
2530 FAIL_IF(!buf);
2531 INC_SIZE(3 + 3);
2532 /* Set al to conditional flag. */
2533 *buf++ = 0x0f;
2534 *buf++ = cond_set;
2535 *buf++ = 0xC0;
2536
2537 *buf++ = 0x0f;
2538 *buf++ = 0xb6;
2539 if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
2540 *buf = 0xC0 | (reg_map[dst] << 3);
2541 else {
2542 *buf = 0xC0;
2543 EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
2544 }
2545
2546 EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
2547 }
2548 }
2549 else {
2550 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
2551 EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
2552 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
2553 FAIL_IF(!buf);
2554 INC_SIZE(3);
2555
2556 *buf++ = 0x0f;
2557 *buf++ = cond_set;
2558 *buf++ = 0xC0 | reg_map[dst];
2559 }
2560 else {
2561 EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
2562
2563 buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
2564 FAIL_IF(!buf);
2565 INC_SIZE(3 + 3 + 1);
2566 /* Set al to conditional flag. */
2567 *buf++ = 0x0f;
2568 *buf++ = cond_set;
2569 *buf++ = 0xC0;
2570
2571 *buf++ = 0x0f;
2572 *buf++ = 0xb6;
2573 *buf++ = 0xC0;
2574
2575 *buf++ = 0x90 + reg_map[TMP_REGISTER];
2576 }
2577 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2578 compiler->skip_checks = 1;
2579 #endif
2580 return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0);
2581 }
2582 #endif
2583
2584 return SLJIT_SUCCESS;
2585 }
2586
2587 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset)
2588 {
2589 CHECK_ERROR();
2590 check_sljit_get_local_base(compiler, dst, dstw, offset);
2591 ADJUST_LOCAL_OFFSET(dst, dstw);
2592
2593 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2594
2595 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2596 compiler->mode32 = 0;
2597 #endif
2598
2599 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
2600
2601 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2602 if (NOT_HALFWORD(offset)) {
2603 FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
2604 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
2605 SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
2606 return compiler->error;
2607 #else
2608 return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
2609 #endif
2610 }
2611 #endif
2612
2613 return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
2614 }
2615
2616 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
2617 {
2618 sljit_ub *buf;
2619 struct sljit_const *const_;
2620 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2621 int reg;
2622 #endif
2623
2624 CHECK_ERROR_PTR();
2625 check_sljit_emit_const(compiler, dst, dstw, init_value);
2626 ADJUST_LOCAL_OFFSET(dst, dstw);
2627
2628 CHECK_EXTRA_REGS(dst, dstw, (void)0);
2629
2630 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2631 PTR_FAIL_IF(!const_);
2632 set_const(const_, compiler);
2633
2634 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2635 compiler->mode32 = 0;
2636 reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
2637
2638 if (emit_load_imm64(compiler, reg, init_value))
2639 return NULL;
2640 #else
2641 if (dst == SLJIT_UNUSED)
2642 dst = TMP_REGISTER;
2643
2644 if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
2645 return NULL;
2646 #endif
2647
2648 buf = (sljit_ub*)ensure_buf(compiler, 2);
2649 PTR_FAIL_IF(!buf);
2650
2651 *buf++ = 0;
2652 *buf++ = 1;
2653
2654 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2655 if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
2656 if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
2657 return NULL;
2658 #endif
2659
2660 return const_;
2661 }
2662
2663 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2664 {
2665 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2666 *(sljit_w*)addr = new_addr - (addr + 4);
2667 #else
2668 *(sljit_uw*)addr = new_addr;
2669 #endif
2670 }
2671
2672 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2673 {
2674 *(sljit_w*)addr = new_constant;
2675 }

  ViewVC Help
Powered by ViewVC 1.1.5