const entity_t *entity = get_irg_loc_description(irg, pos);
if (entity != NULL) {
- source_position_t const *const pos = &entity->base.source_position;
+ position_t const *const pos = &entity->base.pos;
warningf(WARN_UNINITIALIZED, pos, "'%N' might be used uninitialized", entity);
}
return new_r_Unknown(irg, mode);
static src_loc_t dbg_retrieve(const dbg_info *dbg)
{
- source_position_t const *const pos = (source_position_t const*)dbg;
+ position_t const *const pos = (position_t const*)dbg;
if (pos) {
return (src_loc_t){ pos->input_name, pos->lineno, pos->colno };
} else {
}
}
-static dbg_info *get_dbg_info(const source_position_t *pos)
+static dbg_info *get_dbg_info(const position_t *pos)
{
return (dbg_info*) pos;
}
ir_mode *atomic_modes[ATOMIC_TYPE_LAST+1];
-static ir_node *_expression_to_firm(const expression_t *expression);
-static ir_node *expression_to_firm(const expression_t *expression);
+static ir_node *expression_to_control_flow(expression_t const *expr, jump_target *true_target, jump_target *false_target);
+static ir_node *expression_to_value(expression_t const *expr);
static unsigned decide_modulo_shift(unsigned type_size)
{
{
unsigned flags = get_atomic_type_flags(kind);
unsigned size = get_atomic_type_size(kind);
- if ((flags & ATOMIC_TYPE_FLAG_FLOAT)
- && !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) {
+ if (flags & ATOMIC_TYPE_FLAG_FLOAT) {
switch (size) {
case 4: return get_modeF();
case 8: return get_modeD();
{
ir_node *size_node = type->size_node;
if (size_node == NULL) {
- size_node = expression_to_firm(type->size_expression);
+ size_node = expression_to_value(type->size_expression);
type->size_node = size_node;
}
return size_node;
return count;
}
-/**
- * Creates a Firm type for an atomic type
- */
-static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
+static ir_type *create_primitive_irtype(atomic_type_kind_t akind,
+ type_dbg_info *dbgi)
{
ir_mode *mode = atomic_modes[akind];
- type_dbg_info *dbgi = get_type_dbg_info_(type);
ir_type *irtype = new_d_type_primitive(mode, dbgi);
- il_alignment_t alignment = get_atomic_type_alignment(akind);
+ unsigned alignment = get_atomic_type_alignment(akind);
+ unsigned size = get_atomic_type_size(akind);
- set_type_size_bytes(irtype, get_atomic_type_size(akind));
+ set_type_size_bytes(irtype, size);
set_type_alignment_bytes(irtype, alignment);
return irtype;
}
+/**
+ * Creates a Firm type for an atomic type
+ */
+static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
+{
+ type_dbg_info *dbgi = get_type_dbg_info_(type);
+ return create_primitive_irtype(akind, dbgi);
+}
+
/**
* Creates a Firm type for a complex type
*/
-static ir_type *create_complex_type(const atomic_type_t *type)
+static ir_type *create_complex_type(atomic_type_kind_t akind,
+ const type_t *type)
{
- atomic_type_kind_t kind = type->akind;
- ir_mode *mode = atomic_modes[kind];
- ident *id = get_mode_ident(mode);
+ type_dbg_info *dbgi = get_type_dbg_info_(type);
+ ir_type *etype = create_primitive_irtype(akind, NULL);
+ ir_type *irtype = new_d_type_array(1, etype, dbgi);
- (void) id;
+ int align = get_type_alignment_bytes(etype);
+ set_type_alignment_bytes(irtype, align);
+ unsigned n_elements = 2;
+ set_array_bounds_int(irtype, 0, 0, n_elements);
+ size_t elemsize = get_type_size_bytes(etype);
+ if (elemsize % align > 0) {
+ elemsize += align - (elemsize % align);
+ }
+ set_type_size_bytes(irtype, n_elements * elemsize);
- /* FIXME: finish the array */
- return NULL;
+ return irtype;
}
/**
ident = new_id_from_str(symbol->string);
}
- dbg_info *dbgi = get_dbg_info(&entry->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&entry->base.pos);
ir_type *entry_irtype;
if (entry->compound_member.bitfield) {
firm_type = create_atomic_type(type->atomic.akind, type);
break;
case TYPE_COMPLEX:
- firm_type = create_complex_type(&type->atomic);
+ firm_type = create_complex_type(type->atomic.akind, type);
break;
case TYPE_IMAGINARY:
firm_type = create_imaginary_type(&type->atomic);
else
nested_function = true;
- dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&entity->base.pos);
irentity = new_d_entity(owner_type, id, ir_type_method, dbgi);
ident *ld_id;
return new_Const((v ? get_mode_one : get_mode_null)(mode));
}
-static ir_node *create_conv_from_b(dbg_info *dbgi, ir_node *value,
- ir_mode *dest_mode)
-{
- if (is_Const(value)) {
- return create_Const_from_bool(dest_mode, !is_Const_null(value));
- }
-
- ir_node *cond = new_d_Cond(dbgi, value);
- ir_node *proj_true = new_Proj(cond, mode_X, pn_Cond_true);
- ir_node *proj_false = new_Proj(cond, mode_X, pn_Cond_false);
- ir_node *tblock = new_Block(1, &proj_true);
- ir_node *fblock = new_Block(1, &proj_false);
- set_cur_block(tblock);
- ir_node *const1 = new_Const(get_mode_one(dest_mode));
- ir_node *tjump = new_Jmp();
- set_cur_block(fblock);
- ir_node *const0 = new_Const(get_mode_null(dest_mode));
- ir_node *fjump = new_Jmp();
-
- ir_node *in[2] = { tjump, fjump };
- ir_node *mergeblock = new_Block(2, in);
- set_cur_block(mergeblock);
- ir_node *phi_in[2] = { const1, const0 };
- ir_node *phi = new_Phi(2, phi_in, dest_mode);
- return phi;
-}
-
static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
{
ir_mode *value_mode = get_irn_mode(value);
if (value_mode == dest_mode)
return value;
- if (dest_mode == mode_b) {
- ir_node *zero = new_Const(get_mode_null(value_mode));
- ir_node *cmp = new_d_Cmp(dbgi, value, zero, ir_relation_unordered_less_greater);
- return cmp;
- } else if (value_mode == mode_b) {
- return create_conv_from_b(dbgi, value, dest_mode);
- }
-
return new_d_Conv(dbgi, value, dest_mode);
}
+static ir_node *conv_to_storage_type(dbg_info *const dbgi, ir_node *const val, type_t *const type)
+{
+ ir_mode *const mode = get_ir_mode_storage(type);
+ return create_conv(dbgi, val, mode);
+}
+
/**
* Creates a SymConst node representing a string constant.
*
* @param id_prefix a prefix for the name of the generated string constant
* @param value the value of the string constant
*/
-static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_t const *const value)
+static ir_node *string_to_firm(position_t const *const src_pos, char const *const id_prefix, string_t const *const value)
{
size_t const slen = get_string_len(value) + 1;
ir_initializer_t *const initializer = create_initializer_compound(slen);
panic("invalid literal kind");
}
- dbg_info *dbgi = get_dbg_info(&literal->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&literal->base.pos);
ir_node *res = new_d_Const(dbgi, tv);
ir_mode *mode_arith = get_ir_mode_arithmetic(type);
return create_conv(dbgi, res, mode_arith);
panic("invalid literal kind");
}
- dbg_info *dbgi = get_dbg_info(&literal->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&literal->base.pos);
ir_node *res = new_d_Const(dbgi, tv);
ir_mode *mode_arith = get_ir_mode_arithmetic(type);
return create_conv(dbgi, res, mode_arith);
static ir_node *reference_addr(const reference_expression_t *ref)
{
- dbg_info *dbgi = get_dbg_info(&ref->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&ref->base.pos);
entity_t *entity = ref->entity;
assert(is_declaration(entity));
/* for gcc compatibility we have to produce (dummy) addresses for some
* builtins which don't have entities */
if (irentity == NULL) {
- source_position_t const *const pos = &ref->base.source_position;
+ position_t const *const pos = &ref->base.pos;
warningf(WARN_OTHER, pos, "taking address of builtin '%N'", ref->entity);
/* simply create a NULL pointer */
static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
{
- dbg_info *const dbgi = get_dbg_info(&ref->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&ref->base.pos);
entity_t *const entity = ref->entity;
assert(is_declaration(entity));
*/
static ir_node *process_builtin_call(const call_expression_t *call)
{
- dbg_info *dbgi = get_dbg_info(&call->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&call->base.pos);
assert(call->function->kind == EXPR_REFERENCE);
reference_expression_t *builtin = &call->function->reference;
break;
case BUILTIN_ALLOCA: {
expression_t *argument = call->arguments->expression;
- ir_node *size = expression_to_firm(argument);
+ ir_node *size = expression_to_value(argument);
ir_node *store = get_store();
ir_node *alloca = new_d_Alloc(dbgi, store, size, get_unknown_type(),
}
case BUILTIN_EXPECT: {
expression_t *argument = call->arguments->expression;
- return _expression_to_firm(argument);
+ return expression_to_value(argument);
}
case BUILTIN_VA_END:
/* evaluate the argument of va_end for its side effects */
- _expression_to_firm(call->arguments->expression);
+ expression_to_value(call->arguments->expression);
return NULL;
case BUILTIN_OBJECT_SIZE: {
/* determine value of "type" */
return new_d_Const(dbgi, result);
}
case BUILTIN_ROTL: {
- ir_node *val = expression_to_firm(call->arguments->expression);
- ir_node *shf = expression_to_firm(call->arguments->next->expression);
+ ir_node *val = expression_to_value(call->arguments->expression);
+ ir_node *shf = expression_to_value(call->arguments->next->expression);
ir_mode *mode = get_irn_mode(val);
ir_mode *mode_uint = atomic_modes[ATOMIC_TYPE_UINT];
return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode);
}
case BUILTIN_ROTR: {
- ir_node *val = expression_to_firm(call->arguments->expression);
- ir_node *shf = expression_to_firm(call->arguments->next->expression);
+ ir_node *val = expression_to_value(call->arguments->expression);
+ ir_node *shf = expression_to_value(call->arguments->next->expression);
ir_mode *mode = get_irn_mode(val);
ir_mode *mode_uint = atomic_modes[ATOMIC_TYPE_UINT];
ir_node *c = new_Const_long(mode_uint, get_mode_size_bits(mode));
*/
static ir_node *call_expression_to_firm(const call_expression_t *const call)
{
- dbg_info *const dbgi = get_dbg_info(&call->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&call->base.pos);
assert(currently_reachable());
expression_t *function = call->function;
}
}
if (!firm_builtin)
- callee = expression_to_firm(function);
+ callee = expression_to_value(function);
type_t *type = skip_typeref(function->base.type);
assert(is_type_pointer(type));
const call_argument_t *argument = call->arguments;
for (int n = 0; n < n_parameters; ++n) {
expression_t *expression = argument->expression;
- ir_node *arg_node = expression_to_firm(expression);
-
- type_t *arg_type = skip_typeref(expression->base.type);
- if (!is_type_compound(arg_type)) {
- ir_mode *const mode = get_ir_mode_storage(arg_type);
- arg_node = create_conv(dbgi, arg_node, mode);
- }
-
- in[n] = arg_node;
+ ir_node *arg_node = expression_to_value(expression);
+ type_t *arg_type = skip_typeref(expression->base.type);
+ in[n] = conv_to_storage_type(dbgi, arg_node, arg_type);
argument = argument->next;
}
static ir_node *statement_to_firm(statement_t *statement);
static ir_node *compound_statement_to_firm(compound_statement_t *compound);
-
static ir_node *expression_to_addr(const expression_t *expression);
-static ir_node *create_condition_evaluation(expression_t const *expression, jump_target *true_target, jump_target *false_target);
static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type,
ir_node *value)
{
- if (!is_type_compound(type)) {
- ir_mode *mode = get_ir_mode_storage(type);
- value = create_conv(dbgi, value, mode);
- }
+ value = conv_to_storage_type(dbgi, value, type);
ir_node *memory = get_store();
static ir_node *bitfield_extract_to_firm(const select_expression_t *expression,
ir_node *addr)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
entity_t *entity = expression->compound_entry;
type_t *base_type = entity->declaration.type;
ir_mode *mode = get_ir_mode_storage(base_type);
static ir_node *set_value_for_expression_addr(const expression_t *expression,
ir_node *value, ir_node *addr)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
type_t *type = skip_typeref(expression->base.type);
-
- if (!is_type_compound(type)) {
- ir_mode *mode = get_ir_mode_storage(type);
- value = create_conv(dbgi, value, mode);
- }
+ value = conv_to_storage_type(dbgi, value, type);
if (expression->kind == EXPR_REFERENCE) {
const reference_expression_t *ref = &expression->reference;
return value;
}
-static void set_value_for_expression(const expression_t *expression,
- ir_node *value)
-{
- set_value_for_expression_addr(expression, value, NULL);
-}
-
static ir_node *get_value_from_lvalue(const expression_t *expression,
ir_node *addr)
{
}
assert(addr != NULL);
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
ir_node *value;
if (expression->kind == EXPR_SELECT &&
return value;
}
-
-static ir_node *create_incdec(const unary_expression_t *expression)
+static ir_node *incdec_to_firm(unary_expression_t const *const expr, bool const inc, bool const pre)
{
- dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
- const expression_t *value_expr = expression->value;
- ir_node *addr = expression_to_addr(value_expr);
- ir_node *value = get_value_from_lvalue(value_expr, addr);
-
- type_t *type = skip_typeref(expression->base.type);
- ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
+ type_t *const type = skip_typeref(expr->base.type);
+ ir_mode *const mode = get_ir_mode_arithmetic(type);
ir_node *offset;
if (is_type_pointer(type)) {
- pointer_type_t *pointer_type = &type->pointer;
- offset = get_type_size_node(pointer_type->points_to);
+ offset = get_type_size_node(type->pointer.points_to);
} else {
assert(is_type_arithmetic(type));
offset = new_Const(get_mode_one(mode));
}
- ir_node *result;
- ir_node *store_value;
- switch(expression->base.kind) {
- case EXPR_UNARY_POSTFIX_INCREMENT:
- result = value;
- store_value = new_d_Add(dbgi, value, offset, mode);
- break;
- case EXPR_UNARY_POSTFIX_DECREMENT:
- result = value;
- store_value = new_d_Sub(dbgi, value, offset, mode);
- break;
- case EXPR_UNARY_PREFIX_INCREMENT:
- result = new_d_Add(dbgi, value, offset, mode);
- store_value = result;
- break;
- case EXPR_UNARY_PREFIX_DECREMENT:
- result = new_d_Sub(dbgi, value, offset, mode);
- store_value = result;
- break;
- default:
- panic("no incdec expr");
- }
-
- set_value_for_expression_addr(value_expr, store_value, addr);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ expression_t const *const value_expr = expr->value;
+ ir_node *const addr = expression_to_addr(value_expr);
+ ir_node *const value = get_value_from_lvalue(value_expr, addr);
+ ir_node *const new_value = inc
+ ? new_d_Add(dbgi, value, offset, mode)
+ : new_d_Sub(dbgi, value, offset, mode);
- return result;
+ ir_node *const store_value = set_value_for_expression_addr(value_expr, new_value, addr);
+ return pre ? store_value : value;
}
static bool is_local_variable(expression_t *expression)
ir_mode *const mode = get_ir_mode_storage(type);
res = get_value(var->variable.v.value_number, mode);
- res = new_d_Confirm(dbi, res, expression_to_firm(con), relation);
+ res = new_d_Confirm(dbi, res, expression_to_value(con), relation);
set_value(var->variable.v.value_number, res);
}
return res;
* @param dbi debug info
* @param expr the IL assume expression
*/
-static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression)
+static ir_node *handle_assume(expression_t const *const expr)
{
- switch(expression->kind) {
+ switch (expr->kind) {
case EXPR_BINARY_EQUAL:
case EXPR_BINARY_NOTEQUAL:
case EXPR_BINARY_LESS:
case EXPR_BINARY_LESSEQUAL:
case EXPR_BINARY_GREATER:
- case EXPR_BINARY_GREATEREQUAL:
- return handle_assume_compare(dbi, &expression->binary);
+ case EXPR_BINARY_GREATEREQUAL: {
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ return handle_assume_compare(dbgi, &expr->binary);
+ }
+
default:
return NULL;
}
}
-static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node,
- type_t *from_type, type_t *type)
+static ir_node *create_cast(unary_expression_t const *const expr)
{
- type = skip_typeref(type);
- if (is_type_void(type)) {
- /* make sure firm type is constructed */
- (void) get_ir_type(type);
+ type_t *const type = skip_typeref(expr->base.type);
+ if (is_type_void(type))
return NULL;
- }
- if (!is_type_scalar(type)) {
- /* make sure firm type is constructed */
- (void) get_ir_type(type);
- return value_node;
- }
- from_type = skip_typeref(from_type);
- ir_mode *mode = get_ir_mode_storage(type);
+ ir_node *value = expression_to_value(expr->value);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ type_t *const from_type = skip_typeref(expr->value->base.type);
+ ir_mode *const mode = get_ir_mode_storage(type);
/* check for conversion from / to __based types */
if (is_type_pointer(type) && is_type_pointer(from_type)) {
const variable_t *from_var = from_type->pointer.base_variable;
if (from_var != NULL) {
ir_node *const addr = create_symconst(dbgi, from_var->v.entity);
ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
- value_node = new_d_Add(dbgi, value_node, base, mode);
+ value = new_d_Add(dbgi, value, base, mode);
}
if (to_var != NULL) {
ir_node *const addr = create_symconst(dbgi, to_var->v.entity);
ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
- value_node = new_d_Sub(dbgi, value_node, base, mode);
+ value = new_d_Sub(dbgi, value, base, mode);
}
}
}
- if (is_type_atomic(type, ATOMIC_TYPE_BOOL)) {
- /* bool adjustments (we save a mode_Bu, but have to temporarily
- * convert to mode_b so we only get a 0/1 value */
- value_node = create_conv(dbgi, value_node, mode_b);
- }
-
ir_mode *mode_arith = get_ir_mode_arithmetic(type);
- ir_node *node = create_conv(dbgi, value_node, mode);
+ ir_node *node = create_conv(dbgi, value, mode);
node = create_conv(dbgi, node, mode_arith);
-
return node;
}
-static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
+static ir_node *complement_to_firm(unary_expression_t const *const expr)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- type_t *type = skip_typeref(expression->base.type);
-
- const expression_t *value = expression->value;
-
- switch(expression->base.kind) {
- case EXPR_UNARY_TAKE_ADDRESS:
- return expression_to_addr(value);
-
- case EXPR_UNARY_NEGATE: {
- ir_node *value_node = expression_to_firm(value);
- ir_mode *mode = get_ir_mode_arithmetic(type);
- return new_d_Minus(dbgi, value_node, mode);
- }
- case EXPR_UNARY_PLUS:
- return expression_to_firm(value);
- case EXPR_UNARY_BITWISE_NEGATE: {
- ir_node *value_node = expression_to_firm(value);
- ir_mode *mode = get_ir_mode_arithmetic(type);
- return new_d_Not(dbgi, value_node, mode);
- }
- case EXPR_UNARY_NOT: {
- ir_node *value_node = _expression_to_firm(value);
- value_node = create_conv(dbgi, value_node, mode_b);
- ir_node *res = new_d_Not(dbgi, value_node, mode_b);
- return res;
- }
- case EXPR_UNARY_DEREFERENCE: {
- ir_node *value_node = expression_to_firm(value);
- type_t *value_type = skip_typeref(value->base.type);
- assert(is_type_pointer(value_type));
-
- /* check for __based */
- const variable_t *const base_var = value_type->pointer.base_variable;
- if (base_var != NULL) {
- ir_node *const addr = create_symconst(dbgi, base_var->v.entity);
- ir_node *const base = deref_address(dbgi, base_var->base.type, addr);
- value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(value_type));
- }
- type_t *points_to = value_type->pointer.points_to;
- return deref_address(dbgi, points_to, value_node);
- }
- case EXPR_UNARY_POSTFIX_INCREMENT:
- case EXPR_UNARY_POSTFIX_DECREMENT:
- case EXPR_UNARY_PREFIX_INCREMENT:
- case EXPR_UNARY_PREFIX_DECREMENT:
- return create_incdec(expression);
- case EXPR_UNARY_CAST: {
- ir_node *value_node = expression_to_firm(value);
- type_t *from_type = value->base.type;
- return create_cast(dbgi, value_node, from_type, type);
- }
- case EXPR_UNARY_ASSUME:
- return handle_assume(dbgi, value);
-
- default:
- break;
- }
- panic("invalid unary expression type");
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_node *const value = expression_to_value(expr->value);
+ type_t *const type = skip_typeref(expr->base.type);
+ ir_mode *const mode = get_ir_mode_arithmetic(type);
+ return new_d_Not(dbgi, value, mode);
}
-/**
- * produces a 0/1 depending of the value of a mode_b node
- */
-static ir_node *produce_condition_result(const expression_t *expression,
- ir_mode *mode, dbg_info *dbgi)
+static ir_node *dereference_to_firm(unary_expression_t const *const expr)
{
- jump_target true_target;
- jump_target false_target;
- init_jump_target(&true_target, NULL);
- init_jump_target(&false_target, NULL);
- create_condition_evaluation(expression, &true_target, &false_target);
-
- ir_node *val = NULL;
- jump_target exit_target;
- init_jump_target(&exit_target, NULL);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_node *value = expression_to_value(expr->value);
+ type_t *const value_type = skip_typeref(expr->value->base.type);
+ assert(is_type_pointer(value_type));
- if (enter_jump_target(&true_target)) {
- val = new_Const(get_mode_one(mode));
- jump_to_target(&exit_target);
- }
-
- if (enter_jump_target(&false_target)) {
- ir_node *const zero = new_Const(get_mode_null(mode));
- jump_to_target(&exit_target);
- if (val) {
- ir_node *const in[] = { val, zero };
- val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, mode);
- } else {
- val = zero;
- }
+ /* check for __based */
+ variable_t const *const base_var = value_type->pointer.base_variable;
+ if (base_var) {
+ ir_node *const addr = create_symconst(dbgi, base_var->v.entity);
+ ir_node *const base = deref_address(dbgi, base_var->base.type, addr);
+ value = new_d_Add(dbgi, value, base, get_ir_mode_storage(value_type));
}
+ type_t *const points_to = value_type->pointer.points_to;
+ return deref_address(dbgi, points_to, value);
+}
- if (!enter_jump_target(&exit_target)) {
- set_cur_block(new_Block(0, NULL));
- val = new_Unknown(mode);
- }
- return val;
+static ir_node *negate_to_firm(unary_expression_t const *const expr)
+{
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_node *const value = expression_to_value(expr->value);
+ type_t *const type = skip_typeref(expr->base.type);
+ ir_mode *const mode = get_ir_mode_arithmetic(type);
+ return new_d_Minus(dbgi, value, mode);
}
static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi,
return mul;
}
-static ir_node *create_op(dbg_info *dbgi, const binary_expression_t *expression,
- ir_node *left, ir_node *right)
+static ir_node *create_op(binary_expression_t const *const expr, ir_node *left, ir_node *right)
{
- ir_mode *mode;
- type_t *type_left = skip_typeref(expression->left->base.type);
- type_t *type_right = skip_typeref(expression->right->base.type);
-
- expression_kind_t kind = expression->base.kind;
-
+ ir_mode *mode;
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ type_t *const type_left = skip_typeref(expr->left->base.type);
+ type_t *const type_right = skip_typeref(expr->right->base.type);
+ expression_kind_t const kind = expr->base.kind;
switch (kind) {
case EXPR_BINARY_SHIFTLEFT:
case EXPR_BINARY_SHIFTRIGHT:
case EXPR_BINARY_SHIFTLEFT_ASSIGN:
case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
- mode = get_ir_mode_arithmetic(expression->base.type);
+ mode = get_ir_mode_arithmetic(expr->base.type);
right = create_conv(dbgi, right, atomic_modes[ATOMIC_TYPE_UINT]);
break;
if (is_type_pointer(type_left) && is_type_pointer(type_right)) {
const pointer_type_t *const ptr_type = &type_left->pointer;
- mode = get_ir_mode_arithmetic(expression->base.type);
+ mode = get_ir_mode_arithmetic(expr->base.type);
ir_node *const elem_size = get_type_size_node(ptr_type->points_to);
ir_node *const conv_size = new_d_Conv(dbgi, elem_size, mode);
ir_node *const sub = new_d_Sub(dbgi, left, right, mode);
}
}
-static ir_node *create_lazy_op(const binary_expression_t *expression)
+static ir_node *binop_to_firm(binary_expression_t const *const expr)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- type_t *type = skip_typeref(expression->base.type);
- ir_mode *mode = get_ir_mode_arithmetic(type);
-
- if (is_constant_expression(expression->left) == EXPR_CLASS_CONSTANT) {
- bool val = fold_constant_to_bool(expression->left);
- expression_kind_t ekind = expression->base.kind;
- assert(ekind == EXPR_BINARY_LOGICAL_AND || ekind == EXPR_BINARY_LOGICAL_OR);
- if (ekind == EXPR_BINARY_LOGICAL_AND) {
- if (!val) {
- return new_Const(get_mode_null(mode));
- }
+ ir_node *const left = expression_to_value(expr->left);
+ ir_node *const right = expression_to_value(expr->right);
+ return create_op(expr, left, right);
+}
+
+/**
+ * Check if a given expression is a GNU __builtin_expect() call.
+ */
+static bool is_builtin_expect(const expression_t *expression)
+{
+ if (expression->kind != EXPR_CALL)
+ return false;
+
+ expression_t *function = expression->call.function;
+ if (function->kind != EXPR_REFERENCE)
+ return false;
+ reference_expression_t *ref = &function->reference;
+ if (ref->entity->kind != ENTITY_FUNCTION ||
+ ref->entity->function.btk != BUILTIN_EXPECT)
+ return false;
+
+ return true;
+}
+
+static void compare_to_control_flow(expression_t const *const expr, ir_node *const left, ir_node *const right, ir_relation const relation, jump_target *const true_target, jump_target *const false_target)
+{
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_node *const cmp = new_d_Cmp(dbgi, left, right, relation);
+ if (is_Const(cmp)) {
+ if (tarval_is_null(get_Const_tarval(cmp))) {
+ jump_to_target(false_target);
} else {
- if (val) {
- return new_Const(get_mode_one(mode));
- }
+ jump_to_target(true_target);
}
+ } else {
+ ir_node *const cond = new_d_Cond(dbgi, cmp);
+ ir_node *const true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
+ ir_node *const false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
- if (is_constant_expression(expression->right) == EXPR_CLASS_CONSTANT) {
- bool valr = fold_constant_to_bool(expression->right);
- return create_Const_from_bool(mode, valr);
+ /* set branch prediction info based on __builtin_expect */
+ if (is_builtin_expect(expr) && is_Cond(cond)) {
+ call_argument_t *const argument = expr->call.arguments->next;
+ if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+ bool const cnst = fold_constant_to_bool(argument->expression);
+ cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
+ set_Cond_jmp_pred(cond, pred);
+ }
}
- return produce_condition_result(expression->right, mode, dbgi);
+ add_pred_to_jump_target(true_target, true_proj);
+ add_pred_to_jump_target(false_target, false_proj);
}
-
- return produce_condition_result((const expression_t*) expression, mode,
- dbgi);
+ set_unreachable_now();
}
-typedef ir_node * (*create_arithmetic_func)(dbg_info *dbgi, ir_node *left,
- ir_node *right, ir_mode *mode);
-
-static ir_node *create_assign_binop(const binary_expression_t *expression)
+static ir_node *control_flow_to_1_0(expression_t const *const expr, jump_target *const true_target, jump_target *const false_target)
{
- dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
- const expression_t *left_expr = expression->left;
- type_t *type = skip_typeref(left_expr->base.type);
- ir_node *right = expression_to_firm(expression->right);
- ir_node *left_addr = expression_to_addr(left_expr);
- ir_node *left = get_value_from_lvalue(left_expr, left_addr);
- ir_node *result = create_op(dbgi, expression, left, right);
+ ir_node *val = NULL;
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_mode *const mode = get_ir_mode_arithmetic(expr->base.type);
+ jump_target exit_target;
+ init_jump_target(&exit_target, NULL);
- result = create_cast(dbgi, result, expression->right->base.type, type);
+ if (enter_jump_target(true_target)) {
+ jump_to_target(&exit_target);
+ val = new_d_Const(dbgi, get_mode_one(mode));
+ }
- result = set_value_for_expression_addr(left_expr, result, left_addr);
+ if (enter_jump_target(false_target)) {
+ jump_to_target(&exit_target);
+ ir_node *const zero = new_d_Const(dbgi, get_mode_null(mode));
+ if (val) {
+ ir_node *const in[] = { val, zero };
+ val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, mode);
+ } else {
+ val = zero;
+ }
+ }
- if (!is_type_compound(type)) {
- ir_mode *mode_arithmetic = get_ir_mode_arithmetic(type);
- result = create_conv(dbgi, result, mode_arithmetic);
+ if (!enter_jump_target(&exit_target)) {
+ set_cur_block(new_Block(0, NULL));
+ val = new_d_Bad(dbgi, mode);
}
- return result;
+ return val;
}
-static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
+static ir_node *binop_assign_to_firm(binary_expression_t const *const expr)
{
- expression_kind_t kind = expression->base.kind;
+ ir_node *const right = expression_to_value(expr->right);
+ expression_t const *const left_expr = expr->left;
+ ir_node *const addr = expression_to_addr(left_expr);
+ ir_node *const left = get_value_from_lvalue(left_expr, addr);
+ ir_node *result = create_op(expr, left, right);
- switch(kind) {
- case EXPR_BINARY_EQUAL:
- case EXPR_BINARY_NOTEQUAL:
- case EXPR_BINARY_LESS:
- case EXPR_BINARY_LESSEQUAL:
- case EXPR_BINARY_GREATER:
- case EXPR_BINARY_GREATEREQUAL:
- case EXPR_BINARY_ISGREATER:
- case EXPR_BINARY_ISGREATEREQUAL:
- case EXPR_BINARY_ISLESS:
- case EXPR_BINARY_ISLESSEQUAL:
- case EXPR_BINARY_ISLESSGREATER:
- case EXPR_BINARY_ISUNORDERED: {
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *left = expression_to_firm(expression->left);
- ir_node *right = expression_to_firm(expression->right);
- ir_relation relation = get_relation(kind);
- ir_node *cmp = new_d_Cmp(dbgi, left, right, relation);
- return cmp;
- }
- case EXPR_BINARY_ASSIGN: {
- ir_node *addr = expression_to_addr(expression->left);
- ir_node *right = expression_to_firm(expression->right);
- ir_node *res
- = set_value_for_expression_addr(expression->left, right, addr);
-
- type_t *type = skip_typeref(expression->base.type);
- if (!is_type_compound(type)) {
- ir_mode *mode_arithmetic = get_ir_mode_arithmetic(type);
- res = create_conv(NULL, res, mode_arithmetic);
- }
- return res;
+ type_t *const type = skip_typeref(expr->base.type);
+ if (is_type_atomic(type, ATOMIC_TYPE_BOOL)) {
+ jump_target true_target;
+ jump_target false_target;
+ init_jump_target(&true_target, NULL);
+ init_jump_target(&false_target, NULL);
+ ir_mode *const mode = get_irn_mode(result);
+ ir_node *const zero = new_Const(get_mode_null(mode));
+ compare_to_control_flow((expression_t const*)expr, result, zero, ir_relation_unordered_less_greater, &true_target, &false_target);
+ result = control_flow_to_1_0((expression_t const*)expr, &true_target, &false_target);
}
- case EXPR_BINARY_ADD:
- case EXPR_BINARY_SUB:
- case EXPR_BINARY_MUL:
- case EXPR_BINARY_DIV:
- case EXPR_BINARY_MOD:
- case EXPR_BINARY_BITWISE_AND:
- case EXPR_BINARY_BITWISE_OR:
- case EXPR_BINARY_BITWISE_XOR:
- case EXPR_BINARY_SHIFTLEFT:
- case EXPR_BINARY_SHIFTRIGHT:
- {
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *left = expression_to_firm(expression->left);
- ir_node *right = expression_to_firm(expression->right);
- return create_op(dbgi, expression, left, right);
+
+ result = set_value_for_expression_addr(left_expr, result, addr);
+
+ if (!is_type_compound(type)) {
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
+ ir_mode *const mode = get_ir_mode_arithmetic(type);
+ result = create_conv(dbgi, result, mode);
}
- case EXPR_BINARY_LOGICAL_AND:
- case EXPR_BINARY_LOGICAL_OR:
- return create_lazy_op(expression);
- case EXPR_BINARY_COMMA:
- /* create side effects of left side */
- (void) expression_to_firm(expression->left);
- return _expression_to_firm(expression->right);
+ return result;
+}
- case EXPR_BINARY_ADD_ASSIGN:
- case EXPR_BINARY_SUB_ASSIGN:
- case EXPR_BINARY_MUL_ASSIGN:
- case EXPR_BINARY_MOD_ASSIGN:
- case EXPR_BINARY_DIV_ASSIGN:
- case EXPR_BINARY_BITWISE_AND_ASSIGN:
- case EXPR_BINARY_BITWISE_OR_ASSIGN:
- case EXPR_BINARY_BITWISE_XOR_ASSIGN:
- case EXPR_BINARY_SHIFTLEFT_ASSIGN:
- case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
- return create_assign_binop(expression);
- default:
- panic("invalid binexpr type");
+static ir_node *assign_expression_to_firm(binary_expression_t const *const expr)
+{
+ ir_node *const addr = expression_to_addr(expr->left);
+ ir_node *const right = expression_to_value(expr->right);
+ ir_node *res = set_value_for_expression_addr(expr->left, right, addr);
+ type_t *const type = skip_typeref(expr->base.type);
+ if (!is_type_compound(type)) {
+ ir_mode *const mode_arithmetic = get_ir_mode_arithmetic(type);
+ res = create_conv(NULL, res, mode_arithmetic);
}
+ return res;
+}
+
+static ir_node *comma_expression_to_firm(binary_expression_t const *const expr)
+{
+ expression_to_value(expr->left);
+ return expression_to_value(expr->right);
}
static ir_node *array_access_addr(const array_access_expression_t *expression)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *base_addr = expression_to_firm(expression->array_ref);
- ir_node *offset = expression_to_firm(expression->index);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
+ ir_node *base_addr = expression_to_value(expression->array_ref);
+ ir_node *offset = expression_to_value(expression->index);
type_t *ref_type = skip_typeref(expression->array_ref->base.type);
ir_node *real_offset = adjust_for_pointer_arithmetic(dbgi, offset, ref_type);
ir_node *result = new_d_Add(dbgi, base_addr, real_offset, mode_P_data);
static ir_node *array_access_to_firm(
const array_access_expression_t *expression)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
ir_node *addr = array_access_addr(expression);
type_t *type = revert_automatic_type_conversion(
(const expression_t*) expression);
ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
long offset = get_offsetof_offset(expression);
ir_tarval *tv = new_tarval_from_long(offset, mode);
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
return new_d_Const(dbgi, tv);
}
static ir_node *compound_literal_addr(compound_literal_expression_t const *const expression)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
type_t *type = expression->type;
initializer_t *initializer = expression->initializer;
- if (is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT) {
+ if (expression->global_scope ||
+ ((type->base.qualifiers & TYPE_QUALIFIER_CONST)
+ && is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT)) {
ir_entity *entity = create_initializer_entity(dbgi, initializer, type);
return create_symconst(dbgi, entity);
} else {
static ir_node *compound_literal_to_firm(compound_literal_expression_t const* const expr)
{
- dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
type_t *const type = expr->type;
ir_node *const addr = compound_literal_addr(expr);
return deref_address(dbgi, type, addr);
/* §6.5.3.4:2 if the type is a VLA, evaluate the expression. */
if (is_type_array(type) && type->array.is_vla
&& expression->tp_expression != NULL) {
- expression_to_firm(expression->tp_expression);
+ expression_to_value(expression->tp_expression);
}
return get_type_size_node(type);
alignment = get_type_alignment(type);
}
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
ir_tarval *tv = new_tarval_from_long(alignment, mode);
return new_d_Const(dbgi, tv);
init_ir_types();
PUSH_IRG(get_const_code_irg());
- ir_node *const cnst = _expression_to_firm(expression);
+ ir_node *const cnst = expression_to_value(expression);
POP_IRG();
set_optimize(old_optimize);
set_opt_constant_folding(old_constant_folding);
-
- if (!is_Const(cnst)) {
- panic("couldn't fold constant");
- }
-
constant_folding = constant_folding_old;
- ir_tarval *const tv = get_Const_tarval(cnst);
- ir_mode *const mode = get_ir_mode_arithmetic(skip_typeref(expression->base.type));
- return tarval_convert_to(tv, mode);
+ if (!is_Const(cnst))
+ panic("couldn't fold constant");
+ return get_Const_tarval(cnst);
}
/* this function is only used in parser.c, but it relies on libfirm functionality */
static ir_node *conditional_to_firm(const conditional_expression_t *expression)
{
- /* first try to fold a constant condition */
- if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
- bool val = fold_constant_to_bool(expression->condition);
- if (val) {
- expression_t *true_expression = expression->true_expression;
- if (true_expression == NULL)
- true_expression = expression->condition;
- return expression_to_firm(true_expression);
- } else {
- return expression_to_firm(expression->false_expression);
- }
- }
-
jump_target true_target;
jump_target false_target;
init_jump_target(&true_target, NULL);
init_jump_target(&false_target, NULL);
- ir_node *const cond_expr = create_condition_evaluation(expression->condition, &true_target, &false_target);
+ ir_node *const cond_expr = expression_to_control_flow(expression->condition, &true_target, &false_target);
ir_node *val = NULL;
jump_target exit_target;
if (enter_jump_target(&true_target)) {
if (expression->true_expression) {
- val = expression_to_firm(expression->true_expression);
- } else if (cond_expr && get_irn_mode(cond_expr) != mode_b) {
+ val = expression_to_value(expression->true_expression);
+ } else if (cond_expr) {
val = cond_expr;
} else {
/* Condition ended with a short circuit (&&, ||, !) operation or a
}
if (enter_jump_target(&false_target)) {
- ir_node *const false_val = expression_to_firm(expression->false_expression);
+ ir_node *const false_val = expression_to_value(expression->false_expression);
jump_to_target(&exit_target);
if (val) {
ir_node *const in[] = { val, false_val };
- dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&expression->base.pos);
val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
} else {
val = false_val;
*/
static ir_node *select_addr(const select_expression_t *expression)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
construct_select_compound(expression);
- ir_node *compound_addr = expression_to_firm(expression->compound);
+ ir_node *compound_addr = expression_to_value(expression->compound);
entity_t *entry = expression->compound_entry;
assert(entry->kind == ENTITY_COMPOUND_MEMBER);
static ir_node *select_to_firm(const select_expression_t *expression)
{
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.pos);
ir_node *addr = select_addr(expression);
type_t *type = revert_automatic_type_conversion(
(const expression_t*) expression);
}
make_const:;
- dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
ir_mode *const mode = atomic_modes[ATOMIC_TYPE_INT];
ir_tarval *const tv = new_tarval_from_long(tc, mode);
return new_d_Const(dbgi, tv);
case FUNCNAME_PRETTY_FUNCTION:
case FUNCNAME_FUNCDNAME:
if (current_function_name == NULL) {
- source_position_t const *const src_pos = &expr->base.source_position;
- char const *const name = current_function_entity->base.symbol->string;
- string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
+ position_t const *const src_pos = &expr->base.pos;
+ char const *const name = current_function_entity->base.symbol->string;
+ string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
current_function_name = string_to_firm(src_pos, "__func__.%u", &string);
}
return current_function_name;
case FUNCNAME_FUNCSIG:
if (current_funcsig == NULL) {
- source_position_t const *const src_pos = &expr->base.source_position;
- ir_entity *const ent = get_irg_entity(current_ir_graph);
- char const *const name = get_entity_ld_name(ent);
- string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
+ position_t const *const src_pos = &expr->base.pos;
+ ir_entity *const ent = get_irg_entity(current_ir_graph);
+ char const *const name = get_entity_ld_name(ent);
+ string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", &string);
}
return current_funcsig;
}
ir_node *const frame = get_irg_frame(current_ir_graph);
- dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
ir_node *const no_mem = new_NoMem();
ir_node *const arg_sel = new_d_simpleSel(dbgi, no_mem, frame, param_ent);
- set_value_for_expression(expr->ap, arg_sel);
+ set_value_for_expression_addr(expr->ap, arg_sel, NULL);
return NULL;
}
expression_t *const ap_expr = expr->ap;
ir_node *const ap_addr = expression_to_addr(ap_expr);
ir_node *const ap = get_value_from_lvalue(ap_expr, ap_addr);
- dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
ir_node *const res = deref_address(dbgi, type, ap);
ir_node *const cnst = get_type_size_node(expr->base.type);
*/
static ir_node *va_copy_expression_to_firm(const va_copy_expression_t *const expr)
{
- ir_node *const src = expression_to_firm(expr->src);
- set_value_for_expression(expr->dst, src);
+ ir_node *const src = expression_to_value(expr->src);
+ set_value_for_expression_addr(expr->dst, src, NULL);
return NULL;
}
static ir_node *dereference_addr(const unary_expression_t *const expression)
{
assert(expression->base.kind == EXPR_UNARY_DEREFERENCE);
- return expression_to_firm(expression->value);
+ return expression_to_value(expression->value);
}
/**
switch(expression->kind) {
case EXPR_ARRAY_ACCESS:
return array_access_addr(&expression->array_access);
- case EXPR_CALL:
- return call_expression_to_firm(&expression->call);
case EXPR_COMPOUND_LITERAL:
return compound_literal_addr(&expression->compound_literal);
case EXPR_REFERENCE:
symconst_symbol value;
value.entity_p = create_Block_entity(label->label->indirect_block);
- dbg_info *const dbgi = get_dbg_info(&label->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&label->base.pos);
return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
}
-/**
- * creates firm nodes for an expression. The difference between this function
- * and expression_to_firm is, that this version might produce mode_b nodes
- * instead of mode_Is.
- */
-static ir_node *_expression_to_firm(expression_t const *const expr)
+static ir_node *expression_to_value(expression_t const *const expr)
{
#ifndef NDEBUG
if (!constant_folding) {
#endif
switch (expr->kind) {
+ case EXPR_UNARY_CAST:
+ if (is_type_atomic(skip_typeref(expr->base.type), ATOMIC_TYPE_BOOL)) {
+ case EXPR_BINARY_EQUAL:
+ case EXPR_BINARY_GREATER:
+ case EXPR_BINARY_GREATEREQUAL:
+ case EXPR_BINARY_ISGREATER:
+ case EXPR_BINARY_ISGREATEREQUAL:
+ case EXPR_BINARY_ISLESS:
+ case EXPR_BINARY_ISLESSEQUAL:
+ case EXPR_BINARY_ISLESSGREATER:
+ case EXPR_BINARY_ISUNORDERED:
+ case EXPR_BINARY_LESS:
+ case EXPR_BINARY_LESSEQUAL:
+ case EXPR_BINARY_LOGICAL_AND:
+ case EXPR_BINARY_LOGICAL_OR:
+ case EXPR_BINARY_NOTEQUAL:
+ case EXPR_UNARY_NOT:;
+ jump_target true_target;
+ jump_target false_target;
+ init_jump_target(&true_target, NULL);
+ init_jump_target(&false_target, NULL);
+ expression_to_control_flow(expr, &true_target, &false_target);
+ return control_flow_to_1_0(expr, &true_target, &false_target);
+ } else {
+ return create_cast(&expr->unary);
+ }
+
+ case EXPR_BINARY_ADD:
+ case EXPR_BINARY_BITWISE_AND:
+ case EXPR_BINARY_BITWISE_OR:
+ case EXPR_BINARY_BITWISE_XOR:
+ case EXPR_BINARY_DIV:
+ case EXPR_BINARY_MOD:
+ case EXPR_BINARY_MUL:
+ case EXPR_BINARY_SHIFTLEFT:
+ case EXPR_BINARY_SHIFTRIGHT:
+ case EXPR_BINARY_SUB:
+ return binop_to_firm(&expr->binary);
+
+ case EXPR_BINARY_ADD_ASSIGN:
+ case EXPR_BINARY_BITWISE_AND_ASSIGN:
+ case EXPR_BINARY_BITWISE_OR_ASSIGN:
+ case EXPR_BINARY_BITWISE_XOR_ASSIGN:
+ case EXPR_BINARY_DIV_ASSIGN:
+ case EXPR_BINARY_MOD_ASSIGN:
+ case EXPR_BINARY_MUL_ASSIGN:
+ case EXPR_BINARY_SHIFTLEFT_ASSIGN:
+ case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
+ case EXPR_BINARY_SUB_ASSIGN:
+ return binop_assign_to_firm(&expr->binary);
+
+ {
+ bool inc;
+ bool pre;
+ case EXPR_UNARY_POSTFIX_DECREMENT: inc = false; pre = false; goto incdec;
+ case EXPR_UNARY_POSTFIX_INCREMENT: inc = true; pre = false; goto incdec;
+ case EXPR_UNARY_PREFIX_DECREMENT: inc = false; pre = true; goto incdec;
+ case EXPR_UNARY_PREFIX_INCREMENT: inc = true; pre = true; goto incdec;
+incdec:
+ return incdec_to_firm(&expr->unary, inc, pre);
+ }
+
case EXPR_ALIGNOF: return alignof_to_firm( &expr->typeprop);
case EXPR_ARRAY_ACCESS: return array_access_to_firm( &expr->array_access);
- case EXPR_BINARY_CASES: return binary_expression_to_firm( &expr->binary);
+ case EXPR_BINARY_ASSIGN: return assign_expression_to_firm( &expr->binary);
+ case EXPR_BINARY_COMMA: return comma_expression_to_firm( &expr->binary);
case EXPR_BUILTIN_CONSTANT_P: return builtin_constant_to_firm( &expr->builtin_constant);
case EXPR_BUILTIN_TYPES_COMPATIBLE_P: return builtin_types_compatible_to_firm(&expr->builtin_types_compatible);
case EXPR_CALL: return call_expression_to_firm( &expr->call);
case EXPR_CLASSIFY_TYPE: return classify_type_to_firm( &expr->classify_type);
case EXPR_COMPOUND_LITERAL: return compound_literal_to_firm( &expr->compound_literal);
case EXPR_CONDITIONAL: return conditional_to_firm( &expr->conditional);
+ case EXPR_ENUM_CONSTANT: return enum_constant_to_firm( &expr->reference);
case EXPR_FUNCNAME: return function_name_to_firm( &expr->funcname);
case EXPR_LABEL_ADDRESS: return label_address_to_firm( &expr->label_address);
case EXPR_LITERAL_CASES: return literal_to_firm( &expr->literal);
case EXPR_LITERAL_CHARACTER: return char_literal_to_firm( &expr->string_literal);
case EXPR_OFFSETOF: return offsetof_to_firm( &expr->offsetofe);
case EXPR_REFERENCE: return reference_expression_to_firm( &expr->reference);
- case EXPR_ENUM_CONSTANT: return enum_constant_to_firm( &expr->reference);
case EXPR_SELECT: return select_to_firm( &expr->select);
case EXPR_SIZEOF: return sizeof_to_firm( &expr->typeprop);
case EXPR_STATEMENT: return statement_expression_to_firm( &expr->statement);
- case EXPR_UNARY_CASES: return unary_expression_to_firm( &expr->unary);
+ case EXPR_STRING_LITERAL: return string_to_firm( &expr->base.pos, "str.%u", &expr->string_literal.value);
+ case EXPR_UNARY_ASSUME: return handle_assume( expr->unary.value);
+ case EXPR_UNARY_BITWISE_NEGATE: return complement_to_firm( &expr->unary);
+ case EXPR_UNARY_DEREFERENCE: return dereference_to_firm( &expr->unary);
+ case EXPR_UNARY_NEGATE: return negate_to_firm( &expr->unary);
+ case EXPR_UNARY_PLUS: return expression_to_value( expr->unary.value);
+ case EXPR_UNARY_TAKE_ADDRESS: return expression_to_addr( expr->unary.value);
case EXPR_VA_ARG: return va_arg_expression_to_firm( &expr->va_arge);
case EXPR_VA_COPY: return va_copy_expression_to_firm( &expr->va_copye);
case EXPR_VA_START: return va_start_expression_to_firm( &expr->va_starte);
- case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", &expr->string_literal.value);
+ case EXPR_UNARY_DELETE:
+ case EXPR_UNARY_DELETE_ARRAY:
+ case EXPR_UNARY_THROW:
+ panic("expression not implemented");
- case EXPR_ERROR: break;
+ case EXPR_ERROR:
+ break;
}
panic("invalid expression");
}
-/**
- * Check if a given expression is a GNU __builtin_expect() call.
- */
-static bool is_builtin_expect(const expression_t *expression)
-{
- if (expression->kind != EXPR_CALL)
- return false;
-
- expression_t *function = expression->call.function;
- if (function->kind != EXPR_REFERENCE)
- return false;
- reference_expression_t *ref = &function->reference;
- if (ref->entity->kind != ENTITY_FUNCTION ||
- ref->entity->function.btk != BUILTIN_EXPECT)
- return false;
-
- return true;
-}
-
-static bool produces_mode_b(const expression_t *expression)
-{
- switch (expression->kind) {
- case EXPR_BINARY_EQUAL:
- case EXPR_BINARY_NOTEQUAL:
- case EXPR_BINARY_LESS:
- case EXPR_BINARY_LESSEQUAL:
- case EXPR_BINARY_GREATER:
- case EXPR_BINARY_GREATEREQUAL:
- case EXPR_BINARY_ISGREATER:
- case EXPR_BINARY_ISGREATEREQUAL:
- case EXPR_BINARY_ISLESS:
- case EXPR_BINARY_ISLESSEQUAL:
- case EXPR_BINARY_ISLESSGREATER:
- case EXPR_BINARY_ISUNORDERED:
- case EXPR_UNARY_NOT:
- return true;
-
- case EXPR_CALL:
- if (is_builtin_expect(expression)) {
- expression_t *argument = expression->call.arguments->expression;
- return produces_mode_b(argument);
- }
- return false;
- case EXPR_BINARY_COMMA:
- return produces_mode_b(expression->binary.right);
-
- default:
- return false;
- }
-}
-
-static ir_node *expression_to_firm(const expression_t *expression)
-{
- if (!produces_mode_b(expression)) {
- ir_node *res = _expression_to_firm(expression);
- assert(res == NULL || get_irn_mode(res) != mode_b);
- return res;
- }
-
- if (is_constant_expression(expression) == EXPR_CLASS_CONSTANT) {
- return new_Const(fold_constant_to_tarval(expression));
- }
-
- /* we have to produce a 0/1 from the mode_b expression */
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
- return produce_condition_result(expression, mode, dbgi);
-}
-
/**
* create a short-circuit expression evaluation that tries to construct
* efficient control flow structures for &&, || and ! expressions
*/
-static ir_node *create_condition_evaluation(expression_t const *const expression, jump_target *const true_target, jump_target *const false_target)
+static ir_node *expression_to_control_flow(expression_t const *const expr, jump_target *const true_target, jump_target *const false_target)
{
- switch(expression->kind) {
- case EXPR_UNARY_NOT: {
- const unary_expression_t *unary_expression = &expression->unary;
- create_condition_evaluation(unary_expression->value, false_target, true_target);
+ switch (expr->kind) {
+ case EXPR_UNARY_NOT:
+ expression_to_control_flow(expr->unary.value, false_target, true_target);
return NULL;
- }
+
case EXPR_BINARY_LOGICAL_AND: {
jump_target extra_target;
init_jump_target(&extra_target, NULL);
- create_condition_evaluation(expression->binary.left, &extra_target, false_target);
+ expression_to_control_flow(expr->binary.left, &extra_target, false_target);
if (enter_jump_target(&extra_target))
- create_condition_evaluation(expression->binary.right, true_target, false_target);
+ expression_to_control_flow(expr->binary.right, true_target, false_target);
return NULL;
}
+
case EXPR_BINARY_LOGICAL_OR: {
jump_target extra_target;
init_jump_target(&extra_target, NULL);
- create_condition_evaluation(expression->binary.left, true_target, &extra_target);
+ expression_to_control_flow(expr->binary.left, true_target, &extra_target);
if (enter_jump_target(&extra_target))
- create_condition_evaluation(expression->binary.right, true_target, false_target);
+ expression_to_control_flow(expr->binary.right, true_target, false_target);
return NULL;
}
- default:
- break;
- }
- ir_node *cond_expr = _expression_to_firm(expression);
- if (is_Const(cond_expr)) {
- if (tarval_is_null(get_Const_tarval(cond_expr))) {
- jump_to_target(false_target);
- } else {
- jump_to_target(true_target);
- }
- } else {
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *condition = create_conv(dbgi, cond_expr, mode_b);
- ir_node *cond = new_d_Cond(dbgi, condition);
- ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
- ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
+ case EXPR_BINARY_COMMA:
+ expression_to_value(expr->binary.left);
+ return expression_to_control_flow(expr->binary.right, true_target, false_target);
- /* set branch prediction info based on __builtin_expect */
- if (is_builtin_expect(expression) && is_Cond(cond)) {
- call_argument_t *argument = expression->call.arguments->next;
- if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
- bool const cnst = fold_constant_to_bool(argument->expression);
- cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
- set_Cond_jmp_pred(cond, pred);
- }
+ ir_node *val;
+ ir_node *left;
+ ir_node *right;
+ ir_relation relation;
+ case EXPR_BINARY_EQUAL:
+ case EXPR_BINARY_GREATER:
+ case EXPR_BINARY_GREATEREQUAL:
+ case EXPR_BINARY_ISGREATER:
+ case EXPR_BINARY_ISGREATEREQUAL:
+ case EXPR_BINARY_ISLESS:
+ case EXPR_BINARY_ISLESSEQUAL:
+ case EXPR_BINARY_ISLESSGREATER:
+ case EXPR_BINARY_ISUNORDERED:
+ case EXPR_BINARY_LESS:
+ case EXPR_BINARY_LESSEQUAL:
+ case EXPR_BINARY_NOTEQUAL:
+ val = NULL;
+ left = expression_to_value(expr->binary.left);
+ right = expression_to_value(expr->binary.right);
+ relation = get_relation(expr->kind);
+ goto make_cmp;
+
+ case EXPR_UNARY_CAST:
+ if (is_type_atomic(skip_typeref(expr->base.type), ATOMIC_TYPE_BOOL)) {
+ expression_to_control_flow(expr->unary.value, true_target, false_target);
+ return NULL;
+ } else {
+ default:
+ val = expression_to_value(expr);
+ left = val;
+ right = new_Const(get_mode_null(get_irn_mode(val)));
+ relation = ir_relation_unordered_less_greater;
+make_cmp:
+ compare_to_control_flow(expr, left, right, relation, true_target, false_target);
+ return val;
}
-
- add_pred_to_jump_target(true_target, true_proj);
- add_pred_to_jump_target(false_target, false_proj);
}
- set_unreachable_now();
- return cond_expr;
}
static void create_variable_entity(entity_t *variable,
ident *const id = new_id_from_str(variable->base.symbol->string);
ir_type *const irtype = get_ir_type(type);
- dbg_info *const dbgi = get_dbg_info(&variable->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&variable->base.pos);
ir_entity *const irentity = new_d_entity(parent_type, id, irtype, dbgi);
unsigned alignment = variable->declaration.alignment;
const initializer_value_t *initializer)
{
expression_t *expr = initializer->value;
- type_t *type = expr->base.type;
+ type_t *type = skip_typeref(expr->base.type);
if (is_type_compound(type)) {
if (expr->kind == EXPR_UNARY_CAST) {
expr = expr->unary.value;
- type = expr->base.type;
+ type = skip_typeref(expr->base.type);
}
/* must be a compound literal... */
- if (expr->kind != EXPR_COMPOUND_LITERAL)
- panic("initializer creation for compounds needs compound literals");
- return create_ir_initializer(expr->compound_literal.initializer, type);
+ if (expr->kind == EXPR_COMPOUND_LITERAL) {
+ return create_ir_initializer(expr->compound_literal.initializer,
+ type);
+ }
}
- ir_node *value = expression_to_firm(expr);
- ir_mode *mode = get_ir_mode_storage(type);
- value = create_conv(NULL, value, mode);
+ ir_node *value = expression_to_value(expr);
+ value = conv_to_storage_type(NULL, value, type);
return create_initializer_const(value);
}
-/** test wether type can be initialized by a string constant */
+/** Tests whether type can be initialized by a string constant */
static bool is_string_type(type_t *type)
{
if (!is_type_array(type))
return;
}
- assert(get_type_mode(type) == get_irn_mode(node));
- ir_node *mem = get_store();
- ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none);
- ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
- set_store(proj_m);
+ ir_node *mem = get_store();
+ ir_node *new_mem;
+ if (is_compound_type(ent_type)) {
+ ir_node *copyb = new_d_CopyB(dbgi, mem, base_addr, node, ent_type);
+ new_mem = new_Proj(copyb, mode_M, pn_CopyB_M);
+ } else {
+ assert(get_type_mode(type) == get_irn_mode(node));
+ ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none);
+ new_mem = new_Proj(store, mode_M, pn_Store_M);
+ }
+ set_store(new_mem);
return;
}
case IR_INITIALIZER_TARVAL: {
if (initializer->kind == INITIALIZER_VALUE) {
initializer_value_t *initializer_value = &initializer->value;
- ir_node *value = expression_to_firm(initializer_value->value);
+ ir_node *value = expression_to_value(initializer_value->value);
type = skip_typeref(type);
assign_value(dbgi, addr, type, value);
return;
{
assert(entity->kind == ENTITY_VARIABLE);
initializer_t *initializer = entity->variable.initializer;
- dbg_info *dbgi = get_dbg_info(&entity->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&entity->base.pos);
ir_entity *irentity = entity->variable.v.entity;
type_t *type = entity->declaration.type;
type_t *const init_type = skip_typeref(value->base.type);
if (!is_type_scalar(init_type)) {
- /* skip convs */
- while (value->kind == EXPR_UNARY_CAST)
- value = value->unary.value;
-
if (value->kind != EXPR_COMPOUND_LITERAL)
panic("expected non-scalar initializer to be a compound literal");
initializer = value->compound_literal.initializer;
goto have_initializer;
}
- ir_node * node = expression_to_firm(value);
- dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
- ir_mode *const mode = get_ir_mode_storage(init_type);
- node = create_conv(dbgi, node, mode);
+ ir_node * node = expression_to_value(value);
+ dbg_info *const dbgi = get_dbg_info(&entity->base.pos);
+ node = conv_to_storage_type(dbgi, node, init_type);
if (declaration_kind == DECLARATION_KIND_LOCAL_VARIABLE) {
set_value(entity->variable.v.value_number, node);
assert(entity->variable.initializer == NULL);
assert(currently_reachable());
- dbg_info *dbgi = get_dbg_info(&entity->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&entity->base.pos);
type_t *type = entity->declaration.type;
ir_type *el_type = get_ir_type(type->array.element_type);
ir_type *const var_type = entity->variable.thread_local ?
get_tls_type() : get_glob_type();
ir_type *const irtype = get_ir_type(type);
- dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&entity->base.pos);
size_t l = strlen(entity->base.symbol->string);
char buf[l + sizeof(".%u")];
if (!currently_reachable())
return NULL;
- dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(&statement->base.pos);
type_t *const type = skip_typeref(current_function_entity->declaration.type->function.return_type);
- ir_node * res = statement->value ? expression_to_firm(statement->value) : NULL;
+ ir_node * res = statement->value ? expression_to_value(statement->value) : NULL;
int in_len;
if (!is_type_void(type)) {
- ir_mode *const mode = get_ir_mode_storage(type);
if (res) {
- res = create_conv(dbgi, res, mode);
+ res = conv_to_storage_type(dbgi, res, type);
} else {
- res = new_Unknown(mode);
+ res = new_Unknown(get_ir_mode_storage(type));
}
in_len = 1;
} else {
if (!currently_reachable())
return NULL;
- return expression_to_firm(statement->expression);
+ return expression_to_value(statement->expression);
}
static void create_local_declarations(entity_t*);
init_jump_target(&true_target, NULL);
init_jump_target(&false_target, NULL);
if (currently_reachable())
- create_condition_evaluation(statement->condition, &true_target, &false_target);
+ expression_to_control_flow(statement->condition, &true_target, &false_target);
jump_target exit_target;
init_jump_target(&exit_target, NULL);
statement_to_firm(statement->body);
jump_to_target(&continue_target);
if (enter_jump_target(&continue_target))
- create_condition_evaluation(statement->condition, &body_target, &break_target);
+ expression_to_control_flow(statement->condition, &body_target, &break_target);
enter_jump_target(&body_target);
}
enter_jump_target(&break_target);
}
if (statement->initialisation != NULL) {
- expression_to_firm(statement->initialisation);
+ expression_to_value(statement->initialisation);
}
}
if (cond && (is_constant_expression(cond) != EXPR_CLASS_CONSTANT || !fold_constant_to_bool(cond))) {
jump_target body_target;
init_jump_target(&body_target, NULL);
- create_condition_evaluation(cond, &body_target, &break_target);
+ expression_to_control_flow(cond, &body_target, &break_target);
enter_jump_target(&body_target);
}
/* Create the step code. */
if (step && enter_jump_target(&continue_target)) {
- expression_to_firm(step);
+ expression_to_value(step);
jump_to_target(&header_target);
}
static ir_node *switch_statement_to_firm(switch_statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->base.pos);
ir_node *switch_node = NULL;
if (currently_reachable()) {
- ir_node *expression = expression_to_firm(statement->expression);
+ ir_node *expression = expression_to_value(statement->expression);
ir_switch_table *table = create_switch_table(statement);
unsigned n_outs = (unsigned)ir_switch_table_get_n_entries(table) + 1;
static ir_node *computed_goto_to_firm(computed_goto_statement_t const *const statement)
{
if (currently_reachable()) {
- ir_node *const op = expression_to_firm(statement->expression);
+ ir_node *const op = expression_to_value(statement->expression);
ARR_APP1(ir_node*, ijmp_ops, op);
jump_to_target(&ijmp_target);
set_unreachable_now();
const char *clobber_str = clobber->clobber.begin;
if (!be_is_valid_clobber(clobber_str)) {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"invalid clobber '%s' specified", clobber->clobber);
continue;
}
= be_parse_asm_constraints(constraints);
{
- source_position_t const *const pos = &statement->base.source_position;
+ position_t const *const pos = &statement->base.pos;
if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
warningf(WARN_OTHER, pos, "some constraints in '%s' are not supported", constraints);
}
++in_size;
continue;
} else {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"only modifiers but no place set in constraints '%s'",
constraints);
continue;
= be_parse_asm_constraints(constraints);
if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"some constraints in '%s' are not supported", constraints);
continue;
}
if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"some constraints in '%s' are invalid", constraints);
continue;
}
if (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE) {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"write flag specified for input constraints '%s'",
constraints);
continue;
if ( (asm_flags & ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE)
|| (asm_flags & ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER) ) {
/* we can treat this as "normal" input */
- input = expression_to_firm(argument->expression);
+ input = expression_to_value(argument->expression);
} else if (asm_flags & ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP) {
/* pure memory ops need no input (but we have to make sure we
* attach to the memory) */
needs_memory = true;
input = expression_to_addr(argument->expression);
} else {
- errorf(&statement->base.source_position,
+ errorf(&statement->base.pos,
"only modifiers but no place set in constraints '%s'",
constraints);
continue;
ir_asm_constraint *input_constraints = obstack_finish(&asm_obst);
/* create asm node */
- dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->base.pos);
ident *asm_text = new_id_from_str(statement->asm_text.begin);
static ir_node *ms_try_statement_to_firm(ms_try_statement_t *statement)
{
statement_to_firm(statement->try_statement);
- source_position_t const *const pos = &statement->base.source_position;
+ position_t const *const pos = &statement->base.pos;
warningf(WARN_OTHER, pos, "structured exception handling ignored");
return NULL;
}
static ir_node *leave_statement_to_firm(leave_statement_t *statement)
{
- errorf(&statement->base.source_position, "__leave not supported yet");
+ errorf(&statement->base.pos, "__leave not supported yet");
return NULL;
}
assert(parameter->declaration.kind == DECLARATION_KIND_UNKNOWN);
type_t *type = skip_typeref(parameter->declaration.type);
- dbg_info *const dbgi = get_dbg_info(¶meter->base.source_position);
+ dbg_info *const dbgi = get_dbg_info(¶meter->base.pos);
ir_type *const param_irtype = get_method_param_type(function_irtype, n);
if (var_needs_entity(¶meter->variable)) {
ir_type *frame_type = get_irg_frame_type(irg);
ir_mode *param_mode = get_type_mode(param_irtype);
long pn = n;
ir_node *value = new_rd_Proj(dbgi, args, param_mode, pn);
-
- ir_mode *mode = get_ir_mode_storage(type);
- value = create_conv(NULL, value, mode);
+ value = conv_to_storage_type(dbgi, value, type);
parameter->declaration.kind = DECLARATION_KIND_PARAMETER;
parameter->variable.v.value_number = next_value_number_function;
current_vararg_entity = NULL;
set_irg_fp_model(irg, firm_fp_model);
- tarval_enable_fp_ops(1);
set_irn_dbg_info(get_irg_start_block(irg),
get_entity_dbg_info(function_entity));