File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitNativeSPARC_common.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:25:57 2013 UTC (10 years, 11 months ago) by misho
Branches: pcre, MAIN
CVS tags: v8_34, v8_33, HEAD
8.33

    1: /*
    2:  *    Stack-less Just-In-Time compiler
    3:  *
    4:  *    Copyright 2009-2012 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: SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
   28: {
   29: 	return "SPARC" SLJIT_CPUINFO;
   30: }
   31: 
   32: /* Length of an instruction word
   33:    Both for sparc-32 and sparc-64 */
   34: typedef sljit_ui sljit_ins;
   35: 
   36: static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
   37: {
   38: #if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
   39: 	__asm (
   40: 		/* if (from == to) return */
   41: 		"cmp %i0, %i1\n"
   42: 		"be .leave\n"
   43: 		"nop\n"
   44: 
   45: 		/* loop until from >= to */
   46: 		".mainloop:\n"
   47: 		"flush %i0\n"
   48: 		"add %i0, 8, %i0\n"
   49: 		"cmp %i0, %i1\n"
   50: 		"bcs .mainloop\n"
   51: 		"nop\n"
   52: 
   53: 		/* The comparison was done above. */
   54: 		"bne .leave\n"
   55: 		/* nop is not necessary here, since the
   56: 		   sub operation has no side effect. */
   57: 		"sub %i0, 4, %i0\n"
   58: 		"flush %i0\n"
   59: 		".leave:"
   60: 	);
   61: #else
   62: 	if (SLJIT_UNLIKELY(from == to))
   63: 		return;
   64: 
   65: 	do {
   66: 		__asm__ volatile (
   67: 			"flush %0\n"
   68: 			: : "r"(from)
   69: 		);
   70: 		/* Operates at least on doubleword. */
   71: 		from += 2;
   72: 	} while (from < to);
   73: 
   74: 	if (from == to) {
   75: 		/* Flush the last word. */
   76: 		from --;
   77: 		__asm__ volatile (
   78: 			"flush %0\n"
   79: 			: : "r"(from)
   80: 		);
   81: 	}
   82: #endif
   83: }
   84: 
   85: /* TMP_REG2 is not used by getput_arg */
   86: #define TMP_REG1	(SLJIT_NO_REGISTERS + 1)
   87: #define TMP_REG2	(SLJIT_NO_REGISTERS + 2)
   88: #define TMP_REG3	(SLJIT_NO_REGISTERS + 3)
   89: #define TMP_REG4	(SLJIT_NO_REGISTERS + 4)
   90: #define LINK_REG	(SLJIT_NO_REGISTERS + 5)
   91: 
   92: #define TMP_FREG1	(0)
   93: #define TMP_FREG2	((SLJIT_FLOAT_REG6 + 1) << 1)
   94: 
   95: static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
   96: 	0, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 14, 1, 24, 25, 26, 15
   97: };
   98: 
   99: /* --------------------------------------------------------------------- */
  100: /*  Instrucion forms                                                     */
  101: /* --------------------------------------------------------------------- */
  102: 
  103: #define D(d)		(reg_map[d] << 25)
  104: #define DA(d)		((d) << 25)
  105: #define S1(s1)		(reg_map[s1] << 14)
  106: #define S2(s2)		(reg_map[s2])
  107: #define S1A(s1)		((s1) << 14)
  108: #define S2A(s2)		(s2)
  109: #define IMM_ARG		0x2000
  110: #define DOP(op)		((op) << 5)
  111: #define IMM(imm)	(((imm) & 0x1fff) | IMM_ARG)
  112: 
  113: #define DR(dr)		(reg_map[dr])
  114: #define OPC1(opcode)	((opcode) << 30)
  115: #define OPC2(opcode)	((opcode) << 22)
  116: #define OPC3(opcode)	((opcode) << 19)
  117: #define SET_FLAGS	OPC3(0x10)
  118: 
  119: #define ADD		(OPC1(0x2) | OPC3(0x00))
  120: #define ADDC		(OPC1(0x2) | OPC3(0x08))
  121: #define AND		(OPC1(0x2) | OPC3(0x01))
  122: #define ANDN		(OPC1(0x2) | OPC3(0x05))
  123: #define CALL		(OPC1(0x1))
  124: #define FABSS		(OPC1(0x2) | OPC3(0x34) | DOP(0x09))
  125: #define FADDD		(OPC1(0x2) | OPC3(0x34) | DOP(0x42))
  126: #define FADDS		(OPC1(0x2) | OPC3(0x34) | DOP(0x41))
  127: #define FCMPD		(OPC1(0x2) | OPC3(0x35) | DOP(0x52))
  128: #define FCMPS		(OPC1(0x2) | OPC3(0x35) | DOP(0x51))
  129: #define FDIVD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
  130: #define FDIVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
  131: #define FMOVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x01))
  132: #define FMULD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
  133: #define FMULS		(OPC1(0x2) | OPC3(0x34) | DOP(0x49))
  134: #define FNEGS		(OPC1(0x2) | OPC3(0x34) | DOP(0x05))
  135: #define FSUBD		(OPC1(0x2) | OPC3(0x34) | DOP(0x46))
  136: #define FSUBS		(OPC1(0x2) | OPC3(0x34) | DOP(0x45))
  137: #define JMPL		(OPC1(0x2) | OPC3(0x38))
  138: #define NOP		(OPC1(0x0) | OPC2(0x04))
  139: #define OR		(OPC1(0x2) | OPC3(0x02))
  140: #define ORN		(OPC1(0x2) | OPC3(0x06))
  141: #define RDY		(OPC1(0x2) | OPC3(0x28) | S1A(0))
  142: #define RESTORE		(OPC1(0x2) | OPC3(0x3d))
  143: #define SAVE		(OPC1(0x2) | OPC3(0x3c))
  144: #define SETHI		(OPC1(0x0) | OPC2(0x04))
  145: #define SLL		(OPC1(0x2) | OPC3(0x25))
  146: #define SLLX		(OPC1(0x2) | OPC3(0x25) | (1 << 12))
  147: #define SRA		(OPC1(0x2) | OPC3(0x27))
  148: #define SRAX		(OPC1(0x2) | OPC3(0x27) | (1 << 12))
  149: #define SRL		(OPC1(0x2) | OPC3(0x26))
  150: #define SRLX		(OPC1(0x2) | OPC3(0x26) | (1 << 12))
  151: #define SUB		(OPC1(0x2) | OPC3(0x04))
  152: #define SUBC		(OPC1(0x2) | OPC3(0x0c))
  153: #define TA		(OPC1(0x2) | OPC3(0x3a) | (8 << 25))
  154: #define WRY		(OPC1(0x2) | OPC3(0x30) | DA(0))
  155: #define XOR		(OPC1(0x2) | OPC3(0x03))
  156: #define XNOR		(OPC1(0x2) | OPC3(0x07))
  157: 
  158: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  159: #define MAX_DISP	(0x1fffff)
  160: #define MIN_DISP	(-0x200000)
  161: #define DISP_MASK	(0x3fffff)
  162: 
  163: #define BICC		(OPC1(0x0) | OPC2(0x2))
  164: #define FBFCC		(OPC1(0x0) | OPC2(0x6))
  165: #define SLL_W		SLL
  166: #define SDIV		(OPC1(0x2) | OPC3(0x0f))
  167: #define SMUL		(OPC1(0x2) | OPC3(0x0b))
  168: #define UDIV		(OPC1(0x2) | OPC3(0x0e))
  169: #define UMUL		(OPC1(0x2) | OPC3(0x0a))
  170: #else
  171: #define SLL_W		SLLX
  172: #endif
  173: 
  174: #define SIMM_MAX	(0x0fff)
  175: #define SIMM_MIN	(-0x1000)
  176: 
  177: /* dest_reg is the absolute name of the register
  178:    Useful for reordering instructions in the delay slot. */
  179: static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
  180: {
  181: 	sljit_ins *ptr;
  182: 	SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
  183: 		|| (delay_slot & DST_INS_MASK) == MOVABLE_INS
  184: 		|| (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
  185: 	ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
  186: 	FAIL_IF(!ptr);
  187: 	*ptr = ins;
  188: 	compiler->size++;
  189: 	compiler->delay_slot = delay_slot;
  190: 	return SLJIT_SUCCESS;
  191: }
  192: 
  193: static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
  194: {
  195: 	sljit_sw diff;
  196: 	sljit_uw target_addr;
  197: 	sljit_ins *inst;
  198: 	sljit_ins saved_inst;
  199: 
  200: 	if (jump->flags & SLJIT_REWRITABLE_JUMP)
  201: 		return code_ptr;
  202: 
  203: 	if (jump->flags & JUMP_ADDR)
  204: 		target_addr = jump->u.target;
  205: 	else {
  206: 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
  207: 		target_addr = (sljit_uw)(code + jump->u.label->size);
  208: 	}
  209: 	inst = (sljit_ins*)jump->addr;
  210: 
  211: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  212: 	if (jump->flags & IS_CALL) {
  213: 		/* Call is always patchable on sparc 32. */
  214: 		jump->flags |= PATCH_CALL;
  215: 		if (jump->flags & IS_MOVABLE) {
  216: 			inst[0] = inst[-1];
  217: 			inst[-1] = CALL;
  218: 			jump->addr -= sizeof(sljit_ins);
  219: 			return inst;
  220: 		}
  221: 		inst[0] = CALL;
  222: 		inst[1] = NOP;
  223: 		return inst + 1;
  224: 	}
  225: #else
  226: 	/* Both calls and BPr instructions shall not pass this point. */
  227: #error "Implementation required"
  228: #endif
  229: 
  230: 	if (jump->flags & IS_COND)
  231: 		inst--;
  232: 
  233: 	if (jump->flags & IS_MOVABLE) {
  234: 		diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
  235: 		if (diff <= MAX_DISP && diff >= MIN_DISP) {
  236: 			jump->flags |= PATCH_B;
  237: 			inst--;
  238: 			if (jump->flags & IS_COND) {
  239: 				saved_inst = inst[0];
  240: 				inst[0] = inst[1] ^ (1 << 28);
  241: 				inst[1] = saved_inst;
  242: 			} else {
  243: 				inst[1] = inst[0];
  244: 				inst[0] = BICC | DA(0x8);
  245: 			}
  246: 			jump->addr = (sljit_uw)inst;
  247: 			return inst + 1;
  248: 		}
  249: 	}
  250: 
  251: 	diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
  252: 	if (diff <= MAX_DISP && diff >= MIN_DISP) {
  253: 		jump->flags |= PATCH_B;
  254: 		if (jump->flags & IS_COND)
  255: 			inst[0] ^= (1 << 28);
  256: 		else
  257: 			inst[0] = BICC | DA(0x8);
  258: 		inst[1] = NOP;
  259: 		jump->addr = (sljit_uw)inst;
  260: 		return inst + 1;
  261: 	}
  262: 
  263: 	return code_ptr;
  264: }
  265: 
  266: SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
  267: {
  268: 	struct sljit_memory_fragment *buf;
  269: 	sljit_ins *code;
  270: 	sljit_ins *code_ptr;
  271: 	sljit_ins *buf_ptr;
  272: 	sljit_ins *buf_end;
  273: 	sljit_uw word_count;
  274: 	sljit_uw addr;
  275: 
  276: 	struct sljit_label *label;
  277: 	struct sljit_jump *jump;
  278: 	struct sljit_const *const_;
  279: 
  280: 	CHECK_ERROR_PTR();
  281: 	check_sljit_generate_code(compiler);
  282: 	reverse_buf(compiler);
  283: 
  284: 	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
  285: 	PTR_FAIL_WITH_EXEC_IF(code);
  286: 	buf = compiler->buf;
  287: 
  288: 	code_ptr = code;
  289: 	word_count = 0;
  290: 	label = compiler->labels;
  291: 	jump = compiler->jumps;
  292: 	const_ = compiler->consts;
  293: 	do {
  294: 		buf_ptr = (sljit_ins*)buf->memory;
  295: 		buf_end = buf_ptr + (buf->used_size >> 2);
  296: 		do {
  297: 			*code_ptr = *buf_ptr++;
  298: 			SLJIT_ASSERT(!label || label->size >= word_count);
  299: 			SLJIT_ASSERT(!jump || jump->addr >= word_count);
  300: 			SLJIT_ASSERT(!const_ || const_->addr >= word_count);
  301: 			/* These structures are ordered by their address. */
  302: 			if (label && label->size == word_count) {
  303: 				/* Just recording the address. */
  304: 				label->addr = (sljit_uw)code_ptr;
  305: 				label->size = code_ptr - code;
  306: 				label = label->next;
  307: 			}
  308: 			if (jump && jump->addr == word_count) {
  309: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  310: 				jump->addr = (sljit_uw)(code_ptr - 3);
  311: #else
  312: 				jump->addr = (sljit_uw)(code_ptr - 6);
  313: #endif
  314: 				code_ptr = optimize_jump(jump, code_ptr, code);
  315: 				jump = jump->next;
  316: 			}
  317: 			if (const_ && const_->addr == word_count) {
  318: 				/* Just recording the address. */
  319: 				const_->addr = (sljit_uw)code_ptr;
  320: 				const_ = const_->next;
  321: 			}
  322: 			code_ptr ++;
  323: 			word_count ++;
  324: 		} while (buf_ptr < buf_end);
  325: 
  326: 		buf = buf->next;
  327: 	} while (buf);
  328: 
  329: 	if (label && label->size == word_count) {
  330: 		label->addr = (sljit_uw)code_ptr;
  331: 		label->size = code_ptr - code;
  332: 		label = label->next;
  333: 	}
  334: 
  335: 	SLJIT_ASSERT(!label);
  336: 	SLJIT_ASSERT(!jump);
  337: 	SLJIT_ASSERT(!const_);
  338: 	SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size);
  339: 
  340: 	jump = compiler->jumps;
  341: 	while (jump) {
  342: 		do {
  343: 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
  344: 			buf_ptr = (sljit_ins*)jump->addr;
  345: 
  346: 			if (jump->flags & PATCH_CALL) {
  347: 				addr = (sljit_sw)(addr - jump->addr) >> 2;
  348: 				SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
  349: 				buf_ptr[0] = CALL | (addr & 0x3fffffff);
  350: 				break;
  351: 			}
  352: 			if (jump->flags & PATCH_B) {
  353: 				addr = (sljit_sw)(addr - jump->addr) >> 2;
  354: 				SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
  355: 				buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
  356: 				break;
  357: 			}
  358: 
  359: 			/* Set the fields of immediate loads. */
  360: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  361: 			buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
  362: 			buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
  363: #else
  364: #error "Implementation required"
  365: #endif
  366: 		} while (0);
  367: 		jump = jump->next;
  368: 	}
  369: 
  370: 
  371: 	compiler->error = SLJIT_ERR_COMPILED;
  372: 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
  373: 	SLJIT_CACHE_FLUSH(code, code_ptr);
  374: 	return code;
  375: }
  376: 
  377: /* --------------------------------------------------------------------- */
  378: /*  Entry, exit                                                          */
  379: /* --------------------------------------------------------------------- */
  380: 
  381: /* Creates an index in data_transfer_insts array. */
  382: #define LOAD_DATA	0x01
  383: #define WORD_DATA	0x00
  384: #define BYTE_DATA	0x02
  385: #define HALF_DATA	0x04
  386: #define INT_DATA	0x06
  387: #define SIGNED_DATA	0x08
  388: /* Separates integer and floating point registers */
  389: #define GPR_REG		0x0f
  390: #define DOUBLE_DATA	0x10
  391: 
  392: #define MEM_MASK	0x1f
  393: 
  394: #define WRITE_BACK	0x00020
  395: #define ARG_TEST	0x00040
  396: #define ALT_KEEP_CACHE	0x00080
  397: #define CUMULATIVE_OP	0x00100
  398: #define IMM_OP		0x00200
  399: #define SRC2_IMM	0x00400
  400: 
  401: #define REG_DEST	0x00800
  402: #define REG2_SOURCE	0x01000
  403: #define SLOW_SRC1	0x02000
  404: #define SLOW_SRC2	0x04000
  405: #define SLOW_DEST	0x08000
  406: 
  407: /* SET_FLAGS (0x10 << 19) also belong here! */
  408: 
  409: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  410: #include "sljitNativeSPARC_32.c"
  411: #else
  412: #include "sljitNativeSPARC_64.c"
  413: #endif
  414: 
  415: 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)
  416: {
  417: 	CHECK_ERROR();
  418: 	check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
  419: 
  420: 	compiler->scratches = scratches;
  421: 	compiler->saveds = saveds;
  422: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
  423: 	compiler->logical_local_size = local_size;
  424: #endif
  425: 
  426: 	local_size += 23 * sizeof(sljit_sw);
  427: 	local_size = (local_size + 7) & ~0x7;
  428: 	compiler->local_size = local_size;
  429: 
  430: 	if (local_size <= SIMM_MAX) {
  431: 		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | IMM(-local_size), UNMOVABLE_INS));
  432: 	}
  433: 	else {
  434: 		FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
  435: 		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | S2(TMP_REG1), UNMOVABLE_INS));
  436: 	}
  437: 
  438: 	if (args >= 1)
  439: 		FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG1) | S1(0) | S2A(24), DR(SLJIT_SAVED_REG1)));
  440: 	if (args >= 2)
  441: 		FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG2) | S1(0) | S2A(25), DR(SLJIT_SAVED_REG2)));
  442: 	if (args >= 3)
  443: 		FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG3) | S1(0) | S2A(26), DR(SLJIT_SAVED_REG3)));
  444: 
  445: 	return SLJIT_SUCCESS;
  446: }
  447: 
  448: 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)
  449: {
  450: 	CHECK_ERROR_VOID();
  451: 	check_sljit_set_context(compiler, args, scratches, saveds, local_size);
  452: 
  453: 	compiler->scratches = scratches;
  454: 	compiler->saveds = saveds;
  455: #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
  456: 	compiler->logical_local_size = local_size;
  457: #endif
  458: 
  459: 	local_size += 23 * sizeof(sljit_sw);
  460: 	compiler->local_size = (local_size + 7) & ~0x7;
  461: }
  462: 
  463: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
  464: {
  465: 	CHECK_ERROR();
  466: 	check_sljit_emit_return(compiler, op, src, srcw);
  467: 
  468: 	if (op != SLJIT_MOV || !(src <= TMP_REG3)) {
  469: 		FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  470: 		src = SLJIT_SCRATCH_REG1;
  471: 	}
  472: 
  473: 	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
  474: 	return push_inst(compiler, RESTORE | D(SLJIT_SCRATCH_REG1) | S1(src) | S2(0), UNMOVABLE_INS);
  475: }
  476: 
  477: /* --------------------------------------------------------------------- */
  478: /*  Operators                                                            */
  479: /* --------------------------------------------------------------------- */
  480: 
  481: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  482: #define ARCH_32_64(a, b)	a
  483: #else
  484: #define ARCH_32_64(a, b)	b
  485: #endif
  486: 
  487: static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = {
  488: /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  489: /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  490: /* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
  491: /* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,
  492: /* u h s */ OPC1(3) | OPC3(0x06) /* sth */,
  493: /* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,
  494: /* u i s */ OPC1(3) | OPC3(0x04) /* stw */,
  495: /* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,
  496: 
  497: /* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  498: /* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  499: /* s b s */ OPC1(3) | OPC3(0x05) /* stb */,
  500: /* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,
  501: /* s h s */ OPC1(3) | OPC3(0x06) /* sth */,
  502: /* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,
  503: /* s i s */ OPC1(3) | OPC3(0x04) /* stw */,
  504: /* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),
  505: 
  506: /* d   s */ OPC1(3) | OPC3(0x27),
  507: /* d   l */ OPC1(3) | OPC3(0x23),
  508: /* s   s */ OPC1(3) | OPC3(0x24),
  509: /* s   l */ OPC1(3) | OPC3(0x20),
  510: };
  511: 
  512: #undef ARCH_32_64
  513: 
  514: /* Can perform an operation using at most 1 instruction. */
  515: static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  516: {
  517: 	SLJIT_ASSERT(arg & SLJIT_MEM);
  518: 
  519: 	if (!(flags & WRITE_BACK) || !(arg & 0xf)) {
  520: 		if ((!(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN)
  521: 				|| ((arg & 0xf0) && (argw & 0x3) == 0)) {
  522: 			/* Works for both absoulte and relative addresses (immediate case). */
  523: 			if (SLJIT_UNLIKELY(flags & ARG_TEST))
  524: 				return 1;
  525: 			FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
  526: 				| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
  527: 				| S1(arg & 0xf) | ((arg & 0xf0) ? S2((arg >> 4) & 0xf) : IMM(argw)),
  528: 				((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
  529: 			return -1;
  530: 		}
  531: 	}
  532: 	return 0;
  533: }
  534: 
  535: /* See getput_arg below.
  536:    Note: can_cache is called only for binary operators. Those
  537:    operators always uses word arguments without write back. */
  538: static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  539: {
  540: 	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
  541: 
  542: 	/* Simple operation except for updates. */
  543: 	if (arg & 0xf0) {
  544: 		argw &= 0x3;
  545: 		SLJIT_ASSERT(argw);
  546: 		next_argw &= 0x3;
  547: 		if ((arg & 0xf0) == (next_arg & 0xf0) && argw == next_argw)
  548: 			return 1;
  549: 		return 0;
  550: 	}
  551: 
  552: 	if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
  553: 		return 1;
  554: 	return 0;
  555: }
  556: 
  557: /* Emit the necessary instructions. See can_cache above. */
  558: static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  559: {
  560: 	sljit_si base, arg2, delay_slot;
  561: 	sljit_ins dest;
  562: 
  563: 	SLJIT_ASSERT(arg & SLJIT_MEM);
  564: 	if (!(next_arg & SLJIT_MEM)) {
  565: 		next_arg = 0;
  566: 		next_argw = 0;
  567: 	}
  568: 
  569: 	base = arg & 0xf;
  570: 	if (SLJIT_UNLIKELY(arg & 0xf0)) {
  571: 		argw &= 0x3;
  572: 		SLJIT_ASSERT(argw != 0);
  573: 
  574: 		/* Using the cache. */
  575: 		if (((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) && (argw == compiler->cache_argw))
  576: 			arg2 = TMP_REG3;
  577: 		else {
  578: 			if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) {
  579: 				compiler->cache_arg = SLJIT_MEM | (arg & 0xf0);
  580: 				compiler->cache_argw = argw;
  581: 				arg2 = TMP_REG3;
  582: 			}
  583: 			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && (reg << 4) != (arg & 0xf0))
  584: 				arg2 = reg;
  585: 			else /* It must be a mov operation, so tmp1 must be free to use. */
  586: 				arg2 = TMP_REG1;
  587: 			FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1((arg >> 4) & 0xf) | IMM_ARG | argw, DR(arg2)));
  588: 		}
  589: 	}
  590: 	else {
  591: 		/* Using the cache. */
  592: 		if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
  593: 			if (argw != compiler->cache_argw) {
  594: 				FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
  595: 				compiler->cache_argw = argw;
  596: 			}
  597: 			arg2 = TMP_REG3;
  598: 		} else {
  599: 			if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {
  600: 				compiler->cache_arg = SLJIT_MEM;
  601: 				compiler->cache_argw = argw;
  602: 				arg2 = TMP_REG3;
  603: 			}
  604: 			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)
  605: 				arg2 = reg;
  606: 			else /* It must be a mov operation, so tmp1 must be free to use. */
  607: 				arg2 = TMP_REG1;
  608: 			FAIL_IF(load_immediate(compiler, arg2, argw));
  609: 		}
  610: 	}
  611: 
  612: 	dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
  613: 	delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
  614: 	if (!base)
  615: 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
  616: 	if (!(flags & WRITE_BACK))
  617: 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
  618: 	FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
  619: 	return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
  620: }
  621: 
  622: static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  623: {
  624: 	if (getput_arg_fast(compiler, flags, reg, arg, argw))
  625: 		return compiler->error;
  626: 	compiler->cache_arg = 0;
  627: 	compiler->cache_argw = 0;
  628: 	return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
  629: }
  630: 
  631: static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
  632: {
  633: 	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
  634: 		return compiler->error;
  635: 	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
  636: }
  637: 
  638: static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
  639: 	sljit_si dst, sljit_sw dstw,
  640: 	sljit_si src1, sljit_sw src1w,
  641: 	sljit_si src2, sljit_sw src2w)
  642: {
  643: 	/* arg1 goes to TMP_REG1 or src reg
  644: 	   arg2 goes to TMP_REG2, imm or src reg
  645: 	   TMP_REG3 can be used for caching
  646: 	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
  647: 	sljit_si dst_r = TMP_REG2;
  648: 	sljit_si src1_r;
  649: 	sljit_sw src2_r = 0;
  650: 	sljit_si sugg_src2_r = TMP_REG2;
  651: 
  652: 	if (!(flags & ALT_KEEP_CACHE)) {
  653: 		compiler->cache_arg = 0;
  654: 		compiler->cache_argw = 0;
  655: 	}
  656: 
  657: 	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
  658: 		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
  659: 			return SLJIT_SUCCESS;
  660: 	}
  661: 	else if (dst <= TMP_REG3) {
  662: 		dst_r = dst;
  663: 		flags |= REG_DEST;
  664: 		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
  665: 			sugg_src2_r = dst_r;
  666: 	}
  667: 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
  668: 		flags |= SLOW_DEST;
  669: 
  670: 	if (flags & IMM_OP) {
  671: 		if ((src2 & SLJIT_IMM) && src2w) {
  672: 			if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
  673: 				flags |= SRC2_IMM;
  674: 				src2_r = src2w;
  675: 			}
  676: 		}
  677: 		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
  678: 			if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
  679: 				flags |= SRC2_IMM;
  680: 				src2_r = src1w;
  681: 
  682: 				/* And swap arguments. */
  683: 				src1 = src2;
  684: 				src1w = src2w;
  685: 				src2 = SLJIT_IMM;
  686: 				/* src2w = src2_r unneeded. */
  687: 			}
  688: 		}
  689: 	}
  690: 
  691: 	/* Source 1. */
  692: 	if (src1 <= TMP_REG3)
  693: 		src1_r = src1;
  694: 	else if (src1 & SLJIT_IMM) {
  695: 		if (src1w) {
  696: 			FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
  697: 			src1_r = TMP_REG1;
  698: 		}
  699: 		else
  700: 			src1_r = 0;
  701: 	}
  702: 	else {
  703: 		if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
  704: 			FAIL_IF(compiler->error);
  705: 		else
  706: 			flags |= SLOW_SRC1;
  707: 		src1_r = TMP_REG1;
  708: 	}
  709: 
  710: 	/* Source 2. */
  711: 	if (src2 <= TMP_REG3) {
  712: 		src2_r = src2;
  713: 		flags |= REG2_SOURCE;
  714: 		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
  715: 			dst_r = src2_r;
  716: 	}
  717: 	else if (src2 & SLJIT_IMM) {
  718: 		if (!(flags & SRC2_IMM)) {
  719: 			if (src2w) {
  720: 				FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
  721: 				src2_r = sugg_src2_r;
  722: 			}
  723: 			else {
  724: 				src2_r = 0;
  725: 				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM))
  726: 					dst_r = 0;
  727: 			}
  728: 		}
  729: 	}
  730: 	else {
  731: 		if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
  732: 			FAIL_IF(compiler->error);
  733: 		else
  734: 			flags |= SLOW_SRC2;
  735: 		src2_r = sugg_src2_r;
  736: 	}
  737: 
  738: 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
  739: 		SLJIT_ASSERT(src2_r == TMP_REG2);
  740: 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
  741: 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
  742: 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  743: 		}
  744: 		else {
  745: 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
  746: 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
  747: 		}
  748: 	}
  749: 	else if (flags & SLOW_SRC1)
  750: 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  751: 	else if (flags & SLOW_SRC2)
  752: 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
  753: 
  754: 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
  755: 
  756: 	if (dst & SLJIT_MEM) {
  757: 		if (!(flags & SLOW_DEST)) {
  758: 			getput_arg_fast(compiler, flags, dst_r, dst, dstw);
  759: 			return compiler->error;
  760: 		}
  761: 		return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
  762: 	}
  763: 
  764: 	return SLJIT_SUCCESS;
  765: }
  766: 
  767: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
  768: {
  769: 	CHECK_ERROR();
  770: 	check_sljit_emit_op0(compiler, op);
  771: 
  772: 	op = GET_OPCODE(op);
  773: 	switch (op) {
  774: 	case SLJIT_BREAKPOINT:
  775: 		return push_inst(compiler, TA, UNMOVABLE_INS);
  776: 	case SLJIT_NOP:
  777: 		return push_inst(compiler, NOP, UNMOVABLE_INS);
  778: 	case SLJIT_UMUL:
  779: 	case SLJIT_SMUL:
  780: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  781: 		FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1)));
  782: 		return push_inst(compiler, RDY | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2));
  783: #else
  784: #error "Implementation required"
  785: #endif
  786: 	case SLJIT_UDIV:
  787: 	case SLJIT_SDIV:
  788: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  789: 		if (op == SLJIT_UDIV)
  790: 			FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
  791: 		else {
  792: 			FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_SCRATCH_REG1) | IMM(31), DR(TMP_REG1)));
  793: 			FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
  794: 		}
  795: 		FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_SCRATCH_REG1), DR(TMP_REG2)));
  796: 		FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1)));
  797: 		FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_SCRATCH_REG2) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)));
  798: 		FAIL_IF(push_inst(compiler, SUB | D(SLJIT_SCRATCH_REG2) | S1(TMP_REG2) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)));
  799: 		return SLJIT_SUCCESS;
  800: #else
  801: #error "Implementation required"
  802: #endif
  803: 	}
  804: 
  805: 	return SLJIT_SUCCESS;
  806: }
  807: 
  808: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
  809: 	sljit_si dst, sljit_sw dstw,
  810: 	sljit_si src, sljit_sw srcw)
  811: {
  812: 	sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  813: 
  814: 	CHECK_ERROR();
  815: 	check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
  816: 	ADJUST_LOCAL_OFFSET(dst, dstw);
  817: 	ADJUST_LOCAL_OFFSET(src, srcw);
  818: 
  819: 	op = GET_OPCODE(op);
  820: 	switch (op) {
  821: 	case SLJIT_MOV:
  822: 	case SLJIT_MOV_P:
  823: 		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  824: 
  825: 	case SLJIT_MOV_UI:
  826: 		return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  827: 
  828: 	case SLJIT_MOV_SI:
  829: 		return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  830: 
  831: 	case SLJIT_MOV_UB:
  832: 		return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
  833: 
  834: 	case SLJIT_MOV_SB:
  835: 		return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
  836: 
  837: 	case SLJIT_MOV_UH:
  838: 		return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
  839: 
  840: 	case SLJIT_MOV_SH:
  841: 		return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
  842: 
  843: 	case SLJIT_MOVU:
  844: 	case SLJIT_MOVU_P:
  845: 		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  846: 
  847: 	case SLJIT_MOVU_UI:
  848: 		return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  849: 
  850: 	case SLJIT_MOVU_SI:
  851: 		return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  852: 
  853: 	case SLJIT_MOVU_UB:
  854: 		return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
  855: 
  856: 	case SLJIT_MOVU_SB:
  857: 		return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
  858: 
  859: 	case SLJIT_MOVU_UH:
  860: 		return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
  861: 
  862: 	case SLJIT_MOVU_SH:
  863: 		return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
  864: 
  865: 	case SLJIT_NOT:
  866: 	case SLJIT_CLZ:
  867: 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
  868: 
  869: 	case SLJIT_NEG:
  870: 		return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
  871: 	}
  872: 
  873: 	return SLJIT_SUCCESS;
  874: }
  875: 
  876: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
  877: 	sljit_si dst, sljit_sw dstw,
  878: 	sljit_si src1, sljit_sw src1w,
  879: 	sljit_si src2, sljit_sw src2w)
  880: {
  881: 	sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  882: 
  883: 	CHECK_ERROR();
  884: 	check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
  885: 	ADJUST_LOCAL_OFFSET(dst, dstw);
  886: 	ADJUST_LOCAL_OFFSET(src1, src1w);
  887: 	ADJUST_LOCAL_OFFSET(src2, src2w);
  888: 
  889: 	op = GET_OPCODE(op);
  890: 	switch (op) {
  891: 	case SLJIT_ADD:
  892: 	case SLJIT_ADDC:
  893: 	case SLJIT_MUL:
  894: 	case SLJIT_AND:
  895: 	case SLJIT_OR:
  896: 	case SLJIT_XOR:
  897: 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  898: 
  899: 	case SLJIT_SUB:
  900: 	case SLJIT_SUBC:
  901: 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  902: 
  903: 	case SLJIT_SHL:
  904: 	case SLJIT_LSHR:
  905: 	case SLJIT_ASHR:
  906: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  907: 		if (src2 & SLJIT_IMM)
  908: 			src2w &= 0x1f;
  909: #else
  910: 		SLJIT_ASSERT_STOP();
  911: #endif
  912: 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  913: 	}
  914: 
  915: 	return SLJIT_SUCCESS;
  916: }
  917: 
  918: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
  919: {
  920: 	check_sljit_get_register_index(reg);
  921: 	return reg_map[reg];
  922: }
  923: 
  924: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
  925: {
  926: 	check_sljit_get_float_register_index(reg);
  927: 	return reg << 1;
  928: }
  929: 
  930: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
  931: 	void *instruction, sljit_si size)
  932: {
  933: 	CHECK_ERROR();
  934: 	check_sljit_emit_op_custom(compiler, instruction, size);
  935: 	SLJIT_ASSERT(size == 4);
  936: 
  937: 	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
  938: }
  939: 
  940: /* --------------------------------------------------------------------- */
  941: /*  Floating point operators                                             */
  942: /* --------------------------------------------------------------------- */
  943: 
  944: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
  945: {
  946: 	return 1;
  947: }
  948: 
  949: #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))
  950: #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
  951: 
  952: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
  953: 	sljit_si dst, sljit_sw dstw,
  954: 	sljit_si src, sljit_sw srcw)
  955: {
  956: 	sljit_si dst_fr;
  957: 
  958: 	CHECK_ERROR();
  959: 	check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
  960: 	SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
  961: 
  962: 	compiler->cache_arg = 0;
  963: 	compiler->cache_argw = 0;
  964: 
  965: 	if (GET_OPCODE(op) == SLJIT_CMPD) {
  966: 		if (dst > SLJIT_FLOAT_REG6) {
  967: 			FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw));
  968: 			dst = TMP_FREG1;
  969: 		}
  970: 		else
  971: 			dst <<= 1;
  972: 
  973: 		if (src > SLJIT_FLOAT_REG6) {
  974: 			FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0));
  975: 			src = TMP_FREG2;
  976: 		}
  977: 		else
  978: 			src <<= 1;
  979: 
  980: 		return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(dst) | S2A(src), FCC_IS_SET | MOVABLE_INS);
  981: 	}
  982: 
  983: 	dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1);
  984: 
  985: 	if (src > SLJIT_FLOAT_REG6) {
  986: 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw));
  987: 		src = dst_fr;
  988: 	}
  989: 	else
  990: 		src <<= 1;
  991: 
  992: 	switch (GET_OPCODE(op)) {
  993: 		case SLJIT_MOVD:
  994: 			if (src != dst_fr && dst_fr != TMP_FREG1) {
  995: 				FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr) | S2A(src), MOVABLE_INS));
  996: 				if (!(op & SLJIT_SINGLE_OP))
  997: 					FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
  998: 			}
  999: 			break;
 1000: 		case SLJIT_NEGD:
 1001: 			FAIL_IF(push_inst(compiler, FNEGS | DA(dst_fr) | S2A(src), MOVABLE_INS));
 1002: 			if (dst_fr != src && !(op & SLJIT_SINGLE_OP))
 1003: 				FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
 1004: 			break;
 1005: 		case SLJIT_ABSD:
 1006: 			FAIL_IF(push_inst(compiler, FABSS | DA(dst_fr) | S2A(src), MOVABLE_INS));
 1007: 			if (dst_fr != src && !(op & SLJIT_SINGLE_OP))
 1008: 				FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
 1009: 			break;
 1010: 	}
 1011: 
 1012: 	if (dst_fr == TMP_FREG1) {
 1013: 		if (GET_OPCODE(op) == SLJIT_MOVD)
 1014: 			dst_fr = src;
 1015: 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0));
 1016: 	}
 1017: 
 1018: 	return SLJIT_SUCCESS;
 1019: }
 1020: 
 1021: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
 1022: 	sljit_si dst, sljit_sw dstw,
 1023: 	sljit_si src1, sljit_sw src1w,
 1024: 	sljit_si src2, sljit_sw src2w)
 1025: {
 1026: 	sljit_si dst_fr, flags = 0;
 1027: 
 1028: 	CHECK_ERROR();
 1029: 	check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
 1030: 
 1031: 	compiler->cache_arg = 0;
 1032: 	compiler->cache_argw = 0;
 1033: 
 1034: 	dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : (dst << 1);
 1035: 
 1036: 	if (src1 > SLJIT_FLOAT_REG6) {
 1037: 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
 1038: 			FAIL_IF(compiler->error);
 1039: 			src1 = TMP_FREG1;
 1040: 		} else
 1041: 			flags |= SLOW_SRC1;
 1042: 	}
 1043: 	else
 1044: 		src1 <<= 1;
 1045: 
 1046: 	if (src2 > SLJIT_FLOAT_REG6) {
 1047: 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
 1048: 			FAIL_IF(compiler->error);
 1049: 			src2 = TMP_FREG2;
 1050: 		} else
 1051: 			flags |= SLOW_SRC2;
 1052: 	}
 1053: 	else
 1054: 		src2 <<= 1;
 1055: 
 1056: 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
 1057: 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
 1058: 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
 1059: 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
 1060: 		}
 1061: 		else {
 1062: 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
 1063: 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
 1064: 		}
 1065: 	}
 1066: 	else if (flags & SLOW_SRC1)
 1067: 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
 1068: 	else if (flags & SLOW_SRC2)
 1069: 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
 1070: 
 1071: 	if (flags & SLOW_SRC1)
 1072: 		src1 = TMP_FREG1;
 1073: 	if (flags & SLOW_SRC2)
 1074: 		src2 = TMP_FREG2;
 1075: 
 1076: 	switch (GET_OPCODE(op)) {
 1077: 	case SLJIT_ADDD:
 1078: 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
 1079: 		break;
 1080: 
 1081: 	case SLJIT_SUBD:
 1082: 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
 1083: 		break;
 1084: 
 1085: 	case SLJIT_MULD:
 1086: 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
 1087: 		break;
 1088: 
 1089: 	case SLJIT_DIVD:
 1090: 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
 1091: 		break;
 1092: 	}
 1093: 
 1094: 	if (dst_fr == TMP_FREG2)
 1095: 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
 1096: 
 1097: 	return SLJIT_SUCCESS;
 1098: }
 1099: 
 1100: #undef FLOAT_DATA
 1101: #undef SELECT_FOP
 1102: 
 1103: /* --------------------------------------------------------------------- */
 1104: /*  Other instructions                                                   */
 1105: /* --------------------------------------------------------------------- */
 1106: 
 1107: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
 1108: {
 1109: 	CHECK_ERROR();
 1110: 	check_sljit_emit_fast_enter(compiler, dst, dstw);
 1111: 	ADJUST_LOCAL_OFFSET(dst, dstw);
 1112: 
 1113: 	/* For UNUSED dst. Uncommon, but possible. */
 1114: 	if (dst == SLJIT_UNUSED)
 1115: 		return SLJIT_SUCCESS;
 1116: 
 1117: 	if (dst <= TMP_REG3)
 1118: 		return push_inst(compiler, OR | D(dst) | S1(0) | S2(LINK_REG), DR(dst));
 1119: 
 1120: 	/* Memory. */
 1121: 	return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw);
 1122: }
 1123: 
 1124: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
 1125: {
 1126: 	CHECK_ERROR();
 1127: 	check_sljit_emit_fast_return(compiler, src, srcw);
 1128: 	ADJUST_LOCAL_OFFSET(src, srcw);
 1129: 
 1130: 	if (src <= TMP_REG3)
 1131: 		FAIL_IF(push_inst(compiler, OR | D(LINK_REG) | S1(0) | S2(src), DR(LINK_REG)));
 1132: 	else if (src & SLJIT_MEM)
 1133: 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, LINK_REG, src, srcw));
 1134: 	else if (src & SLJIT_IMM)
 1135: 		FAIL_IF(load_immediate(compiler, LINK_REG, srcw));
 1136: 
 1137: 	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(LINK_REG) | IMM(8), UNMOVABLE_INS));
 1138: 	return push_inst(compiler, NOP, UNMOVABLE_INS);
 1139: }
 1140: 
 1141: /* --------------------------------------------------------------------- */
 1142: /*  Conditional instructions                                             */
 1143: /* --------------------------------------------------------------------- */
 1144: 
 1145: SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
 1146: {
 1147: 	struct sljit_label *label;
 1148: 
 1149: 	CHECK_ERROR_PTR();
 1150: 	check_sljit_emit_label(compiler);
 1151: 
 1152: 	if (compiler->last_label && compiler->last_label->size == compiler->size)
 1153: 		return compiler->last_label;
 1154: 
 1155: 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
 1156: 	PTR_FAIL_IF(!label);
 1157: 	set_label(label, compiler);
 1158: 	compiler->delay_slot = UNMOVABLE_INS;
 1159: 	return label;
 1160: }
 1161: 
 1162: static sljit_ins get_cc(sljit_si type)
 1163: {
 1164: 	switch (type) {
 1165: 	case SLJIT_C_EQUAL:
 1166: 	case SLJIT_C_MUL_NOT_OVERFLOW:
 1167: 		return DA(0x1);
 1168: 
 1169: 	case SLJIT_C_NOT_EQUAL:
 1170: 	case SLJIT_C_MUL_OVERFLOW:
 1171: 		return DA(0x9);
 1172: 
 1173: 	case SLJIT_C_LESS:
 1174: 		return DA(0x5);
 1175: 
 1176: 	case SLJIT_C_GREATER_EQUAL:
 1177: 		return DA(0xd);
 1178: 
 1179: 	case SLJIT_C_GREATER:
 1180: 		return DA(0xc);
 1181: 
 1182: 	case SLJIT_C_LESS_EQUAL:
 1183: 		return DA(0x4);
 1184: 
 1185: 	case SLJIT_C_SIG_LESS:
 1186: 		return DA(0x3);
 1187: 
 1188: 	case SLJIT_C_SIG_GREATER_EQUAL:
 1189: 		return DA(0xb);
 1190: 
 1191: 	case SLJIT_C_SIG_GREATER:
 1192: 		return DA(0xa);
 1193: 
 1194: 	case SLJIT_C_SIG_LESS_EQUAL:
 1195: 		return DA(0x2);
 1196: 
 1197: 	case SLJIT_C_OVERFLOW:
 1198: 		return DA(0x7);
 1199: 
 1200: 	case SLJIT_C_NOT_OVERFLOW:
 1201: 		return DA(0xf);
 1202: 
 1203: 	case SLJIT_C_FLOAT_EQUAL:
 1204: 		return DA(0x9);
 1205: 
 1206: 	case SLJIT_C_FLOAT_NOT_EQUAL: /* Unordered. */
 1207: 		return DA(0x1);
 1208: 
 1209: 	case SLJIT_C_FLOAT_LESS:
 1210: 		return DA(0x4);
 1211: 
 1212: 	case SLJIT_C_FLOAT_GREATER_EQUAL: /* Unordered. */
 1213: 		return DA(0xc);
 1214: 
 1215: 	case SLJIT_C_FLOAT_LESS_EQUAL:
 1216: 		return DA(0xd);
 1217: 
 1218: 	case SLJIT_C_FLOAT_GREATER: /* Unordered. */
 1219: 		return DA(0x5);
 1220: 
 1221: 	case SLJIT_C_FLOAT_UNORDERED:
 1222: 		return DA(0x7);
 1223: 
 1224: 	case SLJIT_C_FLOAT_ORDERED:
 1225: 		return DA(0xf);
 1226: 
 1227: 	default:
 1228: 		SLJIT_ASSERT_STOP();
 1229: 		return DA(0x8);
 1230: 	}
 1231: }
 1232: 
 1233: SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
 1234: {
 1235: 	struct sljit_jump *jump;
 1236: 
 1237: 	CHECK_ERROR_PTR();
 1238: 	check_sljit_emit_jump(compiler, type);
 1239: 
 1240: 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 1241: 	PTR_FAIL_IF(!jump);
 1242: 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
 1243: 	type &= 0xff;
 1244: 
 1245: 	if (type < SLJIT_C_FLOAT_EQUAL) {
 1246: 		jump->flags |= IS_COND;
 1247: 		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
 1248: 			jump->flags |= IS_MOVABLE;
 1249: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1250: 		PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
 1251: #else
 1252: #error "Implementation required"
 1253: #endif
 1254: 	}
 1255: 	else if (type < SLJIT_JUMP) {
 1256: 		jump->flags |= IS_COND;
 1257: 		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))
 1258: 			jump->flags |= IS_MOVABLE;
 1259: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1260: 		PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
 1261: #else
 1262: #error "Implementation required"
 1263: #endif
 1264: 	} else {
 1265: 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 1266: 			jump->flags |= IS_MOVABLE;
 1267: 		if (type >= SLJIT_FAST_CALL)
 1268: 			jump->flags |= IS_CALL;
 1269: 	}
 1270: 
 1271: 	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
 1272: 	PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
 1273: 	jump->addr = compiler->size;
 1274: 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 1275: 
 1276: 	return jump;
 1277: }
 1278: 
 1279: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
 1280: {
 1281: 	struct sljit_jump *jump = NULL;
 1282: 	sljit_si src_r;
 1283: 
 1284: 	CHECK_ERROR();
 1285: 	check_sljit_emit_ijump(compiler, type, src, srcw);
 1286: 	ADJUST_LOCAL_OFFSET(src, srcw);
 1287: 
 1288: 	if (src <= TMP_REG3)
 1289: 		src_r = src;
 1290: 	else if (src & SLJIT_IMM) {
 1291: 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 1292: 		FAIL_IF(!jump);
 1293: 		set_jump(jump, compiler, JUMP_ADDR);
 1294: 		jump->u.target = srcw;
 1295: 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 1296: 			jump->flags |= IS_MOVABLE;
 1297: 		if (type >= SLJIT_FAST_CALL)
 1298: 			jump->flags |= IS_CALL;
 1299: 
 1300: 		FAIL_IF(emit_const(compiler, TMP_REG2, 0));
 1301: 		src_r = TMP_REG2;
 1302: 	}
 1303: 	else {
 1304: 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
 1305: 		src_r = TMP_REG2;
 1306: 	}
 1307: 
 1308: 	FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
 1309: 	if (jump)
 1310: 		jump->addr = compiler->size;
 1311: 	return push_inst(compiler, NOP, UNMOVABLE_INS);
 1312: }
 1313: 
 1314: SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
 1315: 	sljit_si dst, sljit_sw dstw,
 1316: 	sljit_si src, sljit_sw srcw,
 1317: 	sljit_si type)
 1318: {
 1319: 	sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
 1320: 
 1321: 	CHECK_ERROR();
 1322: 	check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
 1323: 	ADJUST_LOCAL_OFFSET(dst, dstw);
 1324: 
 1325: 	if (dst == SLJIT_UNUSED)
 1326: 		return SLJIT_SUCCESS;
 1327: 
 1328: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1329: 	op = GET_OPCODE(op);
 1330: 	reg = (op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2;
 1331: 
 1332: 	compiler->cache_arg = 0;
 1333: 	compiler->cache_argw = 0;
 1334: 	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
 1335: 		ADJUST_LOCAL_OFFSET(src, srcw);
 1336: 		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
 1337: 		src = TMP_REG1;
 1338: 		srcw = 0;
 1339: 	}
 1340: 
 1341: 	if (type < SLJIT_C_FLOAT_EQUAL)
 1342: 		FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
 1343: 	else
 1344: 		FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
 1345: 
 1346: 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
 1347: 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
 1348: 
 1349: 	if (op >= SLJIT_ADD)
 1350: 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
 1351: 
 1352: 	return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
 1353: #else
 1354: #error "Implementation required"
 1355: #endif
 1356: }
 1357: 
 1358: SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
 1359: {
 1360: 	sljit_si reg;
 1361: 	struct sljit_const *const_;
 1362: 
 1363: 	CHECK_ERROR_PTR();
 1364: 	check_sljit_emit_const(compiler, dst, dstw, init_value);
 1365: 	ADJUST_LOCAL_OFFSET(dst, dstw);
 1366: 
 1367: 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
 1368: 	PTR_FAIL_IF(!const_);
 1369: 	set_const(const_, compiler);
 1370: 
 1371: 	reg = (dst <= TMP_REG3) ? dst : TMP_REG2;
 1372: 
 1373: 	PTR_FAIL_IF(emit_const(compiler, reg, init_value));
 1374: 
 1375: 	if (dst & SLJIT_MEM)
 1376: 		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
 1377: 
 1378: 	return const_;
 1379: }

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