if( (flags & (ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_FLOAT))
&& !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) {
char name[64];
- mode_sort sort;
+ ir_mode_sort sort;
unsigned bit_size = size * 8;
bool is_signed = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0;
- mode_arithmetic arithmetic;
+ ir_mode_arithmetic arithmetic;
unsigned modulo_shift;
if(flags & ATOMIC_TYPE_FLAG_INTEGER) {
/* initialize pointer modes */
char name[64];
- mode_sort sort = irms_reference;
+ ir_mode_sort sort = irms_reference;
unsigned bit_size = machine_size;
bool is_signed = 0;
- mode_arithmetic arithmetic = irma_twos_complement;
+ ir_mode_arithmetic arithmetic = irma_twos_complement;
unsigned modulo_shift
= bit_size < machine_size ? machine_size : bit_size;
return mode;
}
-static ident *predef_idents[rts_max];
-
/** Names of the runtime functions. */
static const struct {
int id; /**< the rts id */
} rts_data[] = {
{ rts_debugbreak, 0, "__debugbreak", 0, _MS },
{ rts_abort, 0, "abort", 0, _C89 },
+ { rts_alloca, 1, "alloca", 1, _GNUC },
{ rts_abs, 1, "abs", 1, _C89 },
{ rts_labs, 1, "labs", 1, _C89 },
{ rts_llabs, 1, "llabs", 1, _C99 },
{ rts_strncmp, 1, "strncmp", 3, _C89 }
};
+static ident *rts_idents[sizeof(rts_data) / sizeof(rts_data[0])];
+
/**
* Mangles an entity linker (ld) name for win32 usage.
*
set_entity_visibility(entity, visibility_external_visible);
} else {
set_entity_visibility(entity, visibility_external_allocated);
-
- /* We should check for file scope here, but as long as we compile C only
- this is not needed. */
- int n_params = get_method_n_params(ir_type_method);
- int n_res = get_method_n_ress(ir_type_method);
- int i;
-
- if (n_params == 0 && n_res == 0 && id == predef_idents[rts_abort]) {
- /* found abort(), store for later */
- //abort_ent = ent;
- //abort_tp = ftype;
- } else {
- if (! firm_opt.freestanding) {
- /* check for a known runtime function */
- for (i = 0; i < rts_max; ++i) {
- /* ignore those rts functions not necessary needed for current mode */
- if ((c_mode & rts_data[i].flags) == 0)
- continue;
- if (n_params == rts_data[i].n_params && n_res == rts_data[i].n_res &&
- id == predef_idents[rts_data[i].id])
- rts_entities[rts_data[i].id] = entity;
- }
- }
- }
}
set_entity_allocation(entity, allocation_static);
declaration->declaration_kind = DECLARATION_KIND_FUNCTION;
declaration->v.entity = entity;
+ /* We should check for file scope here, but as long as we compile C only
+ this is not needed. */
+ if (! firm_opt.freestanding) {
+ /* check for a known runtime function */
+ for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) {
+ if (id != rts_idents[i])
+ continue;
+
+ /* ignore those rts functions not necessary needed for current mode */
+ if ((c_mode & rts_data[i].flags) == 0)
+ continue;
+ rts_entities[rts_data[i].id] = entity;
+ }
+ }
+
return entity;
}
}
}
+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 || is_Bad(value))
+ return value;
+
+ if(dest_mode == mode_b) {
+ ir_node *zero = new_Const(value_mode, get_mode_null(value_mode));
+ ir_node *cmp = new_d_Cmp(dbgi, value, zero);
+ ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg);
+ return proj;
+ }
+
+ return new_d_Conv(dbgi, value, dest_mode);
+}
+
static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
{
dbg_info *dbgi = get_dbg_info(&ref->base.source_position);
return res;
}
+ case T___builtin_huge_val: {
+ ir_mode *mode = get_ir_mode(function_type->function.return_type);
+ tarval *tv = get_mode_infinite(mode);
+ ir_node *res = new_d_Const(dbgi, mode, tv);
+ return res;
+ }
case T___builtin_nan:
case T___builtin_nanf:
case T___builtin_nand: {
assert(is_type_function(points_to));
function_type_t *function_type = &points_to->function;
- int n_parameters = 0;
- call_argument_t *argument = call->arguments;
- for( ; argument != NULL; argument = argument->next) {
- ++n_parameters;
- }
-
dbg_info *dbgi = get_dbg_info(&call->base.source_position);
+ int n_parameters = 0;
ir_type *ir_method_type = get_ir_type((type_t*) function_type);
ir_type *new_method_type = NULL;
if(function_type->variadic || function_type->unspecified_parameters) {
+ const call_argument_t *argument = call->arguments;
+ for( ; argument != NULL; argument = argument->next) {
+ ++n_parameters;
+ }
+
/* 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);
+ n_parameters, n_res, dbgi);
set_method_calling_convention(new_method_type,
get_method_calling_convention(ir_method_type));
set_method_additional_properties(new_method_type,
set_method_res_type(new_method_type, i,
get_method_res_type(ir_method_type, i));
}
+ argument = call->arguments;
+ for(int i = 0; i < n_parameters; ++i, argument = argument->next) {
+ expression_t *expression = argument->expression;
+ ir_type *irtype = get_ir_type(expression->base.type);
+ set_method_param_type(new_method_type, i, irtype);
+ }
+ ir_method_type = new_method_type;
+ } else {
+ n_parameters = get_method_n_params(ir_method_type);
}
+
ir_node *in[n_parameters];
- argument = call->arguments;
- int n = 0;
- for( ; argument != NULL; argument = argument->next) {
+ 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);
arg_node = do_strict_conv(dbgi, arg_node);
in[n] = arg_node;
- if(new_method_type != NULL) {
- ir_type *irtype = get_ir_type(expression->base.type);
- set_method_param_type(new_method_type, n, irtype);
- }
- n++;
+ argument = argument->next;
}
- assert(n == n_parameters);
-
- if(new_method_type != NULL)
- ir_method_type = new_method_type;
ir_node *store = get_store();
ir_node *node = new_d_Call(dbgi, store, callee, n_parameters, in,
ir_mode *mode = get_ir_mode(type->bitfield.base_type);
ir_node *addr = expression_to_addr(select);
- assert(get_irn_mode(value) == mode);
+ assert(get_irn_mode(value) == mode || is_Bad(value));
dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
assign_value(dbgi, addr, type, value);
}
-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 || is_Bad(value))
- return value;
-
- if(dest_mode == mode_b) {
- ir_node *zero = new_Const(value_mode, get_mode_null(value_mode));
- ir_node *cmp = new_d_Cmp(dbgi, value, zero);
- ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg);
- return proj;
- }
-
- return new_d_Conv(dbgi, value, dest_mode);
-}
-
static ir_node *create_incdec(const unary_expression_t *expression)
{
dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
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);
- offset = create_conv(dbgi, offset, mode_uint);
+
+ /* Matze: it would be better to force mode to mode_uint as this creates more
+ * opportunities for CSE. Unforunately we still have some optimisations that
+ * are too conservative in the presence of convs. So we better go with the
+ * mode of offset and avoid the conv */
+ ir_mode *mode = get_irn_mode(offset);
+ offset = create_conv(dbgi, offset, mode);
type_t *ref_type = skip_typeref(expression->array_ref->base.type);
assert(is_type_pointer(ref_type));
pointer_type_t *pointer_type = &ref_type->pointer;
ir_node *elem_size_const = get_type_size(pointer_type->points_to);
+ elem_size_const = create_conv(dbgi, elem_size_const, mode);
ir_node *real_offset = new_d_Mul(dbgi, offset, elem_size_const,
- mode_uint);
+ mode);
ir_node *result = new_d_Add(dbgi, base_addr, real_offset, mode_P_data);
return result;
type_t *const type = skip_typeref(declaration->type);
ir_type *const global_type = get_glob_type();
- ident *const id = new_id_from_str(declaration->symbol->string);
ir_type *const irtype = get_ir_type(type);
dbg_info *const dbgi = get_dbg_info(&declaration->source_position);
+
+ size_t l = strlen(declaration->symbol->string);
+ char buf[l + sizeof(".%u")];
+ snprintf(buf, sizeof(buf), "%s.%%u", declaration->symbol->string);
+ ident *const id = id_unique(buf);
+
ir_entity *const entity = new_d_entity(global_type, id, irtype, dbgi);
if(type->base.qualifiers & TYPE_QUALIFIER_VOLATILE) {
ir_node *const old_switch_cond = current_switch_cond;
ir_node *const old_break_label = break_label;
const bool old_saw_default_label = saw_default_label;
+ saw_default_label = false;
current_switch_cond = cond;
break_label = break_block;
/* create idents for all known runtime functions */
for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) {
- predef_idents[rts_data[i].id] = new_id_from_str(rts_data[i].name);
+ rts_idents[i] = new_id_from_str(rts_data[i].name);
}
}