diff gcc/c-parser.c @ 1:caeb520cebed

patch for CbC
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2009 17:43:54 +0900
parents a06113de4d67
children 0b3575e68bac
line wrap: on
line diff
--- a/gcc/c-parser.c	Fri Jul 17 14:47:48 2009 +0900
+++ b/gcc/c-parser.c	Fri Jul 17 17:43:54 2009 +0900
@@ -57,6 +57,9 @@
 #include "vec.h"
 #include "target.h"
 #include "cgraph.h"
+#ifndef noCbC
+#include "cbc-tree.h"
+#endif
 
 
 /* Initialization routine for this file.  */
@@ -465,6 +468,12 @@
 	case RID_FRACT:
 	case RID_ACCUM:
 	case RID_SAT:
+#ifndef noCbC
+	case RID_CbC_CODE:
+#endif
+#ifndef noCbC
+	case RID_CbC_CODE:
+#endif
 	  return true;
 	default:
 	  return false;
@@ -1518,6 +1527,9 @@
 	case RID_FRACT:
 	case RID_ACCUM:
 	case RID_SAT:
+#ifndef noCbC
+	case RID_CbC_CODE:
+#endif
 	  if (!typespec_ok)
 	    goto out;
 	  attrs_ok = true;
@@ -3701,8 +3713,14 @@
 	  break;
 	case RID_GOTO:
 	  c_parser_consume_token (parser);
+#ifndef noCbC
+	  if ( c_parser_next_token_is (parser, CPP_NAME) 
+	       && c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON )
+	    {
+#else
 	  if (c_parser_next_token_is (parser, CPP_NAME))
 	    {
+#endif
 	      stmt = c_finish_goto_label (c_parser_peek_token (parser)->value);
 	      c_parser_consume_token (parser);
 	    }
@@ -3712,7 +3730,79 @@
 	      stmt = c_finish_goto_ptr (c_parser_expression (parser).value);
 	    }
 	  else
+#ifndef noCbC
+	    {
+	      struct c_expr expr;
+	      if (c_parser_next_token_is (parser, CPP_NAME)) 
+		{
+		  tree id = c_parser_peek_token (parser)->value;
+                  location_t loc = c_parser_peek_token (parser)->location;
+		  build_external_ref (id,RID_CbC_CODE , loc);
+		}
+	      expr = c_parser_expr_no_commas (parser, NULL);
+	      if (TREE_CODE(expr.value) == CALL_EXPR )
+		{
+		  TREE_TYPE(expr.value) = void_type_node;
+		  if (c_parser_next_token_is (parser, CPP_COMMA)) 
+		    {
+		      struct c_expr env;
+		      tree field, fields=NULL_TREE;
+		      tree env_struct, env_struct_type;
+		      tree ebp, argsp;
+		      tree tmp;
+
+		      c_parser_consume_token (parser);
+		      env = c_parser_expr_no_commas (parser, NULL);
+		      env = default_function_array_conversion (env);
+
+			/* build type_node of environment structure  */
+			env_struct_type = start_struct (RECORD_TYPE, NULL_TREE);
+			field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node);
+			fields = chainon (field, fields);
+			field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node);
+			fields = chainon (field, fields);
+			//field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node);
+			//fields = chainon (field, fields);
+			fields = nreverse(fields);
+			finish_struct (env_struct_type, fields, NULL_TREE);
+
+			env_struct = build_c_cast (build_pointer_type(env_struct_type), env.value);
+			//build_component_ref (cbc_env, get_identifier("argsp"));
+			ebp = build_component_ref (build_indirect_ref (env_struct, "CbCenv->sp"), get_identifier("sp"));
+			argsp = build_component_ref (build_indirect_ref (env_struct, "CbCenv->sp"), get_identifier("argsp"));
+			//ebp = chainon (ebp, argsp);
+			tmp = build_tree_list (ebp, argsp);
+
+		      TREE_OPERAND (expr.value, 2) = tmp;
+
+
+		      /*
+		      c_parser_consume_token (parser);
+		      expr = default_function_array_conversion (expr);
+			ident = c_parser_peek_token (parser)->value;
+		      c_parser_consume_token (parser);
+		      expr.value = build_component_ref (build_indirect_ref (expr.value,
+			    "->"), ident);
+		      expr.original_code = ERROR_MARK;
+		      */
+
+
+		    }
+		  else
+		    TREE_OPERAND (expr.value, 2) = NULL_TREE;
+		  CbC_IS_CbC_GOTO (expr.value) = 1;
+		  CALL_EXPR_TAILCALL (expr.value) = 1;
+		  add_stmt(expr.value);
+		  CbC_HAVE_CbC_GOTO (current_function_decl) = 1;
+		  // should be match with function type?
+		  stmt = c_finish_return (0);
+		}
+	      else
+		c_parser_error (parser, "expected code segment jump or %<*%>");
+	    }
+#else
 	    c_parser_error (parser, "expected identifier or %<*%>");
+#endif
 	  goto expect_semicolon;
 	case RID_CONTINUE:
 	  c_parser_consume_token (parser);
@@ -5093,6 +5183,7 @@
 {
   struct c_expr expr, e1, e2, e3;
   struct c_type_name *t1, *t2;
+  static tree return_label1;
   location_t loc;
   switch (c_parser_peek_token (parser)->type)
     {
@@ -5490,6 +5581,239 @@
 	    expr.original_code = ERROR_MARK;
 	  }
 	  break;
+#ifndef noCbC
+	case RID_CbC_ENV:
+          {
+#if 0
+	    tree valuep_tree;
+	    tree value_tree;
+	    tree env_tree;
+
+	    tree exprstmt;
+	    tree stmt = c_begin_stmt_expr ();
+	    /*
+	     * __value = {
+	     *   void *ebp;
+	     *   char args[sizeof(arguments)];
+	     * };
+	     *
+	     *  __env = ({
+	     *    ebp = __builtin_frame_address(0);
+	     *    *__value=ebp;
+	     *    __value;
+	     *  })
+	     */
+
+	    /* get value of %ebp.  */
+	    env_tree = build_external_ref (
+		        get_identifier ("__builtin_frame_address"), 0,
+			c_parser_peek_token (parser)->location);
+	    env_tree = build_function_call(env_tree, 
+			   build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0)));
+
+	    /* ebp = __builtin_frame_address(0)  */
+	    valuep_tree = build_decl (VAR_DECL, get_identifier("__value"), intTI_type_node);
+	    TREE_STATIC (valuep_tree) = 1;
+	    lang_hooks.decls.pushdecl(valuep_tree);
+	    /* cast __value to pointer to pointer to void.  */
+	    valuep_tree = build_c_cast (build_pointer_type(ptr_type_node), valuep_tree);
+	    value_tree = build_indirect_ref (valuep_tree, "cbc: *__value");
+
+	    /* *__value = ebp;  */
+	    exprstmt = build_modify_expr (value_tree, NOP_EXPR, env_tree);
+	    add_stmt(exprstmt);
+
+	    /* __value;  */
+	    add_stmt(valuep_tree);
+#else
+
+	    //tree env;        // environment structure
+	    tree env_struct; // type of environment structure
+	    tree field;
+	    tree fields=NULL_TREE;
+	    tree comp, comp0;       // component of environment
+	    tree ebp;
+
+	    tree stmt = c_begin_stmt_expr ();
+
+	    /*
+	     * struct {
+	     *     void *sp;     <= %ebp
+	     *     void *argp;   <= &__environment.retval
+	     *     int retval;  // int? or return type of this function
+	     * } __CbCenv;
+	     *
+	     * __environment = &__CbCenv;
+	     *
+	     */
+
+	    if (!cbc_env)
+	      {
+		/* build type_node of environment structure  */
+		env_struct = start_struct (RECORD_TYPE, NULL_TREE);
+		field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node);
+		fields = chainon (field, fields);
+		field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node);
+		fields = chainon (field, fields);
+		field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node);
+		fields = chainon (field, fields);
+		fields = nreverse(fields);
+		//env_struct = make_node(RECORD_TYPE);
+		//TYPE_FIELDS (env_struct) = fields;
+		finish_struct (env_struct, fields, NULL_TREE);
+
+		/* declare __environment structure.  */
+		cbc_env = build_decl (VAR_DECL, get_identifier("__CbCenv"), env_struct);
+		TREE_STATIC (cbc_env) = 1;
+		lang_hooks.decls.pushdecl(cbc_env);
+	      }
+
+	    /* get value of %ebp.  */
+	    ebp = build_external_ref (
+		        get_identifier ("__builtin_frame_address"), 0,
+			c_parser_peek_token (parser)->location);
+	    ebp = build_function_call(ebp, 
+			   build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0)));
+
+	    /* assignment  void *sp = %ebp  */
+	    comp = build_component_ref (cbc_env, get_identifier("sp"));
+	    add_stmt (build_modify_expr (comp, NOP_EXPR, ebp));
+
+	    /* void *argsp = &__environment.retval  */
+	    comp = build_component_ref (cbc_env, get_identifier("argsp"));
+	    comp0 = build_component_ref (cbc_env, get_identifier("retval"));
+	    comp0 = build_unary_op (ADDR_EXPR, comp0, 0);
+	    add_stmt (build_modify_expr (comp, NOP_EXPR, comp0));
+
+
+	    /* &__environment for value of stmt_expr. */
+	    add_stmt (build_unary_op (ADDR_EXPR, cbc_env, 0));
+#endif
+	    //expr.value = valuep_tree;
+	    TREE_SIDE_EFFECTS (stmt) = 1;
+	    expr.value = c_finish_stmt_expr (stmt);
+	    //expr.value = build_unary_op (ADDR_EXPR, env, 0);
+	    c_parser_consume_token (parser);
+          }
+	  break;
+	case RID_CbC_RET:
+	case RID_RETURN:
+#if 1
+	  if (cbc_return_f==0) {
+	      tree retval;
+
+              /*
+                   Generates something like...
+
+                   __return = ({
+                       static volatile int __return;
+                       if (__return) {
+                       return_label:
+                            return value;
+                       }
+                       &&return_label;
+                   })
+               */
+
+	      tree stmt = c_begin_stmt_expr ();
+              cbc_return_f = c_parser_peek_token (parser)->value;
+              cbc_return = c_parser_peek_token (parser)->location;
+	      c_parser_consume_token (parser);
+              location_t next = c_parser_peek_token (parser)->location;
+
+              // dummy variable for hidden condition
+	      struct c_expr cexpr;
+	      tree cond;
+	      location_t loc;
+	      loc = next;
+              tree decl_cond = 
+		    build_decl (VAR_DECL, get_identifier ("__return"),
+		    intHI_type_node);
+              TREE_STATIC (decl_cond) = 1;
+	      cexpr.value = lang_hooks.decls.pushdecl(decl_cond);
+
+	      cexpr.original_code = ERROR_MARK;
+	      cond = c_objc_common_truthvalue_conversion(cexpr.value);
+	      if (EXPR_P (cond))
+		SET_EXPR_LOCATION (cond, loc);
+
+
+
+
+	      tree fwlabel = create_artificial_label ();
+	      //TREE_USED(fwlabel) = 1;
+
+	      //add_stmt (build1 (GOTO_EXPR, void_type_node, fwlabel));
+	      tree block = c_begin_compound_stmt (flag_isoc99);
+
+	      tree tlab = lookup_label(cbc_return_f);
+
+	      tree decl= build_stmt (LABEL_EXPR, tlab);
+	      //TREE_USED(decl) = 1;
+	      add_stmt(decl);
+
+	      //tree hoge = build_int_cst(NULL_TREE,55);
+		if (!cbc_env)
+		  {
+		      tree field,fields,env_struct;
+		    /* build type_node of environment structure  */
+		    env_struct = start_struct (RECORD_TYPE, NULL_TREE);
+		    field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node);
+		    fields = chainon (field, fields);
+		    field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node);
+		    fields = chainon (field, fields);
+		    field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node);
+		    fields = chainon (field, fields);
+		    fields = nreverse(fields);
+		    //env_struct = make_node(RECORD_TYPE);
+		    //TYPE_FIELDS (env_struct) = fields;
+		    finish_struct (env_struct, fields, NULL_TREE);
+
+		    /* declare __environment structure.  */
+		    cbc_env = build_decl (VAR_DECL, get_identifier("__CbCenv"), env_struct);
+		    TREE_STATIC (cbc_env) = 1;
+		    lang_hooks.decls.pushdecl(cbc_env);
+		  }
+		retval = build_component_ref (cbc_env, get_identifier("retval"));
+	      tree ret = c_finish_return (retval); 
+	      TREE_USED(ret) = 1;
+	      tree first_body = c_end_compound_stmt (block, flag_isoc99);
+
+              c_finish_if_stmt (loc, cond, first_body, NULL_TREE, false);
+
+	      // define_label(EXPR_LOCATION(decl) ,cbc_return_f);
+	      return_label1 = 
+		   define_label(cbc_return ,cbc_return_f);
+	      tree fwdef= build_stmt (LABEL_EXPR, fwlabel);
+
+	      //TREE_USED(fwdef) = 1;
+	      add_stmt(fwdef);
+	      TREE_SIDE_EFFECTS (block) = 1;
+
+	      // tree label = lookup_label(c_parser_peek_token (parser)->value);
+	      //TREE_USED(label) = 1;
+
+	      tree value = build1(ADDR_EXPR, ptr_type_node, return_label1);
+              SET_EXPR_LOCATION (value, next);
+	      TREE_SIDE_EFFECTS (value) = 1;
+	      add_stmt(value);
+
+	      TREE_SIDE_EFFECTS (stmt) = 1;
+	      expr.value = c_finish_stmt_expr (stmt);
+	      expr.original_code = ERROR_MARK;
+
+	      // cbc_return_f =0;
+
+	  } else {
+	      //tree label = lookup_label(c_parser_peek_token (parser)->value);
+	      //TREE_USED(label) = 1;
+	      //expr.value = build1(ADDR_EXPR, ptr_type_node, label);
+	      expr.value = build1(ADDR_EXPR, ptr_type_node, return_label1);
+	      c_parser_consume_token (parser);
+          }
+	  break;
+#endif
+#endif
 	default:
 	  c_parser_error (parser, "expected expression");
 	  expr.value = error_mark_node;