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(); }
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); }
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; }