Beispiel #1
0
static void x86_uinst_parse_odep(struct x86_uinst_t *uinst, int index, struct x86_ctx_t *ctx)
{
	struct x86_uinst_t *new_uinst;
	enum x86_dep_t mem_regular_dep;
	int mem_dep_size;
	int dep;

	/* Get dependence */
	assert(index >= X86_UINST_MAX_IDEPS && index < X86_UINST_MAX_DEPS);
	dep = uinst->dep[index];
	if (!dep)
		return;

	/* Memory dependence */
	mem_dep_size = x86_uinst_mem_dep_size(uinst, index, ctx, &mem_regular_dep);
	if (mem_dep_size)
	{
		/* If uinst is 'move', just convert it into a 'store' */
		if (uinst->opcode == x86_uinst_move)
		{
			/* Try to add 'ea' as input dependence */
			if (x86_uinst_add_idep(uinst, x86_dep_ea))
			{
				uinst->opcode = x86_uinst_store;
				uinst->dep[index] = x86_dep_none;
				uinst->address = x86_isa_effective_address(ctx);
				uinst->size = mem_dep_size;
				return;
			}
		}

		/* Store */
		new_uinst = x86_uinst_create();
		new_uinst->opcode = x86_uinst_store;
		new_uinst->idep[0] = x86_dep_ea;
		new_uinst->idep[1] = mem_regular_dep;
		new_uinst->address = x86_isa_effective_address(ctx);
		new_uinst->size = mem_dep_size;
		list_add(x86_uinst_list, new_uinst);

		/* Output dependence of instruction is x86_dep_data */
		uinst->dep[index] = mem_regular_dep;
		return;
	}

	/* Regular dependence */
	x86_uinst_parse_dep(uinst, index, ctx);
}
Beispiel #2
0
static void x86_uinst_parse_idep(struct x86_uinst_t *uinst, int index, struct x86_ctx_t *ctx)
{
	struct x86_uinst_t *new_uinst;
	enum x86_dep_t mem_regular_dep;
	int mem_dep_size;
	int dep;

	/* Get dependence */
	assert(index >= 0 && index < X86_UINST_MAX_IDEPS);
	dep = uinst->dep[index];
	if (!dep)
		return;
	
	/* Memory dependence */
	mem_dep_size = x86_uinst_mem_dep_size(uinst, index, ctx, &mem_regular_dep);
	if (mem_dep_size)
	{
		/* If uinst is 'move', just convert it into a 'load' */
		/* Replace 'rmXXX' by 'ea' dependence */
		if (uinst->opcode == x86_uinst_move)
		{
			uinst->opcode = x86_uinst_load;
			uinst->dep[index] = x86_dep_ea;
			uinst->address = x86_isa_effective_address(ctx);
			uinst->size = mem_dep_size;
			return;
		}

		/* Load */
		new_uinst = x86_uinst_create();
		new_uinst->opcode = x86_uinst_load;
		new_uinst->idep[0] = x86_dep_ea;
		new_uinst->odep[0] = mem_regular_dep;
		new_uinst->address = x86_isa_effective_address(ctx);
		new_uinst->size = mem_dep_size;
		list_add(x86_uinst_list, new_uinst);

		/* Input dependence of instruction is converted into 'x86_dep_data' */
		uinst->dep[index] = mem_regular_dep;
		return;
	}

	/* Regular dependence */
	x86_uinst_parse_dep(uinst, index, ctx);
}
Beispiel #3
0
static void x86_uinst_emit_effaddr(struct x86_uinst_t *uinst, int index, struct x86_ctx_t *ctx)
{
	struct x86_uinst_t *new_uinst;

	/* Check if it is a memory dependence */
	if (!x86_uinst_mem_dep_size(uinst, index, ctx, NULL))
		return;

	/* Record occurrence */
	x86_uinst_effaddr_emitted = 1;
	
	/* Emit 'effaddr' */
	new_uinst = x86_uinst_create();
	new_uinst->opcode = x86_uinst_effaddr;
	new_uinst->idep[0] = ctx->inst.segment ? ctx->inst.segment - x86_reg_es + x86_dep_es : x86_dep_none;
	new_uinst->idep[1] = ctx->inst.ea_base ? ctx->inst.ea_base - x86_reg_eax + x86_dep_eax : x86_dep_none;
	new_uinst->idep[2] = ctx->inst.ea_index ? ctx->inst.ea_index - x86_reg_eax + x86_dep_eax : x86_dep_none;
	new_uinst->odep[0] = x86_dep_ea;
	list_add(x86_uinst_list, new_uinst);
}
Beispiel #4
0
void __x86_uinst_new_mem(struct x86_ctx_t *ctx,
	enum x86_uinst_opcode_t opcode, uint32_t address, int size,
	enum x86_dep_t idep0, enum x86_dep_t idep1, enum x86_dep_t idep2,
	enum x86_dep_t odep0, enum x86_dep_t odep1, enum x86_dep_t odep2,
	enum x86_dep_t odep3)
{
	struct x86_uinst_t *uinst;
	int i;

	/* Do nothing for functional simulation */
	if (x86_emu_kind == x86_emu_kind_functional)
		return;
	
	/* Create uinst */
	uinst = x86_uinst_create();
	uinst->opcode = opcode;
	uinst->idep[0] = idep0;
	uinst->idep[1] = idep1;
	uinst->idep[2] = idep2;
	uinst->odep[0] = odep0;
	uinst->odep[1] = odep1;
	uinst->odep[2] = odep2;
	uinst->odep[3] = odep3;
	uinst->address = address;
	uinst->size = size;

	/* Emit effective address computation if needed. */
	for (i = 0; !x86_uinst_effaddr_emitted && i < X86_UINST_MAX_DEPS; i++)
		x86_uinst_emit_effaddr(uinst, i, ctx);
	
	/* Parse input dependences */
	for (i = 0; i < X86_UINST_MAX_IDEPS; i++)
		x86_uinst_parse_idep(uinst, i, ctx);
	
	/* Add micro-instruction */
	list_add(x86_uinst_list, uinst);
	
	/* Parse output dependences */
	for (i = 0; i < X86_UINST_MAX_ODEPS; i++)
		x86_uinst_parse_odep(uinst, i + X86_UINST_MAX_IDEPS, ctx);
}
Beispiel #5
0
void __x86_uinst_new_mem(X86Context *ctx,
	enum x86_uinst_opcode_t opcode, unsigned int address, int size,
	enum x86_dep_t idep0, enum x86_dep_t idep1, enum x86_dep_t idep2,
	enum x86_dep_t odep0, enum x86_dep_t odep1, enum x86_dep_t odep2,
	enum x86_dep_t odep3)
{
	struct x86_uinst_t *uinst;
	int i;

	/* Create micro-instruction */
	assert(arch_x86->sim_kind == arch_sim_kind_detailed);
	uinst = x86_uinst_create();
	uinst->opcode = opcode;
	uinst->idep[0] = idep0;
	uinst->idep[1] = idep1;
	uinst->idep[2] = idep2;
	uinst->odep[0] = odep0;
	uinst->odep[1] = odep1;
	uinst->odep[2] = odep2;
	uinst->odep[3] = odep3;
	uinst->address = address;
	uinst->size = size;

	/* Emit effective address computation if needed. */
	for (i = 0; !x86_uinst_effaddr_emitted && i < X86_UINST_MAX_DEPS; i++)
		x86_uinst_emit_effaddr(uinst, i, ctx);
	
	/* Parse input dependences */
	for (i = 0; i < X86_UINST_MAX_IDEPS; i++)
		x86_uinst_parse_idep(uinst, i, ctx);
	
	/* Add micro-instruction */
	list_add(x86_uinst_list, uinst);
	
	/* Parse output dependences */
	for (i = 0; i < X86_UINST_MAX_ODEPS; i++)
		x86_uinst_parse_odep(uinst, i + X86_UINST_MAX_IDEPS, ctx);
}