/[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 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: 21627 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 /* x86 64-bit arch dependent functions. */
28
29 static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
30 {
31 sljit_ub *buf;
32
33 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
34 FAIL_IF(!buf);
35 INC_SIZE(2 + sizeof(sljit_sw));
36 *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
37 *buf++ = 0xb8 + (reg_map[reg] & 0x7);
38 *(sljit_sw*)buf = imm;
39 return SLJIT_SUCCESS;
40 }
41
42 static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si 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_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
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_sw*)code_ptr = jump->u.target;
58
59 code_ptr += sizeof(sljit_sw);
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_sw addr, sljit_si type)
68 {
69 sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
70
71 if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
72 *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
73 *(sljit_sw*)code_ptr = delta;
74 }
75 else {
76 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
77 *code_ptr++ = REX_W | REX_B;
78 *code_ptr++ = 0xb8 + 1;
79 *(sljit_sw*)code_ptr = addr;
80 code_ptr += sizeof(sljit_sw);
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 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size)
90 {
91 sljit_si size, pushed_size;
92 sljit_ub *buf;
93
94 CHECK_ERROR();
95 check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
96
97 compiler->temporaries = temporaries;
98 compiler->saveds = saveds;
99 compiler->flags_saved = 0;
100 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
101 compiler->logical_local_size = local_size;
102 #endif
103
104 size = saveds;
105 /* Including the return address saved by the call instruction. */
106 pushed_size = (saveds + 1) * sizeof(sljit_sw);
107 #ifndef _WIN64
108 if (saveds >= 2)
109 size += saveds - 1;
110 #else
111 if (saveds >= 4)
112 size += saveds - 3;
113 if (temporaries >= 5) {
114 size += (5 - 4) * 2;
115 pushed_size += sizeof(sljit_sw);
116 }
117 #endif
118 size += args * 3;
119 if (size > 0) {
120 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
121 FAIL_IF(!buf);
122
123 INC_SIZE(size);
124 if (saveds >= 5) {
125 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
126 *buf++ = REX_B;
127 PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
128 }
129 if (saveds >= 4) {
130 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
131 *buf++ = REX_B;
132 PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
133 }
134 if (saveds >= 3) {
135 #ifndef _WIN64
136 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
137 *buf++ = REX_B;
138 #else
139 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
140 #endif
141 PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]);
142 }
143 if (saveds >= 2) {
144 #ifndef _WIN64
145 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
146 *buf++ = REX_B;
147 #else
148 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
149 #endif
150 PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]);
151 }
152 if (saveds >= 1) {
153 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg);
154 PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
155 }
156 #ifdef _WIN64
157 if (temporaries >= 5) {
158 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
159 *buf++ = REX_B;
160 PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
161 }
162 #endif
163
164 #ifndef _WIN64
165 if (args > 0) {
166 *buf++ = REX_W;
167 *buf++ = 0x8b;
168 *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;
169 }
170 if (args > 1) {
171 *buf++ = REX_W | REX_R;
172 *buf++ = 0x8b;
173 *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;
174 }
175 if (args > 2) {
176 *buf++ = REX_W | REX_R;
177 *buf++ = 0x8b;
178 *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;
179 }
180 #else
181 if (args > 0) {
182 *buf++ = REX_W;
183 *buf++ = 0x8b;
184 *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;
185 }
186 if (args > 1) {
187 *buf++ = REX_W;
188 *buf++ = 0x8b;
189 *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;
190 }
191 if (args > 2) {
192 *buf++ = REX_W | REX_B;
193 *buf++ = 0x8b;
194 *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;
195 }
196 #endif
197 }
198
199 local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
200 compiler->local_size = local_size;
201 #ifdef _WIN64
202 if (local_size > 1024) {
203 /* Allocate stack for the callback, which grows the stack. */
204 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
205 FAIL_IF(!buf);
206 INC_SIZE(4);
207 *buf++ = REX_W;
208 *buf++ = 0x83;
209 *buf++ = 0xc0 | (5 << 3) | 4;
210 /* Pushed size must be divisible by 8. */
211 SLJIT_ASSERT(!(pushed_size & 0x7));
212 if (pushed_size & 0x8) {
213 *buf++ = 5 * sizeof(sljit_sw);
214 local_size -= 5 * sizeof(sljit_sw);
215 } else {
216 *buf++ = 4 * sizeof(sljit_sw);
217 local_size -= 4 * sizeof(sljit_sw);
218 }
219 FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
220 FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
221 }
222 #endif
223 SLJIT_ASSERT(local_size > 0);
224 if (local_size <= 127) {
225 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
226 FAIL_IF(!buf);
227 INC_SIZE(4);
228 *buf++ = REX_W;
229 *buf++ = 0x83;
230 *buf++ = 0xc0 | (5 << 3) | 4;
231 *buf++ = local_size;
232 }
233 else {
234 buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
235 FAIL_IF(!buf);
236 INC_SIZE(7);
237 *buf++ = REX_W;
238 *buf++ = 0x81;
239 *buf++ = 0xc0 | (5 << 3) | 4;
240 *(sljit_si*)buf = local_size;
241 buf += sizeof(sljit_si);
242 }
243
244 return SLJIT_SUCCESS;
245 }
246
247 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size)
248 {
249 sljit_si pushed_size;
250
251 CHECK_ERROR_VOID();
252 check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
253
254 compiler->temporaries = temporaries;
255 compiler->saveds = saveds;
256 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
257 compiler->logical_local_size = local_size;
258 #endif
259
260 /* Including the return address saved by the call instruction. */
261 pushed_size = (saveds + 1) * sizeof(sljit_sw);
262 #ifdef _WIN64
263 if (temporaries >= 5)
264 pushed_size += sizeof(sljit_sw);
265 #endif
266 compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
267 }
268
269 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
270 {
271 sljit_si size;
272 sljit_ub *buf;
273
274 CHECK_ERROR();
275 check_sljit_emit_return(compiler, op, src, srcw);
276
277 compiler->flags_saved = 0;
278 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
279
280 SLJIT_ASSERT(compiler->local_size > 0);
281 if (compiler->local_size <= 127) {
282 buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
283 FAIL_IF(!buf);
284 INC_SIZE(4);
285 *buf++ = REX_W;
286 *buf++ = 0x83;
287 *buf++ = 0xc0 | (0 << 3) | 4;
288 *buf = compiler->local_size;
289 }
290 else {
291 buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
292 FAIL_IF(!buf);
293 INC_SIZE(7);
294 *buf++ = REX_W;
295 *buf++ = 0x81;
296 *buf++ = 0xc0 | (0 << 3) | 4;
297 *(sljit_si*)buf = compiler->local_size;
298 }
299
300 size = 1 + compiler->saveds;
301 #ifndef _WIN64
302 if (compiler->saveds >= 2)
303 size += compiler->saveds - 1;
304 #else
305 if (compiler->saveds >= 4)
306 size += compiler->saveds - 3;
307 if (compiler->temporaries >= 5)
308 size += (5 - 4) * 2;
309 #endif
310 buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
311 FAIL_IF(!buf);
312
313 INC_SIZE(size);
314
315 #ifdef _WIN64
316 if (compiler->temporaries >= 5) {
317 *buf++ = REX_B;
318 POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
319 }
320 #endif
321 if (compiler->saveds >= 1)
322 POP_REG(reg_map[SLJIT_SAVED_REG1]);
323 if (compiler->saveds >= 2) {
324 #ifndef _WIN64
325 *buf++ = REX_B;
326 #endif
327 POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
328 }
329 if (compiler->saveds >= 3) {
330 #ifndef _WIN64
331 *buf++ = REX_B;
332 #endif
333 POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
334 }
335 if (compiler->saveds >= 4) {
336 *buf++ = REX_B;
337 POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
338 }
339 if (compiler->saveds >= 5) {
340 *buf++ = REX_B;
341 POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
342 }
343
344 RET();
345 return SLJIT_SUCCESS;
346 }
347
348 /* --------------------------------------------------------------------- */
349 /* Operators */
350 /* --------------------------------------------------------------------- */
351
352 static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
353 {
354 sljit_ub *buf;
355
356 if (rex != 0) {
357 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_si));
358 FAIL_IF(!buf);
359 INC_SIZE(2 + sizeof(sljit_si));
360 *buf++ = rex;
361 *buf++ = opcode;
362 *(sljit_si*)buf = imm;
363 }
364 else {
365 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_si));
366 FAIL_IF(!buf);
367 INC_SIZE(1 + sizeof(sljit_si));
368 *buf++ = opcode;
369 *(sljit_si*)buf = imm;
370 }
371 return SLJIT_SUCCESS;
372 }
373
374 static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
375 /* The register or immediate operand. */
376 sljit_si a, sljit_sw imma,
377 /* The general operand (not immediate). */
378 sljit_si b, sljit_sw immb)
379 {
380 sljit_ub *buf;
381 sljit_ub *buf_ptr;
382 sljit_ub rex = 0;
383 sljit_si flags = size & ~0xf;
384 sljit_si inst_size;
385
386 /* The immediate operand must be 32 bit. */
387 SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
388 /* Both cannot be switched on. */
389 SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
390 /* Size flags not allowed for typed instructions. */
391 SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
392 /* Both size flags cannot be switched on. */
393 SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
394 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
395 /* SSE2 and immediate is not possible. */
396 SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
397 SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
398 && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
399 && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
400 #endif
401
402 size &= 0xf;
403 inst_size = size;
404
405 if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) {
406 if (emit_load_imm64(compiler, TMP_REG3, immb))
407 return NULL;
408 immb = 0;
409 if (b & 0xf)
410 b |= TMP_REG3 << 4;
411 else
412 b |= TMP_REG3;
413 }
414
415 if (!compiler->mode32 && !(flags & EX86_NO_REXW))
416 rex |= REX_W;
417 else if (flags & EX86_REX)
418 rex |= REX;
419
420 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
421 if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
422 inst_size++;
423 #endif
424 if (flags & EX86_PREF_66)
425 inst_size++;
426
427 /* Calculate size of b. */
428 inst_size += 1; /* mod r/m byte. */
429 if (b & SLJIT_MEM) {
430 if ((b & 0x0f) == SLJIT_UNUSED)
431 inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
432 else {
433 if (reg_map[b & 0x0f] >= 8)
434 rex |= REX_B;
435 if (immb != 0 && !(b & 0xf0)) {
436 /* Immediate operand. */
437 if (immb <= 127 && immb >= -128)
438 inst_size += sizeof(sljit_sb);
439 else
440 inst_size += sizeof(sljit_si);
441 }
442 }
443
444 if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
445 b |= SLJIT_LOCALS_REG << 4;
446
447 if ((b & 0xf0) != SLJIT_UNUSED) {
448 inst_size += 1; /* SIB byte. */
449 if (reg_map[(b >> 4) & 0x0f] >= 8)
450 rex |= REX_X;
451 }
452 }
453 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
454 else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
455 rex |= REX_B;
456 #else
457 else if (reg_map[b] >= 8)
458 rex |= REX_B;
459 #endif
460
461 if (a & SLJIT_IMM) {
462 if (flags & EX86_BIN_INS) {
463 if (imma <= 127 && imma >= -128) {
464 inst_size += 1;
465 flags |= EX86_BYTE_ARG;
466 } else
467 inst_size += 4;
468 }
469 else if (flags & EX86_SHIFT_INS) {
470 imma &= compiler->mode32 ? 0x1f : 0x3f;
471 if (imma != 1) {
472 inst_size ++;
473 flags |= EX86_BYTE_ARG;
474 }
475 } else if (flags & EX86_BYTE_ARG)
476 inst_size++;
477 else if (flags & EX86_HALF_ARG)
478 inst_size += sizeof(short);
479 else
480 inst_size += sizeof(sljit_si);
481 }
482 else {
483 SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
484 /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
485 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
486 if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
487 rex |= REX_R;
488 #else
489 if (reg_map[a] >= 8)
490 rex |= REX_R;
491 #endif
492 }
493
494 if (rex)
495 inst_size++;
496
497 buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
498 PTR_FAIL_IF(!buf);
499
500 /* Encoding the byte. */
501 INC_SIZE(inst_size);
502 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
503 if (flags & EX86_PREF_F2)
504 *buf++ = 0xf2;
505 if (flags & EX86_PREF_F3)
506 *buf++ = 0xf3;
507 #endif
508 if (flags & EX86_PREF_66)
509 *buf++ = 0x66;
510 if (rex)
511 *buf++ = rex;
512 buf_ptr = buf + size;
513
514 /* Encode mod/rm byte. */
515 if (!(flags & EX86_SHIFT_INS)) {
516 if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
517 *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
518
519 if ((a & SLJIT_IMM) || (a == 0))
520 *buf_ptr = 0;
521 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
522 else if (!(flags & EX86_SSE2))
523 *buf_ptr = reg_lmap[a] << 3;
524 else
525 *buf_ptr = a << 3;
526 #else
527 else
528 *buf_ptr = reg_lmap[a] << 3;
529 #endif
530 }
531 else {
532 if (a & SLJIT_IMM) {
533 if (imma == 1)
534 *buf = 0xd1;
535 else
536 *buf = 0xc1;
537 } else
538 *buf = 0xd3;
539 *buf_ptr = 0;
540 }
541
542 if (!(b & SLJIT_MEM))
543 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
544 *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
545 #else
546 *buf_ptr++ |= 0xc0 + reg_lmap[b];
547 #endif
548 else if ((b & 0x0f) != SLJIT_UNUSED) {
549 if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
550 if (immb != 0) {
551 if (immb <= 127 && immb >= -128)
552 *buf_ptr |= 0x40;
553 else
554 *buf_ptr |= 0x80;
555 }
556
557 if ((b & 0xf0) == SLJIT_UNUSED)
558 *buf_ptr++ |= reg_lmap[b & 0x0f];
559 else {
560 *buf_ptr++ |= 0x04;
561 *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3);
562 }
563
564 if (immb != 0) {
565 if (immb <= 127 && immb >= -128)
566 *buf_ptr++ = immb; /* 8 bit displacement. */
567 else {
568 *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
569 buf_ptr += sizeof(sljit_si);
570 }
571 }
572 }
573 else {
574 *buf_ptr++ |= 0x04;
575 *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6);
576 }
577 }
578 else {
579 *buf_ptr++ |= 0x04;
580 *buf_ptr++ = 0x25;
581 *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
582 buf_ptr += sizeof(sljit_si);
583 }
584
585 if (a & SLJIT_IMM) {
586 if (flags & EX86_BYTE_ARG)
587 *buf_ptr = imma;
588 else if (flags & EX86_HALF_ARG)
589 *(short*)buf_ptr = imma;
590 else if (!(flags & EX86_SHIFT_INS))
591 *(sljit_si*)buf_ptr = imma;
592 }
593
594 return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
595 }
596
597 /* --------------------------------------------------------------------- */
598 /* Call / return instructions */
599 /* --------------------------------------------------------------------- */
600
601 static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
602 {
603 sljit_ub *buf;
604
605 #ifndef _WIN64
606 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
607
608 buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
609 FAIL_IF(!buf);
610 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
611 if (type >= SLJIT_CALL3) {
612 *buf++ = REX_W;
613 *buf++ = 0x8b;
614 *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
615 }
616 *buf++ = REX_W;
617 *buf++ = 0x8b;
618 *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
619 #else
620 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
621
622 buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
623 FAIL_IF(!buf);
624 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
625 if (type >= SLJIT_CALL3) {
626 *buf++ = REX_W | REX_R;
627 *buf++ = 0x8b;
628 *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
629 }
630 *buf++ = REX_W;
631 *buf++ = 0x8b;
632 *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
633 #endif
634 return SLJIT_SUCCESS;
635 }
636
637 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
638 {
639 sljit_ub *buf;
640
641 CHECK_ERROR();
642 check_sljit_emit_fast_enter(compiler, dst, dstw);
643 ADJUST_LOCAL_OFFSET(dst, dstw);
644
645 /* For UNUSED dst. Uncommon, but possible. */
646 if (dst == SLJIT_UNUSED)
647 dst = TMP_REGISTER;
648
649 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
650 if (reg_map[dst] < 8) {
651 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
652 FAIL_IF(!buf);
653
654 INC_SIZE(1);
655 POP_REG(reg_lmap[dst]);
656 }
657 else {
658 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
659 FAIL_IF(!buf);
660
661 INC_SIZE(2);
662 *buf++ = REX_B;
663 POP_REG(reg_lmap[dst]);
664 }
665 }
666 else if (dst & SLJIT_MEM) {
667 /* REX_W is not necessary (src is not immediate). */
668 compiler->mode32 = 1;
669 buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
670 FAIL_IF(!buf);
671 *buf++ = 0x8f;
672 }
673 return SLJIT_SUCCESS;
674 }
675
676 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
677 {
678 sljit_ub *buf;
679
680 CHECK_ERROR();
681 check_sljit_emit_fast_return(compiler, src, srcw);
682 ADJUST_LOCAL_OFFSET(src, srcw);
683
684 if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
685 FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw));
686 src = TMP_REGISTER;
687 }
688
689 if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
690 if (reg_map[src] < 8) {
691 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
692 FAIL_IF(!buf);
693
694 INC_SIZE(1 + 1);
695 PUSH_REG(reg_lmap[src]);
696 }
697 else {
698 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
699 FAIL_IF(!buf);
700
701 INC_SIZE(2 + 1);
702 *buf++ = REX_B;
703 PUSH_REG(reg_lmap[src]);
704 }
705 }
706 else if (src & SLJIT_MEM) {
707 /* REX_W is not necessary (src is not immediate). */
708 compiler->mode32 = 1;
709 buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
710 FAIL_IF(!buf);
711 *buf++ = 0xff;
712 *buf |= 6 << 3;
713
714 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
715 FAIL_IF(!buf);
716 INC_SIZE(1);
717 }
718 else {
719 SLJIT_ASSERT(IS_HALFWORD(srcw));
720 /* SLJIT_IMM. */
721 buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
722 FAIL_IF(!buf);
723
724 INC_SIZE(5 + 1);
725 *buf++ = 0x68;
726 *(sljit_si*)buf = srcw;
727 buf += sizeof(sljit_si);
728 }
729
730 RET();
731 return SLJIT_SUCCESS;
732 }
733
734
735 /* --------------------------------------------------------------------- */
736 /* Extend input */
737 /* --------------------------------------------------------------------- */
738
739 static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
740 sljit_si dst, sljit_sw dstw,
741 sljit_si src, sljit_sw srcw)
742 {
743 sljit_ub* code;
744 sljit_si dst_r;
745
746 compiler->mode32 = 0;
747
748 if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
749 return SLJIT_SUCCESS; /* Empty instruction. */
750
751 if (src & SLJIT_IMM) {
752 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
753 if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
754 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
755 FAIL_IF(!code);
756 *code = 0xc7;
757 return SLJIT_SUCCESS;
758 }
759 return emit_load_imm64(compiler, dst, srcw);
760 }
761 compiler->mode32 = 1;
762 code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
763 FAIL_IF(!code);
764 *code = 0xc7;
765 compiler->mode32 = 0;
766 return SLJIT_SUCCESS;
767 }
768
769 dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;
770
771 if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))
772 dst_r = src;
773 else {
774 if (sign) {
775 code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
776 FAIL_IF(!code);
777 *code++ = 0x63;
778 } else {
779 compiler->mode32 = 1;
780 FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
781 compiler->mode32 = 0;
782 }
783 }
784
785 if (dst & SLJIT_MEM) {
786 compiler->mode32 = 1;
787 code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
788 FAIL_IF(!code);
789 *code = 0x89;
790 compiler->mode32 = 0;
791 }
792
793 return SLJIT_SUCCESS;
794 }

  ViewVC Help
Powered by ViewVC 1.1.5