# HG changeset patch # User Shinji KONO # Date 1247820234 -32400 # Node ID caeb520cebed99a8d6fb7654026e249ef7020f51 # Parent a06113de4d676b497759e6a9bf820a208b02e09b patch for CbC diff -r a06113de4d67 -r caeb520cebed gcc/Makefile.in --- a/gcc/Makefile.in Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/Makefile.in Fri Jul 17 17:43:54 2009 +0900 @@ -2521,7 +2521,7 @@ hard-reg-set.h $(TOPLEV_H) hard-reg-set.h except.h $(TM_P_H) $(PREDICT_H) \ libfuncs.h $(REAL_H) langhooks.h $(BASIC_BLOCK_H) tree-mudflap.h \ $(BUILTINS_DEF) $(MACHMODE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) value-prof.h -calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ +calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) cbc-goto.h coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \ libfuncs.h $(REGS_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_P_H) \ $(CGRAPH_H) except.h sbitmap.h $(DBGCNT_H) $(TREE_FLOW_H) diff -r a06113de4d67 -r caeb520cebed gcc/c-common.c --- a/gcc/c-common.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/c-common.c Fri Jul 17 17:43:54 2009 +0900 @@ -616,6 +616,10 @@ { "__asm__", RID_ASM, 0 }, { "__attribute", RID_ATTRIBUTE, 0 }, { "__attribute__", RID_ATTRIBUTE, 0 }, +#ifndef noCbC + /* CbC project */ + { "__code", RID_CbC_CODE, 0 }, +#endif { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY }, { "__builtin_offsetof", RID_OFFSETOF, 0 }, { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY }, @@ -624,6 +628,11 @@ { "__complex__", RID_COMPLEX, 0 }, { "__const", RID_CONST, 0 }, { "__const__", RID_CONST, 0 }, +#ifndef noCbC + /* CbC project */ + { "__environment", RID_CbC_ENV, 0 }, + { "__return", RID_CbC_RET, 0 }, +#endif { "__decltype", RID_DECLTYPE, D_CXXONLY }, { "__extension__", RID_EXTENSION, 0 }, { "__func__", RID_C99_FUNCTION_NAME, 0 }, diff -r a06113de4d67 -r caeb520cebed gcc/c-common.h --- a/gcc/c-common.h Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/c-common.h Fri Jul 17 17:43:54 2009 +0900 @@ -119,6 +119,11 @@ RID_AT_INTERFACE, RID_AT_IMPLEMENTATION, +#ifndef noCbC + /* Continuation based C */ + RID_CbC_CODE, RID_CbC_ENV, RID_CbC_RET, +#endif + RID_MAX, RID_FIRST_MODIFIER = RID_STATIC, diff -r a06113de4d67 -r caeb520cebed gcc/c-decl.c --- a/gcc/c-decl.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/c-decl.c Fri Jul 17 17:43:54 2009 +0900 @@ -63,6 +63,13 @@ #include "langhooks-def.h" #include "pointer-set.h" #include "gimple.h" +#ifndef noCbC +#include "cbc-tree.h" +tree cbc_env; +tree cbc_return_f; +location_t cbc_return; +#endif + /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -2339,8 +2346,13 @@ /* Generate an implicit declaration for identifier FUNCTIONID as a function of type int (). */ +#ifndef noCbC +tree +implicitly_declare (tree functionid, int fun) +#else tree implicitly_declare (tree functionid) +#endif { struct c_binding *b; tree decl = 0; @@ -2415,7 +2427,12 @@ } /* Not seen before. */ +#ifndef noCbC + decl = build_decl (FUNCTION_DECL, functionid, + fun==RID_CbC_CODE?build_function_type (void_type_node, NULL_TREE):default_function_type); +#else decl = build_decl (FUNCTION_DECL, functionid, default_function_type); +#endif DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; C_DECL_IMPLICIT (decl) = 1; @@ -4560,7 +4577,17 @@ } type_quals = TYPE_UNQUALIFIED; - type = build_function_type (type, arg_types); +#ifndef noCbC + if ( declspecs->typespec_word == cts_CbC_code ) + { + type = build_code_segment_type (type, arg_types); + } + else +#endif + { + type = build_function_type (type, arg_types); + } + declarator = declarator->declarator; /* Set the TYPE_CONTEXTs for each tagged type which is local to @@ -6072,6 +6099,68 @@ return tree_cons (decl, value, NULL_TREE); } +#ifndef noCbC +#define CbC_STACK_SIZE (1024 * 8) +static void cbc_set_codesegment(tree fndecl){ + tree args; + tree *nextp; +// tree itype; +// tree icst; +// tree padding_array; +// tree list; + int padding_size = CbC_STACK_SIZE; + + //CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) = 1; + //CbC_IS_CODE_SEGMENT(fndecl) = 1; + + nextp = & TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + for (args = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); args; + args = TREE_CHAIN (args)) + { + tree type = args ? TREE_VALUE (args) : 0; + tree type_size; + unsigned int size; + + if (type == void_type_node) + break; + + type_size = TYPE_SIZE (type); + size = TREE_INT_CST_LOW (type_size); + padding_size -= size; + + nextp = & TREE_CHAIN(args); + } + + /* error check. */ + if (padding_size<0) + { + error ("CbC: too many arguments on code segment %qE", fndecl); + return ; + } + else if (padding_size==0) + return ; + +#if 0 + /* itype is integer_type that means last index. */ + icst = build_int_cst (NULL_TREE, padding_size-1); + itype = build_index_type (icst); + + /* create array_type node. */ + padding_array = build_array_type (integer_type_node, itype); + + /* add array_type to this function's argument list + before void_type_node. */ + if (!args) + args = build_tree_list(NULL_TREE, void_type_node); + list = build_tree_list(NULL_TREE, padding_array); + TREE_CHAIN(list) = args; + *nextp = list; +#endif + + return ; +} +#endif + /* Create the FUNCTION_DECL for a function definition. DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of @@ -6121,6 +6210,16 @@ decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, &attributes, DEPRECATED_NORMAL); +#ifndef noCbC + cbc_return_f = NULL_TREE; + cbc_env = NULL_TREE; + if ( declspecs->typespec_word == cts_CbC_code ) + { + cbc_set_codesegment(decl1); + //CbC_IS_CODE_SEGMENT(TREE_TYPE(decl1)) = 1; + } +#endif + /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == 0) @@ -7249,6 +7348,11 @@ else if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error ("both % and % in " + "declaration specifiers"); +#endif else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); @@ -7278,6 +7382,11 @@ else if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error ("both % and % in " + "declaration specifiers"); +#endif else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); @@ -7310,6 +7419,11 @@ else if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error ("both % and % in " + "declaration specifiers"); +#endif else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); @@ -7339,6 +7453,11 @@ else if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error ("both % and % in " + "declaration specifiers"); +#endif else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); @@ -7367,6 +7486,11 @@ if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error ("both % and % in " + "declaration specifiers"); +#endif else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); @@ -7469,6 +7593,27 @@ else specs->typespec_word = cts_void; return specs; +#ifndef noCbC + case RID_CbC_CODE: + if (specs->long_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->short_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->signed_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->unsigned_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->complex_p) + error ("both % and % in " + "declaration specifiers"); + else + specs->typespec_word = cts_CbC_code; + return specs; +#endif case RID_BOOL: if (specs->long_p) error ("both % and %<_Bool%> in " @@ -7823,6 +7968,9 @@ switch (specs->typespec_word) { case cts_void: +#ifndef noCbC + case cts_CbC_code: +#endif gcc_assert (!specs->long_p && !specs->short_p && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); diff -r a06113de4d67 -r caeb520cebed gcc/c-parser.c --- 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; diff -r a06113de4d67 -r caeb520cebed gcc/c-tree.h --- a/gcc/c-tree.h Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/c-tree.h Fri Jul 17 17:43:54 2009 +0900 @@ -213,6 +213,9 @@ cts_int, cts_float, cts_double, +#ifndef noCbC + cts_CbC_code, +#endif cts_dfloat32, cts_dfloat64, cts_dfloat128, @@ -480,7 +483,11 @@ struct c_declspecs *, tree, tree *); extern tree groktypename (struct c_type_name *); extern tree grokparm (const struct c_parm *); +#ifndef noCbC +extern tree implicitly_declare (tree,int); +#else extern tree implicitly_declare (tree); +#endif extern void keep_next_level (void); extern void pending_xref_error (void); extern void c_push_function_context (void); diff -r a06113de4d67 -r caeb520cebed gcc/c-typeck.c --- a/gcc/c-typeck.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/c-typeck.c Fri Jul 17 17:43:54 2009 +0900 @@ -44,6 +44,9 @@ #include "tree-iterator.h" #include "gimple.h" #include "tree-flow.h" +#ifndef noCbC + #include "cbc-tree.h" +#endif /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ @@ -403,6 +406,9 @@ /* Function types: prefer the one that specified arg types. If both do, merge the arg types. Also merge the return types. */ { +#ifndef noCbC + int is_code_segment = CbC_IS_CODE_SEGMENT(t1); +#endif tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); @@ -419,12 +425,20 @@ /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == 0) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t2)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); } if (TYPE_ARG_TYPES (t2) == 0) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t1)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); @@ -518,6 +532,11 @@ } c_override_global_bindings_to_false = false; + +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, newargs); + else +#endif t1 = build_function_type (valtype, newargs); t1 = qualify_type (t1, t2); /* ... falls through ... */ @@ -2199,7 +2218,11 @@ ref = decl; else if (fun) /* Implicit function declaration. */ +#ifndef noCbC + ref = implicitly_declare (id, fun); +#else ref = implicitly_declare (id); +#endif else if (decl == error_mark_node) /* Don't complain about something that's already been complained about. */ @@ -2743,7 +2766,13 @@ gcc_assert (parmnum == nargs); +#ifndef noCbC + if (typetail != 0 && TREE_VALUE (typetail) != void_type_node + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(fundecl)) ) + && !(fundecl&&CbC_IS_CODE_SEGMENT(fundecl)) ) +#else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) +#endif { error ("too few arguments to function %qE", function); return -1; diff -r a06113de4d67 -r caeb520cebed gcc/calls.c --- a/gcc/calls.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/calls.c Fri Jul 17 17:43:54 2009 +0900 @@ -98,6 +98,9 @@ word-sized pseudos we made. */ rtx *aligned_regs; int n_aligned_regs; +#ifndef noCbC +rtx exprs; +#endif }; /* A vector of one char per byte of stack space. A byte if nonzero if @@ -1879,6 +1882,11 @@ return true; } +#ifndef noCbC +#include "cbc-tree.h" +#include "cbc-goto.h" +#endif + /* If X is a likely-spilled register value, copy it to a pseudo register and return that register. Return X otherwise. */ @@ -1904,7 +1912,7 @@ return x; } -/* Generate all the code for a CALL_EXPR exp +/* Generate all the code for a function call and return an rtx for its value. Store the value in TARGET (specified as an rtx) if convenient. If the value is stored in TARGET then TARGET is returned. @@ -2374,6 +2382,39 @@ preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; +#ifndef noCbC + if ( fntype + //&& CbC_IS_CODE_SEGMENT (fntype) + //&& fndecl + //&& CbC_IS_CODE_SEGMENT (fndecl) + //&& CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) + //&& CALL_EXPR_TAILCALL (exp) + && CbC_IS_CbC_GOTO (exp) // it's better? than CALL_EXPR_TAILCALL() + ) + { + + // fprintf(stderr, "\n\tgoto code segment.\n"); + args_size.constant = CbC_ARGS_SIZE; + return expand_cbc_goto(exp, target, fndecl, funtype, + addr, ignore, flags, num_actuals, args, &args_size, + args_so_far, + old_stack_level, reg_parm_stack_space, old_pending_adj, + preferred_stack_boundary, preferred_unit_stack_boundary, + structure_value_addr, old_inhibit_defer_pop); + } + else if ( fndecl&&CbC_HAVE_CbC_GOTO(fndecl) ) + { + char *name = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + fprintf(stderr, "\nCbC: function %s having CbCgoto statement has been `CALLED'.\n", name); + //args_size.constant = CbC_ARGS_SIZE; + } + else if ( fntype&&CbC_IS_CODE_SEGMENT(fntype) ) + { + char *name = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + fprintf(stderr, "\nCbC error: codesegment %s has been `CALLED!'.\n", name); + } +#endif + /* We want to make two insn chains; one for a sibling call, the other for a normal call. We will select one of the two chains after initial RTL generation is complete. */ @@ -2444,12 +2485,27 @@ and there may be a minimum required size. When generating a sibcall pattern, do not round up, since we'll be re-using whatever space our caller provided. */ +#ifndef noCbC + if ( ( fntype && CbC_IS_CODE_SEGMENT(fntype) ) + || ( fndecl && CbC_HAVE_CbC_GOTO(fndecl) ) ) + { + unadjusted_args_size = args_size.constant; + adjusted_args_size.constant = CbC_ARGS_SIZE; + compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } + else +#endif + { unadjusted_args_size = compute_argument_block_size (reg_parm_stack_space, &adjusted_args_size, fndecl, fntype, (pass == 0 ? 0 : preferred_stack_boundary)); + } old_stack_allocated = stack_pointer_delta - pending_stack_adjust; diff -r a06113de4d67 -r caeb520cebed gcc/cbc-tree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/cbc-tree.h Fri Jul 17 17:43:54 2009 +0900 @@ -0,0 +1,16 @@ +/* Set if the fntype is code segment on CbC language. */ +// flag3,5,6 has been used by c-tree.h +#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 ( FUNCTION_TYPE_CHECK(TYPE)) +#define CbC_HAVE_CbC_GOTO(EXP) DECL_LANG_FLAG_4 (FUNCTION_DECL_CHECK (EXP)) + +/* Set if the CALL_EXPR NODE is goto statement on CbC language. */ +//#define CbC_IS_CbC_GOTO(NODE) (CALL_EXPR_CHECK(NODE)->common.lang_flag_5) + +// old difinition +//#define CbC_IS_CODE_SEGMENT(EXP) DECL_LANG_FLAG_7 (FUNCTION_DECL_CHECK (EXP)) +//#define CbC_IS_CODE_SEGMENT(NODE) (TYPE_CHECK (NODE)->type.lang_flag_5) +#define CbC_IS_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) + +extern tree cbc_return_f; +extern tree cbc_env; +extern location_t cbc_return; diff -r a06113de4d67 -r caeb520cebed gcc/function.c --- a/gcc/function.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/function.c Fri Jul 17 17:43:54 2009 +0900 @@ -3228,6 +3228,11 @@ SET_DECL_RTL (result, x); } +#ifndef noCbC + //if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) + //all.stack_args_size.constant = CbC_STACK_SIZE; +#endif + /* We have aligned all the args, so add space for the pretend args. */ crtl->args.pretend_args_size = all.pretend_args_size; all.stack_args_size.constant += all.extra_pretend_bytes; diff -r a06113de4d67 -r caeb520cebed gcc/gcc.c --- a/gcc/gcc.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/gcc.c Fri Jul 17 17:43:54 2009 +0900 @@ -988,6 +988,9 @@ {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, /* Next come the entries for C. */ {".c", "@c", 0, 1, 1}, +#ifndef noCbC + {".cbc", "@c", 0, 1, 1}, +#endif {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ diff -r a06113de4d67 -r caeb520cebed gcc/gimplify.c --- a/gcc/gimplify.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/gimplify.c Fri Jul 17 17:43:54 2009 +0900 @@ -52,6 +52,10 @@ #include "splay-tree.h" #include "vec.h" #include "gimple.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif + enum gimplify_omp_var_data @@ -1329,7 +1333,16 @@ return GS_ALL_DONE; } - if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) + if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) +#ifndef noCbC + || ( ret_expr + && TREE_CODE(ret_expr)==CALL_EXPR + && CbC_IS_CbC_GOTO(ret_expr) + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl))) + && !(current_function_decl&&CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)))) + //&& !(current_function_decl&&CbC_IS_CODE_SEGMENT(current_function_decl))) +#endif + ) result_decl = NULL_TREE; else { diff -r a06113de4d67 -r caeb520cebed gcc/passes.c --- a/gcc/passes.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/passes.c Fri Jul 17 17:43:54 2009 +0900 @@ -518,7 +518,11 @@ NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_lower_complex_O0); NEXT_PASS (pass_lower_vector); +#ifndef noCbC + //NEXT_PASS (pass_warn_function_return); +#else NEXT_PASS (pass_warn_function_return); +#endif NEXT_PASS (pass_build_cgraph_edges); NEXT_PASS (pass_inline_parameters); *p = NULL; diff -r a06113de4d67 -r caeb520cebed gcc/tree-ssa-operands.c --- a/gcc/tree-ssa-operands.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/tree-ssa-operands.c Fri Jul 17 17:43:54 2009 +0900 @@ -34,6 +34,9 @@ #include "toplev.h" #include "langhooks.h" #include "ipa-reference.h" +#ifndef noCbC + #include "cbc-tree.h" +#endif /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt diff -r a06113de4d67 -r caeb520cebed gcc/tree.c --- a/gcc/tree.c Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/tree.c Fri Jul 17 17:43:54 2009 +0900 @@ -90,6 +90,10 @@ #undef DEFTREECODE #undef END_OF_BASE_TREE_CODES +#ifndef noCbC +#include "cbc-tree.h" +#endif + /* Each tree code class has an associated string representation. These must correspond to the tree_code_class entries. */ @@ -5808,6 +5812,28 @@ return type; } +#ifndef noCbC +tree +build_code_segment_type (tree value_type, tree arg_types) +{ + tree t; + hashval_t hashcode = 0; + + gcc_assert (TREE_CODE (value_type) == VOID_TYPE); + + /* Make a node of the sort we want. */ + t = make_node (FUNCTION_TYPE); + TREE_TYPE (t) = value_type; + TYPE_ARG_TYPES (t) = arg_types; + + CbC_IS_CODE_SEGMENT (t) = 1; + + if (!COMPLETE_TYPE_P (t)) + layout_type (t); + return t; +} +#endif + /* Computes the canonical argument types from the argument type list ARGTYPES. diff -r a06113de4d67 -r caeb520cebed gcc/tree.h --- a/gcc/tree.h Fri Jul 17 14:47:48 2009 +0900 +++ b/gcc/tree.h Fri Jul 17 17:43:54 2009 +0900 @@ -4017,6 +4017,9 @@ extern tree value_member (tree, tree); extern tree purpose_member (const_tree, tree); +#ifndef noCbC +extern tree build_code_segment_type (tree, tree); +#endif extern int attribute_list_equal (const_tree, const_tree); extern int attribute_list_contained (const_tree, const_tree); extern int tree_int_cst_equal (const_tree, const_tree);