}
}
+static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node,
+ type_t *from_type, type_t *type)
+{
+ type = skip_typeref(type);
+ 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);
+ /* 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;
+ const variable_t *to_var = type->pointer.base_variable;
+ if (from_var != to_var) {
+ if (from_var != NULL) {
+ ir_node *const addr = get_global_var_address(dbgi, from_var);
+ ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
+ value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
+ }
+ if (to_var != NULL) {
+ ir_node *const addr = get_global_var_address(dbgi, to_var);
+ ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
+ value_node = new_d_Sub(dbgi, value_node, 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);
+ node = do_strict_conv(dbgi, node);
+ node = create_conv(dbgi, node, mode_arith);
+
+ return node;
+}
+
static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
{
dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
case EXPR_UNARY_PREFIX_INCREMENT:
case EXPR_UNARY_PREFIX_DECREMENT:
return create_incdec(expression);
+ case EXPR_UNARY_CAST_IMPLICIT:
case EXPR_UNARY_CAST: {
ir_node *value_node = expression_to_firm(value);
- if (is_type_scalar(type)) {
- ir_mode *mode = get_ir_mode_storage(type);
- type_t *from_type = skip_typeref(value->base.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;
- const variable_t *to_var = type->pointer.base_variable;
- if (from_var != to_var) {
- if (from_var != NULL) {
- ir_node *const addr = get_global_var_address(dbgi, from_var);
- ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
- value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
- }
- if (to_var != NULL) {
- ir_node *const addr = get_global_var_address(dbgi, to_var);
- ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
- value_node = new_d_Sub(dbgi, value_node, base, mode);
- }
- }
- }
- ir_node *node = create_conv(dbgi, value_node, mode);
- node = do_strict_conv(dbgi, node);
- ir_mode *mode_arith = get_ir_mode_arithmetic(type);
- node = create_conv(dbgi, node, mode_arith);
- return node;
- } else {
- /* make sure firm type is constructed */
- (void) get_ir_type(type);
- return value_node;
- }
- }
- case EXPR_UNARY_CAST_IMPLICIT: {
- ir_node *value_node = expression_to_firm(value);
- if (is_type_scalar(type)) {
- ir_mode *mode = get_ir_mode_storage(type);
- ir_node *res = create_conv(dbgi, value_node, mode);
- ir_mode *mode_arith = get_ir_mode_arithmetic(type);
- res = create_conv(dbgi, res, mode_arith);
- return res;
- } else {
- return value_node;
- }
+ type_t *from_type = value->base.type;
+ return create_cast(dbgi, value_node, from_type, type);
}
case EXPR_UNARY_ASSUME:
if (firm_opt.confirm)
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_mode *left_mode = get_ir_mode_storage(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);
- result = create_conv(dbgi, result, left_mode);
+ result = create_cast(dbgi, result, expression->right->base.type, type);
result = do_strict_conv(dbgi, result);
result = set_value_for_expression_addr(left_expr, result, left_addr);
* Pointer to a label. This is used for the
* GNU address-of-label extension.
*/
-static ir_node *label_address_to_firm(
- const label_address_expression_t *label)
+static ir_node *label_address_to_firm(const label_address_expression_t *label)
{
- ir_node *block = get_label_block(label->label);
- ir_label_t nr = get_Block_label(block);
+ dbg_info *dbgi = get_dbg_info(&label->base.source_position);
+ ir_node *block = get_label_block(label->label);
+ ir_entity *entity = create_Block_entity(block);
- if (nr == 0) {
- nr = get_irp_next_label_nr();
- set_Block_label(block, nr);
- }
symconst_symbol value;
- value.label = nr;
- return new_SymConst(mode_P_code, value, symconst_label);
+ value.entity_p = entity;
+ return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
}
/**
static void switch_statement_to_firm(switch_statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+ ir_node *first_block = NULL;
+ dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+ ir_node *cond = NULL;
- ir_node *expression = expression_to_firm(statement->expression);
- ir_node *cond = new_d_Cond(dbgi, expression);
+ if (get_cur_block() != NULL) {
+ ir_node *expression = expression_to_firm(statement->expression);
+ cond = new_d_Cond(dbgi, expression);
+ first_block = get_cur_block();
+ }
set_cur_block(NULL);
add_immBlock_pred(get_break_label(), jmp);
}
- if (!saw_default_label) {
- set_cur_block(get_nodes_block(cond));
+ if (!saw_default_label && first_block != NULL) {
+ set_cur_block(first_block);
ir_node *const proj = new_d_defaultProj(dbgi, cond,
statement->default_proj_nr);
add_immBlock_pred(get_break_label(), proj);
ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
ir_node *proj;
- ir_node *block = new_immBlock();
-
- set_cur_block(get_nodes_block(current_switch_cond));
- if (statement->expression != NULL) {
- long pn = statement->first_case;
- long end_pn = statement->last_case;
- assert(pn <= end_pn);
- /* create jumps for all cases in the given range */
- do {
- proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
- add_immBlock_pred(block, proj);
- } while (pn++ < end_pn);
- } else {
- saw_default_label = true;
- proj = new_d_defaultProj(dbgi, current_switch_cond,
- current_switch->default_proj_nr);
+ ir_node *block = new_immBlock();
- add_immBlock_pred(block, proj);
+ if (current_switch_cond != NULL) {
+ set_cur_block(get_nodes_block(current_switch_cond));
+ if (statement->expression != NULL) {
+ long pn = statement->first_case;
+ long end_pn = statement->last_case;
+ assert(pn <= end_pn);
+ /* create jumps for all cases in the given range */
+ do {
+ proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
+ add_immBlock_pred(block, proj);
+ } while (pn++ < end_pn);
+ } else {
+ saw_default_label = true;
+ proj = new_d_defaultProj(dbgi, current_switch_cond,
+ current_switch->default_proj_nr);
+
+ add_immBlock_pred(block, proj);
+ }
}
if (fallthrough != NULL) {
char buf[64];
ir_node *value = get_value_from_lvalue(expr, addr);
- snprintf(buf, sizeof(buf), "%u", pos);
+ snprintf(buf, sizeof(buf), "%u", (unsigned) out_size);
ir_asm_constraint constraint;
constraint.pos = pos;
if (entity->function.need_closure) {
/* add an extra parameter for the static link */
- entity->function.static_link = new_r_Proj(irg, start_block, args, mode_P_data, 0);
+ entity->function.static_link = new_r_Proj(start_block, args, mode_P_data, 0);
++first_param_nr;
}
ir_mode *param_mode = get_type_mode(param_irtype);
long pn = n + first_param_nr;
- ir_node *value = new_r_Proj(irg, start_block, args, param_mode, pn);
+ ir_node *value = new_r_Proj(start_block, args, param_mode, pn);
ir_mode *mode = get_ir_mode_storage(type);
value = create_conv(NULL, value, mode);
(void)get_function_entity(entity, NULL);
} else if (entity->kind == ENTITY_VARIABLE) {
create_global_variable(entity);
+ } else if (entity->kind == ENTITY_NAMESPACE) {
+ scope_to_firm(&entity->namespacee.members);
}
}