/* * Create the slots for the declared local variables. * Returns zero if out of memory. */ static int _ILJitLocalSlotsCreateLocals(ILJITCoder *jitCoder, ILJitLocalSlots *localSlots, ILStandAloneSig *localVarSig) { if(localVarSig) { ILType *signature; ILType *type; ILJitType jitType; ILUInt32 num; ILUInt32 current; /* Determine the number of locals to allocate */ if(!(signature = ILStandAloneSigGetType(localVarSig))) { return 0; } num = ILTypeNumLocals(signature); /* Allocate the "jitLocals" array for the variables */ _ILJitLocalsAlloc(*localSlots, num); /* Create the jit values for the local variables */ for(current = 0; current < num; ++current) { ILJitLocalSlot *local = &_ILJitLocalSlotFromSlots(*localSlots, current); if(!(type = ILTypeGetLocal(signature, current))) { return 0; } if(!(jitType = _ILJitGetLocalsType(type, jitCoder->process))) { return 0; } if(!(local->value = jit_value_create(jitCoder->jitFunction, jitType))) { return 0; } local->flags = 0; local->refValue = 0; } /* Record the number of used locals in the local slots. */ localSlots->numSlots = num; } else { /* Set the number of used locals to 0. */ localSlots->numSlots = 0; } return 1; }
Compiler::value Match::compile(Compiler& c) const { auto v = value->compile(c); jit_value_t res = jit_value_create(c.F, VM::get_jit_type(type)); jit_label_t label_end = jit_label_undefined; for (size_t i = 0; i < pattern_list.size(); ++i) { bool is_default = false; for (const Pattern& pattern : pattern_list[i]) { is_default = is_default || pattern.is_default(); } if (is_default) { auto ret = returns[i]->compile(c); jit_insn_store(c.F, res, ret.v); jit_insn_label(c.F, &label_end); c.insn_delete_temporary(v); return {res, type}; } jit_label_t label_next = jit_label_undefined; if (pattern_list[i].size() == 1) { jit_value_t cond = pattern_list[i][0].match(c, v.v); jit_insn_branch_if_not(c.F, cond, &label_next); } else { jit_label_t label_match = jit_label_undefined; for (const Pattern& pattern : pattern_list[i]) { jit_value_t cond = pattern.match(c, v.v); jit_insn_branch_if(c.F, cond, &label_match); } jit_insn_branch(c.F, &label_next); jit_insn_label(c.F, &label_match); } auto ret = returns[i]->compile(c); jit_insn_store(c.F, res, ret.v); jit_insn_branch(c.F, &label_end); jit_insn_label(c.F, &label_next); } // In the case of no default pattern jit_insn_store(c.F, res, c.new_null().v); jit_insn_label(c.F, &label_end); c.insn_delete_temporary(v); return {res, type}; }
/*@ * @deftypefun jit_value_t jit_value_get_param (jit_function_t @var{func}, unsigned int @var{param}) * Get the value that corresponds to a specified function parameter. * Returns NULL if out of memory or @var{param} is invalid. * @end deftypefun @*/ jit_value_t jit_value_get_param(jit_function_t func, unsigned int param) { unsigned int num_params, current; /* Ensure that we have a builder for this function */ if(!_jit_function_ensure_builder(func)) { return 0; } /* Ensure valid param number. */ jit_type_t signature = func->signature; num_params = jit_type_num_params(signature); if(param >= num_params) { return 0; } /* If we have already created the values, then exit immediately */ jit_value_t *values = func->builder->param_values; if(values) { return values[param]; } /* Create the values for the first time */ values = (jit_value_t *) jit_calloc(num_params, sizeof(jit_value_t)); if(!values) { return 0; } func->builder->param_values = values; for(current = 0; current < num_params; ++current) { jit_type_t type = jit_type_get_param(signature, current); values[current] = jit_value_create(func, type); if(values[current]) { /* The value belongs to the entry block, no matter where it happens to be created */ values[current]->block = func->builder->entry_block; values[current]->is_parameter = 1; } } /* Return the value block for the desired parameter */ return values[param]; }
Compiler::value If::compile(Compiler& c) const { jit_value_t res = nullptr; if (type != Type::VOID) { res = jit_value_create(c.F, VM::get_jit_type(type)); } jit_label_t label_else = jit_label_undefined; jit_label_t label_end = jit_label_undefined; auto cond = condition->compile(c); condition->compile_end(c); if (condition->type.nature == Nature::POINTER) { auto cond_bool = c.insn_to_bool(cond); c.insn_delete_temporary(cond); jit_insn_branch_if_not(c.F, cond_bool.v, &label_else); } else { jit_insn_branch_if_not(c.F, cond.v, &label_else); } auto then_v = then->compile(c); then->compile_end(c); if (then_v.v) { jit_insn_store(c.F, res, then_v.v); } jit_insn_branch(c.F, &label_end); jit_insn_label(c.F, &label_else); if (elze != nullptr) { auto else_v = elze->compile(c); elze->compile_end(c); if (else_v.v) { jit_insn_store(c.F, res, else_v.v); } } else { if (type != Type::VOID) { jit_insn_store(c.F, res, c.new_null().v); } } jit_insn_label(c.F, &label_end); return {res, type}; }
/* * Create a new jit_value_t with the type of the existing jit_value_t in the * local slot and replace the existing one with the new one. * Clear the protect flag afterwards. */ static int _ILJitLocalSlotNewValue(ILJITCoder *jitCoder, ILJitLocalSlot *localSlot) { ILJitType type; ILJitValue value; if(!(type = jit_value_get_type(localSlot->value))) { return 0; } if(!(value = jit_value_create(jitCoder->jitFunction, type))) { return 0; } localSlot->value = value; localSlot->refValue = 0; localSlot->flags &= ~_IL_JIT_VALUE_PROTECT; return 1; }
/*@ * @deftypefun jit_value_t jit_value_get_struct_pointer (jit_function_t @var{func}) * Get the value that contains the structure return pointer for * a function. If the function does not have a structure return pointer * (i.e. structures are returned in registers), then this returns NULL. * @end deftypefun @*/ jit_value_t jit_value_get_struct_pointer(jit_function_t func) { jit_type_t type; jit_value_t value; /* Ensure that we have a builder for this function */ if(!_jit_function_ensure_builder(func)) { return 0; } type = jit_type_remove_tags(jit_type_get_return(func->signature)); if(jit_type_is_struct(type) || jit_type_is_union(type)) { if(jit_type_return_via_pointer(type)) { if(!func->builder->struct_return) { type = jit_type_create_pointer(type, 1); if(!type) { return 0; } value = jit_value_create(func, type); func->builder->struct_return = value; if(value) { /* The value belongs to the entry block, no matter where it happens to be created */ value->block = func->builder->entry_block; value->is_parameter = 1; } jit_type_free(type); } return func->builder->struct_return; } } return 0; }
/* * Save the current jitStack status to the label. * This is done when the label is referenced the first time. */ static int _ILJitLabelSaveStack(ILJITCoder *coder, ILJITLabel *label) { int coderStackHeight = _ILJitStackHeight(coder); #ifdef _IL_JIT_ENABLE_INLINE int coderStackBase; if(coder->currentInlineContext) { coderStackBase = coder->currentInlineContext->stackBase; coderStackHeight -= coderStackBase; } else { coderStackBase = 0; } #else /* !_IL_JIT_ENABLE_INLINE */ int coderStackBase = 0; #endif /* !_IL_JIT_ENABLE_INLINE */ if(((label->labelType & (_IL_JIT_LABEL_NORMAL | _IL_JIT_LABEL_STARTCATCH)) != 0) && (coderStackHeight > 0)) { int current = 0; ILJitValue *stack = ILMemStackAllocItem(&(coder->stackStates), coderStackHeight * sizeof(ILJitValue)); if(!stack) { return 0; } /* Now save the current stack state. */ for(current = 0; current < coderStackHeight; current++) { ILJitStackItem *stackItem = _ILJitStackItemGet(coder, coderStackBase + current); stack[current] = _ILJitStackItemValue(*stackItem); if(jit_value_is_constant(_ILJitStackItemValue(*stackItem))) { /* We have to handle this case different. */ /* Create a local value of the type of the constant. */ ILJitValue temp = jit_value_create(coder->jitFunction, jit_value_get_type(_ILJitStackItemValue(*stackItem))); /* and store the value of the constant in the new temporary. */ jit_insn_store(coder->jitFunction, temp, _ILJitStackItemValue(*stackItem)); /* Now replace the constant with the new temporary. */ stack[current] = temp; _ILJitStackItemSetValue(*stackItem, temp); } else if(_ILJitStackItemNeedsDupOnLabel(*stackItem)) { ILJitValue temp = jit_insn_dup(coder->jitFunction, _ILJitStackItemValue(*stackItem)); stack[current] = temp; _ILJitStackItemSetValue(*stackItem, temp); } } label->jitStack = stack; label->stackSize = coderStackHeight; } return 1; }
/*@ * @deftypefun int _jit_create_call_setup_insns (jit_function_t @var{func}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{is_nested}, int @var{nested_level}, jit_value_t *@var{struct_return}, int @var{flags}) * Create instructions within @var{func} necessary to set up for a * function call to a function with the specified @var{signature}. * Use @code{jit_insn_push} to push values onto the system stack, * or @code{jit_insn_outgoing_reg} to copy values into call registers. * * If @var{is_nested} is non-zero, then it indicates that we are calling a * nested function within the current function's nested relationship tree. * The @var{nested_level} value will be -1 to call a child, zero to call a * sibling of @var{func}, 1 to call a sibling of the parent, 2 to call * a sibling of the grandparent, etc. The @code{jit_insn_setup_for_nested} * instruction should be used to create the nested function setup code. * * If the function returns a structure by pointer, then @var{struct_return} * must be set to a new local variable that will contain the returned * structure. Otherwise it should be set to NULL. * @end deftypefun @*/ int _jit_create_call_setup_insns (jit_function_t func, jit_type_t signature, jit_value_t *args, unsigned int num_args, int is_nested, int nested_level, jit_value_t *struct_return, int flags) { jit_type_t type; jit_type_t vtype; jit_value_t value; unsigned int arg_num; jit_nint offset; jit_nuint size; /* Regular or tail call? */ if((flags & JIT_CALL_TAIL) == 0) { /* Push all of the arguments in reverse order */ while(num_args > 0) { --num_args; type = jit_type_get_param(signature, num_args); type = jit_type_remove_tags(type); if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION) { /* If the value is a pointer, then we are pushing a structure argument by pointer rather than by local variable */ vtype = jit_type_normalize(jit_value_get_type(args[num_args])); if(vtype->kind <= JIT_TYPE_MAX_PRIMITIVE) { if(!jit_insn_push_ptr(func, args[num_args], type)) { return 0; } continue; } } if(!jit_insn_push(func, args[num_args])) { return 0; } } /* Do we need to add a structure return pointer argument? */ type = jit_type_get_return(signature); if(jit_type_return_via_pointer(type)) { value = jit_value_create(func, type); if(!value) { return 0; } *struct_return = value; value = jit_insn_address_of(func, value); if(!value) { return 0; } if(!jit_insn_push(func, value)) { return 0; } } else if((flags & JIT_CALL_NATIVE) != 0) { /* Native calls always return a return area pointer */ if(!jit_insn_push_return_area_ptr(func)) { return 0; } *struct_return = 0; } else { *struct_return = 0; } /* Do we need to add nested function scope information? */ if(is_nested) { if(!jit_insn_setup_for_nested(func, nested_level, -1)) { return 0; } } } else { /* Copy the arguments into our own parameter slots */ offset = -1; if(func->nested_parent) { offset -= 2; } type = jit_type_get_return(signature); if(jit_type_return_via_pointer(type)) { --offset; } for(arg_num = 0; arg_num < num_args; ++arg_num) { type = jit_type_get_param(signature, arg_num); value = jit_value_create(func, type); if(!value) { return 0; } if(!jit_insn_outgoing_frame_posn(func, value, offset)) { return 0; } type = jit_type_remove_tags(type); size = jit_type_get_size(type); offset -= (jit_nint)(JIT_NUM_ITEMS_IN_STRUCT(size)); if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION) { /* If the value is a pointer, then we are pushing a structure argument by pointer rather than by local variable */ vtype = jit_type_normalize(jit_value_get_type(args[arg_num])); if(vtype->kind <= JIT_TYPE_MAX_PRIMITIVE) { value = jit_insn_address_of(func, value); if(!value) { return 0; } if(!jit_insn_memcpy (func, value, args[arg_num], jit_value_create_nint_constant (func, jit_type_nint, (jit_nint)size))) { return 0; } continue; } } if(!jit_insn_store(func, value, args[arg_num])) { return 0; } } *struct_return = 0; } /* The call is ready to proceed */ return 1; }
static jit_value_t parse_recursive(jit_function_t func) { jit_value_t arg1, arg2, result; jit_function_t func1; double val; char *t = token(); // Somebody, do something with this! // It's awful monkeycoding, but I'm too lazy to rewrite it :3 if (STREQ(t, "F")) result = val_freq; else if (STREQ(t, "X")) result = jit_insn_convert(func, val_sample, jit_type_float64, 0); else if (STREQ(t, "LEN")) result = jit_insn_convert(func, val_length, jit_type_float64, 0); else if (STREQ(t, "RATE")) result = const_rate; else if (STREQ(t, "PI")) result = const_pi; else if (STREQ(t, "+")) result = jit_insn_add(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "-")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_sub(func, arg1, arg2); } else if (STREQ(t, "*")) result = jit_insn_mul(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "/")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_div(func, arg1, arg2); } else if (STREQ(t, "%")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_rem(func, arg1, arg2); } else if (STREQ(t, ">")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_gt(func, arg1, arg2); } else if (STREQ(t, "<")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_lt(func, arg1, arg2); } else if (STREQ(t, "if")) { jit_value_t tmpval = jit_value_create(func, jit_type_float64); jit_label_t lb_false = jit_label_undefined, lb_end = jit_label_undefined; jit_insn_branch_if_not(func, jit_insn_to_bool(func, parse_recursive(func)), &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_branch(func, &lb_end); jit_insn_label(func, &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_label(func, &lb_end); result = jit_insn_load(func, tmpval); } else if (STREQ(t, "sin")) result = jit_insn_sin(func, parse_recursive(func)); else if (sscanf(t, "%lf", &val) == 1) result = jit_value_create_float64_constant(func, jit_type_float64, val); else if ((func1 = get_function_by_name(t)) != NULL) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); jit_value_t args[3] = {arg1, arg2, val_length}; result = jit_insn_call( func, t, func1, NULL, args, 3, 0); } else { LOGF("Unexpected token '%s'", t); result = NULL; } free(t); return result; }
/*@ * @deftypemethod jit_function jit_value new_value (jit_type_t @var{type}) * Create a new temporary value. This is the C++ counterpart to * @code{jit_value_create}. * @end deftypemethod @*/ jit_value jit_function::new_value(jit_type_t type) { value_wrap(jit_value_create(func, type)); }
void *LibJITFormula::emit (CallExprAST *expr) { if (expr->function == "if") { // We're going to make a new temporary, and store a value to it depending // on what happens here. jit_value_t result = jit_value_create (function, jit_type_float64); // if (cond) jit_value_t cond = (jit_value_t)expr->args[0]->generate (this); if (!cond) return NULL; jit_value_t one = jit_value_create_float64_constant (function, jit_type_float64, 1.0); jit_value_t comparison = jit_insn_eq (function, cond, one); jit_label_t label_if = jit_label_undefined; jit_label_t label_end = jit_label_undefined; jit_insn_branch_if_not (function, comparison, &label_if); // (the if-value) jit_value_t t = (jit_value_t)expr->args[1]->generate (this); jit_insn_store (function, result, t); jit_insn_branch (function, &label_end); // The else branches to here... jit_insn_label (function, &label_if); // (the else-value) jit_value_t f = (jit_value_t)expr->args[2]->generate (this); jit_insn_store (function, result, f); jit_insn_label (function, &label_end); return result; } else if (expr->function == "sign") { // Same thing as the if-function above jit_value_t one = jit_value_create_float64_constant (function, jit_type_float64, 1.0); jit_value_t zero = jit_value_create_float64_constant (function, jit_type_float64, 0.0); jit_value_t minusone = jit_value_create_float64_constant (function, jit_type_float64, -1.0); jit_value_t arg = (jit_value_t)expr->args[0]->generate (this); jit_value_t result = jit_value_create (function, jit_type_float64); jit_label_t label_end = jit_label_undefined; jit_value_t positive = jit_insn_gt (function, arg, zero); jit_label_t label_positive = jit_label_undefined; jit_insn_branch_if_not (function, positive, &label_positive); jit_insn_store (function, result, one); jit_insn_branch (function, &label_end); jit_insn_label (function, &label_positive); jit_value_t negative = jit_insn_lt (function, arg, zero); jit_label_t label_negative = jit_label_undefined; jit_insn_branch_if_not (function, negative, &label_negative); jit_insn_store (function, result, minusone); jit_insn_branch (function, &label_end); jit_insn_label (function, &label_negative); jit_insn_store (function, result, zero); jit_insn_label (function, &label_end); return result; } else if (expr->function == "atan2") { // HACK: We have to put this here since it has two arguments jit_value_t args[2]; args[0] = (jit_value_t)expr->args[0]->generate (this); args[1] = (jit_value_t)expr->args[1]->generate (this); jit_type_t params[2]; params[0] = jit_type_float64; params[1] = jit_type_float64; jit_type_t signature; signature = jit_type_create_signature (jit_abi_cdecl, jit_type_float64, params, 2, 1); return jit_insn_call_native (function, "atan2", (void *)((double (*)(double, double))atan2), signature, args, 2, 0); } // Compile the arguments // HACK: we just assume for now that if() is the only thing with // more than one argument. jit_value_t arg = (jit_value_t)expr->args[0]->generate (this); // Create a native signature for our few native functions jit_type_t params[1]; params[0] = jit_type_float64; jit_type_t signature; signature = jit_type_create_signature (jit_abi_cdecl, jit_type_float64, params, 1, 1); // Several of the jit_insn_FUNC constructs below have been replaced // by jit_insn_call_native, because the intrinsic instructions seem to // give the wrong answers. if (expr->function == "sin") return jit_insn_call_native (function, "sin", (void *)((double (*)(double))sin), signature, &arg, 1, 0); else if (expr->function == "cos") return jit_insn_call_native (function, "cos", (void *)((double (*)(double))cos), signature, &arg, 1, 0); else if (expr->function == "tan") return jit_insn_call_native (function, "tan", (void *)((double (*)(double))tan), signature, &arg, 1, 0); else if (expr->function == "asin") return jit_insn_call_native (function, "asin", (void *)((double (*)(double))asin), signature, &arg, 1, 0); else if (expr->function == "acos") return jit_insn_call_native (function, "acos", (void *)((double (*)(double))acos), signature, &arg, 1, 0); else if (expr->function == "atan") return jit_insn_call_native (function, "atan", (void *)((double (*)(double))atan), signature, &arg, 1, 0); else if (expr->function == "sinh") return jit_insn_call_native (function, "sinh", (void *)((double (*)(double))sinh), signature, &arg, 1, 0); else if (expr->function == "cosh") return jit_insn_call_native (function, "cosh", (void *)((double (*)(double))cosh), signature, &arg, 1, 0); else if (expr->function == "tanh") return jit_insn_call_native (function, "tanh", (void *)((double (*)(double))tanh), signature, &arg, 1, 0); else if (expr->function == "asinh") return jit_insn_call_native (function, "asinh", (void *)((double (*)(double))asinh), signature, &arg, 1, 0); else if (expr->function == "acosh") return jit_insn_call_native (function, "acosh", (void *)((double (*)(double))acosh), signature, &arg, 1, 0); else if (expr->function == "atanh") return jit_insn_call_native (function, "atanh", (void *)((double (*)(double))atanh), signature, &arg, 1, 0); else if (expr->function == "log2") return jit_insn_call_native (function, "log2", (void *)((double (*)(double))log2), signature, &arg, 1, 0); else if (expr->function == "log" || expr->function == "log10") return jit_insn_call_native (function, "log10", (void *)((double (*)(double))log10), signature, &arg, 1, 0); else if (expr->function == "ln") return jit_insn_call_native (function, "log", (void *)((double (*)(double))log), signature, &arg, 1, 0); else if (expr->function == "exp") return jit_insn_call_native (function, "exp", (void *)((double (*)(double))exp), signature, &arg, 1, 0); else if (expr->function == "sqrt") return jit_insn_sqrt (function, arg); else if (expr->function == "abs") return jit_insn_abs (function, arg); else if (expr->function == "rint") return jit_insn_call_native (function, "rint", (void *)((double (*)(double))rint), signature, &arg, 1, 0); else return NULL; }
// LIBJIT void vm_cpu_4(uint32_t newPC,int opt, int size) { int i; PC = newPC; nPC = 4; RF[0] = 0; //Register $zero must always be zero RF[31] = 1; //Return default (if the program does not set to zero, should put error) uint32_t HI = 0, LO = 0; uint32_t offset = 4; uint8_t halted = 0; uint32_t instr; uint8_t op; uint8_t rs; uint8_t rt; uint8_t rd; int16_t immediate; uint32_t address; uint8_t shamt; uint8_t funct; uint64_t mult; /*lib jit variables */ jit_context_t context; jit_type_t signature; jit_function_t function; jit_type_t params[VM_MEMORY_SZ+2]; jit_int result; jit_value_t constant_sum; jit_value_t constant_while; jit_value_t v_it; jit_value_t constant_update; jit_value_t compare; jit_value_t reg[32]; /* Reg */ jit_value_t mem[VM_MEMORY_SZ]; /* Memory */ jit_label_t labels[10]; /* Labs for jumping :D */ jit_value_t sum, t_sum; void *args[VM_MEMORY_SZ+2]; /* Args */ jit_int arg_uint[VM_MEMORY_SZ+2]; /* Create a context to hold the JIT's primary state */ context = jit_context_create(); /* Lock the context while we build and compile the function */ jit_context_build_start(context); for(i=0; i<(VM_MEMORY_SZ+2); i++) { params[i] = jit_type_int; } signature = jit_type_create_signature(jit_abi_cdecl, jit_type_int, params, VM_MEMORY_SZ+2, 1); /* Create the function object */ function = jit_function_create(context, signature); jit_type_free(signature); // Read memory and start registers for(i=0; i<VM_MEMORY_SZ; i++) { //printf("%d\n",i); mem[i] = jit_value_get_param(function, i); } reg[0] = jit_value_get_param(function, VM_MEMORY_SZ); reg[31] = jit_value_get_param(function, VM_MEMORY_SZ+1); /*int verify = 0 - 1; for (i=1; i<VM_MEMORY_SZ; i++) { if((i%2)==0) { verify = verify + (i); } else { verify = verify - i; } } printf("verify %d\n", verify); */ int l_index; // Only doing the micro benchmark, for analysis // Addiu #define loopSize 10000 #define smallerLoopSize 1000 #define opPerLoop 100 // v_it = 0 ; constant_while = loopSize ; constant_update = 1 v_it = jit_value_create(function, jit_type_uint); constant_update = jit_value_create_nint_constant(function, jit_type_int, (int)0); jit_insn_store(function, v_it, constant_update); reg[2] = jit_value_create(function, jit_type_uint); constant_while = jit_value_create_nint_constant(function, jit_type_int, 0); jit_insn_store(function, reg[2], constant_while); reg[3] = jit_value_create(function, jit_type_uint); constant_while = jit_value_create_nint_constant(function, jit_type_int, 1); jit_insn_store(function, reg[3], constant_while); // do while (v_it < constant_while) { jit_insn_label(function, &labels[0]); if (opt == 0) { constant_update = jit_insn_add(function, reg[2], reg[3]); } else if(opt == 1) { constant_update = jit_insn_xor(function, reg[2], reg[3]); } else if(opt == 2) { constant_update = jit_insn_load(function, mem[0]); } for (l_index = 1; l_index < opPerLoop; l_index++) { if (opt == 0) { constant_update = jit_insn_add(function, constant_update, reg[3]); } else if(opt == 1) { constant_update = jit_insn_xor(function, constant_update, reg[3]); } else if(opt == 2) { constant_update = jit_insn_load(function, mem[l_index % 5]); } } jit_insn_store(function, reg[2], constant_update); // do while constant_update = jit_value_create_nint_constant(function, jit_type_uint, 1); constant_sum = jit_insn_add(function, v_it, constant_update); jit_insn_store(function, v_it, constant_sum); if(size > 0) { constant_while = jit_value_create_nint_constant(function, jit_type_uint, loopSize); } else { constant_while = jit_value_create_nint_constant(function, jit_type_uint, smallerLoopSize); } compare = jit_insn_gt(function, constant_while, v_it); jit_insn_branch_if(function, compare, &labels[0]); // Return //jit_insn_return(function, reg[2]); jit_insn_return(function, reg[2]); // START OF FINAL PART /* Compile the function */ jit_function_compile(function); /* Unlock the context */ jit_context_build_end(context); // Put memory and first registers for (i=0; i<VM_MEMORY_SZ; i++) { arg_uint[i] = (int) VM_memory[i]; //arg_uint[i] = (int)i; args[i] = &(arg_uint[i]); } arg_uint[VM_MEMORY_SZ] = 0; args[VM_MEMORY_SZ] = &(arg_uint[VM_MEMORY_SZ]); arg_uint[VM_MEMORY_SZ+1] = 1; args[VM_MEMORY_SZ+1] = &(arg_uint[VM_MEMORY_SZ+1]); jit_function_apply(function, args, &result); //printf("%d\n", result); return; /* end lib jit variables */ }