[EXPR_FUNCNAME] = PREC_PRIMARY,
[EXPR_BUILTIN_SYMBOL] = PREC_PRIMARY,
[EXPR_BUILTIN_CONSTANT_P] = PREC_PRIMARY,
+ [EXPR_BUILTIN_ADDRESS] = PREC_PRIMARY,
[EXPR_BUILTIN_PREFETCH] = PREC_PRIMARY,
[EXPR_OFFSETOF] = PREC_PRIMARY,
[EXPR_VA_START] = PREC_PRIMARY,
fputc(')', out);
}
+/**
+ * Prints a builtin address expression.
+ *
+ * @param expression the builtin address expression
+ */
+static void print_builtin_address(const builtin_address_expression_t *expression)
+{
+ fputs(expression->kind == builtin_return_address ?
+ "__builtin_return_address(" : "__builtin_frame_address(", out);
+ print_assignment_expression(expression->value);
+ fputc(')', out);
+}
+
/**
* Prints a builtin prefetch expression.
*
case EXPR_BUILTIN_CONSTANT_P:
print_builtin_constant(&expression->builtin_constant);
break;
+ case EXPR_BUILTIN_ADDRESS:
+ print_builtin_address(&expression->builtin_address);
+ break;
case EXPR_BUILTIN_PREFETCH:
print_builtin_prefetch(&expression->builtin_prefetch);
break;
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_PREFETCH:
+ case EXPR_BUILTIN_ADDRESS:
case EXPR_SELECT:
case EXPR_VA_START:
case EXPR_VA_ARG:
typedef struct va_arg_expression_t va_arg_expression_t;
typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
typedef struct builtin_constant_expression_t builtin_constant_expression_t;
+typedef struct builtin_address_expression_t builtin_address_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;
}
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)
{
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);
return new_Const_long(mode, v);
}
+static ir_node *builtin_address_to_firm(
+ const builtin_address_expression_t *expression)
+{
+ panic("builtin_address_expression not implemented yet");
+}
+
static ir_node *builtin_prefetch_to_firm(
const builtin_prefetch_expression_t *expression)
{
return builtin_symbol_to_firm(&expression->builtin_symbol);
case EXPR_BUILTIN_CONSTANT_P:
return builtin_constant_to_firm(&expression->builtin_constant);
+ case EXPR_BUILTIN_ADDRESS:
+ return builtin_address_to_firm(&expression->builtin_address);
case EXPR_BUILTIN_PREFETCH:
return builtin_prefetch_to_firm(&expression->builtin_prefetch);
case EXPR_OFFSETOF:
/* 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;
EXPR_FUNCNAME,
EXPR_BUILTIN_SYMBOL,
EXPR_BUILTIN_CONSTANT_P,
+ EXPR_BUILTIN_ADDRESS,
EXPR_BUILTIN_PREFETCH,
EXPR_OFFSETOF,
EXPR_VA_START,
expression_t *value;
};
+typedef enum buitin_address_kind {
+ builtin_return_address,
+ builtin_frame_address
+} builtin_address_kind;
+
+struct builtin_address_expression_t {
+ expression_base_t base;
+ builtin_address_kind kind;
+ expression_t *value;
+};
+
struct builtin_prefetch_expression_t {
expression_base_t base;
expression_t *adr;
compound_literal_expression_t compound_literal;
builtin_symbol_expression_t builtin_symbol;
builtin_constant_expression_t builtin_constant;
+ builtin_address_expression_t builtin_address;
builtin_prefetch_expression_t builtin_prefetch;
reference_expression_t reference;
call_expression_t call;
[EXPR_FUNCNAME] = sizeof(funcname_expression_t),
[EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
[EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
+ [EXPR_BUILTIN_ADDRESS] = sizeof(builtin_address_expression_t),
[EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
[EXPR_OFFSETOF] = sizeof(offsetof_expression_t),
[EXPR_VA_START] = sizeof(va_start_expression_t),
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
+ case EXPR_BUILTIN_ADDRESS:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_STATEMENT: // TODO
prev_decl->type, symbol);
}
- storage_class_tag_t new_storage_class = decl->storage_class;
+ storage_class_t new_storage_class = decl->storage_class;
/* pretend no storage class means extern for function
* declarations (except if the previous declaration is neither
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
+ case EXPR_BUILTIN_ADDRESS:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_INVALID:
return make_function_1_type(type_void, type_valist);
case T___builtin_expect:
return make_function_2_type(type_long, type_long, type_long);
+ case T___builtin_return_address:
+ case T___builtin_frame_address:
+ return make_function_1_type(type_void_ptr, type_unsigned_int);
default:
internal_errorf(HERE, "not implemented builtin identifier found");
}
return create_invalid_expression();
}
+/**
+ * Parses a __buildin_return_address of a __builtin_frame_address() expression.
+ *
+ * @param tok_type either T___buildin_return_address or T___builtin_frame_address
+ */
+static expression_t *parse_builtin_address(int tok_type)
+{
+ expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_ADDRESS);
+
+ expression->builtin_address.kind = tok_type == T___builtin_return_address ?
+ builtin_return_address : builtin_frame_address;
+
+ eat(tok_type);
+
+ expect('(', end_error);
+ add_anchor_token(')');
+ expression->builtin_address.value = parse_constant_expression();
+ rem_anchor_token(')');
+ expect(')', end_error);
+ expression->base.type = type_void_ptr;
+
+ return expression;
+end_error:
+ return create_invalid_expression();
+}
+
/**
* Parses a __builtin_is_*() compare expression.
*/
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_return_address: return parse_builtin_address(T___builtin_return_address);
+ case T___builtin_frame_address: return parse_builtin_address(T___builtin_frame_address);
case T__assume: return parse_assume();
case T_ANDAND:
if (GNU_MODE)
S(_ALL, __builtin_constant_p)
S(_ALL, __builtin_prefetch)
S(_ALL, __builtin_huge_val)
+S(_ALL, __builtin_return_address)
+S(_ALL, __builtin_frame_address)
S(_ALL, __PRETTY_FUNCTION__)
S(_ALL, __FUNCTION__)
S(_ALL, __label__)