X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=27c82207bd096c57899853b819239d44658e0d5a;hb=3cdead30b5c1d131d5c363188c26255514ea2fc8;hp=e558b9b8dcb5448812e26c0e11258a1ec64329d8;hpb=0a0df482ce40db64e6d6f0e7c84d5217eeae8191;p=cparser diff --git a/ast2firm.c b/ast2firm.c index e558b9b..27c8220 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -58,6 +58,9 @@ static ir_type *ir_type_int; /* architecture specific floating point arithmetic mode (if any) */ static ir_mode *mode_float_arithmetic; +/* alignment of stack parameters */ +static unsigned stack_param_align; + static int next_value_number_function; static ir_node *continue_label; static ir_node *break_label; @@ -241,55 +244,6 @@ ir_mode *get_atomic_mode(atomic_type_kind_t kind) return atomic_modes[kind]; } -static unsigned get_compound_type_size(compound_type_t *type) -{ - ir_type *irtype = get_ir_type((type_t*) type); - return get_type_size_bytes(irtype); -} - -static unsigned get_array_type_size(array_type_t *type) -{ - assert(!type->is_vla); - ir_type *irtype = get_ir_type((type_t*) type); - return get_type_size_bytes(irtype); -} - -static unsigned get_type_size_const(type_t *type) -{ - switch(type->kind) { - case TYPE_ERROR: - panic("error type occurred"); - case TYPE_ATOMIC: - return get_atomic_type_size(type->atomic.akind); - case TYPE_COMPLEX: - return 2 * get_atomic_type_size(type->complex.akind); - case TYPE_IMAGINARY: - return get_atomic_type_size(type->imaginary.akind); - case TYPE_ENUM: - return get_atomic_type_size(type->enumt.akind); - case TYPE_COMPOUND_UNION: - case TYPE_COMPOUND_STRUCT: - return get_compound_type_size(&type->compound); - case TYPE_FUNCTION: - /* just a pointer to the function */ - return get_mode_size_bytes(mode_P_code); - case TYPE_POINTER: - case TYPE_REFERENCE: - return get_mode_size_bytes(mode_P_data); - case TYPE_ARRAY: - return get_array_type_size(&type->array); - case TYPE_BUILTIN: - return get_type_size_const(type->builtin.real_type); - case TYPE_BITFIELD: - panic("type size of bitfield request"); - case TYPE_TYPEDEF: - case TYPE_TYPEOF: - case TYPE_INVALID: - break; - } - panic("Trying to determine size of invalid type"); -} - static ir_node *get_vla_size(array_type_t *const type) { ir_node *size_node = type->size_node; @@ -300,6 +254,9 @@ static ir_node *get_vla_size(array_type_t *const type) return size_node; } +/** + * Return a node representing the size of a type. + */ static ir_node *get_type_size(type_t *type) { type = skip_typeref(type); @@ -1375,7 +1332,7 @@ static ir_node *deref_address(dbg_info *const dbgi, type_t *const type, } ir_cons_flags flags = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE - ? cons_volatile : 0; + ? cons_volatile : cons_none; ir_mode *const mode = get_type_mode(irtype); ir_node *const memory = get_store(); ir_node *const load = new_d_Load(dbgi, memory, addr, mode, flags); @@ -1389,7 +1346,7 @@ static ir_node *deref_address(dbg_info *const dbgi, type_t *const type, } /** - * Creates a strict Conv if neccessary. + * Creates a strict Conv if necessary. */ static ir_node *do_strict_conv(dbg_info *dbgi, ir_node *node) { @@ -1493,6 +1450,21 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref) } case DECLARATION_KIND_FUNCTION: { ir_mode *const mode = get_ir_mode_storage(type); + + if (entity->function.btk != bk_none) { + /* for gcc compatibility we have to produce (dummy) addresses for some + * builtins */ + if (warning.other) { + warningf(&ref->base.source_position, + "taking address of builtin '%Y'", ref->entity->base.symbol); + } + + /* simply create a NULL pointer */ + ir_mode *mode = get_ir_mode_arithmetic(type_void_ptr); + ir_node *res = new_Const_long(mode, 0); + + return res; + } return create_symconst(dbgi, mode, entity->function.entity); } case DECLARATION_KIND_INNER_FUNCTION: { @@ -1584,6 +1556,71 @@ static ir_node *reference_addr(const reference_expression_t *ref) panic("reference to declaration with unknown type found"); } +/** + * Generate an unary builtin. + * + * @param kind the builtin kind to generate + * @param op the operand + * @param function_type the function type for the GNU builtin routine + * @param db debug info + */ +static ir_node *gen_unary_builtin(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db) +{ + ir_node *in[1]; + in[0] = expression_to_firm(op); + + ir_type *tp = get_ir_type(function_type); + ir_type *res = get_method_res_type(tp, 0); + ir_node *irn = new_d_Builtin(db, get_irg_no_mem(current_ir_graph), kind, 1, in, tp); + set_irn_pinned(irn, op_pin_state_floats); + return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result); +} + +/** + * Generate a pinned unary builtin. + * + * @param kind the builtin kind to generate + * @param op the operand + * @param function_type the function type for the GNU builtin routine + * @param db debug info + */ +static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db) +{ + ir_node *in[1]; + in[0] = expression_to_firm(op); + + ir_type *tp = get_ir_type(function_type); + ir_type *res = get_method_res_type(tp, 0); + ir_node *mem = get_store(); + ir_node *irn = new_d_Builtin(db, mem, kind, 1, in, tp); + set_store(new_Proj(irn, mode_M, pn_Builtin_M)); + return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result); +} + + +/** + * Generate an binary-void-return builtin. + * + * @param kind the builtin kind to generate + * @param op1 the first operand + * @param op2 the second operand + * @param function_type the function type for the GNU builtin routine + * @param db debug info + */ +static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1, expression_t *op2, + type_t *function_type, dbg_info *db) +{ + ir_node *in[2]; + in[0] = expression_to_firm(op1); + in[1] = expression_to_firm(op2); + + ir_type *tp = get_ir_type(function_type); + ir_node *mem = get_store(); + ir_node *irn = new_d_Builtin(db, mem, kind, 2, in, tp); + set_store(new_Proj(irn, mode_M, pn_Builtin_M)); + return NULL; +} + /** * Transform calls to builtin functions. */ @@ -1591,17 +1628,16 @@ static ir_node *process_builtin_call(const call_expression_t *call) { dbg_info *dbgi = get_dbg_info(&call->base.source_position); - assert(call->function->kind == EXPR_BUILTIN_SYMBOL); - builtin_symbol_expression_t *builtin = &call->function->builtin_symbol; + assert(call->function->kind == EXPR_REFERENCE); + reference_expression_t *builtin = &call->function->reference; type_t *type = skip_typeref(builtin->base.type); assert(is_type_pointer(type)); type_t *function_type = skip_typeref(type->pointer.points_to); - symbol_t *symbol = builtin->symbol; - switch(symbol->ID) { - case T___builtin_alloca: { + switch (builtin->entity->function.btk) { + case bk_gnu_builtin_alloca: { if (call->arguments == NULL || call->arguments->next != NULL) { panic("invalid number of parameters on __builtin_alloca"); } @@ -1618,19 +1654,19 @@ static ir_node *process_builtin_call(const call_expression_t *call) return res; } - case T___builtin_huge_val: - case T___builtin_inf: - case T___builtin_inff: - case T___builtin_infl: { + case bk_gnu_builtin_huge_val: + case bk_gnu_builtin_inf: + case bk_gnu_builtin_inff: + case bk_gnu_builtin_infl: { type_t *type = function_type->function.return_type; ir_mode *mode = get_ir_mode_arithmetic(type); tarval *tv = get_mode_infinite(mode); ir_node *res = new_d_Const(dbgi, tv); return res; } - case T___builtin_nan: - case T___builtin_nanf: - case T___builtin_nanl: { + case bk_gnu_builtin_nan: + case bk_gnu_builtin_nanf: + case bk_gnu_builtin_nanl: { /* Ignore string for now... */ assert(is_type_function(function_type)); type_t *type = function_type->function.return_type; @@ -1639,14 +1675,131 @@ static ir_node *process_builtin_call(const call_expression_t *call) ir_node *res = new_d_Const(dbgi, tv); return res; } - case T___builtin_expect: { + case bk_gnu_builtin_expect: { expression_t *argument = call->arguments->expression; return _expression_to_firm(argument); } - case T___builtin_va_end: + case bk_gnu_builtin_va_end: /* evaluate the argument of va_end for its side effects */ _expression_to_firm(call->arguments->expression); return NULL; + case bk_gnu_builtin_frame_address: { + expression_t *const expression = call->arguments->expression; + long val = fold_constant(expression); + if (val == 0) { + /* the nice case */ + return get_irg_frame(current_ir_graph); + } else { + /* get the argument */ + ir_node *in[2]; + + in[0] = expression_to_firm(expression); + in[1] = get_irg_frame(current_ir_graph); + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_frame_addess, 2, in, tp); + return new_Proj(irn, mode_P_data, pn_Builtin_1_result); + } + } + case bk_gnu_builtin_return_address: { + expression_t *const expression = call->arguments->expression; + ir_node *in[2]; + + in[0] = expression_to_firm(expression); + in[1] = get_irg_frame(current_ir_graph); + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp); + return new_Proj(irn, mode_P_data, pn_Builtin_1_result); + } + case bk_gnu_builtin_ffs: + return gen_unary_builtin(ir_bk_ffs, call->arguments->expression, function_type, dbgi); + case bk_gnu_builtin_clz: + return gen_unary_builtin(ir_bk_clz, call->arguments->expression, function_type, dbgi); + case bk_gnu_builtin_ctz: + return gen_unary_builtin(ir_bk_ctz, call->arguments->expression, function_type, dbgi); + case bk_gnu_builtin_popcount: + case bk_ms__popcount: + return gen_unary_builtin(ir_bk_popcount, call->arguments->expression, function_type, dbgi); + case bk_gnu_builtin_parity: + return gen_unary_builtin(ir_bk_parity, call->arguments->expression, function_type, dbgi); + case bk_gnu_builtin_prefetch: { + call_argument_t *const args = call->arguments; + expression_t *const addr = args->expression; + ir_node *in[3]; + + in[0] = _expression_to_firm(addr); + if (args->next != NULL) { + expression_t *const rw = args->next->expression; + + in[1] = _expression_to_firm(rw); + + if (args->next->next != NULL) { + expression_t *const locality = args->next->next->expression; + + in[2] = expression_to_firm(locality); + } else { + in[2] = new_Const_long(mode_int, 3); + } + } else { + in[1] = new_Const_long(mode_int, 0); + in[2] = new_Const_long(mode_int, 3); + } + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_prefetch, 3, in, tp); + set_store(new_Proj(irn, mode_M, pn_Builtin_M)); + return NULL; + } + case bk_gnu_builtin_trap: + case bk_ms__ud2: + { + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_trap, 0, NULL, tp); + set_store(new_Proj(irn, mode_M, pn_Builtin_M)); + return NULL; + } + case bk_ms__debugbreak: { + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_debugbreak, 0, NULL, tp); + set_store(new_Proj(irn, mode_M, pn_Builtin_M)); + return NULL; + } + case bk_ms_ReturnAddress: { + ir_node *in[2]; + + in[0] = new_Const_long(mode_int, 0); + in[1] = get_irg_frame(current_ir_graph); + ir_type *tp = get_ir_type(function_type); + ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp); + return new_Proj(irn, mode_P_data, pn_Builtin_1_result); + } + case bk_ms_rotl: + case bk_ms_rotl64: { + ir_node *val = expression_to_firm(call->arguments->expression); + ir_node *shf = expression_to_firm(call->arguments->next->expression); + ir_mode *mode = get_irn_mode(val); + return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode); + } + case bk_ms_rotr: + case bk_ms_rotr64: { + ir_node *val = expression_to_firm(call->arguments->expression); + ir_node *shf = expression_to_firm(call->arguments->next->expression); + ir_mode *mode = get_irn_mode(val); + ir_node *c = new_Const_long(mode_uint, get_mode_size_bits(mode)); + ir_node *sub = new_d_Sub(dbgi, c, create_conv(dbgi, shf, mode_uint), mode_uint); + return new_d_Rotl(dbgi, val, sub, mode); + } + case bk_ms_byteswap_ushort: + case bk_ms_byteswap_ulong: + case bk_ms_byteswap_uint64: + return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi); + case bk_ms__inbyte: + case bk_ms__inword: + case bk_ms__indword: + return gen_unary_builtin_pinned(ir_bk_inport, call->arguments->expression, function_type, dbgi); + case bk_ms__outbyte: + case bk_ms__outword: + case bk_ms__outdword: + return gen_binary_builtin_mem(ir_bk_outport, call->arguments->expression, + call->arguments->next->expression, function_type, dbgi); default: panic("unsupported builtin found"); } @@ -1659,19 +1812,21 @@ static ir_node *process_builtin_call(const call_expression_t *call) * 176.gcc for instance might allocate 2GB instead of 256 MB if alloca is not * handled right... */ -static ir_node *call_expression_to_firm(const call_expression_t *call) +static ir_node *call_expression_to_firm(const call_expression_t *const call) { - dbg_info *dbgi = get_dbg_info(&call->base.source_position); + dbg_info *const dbgi = get_dbg_info(&call->base.source_position); assert(get_cur_block() != NULL); expression_t *function = call->function; - if (function->kind == EXPR_BUILTIN_SYMBOL) { - return process_builtin_call(call); - } if (function->kind == EXPR_REFERENCE) { const reference_expression_t *ref = &function->reference; entity_t *entity = ref->entity; + if (ref->entity->kind == ENTITY_FUNCTION && + ref->entity->function.btk != bk_none) { + return process_builtin_call(call); + } + if (entity->kind == ENTITY_FUNCTION && entity->function.entity == rts_entities[rts_alloca]) { /* handle alloca() call */ @@ -1682,7 +1837,6 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) size = create_conv(dbgi, size, mode); ir_node *store = get_store(); - dbg_info *dbgi = get_dbg_info(&call->base.source_position); ir_node *alloca = new_d_Alloc(dbgi, store, size, firm_unknown_type, stack_alloc); ir_node *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M); @@ -1713,7 +1867,6 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) /* we need to construct a new method type matching the call * arguments... */ int n_res = get_method_n_ress(ir_method_type); - dbg_info *dbgi = get_dbg_info(&call->base.source_position); new_method_type = new_d_type_method(id_unique("calltype.%u"), n_parameters, n_res, dbgi); set_method_calling_convention(new_method_type, @@ -1813,7 +1966,7 @@ static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type, if (is_type_scalar(type)) { ir_cons_flags flags = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE - ? cons_volatile : 0; + ? cons_volatile : cons_none; ir_node *store = new_d_Store(dbgi, memory, addr, value, flags); ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M); set_store(store_mem); @@ -1871,7 +2024,7 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi, /* load current value */ ir_node *mem = get_store(); ir_node *load = new_d_Load(dbgi, mem, addr, mode, - set_volatile ? cons_volatile : 0); + set_volatile ? cons_volatile : cons_none); 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); tarval *shift_mask = create_bitfield_mask(mode, bitoffset, bitsize); @@ -1882,7 +2035,7 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi, /* construct new value and store */ ir_node *new_val = new_d_Or(dbgi, load_res_masked, value_maskshift, mode); ir_node *store = new_d_Store(dbgi, load_mem, addr, new_val, - set_volatile ? cons_volatile : 0); + set_volatile ? cons_volatile : cons_none); ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M); set_store(store_mem); @@ -1896,7 +2049,7 @@ static ir_node *bitfield_extract_to_firm(const select_expression_t *expression, type_t *type = expression->base.type; ir_mode *mode = get_ir_mode_storage(type); ir_node *mem = get_store(); - ir_node *load = new_d_Load(dbgi, mem, addr, mode, 0); + ir_node *load = new_d_Load(dbgi, mem, addr, mode, cons_none); 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); @@ -2327,22 +2480,10 @@ static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi, assert(is_type_pointer(type)); pointer_type_t *const pointer_type = &type->pointer; type_t *const points_to = skip_typeref(pointer_type->points_to); - unsigned elem_size = get_type_size_const(points_to); - - value = create_conv(dbgi, value, mode); - - /* gcc extension: allow arithmetic with void * and function * */ - if ((elem_size == 0 && is_type_atomic(points_to, ATOMIC_TYPE_VOID)) || - is_type_function(points_to)) { - elem_size = 1; - } - - assert(elem_size >= 1); - if (elem_size == 1) - return value; - - ir_node *const cnst = new_Const_long(mode, (long)elem_size); - ir_node *const mul = new_d_Mul(dbgi, value, cnst, mode); + ir_node * elem_size = get_type_size(points_to); + elem_size = create_conv(dbgi, elem_size, mode); + value = create_conv(dbgi, value, mode); + ir_node *const mul = new_d_Mul(dbgi, value, elem_size, mode); return mul; } @@ -2724,7 +2865,7 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression) } type = skip_typeref(type); - /* § 6.5.3.4 (2) if the type is a VLA, evaluate the expression. */ + /* §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); @@ -2862,11 +3003,11 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression) set_cur_block(cur_block); ir_node *const cond_expr = create_condition_evaluation(expression->condition, true_block, false_block); if (expression->true_expression == NULL) { - if (cond_expr != NULL) { + if (cond_expr != NULL && get_irn_mode(cond_expr) != mode_b) { true_val = cond_expr; } else { - /* Condition ended with a short circuit (&&, ||, !) operation. - * Generate a "1" as value for the true branch. */ + /* Condition ended with a short circuit (&&, ||, !) operation or a + * comparison. Generate a "1" as value for the true branch. */ true_val = new_Const(get_mode_one(mode_Is)); } } @@ -3089,7 +3230,12 @@ static ir_node *va_start_expression_to_firm( new_d_simpleSel(dbgi, no_mem, arg_base, parm_ent); ir_node *const cnst = get_type_size(expr->parameter->base.type); - ir_node *const add = new_d_Add(dbgi, arg_sel, cnst, mode_P_data); + ir_mode *const mode = get_irn_mode(cnst); + ir_node *const c1 = new_Const_long(mode, stack_param_align - 1); + ir_node *const c2 = new_d_Add(dbgi, cnst, c1, mode); + ir_node *const c3 = new_Const_long(mode, -(long)stack_param_align); + ir_node *const c4 = new_d_And(dbgi, c2, c3, mode); + ir_node *const add = new_d_Add(dbgi, arg_sel, c2, mode_P_data); set_value_for_expression(expr->ap, add); return NULL; @@ -3105,7 +3251,12 @@ static ir_node *va_arg_expression_to_firm(const va_arg_expression_t *const expr) ir_node *const res = deref_address(dbgi, type, ap); ir_node *const cnst = get_type_size(expr->base.type); - ir_node *const add = new_d_Add(dbgi, ap, cnst, mode_P_data); + ir_mode *const mode = get_irn_mode(cnst); + ir_node *const c1 = new_Const_long(mode, stack_param_align - 1); + ir_node *const c2 = new_d_Add(dbgi, cnst, c1, mode); + ir_node *const c3 = new_Const_long(mode, -(long)stack_param_align); + ir_node *const c4 = new_d_And(dbgi, c2, c3, mode); + ir_node *const add = new_d_Add(dbgi, ap, c4, mode_P_data); set_value_for_expression_addr(ap_expr, add, ap_addr); @@ -3156,13 +3307,14 @@ static ir_node *builtin_constant_to_firm( return new_Const_long(mode, v); } -static ir_node *builtin_prefetch_to_firm( - const builtin_prefetch_expression_t *expression) +static ir_node *builtin_types_compatible_to_firm( + const builtin_types_compatible_expression_t *expression) { - ir_node *adr = expression_to_firm(expression->adr); - /* no Firm support for prefetch yet */ - (void) adr; - return NULL; + type_t *const left = get_unqualified_type(skip_typeref(expression->left)); + type_t *const right = get_unqualified_type(skip_typeref(expression->right)); + long const value = types_compatible(left, right) ? 1 : 0; + ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type); + return new_Const_long(mode, value); } static ir_node *get_label_block(label_t *label) @@ -3204,23 +3356,6 @@ static ir_node *label_address_to_firm( return new_SymConst(mode_P_code, value, symconst_label); } -static ir_node *builtin_symbol_to_firm( - const builtin_symbol_expression_t *expression) -{ - /* for gcc compatibility we have to produce (dummy) addresses for some - * builtins */ - if (warning.other) { - warningf(&expression->base.source_position, - "taking address of builtin '%Y'", expression->symbol); - } - - /* simply create a NULL pointer */ - ir_mode *mode = get_ir_mode_arithmetic(type_void_ptr); - ir_node *res = new_Const_long(mode, 0); - - return res; -} - /** * creates firm nodes for an expression. The difference between this function * and expression_to_firm is, that this version might produce mode_b nodes @@ -3276,12 +3411,10 @@ static ir_node *_expression_to_firm(const expression_t *expression) return va_start_expression_to_firm(&expression->va_starte); case EXPR_VA_ARG: return va_arg_expression_to_firm(&expression->va_arge); - case EXPR_BUILTIN_SYMBOL: - return builtin_symbol_to_firm(&expression->builtin_symbol); case EXPR_BUILTIN_CONSTANT_P: return builtin_constant_to_firm(&expression->builtin_constant); - case EXPR_BUILTIN_PREFETCH: - return builtin_prefetch_to_firm(&expression->builtin_prefetch); + case EXPR_BUILTIN_TYPES_COMPATIBLE_P: + return builtin_types_compatible_to_firm(&expression->builtin_types_compatible); case EXPR_OFFSETOF: return offsetof_to_firm(&expression->offsetofe); case EXPR_COMPOUND_LITERAL: @@ -3296,15 +3429,20 @@ static ir_node *_expression_to_firm(const expression_t *expression) panic("invalid expression found"); } +/** + * 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_BUILTIN_SYMBOL) + if (function->kind != EXPR_REFERENCE) return false; - if (function->builtin_symbol.symbol->ID != T___builtin_expect) + reference_expression_t *ref = &function->reference; + if (ref->entity->kind != ENTITY_FUNCTION || + ref->entity->function.btk != bk_gnu_builtin_expect) return false; return true; @@ -3896,7 +4034,7 @@ static void create_dynamic_null_initializer(ir_type *type, dbg_info *dbgi, /* TODO: bitfields */ ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, 0); + ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, cons_none); ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); set_store(proj_m); } else { @@ -3954,7 +4092,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer, assert(get_type_mode(type) == mode); ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, node, 0); + 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); return; @@ -3974,7 +4112,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer, assert(get_type_mode(type) == mode); ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, 0); + ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, cons_none); ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); set_store(proj_m); return; @@ -5339,7 +5477,9 @@ static void initialize_function_parameters(entity_t *entity) int n = 0; entity_t *parameter = entity->function.parameters.entities; for ( ; parameter != NULL; parameter = parameter->base.next, ++n) { - assert(parameter->kind == ENTITY_PARAMETER); + if (parameter->kind != ENTITY_PARAMETER) + continue; + assert(parameter->declaration.kind == DECLARATION_KIND_UNKNOWN); type_t *type = skip_typeref(parameter->declaration.type); @@ -5604,6 +5744,10 @@ static void scope_to_firm(scope_t *scope) continue; if (entity->kind == ENTITY_FUNCTION) { + if (entity->function.btk != bk_none) { + /* builtins have no representation */ + continue; + } get_function_entity(entity); } else if (entity->kind == ENTITY_VARIABLE) { create_global_variable(entity); @@ -5617,6 +5761,10 @@ static void scope_to_firm(scope_t *scope) continue; if (entity->kind == ENTITY_FUNCTION) { + if (entity->function.btk != bk_none) { + /* builtins have no representation */ + continue; + } create_function(entity); } else if (entity->kind == ENTITY_VARIABLE) { assert(entity->declaration.kind @@ -5669,6 +5817,8 @@ static void init_ir_types(void) const backend_params *be_params = be_get_backend_param(); mode_float_arithmetic = be_params->mode_float_arithmetic; + + stack_param_align = be_params->stack_param_align; } void exit_ast2firm(void)