Beispiel #1
0
void gen_expr_struct(expr *e)
{
	ASSERT_NOT_DOT();

	gen_expr_struct_lea(e);

	out_deref();
}
const out_val *gen_expr_assign_compound(const expr *e, out_ctx *octx)
{
	/* int += float
	 * lea int, cast up to float, add, cast down to int, store
	 */
	const out_val *saved_post = NULL, *addr_lhs, *rhs, *lhs, *result;

	addr_lhs = gen_expr(e->lhs, octx);

	out_val_retain(octx, addr_lhs); /* 2 */

	if(e->assign_is_post){
		out_val_retain(octx, addr_lhs); /* 3 */
		saved_post = out_deref(octx, addr_lhs); /* addr_lhs=2, saved_post=1 */
	}

	/* delay the dereference until after generating rhs.
	 * this is fine, += etc aren't sequence points
	 */

	rhs = gen_expr(e->rhs, octx);

	/* here's the delayed dereference */
	lhs = out_deref(octx, addr_lhs); /* addr_lhs=1 */
	if(e->bits.compoundop.upcast_ty)
		lhs = out_cast(octx, lhs, e->bits.compoundop.upcast_ty, /*normalise_bool:*/1);

	result = out_op(octx, e->bits.compoundop.op, lhs, rhs);
	gen_op_trapv(e->tree_type, &result, octx, e->bits.compoundop.op);

	if(e->bits.compoundop.upcast_ty) /* need to cast back down to store */
		result = out_cast(octx, result, e->tree_type, /*normalise_bool:*/1);

	if(!saved_post)
		out_val_retain(octx, result);
	out_store(octx, addr_lhs, result);

	if(!saved_post)
		return result;
	return saved_post;
}
void gen_expr_assign_compound(expr *e)
{
	/* int += float
	 * lea int, cast up to float, add, cast down to int, store
	 */
	lea_expr(e->bits.compound_upcast ? expr_cast_child(e->lhs) : e->lhs);

	if(e->assign_is_post){
		out_dup();
		out_deref();
		out_flush_volatile();
		out_swap();
		out_comment("saved for compound op");
	}

	out_dup();
	/* delay the dereference until after generating rhs.
	 * this is fine, += etc aren't sequence points
	 */

	gen_expr(e->rhs);

	/* here's the delayed dereference */
	out_swap();
	out_deref();
	if(e->bits.compound_upcast)
		out_cast(e->lhs->tree_type, /*normalise_bool:*/1);
	out_swap();

	out_op(e->op);

	if(e->bits.compound_upcast) /* need to cast back down to store */
		out_cast(e->tree_type, /*normalise_bool:*/1);

	out_store();

	if(e->assign_is_post)
		out_pop();
}
Beispiel #4
0
const out_val *gen_expr_assign(const expr *e, out_ctx *octx)
{
	const out_val *val, *store;

	UCC_ASSERT(!e->assign_is_post, "assign_is_post set for non-compound assign");

	assert(!type_is_s_or_u(e->tree_type));

	val = gen_expr(e->rhs, octx);
	store = gen_expr(e->lhs, octx);
	out_val_retain(octx, store);

	out_store(octx, store, val);

	/* re-read from the store,
	 * e.g. if the value has undergone bitfield truncation */
	return out_deref(octx, store);
}
Beispiel #5
0
static const out_val *vla_cached_size(type *const qual_t, out_ctx *octx)
{
	type *t = type_skip_all(qual_t);
	struct cc1_out_ctx **cc1_octx = cc1_out_ctx(octx);
	dynmap *vlamap;

	if(*cc1_octx && (vlamap = (*cc1_octx)->vlamap)){
		const out_val *stack_off = dynmap_get(type *, const out_val *, vlamap, t);

		if(stack_off){
			out_comment(octx, "vla saved size for %s", type_to_str(qual_t));

			out_val_retain(octx, stack_off);
			return out_deref(octx, stack_off);
		}
	}

	return NULL;
}