File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitNativeX86_64.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:05:52 2012 UTC (12 years, 5 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /*
    2:  *    Stack-less Just-In-Time compiler
    3:  *
    4:  *    Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
    5:  *
    6:  * Redistribution and use in source and binary forms, with or without modification, are
    7:  * permitted provided that the following conditions are met:
    8:  *
    9:  *   1. Redistributions of source code must retain the above copyright notice, this list of
   10:  *      conditions and the following disclaimer.
   11:  *
   12:  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
   13:  *      of conditions and the following disclaimer in the documentation and/or other materials
   14:  *      provided with the distribution.
   15:  *
   16:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
   17:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
   19:  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   20:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   21:  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
   22:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   23:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25:  */
   26: 
   27: /* x86 64-bit arch dependent functions. */
   28: 
   29: static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
   30: {
   31: 	sljit_ub *buf;
   32: 
   33: 	buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));
   34: 	FAIL_IF(!buf);
   35: 	INC_SIZE(2 + sizeof(sljit_w));
   36: 	*buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
   37: 	*buf++ = 0xb8 + (reg_map[reg] & 0x7);
   38: 	*(sljit_w*)buf = imm;
   39: 	return SLJIT_SUCCESS;
   40: }
   41: 
   42: static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
   43: {
   44: 	if (type < SLJIT_JUMP) {
   45: 		*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
   46: 		*code_ptr++ = 10 + 3;
   47: 	}
   48: 
   49: 	SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
   50: 	*code_ptr++ = REX_W | REX_B;
   51: 	*code_ptr++ = 0xb8 + 1;
   52: 	jump->addr = (sljit_uw)code_ptr;
   53: 
   54: 	if (jump->flags & JUMP_LABEL)
   55: 		jump->flags |= PATCH_MD;
   56: 	else
   57: 		*(sljit_w*)code_ptr = jump->u.target;
   58: 
   59: 	code_ptr += sizeof(sljit_w);
   60: 	*code_ptr++ = REX_B;
   61: 	*code_ptr++ = 0xff;
   62: 	*code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
   63: 
   64: 	return code_ptr;
   65: }
   66: 
   67: static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
   68: {
   69: 	sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
   70: 
   71: 	if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
   72: 		*code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
   73: 		*(sljit_w*)code_ptr = delta;
   74: 	}
   75: 	else {
   76: 		SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
   77: 		*code_ptr++ = REX_W | REX_B;
   78: 		*code_ptr++ = 0xb8 + 1;
   79: 		*(sljit_w*)code_ptr = addr;
   80: 		code_ptr += sizeof(sljit_w);
   81: 		*code_ptr++ = REX_B;
   82: 		*code_ptr++ = 0xff;
   83: 		*code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
   84: 	}
   85: 
   86: 	return code_ptr;
   87: }
   88: 
   89: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
   90: {
   91: 	int size, pushed_size;
   92: 	sljit_ub *buf;
   93: 
   94: 	CHECK_ERROR();
   95: 	check_sljit_emit_enter(compiler, args, temporaries, generals, local_size);
   96: 
   97: 	compiler->temporaries = temporaries;
   98: 	compiler->generals = generals;
   99: 	compiler->flags_saved = 0;
  100: 
  101: 	size = generals;
  102: 	/* Including the return address saved by the call instruction. */
  103: 	pushed_size = (generals + 1) * sizeof(sljit_w);
  104: #ifndef _WIN64
  105: 	if (generals >= 2)
  106: 		size += generals - 1;
  107: #else
  108: 	/* Saving the virtual stack pointer. */
  109: 	compiler->has_locals = local_size > 0;
  110: 	if (local_size > 0) {
  111: 		size += 2;
  112: 		pushed_size += sizeof(sljit_w);
  113: 	}
  114: 	if (generals >= 4)
  115: 		size += generals - 3;
  116: 	if (temporaries >= 5) {
  117: 		size += (5 - 4) * 2;
  118: 		pushed_size += sizeof(sljit_w);
  119: 	}
  120: #endif
  121: 	size += args * 3;
  122: 	if (size > 0) {
  123: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
  124: 		FAIL_IF(!buf);
  125: 
  126: 		INC_SIZE(size);
  127: 		if (generals >= 5) {
  128: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_EREG2] >= 8, general_ereg2_is_hireg);
  129: 			*buf++ = REX_B;
  130: 			PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG2]);
  131: 		}
  132: 		if (generals >= 4) {
  133: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_EREG1] >= 8, general_ereg1_is_hireg);
  134: 			*buf++ = REX_B;
  135: 			PUSH_REG(reg_lmap[SLJIT_GENERAL_EREG1]);
  136: 		}
  137: 		if (generals >= 3) {
  138: #ifndef _WIN64
  139: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG3] >= 8, general_reg3_is_hireg);
  140: 			*buf++ = REX_B;
  141: #else
  142: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG3] < 8, general_reg3_is_loreg);
  143: #endif
  144: 			PUSH_REG(reg_lmap[SLJIT_GENERAL_REG3]);
  145: 		}
  146: 		if (generals >= 2) {
  147: #ifndef _WIN64
  148: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG2] >= 8, general_reg2_is_hireg);
  149: 			*buf++ = REX_B;
  150: #else
  151: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG2] < 8, general_reg2_is_loreg);
  152: #endif
  153: 			PUSH_REG(reg_lmap[SLJIT_GENERAL_REG2]);
  154: 		}
  155: 		if (generals >= 1) {
  156: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_GENERAL_REG1] < 8, general_reg1_is_loreg);
  157: 			PUSH_REG(reg_lmap[SLJIT_GENERAL_REG1]);
  158: 		}
  159: #ifdef _WIN64
  160: 		if (temporaries >= 5) {
  161: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
  162: 			*buf++ = REX_B;
  163: 			PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
  164: 		}
  165: 		if (local_size > 0) {
  166: 			SLJIT_COMPILE_ASSERT(reg_map[SLJIT_LOCALS_REG] >= 8, locals_reg_is_hireg);
  167: 			*buf++ = REX_B;
  168: 			PUSH_REG(reg_lmap[SLJIT_LOCALS_REG]);
  169: 		}
  170: #endif
  171: 
  172: #ifndef _WIN64
  173: 		if (args > 0) {
  174: 			*buf++ = REX_W;
  175: 			*buf++ = 0x8b;
  176: 			*buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG1] << 3) | 0x7;
  177: 		}
  178: 		if (args > 1) {
  179: 			*buf++ = REX_W | REX_R;
  180: 			*buf++ = 0x8b;
  181: 			*buf++ = 0xc0 | (reg_lmap[SLJIT_GENERAL_REG2] << 3) | 0x6;
  182: 		}
  183: 		if (args > 2) {
  184: 			*buf++ = REX_W | REX_R;
  185: 			*buf++ = 0x8b;
  186: 			*buf++ = 0xc0 | (reg_lmap[SLJIT_GENERAL_REG3] << 3) | 0x2;
  187: 		}
  188: #else
  189: 		if (args > 0) {
  190: 			*buf++ = REX_W;
  191: 			*buf++ = 0x8b;
  192: 			*buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG1] << 3) | 0x1;
  193: 		}
  194: 		if (args > 1) {
  195: 			*buf++ = REX_W;
  196: 			*buf++ = 0x8b;
  197: 			*buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG2] << 3) | 0x2;
  198: 		}
  199: 		if (args > 2) {
  200: 			*buf++ = REX_W | REX_B;
  201: 			*buf++ = 0x8b;
  202: 			*buf++ = 0xc0 | (reg_map[SLJIT_GENERAL_REG3] << 3) | 0x0;
  203: 		}
  204: #endif
  205: 	}
  206: 
  207: 	local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
  208: #ifdef _WIN64
  209: 	local_size += 4 * sizeof(sljit_w);
  210: 	compiler->local_size = local_size;
  211: 	if (local_size > 1024) {
  212: 		/* Allocate the stack for the function itself. */
  213: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
  214: 		FAIL_IF(!buf);
  215: 		INC_SIZE(4);
  216: 		*buf++ = REX_W;
  217: 		*buf++ = 0x83;
  218: 		*buf++ = 0xc0 | (5 << 3) | 4;
  219: 		/* Pushed size must be divisible by 8. */
  220: 		SLJIT_ASSERT(!(pushed_size & 0x7));
  221: 		if (pushed_size & 0x8) {
  222: 			*buf++ = 5 * sizeof(sljit_w);
  223: 			local_size -= 5 * sizeof(sljit_w);
  224: 		} else {
  225: 			*buf++ = 4 * sizeof(sljit_w);
  226: 			local_size -= 4 * sizeof(sljit_w);
  227: 		}
  228: 		FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
  229: 		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
  230: 	}
  231: #else
  232: 	compiler->local_size = local_size;
  233: 	if (local_size > 0) {
  234: #endif
  235: 		/* In case of Win64, local_size is always > 4 * sizeof(sljit_w) */
  236: 		if (local_size <= 127) {
  237: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
  238: 			FAIL_IF(!buf);
  239: 			INC_SIZE(4);
  240: 			*buf++ = REX_W;
  241: 			*buf++ = 0x83;
  242: 			*buf++ = 0xc0 | (5 << 3) | 4;
  243: 			*buf++ = local_size;
  244: 		}
  245: 		else {
  246: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
  247: 			FAIL_IF(!buf);
  248: 			INC_SIZE(7);
  249: 			*buf++ = REX_W;
  250: 			*buf++ = 0x81;
  251: 			*buf++ = 0xc0 | (5 << 3) | 4;
  252: 			*(sljit_hw*)buf = local_size;
  253: 			buf += sizeof(sljit_hw);
  254: 		}
  255: #ifndef _WIN64
  256: 	}
  257: #endif
  258: 
  259: #ifdef _WIN64
  260: 	if (compiler->has_locals) {
  261: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
  262: 		FAIL_IF(!buf);
  263: 		INC_SIZE(5);
  264: 		*buf++ = REX_W | REX_R;
  265: 		*buf++ = 0x8d;
  266: 		*buf++ = 0x40 | (reg_lmap[SLJIT_LOCALS_REG] << 3) | 0x4;
  267: 		*buf++ = 0x24;
  268: 		*buf = 4 * sizeof(sljit_w);
  269: 	}
  270: #endif
  271: 
  272: 	/* Mov arguments to general registers. */
  273: 	return SLJIT_SUCCESS;
  274: }
  275: 
  276: SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
  277: {
  278: 	int pushed_size;
  279: 
  280: 	CHECK_ERROR_VOID();
  281: 	check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
  282: 
  283: 	compiler->temporaries = temporaries;
  284: 	compiler->generals = generals;
  285: 	/* Including the return address saved by the call instruction. */
  286: 	pushed_size = (generals + 1) * sizeof(sljit_w);
  287: #ifdef _WIN64
  288: 	compiler->has_locals = local_size > 0;
  289: 	if (local_size > 0)
  290: 		pushed_size += sizeof(sljit_w);
  291: 	if (temporaries >= 5)
  292: 		pushed_size += sizeof(sljit_w);
  293: #endif
  294: 	compiler->local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
  295: #ifdef _WIN64
  296: 	compiler->local_size += 4 * sizeof(sljit_w);
  297: #endif
  298: }
  299: 
  300: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
  301: {
  302: 	int size;
  303: 	sljit_ub *buf;
  304: 
  305: 	CHECK_ERROR();
  306: 	check_sljit_emit_return(compiler, src, srcw);
  307: 
  308: 	compiler->flags_saved = 0;
  309: 
  310: 	if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG) {
  311: 		compiler->mode32 = 0;
  312: 		FAIL_IF(emit_mov(compiler, SLJIT_RETURN_REG, 0, src, srcw));
  313: 	}
  314: 
  315: 	if (compiler->local_size > 0) {
  316: 		if (compiler->local_size <= 127) {
  317: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
  318: 			FAIL_IF(!buf);
  319: 			INC_SIZE(4);
  320: 			*buf++ = REX_W;
  321: 			*buf++ = 0x83;
  322: 			*buf++ = 0xc0 | (0 << 3) | 4;
  323: 			*buf = compiler->local_size;
  324: 		}
  325: 		else {
  326: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
  327: 			FAIL_IF(!buf);
  328: 			INC_SIZE(7);
  329: 			*buf++ = REX_W;
  330: 			*buf++ = 0x81;
  331: 			*buf++ = 0xc0 | (0 << 3) | 4;
  332: 			*(sljit_hw*)buf = compiler->local_size;
  333: 		}
  334: 	}
  335: 
  336: 	size = 1 + compiler->generals;
  337: #ifndef _WIN64
  338: 	if (compiler->generals >= 2)
  339: 		size += compiler->generals - 1;
  340: #else
  341: 	if (compiler->has_locals)
  342: 		size += 2;
  343: 	if (compiler->generals >= 4)
  344: 		size += compiler->generals - 3;
  345: 	if (compiler->temporaries >= 5)
  346: 		size += (5 - 4) * 2;
  347: #endif
  348: 	buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
  349: 	FAIL_IF(!buf);
  350: 
  351: 	INC_SIZE(size);
  352: 
  353: #ifdef _WIN64
  354: 	if (compiler->has_locals) {
  355: 		*buf++ = REX_B;
  356: 		POP_REG(reg_lmap[SLJIT_LOCALS_REG]);
  357: 	}
  358: 	if (compiler->temporaries >= 5) {
  359: 		*buf++ = REX_B;
  360: 		POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
  361: 	}
  362: #endif
  363: 	if (compiler->generals >= 1)
  364: 		POP_REG(reg_map[SLJIT_GENERAL_REG1]);
  365: 	if (compiler->generals >= 2) {
  366: #ifndef _WIN64
  367: 		*buf++ = REX_B;
  368: #endif
  369: 		POP_REG(reg_lmap[SLJIT_GENERAL_REG2]);
  370: 	}
  371: 	if (compiler->generals >= 3) {
  372: #ifndef _WIN64
  373: 		*buf++ = REX_B;
  374: #endif
  375: 		POP_REG(reg_lmap[SLJIT_GENERAL_REG3]);
  376: 	}
  377: 	if (compiler->generals >= 4) {
  378: 		*buf++ = REX_B;
  379: 		POP_REG(reg_lmap[SLJIT_GENERAL_EREG1]);
  380: 	}
  381: 	if (compiler->generals >= 5) {
  382: 		*buf++ = REX_B;
  383: 		POP_REG(reg_lmap[SLJIT_GENERAL_EREG2]);
  384: 	}
  385: 
  386: 	RET();
  387: 	return SLJIT_SUCCESS;
  388: }
  389: 
  390: /* --------------------------------------------------------------------- */
  391: /*  Operators                                                            */
  392: /* --------------------------------------------------------------------- */
  393: 
  394: static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
  395: {
  396: 	sljit_ub *buf;
  397: 
  398: 	if (rex != 0) {
  399: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));
  400: 		FAIL_IF(!buf);
  401: 		INC_SIZE(2 + sizeof(sljit_hw));
  402: 		*buf++ = rex;
  403: 		*buf++ = opcode;
  404: 		*(sljit_hw*)buf = imm;
  405: 	}
  406: 	else {
  407: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw));
  408: 		FAIL_IF(!buf);
  409: 		INC_SIZE(1 + sizeof(sljit_hw));
  410: 		*buf++ = opcode;
  411: 		*(sljit_hw*)buf = imm;
  412: 	}
  413: 	return SLJIT_SUCCESS;
  414: }
  415: 
  416: static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
  417: 	/* The register or immediate operand. */
  418: 	int a, sljit_w imma,
  419: 	/* The general operand (not immediate). */
  420: 	int b, sljit_w immb)
  421: {
  422: 	sljit_ub *buf;
  423: 	sljit_ub *buf_ptr;
  424: 	sljit_ub rex = 0;
  425: 	int flags = size & ~0xf;
  426: 	int inst_size;
  427: 
  428: 	/* The immediate operand must be 32 bit. */
  429: 	SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
  430: 	/* Both cannot be switched on. */
  431: 	SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
  432: 	/* Size flags not allowed for typed instructions. */
  433: 	SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
  434: 	/* Both size flags cannot be switched on. */
  435: 	SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
  436: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  437: 	/* SSE2 and immediate is not possible. */
  438: 	SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
  439: #endif
  440: 
  441: 	size &= 0xf;
  442: 	inst_size = size;
  443: 
  444: 	if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) {
  445: 		if (emit_load_imm64(compiler, TMP_REG3, immb))
  446: 			return NULL;
  447: 		immb = 0;
  448: 		if (b & 0xf)
  449: 			b |= TMP_REG3 << 4;
  450: 		else
  451: 			b |= TMP_REG3;
  452: 	}
  453: 
  454: 	if (!compiler->mode32 && !(flags & EX86_NO_REXW))
  455: 		rex |= REX_W;
  456: 	else if (flags & EX86_REX)
  457: 		rex |= REX;
  458: 
  459: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  460: 	if (flags & EX86_PREF_F2)
  461: 		inst_size++;
  462: #endif
  463: 	if (flags & EX86_PREF_66)
  464: 		inst_size++;
  465: 
  466: 	/* Calculate size of b. */
  467: 	inst_size += 1; /* mod r/m byte. */
  468: 	if (b & SLJIT_MEM) {
  469: 		if ((b & 0x0f) == SLJIT_UNUSED)
  470: 			inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */
  471: 		else {
  472: 			if (reg_map[b & 0x0f] >= 8)
  473: 				rex |= REX_B;
  474: 			if (immb != 0 && !(b & 0xf0)) {
  475: 				/* Immediate operand. */
  476: 				if (immb <= 127 && immb >= -128)
  477: 					inst_size += sizeof(sljit_b);
  478: 				else
  479: 					inst_size += sizeof(sljit_hw);
  480: 			}
  481: 		}
  482: 
  483: #ifndef _WIN64
  484: 		if ((b & 0xf) == SLJIT_LOCALS_REG && (b & 0xf0) == 0)
  485: 			b |= SLJIT_LOCALS_REG << 4;
  486: #endif
  487: 
  488: 		if ((b & 0xf0) != SLJIT_UNUSED) {
  489: 			inst_size += 1; /* SIB byte. */
  490: 			if (reg_map[(b >> 4) & 0x0f] >= 8)
  491: 				rex |= REX_X;
  492: 		}
  493: 	}
  494: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  495: 	else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
  496: 		rex |= REX_B;
  497: #else
  498: 	else if (reg_map[b] >= 8)
  499: 		rex |= REX_B;
  500: #endif
  501: 
  502: 	if (a & SLJIT_IMM) {
  503: 		if (flags & EX86_BIN_INS) {
  504: 			if (imma <= 127 && imma >= -128) {
  505: 				inst_size += 1;
  506: 				flags |= EX86_BYTE_ARG;
  507: 			} else
  508: 				inst_size += 4;
  509: 		}
  510: 		else if (flags & EX86_SHIFT_INS) {
  511: 			imma &= 0x3f;
  512: 			if (imma != 1) {
  513: 				inst_size ++;
  514: 				flags |= EX86_BYTE_ARG;
  515: 			}
  516: 		} else if (flags & EX86_BYTE_ARG)
  517: 			inst_size++;
  518: 		else if (flags & EX86_HALF_ARG)
  519: 			inst_size += sizeof(short);
  520: 		else
  521: 			inst_size += sizeof(sljit_hw);
  522: 	}
  523: 	else {
  524: 		SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
  525: 		/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
  526: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  527: 		if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
  528: 			rex |= REX_R;
  529: #else
  530: 		if (reg_map[a] >= 8)
  531: 			rex |= REX_R;
  532: #endif
  533: 	}
  534: 
  535: 	if (rex)
  536: 		inst_size++;
  537: 
  538: 	buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
  539: 	PTR_FAIL_IF(!buf);
  540: 
  541: 	/* Encoding the byte. */
  542: 	INC_SIZE(inst_size);
  543: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  544: 	if (flags & EX86_PREF_F2)
  545: 		*buf++ = 0xf2;
  546: #endif
  547: 	if (flags & EX86_PREF_66)
  548: 		*buf++ = 0x66;
  549: 	if (rex)
  550: 		*buf++ = rex;
  551: 	buf_ptr = buf + size;
  552: 
  553: 	/* Encode mod/rm byte. */
  554: 	if (!(flags & EX86_SHIFT_INS)) {
  555: 		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
  556: 			*buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
  557: 
  558: 		if ((a & SLJIT_IMM) || (a == 0))
  559: 			*buf_ptr = 0;
  560: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  561: 		else if (!(flags & EX86_SSE2))
  562: 			*buf_ptr = reg_lmap[a] << 3;
  563: 		else
  564: 			*buf_ptr = a << 3;
  565: #else
  566: 		else
  567: 			*buf_ptr = reg_lmap[a] << 3;
  568: #endif
  569: 	}
  570: 	else {
  571: 		if (a & SLJIT_IMM) {
  572: 			if (imma == 1)
  573: 				*buf = 0xd1;
  574: 			else
  575: 				*buf = 0xc1;
  576: 		} else
  577: 			*buf = 0xd3;
  578: 		*buf_ptr = 0;
  579: 	}
  580: 
  581: 	if (!(b & SLJIT_MEM))
  582: #if (defined SLJIT_SSE2 && SLJIT_SSE2)
  583: 		*buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
  584: #else
  585: 		*buf_ptr++ |= 0xc0 + reg_lmap[b];
  586: #endif
  587: 	else if ((b & 0x0f) != SLJIT_UNUSED) {
  588: #ifdef _WIN64
  589: 		SLJIT_ASSERT((b & 0xf0) != (SLJIT_LOCALS_REG << 4));
  590: #endif
  591: 		if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
  592: 			if (immb != 0) {
  593: 				if (immb <= 127 && immb >= -128)
  594: 					*buf_ptr |= 0x40;
  595: 				else
  596: 					*buf_ptr |= 0x80;
  597: 			}
  598: 
  599: 			if ((b & 0xf0) == SLJIT_UNUSED)
  600: 				*buf_ptr++ |= reg_lmap[b & 0x0f];
  601: 			else {
  602: 				*buf_ptr++ |= 0x04;
  603: 				*buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3);
  604: 			}
  605: 
  606: 			if (immb != 0) {
  607: 				if (immb <= 127 && immb >= -128)
  608: 					*buf_ptr++ = immb; /* 8 bit displacement. */
  609: 				else {
  610: 					*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
  611: 					buf_ptr += sizeof(sljit_hw);
  612: 				}
  613: 			}
  614: 		}
  615: 		else {
  616: 			*buf_ptr++ |= 0x04;
  617: 			*buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6);
  618: 		}
  619: 	}
  620: 	else {
  621: 		*buf_ptr++ |= 0x04;
  622: 		*buf_ptr++ = 0x25;
  623: 		*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
  624: 		buf_ptr += sizeof(sljit_hw);
  625: 	}
  626: 
  627: 	if (a & SLJIT_IMM) {
  628: 		if (flags & EX86_BYTE_ARG)
  629: 			*buf_ptr = imma;
  630: 		else if (flags & EX86_HALF_ARG)
  631: 			*(short*)buf_ptr = imma;
  632: 		else if (!(flags & EX86_SHIFT_INS))
  633: 			*(sljit_hw*)buf_ptr = imma;
  634: 	}
  635: 
  636: 	return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
  637: }
  638: 
  639: /* --------------------------------------------------------------------- */
  640: /*  Call / return instructions                                           */
  641: /* --------------------------------------------------------------------- */
  642: 
  643: static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
  644: {
  645: 	sljit_ub *buf;
  646: 
  647: #ifndef _WIN64
  648: 	SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
  649: 
  650: 	buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
  651: 	FAIL_IF(!buf);
  652: 	INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
  653: 	if (type >= SLJIT_CALL3) {
  654: 		*buf++ = REX_W;
  655: 		*buf++ = 0x8b;
  656: 		*buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
  657: 	}
  658: 	*buf++ = REX_W;
  659: 	*buf++ = 0x8b;
  660: 	*buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
  661: #else
  662: 	SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
  663: 
  664: 	buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
  665: 	FAIL_IF(!buf);
  666: 	INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
  667: 	if (type >= SLJIT_CALL3) {
  668: 		*buf++ = REX_W | REX_R;
  669: 		*buf++ = 0x8b;
  670: 		*buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
  671: 	}
  672: 	*buf++ = REX_W;
  673: 	*buf++ = 0x8b;
  674: 	*buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
  675: #endif
  676: 	return SLJIT_SUCCESS;
  677: }
  678: 
  679: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int generals, int local_size)
  680: {
  681: 	sljit_ub *buf;
  682: 
  683: 	CHECK_ERROR();
  684: 	check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, generals, local_size);
  685: 
  686: 	compiler->temporaries = temporaries;
  687: 	compiler->generals = generals;
  688: 	compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
  689: #ifdef _WIN64
  690: 	compiler->local_size += 4 * sizeof(sljit_w);
  691: #endif
  692: 
  693: 	/* For UNUSED dst. Uncommon, but possible. */
  694: 	if (dst == SLJIT_UNUSED)
  695: 		dst = TMP_REGISTER;
  696: 
  697: 	if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
  698: 		if (reg_map[dst] < 8) {
  699: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
  700: 			FAIL_IF(!buf);
  701: 
  702: 			INC_SIZE(1);
  703: 			POP_REG(reg_lmap[dst]);
  704: 		}
  705: 		else {
  706: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
  707: 			FAIL_IF(!buf);
  708: 
  709: 			INC_SIZE(2);
  710: 			*buf++ = REX_B;
  711: 			POP_REG(reg_lmap[dst]);
  712: 		}
  713: 	}
  714: 	else if (dst & SLJIT_MEM) {
  715: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
  716: 		/* REX_W is not necessary (src is not immediate). */
  717: 		compiler->mode32 = 1;
  718: #endif
  719: 		buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
  720: 		FAIL_IF(!buf);
  721: 		*buf++ = 0x8f;
  722: 	}
  723: 	return SLJIT_SUCCESS;
  724: }
  725: 
  726: SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
  727: {
  728: 	sljit_ub *buf;
  729: 
  730: 	CHECK_ERROR();
  731: 	check_sljit_emit_fast_return(compiler, src, srcw);
  732: 
  733: 	CHECK_EXTRA_REGS(src, srcw, (void)0);
  734: 
  735: 	if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
  736: 		FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw));
  737: 		src = TMP_REGISTER;
  738: 	}
  739: 
  740: 	if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
  741: 		if (reg_map[src] < 8) {
  742: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
  743: 			FAIL_IF(!buf);
  744: 
  745: 			INC_SIZE(1 + 1);
  746: 			PUSH_REG(reg_lmap[src]);
  747: 		}
  748: 		else {
  749: 			buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
  750: 			FAIL_IF(!buf);
  751: 
  752: 			INC_SIZE(2 + 1);
  753: 			*buf++ = REX_B;
  754: 			PUSH_REG(reg_lmap[src]);
  755: 		}
  756: 	}
  757: 	else if (src & SLJIT_MEM) {
  758: #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
  759: 		/* REX_W is not necessary (src is not immediate). */
  760: 		compiler->mode32 = 1;
  761: #endif
  762: 		buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
  763: 		FAIL_IF(!buf);
  764: 		*buf++ = 0xff;
  765: 		*buf |= 6 << 3;
  766: 
  767: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
  768: 		FAIL_IF(!buf);
  769: 		INC_SIZE(1);
  770: 	}
  771: 	else {
  772: 		SLJIT_ASSERT(IS_HALFWORD(srcw));
  773: 		/* SLJIT_IMM. */
  774: 		buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
  775: 		FAIL_IF(!buf);
  776: 
  777: 		INC_SIZE(5 + 1);
  778: 		*buf++ = 0x68;
  779: 		*(sljit_hw*)buf = srcw;
  780: 		buf += sizeof(sljit_hw);
  781: 	}
  782: 
  783: 	RET();
  784: 	return SLJIT_SUCCESS;
  785: }
  786: 
  787: 
  788: /* --------------------------------------------------------------------- */
  789: /*  Extend input                                                         */
  790: /* --------------------------------------------------------------------- */
  791: 
  792: static int emit_mov_int(struct sljit_compiler *compiler, int sign,
  793: 	int dst, sljit_w dstw,
  794: 	int src, sljit_w srcw)
  795: {
  796: 	sljit_ub* code;
  797: 	int dst_r;
  798: 
  799: 	compiler->mode32 = 0;
  800: 
  801: 	if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
  802: 		return SLJIT_SUCCESS; /* Empty instruction. */
  803: 
  804: 	if (src & SLJIT_IMM) {
  805: 		if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
  806: 			return emit_load_imm64(compiler, dst, srcw);
  807: 		compiler->mode32 = 1;
  808: 		code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(int)srcw, dst, dstw);
  809: 		FAIL_IF(!code);
  810: 		*code = 0xc7;
  811: 		compiler->mode32 = 0;
  812: 		return SLJIT_SUCCESS;
  813: 	}
  814: 
  815: 	dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_GENERAL_REG3) ? dst : TMP_REGISTER;
  816: 
  817: 	if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_GENERAL_REG3))
  818: 		dst_r = src;
  819: 	else {
  820: 		if (sign) {
  821: 			code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
  822: 			FAIL_IF(!code);
  823: 			*code++ = 0x63;
  824: 		}
  825: 		else {
  826: 			if (dst_r == src) {
  827: 				compiler->mode32 = 1;
  828: 				code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, 0);
  829: 				FAIL_IF(!code);
  830: 				*code++ = 0x8b;
  831: 				compiler->mode32 = 0;
  832: 			}
  833: 			/* xor reg, reg. */
  834: 			code = emit_x86_instruction(compiler, 1, dst_r, 0, dst_r, 0);
  835: 			FAIL_IF(!code);
  836: 			*code++ = 0x33;
  837: 			if (dst_r != src) {
  838: 				compiler->mode32 = 1;
  839: 				code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
  840: 				FAIL_IF(!code);
  841: 				*code++ = 0x8b;
  842: 				compiler->mode32 = 0;
  843: 			}
  844: 			else {
  845: 				compiler->mode32 = 1;
  846: 				code = emit_x86_instruction(compiler, 1, src, 0, TMP_REGISTER, 0);
  847: 				FAIL_IF(!code);
  848: 				*code++ = 0x8b;
  849: 				compiler->mode32 = 0;
  850: 			}
  851: 		}
  852: 	}
  853: 
  854: 	if (dst & SLJIT_MEM) {
  855: 		compiler->mode32 = 1;
  856: 		code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
  857: 		FAIL_IF(!code);
  858: 		*code = 0x89;
  859: 		compiler->mode32 = 0;
  860: 	}
  861: 
  862: 	return SLJIT_SUCCESS;
  863: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>