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

  ViewVC Help
Powered by ViewVC 1.1.5