static int add3(long a, long b, long c) { void *code; unsigned long len; func3_t func; /* Create a SLJIT compiler */ struct sljit_compiler *C = sljit_create_compiler(); /* Start a context(function entry), have 3 arguments, discuss later */ sljit_emit_enter(C, 0, 3, 1, 3, 0, 0, 0); /* The first arguments of function is register SLJIT_S0, 2nd, SLJIT_S1, etc. */ /* R0 = first */ sljit_emit_op1(C, SLJIT_MOV, SLJIT_R0, 0, SLJIT_S0, 0); /* R0 = R0 + second */ sljit_emit_op2(C, SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_S1, 0); /* R0 = R0 + third */ sljit_emit_op2(C, SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_S2, 0); /* This statement mov R0 to RETURN REG and return */ /* in fact, R0 is RETURN REG itself */ sljit_emit_return(C, SLJIT_MOV, SLJIT_R0, 0); /* Generate machine code */ code = sljit_generate_code(C); len = sljit_get_generated_code_size(C); /* Execute code */ func = (func3_t)code; printf("func return %ld\n", func(a, b, c)); /* dump_code(code, len); */ /* Clean up */ sljit_free_compiler(C); sljit_free_code(code); return 0; }
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* Default compare for most architectures. */ int flags, tmp_src, condition; sljit_w tmp_srcw; CHECK_ERROR_PTR(); check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); condition = type & 0xff; if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { /* Immediate is prefered as second argument by most architectures. */ switch (condition) { case SLJIT_C_LESS: condition = SLJIT_C_GREATER; break; case SLJIT_C_GREATER_EQUAL: condition = SLJIT_C_LESS_EQUAL; break; case SLJIT_C_GREATER: condition = SLJIT_C_LESS; break; case SLJIT_C_LESS_EQUAL: condition = SLJIT_C_GREATER_EQUAL; break; case SLJIT_C_SIG_LESS: condition = SLJIT_C_SIG_GREATER; break; case SLJIT_C_SIG_GREATER_EQUAL: condition = SLJIT_C_SIG_LESS_EQUAL; break; case SLJIT_C_SIG_GREATER: condition = SLJIT_C_SIG_LESS; break; case SLJIT_C_SIG_LESS_EQUAL: condition = SLJIT_C_SIG_GREATER_EQUAL; break; } type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); tmp_src = src1; src1 = src2; src2 = tmp_src; tmp_srcw = src1w; src1w = src2w; src2w = tmp_srcw; } if (condition <= SLJIT_C_NOT_ZERO) flags = SLJIT_SET_E; else if (condition <= SLJIT_C_LESS_EQUAL) flags = SLJIT_SET_U; else flags = SLJIT_SET_S; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); }