support for alloca
authorMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 18:25:04 +0000 (18:25 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 18:25:04 +0000 (18:25 +0000)
[r18514]

ast2firm.c
parser.c
tokens.inc

index 5f8a877..101b87a 100644 (file)
@@ -28,6 +28,8 @@ static type_t *type_const_char;
 static type_t *type_void;
 static type_t *type_int;
 
+static symbol_t *symbol_alloca;
+
 static int       next_value_number_function;
 static ir_node  *continue_label;
 static ir_node  *break_label;
@@ -97,6 +99,8 @@ void init_ast2firm(void)
                                              ir_type_void, mode_P_data);
 
        type_void->firm_type = ir_type_void;
+
+       symbol_alloca = symbol_table_insert("__builtin_alloca");
 }
 
 void exit_ast2firm(void)
@@ -712,11 +716,43 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        panic("reference to declaration with unknown type found");
 }
 
+static ir_node *process_builtin_call(const call_expression_t *call)
+{
+       dbg_info *dbgi = get_dbg_info(&call->expression.source_position);
+
+       assert(call->function->type == EXPR_BUILTIN_SYMBOL);
+       builtin_symbol_expression_t *builtin
+               = (builtin_symbol_expression_t*) call->function;
+       symbol_t *symbol = builtin->symbol;
+
+       if(symbol == symbol_alloca) {
+               if(call->arguments == NULL || call->arguments->next != NULL) {
+                       panic("invalid number of parameters on __builtin_alloca");
+               }
+               expression_t *argument = call->arguments->expression;
+               ir_node      *size     = expression_to_firm(argument);
+
+               ir_node *store  = get_store();
+               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);
+               set_store(proj_m);
+               ir_node *res    = new_Proj(alloca, mode_P_data, pn_Alloc_res);
+
+               return res;
+       } else {
+               panic("Unsupported builtin found\n");
+       }
+}
+
 static ir_node *call_expression_to_firm(const call_expression_t *call)
 {
        assert(get_cur_block() != NULL);
 
        expression_t  *function = call->function;
+       if(function->type == EXPR_BUILTIN_SYMBOL) {
+               return process_builtin_call(call);
+       }
        ir_node       *callee   = expression_to_firm(function);
 
        function_type_t *function_type;
index 4af5907..eb7eb9c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -45,6 +45,7 @@ static type_t         *type_float       = NULL;
 static type_t         *type_const_char  = NULL;
 static type_t         *type_string      = NULL;
 static type_t         *type_void        = NULL;
+static type_t         *type_void_ptr    = NULL;
 static type_t         *type_size_t      = NULL;
 static type_t         *type_ptrdiff_t   = NULL;
 
@@ -2656,18 +2657,42 @@ static expression_t *parse_va_arg(void)
        return (expression_t*) expression;
 }
 
+static type_t *make_function_1_type(type_t *result_type, type_t *argument_type)
+{
+       function_parameter_t *parameter = allocate_type_zero(sizeof(parameter[0]));
+       parameter->type = argument_type;
+
+       function_type_t *type = allocate_type_zero(sizeof(type[0]));
+       type->type.type   = TYPE_FUNCTION;
+       type->result_type = result_type;
+       type->parameters  = parameter;
+
+       type_t *result = typehash_insert((type_t*) type);
+       if(result != (type_t*) type) {
+               free_type(type);
+       }
+
+       return result;
+}
+
 static expression_t *parse_builtin_symbol(void)
 {
        builtin_symbol_expression_t *expression
                = allocate_ast_zero(sizeof(expression[0]));
        expression->expression.type = EXPR_BUILTIN_SYMBOL;
 
-       /* TODO: set datatype */
-
        expression->symbol = token.v.symbol;
 
+       type_t *type;
+       switch(token.type) {
+       case T___builtin_alloca:
+               type = make_function_1_type(type_void_ptr, type_size_t);
+               break;
+       }
+
        next_token();
 
+       expression->expression.datatype = type;
        return (expression_t*) expression;
 }
 
@@ -2691,6 +2716,7 @@ static expression_t *parse_primary_expression(void)
                return parse_offsetof();
        case T___builtin_va_arg:
                return parse_va_arg();
+       case T___builtin_alloca:
        case T___builtin_expect:
        case T___builtin_va_start:
        case T___builtin_va_end:
@@ -4304,6 +4330,7 @@ void init_parser(void)
        type_ptrdiff_t   = make_atomic_type(ATOMIC_TYPE_LONG, 0);
        type_const_char  = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST);
        type_void        = make_atomic_type(ATOMIC_TYPE_VOID, 0);
+       type_void_ptr    = make_pointer_type(type_void, 0);
        type_string      = make_pointer_type(type_const_char, 0);
 }
 
index bed58e0..3090976 100644 (file)
@@ -52,6 +52,7 @@ S(__builtin_offsetof)
 S(__builtin_va_start)
 S(__builtin_va_arg)
 S(__builtin_va_end)
+S(__builtin_alloca)
 S(__PRETTY_FUNCTION__)
 S(__FUNCTION__)
 S(__func__)