static void static_val(enum section_type sec, type *ty, expr *e) { consty k; memset(&k, 0, sizeof k); const_fold(e, &k); switch(k.type){ case CONST_NEED_ADDR: case CONST_NO: ICE("non-constant expr-%s const=%d%s", e->f_str(), k.type, k.type == CONST_NEED_ADDR ? " (needs addr)" : ""); break; case CONST_NUM: if(K_FLOATING(k.bits.num)){ /* asm fp const */ asm_out_fp(sec, ty, k.bits.num.val.f); }else{ char buf[INTEGRAL_BUF_SIZ]; asm_declare_init_type(sec, ty); integral_str(buf, sizeof buf, k.bits.num.val.i, e->tree_type); asm_out_section(sec, "%s", buf); } break; case CONST_ADDR: asm_declare_init_type(sec, ty); if(k.bits.addr.is_lbl) asm_out_section(sec, "%s", k.bits.addr.bits.lbl); else asm_out_section(sec, "%ld", k.bits.addr.bits.memaddr); break; case CONST_STRK: stringlit_use(k.bits.str->lit); /* must be before the label access */ asm_declare_init_type(sec, ty); asm_out_section(sec, "%s", k.bits.str->lit->lbl); break; } /* offset in bytes, no mul needed */ if(k.offset) asm_out_section(sec, " + %ld", k.offset); asm_out_section(sec, "\n"); }
static void fold_cast_num(expr *const e, numeric *const num) { int to_fp, from_fp; to_fp = type_is_floating(e->tree_type); from_fp = type_is_floating(expr_cast_child(e)->tree_type); if(to_fp){ if(from_fp){ UCC_ASSERT(K_FLOATING(*num), "i/f mismatch types"); /* float -> float - nothing to see here */ }else{ UCC_ASSERT(K_INTEGRAL(*num), "i/f mismatch types"); /* int -> float */ if(num->suffix & VAL_UNSIGNED){ num->val.f = num->val.i; }else{ /* force a signed conversion, long long to long double */ num->val.f = (sintegral_t)num->val.i; } } /* perform the trunc */ switch(type_primitive(e->tree_type)){ default: ICE("fp expected"); #define TRUNC(cse, ty, bmask) \ case type_ ## cse: \ num->val.f = (ty)num->val.f; \ num->suffix = bmask; \ break TRUNC(float, float, VAL_FLOAT); TRUNC(double, double, VAL_DOUBLE); TRUNC(ldouble, long double, VAL_LDOUBLE); #undef TRUNC } return; }else if(from_fp){ UCC_ASSERT(K_FLOATING(*num), "i/f mismatch types"); /* special case _Bool */ if(type_is_primitive(e->tree_type, type__Bool)){ num->val.i = !!num->val.f; }else{ /* float -> int */ num->val.i = num->val.f; } num->suffix = 0; /* fall through to int logic */ } UCC_ASSERT(K_INTEGRAL(*num), "fp const?"); #define pv (&num->val.i) /* need to cast the val.i down as appropriate */ if(type_is_primitive(e->tree_type, type__Bool)){ *pv = !!*pv; /* analagous to out/out.c::out_normalise()'s constant case */ }else if(!from_fp){ *pv = convert_integral_to_integral_warn( *pv, e->expr->tree_type, e->tree_type, e->expr_cast_implicit, &e->where); } #undef pv }