Annotation of embedaddon/pcre/sljit/sljitNativeX86_32.c, revision 1.1.1.4
1.1 misho 1: /*
2: * Stack-less Just-In-Time compiler
3: *
1.1.1.2 misho 4: * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
1.1 misho 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 32-bit arch dependent functions. */
28:
1.1.1.4 ! misho 29: static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm)
1.1 misho 30: {
1.1.1.4 ! misho 31: sljit_ub *inst;
1.1 misho 32:
1.1.1.4 ! misho 33: inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
! 34: FAIL_IF(!inst);
! 35: INC_SIZE(1 + sizeof(sljit_sw));
! 36: *inst++ = opcode;
! 37: *(sljit_sw*)inst = imm;
1.1 misho 38: return SLJIT_SUCCESS;
39: }
40:
1.1.1.4 ! misho 41: static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
1.1 misho 42: {
43: if (type == SLJIT_JUMP) {
1.1.1.4 ! misho 44: *code_ptr++ = JMP_i32;
1.1 misho 45: jump->addr++;
46: }
47: else if (type >= SLJIT_FAST_CALL) {
1.1.1.4 ! misho 48: *code_ptr++ = CALL_i32;
1.1 misho 49: jump->addr++;
50: }
51: else {
1.1.1.4 ! misho 52: *code_ptr++ = GROUP_0F;
1.1 misho 53: *code_ptr++ = get_jump_code(type);
54: jump->addr += 2;
55: }
56:
57: if (jump->flags & JUMP_LABEL)
58: jump->flags |= PATCH_MW;
59: else
1.1.1.4 ! misho 60: *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4);
1.1 misho 61: code_ptr += 4;
62:
63: return code_ptr;
64: }
65:
1.1.1.4 ! misho 66: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
1.1 misho 67: {
1.1.1.4 ! misho 68: sljit_si size;
! 69: sljit_si locals_offset;
! 70: sljit_ub *inst;
1.1 misho 71:
72: CHECK_ERROR();
1.1.1.4 ! misho 73: check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
1.1 misho 74:
1.1.1.4 ! misho 75: compiler->scratches = scratches;
1.1.1.2 misho 76: compiler->saveds = saveds;
1.1 misho 77: compiler->args = args;
78: compiler->flags_saved = 0;
1.1.1.3 misho 79: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
80: compiler->logical_local_size = local_size;
81: #endif
1.1 misho 82:
83: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
1.1.1.2 misho 84: size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
1.1 misho 85: #else
1.1.1.2 misho 86: size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
1.1 misho 87: #endif
1.1.1.4 ! misho 88: inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
! 89: FAIL_IF(!inst);
1.1 misho 90:
91: INC_SIZE(size);
92: PUSH_REG(reg_map[TMP_REGISTER]);
93: #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
94: if (args > 0) {
1.1.1.4 ! misho 95: *inst++ = MOV_r_rm;
! 96: *inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */;
1.1 misho 97: }
98: #endif
1.1.1.2 misho 99: if (saveds > 2)
100: PUSH_REG(reg_map[SLJIT_SAVED_REG3]);
101: if (saveds > 1)
102: PUSH_REG(reg_map[SLJIT_SAVED_REG2]);
103: if (saveds > 0)
104: PUSH_REG(reg_map[SLJIT_SAVED_REG1]);
1.1 misho 105:
106: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
107: if (args > 0) {
1.1.1.4 ! misho 108: *inst++ = MOV_r_rm;
! 109: *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3];
1.1 misho 110: }
111: if (args > 1) {
1.1.1.4 ! misho 112: *inst++ = MOV_r_rm;
! 113: *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2];
1.1 misho 114: }
115: if (args > 2) {
1.1.1.4 ! misho 116: *inst++ = MOV_r_rm;
! 117: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */;
! 118: *inst++ = 0x24;
! 119: *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
1.1 misho 120: }
121: #else
122: if (args > 0) {
1.1.1.4 ! misho 123: *inst++ = MOV_r_rm;
! 124: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
! 125: *inst++ = sizeof(sljit_sw) * 2;
1.1 misho 126: }
127: if (args > 1) {
1.1.1.4 ! misho 128: *inst++ = MOV_r_rm;
! 129: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
! 130: *inst++ = sizeof(sljit_sw) * 3;
1.1 misho 131: }
132: if (args > 2) {
1.1.1.4 ! misho 133: *inst++ = MOV_r_rm;
! 134: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
! 135: *inst++ = sizeof(sljit_sw) * 4;
1.1 misho 136: }
137: #endif
138:
1.1.1.4 ! misho 139: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
1.1.1.3 misho 140: locals_offset = 2 * sizeof(sljit_uw);
1.1.1.4 ! misho 141: #else
! 142: SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
! 143: locals_offset = FIXED_LOCALS_OFFSET;
! 144: #endif
! 145: compiler->scratches_start = locals_offset;
! 146: if (scratches > 3)
! 147: locals_offset += (scratches - 3) * sizeof(sljit_uw);
1.1.1.3 misho 148: compiler->saveds_start = locals_offset;
1.1.1.2 misho 149: if (saveds > 3)
1.1.1.3 misho 150: locals_offset += (saveds - 3) * sizeof(sljit_uw);
151: compiler->locals_offset = locals_offset;
1.1.1.4 ! misho 152: #if defined(__APPLE__)
! 153: saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
! 154: local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
! 155: #else
1.1.1.3 misho 156: local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
1.1.1.4 ! misho 157: #endif
1.1 misho 158:
1.1.1.4 ! misho 159: compiler->local_size = local_size;
1.1 misho 160: #ifdef _WIN32
161: if (local_size > 1024) {
1.1.1.4 ! misho 162: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
! 163: FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
! 164: #else
! 165: local_size -= FIXED_LOCALS_OFFSET;
! 166: FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
! 167: FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
! 168: SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET));
! 169: #endif
1.1.1.3 misho 170: FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
1.1 misho 171: }
172: #endif
173:
1.1.1.3 misho 174: SLJIT_ASSERT(local_size > 0);
1.1.1.4 ! misho 175: return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
1.1.1.3 misho 176: SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
1.1 misho 177: }
178:
1.1.1.4 ! misho 179: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
1.1 misho 180: {
1.1.1.4 ! misho 181: sljit_si locals_offset;
1.1.1.3 misho 182:
1.1 misho 183: CHECK_ERROR_VOID();
1.1.1.4 ! misho 184: check_sljit_set_context(compiler, args, scratches, saveds, local_size);
1.1 misho 185:
1.1.1.4 ! misho 186: compiler->scratches = scratches;
1.1.1.2 misho 187: compiler->saveds = saveds;
1.1 misho 188: compiler->args = args;
1.1.1.3 misho 189: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
190: compiler->logical_local_size = local_size;
191: #endif
192:
1.1.1.4 ! misho 193: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
1.1.1.3 misho 194: locals_offset = 2 * sizeof(sljit_uw);
1.1.1.4 ! misho 195: #else
! 196: locals_offset = FIXED_LOCALS_OFFSET;
! 197: #endif
! 198: compiler->scratches_start = locals_offset;
! 199: if (scratches > 3)
! 200: locals_offset += (scratches - 3) * sizeof(sljit_uw);
1.1.1.3 misho 201: compiler->saveds_start = locals_offset;
1.1.1.2 misho 202: if (saveds > 3)
1.1.1.3 misho 203: locals_offset += (saveds - 3) * sizeof(sljit_uw);
204: compiler->locals_offset = locals_offset;
1.1.1.4 ! misho 205: #if defined(__APPLE__)
! 206: saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
! 207: compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
! 208: #else
1.1.1.3 misho 209: compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
1.1.1.4 ! misho 210: #endif
1.1 misho 211: }
212:
1.1.1.4 ! misho 213: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1.1 misho 214: {
1.1.1.4 ! misho 215: sljit_si size;
! 216: sljit_ub *inst;
1.1 misho 217:
218: CHECK_ERROR();
1.1.1.2 misho 219: check_sljit_emit_return(compiler, op, src, srcw);
1.1 misho 220: SLJIT_ASSERT(compiler->args >= 0);
221:
222: compiler->flags_saved = 0;
1.1.1.2 misho 223: FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
1.1 misho 224:
1.1.1.3 misho 225: SLJIT_ASSERT(compiler->local_size > 0);
1.1.1.4 ! misho 226: FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
1.1.1.3 misho 227: SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
1.1 misho 228:
1.1.1.2 misho 229: size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
1.1 misho 230: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
231: if (compiler->args > 2)
232: size += 2;
233: #else
234: if (compiler->args > 0)
235: size += 2;
236: #endif
1.1.1.4 ! misho 237: inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
! 238: FAIL_IF(!inst);
1.1 misho 239:
240: INC_SIZE(size);
241:
1.1.1.2 misho 242: if (compiler->saveds > 0)
243: POP_REG(reg_map[SLJIT_SAVED_REG1]);
244: if (compiler->saveds > 1)
245: POP_REG(reg_map[SLJIT_SAVED_REG2]);
246: if (compiler->saveds > 2)
247: POP_REG(reg_map[SLJIT_SAVED_REG3]);
1.1 misho 248: POP_REG(reg_map[TMP_REGISTER]);
249: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
250: if (compiler->args > 2)
1.1.1.4 ! misho 251: RET_I16(sizeof(sljit_sw));
1.1 misho 252: else
253: RET();
254: #else
1.1.1.4 ! misho 255: RET();
1.1 misho 256: #endif
257:
258: return SLJIT_SUCCESS;
259: }
260:
261: /* --------------------------------------------------------------------- */
262: /* Operators */
263: /* --------------------------------------------------------------------- */
264:
265: /* Size contains the flags as well. */
1.1.1.4 ! misho 266: static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
1.1 misho 267: /* The register or immediate operand. */
1.1.1.4 ! misho 268: sljit_si a, sljit_sw imma,
1.1 misho 269: /* The general operand (not immediate). */
1.1.1.4 ! misho 270: sljit_si b, sljit_sw immb)
1.1 misho 271: {
1.1.1.4 ! misho 272: sljit_ub *inst;
1.1 misho 273: sljit_ub *buf_ptr;
1.1.1.4 ! misho 274: sljit_si flags = size & ~0xf;
! 275: sljit_si inst_size;
1.1 misho 276:
277: /* Both cannot be switched on. */
278: SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
279: /* Size flags not allowed for typed instructions. */
280: SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
281: /* Both size flags cannot be switched on. */
282: SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
283: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
284: /* SSE2 and immediate is not possible. */
285: SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
1.1.1.4 ! misho 286: SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
! 287: && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
! 288: && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
1.1 misho 289: #endif
290:
291: size &= 0xf;
292: inst_size = size;
293:
294: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1.1.1.4 ! misho 295: if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
1.1 misho 296: inst_size++;
297: #endif
298: if (flags & EX86_PREF_66)
299: inst_size++;
300:
301: /* Calculate size of b. */
302: inst_size += 1; /* mod r/m byte. */
303: if (b & SLJIT_MEM) {
304: if ((b & 0x0f) == SLJIT_UNUSED)
1.1.1.4 ! misho 305: inst_size += sizeof(sljit_sw);
1.1 misho 306: else if (immb != 0 && !(b & 0xf0)) {
307: /* Immediate operand. */
308: if (immb <= 127 && immb >= -128)
1.1.1.4 ! misho 309: inst_size += sizeof(sljit_sb);
1.1 misho 310: else
1.1.1.4 ! misho 311: inst_size += sizeof(sljit_sw);
1.1 misho 312: }
313:
314: if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
315: b |= SLJIT_LOCALS_REG << 4;
316:
317: if ((b & 0xf0) != SLJIT_UNUSED)
318: inst_size += 1; /* SIB byte. */
319: }
320:
321: /* Calculate size of a. */
322: if (a & SLJIT_IMM) {
323: if (flags & EX86_BIN_INS) {
324: if (imma <= 127 && imma >= -128) {
325: inst_size += 1;
326: flags |= EX86_BYTE_ARG;
327: } else
328: inst_size += 4;
329: }
330: else if (flags & EX86_SHIFT_INS) {
331: imma &= 0x1f;
332: if (imma != 1) {
333: inst_size ++;
334: flags |= EX86_BYTE_ARG;
335: }
336: } else if (flags & EX86_BYTE_ARG)
337: inst_size++;
338: else if (flags & EX86_HALF_ARG)
339: inst_size += sizeof(short);
340: else
1.1.1.4 ! misho 341: inst_size += sizeof(sljit_sw);
1.1 misho 342: }
343: else
344: SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
345:
1.1.1.4 ! misho 346: inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
! 347: PTR_FAIL_IF(!inst);
1.1 misho 348:
349: /* Encoding the byte. */
350: INC_SIZE(inst_size);
351: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
352: if (flags & EX86_PREF_F2)
1.1.1.4 ! misho 353: *inst++ = 0xf2;
! 354: if (flags & EX86_PREF_F3)
! 355: *inst++ = 0xf3;
1.1 misho 356: #endif
357: if (flags & EX86_PREF_66)
1.1.1.4 ! misho 358: *inst++ = 0x66;
1.1 misho 359:
1.1.1.4 ! misho 360: buf_ptr = inst + size;
1.1 misho 361:
362: /* Encode mod/rm byte. */
363: if (!(flags & EX86_SHIFT_INS)) {
364: if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
1.1.1.4 ! misho 365: *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
1.1 misho 366:
367: if ((a & SLJIT_IMM) || (a == 0))
368: *buf_ptr = 0;
369: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
370: else if (!(flags & EX86_SSE2))
371: *buf_ptr = reg_map[a] << 3;
372: else
373: *buf_ptr = a << 3;
374: #else
375: else
376: *buf_ptr = reg_map[a] << 3;
377: #endif
378: }
379: else {
380: if (a & SLJIT_IMM) {
381: if (imma == 1)
1.1.1.4 ! misho 382: *inst = GROUP_SHIFT_1;
1.1 misho 383: else
1.1.1.4 ! misho 384: *inst = GROUP_SHIFT_N;
1.1 misho 385: } else
1.1.1.4 ! misho 386: *inst = GROUP_SHIFT_CL;
1.1 misho 387: *buf_ptr = 0;
388: }
389:
390: if (!(b & SLJIT_MEM))
391: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
1.1.1.4 ! misho 392: *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
1.1 misho 393: #else
1.1.1.4 ! misho 394: *buf_ptr++ |= MOD_REG + reg_map[b];
1.1 misho 395: #endif
396: else if ((b & 0x0f) != SLJIT_UNUSED) {
397: if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
398: if (immb != 0) {
399: if (immb <= 127 && immb >= -128)
400: *buf_ptr |= 0x40;
401: else
402: *buf_ptr |= 0x80;
403: }
404:
405: if ((b & 0xf0) == SLJIT_UNUSED)
406: *buf_ptr++ |= reg_map[b & 0x0f];
407: else {
408: *buf_ptr++ |= 0x04;
409: *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3);
410: }
411:
412: if (immb != 0) {
413: if (immb <= 127 && immb >= -128)
414: *buf_ptr++ = immb; /* 8 bit displacement. */
415: else {
1.1.1.4 ! misho 416: *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
! 417: buf_ptr += sizeof(sljit_sw);
1.1 misho 418: }
419: }
420: }
421: else {
422: *buf_ptr++ |= 0x04;
423: *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6);
424: }
425: }
426: else {
427: *buf_ptr++ |= 0x05;
1.1.1.4 ! misho 428: *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
! 429: buf_ptr += sizeof(sljit_sw);
1.1 misho 430: }
431:
432: if (a & SLJIT_IMM) {
433: if (flags & EX86_BYTE_ARG)
434: *buf_ptr = imma;
435: else if (flags & EX86_HALF_ARG)
436: *(short*)buf_ptr = imma;
437: else if (!(flags & EX86_SHIFT_INS))
1.1.1.4 ! misho 438: *(sljit_sw*)buf_ptr = imma;
1.1 misho 439: }
440:
1.1.1.4 ! misho 441: return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
1.1 misho 442: }
443:
444: /* --------------------------------------------------------------------- */
445: /* Call / return instructions */
446: /* --------------------------------------------------------------------- */
447:
1.1.1.4 ! misho 448: static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
1.1 misho 449: {
1.1.1.4 ! misho 450: sljit_ub *inst;
1.1 misho 451:
452: #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
1.1.1.4 ! misho 453: inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
! 454: FAIL_IF(!inst);
1.1 misho 455: INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
456:
457: if (type >= SLJIT_CALL3)
1.1.1.4 ! misho 458: PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]);
! 459: *inst++ = MOV_r_rm;
! 460: *inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1];
! 461: #else
! 462: inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
! 463: FAIL_IF(!inst);
! 464: INC_SIZE(4 * (type - SLJIT_CALL0));
! 465:
! 466: *inst++ = MOV_rm_r;
! 467: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */;
! 468: *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
! 469: *inst++ = 0;
! 470: if (type >= SLJIT_CALL2) {
! 471: *inst++ = MOV_rm_r;
! 472: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */;
! 473: *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
! 474: *inst++ = sizeof(sljit_sw);
! 475: }
! 476: if (type >= SLJIT_CALL3) {
! 477: *inst++ = MOV_rm_r;
! 478: *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */;
! 479: *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
! 480: *inst++ = 2 * sizeof(sljit_sw);
! 481: }
1.1 misho 482: #endif
483: return SLJIT_SUCCESS;
484: }
485:
1.1.1.4 ! misho 486: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1.1 misho 487: {
1.1.1.4 ! misho 488: sljit_ub *inst;
1.1 misho 489:
490: CHECK_ERROR();
1.1.1.3 misho 491: check_sljit_emit_fast_enter(compiler, dst, dstw);
492: ADJUST_LOCAL_OFFSET(dst, dstw);
1.1 misho 493:
494: CHECK_EXTRA_REGS(dst, dstw, (void)0);
495:
1.1.1.4 ! misho 496: /* For UNUSED dst. Uncommon, but possible. */
! 497: if (dst == SLJIT_UNUSED)
! 498: dst = TMP_REGISTER;
! 499:
! 500: if (dst <= TMP_REGISTER) {
! 501: /* Unused dest is possible here. */
! 502: inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 503: FAIL_IF(!inst);
1.1 misho 504:
505: INC_SIZE(1);
506: POP_REG(reg_map[dst]);
507: return SLJIT_SUCCESS;
508: }
509:
1.1.1.4 ! misho 510: /* Memory. */
! 511: inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
! 512: FAIL_IF(!inst);
! 513: *inst++ = POP_rm;
1.1 misho 514: return SLJIT_SUCCESS;
515: }
516:
1.1.1.4 ! misho 517: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1.1 misho 518: {
1.1.1.4 ! misho 519: sljit_ub *inst;
1.1 misho 520:
521: CHECK_ERROR();
522: check_sljit_emit_fast_return(compiler, src, srcw);
1.1.1.3 misho 523: ADJUST_LOCAL_OFFSET(src, srcw);
1.1 misho 524:
525: CHECK_EXTRA_REGS(src, srcw, (void)0);
526:
1.1.1.4 ! misho 527: if (src <= TMP_REGISTER) {
! 528: inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
! 529: FAIL_IF(!inst);
1.1 misho 530:
531: INC_SIZE(1 + 1);
532: PUSH_REG(reg_map[src]);
533: }
534: else if (src & SLJIT_MEM) {
1.1.1.4 ! misho 535: inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
! 536: FAIL_IF(!inst);
! 537: *inst++ = GROUP_FF;
! 538: *inst |= PUSH_rm;
1.1 misho 539:
1.1.1.4 ! misho 540: inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
! 541: FAIL_IF(!inst);
1.1 misho 542: INC_SIZE(1);
543: }
544: else {
545: /* SLJIT_IMM. */
1.1.1.4 ! misho 546: inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
! 547: FAIL_IF(!inst);
1.1 misho 548:
549: INC_SIZE(5 + 1);
1.1.1.4 ! misho 550: *inst++ = PUSH_i32;
! 551: *(sljit_sw*)inst = srcw;
! 552: inst += sizeof(sljit_sw);
1.1 misho 553: }
554:
555: RET();
556: return SLJIT_SUCCESS;
557: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>