Example #1
0
void jit_function::insn_branch_if(const jit_value& value, jit_label& label)
{
	if(!jit_insn_branch_if(func, value.raw(), label.rawp()))
	{
		out_of_memory();
	}
}
void do_lds(jit_function_t func) {
	jit_value_t ldw = LOAD(LDWhich, jit_type_uint);
	jit_label_t label = jit_label_undefined;
	jit_insn_branch_if(func, jit_insn_eq(func, ldw, make_ubyte(35)), &label);
	jit_value_t raw = LOAD(_ReadAbsorbWhich, jit_type_ubyte);
	WGPR_VAL(ldw, LOAD(LDValue, jit_type_uint));
	WRA(ldw, CAST(LOAD(LDAbsorb, jit_type_uint), jit_type_ubyte));
	STORE(_ReadFudge, CAST(ldw, jit_type_ubyte));
	STORE(_ReadAbsorbWhich, CAST(jit_insn_or(func, raw, jit_insn_and(func, ldw, make_uint(0x1F))), jit_type_ubyte));
	jit_insn_label(func, &label);
	STORE(LDWhich, make_uint(35));
}
Example #3
0
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};
}
/*
 * Output an entry for a table-based switch statement.
 */
static void JITCoder_SwitchEntry(ILCoder *_coder, ILUInt32 dest)
{
	ILJITCoder *jitCoder = _ILCoderToILJITCoder(_coder);
	ILJITLabel *label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL);
	
	ILJitValue constant = jit_value_create_nint_constant(jitCoder->jitFunction,
														 jit_type_nint,
														 jitCoder->numSwitch);

	ILJitValue temp = jit_insn_eq(jitCoder->jitFunction, 
								  jitCoder->switchValue,
								  constant);

	jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label));

	++jitCoder->numSwitch;
}
/*
 * Output a branch instruction using a JIT coder.
 */
static void JITCoder_Branch(ILCoder *coder, int opcode, ILUInt32 dest,
				   		    ILEngineType type1, ILEngineType type2)
{
	ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
	ILJITLabel *label = 0;
	ILJitValue temp = 0;
	_ILJitStackItemNew(value2);
	_ILJitStackItemNew(value1);

#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
	if (jitCoder->flags & IL_CODER_FLAG_STATS)
	{
		ILMutexLock(globalTraceMutex);
		fprintf(stdout,
			"Branch: %i\n", 
			dest);
		ILMutexUnlock(globalTraceMutex);
	}
#endif
	/* Determine what form of branch to use */
	switch(opcode)
	{
		case IL_OP_BR:
		case IL_OP_BR_S:
		case IL_OP_LEAVE:
		case IL_OP_LEAVE_S:
		{
			/* Unconditional branch */
			label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL);

			jit_insn_branch(jitCoder->jitFunction, &(label->label));
		}
		break;

		case IL_OP_BRTRUE_S:
		case IL_OP_BRTRUE:
		{
			/* Branch if the top-most stack item is true */
			_ILJitStackPop(jitCoder, value1);
			label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL);

			jit_insn_branch_if(jitCoder->jitFunction,
							   _ILJitStackItemValue(value1),
							   &(label->label));
		}
		break;

		case IL_OP_BRFALSE_S:
		case IL_OP_BRFALSE:
		{
			/* Branch if the top-most stack item is false */
			_ILJitStackPop(jitCoder, value1);
			label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL);

			jit_insn_branch_if_not(jitCoder->jitFunction,
								   _ILJitStackItemValue(value1),
								   &(label->label));
		}
		break;

		default:
		{
			_ILJitStackPop(jitCoder, value2);
			_ILJitStackPop(jitCoder, value1);
			label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL);

			switch(opcode)
			{
				case IL_OP_BEQ:
				case IL_OP_BEQ_S:
				{
					/* Equality testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BEQ,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp, 
									   &(label->label));
				}
				break;

				case IL_OP_BNE_UN:
				case IL_OP_BNE_UN_S:
				{
					/* Unsigned inequality testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BNE_UN,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp, 
									   &(label->label));
				}
				break;

				case IL_OP_BGT:
				case IL_OP_BGT_S:
				{
					/* Signed greater than testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BGT,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BGT_UN:
				case IL_OP_BGT_UN_S:
				{
					/* Unsigned greater than testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BGT_UN,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BGE:
				case IL_OP_BGE_S:
				{
					/* Signed greater than or equal testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BGE,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BGE_UN:
				case IL_OP_BGE_UN_S:
				{
					/* Unsigned greater than or equal testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BGE_UN,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BLT:
				case IL_OP_BLT_S:
				{
					/* Signed less than testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BLT,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BLT_UN:
				case IL_OP_BLT_UN_S:
				{
					/* Unsigned less than testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BLT_UN,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BLE:
				case IL_OP_BLE_S:
				{
					/* Signed less than or equal testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BLE,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;

				case IL_OP_BLE_UN:
				case IL_OP_BLE_UN_S:
				{
					/* Unsigned less than or equal testing branch */
					temp = OutputCompare(jitCoder, IL_OP_BLE_UN,
										 &(_ILJitStackItemValue(value1)),
										 &(_ILJitStackItemValue(value2)));
					jit_insn_branch_if(jitCoder->jitFunction, temp,
									   &(label->label));
				}
				break;
			}
		}
		break;
	}

}
Example #6
0
// 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 */
	
}