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_modeb(const expression_t *expression);
static dbg_info *get_dbg_info(const source_position_t *pos)
{
static ir_node *create_lazy_op(const binary_expression_t *expression)
{
+ dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
+
bool is_or = (expression->type == BINEXPR_LOGICAL_OR);
assert(is_or || expression->type == BINEXPR_LOGICAL_AND);
- dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
- ir_node *val1 = expression_to_firm(expression->left);
- val1 = create_conv(dbgi, val1, mode_b);
-
- ir_node *cond = new_d_Cond(dbgi, val1);
- 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);
+ ir_node *val1 = expression_to_modeb(expression->left);
+ ir_node *cond = new_d_Cond(dbgi, val1);
+ 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);
ir_node *fallthrough_block = new_immBlock();
mature_immBlock(calc_val2_block);
- ir_node *val2 = expression_to_firm(expression->right);
- val2 = create_conv(dbgi, val2, mode_b);
+ ir_node *val2 = expression_to_modeb(expression->right);
if(get_cur_block() != NULL) {
ir_node *jmp = new_d_Jmp(dbgi);
add_immBlock_pred(fallthrough_block, jmp);
dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
ir_node *left = expression_to_firm(expression->left);
ir_node *right = expression_to_firm(expression->right);
- type_t *type = expression->expression.datatype;
+ type_t *type = expression->right->datatype;
+ /* be careful with the modes, because in asithmetic assign nodes only
+ * the right operand has the mode of the arithmetic alread */
ir_mode *mode = get_ir_mode(type);
+ left = create_conv(dbgi, left, mode);
ir_node *res = func(dbgi, left, right, mode);
return res;
}
+static ir_node *create_arithmetic_assign_binop(
+ const binary_expression_t *expression, create_arithmetic_func func)
+{
+ dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
+ ir_node *value = create_arithmetic_binop(expression, func);
+ type_t *type = expression->expression.datatype;
+ ir_mode *mode = get_ir_mode(type);
+
+ assert(type->type != TYPE_POINTER);
+
+ value = create_conv(dbgi, value, mode);
+ set_value_for_expression(expression->left, value);
+
+ return value;
+}
+
static ir_node *create_add(const binary_expression_t *expression)
{
dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
assert(elem_size >= 1);
if(elem_size > 1) {
- ir_node *cnst = new_Const_long(mode_Iu, elem_size);
- ir_node *mul = new_d_Mul(dbgi, integer, cnst, mode_Iu);
+ integer = create_conv(dbgi, integer, mode_Is);
+ ir_node *cnst = new_Const_long(mode_Is, (int) elem_size);
+ ir_node *mul = new_d_Mul(dbgi, integer, cnst, mode_Is);
integer = mul;
}
return res;
}
+static ir_node *create_divmod(const binary_expression_t *expression)
+{
+ dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
+ ir_node *left = expression_to_firm(expression->left);
+ ir_node *right = expression_to_firm(expression->right);
+ ir_node *pin = new_Pin(new_NoMem());
+ type_t *type = expression->expression.datatype;
+ ir_mode *mode = get_ir_mode(type);
+ ir_node *op;
+ ir_node *res;
+
+ if(expression->type == BINEXPR_DIV) {
+ if(mode_is_float(mode)) {
+ op = new_d_Quot(dbgi, pin, left, right, mode, op_pin_state_floats);
+ res = new_d_Proj(dbgi, op, mode, pn_Quot_res);
+ } else {
+ op = new_d_Div(dbgi, pin, left, right, mode, op_pin_state_floats);
+ res = new_d_Proj(dbgi, op, mode, pn_Div_res);
+ }
+ } else {
+ assert(expression->type == BINEXPR_MOD);
+ assert(!mode_is_float(mode));
+ op = new_d_Mod(dbgi, pin, left, right, mode, op_pin_state_floats);
+ res = new_d_Proj(dbgi, op, mode, pn_Mod_res);
+ }
+
+ return res;
+}
+
static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
return create_arithmetic_binop(expression, new_d_Shl);
case BINEXPR_SHIFTRIGHT:
return create_arithmetic_binop(expression, new_d_Shr);
+ case BINEXPR_DIV:
+ case BINEXPR_MOD:
+ return create_divmod(expression);
case BINEXPR_LOGICAL_AND:
case BINEXPR_LOGICAL_OR:
return create_lazy_op(expression);
+ case BINEXPR_COMMA:
+ expression_to_firm(expression->left);
+ return expression_to_firm(expression->right);
+ case BINEXPR_ADD_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Add);
+ case BINEXPR_SUB_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Sub);
+ case BINEXPR_MUL_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Mul);
+ case BINEXPR_BITWISE_AND_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_And);
+ case BINEXPR_BITWISE_OR_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Or);
+ case BINEXPR_BITWISE_XOR_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Eor);
+ case BINEXPR_SHIFTLEFT_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Shl);
+ case BINEXPR_SHIFTRIGHT_ASSIGN:
+ return create_arithmetic_assign_binop(expression, new_d_Shr);
default:
panic("TODO binexpr type");
}
return size_node;
}
+static ir_node *conditional_to_firm(const conditional_expression_t *expression)
+{
+ dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
+
+ ir_node *condition = expression_to_modeb(expression->condition);
+ 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);
+
+ /* create the true block */
+ ir_node *true_block = new_immBlock();
+ add_immBlock_pred(true_block, true_proj);
+ mature_immBlock(true_block);
+
+ ir_node *true_val = expression_to_firm(expression->true_expression);
+ ir_node *true_jmp = new_Jmp();
+
+ /* create the false block */
+ ir_node *false_block = new_immBlock();
+ add_immBlock_pred(false_block, false_proj);
+ mature_immBlock(false_block);
+
+ ir_node *false_val = expression_to_firm(expression->false_expression);
+ ir_node *false_jmp = new_Jmp();
+
+ /* create the common block */
+ ir_node *common_block = new_immBlock();
+ add_immBlock_pred(common_block, true_jmp);
+ add_immBlock_pred(common_block, false_jmp);
+ mature_immBlock(common_block);
+
+ ir_node *in[2] = { true_val, false_val };
+ ir_mode *mode = get_irn_mode(true_val);
+ assert(get_irn_mode(false_val) == mode);
+ ir_node *val = new_d_Phi(dbgi, 2, in, mode);
+
+ return val;
+}
+
static ir_node *expression_to_addr(const expression_t *expression)
{
switch(expression->type) {
(const array_access_expression_t*) expression);
case EXPR_SIZEOF:
return sizeof_to_firm((const sizeof_expression_t*) expression);
+ case EXPR_CONDITIONAL:
+ return conditional_to_firm((const conditional_expression_t*)expression);
default:
break;
}
return res;
}
+static ir_node *expression_to_modeb(const expression_t *expression)
+{
+ ir_node *res = _expression_to_firm(expression);
+ res = create_conv(NULL, res, mode_b);
+
+ return res;
+}
static void statement_to_firm(statement_t *statement);
static void if_statement_to_firm(if_statement_t *statement)
{
dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
- ir_node *condition = _expression_to_firm(statement->condition);
- assert(condition != NULL);
+ ir_node *condition = expression_to_modeb(statement->condition);
/* make sure we have a mode_b condition */
- condition = create_conv(dbgi, condition, 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);
}
/* create the condition */
- ir_node *condition = _expression_to_firm(statement->condition);
- condition = create_conv(dbgi, condition, mode_b);
-
+ ir_node *condition = expression_to_modeb(statement->condition);
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);
mature_immBlock(header_block);
/* create the condition */
- ir_node *condition = _expression_to_firm(statement->condition);
- condition = create_conv(dbgi, condition, mode_b);
-
+ ir_node *condition = expression_to_modeb(statement->condition);
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);
/* create the step block */
ir_node *const step_block = new_immBlock();
- expression_to_firm(statement->step);
+ if (statement->step != NULL) {
+ expression_to_firm(statement->step);
+ }
ir_node *const step_jmp = new_Jmp();
/* create the header block */
add_immBlock_pred(header_block, step_jmp);
/* create the condition */
- ir_node *const cond_expr = _expression_to_firm(statement->condition);
- ir_node *const condition = create_conv(dbgi, cond_expr, mode_b);
-
- ir_node *const cond = new_d_Cond(dbgi, condition);
- 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);
+ ir_node *true_proj;
+ ir_node *false_proj;
+ if (statement->condition != NULL) {
+ ir_node *const condition = expression_to_modeb(statement->condition);
+ ir_node *const cond = new_d_Cond(dbgi, condition);
+ true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
+ false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
+ } else {
+ keep_alive(header_block);
+ true_proj = new_Jmp();
+ false_proj = NULL;
+ }
/* the false block */
ir_node *const false_block = new_immBlock();
- add_immBlock_pred(false_block, false_proj);
+ if (false_proj != NULL) {
+ add_immBlock_pred(false_block, false_proj);
+ }
/* the loop body */
ir_node *const body_block = new_immBlock();
if(declaration->declaration_type == DECLARATION_TYPE_LOCAL_VARIABLE) {
set_value(declaration->v.value_number, init_node);
} else {
- panic("initializer not completely implemented yet");
+ ir_entity *entity = declaration->v.entity;
+
+ set_entity_variability(entity, variability_initialized);
+ set_atomic_ent_value(entity, init_node);
}
} else {
assert(initializer->type == INITIALIZER_LIST);
} else {
set_entity_visibility(entity, visibility_external_visible);
}
+ current_ir_graph = get_const_code_irg();
+ create_initializer(declaration);
}
static void context_to_firm(context_t *context)
if(declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY
|| declaration->storage_class == STORAGE_CLASS_TYPEDEF)
continue;
+ if(declaration->symbol == NULL)
+ continue;
type_t *type = declaration->type;
if(type->type == TYPE_FUNCTION) {