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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 722 - (show annotations)
Fri Oct 7 19:18:55 2011 UTC (8 years ago) by zherczeg
File MIME type: text/plain
File size: 21688 byte(s)
Error occurred while calculating annotation data.
JIT compiler update: Make fast_call a separate call type. Allows call optimizations on MIPS.
1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 /* x86 64-bit arch dependent functions. */
28
29 static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
30 {
31 sljit_ub *buf;
32
33 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));
34 FAIL_IF(!buf);
35 INC_SIZE(2 + sizeof(sljit_w));
36 *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
37 *buf++ = 0xb8 + (reg_map[reg] & 0x7);
38 *(sljit_w*)buf = imm;
39 return SLJIT_SUCCESS;
40 }
41
42 static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
43 {
44 if (type < SLJIT_JUMP) {
45 *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
46 *code_ptr++ = 10 + 3;
47 }
48
49 SLJIT_ASSERT(reg_map[TMP_REG3] == 9);
50 *code_ptr++ = REX_W | REX_B;
51 *code_ptr++ = 0xb8 + 1;
52 jump->addr = (sljit_uw)code_ptr;
53
54 if (jump->flags & JUMP_LABEL)
55 jump->flags |= PATCH_MD;
56 else
57 *(sljit_w*)code_ptr = jump->u.target;
58
59 code_ptr += sizeof(sljit_w);
60 *code_ptr++ = REX_B;
61 *code_ptr++ = 0xff;
62 *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
63
64 return code_ptr;
65 }
66
67 static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
68 {
69 sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
70
71 if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
72 *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
73 *(sljit_w*)code_ptr = delta;
74 }
75 else {
76 SLJIT_ASSERT(reg_map[TMP_REG3] == 9);
77 *code_ptr++ = REX_W | REX_B;
78 *code_ptr++ = 0xb8 + 1;
79 *(sljit_w*)code_ptr = addr;
80 code_ptr += sizeof(sljit_w);
81 *code_ptr++ = REX_B;
82 *code_ptr++ = 0xff;
83 *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
84 }
85
86 return code_ptr;
87 }
88
89 int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
90 {
91 int size;
92 sljit_ub *buf;
93
94 CHECK_ERROR();
95 check_sljit_emit_enter(compiler, args, temporaries, generals, local_size);
96
97 compiler->temporaries = temporaries;
98 compiler->generals = generals;
99 compiler->flags_saved = 0;
100
101 size = generals;
102 #ifndef _WIN64
103 if (generals >= 2)
104 size += generals - 1;
105 #else
106 if (local_size > 0)
107 size += 2;
108 if (generals >= 4)
109 size += generals - 3;
110 if (temporaries >= 5)
111 size += (5 - 4) * 2;
112 #endif
113 size += args * 3;
114 if (size > 0) {
115 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
116 FAIL_IF(!buf);
117
118 INC_SIZE(size);
119 if (generals >= 5) {
120 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_EREG2] >= 8);
121 *buf++ = REX_B;
122 PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG2]);
123 }
124 if (generals >= 4) {
125 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_EREG1] >= 8);
126 *buf++ = REX_B;
127 PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG1]);
128 }
129 if (generals >= 3) {
130 #ifndef _WIN64
131 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_REG3] >= 8);
132 *buf++ = REX_B;
133 #else
134 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_REG3] < 8);
135 #endif
136 PUSH_REG(reg_lmap[SLJIT_GENERAL_REG3]);
137 }
138 if (generals >= 2) {
139 #ifndef _WIN64
140 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_REG2] >= 8);
141 *buf++ = REX_B;
142 #else
143 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_REG2] < 8);
144 #endif
145 PUSH_REG(reg_lmap[SLJIT_GENERAL_REG2]);
146 }
147 if (generals >= 1) {
148 SLJIT_ASSERT(reg_map[SLJIT_GENERAL_REG1] < 8);
149 PUSH_REG(reg_lmap[SLJIT_GENERAL_REG1]);
150 }
151 #ifdef _WIN64
152 if (temporaries >= 5) {
153 SLJIT_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8);
154 *buf++ = REX_B;
155 PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
156 }
157 if (local_size > 0) {
158 SLJIT_ASSERT(reg_map[SLJIT_LOCALS_REG] >= 8);
159 *buf++ = REX_B;
160 PUSH_REG(reg_lmap[SLJIT_LOCALS_REG]);
161 }
162 #endif
163
164 #ifndef _WIN64
165 if (args > 0) {
166 *buf++ = REX_W;
167 *buf++ = 0x8b;
168 *buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG1] << 3) | 0x7;
169 }
170 if (args > 1) {
171 *buf++ = REX_W | REX_R;
172 *buf++ = 0x8b;
173 *buf++ = 0xc0 | (reg_lmap[SLJIT_GENERAL_REG2] << 3) | 0x6;
174 }
175 if (args > 2) {
176 *buf++ = REX_W | REX_R;
177 *buf++ = 0x8b;
178 *buf++ = 0xc0 | (reg_lmap[SLJIT_GENERAL_REG3] << 3) | 0x2;
179 }
180 #else
181 if (args > 0) {
182 *buf++ = REX_W;
183 *buf++ = 0x8b;
184 *buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG1] << 3) | 0x1;
185 }
186 if (args > 1) {
187 *buf++ = REX_W;
188 *buf++ = 0x8b;
189 *buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG2] << 3) | 0x2;
190 }
191 if (args > 2) {
192 *buf++ = REX_W | REX_B;
193 *buf++ = 0x8b;
194 *buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG3] << 3) | 0x0;
195 }
196 #endif
197 }
198
199 local_size = (local_size + 16 - 1) & ~(16 - 1);
200 #ifdef _WIN64
201 local_size += 4 * sizeof(sljit_w);
202 compiler->local_size = local_size;
203 if (local_size > 1024) {
204 /* Allocate the stack for the function itself. */
205 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
206 FAIL_IF(!buf);
207 INC_SIZE(4);
208 *buf++ = REX_W;
209 *buf++ = 0x83;
210 *buf++ = 0xc0 | (5 << 3) | 4;
211 *buf++ = 4 * sizeof(sljit_w);
212 local_size -= 4 * sizeof(sljit_w);
213 FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
214 FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
215 }
216 #else
217 compiler->local_size = local_size;
218 if (local_size > 0) {
219 #endif
220 if (local_size <= 127) {
221 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
222 FAIL_IF(!buf);
223 INC_SIZE(4);
224 *buf++ = REX_W;
225 *buf++ = 0x83;
226 *buf++ = 0xc0 | (5 << 3) | 4;
227 *buf++ = local_size;
228 }
229 else {
230 buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
231 FAIL_IF(!buf);
232 INC_SIZE(7);
233 *buf++ = REX_W;
234 *buf++ = 0x81;
235 *buf++ = 0xc0 | (5 << 3) | 4;
236 *(sljit_hw*)buf = local_size;
237 buf += sizeof(sljit_hw);
238 }
239 #ifndef _WIN64
240 }
241 #endif
242
243 #ifdef _WIN64
244 if (local_size > 4 * sizeof(sljit_w)) {
245 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
246 FAIL_IF(!buf);
247 INC_SIZE(5);
248 *buf++ = REX_W | REX_R;
249 *buf++ = 0x8d;
250 *buf++ = 0x40 | (reg_lmap[SLJIT_LOCALS_REG] << 3) | 0x4;
251 *buf++ = 0x24;
252 *buf = 4 * sizeof(sljit_w);
253 }
254 #endif
255
256 /* Mov arguments to general registers. */
257 return SLJIT_SUCCESS;
258 }
259
260 void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
261 {
262 CHECK_ERROR_VOID();
263 check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
264
265 compiler->temporaries = temporaries;
266 compiler->generals = generals;
267 compiler->local_size = (local_size + 16 - 1) & ~(16 - 1);
268 #ifdef _WIN64
269 compiler->local_size += 4 * sizeof(sljit_w);
270 #endif
271 }
272
273 int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
274 {
275 int size;
276 sljit_ub *buf;
277
278 CHECK_ERROR();
279 check_sljit_emit_return(compiler, src, srcw);
280
281 compiler->flags_saved = 0;
282
283 if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG) {
284 compiler->mode32 = 0;
285 FAIL_IF(emit_mov(compiler, SLJIT_RETURN_REG, 0, src, srcw));
286 }
287
288 if (compiler->local_size > 0) {
289 if (compiler->local_size <= 127) {
290 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
291 FAIL_IF(!buf);
292 INC_SIZE(4);
293 *buf++ = REX_W;
294 *buf++ = 0x83;
295 *buf++ = 0xc0 | (0 << 3) | 4;
296 *buf = compiler->local_size;
297 }
298 else {
299 buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
300 FAIL_IF(!buf);
301 INC_SIZE(7);
302 *buf++ = REX_W;
303 *buf++ = 0x81;
304 *buf++ = 0xc0 | (0 << 3) | 4;
305 *(sljit_hw*)buf = compiler->local_size;
306 }
307 }
308
309 size = 1 + compiler->generals;
310 #ifndef _WIN64
311 if (compiler->generals >= 2)
312 size += compiler->generals - 1;
313 #else
314 if (compiler->local_size > 4 * sizeof(sljit_w))
315 size += 2;
316 if (compiler->generals >= 4)
317 size += compiler->generals - 3;
318 if (compiler->temporaries >= 5)
319 size += (5 - 4) * 2;
320 #endif
321 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
322 FAIL_IF(!buf);
323
324 INC_SIZE(size);
325
326 #ifdef _WIN64
327 if (compiler->local_size > 4 * sizeof(sljit_w)) {
328 *buf++ = REX_B;
329 POP_REG(reg_lmap[SLJIT_LOCALS_REG]);
330 }
331 if (compiler->temporaries >= 5) {
332 *buf++ = REX_B;
333 POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
334 }
335 #endif
336 if (compiler->generals >= 1)
337 POP_REG(reg_map[SLJIT_GENERAL_REG1]);
338 if (compiler->generals >= 2) {
339 #ifndef _WIN64
340 *buf++ = REX_B;
341 #endif
342 POP_REG(reg_lmap[SLJIT_GENERAL_REG2]);
343 }
344 if (compiler->generals >= 3) {
345 #ifndef _WIN64
346 *buf++ = REX_B;
347 #endif
348 POP_REG(reg_lmap[SLJIT_GENERAL_REG3]);
349 }
350 if (compiler->generals >= 4) {
351 *buf++ = REX_B;
352 POP_REG(reg_lmap[SLJIT_GENERAL_EREG1]);
353 }
354 if (compiler->generals >= 5) {
355 *buf++ = REX_B;
356 POP_REG(reg_lmap[SLJIT_GENERAL_EREG2]);
357 }
358
359 RET();
360 return SLJIT_SUCCESS;
361 }
362
363 /* --------------------------------------------------------------------- */
364 /* Operators */
365 /* --------------------------------------------------------------------- */
366
367 static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
368 {
369 sljit_ub *buf;
370
371 if (rex != 0) {
372 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));
373 FAIL_IF(!buf);
374 INC_SIZE(2 + sizeof(sljit_hw));
375 *buf++ = rex;
376 *buf++ = opcode;
377 *(sljit_hw*)buf = imm;
378 }
379 else {
380 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw));
381 FAIL_IF(!buf);
382 INC_SIZE(1 + sizeof(sljit_hw));
383 *buf++ = opcode;
384 *(sljit_hw*)buf = imm;
385 }
386 return SLJIT_SUCCESS;
387 }
388
389 static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
390 /* The register or immediate operand. */
391 int a, sljit_w imma,
392 /* The general operand (not immediate). */
393 int b, sljit_w immb)
394 {
395 sljit_ub *buf;
396 sljit_ub *buf_ptr;
397 sljit_ub rex = 0;
398 int flags = size & ~0xf;
399 int inst_size;
400
401 /* The immediate operand must be 32 bit. */
402 SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
403 /* Both cannot be switched on. */
404 SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
405 /* Size flags not allowed for typed instructions. */
406 SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
407 /* Both size flags cannot be switched on. */
408 SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
409 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
410 /* SSE2 and immediate is not possible. */
411 SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
412 #endif
413
414 size &= 0xf;
415 inst_size = size;
416
417 if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) {
418 if (emit_load_imm64(compiler, TMP_REG3, immb))
419 return NULL;
420 immb = 0;
421 if (b & 0xf)
422 b |= TMP_REG3 << 4;
423 else
424 b |= TMP_REG3;
425 }
426
427 if (!compiler->mode32 && !(flags & EX86_NO_REXW))
428 rex |= REX_W;
429 else if (flags & EX86_REX)
430 rex |= REX;
431
432 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
433 if (flags & EX86_PREF_F2)
434 inst_size++;
435 #endif
436 if (flags & EX86_PREF_66)
437 inst_size++;
438
439 /* Calculate size of b. */
440 inst_size += 1; /* mod r/m byte. */
441 if (b & SLJIT_MEM) {
442 if ((b & 0x0f) == SLJIT_UNUSED)
443 inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */
444 else {
445 if (reg_map[b & 0x0f] >= 8)
446 rex |= REX_B;
447 if (immb != 0 && !(b & 0xf0)) {
448 /* Immediate operand. */
449 if (immb <= 127 && immb >= -128)
450 inst_size += sizeof(sljit_b);
451 else
452 inst_size += sizeof(sljit_hw);
453 }
454 }
455
456 #ifndef _WIN64
457 if ((b & 0xf) == SLJIT_LOCALS_REG && (b & 0xf0) == 0)
458 b |= SLJIT_LOCALS_REG << 4;
459 #endif
460
461 if ((b & 0xf0) != SLJIT_UNUSED) {
462 inst_size += 1; /* SIB byte. */
463 if (reg_map[(b >> 4) & 0x0f] >= 8)
464 rex |= REX_X;
465 }
466 }
467 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
468 else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
469 rex |= REX_B;
470 #else
471 else if (reg_map[b] >= 8)
472 rex |= REX_B;
473 #endif
474
475 if (a & SLJIT_IMM) {
476 if (flags & EX86_BIN_INS) {
477 if (imma <= 127 && imma >= -128) {
478 inst_size += 1;
479 flags |= EX86_BYTE_ARG;
480 } else
481 inst_size += 4;
482 }
483 else if (flags & EX86_SHIFT_INS) {
484 imma &= 0x3f;
485 if (imma != 1) {
486 inst_size ++;
487 flags |= EX86_BYTE_ARG;
488 }
489 } else if (flags & EX86_BYTE_ARG)
490 inst_size++;
491 else if (flags & EX86_HALF_ARG)
492 inst_size += sizeof(short);
493 else
494 inst_size += sizeof(sljit_hw);
495 }
496 else {
497 SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
498 /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
499 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
500 if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
501 rex |= REX_R;
502 #else
503 if (reg_map[a] >= 8)
504 rex |= REX_R;
505 #endif
506 }
507
508 if (rex)
509 inst_size++;
510
511 buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
512 PTR_FAIL_IF(!buf);
513
514 /* Encoding the byte. */
515 INC_SIZE(inst_size);
516 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
517 if (flags & EX86_PREF_F2)
518 *buf++ = 0xf2;
519 #endif
520 if (flags & EX86_PREF_66)
521 *buf++ = 0x66;
522 if (rex)
523 *buf++ = rex;
524 buf_ptr = buf + size;
525
526 /* Encode mod/rm byte. */
527 if (!(flags & EX86_SHIFT_INS)) {
528 if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
529 *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
530
531 if ((a & SLJIT_IMM) || (a == 0))
532 *buf_ptr = 0;
533 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
534 else if (!(flags & EX86_SSE2))
535 *buf_ptr = reg_lmap[a] << 3;
536 else
537 *buf_ptr = a << 3;
538 #else
539 else
540 *buf_ptr = reg_lmap[a] << 3;
541 #endif
542 }
543 else {
544 if (a & SLJIT_IMM) {
545 if (imma == 1)
546 *buf = 0xd1;
547 else
548 *buf = 0xc1;
549 } else
550 *buf = 0xd3;
551 *buf_ptr = 0;
552 }
553
554 if (!(b & SLJIT_MEM))
555 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
556 *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
557 #else
558 *buf_ptr++ |= 0xc0 + reg_lmap[b];
559 #endif
560 else if ((b & 0x0f) != SLJIT_UNUSED) {
561 #ifdef _WIN64
562 SLJIT_ASSERT((b & 0xf0) != (SLJIT_LOCALS_REG << 4));
563 #endif
564 if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
565 if (immb != 0) {
566 if (immb <= 127 && immb >= -128)
567 *buf_ptr |= 0x40;
568 else
569 *buf_ptr |= 0x80;
570 }
571
572 if ((b & 0xf0) == SLJIT_UNUSED)
573 *buf_ptr++ |= reg_lmap[b & 0x0f];
574 else {
575 *buf_ptr++ |= 0x04;
576 *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3);
577 }
578
579 if (immb != 0) {
580 if (immb <= 127 && immb >= -128)
581 *buf_ptr++ = immb; /* 8 bit displacement. */
582 else {
583 *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
584 buf_ptr += sizeof(sljit_hw);
585 }
586 }
587 }
588 else {
589 *buf_ptr++ |= 0x04;
590 *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6);
591 }
592 }
593 else {
594 *buf_ptr++ |= 0x04;
595 *buf_ptr++ = 0x25;
596 *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
597 buf_ptr += sizeof(sljit_hw);
598 }
599
600 if (a & SLJIT_IMM) {
601 if (flags & EX86_BYTE_ARG)
602 *buf_ptr = imma;
603 else if (flags & EX86_HALF_ARG)
604 *(short*)buf_ptr = imma;
605 else if (!(flags & EX86_SHIFT_INS))
606 *(sljit_hw*)buf_ptr = imma;
607 }
608
609 return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
610 }
611
612 /* --------------------------------------------------------------------- */
613 /* Call / return instructions */
614 /* --------------------------------------------------------------------- */
615
616 static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
617 {
618 sljit_ub *buf;
619
620 #ifndef _WIN64
621 SLJIT_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8);
622
623 buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
624 FAIL_IF(!buf);
625 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
626 if (type >= SLJIT_CALL3) {
627 *buf++ = REX_W;
628 *buf++ = 0x8b;
629 *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
630 }
631 *buf++ = REX_W;
632 *buf++ = 0x8b;
633 *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
634 #else
635 SLJIT_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8);
636
637 buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
638 FAIL_IF(!buf);
639 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
640 if (type >= SLJIT_CALL3) {
641 *buf++ = REX_W | REX_R;
642 *buf++ = 0x8b;
643 *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
644 }
645 *buf++ = REX_W;
646 *buf++ = 0x8b;
647 *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
648 #endif
649 return SLJIT_SUCCESS;
650 }
651
652 int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int generals, int local_size)
653 {
654 sljit_ub *buf;
655
656 CHECK_ERROR();
657 check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, generals, local_size);
658
659 compiler->temporaries = temporaries;
660 compiler->generals = generals;
661 compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
662 #ifdef _WIN64
663 compiler->local_size += 4 * sizeof(sljit_w);
664 #endif
665
666 /* For UNUSED dst. Uncommon, but possible. */
667 if (dst == SLJIT_UNUSED)
668 dst = TMP_REGISTER;
669
670 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
671 if (reg_map[dst] < 8) {
672 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
673 FAIL_IF(!buf);
674
675 INC_SIZE(1);
676 POP_REG(reg_lmap[dst]);
677 }
678 else {
679 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
680 FAIL_IF(!buf);
681
682 INC_SIZE(2);
683 *buf++ = REX_B;
684 POP_REG(reg_lmap[dst]);
685 }
686 }
687 else if (dst & SLJIT_MEM) {
688 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
689 /* REX_W is not necessary (src is not immediate). */
690 compiler->mode32 = 1;
691 #endif
692 buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
693 FAIL_IF(!buf);
694 *buf++ = 0x8f;
695 }
696 return SLJIT_SUCCESS;
697 }
698
699 int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
700 {
701 sljit_ub *buf;
702
703 CHECK_ERROR();
704 check_sljit_emit_fast_return(compiler, src, srcw);
705
706 CHECK_EXTRA_REGS(src, srcw, (void)0);
707
708 if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
709 FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw));
710 src = TMP_REGISTER;
711 }
712
713 if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
714 if (reg_map[src] < 8) {
715 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
716 FAIL_IF(!buf);
717
718 INC_SIZE(1 + 1);
719 PUSH_REG(reg_lmap[src]);
720 }
721 else {
722 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
723 FAIL_IF(!buf);
724
725 INC_SIZE(2 + 1);
726 *buf++ = REX_B;
727 PUSH_REG(reg_lmap[src]);
728 }
729 }
730 else if (src & SLJIT_MEM) {
731 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
732 /* REX_W is not necessary (src is not immediate). */
733 compiler->mode32 = 1;
734 #endif
735 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
736 FAIL_IF(!buf);
737 *buf++ = 0xff;
738 *buf |= 6 << 3;
739
740 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
741 FAIL_IF(!buf);
742 INC_SIZE(1);
743 }
744 else {
745 SLJIT_ASSERT(IS_HALFWORD(srcw));
746 /* SLJIT_IMM. */
747 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
748 FAIL_IF(!buf);
749
750 INC_SIZE(5 + 1);
751 *buf++ = 0x68;
752 *(sljit_hw*)buf = srcw;
753 buf += sizeof(sljit_hw);
754 }
755
756 RET();
757 return SLJIT_SUCCESS;
758 }
759
760
761 /* --------------------------------------------------------------------- */
762 /* Extend input */
763 /* --------------------------------------------------------------------- */
764
765 static int emit_mov_int(struct sljit_compiler *compiler, int sign,
766 int dst, sljit_w dstw,
767 int src, sljit_w srcw)
768 {
769 sljit_ub* code;
770 int dst_r;
771
772 compiler->mode32 = 0;
773
774 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
775 return SLJIT_SUCCESS; /* Empty instruction. */
776
777 if (src & SLJIT_IMM) {
778 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
779 return emit_load_imm64(compiler, dst, srcw);
780 compiler->mode32 = 1;
781 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(int)srcw, dst, dstw);
782 FAIL_IF(!code);
783 *code = 0xc7;
784 compiler->mode32 = 0;
785 return SLJIT_SUCCESS;
786 }
787
788 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_GENERAL_REG3) ? dst : TMP_REGISTER;
789
790 if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_GENERAL_REG3))
791 dst_r = src;
792 else {
793 if (sign) {
794 code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
795 FAIL_IF(!code);
796 *code++ = 0x63;
797 }
798 else {
799 if (dst_r == src) {
800 compiler->mode32 = 1;
801 code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, 0);
802 FAIL_IF(!code);
803 *code++ = 0x8b;
804 compiler->mode32 = 0;
805 }
806 /* xor reg, reg. */
807 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst_r, 0);
808 FAIL_IF(!code);
809 *code++ = 0x33;
810 if (dst_r != src) {
811 compiler->mode32 = 1;
812 code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
813 FAIL_IF(!code);
814 *code++ = 0x8b;
815 compiler->mode32 = 0;
816 }
817 else {
818 compiler->mode32 = 1;
819 code = emit_x86_instruction(compiler, 1, src, 0, TMP_REGISTER, 0);
820 FAIL_IF(!code);
821 *code++ = 0x8b;
822 compiler->mode32 = 0;
823 }
824 }
825 }
826
827 if (dst & SLJIT_MEM) {
828 compiler->mode32 = 1;
829 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
830 FAIL_IF(!code);
831 *code = 0x89;
832 compiler->mode32 = 0;
833 }
834
835 return SLJIT_SUCCESS;
836 }

  ViewVC Help
Powered by ViewVC 1.1.5