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