C-sparse

 view release on metacpan or  search on metacpan

src/sparse-0.4.4/example.c  view on Meta::CPAN


/*
 * Fake "call" linearization just as a taster..
 */
static void generate_call(SCTX_ struct bb_state *state, struct instruction *insn)
{
	int offset = 0;
	pseudo_t arg;

	FOR_EACH_PTR(insn->arguments, arg) {
		output_insn(sctx_ state, "pushl %s", generic(sctx_ state, arg));
		offset += 4;
	} END_FOR_EACH_PTR(arg);
	flush_reg(sctx_ state, hardregs+0);
	flush_reg(sctx_ state, hardregs+1);
	flush_reg(sctx_ state, hardregs+2);
	output_insn(sctx_ state, "call %s", show_pseudo(sctx_ insn->func));
	if (offset)
		output_insn(sctx_ state, "addl $%d,%%esp", offset);
	if (insn->target && insn->target != VOID)
		add_pseudo_reg(sctx_ state, insn->target, hardregs+0);
}

static void generate_select(SCTX_ struct bb_state *state, struct instruction *insn)
{
	const char *cond;
	struct hardreg *src1, *src2, *dst;

	src1 = getreg(sctx_ state, insn->src2, NULL);
	dst = copy_reg(sctx_ state, src1, insn->target);
	add_pseudo_reg(sctx_ state, insn->target, dst);
	src2 = getreg(sctx_ state, insn->src3, insn->target);

	if (state->cc_target == insn->src1) {
		cond = conditional[state->cc_opcode];
	} else {
		struct hardreg *reg = getreg(sctx_ state, insn->src1, NULL);
		output_insn(sctx_ state, "testl %s,%s", reg->name, reg->name);
		cond = "ne";
	}

	output_insn(sctx_ state, "sel%s %s,%s", cond, src2->name, dst->name);
}

struct asm_arg {
	const struct ident *name;
	const char *value;
	pseudo_t pseudo;
	struct hardreg *reg;
};

static void replace_asm_arg(SCTX_ char **dst_p, struct asm_arg *arg)
{
	char *dst = *dst_p;
	int len = strlen(arg->value);

	memcpy(dst, arg->value, len);
	*dst_p = dst + len;
}

static void replace_asm_percent(SCTX_ const char **src_p, char **dst_p, struct asm_arg *args, int nr)
{
	const char *src = *src_p;
	char c;
	int index;

	c = *src++;
	switch (c) {
	case '0' ... '9':
		index = c - '0';
		if (index < nr)
			replace_asm_arg(sctx_ dst_p, args+index);
		break;
	}	
	*src_p = src;
	return;
}

static void replace_asm_named(SCTX_ const char **src_p, char **dst_p, struct asm_arg *args, int nr)
{
	const char *src = *src_p;
	const char *end = src;

	for(;;) {
		char c = *end++;
		if (!c)
			return;
		if (c == ']') {
			int i;

			*src_p = end;
			for (i = 0; i < nr; i++) {
				const struct ident *ident = args[i].name;
				int len;
				if (!ident)
					continue;
				len = ident->len;
				if (memcmp(src, ident->name, len))
					continue;
				replace_asm_arg(sctx_ dst_p, args+i);
				return;
			}
		}
	}
}

static const char *replace_asm_args(SCTX_ const char *str, struct asm_arg *args, int nr)
{
	static char buffer[1000];
	char *p = buffer;

	for (;;) {
		char c = *str;
		*p = c;
		if (!c)
			return buffer;
		str++;
		switch (c) {
		case '%':
			if (*str == '%') {
				str++;
				p++;
				continue;
			}
			replace_asm_percent(sctx_ &str, &p, args, nr);
			continue;
		case '[':
			replace_asm_named(sctx_ &str, &p, args, nr);
			continue;
		default:
			break;
		}
		p++;
	}
}

#define MAX_ASM_ARG (50)
static struct asm_arg asm_arguments[MAX_ASM_ARG];

static struct asm_arg *generate_asm_inputs(SCTX_ struct bb_state *state, struct asm_constraint_list *list, struct asm_arg *arg)
{
	struct asm_constraint *entry;

	FOR_EACH_PTR(list, entry) {
		const char *constraint = entry->constraint;
		pseudo_t pseudo = entry->pseudo;
		struct hardreg *reg, *orig;
		const char *string;
		int index;

		string = "undef";
		switch (*constraint) {
		case 'r':
			string = getreg(sctx_ state, pseudo, NULL)->name;
			break;
		case '0' ... '9':
			index = *constraint - '0';
			reg = asm_arguments[index].reg;
			orig = find_in_reg(sctx_ state, pseudo);
			if (orig)
				move_reg(sctx_ state, orig, reg);
			else
				fill_reg(sctx_ state, reg, pseudo);
			string = reg->name;
			break;
		default:
			string = generic(sctx_ state, pseudo);
			break;
		}

		output_insn(sctx_ state, "# asm input \"%s\": %s : %s", constraint, show_pseudo(sctx_ pseudo), string);

		arg->name = entry->ident;
		arg->value = string;
		arg->pseudo = NULL;
		arg->reg = NULL;
		arg++;
	} END_FOR_EACH_PTR(entry);
	return arg;
}

static struct asm_arg *generate_asm_outputs(SCTX_ struct bb_state *state, struct asm_constraint_list *list, struct asm_arg *arg)
{
	struct asm_constraint *entry;



( run in 0.963 second using v1.01-cache-2.11-cpan-39bf76dae61 )