/[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 662 - (hide annotations) (download)
Mon Aug 22 14:35:22 2011 UTC (21 months, 4 weeks ago) by ph10
File MIME type: text/plain
File size: 21684 byte(s)
JIT compiler source

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     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_CALL0) ? 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     }

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12