[EXPR_BUILTIN_SYMBOL] = PREC_PRIMARY,
[EXPR_BUILTIN_CONSTANT_P] = PREC_PRIMARY,
[EXPR_BUILTIN_TYPES_COMPATIBLE_P] = PREC_PRIMARY,
- [EXPR_BUILTIN_PREFETCH] = PREC_PRIMARY,
[EXPR_OFFSETOF] = PREC_PRIMARY,
[EXPR_VA_START] = PREC_PRIMARY,
[EXPR_VA_ARG] = PREC_PRIMARY,
fputc(')', out);
}
-/**
- * Prints a builtin prefetch expression.
- *
- * @param expression the builtin prefetch expression
- */
-static void print_builtin_prefetch(const builtin_prefetch_expression_t *expression)
-{
- fputs("__builtin_prefetch(", out);
- print_assignment_expression(expression->adr);
- if (expression->rw) {
- fputc(',', out);
- print_assignment_expression(expression->rw);
- }
- if (expression->locality) {
- fputc(',', out);
- print_assignment_expression(expression->locality);
- }
- fputc(')', out);
-}
-
/**
* Prints a conditional expression.
*
case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
print_builtin_types_compatible(&expression->builtin_types_compatible);
break;
- case EXPR_BUILTIN_PREFETCH:
- print_builtin_prefetch(&expression->builtin_prefetch);
- break;
case EXPR_CONDITIONAL:
print_conditional(&expression->conditional);
break;
}
case EXPR_BUILTIN_SYMBOL:
- case EXPR_BUILTIN_PREFETCH:
case EXPR_SELECT:
case EXPR_VA_START:
case EXPR_VA_ARG:
typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
typedef struct builtin_constant_expression_t builtin_constant_expression_t;
typedef struct builtin_types_compatible_expression_t builtin_types_compatible_expression_t;
-typedef struct builtin_prefetch_expression_t builtin_prefetch_expression_t;
typedef struct classify_type_expression_t classify_type_expression_t;
typedef struct bitfield_extract_expression_t bitfield_extract_expression_t;
typedef struct label_address_expression_t label_address_expression_t;
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 T___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((type_t*) 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;
+ }
default:
panic("unsupported builtin found");
}
return new_Const_long(mode, value);
}
-static ir_node *builtin_prefetch_to_firm(
- const builtin_prefetch_expression_t *expression)
-{
- ir_node *adr = expression_to_firm(expression->adr);
- /* no Firm support for prefetch yet */
- (void) adr;
- return NULL;
-}
-
static ir_node *get_label_block(label_t *label)
{
if (label->block != NULL)
return builtin_constant_to_firm(&expression->builtin_constant);
case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
return builtin_types_compatible_to_firm(&expression->builtin_types_compatible);
- case EXPR_BUILTIN_PREFETCH:
- return builtin_prefetch_to_firm(&expression->builtin_prefetch);
case EXPR_OFFSETOF:
return offsetof_to_firm(&expression->offsetofe);
case EXPR_COMPOUND_LITERAL:
EXPR_BUILTIN_SYMBOL,
EXPR_BUILTIN_CONSTANT_P,
EXPR_BUILTIN_TYPES_COMPATIBLE_P,
- EXPR_BUILTIN_PREFETCH,
EXPR_OFFSETOF,
EXPR_VA_START,
EXPR_VA_ARG,
type_t *right;
};
-struct builtin_prefetch_expression_t {
- expression_base_t base;
- expression_t *adr;
- expression_t *rw;
- expression_t *locality;
-};
-
struct reference_expression_t {
expression_base_t base;
entity_t *entity;
builtin_symbol_expression_t builtin_symbol;
builtin_constant_expression_t builtin_constant;
builtin_types_compatible_expression_t builtin_types_compatible;
- builtin_prefetch_expression_t builtin_prefetch;
reference_expression_t reference;
call_expression_t call;
unary_expression_t unary;
[EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
[EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
[EXPR_BUILTIN_TYPES_COMPATIBLE_P] = sizeof(builtin_types_compatible_expression_t),
- [EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
[EXPR_OFFSETOF] = sizeof(offsetof_expression_t),
[EXPR_VA_START] = sizeof(va_start_expression_t),
[EXPR_VA_ARG] = sizeof(va_arg_expression_t),
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
- case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_STATEMENT: // TODO
case EXPR_LABEL_ADDRESS:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
- case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_INVALID:
return true;
return identify_new_type(type);
}
+static type_t *make_function_1_type_variadic(type_t *return_type, type_t *argument_type)
+{
+ type_t *res = make_function_1_type(return_type, argument_type);
+ res->function.variadic = 1;
+ return res;
+}
+
+/**
+ * Creates a return_type (func)(void) function type if not
+ * already exists.
+ *
+ * @param return_type the return type
+ */
static type_t *make_function_0_type(type_t *return_type)
{
type_t *type = allocate_type_zero(TYPE_FUNCTION);
case T___builtin_return_address:
case T___builtin_frame_address:
return make_function_1_type(type_void_ptr, type_unsigned_int);
+ case T___builtin_prefetch:
+ return make_function_1_type_variadic(type_float, type_void_ptr);
default:
internal_errorf(HERE, "not implemented builtin identifier found");
}
return create_invalid_expression();
}
-/**
- * Parses a __builtin_prefetch() expression.
- */
-static expression_t *parse_builtin_prefetch(void)
-{
- expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_PREFETCH);
-
- eat(T___builtin_prefetch);
-
- expect('(', end_error);
- add_anchor_token(')');
- expression->builtin_prefetch.adr = parse_assignment_expression();
- if (token.type == ',') {
- next_token();
- expression->builtin_prefetch.rw = parse_assignment_expression();
- }
- if (token.type == ',') {
- next_token();
- expression->builtin_prefetch.locality = parse_assignment_expression();
- }
- rem_anchor_token(')');
- expect(')', end_error);
- expression->base.type = type_void;
-
- return expression;
-end_error:
- return create_invalid_expression();
-}
-
/**
* Parses a __builtin_is_*() compare expression.
*/
case T___builtin_huge_val:
case T___builtin_va_end:
case T___builtin_return_address:
- case T___builtin_frame_address: return parse_builtin_symbol();
+ case T___builtin_frame_address:
+ case T___builtin_prefetch: return parse_builtin_symbol();
case T___builtin_isgreater:
case T___builtin_isgreaterequal:
case T___builtin_isless:
case T___builtin_islessgreater:
case T___builtin_isunordered: return parse_compare_builtin();
case T___builtin_constant_p: return parse_builtin_constant();
- case T___builtin_prefetch: return parse_builtin_prefetch();
case T___builtin_types_compatible_p: return parse_builtin_types_compatible();
case T__assume: return parse_assume();
case T_ANDAND:
}
break;
}
+ case T___builtin_prefetch: {
+ /* second and third argument must be constant if existant */
+ call_argument_t *rw = call->arguments->next;
+ call_argument_t *locality = NULL;
+
+ if (rw != NULL) {
+ if (! is_constant_expression(rw->expression)) {
+ errorf(&call->base.source_position,
+ "second argument of '%Y' must be a constant expression",
+ call->function->builtin_symbol.symbol);
+ }
+ locality = rw->next;
+ }
+ if (locality != NULL) {
+ if (! is_constant_expression(locality->expression)) {
+ errorf(&call->base.source_position,
+ "third argument of '%Y' must be a constant expression",
+ call->function->builtin_symbol.symbol);
+ }
+ locality = rw->next;
+ }
+ break;
+ }
default:
break;
}
return true;
switch (call->function->builtin_symbol.symbol->ID) {
- case T___builtin_va_end: return true;
- default: return false;
+ case T___builtin_prefetch:
+ case T___builtin_va_end: return true;
+ default: return false;
}
}
case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */
case EXPR_BUILTIN_CONSTANT_P: return false;
case EXPR_BUILTIN_TYPES_COMPATIBLE_P: return false;
- case EXPR_BUILTIN_PREFETCH: return true;
case EXPR_OFFSETOF: return false;
case EXPR_VA_START: return true;
case EXPR_VA_ARG: return true;
walk_expression(expr->conditional.false_expression, callback, env);
return;
- case EXPR_BUILTIN_PREFETCH: {
- builtin_prefetch_expression_t const *const pf = &expr->builtin_prefetch;
- walk_expression(pf->adr, callback, env);
- if (pf->rw != NULL) {
- walk_expression(pf->rw, callback, env);
- if (pf->locality != NULL)
- walk_expression(pf->locality, callback, env);
- }
- return;
- }
-
case EXPR_BUILTIN_CONSTANT_P:
walk_expression(expr->builtin_constant.value, callback, env);
return;