#include "adt/error.h"
#include "adt/array.h"
+#include "adt/util.h"
#include "symbol_t.h"
#include "token_t.h"
#include "type_t.h"
/* 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;
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;
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);
{ rts_strncmp, 1, "strncmp", 3, _C89 }
};
-static ident *rts_idents[sizeof(rts_data) / sizeof(rts_data[0])];
+static ident *rts_idents[lengthof(rts_data)];
static ident* (*create_ld_ident)(entity_t*) = create_name_linux_elf;
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) {
+ for (size_t i = 0; i < lengthof(rts_data); ++i) {
if (id != rts_idents[i])
continue;
}
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);
}
/**
- * Creates a strict Conv if neccessary.
+ * Creates a strict Conv if necessary.
*/
static ir_node *do_strict_conv(dbg_info *dbgi, ir_node *node)
{
/**
* Keep all memory edges of the given block.
*/
-static void keep_all_memory(ir_node *block) {
+static void keep_all_memory(ir_node *block)
+{
ir_node *old = get_cur_block();
set_cur_block(block);
}
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: {
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.
*/
{
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");
}
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;
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");
}
* 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 */
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);
/* 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,
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);
/* 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);
/* 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);
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);
* @param dbi debug info
* @param expr the IL assume expression
*/
-static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression) {
+static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression)
+{
switch(expression->kind) {
case EXPR_BINARY_EQUAL:
case EXPR_BINARY_NOTEQUAL:
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;
}
}
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);
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));
}
}
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;
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);
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)
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
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:
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;
/* 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 {
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;
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;
static void declaration_statement_to_firm(declaration_statement_t *statement)
{
- entity_t * entity = statement->declarations_begin;
- entity_t *const last = statement->declarations_end;
- if (entity != NULL) {
- for ( ;; entity = entity->base.next) {
- if (is_declaration(entity)) {
- initialize_local_declaration(entity);
- } else if (entity->kind == ENTITY_TYPEDEF) {
- type_t *const type = skip_typeref(entity->typedefe.type);
- if (is_type_array(type) && type->array.is_vla)
- get_vla_size(&type->array);
- }
- if (entity == last)
- break;
+ entity_t *entity = statement->declarations_begin;
+ if (entity == NULL)
+ return;
+
+ entity_t *const last = statement->declarations_end;
+ for ( ;; entity = entity->base.next) {
+ if (is_declaration(entity)) {
+ initialize_local_declaration(entity);
+ } else if (entity->kind == ENTITY_TYPEDEF) {
+ type_t *const type = skip_typeref(entity->typedefe.type);
+ if (is_type_array(type) && type->array.is_vla)
+ get_vla_size(&type->array);
}
+ if (entity == last)
+ break;
}
}
}
}
-static void ms_try_statement_to_firm(ms_try_statement_t *statement) {
+static void ms_try_statement_to_firm(ms_try_statement_t *statement)
+{
statement_to_firm(statement->try_statement);
warningf(&statement->base.source_position, "structured exception handling ignored");
}
-static void leave_statement_to_firm(leave_statement_t *statement) {
+static void leave_statement_to_firm(leave_statement_t *statement)
+{
errorf(&statement->base.source_position, "__leave not supported yet");
}
const entity_t *const last)
{
int count = 0;
- for (; entity != NULL; entity = entity->base.next) {
+ entity_t const *const end = last != NULL ? last->base.next : NULL;
+ for (; entity != end; entity = entity->base.next) {
type_t *type;
bool address_taken;
if (!address_taken && is_type_scalar(type))
++count;
-
- if (entity == last)
- break;
}
return count;
}
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);
/**
* Generate possible IJmp branches to a given label block.
*/
-static void gen_ijmp_branches(ir_node *block) {
+static void gen_ijmp_branches(ir_node *block)
+{
ir_node *ijmp;
for (ijmp = ijmp_list; ijmp != NULL; ijmp = get_irn_link(ijmp)) {
add_immBlock_pred(block, ijmp);
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);
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
}
/* create idents for all known runtime functions */
- for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) {
+ for (size_t i = 0; i < lengthof(rts_data); ++i) {
rts_idents[i] = new_id_from_str(rts_data[i].name);
}
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)