/[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 1499 - (hide annotations) (download)
Mon Aug 11 06:42:28 2014 UTC (2 weeks, 3 days ago) by zherczeg
File MIME type: text/plain
File size: 21694 byte(s)
JIT compiler update.
1 ph10 662 /*
2     * Stack-less Just-In-Time compiler
3     *
4 ph10 836 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5 ph10 662 *
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 zherczeg 1195 static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
30 ph10 662 {
31 zherczeg 1201 sljit_ub *inst;
32 ph10 662
33 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
34     FAIL_IF(!inst);
35 zherczeg 1195 INC_SIZE(2 + sizeof(sljit_sw));
36 zherczeg 1201 *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
37     *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);
38     *(sljit_sw*)inst = imm;
39 ph10 662 return SLJIT_SUCCESS;
40     }
41    
42 zherczeg 1195 static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
43 ph10 662 {
44     if (type < SLJIT_JUMP) {
45 zherczeg 1201 /* Invert type. */
46 ph10 662 *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
47     *code_ptr++ = 10 + 3;
48     }
49    
50 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
51 ph10 662 *code_ptr++ = REX_W | REX_B;
52 zherczeg 1201 *code_ptr++ = MOV_r_i32 + 1;
53 ph10 662 jump->addr = (sljit_uw)code_ptr;
54    
55     if (jump->flags & JUMP_LABEL)
56     jump->flags |= PATCH_MD;
57     else
58 zherczeg 1195 *(sljit_sw*)code_ptr = jump->u.target;
59 ph10 662
60 zherczeg 1195 code_ptr += sizeof(sljit_sw);
61 ph10 662 *code_ptr++ = REX_B;
62 zherczeg 1201 *code_ptr++ = GROUP_FF;
63     *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
64 ph10 662
65     return code_ptr;
66     }
67    
68 zherczeg 1195 static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type)
69 ph10 662 {
70 zherczeg 1195 sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
71 ph10 662
72 zherczeg 1461 if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) {
73 zherczeg 1201 *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
74 zherczeg 1195 *(sljit_sw*)code_ptr = delta;
75 ph10 662 }
76     else {
77 zherczeg 740 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
78 ph10 662 *code_ptr++ = REX_W | REX_B;
79 zherczeg 1201 *code_ptr++ = MOV_r_i32 + 1;
80 zherczeg 1195 *(sljit_sw*)code_ptr = addr;
81     code_ptr += sizeof(sljit_sw);
82 ph10 662 *code_ptr++ = REX_B;
83 zherczeg 1201 *code_ptr++ = GROUP_FF;
84     *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
85 ph10 662 }
86    
87     return code_ptr;
88     }
89    
90 zherczeg 1491 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
91 zherczeg 1499 sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
92 zherczeg 1491 sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
93 ph10 662 {
94 zherczeg 1493 sljit_si i, tmp, size, saved_register_size;
95 zherczeg 1201 sljit_ub *inst;
96 ph10 662
97     CHECK_ERROR();
98 zherczeg 1499 check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
99 ph10 662
100 zherczeg 1499 compiler->options = options;
101 zherczeg 1215 compiler->scratches = scratches;
102 zherczeg 880 compiler->saveds = saveds;
103 zherczeg 1491 compiler->fscratches = fscratches;
104     compiler->fsaveds = fsaveds;
105 ph10 662 compiler->flags_saved = 0;
106 zherczeg 955 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
107     compiler->logical_local_size = local_size;
108     #endif
109 ph10 662
110 zherczeg 740 /* Including the return address saved by the call instruction. */
111 zherczeg 1493 saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
112 zherczeg 1491
113     tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
114     for (i = SLJIT_S0; i >= tmp; i--) {
115     size = reg_map[i] >= 8 ? 2 : 1;
116 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
117     FAIL_IF(!inst);
118 zherczeg 1491 INC_SIZE(size);
119     if (reg_map[i] >= 8)
120     *inst++ = REX_B;
121     PUSH_REG(reg_lmap[i]);
122     }
123 ph10 662
124 zherczeg 1491 for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
125     size = reg_map[i] >= 8 ? 2 : 1;
126     inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
127     FAIL_IF(!inst);
128 ph10 662 INC_SIZE(size);
129 zherczeg 1491 if (reg_map[i] >= 8)
130 zherczeg 1201 *inst++ = REX_B;
131 zherczeg 1491 PUSH_REG(reg_lmap[i]);
132     }
133 ph10 662
134 zherczeg 1491 if (args > 0) {
135     size = args * 3;
136     inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
137     FAIL_IF(!inst);
138    
139     INC_SIZE(size);
140    
141 ph10 662 #ifndef _WIN64
142     if (args > 0) {
143 zherczeg 1201 *inst++ = REX_W;
144     *inst++ = MOV_r_rm;
145 zherczeg 1491 *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;
146 ph10 662 }
147     if (args > 1) {
148 zherczeg 1201 *inst++ = REX_W | REX_R;
149     *inst++ = MOV_r_rm;
150 zherczeg 1491 *inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;
151 ph10 662 }
152     if (args > 2) {
153 zherczeg 1201 *inst++ = REX_W | REX_R;
154     *inst++ = MOV_r_rm;
155 zherczeg 1491 *inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;
156 ph10 662 }
157     #else
158     if (args > 0) {
159 zherczeg 1201 *inst++ = REX_W;
160     *inst++ = MOV_r_rm;
161 zherczeg 1491 *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;
162 ph10 662 }
163     if (args > 1) {
164 zherczeg 1201 *inst++ = REX_W;
165     *inst++ = MOV_r_rm;
166 zherczeg 1491 *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;
167 ph10 662 }
168     if (args > 2) {
169 zherczeg 1201 *inst++ = REX_W | REX_B;
170     *inst++ = MOV_r_rm;
171 zherczeg 1491 *inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;
172 ph10 662 }
173     #endif
174     }
175    
176 zherczeg 1493 local_size = ((local_size + FIXED_LOCALS_OFFSET + saved_register_size + 16 - 1) & ~(16 - 1)) - saved_register_size;
177 ph10 662 compiler->local_size = local_size;
178 zherczeg 1491
179 zherczeg 956 #ifdef _WIN64
180 ph10 662 if (local_size > 1024) {
181 zherczeg 956 /* Allocate stack for the callback, which grows the stack. */
182 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si)));
183     FAIL_IF(!inst);
184     INC_SIZE(4 + (3 + sizeof(sljit_si)));
185     *inst++ = REX_W;
186     *inst++ = GROUP_BINARY_83;
187     *inst++ = MOD_REG | SUB | 4;
188 zherczeg 1491 /* Allocated size for registers must be divisible by 8. */
189 zherczeg 1493 SLJIT_ASSERT(!(saved_register_size & 0x7));
190 zherczeg 1491 /* Aligned to 16 byte. */
191 zherczeg 1493 if (saved_register_size & 0x8) {
192 zherczeg 1201 *inst++ = 5 * sizeof(sljit_sw);
193 zherczeg 1195 local_size -= 5 * sizeof(sljit_sw);
194 zherczeg 740 } else {
195 zherczeg 1201 *inst++ = 4 * sizeof(sljit_sw);
196 zherczeg 1195 local_size -= 4 * sizeof(sljit_sw);
197 zherczeg 740 }
198 zherczeg 1201 /* Second instruction */
199 zherczeg 1491 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg);
200 zherczeg 1201 *inst++ = REX_W;
201     *inst++ = MOV_rm_i32;
202 zherczeg 1491 *inst++ = MOD_REG | reg_lmap[SLJIT_R0];
203 zherczeg 1201 *(sljit_si*)inst = local_size;
204     #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
205     compiler->skip_checks = 1;
206     #endif
207 zherczeg 956 FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
208 ph10 662 }
209     #endif
210 zherczeg 1491
211 zherczeg 956 SLJIT_ASSERT(local_size > 0);
212     if (local_size <= 127) {
213 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
214     FAIL_IF(!inst);
215 zherczeg 956 INC_SIZE(4);
216 zherczeg 1201 *inst++ = REX_W;
217     *inst++ = GROUP_BINARY_83;
218     *inst++ = MOD_REG | SUB | 4;
219     *inst++ = local_size;
220 ph10 662 }
221 zherczeg 956 else {
222 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
223     FAIL_IF(!inst);
224 zherczeg 956 INC_SIZE(7);
225 zherczeg 1201 *inst++ = REX_W;
226     *inst++ = GROUP_BINARY_81;
227     *inst++ = MOD_REG | SUB | 4;
228     *(sljit_si*)inst = local_size;
229     inst += sizeof(sljit_si);
230 zherczeg 956 }
231 zherczeg 1491
232 zherczeg 1201 #ifdef _WIN64
233 zherczeg 1491 /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */
234     if (fscratches >= 6 || fsaveds >= 1) {
235     inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
236     FAIL_IF(!inst);
237     INC_SIZE(5);
238     *inst++ = GROUP_0F;
239     *(sljit_si*)inst = 0x20247429;
240     }
241 zherczeg 1201 #endif
242 ph10 662
243     return SLJIT_SUCCESS;
244     }
245    
246 zherczeg 1491 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
247 zherczeg 1499 sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
248 zherczeg 1491 sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
249 ph10 662 {
250 zherczeg 1493 sljit_si saved_register_size;
251 zherczeg 740
252 ph10 662 CHECK_ERROR_VOID();
253 zherczeg 1499 check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
254 ph10 662
255 zherczeg 1499 compiler->options = options;
256 zherczeg 1215 compiler->scratches = scratches;
257 zherczeg 880 compiler->saveds = saveds;
258 zherczeg 1491 compiler->fscratches = fscratches;
259     compiler->fsaveds = fsaveds;
260 zherczeg 955 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
261     compiler->logical_local_size = local_size;
262     #endif
263    
264 zherczeg 740 /* Including the return address saved by the call instruction. */
265 zherczeg 1493 saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
266     compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + saved_register_size + 16 - 1) & ~(16 - 1)) - saved_register_size;
267 ph10 662 }
268    
269 zherczeg 1195 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
270 ph10 662 {
271 zherczeg 1491 sljit_si i, tmp, size;
272 zherczeg 1201 sljit_ub *inst;
273 ph10 662
274     CHECK_ERROR();
275 zherczeg 875 check_sljit_emit_return(compiler, op, src, srcw);
276 ph10 662
277     compiler->flags_saved = 0;
278 zherczeg 875 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
279 ph10 662
280 zherczeg 1201 #ifdef _WIN64
281 zherczeg 1491 /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */
282     if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) {
283     inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
284     FAIL_IF(!inst);
285     INC_SIZE(5);
286     *inst++ = GROUP_0F;
287     *(sljit_si*)inst = 0x20247428;
288     }
289 zherczeg 1201 #endif
290 zherczeg 1491
291 zherczeg 956 SLJIT_ASSERT(compiler->local_size > 0);
292     if (compiler->local_size <= 127) {
293 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
294     FAIL_IF(!inst);
295 zherczeg 956 INC_SIZE(4);
296 zherczeg 1201 *inst++ = REX_W;
297     *inst++ = GROUP_BINARY_83;
298     *inst++ = MOD_REG | ADD | 4;
299     *inst = compiler->local_size;
300 ph10 662 }
301 zherczeg 956 else {
302 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
303     FAIL_IF(!inst);
304 zherczeg 956 INC_SIZE(7);
305 zherczeg 1201 *inst++ = REX_W;
306     *inst++ = GROUP_BINARY_81;
307     *inst++ = MOD_REG | ADD | 4;
308     *(sljit_si*)inst = compiler->local_size;
309 zherczeg 956 }
310 ph10 662
311 zherczeg 1491 tmp = compiler->scratches;
312     for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
313     size = reg_map[i] >= 8 ? 2 : 1;
314     inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
315     FAIL_IF(!inst);
316     INC_SIZE(size);
317     if (reg_map[i] >= 8)
318     *inst++ = REX_B;
319     POP_REG(reg_lmap[i]);
320     }
321 ph10 662
322 zherczeg 1491 tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
323     for (i = tmp; i <= SLJIT_S0; i++) {
324     size = reg_map[i] >= 8 ? 2 : 1;
325     inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
326     FAIL_IF(!inst);
327     INC_SIZE(size);
328     if (reg_map[i] >= 8)
329     *inst++ = REX_B;
330     POP_REG(reg_lmap[i]);
331 ph10 662 }
332    
333 zherczeg 1491 inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
334     FAIL_IF(!inst);
335     INC_SIZE(1);
336 ph10 662 RET();
337     return SLJIT_SUCCESS;
338     }
339    
340     /* --------------------------------------------------------------------- */
341     /* Operators */
342     /* --------------------------------------------------------------------- */
343    
344 zherczeg 1195 static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
345 ph10 662 {
346 zherczeg 1201 sljit_ub *inst;
347     sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si);
348 ph10 662
349 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + length);
350     FAIL_IF(!inst);
351     INC_SIZE(length);
352     if (rex)
353     *inst++ = rex;
354     *inst++ = opcode;
355     *(sljit_si*)inst = imm;
356 ph10 662 return SLJIT_SUCCESS;
357     }
358    
359 zherczeg 1195 static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
360 ph10 662 /* The register or immediate operand. */
361 zherczeg 1195 sljit_si a, sljit_sw imma,
362 ph10 662 /* The general operand (not immediate). */
363 zherczeg 1195 sljit_si b, sljit_sw immb)
364 ph10 662 {
365 zherczeg 1201 sljit_ub *inst;
366 ph10 662 sljit_ub *buf_ptr;
367     sljit_ub rex = 0;
368 zherczeg 1195 sljit_si flags = size & ~0xf;
369     sljit_si inst_size;
370 ph10 662
371     /* The immediate operand must be 32 bit. */
372     SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
373     /* Both cannot be switched on. */
374     SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
375     /* Size flags not allowed for typed instructions. */
376     SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
377     /* Both size flags cannot be switched on. */
378     SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
379     /* SSE2 and immediate is not possible. */
380     SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
381 zherczeg 1195 SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
382     && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
383     && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
384 ph10 662
385     size &= 0xf;
386     inst_size = size;
387    
388     if (!compiler->mode32 && !(flags & EX86_NO_REXW))
389     rex |= REX_W;
390     else if (flags & EX86_REX)
391     rex |= REX;
392    
393 zherczeg 1195 if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
394 ph10 662 inst_size++;
395     if (flags & EX86_PREF_66)
396     inst_size++;
397    
398     /* Calculate size of b. */
399     inst_size += 1; /* mod r/m byte. */
400     if (b & SLJIT_MEM) {
401 zherczeg 1483 if (!(b & OFFS_REG_MASK)) {
402     if (NOT_HALFWORD(immb)) {
403     if (emit_load_imm64(compiler, TMP_REG3, immb))
404     return NULL;
405     immb = 0;
406     if (b & REG_MASK)
407     b |= TO_OFFS_REG(TMP_REG3);
408     else
409     b |= TMP_REG3;
410     }
411     else if (reg_lmap[b & REG_MASK] == 4)
412 zherczeg 1491 b |= TO_OFFS_REG(SLJIT_SP);
413 zherczeg 1483 }
414    
415 zherczeg 1453 if ((b & REG_MASK) == SLJIT_UNUSED)
416 zherczeg 1195 inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
417 ph10 662 else {
418 zherczeg 1453 if (reg_map[b & REG_MASK] >= 8)
419 ph10 662 rex |= REX_B;
420 zherczeg 1491
421     if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {
422 ph10 662 /* Immediate operand. */
423     if (immb <= 127 && immb >= -128)
424 zherczeg 1195 inst_size += sizeof(sljit_sb);
425 ph10 662 else
426 zherczeg 1195 inst_size += sizeof(sljit_si);
427 ph10 662 }
428 zherczeg 1491 else if (reg_lmap[b & REG_MASK] == 5)
429     inst_size += sizeof(sljit_sb);
430 ph10 662
431 zherczeg 1483 if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
432     inst_size += 1; /* SIB byte. */
433     if (reg_map[OFFS_REG(b)] >= 8)
434     rex |= REX_X;
435     }
436 ph10 662 }
437     }
438 zherczeg 1483 else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
439 ph10 662 rex |= REX_B;
440    
441     if (a & SLJIT_IMM) {
442     if (flags & EX86_BIN_INS) {
443     if (imma <= 127 && imma >= -128) {
444     inst_size += 1;
445     flags |= EX86_BYTE_ARG;
446     } else
447     inst_size += 4;
448     }
449     else if (flags & EX86_SHIFT_INS) {
450 zherczeg 860 imma &= compiler->mode32 ? 0x1f : 0x3f;
451 ph10 662 if (imma != 1) {
452     inst_size ++;
453     flags |= EX86_BYTE_ARG;
454     }
455     } else if (flags & EX86_BYTE_ARG)
456     inst_size++;
457     else if (flags & EX86_HALF_ARG)
458     inst_size += sizeof(short);
459     else
460 zherczeg 1195 inst_size += sizeof(sljit_si);
461 ph10 662 }
462     else {
463     SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
464     /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
465 zherczeg 1483 if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
466 ph10 662 rex |= REX_R;
467     }
468    
469     if (rex)
470     inst_size++;
471    
472 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
473     PTR_FAIL_IF(!inst);
474 ph10 662
475     /* Encoding the byte. */
476     INC_SIZE(inst_size);
477     if (flags & EX86_PREF_F2)
478 zherczeg 1201 *inst++ = 0xf2;
479 zherczeg 1195 if (flags & EX86_PREF_F3)
480 zherczeg 1201 *inst++ = 0xf3;
481 ph10 662 if (flags & EX86_PREF_66)
482 zherczeg 1201 *inst++ = 0x66;
483 ph10 662 if (rex)
484 zherczeg 1201 *inst++ = rex;
485     buf_ptr = inst + size;
486 ph10 662
487     /* Encode mod/rm byte. */
488     if (!(flags & EX86_SHIFT_INS)) {
489     if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
490 zherczeg 1201 *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
491 ph10 662
492     if ((a & SLJIT_IMM) || (a == 0))
493     *buf_ptr = 0;
494 zherczeg 1483 else if (!(flags & EX86_SSE2_OP1))
495 ph10 662 *buf_ptr = reg_lmap[a] << 3;
496     else
497     *buf_ptr = a << 3;
498     }
499     else {
500     if (a & SLJIT_IMM) {
501     if (imma == 1)
502 zherczeg 1201 *inst = GROUP_SHIFT_1;
503 ph10 662 else
504 zherczeg 1201 *inst = GROUP_SHIFT_N;
505 ph10 662 } else
506 zherczeg 1201 *inst = GROUP_SHIFT_CL;
507 ph10 662 *buf_ptr = 0;
508     }
509    
510     if (!(b & SLJIT_MEM))
511 zherczeg 1483 *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
512 zherczeg 1453 else if ((b & REG_MASK) != SLJIT_UNUSED) {
513 zherczeg 1491 if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
514     if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
515 ph10 662 if (immb <= 127 && immb >= -128)
516     *buf_ptr |= 0x40;
517     else
518     *buf_ptr |= 0x80;
519     }
520    
521 zherczeg 1453 if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)
522     *buf_ptr++ |= reg_lmap[b & REG_MASK];
523 ph10 662 else {
524     *buf_ptr++ |= 0x04;
525 zherczeg 1453 *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3);
526 ph10 662 }
527    
528 zherczeg 1491 if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
529 ph10 662 if (immb <= 127 && immb >= -128)
530     *buf_ptr++ = immb; /* 8 bit displacement. */
531     else {
532 zherczeg 1195 *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
533     buf_ptr += sizeof(sljit_si);
534 ph10 662 }
535     }
536     }
537     else {
538 zherczeg 1491 if (reg_lmap[b & REG_MASK] == 5)
539     *buf_ptr |= 0x40;
540 ph10 662 *buf_ptr++ |= 0x04;
541 zherczeg 1453 *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6);
542 zherczeg 1491 if (reg_lmap[b & REG_MASK] == 5)
543     *buf_ptr++ = 0;
544 ph10 662 }
545     }
546     else {
547     *buf_ptr++ |= 0x04;
548     *buf_ptr++ = 0x25;
549 zherczeg 1195 *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
550     buf_ptr += sizeof(sljit_si);
551 ph10 662 }
552    
553     if (a & SLJIT_IMM) {
554     if (flags & EX86_BYTE_ARG)
555     *buf_ptr = imma;
556     else if (flags & EX86_HALF_ARG)
557     *(short*)buf_ptr = imma;
558     else if (!(flags & EX86_SHIFT_INS))
559 zherczeg 1195 *(sljit_si*)buf_ptr = imma;
560 ph10 662 }
561    
562 zherczeg 1201 return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
563 ph10 662 }
564    
565     /* --------------------------------------------------------------------- */
566     /* Call / return instructions */
567     /* --------------------------------------------------------------------- */
568    
569 zherczeg 1195 static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
570 ph10 662 {
571 zherczeg 1201 sljit_ub *inst;
572 ph10 662
573     #ifndef _WIN64
574 zherczeg 1491 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
575 ph10 662
576 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
577     FAIL_IF(!inst);
578 ph10 662 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
579     if (type >= SLJIT_CALL3) {
580 zherczeg 1201 *inst++ = REX_W;
581     *inst++ = MOV_r_rm;
582 zherczeg 1491 *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2];
583 ph10 662 }
584 zherczeg 1201 *inst++ = REX_W;
585     *inst++ = MOV_r_rm;
586 zherczeg 1491 *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0];
587 ph10 662 #else
588 zherczeg 1491 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
589 ph10 662
590 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
591     FAIL_IF(!inst);
592 ph10 662 INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
593     if (type >= SLJIT_CALL3) {
594 zherczeg 1201 *inst++ = REX_W | REX_R;
595     *inst++ = MOV_r_rm;
596 zherczeg 1491 *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2];
597 ph10 662 }
598 zherczeg 1201 *inst++ = REX_W;
599     *inst++ = MOV_r_rm;
600 zherczeg 1491 *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0];
601 ph10 662 #endif
602     return SLJIT_SUCCESS;
603     }
604    
605 zherczeg 1195 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
606 ph10 662 {
607 zherczeg 1201 sljit_ub *inst;
608 ph10 662
609     CHECK_ERROR();
610 zherczeg 955 check_sljit_emit_fast_enter(compiler, dst, dstw);
611     ADJUST_LOCAL_OFFSET(dst, dstw);
612 ph10 662
613     /* For UNUSED dst. Uncommon, but possible. */
614     if (dst == SLJIT_UNUSED)
615 zherczeg 1453 dst = TMP_REG1;
616 ph10 662
617 zherczeg 1453 if (FAST_IS_REG(dst)) {
618 ph10 662 if (reg_map[dst] < 8) {
619 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
620     FAIL_IF(!inst);
621 ph10 662 INC_SIZE(1);
622     POP_REG(reg_lmap[dst]);
623 zherczeg 1215 return SLJIT_SUCCESS;
624 ph10 662 }
625    
626 zherczeg 1215 inst = (sljit_ub*)ensure_buf(compiler, 1 + 2);
627 zherczeg 1201 FAIL_IF(!inst);
628 zherczeg 1215 INC_SIZE(2);
629     *inst++ = REX_B;
630     POP_REG(reg_lmap[dst]);
631     return SLJIT_SUCCESS;
632 ph10 662 }
633 zherczeg 1215
634     /* REX_W is not necessary (src is not immediate). */
635     compiler->mode32 = 1;
636     inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
637     FAIL_IF(!inst);
638     *inst++ = POP_rm;
639 ph10 662 return SLJIT_SUCCESS;
640     }
641    
642 zherczeg 1195 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
643 ph10 662 {
644 zherczeg 1201 sljit_ub *inst;
645 ph10 662
646     CHECK_ERROR();
647     check_sljit_emit_fast_return(compiler, src, srcw);
648 zherczeg 955 ADJUST_LOCAL_OFFSET(src, srcw);
649 ph10 662
650     if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
651 zherczeg 1453 FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
652     src = TMP_REG1;
653 ph10 662 }
654    
655 zherczeg 1453 if (FAST_IS_REG(src)) {
656 ph10 662 if (reg_map[src] < 8) {
657 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
658     FAIL_IF(!inst);
659 ph10 662
660     INC_SIZE(1 + 1);
661     PUSH_REG(reg_lmap[src]);
662     }
663     else {
664 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
665     FAIL_IF(!inst);
666 ph10 662
667     INC_SIZE(2 + 1);
668 zherczeg 1201 *inst++ = REX_B;
669 ph10 662 PUSH_REG(reg_lmap[src]);
670     }
671     }
672     else if (src & SLJIT_MEM) {
673     /* REX_W is not necessary (src is not immediate). */
674     compiler->mode32 = 1;
675 zherczeg 1201 inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
676     FAIL_IF(!inst);
677     *inst++ = GROUP_FF;
678     *inst |= PUSH_rm;
679 ph10 662
680 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
681     FAIL_IF(!inst);
682 ph10 662 INC_SIZE(1);
683     }
684     else {
685     SLJIT_ASSERT(IS_HALFWORD(srcw));
686     /* SLJIT_IMM. */
687 zherczeg 1201 inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
688     FAIL_IF(!inst);
689 ph10 662
690     INC_SIZE(5 + 1);
691 zherczeg 1201 *inst++ = PUSH_i32;
692     *(sljit_si*)inst = srcw;
693     inst += sizeof(sljit_si);
694 ph10 662 }
695    
696     RET();
697     return SLJIT_SUCCESS;
698     }
699    
700    
701     /* --------------------------------------------------------------------- */
702     /* Extend input */
703     /* --------------------------------------------------------------------- */
704    
705 zherczeg 1195 static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
706     sljit_si dst, sljit_sw dstw,
707     sljit_si src, sljit_sw srcw)
708 ph10 662 {
709 zherczeg 1201 sljit_ub* inst;
710 zherczeg 1195 sljit_si dst_r;
711 ph10 662
712     compiler->mode32 = 0;
713    
714     if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
715     return SLJIT_SUCCESS; /* Empty instruction. */
716    
717     if (src & SLJIT_IMM) {
718 zherczeg 1453 if (FAST_IS_REG(dst)) {
719 zherczeg 867 if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
720 zherczeg 1201 inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
721     FAIL_IF(!inst);
722     *inst = MOV_rm_i32;
723 zherczeg 867 return SLJIT_SUCCESS;
724     }
725 ph10 662 return emit_load_imm64(compiler, dst, srcw);
726 zherczeg 867 }
727 ph10 662 compiler->mode32 = 1;
728 zherczeg 1201 inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
729     FAIL_IF(!inst);
730     *inst = MOV_rm_i32;
731 ph10 662 compiler->mode32 = 0;
732     return SLJIT_SUCCESS;
733     }
734    
735 zherczeg 1453 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
736 ph10 662
737 zherczeg 1453 if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
738 ph10 662 dst_r = src;
739     else {
740     if (sign) {
741 zherczeg 1201 inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
742     FAIL_IF(!inst);
743     *inst++ = MOVSXD_r_rm;
744 zherczeg 847 } else {
745     compiler->mode32 = 1;
746 zherczeg 867 FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
747 zherczeg 847 compiler->mode32 = 0;
748 ph10 662 }
749     }
750    
751     if (dst & SLJIT_MEM) {
752     compiler->mode32 = 1;
753 zherczeg 1201 inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
754     FAIL_IF(!inst);
755     *inst = MOV_rm_r;
756 ph10 662 compiler->mode32 = 0;
757     }
758    
759     return SLJIT_SUCCESS;
760     }

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12