X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=9e27b840191d8cf97c9fbae4889ff784a783f632;hb=3b491a136d937af49b07f0d46ad0022c37506ecb;hp=ebe39574fd77b41fd0414c7e3742b0dcf2ac47d1;hpb=bfe76ff46dbc10738f330e87edc21f6b55875a20;p=cparser diff --git a/ast2firm.c b/ast2firm.c index ebe3957..9e27b84 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -41,13 +41,6 @@ typedef enum declaration_type_t { DECLARATION_TYPE_COMPOUND_MEMBER } declaration_type_t; -typedef struct type2firm_env_t type2firm_env_t; -struct type2firm_env_t { - int can_cache; /* nonzero if type can safely be cached because - no typevariables are in the hierarchy */ -}; - -static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type); static ir_type *get_ir_type(type_t *type); ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos) @@ -114,33 +107,6 @@ static ident *unique_ident(const char *tag) return new_id_from_str(buf); } -static type_t *skip_typeref(type_t *type) -{ - while(1) { - switch(type->type) { - case TYPE_TYPEDEF: { - const typedef_type_t *typedef_type = (const typedef_type_t*) type; - type = typedef_type->declaration->type; - continue; - } - case TYPE_TYPEOF: { - const typeof_type_t *typeof_type = (const typeof_type_t *) type; - if(typeof_type->typeof_type != NULL) { - type = typeof_type->typeof_type; - } else { - type = typeof_type->expression->datatype; - } - continue; - } - default: - break; - } - break; - } - - return type; -} - static ir_mode *get_atomic_mode(const atomic_type_t* atomic_type) { switch(atomic_type->atype) { @@ -184,8 +150,8 @@ static ir_mode *get_atomic_mode(const atomic_type_t* atomic_type) break; #endif case ATOMIC_TYPE_VOID: - panic("tried to get mode from void type"); - break; + /* firm has no real void... */ + return mode_Is; case ATOMIC_TYPE_INVALID: break; } @@ -287,10 +253,8 @@ static unsigned count_parameters(const function_type_t *function_type) -static ir_type *create_atomic_type(type2firm_env_t *env, - const atomic_type_t *type) +static ir_type *create_atomic_type(const atomic_type_t *type) { - (void) env; ir_mode *mode = get_atomic_mode(type); ident *id = get_mode_ident(mode); ir_type *irtype = new_type_primitive(id, mode); @@ -298,8 +262,7 @@ static ir_type *create_atomic_type(type2firm_env_t *env, return irtype; } -static ir_type *create_method_type(type2firm_env_t *env, - const function_type_t *function_type) +static ir_type *create_method_type(const function_type_t *function_type) { type_t *result_type = function_type->result_type; @@ -309,26 +272,26 @@ static ir_type *create_method_type(type2firm_env_t *env, ir_type *irtype = new_type_method(id, n_parameters, n_results); if(result_type != type_void) { - ir_type *restype = _get_ir_type(env, result_type); + ir_type *restype = get_ir_type(result_type); set_method_res_type(irtype, 0, restype); } function_parameter_t *parameter = function_type->parameters; int n = 0; for( ; parameter != NULL; parameter = parameter->next) { - ir_type *p_irtype = _get_ir_type(env, parameter->type); + ir_type *p_irtype = get_ir_type(parameter->type); set_method_param_type(irtype, n, p_irtype); ++n; } - if(function_type->variadic) { + if(function_type->variadic || function_type->unspecified_parameters) { set_method_variadicity(irtype, variadicity_variadic); } return irtype; } -static ir_type *create_pointer_type(type2firm_env_t *env, pointer_type_t *type) +static ir_type *create_pointer_type(pointer_type_t *type) { type_t *points_to = type->points_to; ir_type *ir_points_to; @@ -340,16 +303,16 @@ static ir_type *create_pointer_type(type2firm_env_t *env, pointer_type_t *type) ir_type_void, mode_P_data); type->type.firm_type = ir_type; - ir_points_to = _get_ir_type(env, points_to); + ir_points_to = get_ir_type(points_to); set_pointer_points_to_type(ir_type, ir_points_to); return ir_type; } -static ir_type *create_array_type(type2firm_env_t *env, array_type_t *type) +static ir_type *create_array_type(array_type_t *type) { type_t *element_type = type->element_type; - ir_type *ir_element_type = _get_ir_type(env, element_type); + ir_type *ir_element_type = get_ir_type(element_type); /* TODO... */ int n_elements = 0; @@ -372,7 +335,7 @@ static ir_type *create_array_type(type2firm_env_t *env, array_type_t *type) #define INVALID_TYPE ((ir_type_ptr)-1) -static ir_type *create_struct_type(type2firm_env_t *env, compound_type_t *type) +static ir_type *create_struct_type(compound_type_t *type) { symbol_t *symbol = type->declaration->symbol; ident *id; @@ -389,8 +352,11 @@ static ir_type *create_struct_type(type2firm_env_t *env, compound_type_t *type) int offset = 0; declaration_t *entry = type->declaration->context.declarations; for( ; entry != NULL; entry = entry->next) { + if(entry->namespace != NAMESPACE_NORMAL) + continue; + ident *ident = new_id_from_str(entry->symbol->string); - ir_type_ptr entry_ir_type = _get_ir_type(env, entry->type); + ir_type_ptr entry_ir_type = get_ir_type(entry->type); int entry_size = get_type_size_bytes(entry_ir_type); int entry_alignment = get_type_alignment_bytes(entry_ir_type); @@ -421,7 +387,7 @@ static ir_type *create_struct_type(type2firm_env_t *env, compound_type_t *type) return ir_type; } -static ir_type *create_union_type(type2firm_env_t *env, compound_type_t *type) +static ir_type *create_union_type(compound_type_t *type) { declaration_t *declaration = type->declaration; symbol_t *symbol = declaration->symbol; @@ -439,8 +405,11 @@ static ir_type *create_union_type(type2firm_env_t *env, compound_type_t *type) int size = 0; declaration_t *entry = declaration->context.declarations; for( ; entry != NULL; entry = entry->next) { + if(entry->namespace != NAMESPACE_NORMAL) + continue; + ident *ident = new_id_from_str(entry->symbol->string); - ir_type_ptr entry_ir_type = _get_ir_type(env, entry->type); + ir_type_ptr entry_ir_type = get_ir_type(entry->type); int entry_size = get_type_size_bytes(entry_ir_type); int entry_alignment = get_type_alignment_bytes(entry_ir_type); @@ -469,7 +438,7 @@ static ir_type *create_union_type(type2firm_env_t *env, compound_type_t *type) return ir_type; } -static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type) +static ir_type *get_ir_type(type_t *type) { assert(type != NULL); @@ -483,22 +452,22 @@ static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type) ir_type *firm_type = NULL; switch(type->type) { case TYPE_ATOMIC: - firm_type = create_atomic_type(env, (atomic_type_t*) type); + firm_type = create_atomic_type((atomic_type_t*) type); break; case TYPE_FUNCTION: - firm_type = create_method_type(env, (function_type_t*) type); + firm_type = create_method_type((function_type_t*) type); break; case TYPE_POINTER: - firm_type = create_pointer_type(env, (pointer_type_t*) type); + firm_type = create_pointer_type((pointer_type_t*) type); break; case TYPE_ARRAY: - firm_type = create_array_type(env, (array_type_t*) type); + firm_type = create_array_type((array_type_t*) type); break; case TYPE_COMPOUND_STRUCT: - firm_type = create_struct_type(env, (compound_type_t*) type); + firm_type = create_struct_type((compound_type_t*) type); break; case TYPE_COMPOUND_UNION: - firm_type = create_union_type(env, (compound_type_t*) type); + firm_type = create_union_type((compound_type_t*) type); break; case TYPE_ENUM: firm_type = ir_type_int; @@ -512,19 +481,8 @@ static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type) if(firm_type == NULL) panic("unknown type found"); - if(env->can_cache) { - type->firm_type = firm_type; - } + type->firm_type = firm_type; return firm_type; - -} - -static ir_type *get_ir_type(type_t *type) -{ - type2firm_env_t env; - env.can_cache = 1; - - return _get_ir_type(&env, type); } static inline ir_mode *get_ir_mode(type_t *type) @@ -569,7 +527,7 @@ static ir_entity* get_function_entity(declaration_t *declaration) 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) { @@ -634,6 +592,19 @@ static ir_node *string_literal_to_firm(const string_literal_t* literal) return create_symconst(dbgi, entity); } +static ir_node *load_from_expression_addr(type_t *type, ir_node *addr, + dbg_info *dbgi) +{ + ir_mode *mode = get_ir_mode(type); + ir_node *memory = get_store(); + ir_node *load = new_d_Load(dbgi, memory, addr, mode); + ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); + ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); + set_store(load_mem); + + return load_res; +} + static ir_node *reference_expression_to_firm(const reference_expression_t *ref) { dbg_info *dbgi = get_dbg_info(&ref->expression.source_position); @@ -649,8 +620,38 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref) case DECLARATION_TYPE_FUNCTION: { return create_symconst(dbgi, declaration->v.entity); } + case DECLARATION_TYPE_GLOBAL_VARIABLE: { + ir_entity *entity = declaration->v.entity; + ir_node *symconst = create_symconst(dbgi, entity); + return load_from_expression_addr(type, symconst, dbgi); + } + case DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY: + case DECLARATION_TYPE_COMPOUND_MEMBER: + panic("not implemented reference type"); + } + + panic("reference to declaration with unknown type found"); +} + +static ir_node *reference_addr(const reference_expression_t *ref) +{ + dbg_info *dbgi = get_dbg_info(&ref->expression.source_position); + declaration_t *declaration = ref->declaration; + + switch((declaration_type_t) declaration->declaration_type) { + case DECLARATION_TYPE_UNKNOWN: + break; + case DECLARATION_TYPE_LOCAL_VARIABLE: + panic("local variable without entity has no address"); + case DECLARATION_TYPE_FUNCTION: { + return create_symconst(dbgi, declaration->v.entity); + } + case DECLARATION_TYPE_GLOBAL_VARIABLE: { + ir_entity *entity = declaration->v.entity; + ir_node *symconst = create_symconst(dbgi, entity); + return symconst; + } case DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY: - case DECLARATION_TYPE_GLOBAL_VARIABLE: case DECLARATION_TYPE_COMPOUND_MEMBER: panic("not implemented reference type"); } @@ -676,7 +677,7 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) ir_type *ir_method_type = get_ir_type((type_t*) function_type); ir_type *new_method_type = NULL; - if(function_type->variadic) { + if(function_type->variadic || function_type->unspecified_parameters) { /* we need to construct a new method type matching the call * arguments... */ int n_res = get_method_n_ress(ir_method_type); @@ -731,19 +732,6 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) return result; } -static ir_node *load_from_expression_addr(type_t *type, ir_node *addr, - dbg_info *dbgi) -{ - ir_mode *mode = get_ir_mode(type); - ir_node *memory = get_store(); - ir_node *load = new_d_Load(dbgi, memory, addr, mode); - ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); - ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); - set_store(load_mem); - - return load_res; -} - static ir_node *expression_to_addr(const expression_t *expression); static void set_value_for_expression(const expression_t *expression, @@ -867,16 +855,15 @@ static long get_pnc(binary_expression_type_t type) 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(); @@ -890,8 +877,7 @@ static ir_node *create_lazy_op(const binary_expression_t *expression) 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); @@ -921,20 +907,153 @@ typedef ir_node * (*create_arithmetic_func)(dbg_info *dbgi, ir_node *left, static ir_node *create_arithmetic_binop(const binary_expression_t *expression, create_arithmetic_func func) +{ + 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->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); ir_node *left = expression_to_firm(expression->left); ir_node *right = expression_to_firm(expression->right); type_t *type = expression->expression.datatype; ir_mode *mode = get_ir_mode(type); - /* TODO FIXME Hack for now */ - right = create_conv(dbgi, right, get_irn_mode(left)); - ir_node *res = func(dbgi, left, right, mode); + expression_t *expr_left = expression->left; + expression_t *expr_right = expression->right; + type_t *type_left = skip_typeref(expr_left->datatype); + type_t *type_right = skip_typeref(expr_right->datatype); + + if(is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) { + return new_d_Add(dbgi, left, right, mode); + } + + ir_node *pointer; + ir_node *integer; + pointer_type_t *pointer_type; + if(type_left->type == TYPE_POINTER) { + pointer = left; + integer = right; + pointer_type = (pointer_type_t*) type_left; + } else { + assert(type_right->type == TYPE_POINTER); + pointer = right; + integer = left; + pointer_type = (pointer_type_t*) type_right; + } + + type_t *points_to = pointer_type->points_to; + unsigned elem_size = get_type_size(points_to); + + assert(elem_size >= 1); + if(elem_size > 1) { + 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; + } + + ir_node *res = new_d_Add(dbgi, pointer, integer, mode); + + return res; +} + +static ir_node *create_sub(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); + type_t *type = expression->expression.datatype; + ir_mode *mode = get_ir_mode(type); + + expression_t *expr_left = expression->left; + expression_t *expr_right = expression->right; + type_t *type_left = skip_typeref(expr_left->datatype); + type_t *type_right = skip_typeref(expr_right->datatype); + + if((is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) + || (type_left->type == TYPE_POINTER + && type_right->type == TYPE_POINTER)) { + return new_d_Sub(dbgi, left, right, mode); + } + + assert(type_right->type == TYPE_POINTER); + ir_node *pointer = left; + ir_node *integer = right; + pointer_type_t *pointer_type = (pointer_type_t*) type_right; + + type_t *points_to = pointer_type->points_to; + unsigned elem_size = get_type_size(points_to); + + 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 = mul; + } + + ir_node *res = new_d_Sub(dbgi, pointer, integer, mode); 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) { binary_expression_type_t type = expression->type; @@ -959,9 +1078,9 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression) return right; } case BINEXPR_ADD: - return create_arithmetic_binop(expression, new_d_Add); + return create_add(expression); case BINEXPR_SUB: - return create_arithmetic_binop(expression, new_d_Sub); + return create_sub(expression); case BINEXPR_MUL: return create_arithmetic_binop(expression, new_d_Mul); case BINEXPR_BITWISE_AND: @@ -974,9 +1093,31 @@ 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"); } @@ -1025,9 +1166,50 @@ static ir_node *sizeof_to_firm(const sizeof_expression_t *expression) 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) { + case EXPR_REFERENCE: + return reference_addr((const reference_expression_t*) expression); case EXPR_ARRAY_ACCESS: return array_access_addr((const array_access_expression_t*) expression); default: @@ -1058,6 +1240,8 @@ static ir_node *_expression_to_firm(const expression_t *expression) (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; } @@ -1076,6 +1260,13 @@ static ir_node *expression_to_firm(const expression_t *expression) 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); @@ -1116,12 +1307,9 @@ static void expression_statement_to_firm(expression_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); @@ -1174,9 +1362,7 @@ static void while_statement_to_firm(while_statement_t *statement) } /* 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); @@ -1257,9 +1443,7 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) 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); @@ -1273,6 +1457,71 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) set_cur_block(false_block); } +static void for_statement_to_firm(for_statement_t *statement) +{ + dbg_info *const dbgi = get_dbg_info(&statement->statement.source_position); + + ir_node *jmp = NULL; + if (get_cur_block() != NULL) { + if(statement->initialisation != NULL) { + expression_to_firm(statement->initialisation); + } + jmp = new_Jmp(); + } + + /* create the step block */ + ir_node *const step_block = new_immBlock(); + if (statement->step != NULL) { + expression_to_firm(statement->step); + } + ir_node *const step_jmp = new_Jmp(); + + /* create the header block */ + ir_node *const header_block = new_immBlock(); + if (jmp != NULL) { + add_immBlock_pred(header_block, jmp); + } + add_immBlock_pred(header_block, step_jmp); + + /* create the condition */ + ir_node *const condition = expression_to_modeb(statement->condition); + 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); + + /* the false block */ + ir_node *const false_block = new_immBlock(); + add_immBlock_pred(false_block, false_proj); + + /* the loop body */ + ir_node *const body_block = new_immBlock(); + add_immBlock_pred(body_block, true_proj); + mature_immBlock(body_block); + + ir_node *const old_continue_label = continue_label; + ir_node *const old_break_label = break_label; + continue_label = step_block; + break_label = false_block; + + statement_to_firm(statement->body); + + assert(continue_label == step_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; + + if (get_cur_block() != NULL) { + ir_node *const jmp = new_Jmp(); + add_immBlock_pred(step_block, jmp); + } + + mature_immBlock(step_block); + mature_immBlock(header_block); + mature_immBlock(false_block); + + set_cur_block(false_block); +} + static void create_declaration_entity(declaration_t *declaration, declaration_type_t declaration_type, ir_type *parent_type) @@ -1302,7 +1551,10 @@ static void create_initializer(declaration_t *declaration) 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); @@ -1471,6 +1723,9 @@ static void statement_to_firm(statement_t *statement) case STATEMENT_CASE_LABEL: case_label_to_firm((case_label_statement_t*) statement); return; + case STATEMENT_FOR: + for_statement_to_firm((for_statement_t*) statement); + return; default: break; } @@ -1584,18 +1839,39 @@ static void create_function(declaration_t *declaration) irg_vrfy(irg); } +static void create_global_variable(declaration_t *declaration) +{ + ir_type *global_type = get_glob_type(); + create_declaration_entity(declaration, DECLARATION_TYPE_GLOBAL_VARIABLE, + global_type); + + ir_entity *entity = declaration->v.entity; + if(declaration->storage_class == STORAGE_CLASS_STATIC) { + set_entity_visibility(entity, visibility_local); + } else if(declaration->storage_class == STORAGE_CLASS_EXTERN) { + set_entity_visibility(entity, visibility_external_allocated); + } 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) { declaration_t *declaration = context->declarations; for( ; declaration != NULL; declaration = declaration->next) { if(declaration->namespace != NAMESPACE_NORMAL) continue; + if(declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY + || declaration->storage_class == STORAGE_CLASS_TYPEDEF) + continue; type_t *type = declaration->type; if(type->type == TYPE_FUNCTION) { create_function(declaration); } else { - /* TODO... */ + create_global_variable(declaration); } } }