Exemplo n.º 1
0
void gen_expr_if(expr *e, symtable *stab)
{
	char *lblfin, *lblelse;

	lblfin = asm_label_code("ifexpa");

	gen_expr(e->expr, stab);

	if(e->lhs){
		lblelse = asm_label_code("ifexpb");

		asm_temp(1, "pop rax");
		asm_temp(1, "test rax, rax");
		asm_temp(1, "jz %s", lblelse);
		gen_expr(e->lhs, stab);
		asm_temp(1, "jmp %s", lblfin);
		asm_label(lblelse);
	}else{
		asm_temp(1, "mov rax, [rsp] ; save for ?:");
		asm_temp(1, "test rax, rax");
		asm_temp(1, "jnz %s", lblfin);
		asm_temp(1, "pop rax ; discard lhs");
	}

	gen_expr(e->rhs, stab);
	asm_label(lblfin);

	if(e->lhs)
		free(lblelse);

	free(lblfin);
}
Exemplo n.º 2
0
void gen_expr_sizeof(expr *e, symtable *stab)
{
	decl *d = e->expr->tree_type;
	(void)stab;

	asm_temp(1, "push %d ; sizeof %s%s", decl_size(d), e->expr->expr_is_sizeof ? "type " : "", decl_to_str(d));
}
Exemplo n.º 3
0
void gen_stmt_do(stmt *s)
{
	char *begin = asm_label_flow("do_start");

	asm_label(begin);
	gen_stmt(s->lhs);

	asm_label(s->lbl_continue);
	gen_expr(s->expr, s->symtab);

	asm_temp(1, "pop rax");
	asm_temp(1, "test rax, rax");
	asm_temp(1, "jnz %s", begin);

	asm_label(s->lbl_break);

	free(begin);
}
Exemplo n.º 4
0
void gen_expr_funcall(expr *e, symtable *stab)
{
	const char *const fname = e->expr->spel;
	expr **iter;
	int nargs = 0;

	if(fopt_mode & FOPT_ENABLE_ASM && fname && !strcmp(fname, ASM_INLINE_FNAME)){
		const char *str;
		expr *arg1;
		int i;

		if(!e->funcargs || e->funcargs[1] || !expr_kind(e->funcargs[0], addr))
			die_at(&e->where, "invalid __asm__ arguments");

		arg1 = e->funcargs[0];
		str = arg1->array_store->data.str;
		for(i = 0; i < arg1->array_store->len - 1; i++){
			char ch = str[i];
			if(!isprint(ch) && !isspace(ch))
invalid:
				die_at(&arg1->where, "invalid __asm__ string (character %d)", ch);
		}

		if(str[i])
			goto invalid;

		asm_temp(0, "; start manual __asm__");
		fprintf(cc_out[SECTION_TEXT], "%s\n", arg1->array_store->data.str);
		asm_temp(0, "; end manual __asm__");
	}else{
		/* continue with normal funcall */

		if(e->funcargs){
			/* need to push on in reverse order */
			for(iter = e->funcargs; *iter; iter++);
			for(iter--; iter >= e->funcargs; iter--){
				gen_expr(*iter, stab);
				nargs++;
			}
		}

		if(e->sym && !e->sym->decl->decl_ptr && e->sym->decl->spel){
			/* simple */
			asm_temp(1, "call %s", e->sym->decl->spel);
		}else{
			gen_expr(e->expr, stab);
			asm_temp(1, "pop rax  ; function address");
			asm_temp(1, "call rax ; duh");
		}

		if(nargs)
			asm_temp(1, "add rsp, %d ; %d arg%s",
					nargs * platform_word_size(),
					nargs,
					nargs == 1 ? "" : "s");

		asm_temp(1, "push rax ; ret");
	}
}
Exemplo n.º 5
0
void gen_expr_val(expr *e, symtable *stab)
{
	(void)stab;

	fputs("\tmov rax, ", cc_out[SECTION_TEXT]);
	e->f_gen_1(e, cc_out[SECTION_TEXT]);
	fputc('\n', cc_out[SECTION_TEXT]);

	asm_temp(1, "push rax");
}
Exemplo n.º 6
0
void gen_stmt_if(stmt *s)
{
	char *lbl_else = asm_label_code("else");
	char *lbl_fi   = asm_label_code("fi");

	gen_expr(s->expr, s->symtab);
	asm_temp(1, "pop rax");

	asm_temp(1, "test rax, rax");
	asm_temp(1, "jz %s", lbl_else);
	gen_stmt(s->lhs);
	asm_temp(1, "jmp %s", lbl_fi);
	asm_label(lbl_else);
	if(s->rhs)
		gen_stmt(s->rhs);
	asm_label(lbl_fi);

	free(lbl_else);
	free(lbl_fi);
}
Exemplo n.º 7
0
void gen_stmt_for(stmt *s)
{
	char *lbl_test = asm_label_flow("for_test");

	/* don't else-if, possible to have both (comma-exp for init) */
	if(s->flow->for_init){
		gen_expr(s->flow->for_init, s->flow->for_init_symtab);
		asm_temp(1, "pop rax ; unused for init");
	}

	asm_label(lbl_test);
	if(s->flow->for_while){
		gen_expr(s->flow->for_while, s->flow->for_init_symtab);

		asm_temp(1, "pop rax");
		asm_temp(1, "test rax, rax");
		asm_temp(1, "jz %s", s->lbl_break);
	}

	gen_stmt(s->lhs);
	asm_label(s->lbl_continue);
	if(s->flow->for_inc){
		gen_expr(s->flow->for_inc, s->flow->for_init_symtab);
		asm_temp(1, "pop rax ; unused for inc");
	}

	asm_temp(1, "jmp %s", lbl_test);

	asm_label(s->lbl_break);

	free(lbl_test);
}
Exemplo n.º 8
0
Arquivo: asm.c Projeto: mtexier/ucc
void asm_sym(enum asm_sym_type t, sym *s, const char *reg)
{
	const int is_global = s->type == sym_global || (s->decl->type->spec & (spec_extern | spec_static));
	char *const dsp = s->decl->spel;
	int is_auto = s->type == sym_local;
	char  stackbrackets[16];
	char *brackets;

	if(is_global){
		const int bracket_len = strlen(dsp) + 16;

		brackets = umalloc(bracket_len + 1);

		if(t == ASM_LEA || s->decl->func_code){
			snprintf(brackets, bracket_len, "%s", dsp); /* int (*p)() = printf; for example */
			/*
			 * either:
			 *   we want             lea rax, [a]
			 *   and convert this to mov rax, a   // this is because Macho-64 is an awful binary format
			 * force a mov for funcs (i.e. &func == func)
			 */
			t = ASM_LOAD;
		}else{
			const char *type_s = "";

			if(asm_type_size(s->decl) == ASM_SIZE_WORD)
				type_s = "qword ";

			/* get warnings for "lea rax, [qword tim]", just do "lea rax, [tim]" */
			snprintf(brackets, bracket_len, "[%s%s]",
					t == ASM_LEA ? "" : type_s, dsp);
		}
	}else{
		brackets = stackbrackets;
		snprintf(brackets, sizeof stackbrackets, "[rbp %c %d]",
				is_auto ? '-' : '+',
				((is_auto ? 1 : 2) * platform_word_size()) + s->offset);
	}

	asm_temp(1, "%s %s, %s ; %s%s",
			t == ASM_LEA ? "lea"    : "mov",
			t == ASM_SET ? brackets : reg,
			t == ASM_SET ? reg      : brackets,
			t == ASM_LEA ? "&"      : "",
			dsp
			);

	if(brackets != stackbrackets)
		free(brackets);
}
Exemplo n.º 9
0
Arquivo: asm.c Projeto: mtexier/ucc
void asm_new(enum asm_type t, void *p)
{
	switch(t){
		case asm_assign:
			asm_temp(1, "pop rax");
			break;

		case asm_call:
			asm_temp(1, "call %s", (const char *)p);
			break;

		case asm_load_ident:
			asm_temp(1, "load %s", (const char *)p);
			break;

		case asm_load_val:
			asm_temp(1, "load val %d", *(int *)p);
			break;

		case asm_op:
			asm_temp(1, "%s", op_to_str(*(enum op_type *)p));
			break;

		case asm_pop:
			asm_temp(1, "pop");
			break;

		case asm_push:
			asm_temp(1, "push");
			break;

		case asm_addrof:
			fprintf(stderr, "BUH?? (addrof)\n");
			break;
	}
}
Exemplo n.º 10
0
Arquivo: asm.c Projeto: mtexier/ucc
void asm_label(const char *lbl)
{
	asm_temp(0, "%s:", lbl);
}
Exemplo n.º 11
0
void gen_stmt_noop(stmt *s)
{
	(void)s;
	asm_temp(1, "; noop");
}