/[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 740 - (hide annotations) (download)
Mon Oct 31 06:10:14 2011 UTC (2 years, 9 months ago) by zherczeg
File MIME type: text/plain
File size: 23060 byte(s)
Updating the JIT compiler
1 ph10 662 /*
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 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
50 ph10 662 *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 zherczeg 722 *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
63 ph10 662
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 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
77 ph10 662 *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 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
90 ph10 662 {
91 zherczeg 740 int size, pushed_size;
92 ph10 662 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 zherczeg 740 /* Including the return address saved by the call instruction. */
103     pushed_size = (generals + 1) * sizeof(sljit_w);
104 ph10 662 #ifndef _WIN64
105     if (generals >= 2)
106     size += generals - 1;
107     #else
108 zherczeg 740 /* Saving the virtual stack pointer. */
109     compiler->has_locals = local_size > 0;
110     if (local_size > 0) {
111 ph10 662 size += 2;
112 zherczeg 740 pushed_size += sizeof(sljit_w);
113     }
114 ph10 662 if (generals >= 4)
115     size += generals - 3;
116 zherczeg 740 if (temporaries >= 5) {
117 ph10 662 size += (5 - 4) * 2;
118 zherczeg 740 pushed_size += sizeof(sljit_w);
119     }
120 ph10 662 #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 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_EREG2] >= 8, general_ereg2_is_hireg);
129 ph10 662 *buf++ = REX_B;
130     PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG2]);
131     }
132     if (generals >= 4) {
133 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_EREG1] >= 8, general_ereg1_is_hireg);
134 ph10 662 *buf++ = REX_B;
135     PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG1]);
136     }
137     if (generals >= 3) {
138     #ifndef _WIN64
139 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG3] >= 8, general_reg3_is_hireg);
140 ph10 662 *buf++ = REX_B;
141     #else
142 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG3] < 8, general_reg3_is_loreg);
143 ph10 662 #endif
144     PUSH_REG(reg_lmap[SLJIT_GENERAL_REG3]);
145     }
146     if (generals >= 2) {
147     #ifndef _WIN64
148 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG2] >= 8, general_reg2_is_hireg);
149 ph10 662 *buf++ = REX_B;
150     #else
151 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG2] < 8, general_reg2_is_loreg);
152 ph10 662 #endif
153     PUSH_REG(reg_lmap[SLJIT_GENERAL_REG2]);
154     }
155     if (generals >= 1) {
156 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG1] < 8, general_reg1_is_loreg);
157 ph10 662 PUSH_REG(reg_lmap[SLJIT_GENERAL_REG1]);
158     }
159     #ifdef _WIN64
160     if (temporaries >= 5) {
161 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
162 ph10 662 *buf++ = REX_B;
163     PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
164     }
165     if (local_size > 0) {
166 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_LOCALS_REG] >= 8, locals_reg_is_hireg);
167 ph10 662 *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 zherczeg 740 local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
208 ph10 662 #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 zherczeg 740 /* 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 ph10 662 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 zherczeg 740 /* In case of Win64, local_size is always > 4 * sizeof(sljit_w) */
236 ph10 662 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 zherczeg 740 if (compiler->has_locals) {
261 ph10 662 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 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
277 ph10 662 {
278 zherczeg 740 int pushed_size;
279    
280 ph10 662 CHECK_ERROR_VOID();
281     check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
282    
283     compiler->temporaries = temporaries;
284     compiler->generals = generals;
285 zherczeg 740 /* Including the return address saved by the call instruction. */
286     pushed_size = (generals + 1) * sizeof(sljit_w);
287 ph10 662 #ifdef _WIN64
288 zherczeg 740 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 ph10 662 compiler->local_size += 4 * sizeof(sljit_w);
297     #endif
298     }
299    
300 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
301 ph10 662 {
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 zherczeg 740 if (compiler->has_locals)
342 ph10 662 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 zherczeg 740 if (compiler->has_locals) {
355 ph10 662 *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 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
649 ph10 662
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 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
663 ph10 662
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 zherczeg 740 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 ph10 662 {
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 zherczeg 740 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
727 ph10 662 {
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     }

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12