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

  ViewVC Help
Powered by ViewVC 1.1.5