diff options
Diffstat (limited to 'gcc/ch/tasking.c')
-rw-r--r-- | gcc/ch/tasking.c | 3432 |
1 files changed, 0 insertions, 3432 deletions
diff --git a/gcc/ch/tasking.c b/gcc/ch/tasking.c deleted file mode 100644 index 310ccb5c211..00000000000 --- a/gcc/ch/tasking.c +++ /dev/null @@ -1,3432 +0,0 @@ -/* Implement tasking-related actions for CHILL. - Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 - Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "ch-tree.h" -#include "flags.h" -#include "input.h" -#include "obstack.h" -#include "assert.h" -#include "tasking.h" -#include "lex.h" -#include "toplev.h" - -/* from ch-lex.l, from compiler directives */ -extern tree process_type; -extern tree send_signal_prio; -extern tree send_buffer_prio; - -tree tasking_message_type; -tree instance_type_node; -tree generic_signal_type_node; - -/* the type a tasking code variable has */ -tree chill_taskingcode_type_node; - -/* forward declarations */ -#if 0 -static void validate_process_parameters PARAMS ((tree)); -static tree get_struct_variable_name PARAMS ((tree)); -static tree decl_tasking_code_variable PARAMS ((tree, tree *, int)); -#endif -static tree get_struct_debug_type_name PARAMS ((tree)); -static tree get_process_wrapper_name PARAMS ((tree)); -static tree build_tasking_enum PARAMS ((void)); -static void build_tasking_message_type PARAMS ((void)); -static tree build_receive_signal_case_label PARAMS ((tree, tree)); -static tree build_receive_buffer_case_label PARAMS ((tree, tree)); -static void build_receive_buffer_case_end PARAMS ((tree, tree)); -static void build_receive_signal_case_end PARAMS ((tree, tree)); - -/* list of this module's process, buffer, etc. decls. - This is a list of TREE_VECs, chain by their TREE_CHAINs. */ -tree tasking_list = NULL_TREE; -/* The parts of a tasking_list element. */ -#define TASK_INFO_PDECL(NODE) TREE_VEC_ELT(NODE,0) -#define TASK_INFO_ENTRY(NODE) TREE_VEC_ELT(NODE,1) -#define TASK_INFO_CODE_DECL(NODE) TREE_VEC_ELT(NODE,2) -#define TASK_INFO_STUFF_NUM(NODE) TREE_VEC_ELT(NODE,3) -#define TASK_INFO_STUFF_TYPE(NODE) TREE_VEC_ELT(NODE,4) - -/* name template for process argument type */ -#define STRUCT_NAME "__tmp_%s_arg_type" - -/* name template for process arguments for debugging type */ -#define STRUCT_DEBUG_NAME "__tmp_%s_debug_type" - -/* name template for process argument variable */ -#define DATA_NAME "__tmp_%s_arg_variable" - -/* name template for process wrapper */ -#define WRAPPER_NAME "__tmp_%s_wrapper" - -/* name template for process code */ -#define SKELNAME "__tmp_%s_code" - -extern int ignoring; -static tree void_ftype_void; -static tree pointer_to_instance; -static tree infinite_buffer_event_length_node; - -tree -get_struct_type_name (name) - tree name; -{ - const char *idp = IDENTIFIER_POINTER (name); /* process name */ - char *tmpname = xmalloc (strlen (idp) + sizeof (STRUCT_NAME)); - - sprintf (tmpname, STRUCT_NAME, idp); - return get_identifier (tmpname); -} - -static tree -get_struct_debug_type_name (name) - tree name; -{ - const char *idp = IDENTIFIER_POINTER (name); /* process name */ - char *tmpname = xmalloc (strlen (idp) + sizeof (STRUCT_DEBUG_NAME)); - - sprintf (tmpname, STRUCT_DEBUG_NAME, idp); - return get_identifier (tmpname); -} - - -tree -get_tasking_code_name (name) - tree name; -{ - const char *name_str = IDENTIFIER_POINTER (name); - char *tmpname = (char *) alloca (IDENTIFIER_LENGTH (name) + - sizeof (SKELNAME)); - - sprintf (tmpname, SKELNAME, name_str); - return get_identifier (tmpname); -} - -#if 0 -static tree -get_struct_variable_name (name) - tree name; -{ - const char *idp = IDENTIFIER_POINTER (name); /* process name */ - char *tmpname = xmalloc (strlen (idp) + sizeof (DATA_NAME)); - - sprintf (tmpname, DATA_NAME, idp); - return get_identifier (tmpname); -} -#endif - -static tree -get_process_wrapper_name (name) - tree name; -{ - const char *idp = IDENTIFIER_POINTER (name); - char *tmpname = xmalloc (strlen (idp) + sizeof (WRAPPER_NAME)); - - sprintf (tmpname, WRAPPER_NAME, idp); - return get_identifier (tmpname); -} - -/* - * If this is a quasi declaration - parsed within a SPEC MODULE, - * QUASI_FLAG is TRUE, to indicate that the variable should not - * be initialized. The other module will do that. - */ -tree -generate_tasking_code_variable (name, tasking_code_ptr, quasi_flag) - tree name, *tasking_code_ptr; - int quasi_flag; -{ - - tree decl; - tree tasking_code_name = get_tasking_code_name (name); - - if (pass == 2 && ! quasi_flag && *tasking_code_ptr != NULL_TREE) - { - /* check for value should be assigned is out of range */ - if (TREE_INT_CST_LOW (*tasking_code_ptr) > - TREE_INT_CST_LOW (TYPE_MAX_VALUE (chill_taskingcode_type_node))) - error ("Tasking code %ld out of range for `%s'.", - (long) TREE_INT_CST_LOW (*tasking_code_ptr), - IDENTIFIER_POINTER (name)); - } - - decl = do_decl (tasking_code_name, - chill_taskingcode_type_node, 1, 1, - quasi_flag ? NULL_TREE : *tasking_code_ptr, - 0); - - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - if (pass == 2 && ! quasi_flag && *tasking_code_ptr != NULL_TREE) - *tasking_code_ptr = fold (build (PLUS_EXPR, chill_taskingcode_type_node, - integer_one_node, - *tasking_code_ptr)); - return decl; -} - - -/* - * If this is a quasi declaration - parsed within a SPEC MODULE, - * QUASI_FLAG is TRUE, to indicate that the variable should not - * be initialized. The other module will do that. This is just - * for BUFFERs and EVENTs. - */ -#if 0 -static tree -decl_tasking_code_variable (name, tasking_code_ptr, quasi_flag) - tree name, *tasking_code_ptr; - int quasi_flag; -{ - extern struct obstack permanent_obstack; - tree tasking_code_name = get_tasking_code_name (name); - tree decl; - - /* guarantee that RTL for the code_variable resides in - the permanent obstack. The BUFFER or EVENT may be - declared in a PROC, not at global scope... */ - push_obstacks (&permanent_obstack, &permanent_obstack); - push_obstacks_nochange (); - - if (pass == 2 && ! quasi_flag && *tasking_code_ptr != NULL_TREE) - { - /* check for value should be assigned is out of range */ - if (TREE_INT_CST_LOW (*tasking_code_ptr) > - TREE_INT_CST_LOW (TYPE_MAX_VALUE (chill_taskingcode_type_node))) - error ("Tasking code %ld out of range for `%s'.", - (long) TREE_INT_CST_LOW (*tasking_code_ptr), - IDENTIFIER_POINTER (name)); - } - - decl = decl_temp1 (tasking_code_name, - chill_taskingcode_type_node, 1, - quasi_flag ? NULL_TREE : *tasking_code_ptr, - 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - /* Return to the ambient context. */ - pop_obstacks (); - - if (pass == 2 && ! quasi_flag && *tasking_code_ptr != NULL_TREE) - *tasking_code_ptr = fold (build (PLUS_EXPR, chill_taskingcode_type_node, - integer_one_node, - *tasking_code_ptr)); - return decl; -} -#endif - -/* - * Transmute a process parameter list into an argument structure - * TYPE_DECL for the start_process call to reference. Create a - * proc_type variable for later. Returns the new struct type. - */ -tree -make_process_struct (name, processparlist) - tree name, processparlist; -{ - tree temp; - tree a_parm; - tree field_decls = NULL_TREE; - - if (name == NULL_TREE || TREE_CODE (name) == ERROR_MARK) - return error_mark_node; - - if (processparlist == NULL_TREE) - return tree_cons (NULL_TREE, NULL_TREE, void_list_node); - - if (TREE_CODE (processparlist) == ERROR_MARK) - return error_mark_node; - - /* build list of field decls for build_chill_struct_type */ - for (a_parm = processparlist; a_parm != NULL_TREE; - a_parm = TREE_CHAIN (a_parm)) - { - tree parnamelist = TREE_VALUE (a_parm); - tree purpose = TREE_PURPOSE (a_parm); - tree mode = TREE_VALUE (purpose); - tree parm_attr = TREE_PURPOSE (purpose); - tree field; - - /* build a FIELD_DECL node */ - if (parm_attr != NULL_TREE) - { - if (parm_attr == ridpointers[(int)RID_LOC]) - mode = build_chill_reference_type (mode); - else if (parm_attr == ridpointers[(int)RID_IN]) - ; - else if (pass == 1) - { - for (field = parnamelist; field != NULL_TREE; - field = TREE_CHAIN (field)) - error ("invalid attribute for argument `%s' (only IN or LOC allowed).", - IDENTIFIER_POINTER (TREE_VALUE (field))); - } - } - - field = grok_chill_fixedfields (parnamelist, mode, NULL_TREE); - - /* chain the fields in reverse */ - if (field_decls == NULL_TREE) - field_decls = field; - else - chainon (field_decls, field); - } - - temp = build_chill_struct_type (field_decls); - return temp; -} - -/* Build a function for a PROCESS and define some - types for the process arguments. - After the PROCESS a wrapper function will be - generated which gets the PROCESS arguments via a pointer - to a structure having the same layout as the arguments. - This wrapper function then will call the PROCESS. - The advantage in doing it this way is, that PROCESS - arguments may be displayed by gdb without any change - to gdb. -*/ -tree -build_process_header (plabel, paramlist) - tree plabel, paramlist; -{ - tree struct_ptr_type = NULL_TREE; - tree new_param_list = NULL_TREE; - tree struct_decl = NULL_TREE; - tree process_struct = NULL_TREE; - tree struct_debug_type = NULL_TREE; - tree code_decl; - - if (! global_bindings_p ()) - { - error ("PROCESS may only be declared at module level"); - return error_mark_node; - } - - if (paramlist) - { - /* must make the structure OUTSIDE the parameter scope */ - if (pass == 1) - { - process_struct = make_process_struct (plabel, paramlist); - struct_ptr_type = build_chill_pointer_type (process_struct); - } - else - { - process_struct = NULL_TREE; - struct_ptr_type = NULL_TREE; - } - - struct_decl = push_modedef (get_struct_type_name (plabel), - struct_ptr_type, -1); - DECL_SOURCE_LINE (struct_decl) = 0; - struct_debug_type = push_modedef (get_struct_debug_type_name (plabel), - process_struct, -1); - DECL_SOURCE_LINE (struct_debug_type) = 0; - - if (pass == 2) - { - /* build a list of PARM_DECL's */ - tree wrk = paramlist; - tree tmp, list = NULL_TREE; - - while (wrk != NULL_TREE) - { - tree wrk1 = TREE_VALUE (wrk); - - while (wrk1 != NULL_TREE) - { - tmp = make_node (PARM_DECL); - DECL_ASSEMBLER_NAME (tmp) = DECL_NAME (tmp) = TREE_VALUE (wrk1); - if (list == NULL_TREE) - new_param_list = list = tmp; - else - { - TREE_CHAIN (list) = tmp; - list = tmp; - } - wrk1 = TREE_CHAIN (wrk1); - } - wrk = TREE_CHAIN (wrk); - } - } - else - { - /* build a list of modes */ - tree wrk = paramlist; - - while (wrk != NULL_TREE) - { - tree wrk1 = TREE_VALUE (wrk); - - while (wrk1 != NULL_TREE) - { - new_param_list = tree_cons (TREE_PURPOSE (TREE_PURPOSE (wrk)), - TREE_VALUE (TREE_PURPOSE (wrk)), - new_param_list); - wrk1 = TREE_CHAIN (wrk1); - } - wrk = TREE_CHAIN (wrk); - } - new_param_list = nreverse (new_param_list); - } - } - - /* declare the code variable outside the process */ - code_decl = generate_tasking_code_variable (plabel, - &process_type, 0); - - /* start the parameter scope */ - push_chill_function_context (); - - if (! start_chill_function (plabel, void_type_node, - new_param_list, NULL_TREE, NULL_TREE)) - return error_mark_node; - - current_module->procedure_seen = 1; - CH_DECL_PROCESS (current_function_decl) = 1; - /* remember the code variable in the function decl */ - DECL_TASKING_CODE_DECL (current_function_decl) = - (struct lang_decl *)code_decl; - if (paramlist == NULL_TREE) - /* do it here, cause we don't have a wrapper */ - add_taskstuff_to_list (code_decl, "_TT_Process", process_type, - current_function_decl, NULL_TREE); - - return perm_tree_cons (code_decl, struct_decl, NULL_TREE); -} - -/* Generate a function which gets a pointer - to an argument block and call the corresponding - PROCESS -*/ -void -build_process_wrapper (plabel, processdata) - tree plabel; - tree processdata; -{ - tree args = NULL_TREE; - tree wrapper = NULL_TREE; - tree parammode = TREE_VALUE (processdata); - tree code_decl = TREE_PURPOSE (processdata); - tree func = lookup_name (plabel); - - /* check the mode. If it is an ERROR_MARK there was an error - in build_process_header, if it is a NULL_TREE the process - don't have parameters, so we must not generate a wrapper */ - if (parammode == NULL_TREE || - TREE_CODE (parammode) == ERROR_MARK) - return; - - /* get the function name */ - wrapper = get_process_wrapper_name (plabel); - - /* build the argument */ - if (pass == 2) - { - /* build a PARM_DECL */ - args = make_node (PARM_DECL); - DECL_ASSEMBLER_NAME (args) = DECL_NAME (args) = get_identifier ("x"); - } - else - { - /* build a tree list with the mode */ - args = tree_cons (NULL_TREE, - TREE_TYPE (parammode), - NULL_TREE); - } - - /* start the function */ - push_chill_function_context (); - - if (! start_chill_function (wrapper, void_type_node, - args, NULL_TREE, NULL_TREE)) - return; - - /* to avoid granting */ - DECL_SOURCE_LINE (current_function_decl) = 0; - - if (! ignoring) - { - /* make the call to the PROCESS */ - tree wrk; - tree x = lookup_name (get_identifier ("x")); - /* no need to check this pointer to be NULL */ - tree indref = build_chill_indirect_ref (x, NULL_TREE, 0); - - args = NULL_TREE; - wrk = TYPE_FIELDS (TREE_TYPE (TREE_TYPE (x))); - while (wrk != NULL_TREE) - { - args = tree_cons (NULL_TREE, - build_component_ref (indref, DECL_NAME (wrk)), - args); - wrk = TREE_CHAIN (wrk); - } - CH_DECL_PROCESS (func) = 0; - expand_expr_stmt ( - build_chill_function_call (func, nreverse (args))); - CH_DECL_PROCESS (func) = 1; - } - - add_taskstuff_to_list (code_decl, "_TT_Process", process_type, - func, current_function_decl); - - /* finish the function */ - finish_chill_function (); - pop_chill_function_context (); -} - -/* Generate errors for INOUT, OUT parameters. - - "Only if LOC is specified may the mode have the non-value - property" - */ - -#if 0 -static void -validate_process_parameters (parms) - tree parms ATTRIBUTE_UNUSED; -{ -} -#endif - -/* - * build the tree for a start process action. Loop through the - * actual parameters, making a constructor list, which we use to - * initialize the argument structure. NAME is the process' name. - * COPYNUM is its copy number, whatever that is. EXPRLIST is the - * list of actual parameters passed by the start call. They must - * match. EXPRLIST must still be in reverse order; we'll reverse it here. - * - * Note: the OPTSET name is not now used - it's here for - * possible future support for the optional 'SET instance-var' - * clause. - */ -void -build_start_process (process_name, copynum, - exprlist, optset) - tree process_name, copynum, exprlist, optset; -{ - tree process_decl = NULL_TREE, struct_type_node = NULL_TREE; - tree result; - tree valtail, typetail; - tree tuple = NULL_TREE, actuallist = NULL_TREE; - tree typelist; - int parmno = 2; - tree args; - tree filename, linenumber; - - if (exprlist != NULL_TREE && TREE_CODE (exprlist) == ERROR_MARK) - process_decl = NULL_TREE; - else if (! ignoring) - { - process_decl = lookup_name (process_name); - if (process_decl == NULL_TREE) - error ("process name %s never declared", - IDENTIFIER_POINTER (process_name)); - else if (TREE_CODE (process_decl) != FUNCTION_DECL - || ! CH_DECL_PROCESS (process_decl)) - { - error ("You may only START a process, not a proc"); - process_decl = NULL_TREE; - } - else if (DECL_EXTERNAL (process_decl)) - { - args = TYPE_ARG_TYPES (TREE_TYPE (process_decl)); - if (TREE_VALUE (args) != void_type_node) - struct_type_node = TREE_TYPE (TREE_VALUE (args)); - else - struct_type_node = NULL_TREE; - } - else - { - tree debug_type = lookup_name ( - get_struct_debug_type_name (DECL_NAME (process_decl))); - - if (debug_type == NULL_TREE) - /* no debug type, no arguments */ - struct_type_node = NULL_TREE; - else - struct_type_node = TREE_TYPE (debug_type); - } - } - - /* begin a new name scope */ - pushlevel (1); - clear_last_expr (); - push_momentary (); - if (pass == 2) - expand_start_bindings (0); - - if (! ignoring && process_decl != NULL_TREE) - { - if (optset == NULL_TREE) ; - else if (!CH_REFERABLE (optset)) - { - error ("SET expression not a location."); - optset = NULL_TREE; - } - else if (!CH_IS_INSTANCE_MODE (TREE_TYPE (optset))) - { - error ("SET location must be INSTANCE mode"); - optset = NULL_TREE; - } - if (optset) - optset = force_addr_of (optset); - else - optset = convert (ptr_type_node, integer_zero_node); - - if (struct_type_node != NULL_TREE) - { - typelist = TYPE_FIELDS (struct_type_node); - - for (valtail = nreverse (exprlist), typetail = typelist; - valtail != NULL_TREE && typetail != NULL_TREE; parmno++, - valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail)) - { - register tree actual = valtail ? TREE_VALUE (valtail) : 0; - register tree type = typetail ? TREE_TYPE (typetail) : 0; - char place[30]; - sprintf (place, "signal field %d", parmno); - actual = chill_convert_for_assignment (type, actual, place); - actuallist = tree_cons (NULL_TREE, actual, - actuallist); - } - - tuple = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse (actuallist)); - } - else - { - valtail = NULL_TREE; - typetail = NULL_TREE; - } - - if (valtail != 0 && TREE_VALUE (valtail) != void_type_node) - { - if (process_name) - error ("too many arguments to process `%s'", - IDENTIFIER_POINTER (process_name)); - else - error ("too many arguments to process"); - } - else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) - { - if (process_name) - error ("too few arguments to process `%s'", - IDENTIFIER_POINTER (process_name)); - else - error ("too few arguments to process"); - } - else - { - tree process_decl = lookup_name (process_name); - tree process_type = (tree)DECL_TASKING_CODE_DECL (process_decl); - tree struct_size, struct_pointer; - - if (struct_type_node != NULL_TREE) - { - result = - decl_temp1 (get_unique_identifier ("START_ARG"), - struct_type_node, 0, tuple, 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (result) = 0; - - mark_addressable (result); - struct_pointer - = build1 (ADDR_EXPR, - build_chill_pointer_type (struct_type_node), - result); - struct_size = size_in_bytes (struct_type_node); - } - else - { - struct_size = integer_zero_node; - struct_pointer = null_pointer_node; - } - - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - expand_expr_stmt ( - build_chill_function_call (lookup_name (get_identifier ("__start_process")), - tree_cons (NULL_TREE, process_type, - tree_cons (NULL_TREE, convert (integer_type_node, copynum), - tree_cons (NULL_TREE, struct_size, - tree_cons (NULL_TREE, struct_pointer, - tree_cons (NULL_TREE, optset, - tree_cons (NULL_TREE, filename, - build_tree_list (NULL_TREE, linenumber))))))))); - } - } - /* end of scope */ - - if (pass == 2) - expand_end_bindings (getdecls (), kept_level_p (), 0); - poplevel (kept_level_p (), 0, 0); - pop_momentary (); -} - -/* - * A CHILL SET which represents all of the possible tasking - * elements. - */ -static tree -build_tasking_enum () -{ - tree result, decl1; - tree enum1; - tree list = NULL_TREE; - tree value = integer_zero_node; - - enum1 = start_enum (NULL_TREE); - result = build_enumerator (get_identifier ("_TT_UNUSED"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Process"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Signal"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Buffer"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Event"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Synonym"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = build_enumerator (get_identifier ("_TT_Exception"), - value); - list = chainon (result, list); - value = fold (build (PLUS_EXPR, integer_type_node, - value, integer_one_node)); - - result = finish_enum (enum1, list); - - decl1 = build_decl (TYPE_DECL, - get_identifier ("__tmp_TaskingEnum"), - result); - pushdecl (decl1); - satisfy_decl (decl1, 0); - return decl1; -} - -tree -build_tasking_struct () -{ - tree listbase, decl1, decl2, result; - tree enum_type = TREE_TYPE (build_tasking_enum ()); - /* We temporarily reset the maximum_field_alignment to zero so the - compiler's init data structures can be compatible with the - run-time system, even when we're compiling with -fpack. */ - unsigned int save_maximum_field_alignment = maximum_field_alignment; - maximum_field_alignment = 0; - - decl1 = build_decl (FIELD_DECL, get_identifier ("TaskName"), - build_chill_pointer_type (char_type_node)); - DECL_INITIAL (decl1) = NULL_TREE; - listbase = decl1; - - decl2 = build_decl (FIELD_DECL, get_identifier ("TaskValue"), - build_chill_pointer_type (chill_taskingcode_type_node)); - TREE_CHAIN (decl1) = decl2; - DECL_INITIAL (decl2) = NULL_TREE; - decl1 = decl2; - - decl2 = build_decl (FIELD_DECL, get_identifier ("TaskValueDefined"), - integer_type_node); - TREE_CHAIN (decl1) = decl2; - DECL_INITIAL (decl2) = NULL_TREE; - decl1 = decl2; - - decl2 = build_decl (FIELD_DECL, get_identifier ("TaskEntry"), - build_chill_pointer_type (void_ftype_void)); - TREE_CHAIN (decl1) = decl2; - DECL_INITIAL (decl2) = NULL_TREE; - decl1 = decl2; - - decl2 = build_decl (FIELD_DECL, get_identifier ("TaskType"), - enum_type); - TREE_CHAIN (decl1) = decl2; - DECL_INITIAL (decl2) = NULL_TREE; - decl1 = decl2; - - TREE_CHAIN (decl2) = NULL_TREE; - result = build_chill_struct_type (listbase); - satisfy_decl (result, 0); - maximum_field_alignment = save_maximum_field_alignment; - return result; -} - -/* - * build data structures describing each task/signal, etc. - * in current module. - */ -void -tasking_setup () -{ - tree tasknode; - tree struct_type; - - if (pass == 1) - return; - - struct_type = TREE_TYPE (lookup_name ( - get_identifier ("__tmp_TaskingStruct"))); - - for (tasknode = tasking_list; tasknode != NULL_TREE; - tasknode = TREE_CHAIN (tasknode)) - { - /* This is the tasking_code_variable's decl */ - tree stuffnumber = TASK_INFO_STUFF_NUM (tasknode); - tree code_decl = TASK_INFO_CODE_DECL (tasknode); - tree proc_decl = TASK_INFO_PDECL (tasknode); - tree entry = TASK_INFO_ENTRY (tasknode); - tree name = DECL_NAME (proc_decl); - char *init_struct = (char *) alloca (IDENTIFIER_LENGTH(name) + 20); - /* take care of zero termination */ - tree task_name; - /* these are the fields of the struct, in declaration order */ - tree init_flag = (stuffnumber == NULL_TREE) ? - integer_zero_node : integer_one_node; - tree type = DECL_INITIAL (TASK_INFO_STUFF_TYPE (tasknode)); - tree int_addr; - tree entry_point; - tree name_ptr; - tree decl; - tree struct_id; - tree initializer; - - if (TREE_CODE (proc_decl) == FUNCTION_DECL - && CH_DECL_PROCESS (proc_decl) - && ! DECL_EXTERNAL (proc_decl)) - { - if (entry == NULL_TREE) - entry = proc_decl; - mark_addressable (entry); - entry_point = build1 (ADDR_EXPR, - build_chill_pointer_type (void_ftype_void), - entry); - } - else - entry_point = build1 (NOP_EXPR, - build_chill_pointer_type (void_ftype_void), - null_pointer_node); - - /* take care of zero termination */ - task_name = - build_chill_string (IDENTIFIER_LENGTH (name) + 1, - IDENTIFIER_POINTER (name)); - - mark_addressable (code_decl); - int_addr = build1 (ADDR_EXPR, - build_chill_pointer_type (chill_integer_type_node), - code_decl); - - mark_addressable (task_name); - name_ptr = build1 (ADDR_EXPR, - build_chill_pointer_type (char_type_node), - task_name); - - sprintf (init_struct, "__tmp_%s_struct", - IDENTIFIER_POINTER (name)); - - struct_id = get_identifier (init_struct); - initializer = build (CONSTRUCTOR, struct_type, NULL_TREE, - tree_cons (NULL_TREE, name_ptr, - tree_cons (NULL_TREE, int_addr, - tree_cons (NULL_TREE, init_flag, - tree_cons (NULL_TREE, entry_point, - tree_cons (NULL_TREE, type, NULL_TREE)))))); - TREE_CONSTANT (initializer) = 1; - decl = decl_temp1 (struct_id, struct_type, 1, initializer, 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - /* pass the decl to tasking_registry() in the symbol table */ - IDENTIFIER_LOCAL_VALUE (struct_id) = decl; - } -} - - -/* - * Generate code to register the tasking-related stuff - * with the runtime. Only in pass 2. - */ -void -tasking_registry () -{ - tree tasknode, fn_decl; - - if (pass == 1) - return; - - fn_decl = lookup_name (get_identifier ("__register_tasking")); - - for (tasknode = tasking_list; tasknode != NULL_TREE; - tasknode = TREE_CHAIN (tasknode)) - { - tree proc_decl = TASK_INFO_PDECL (tasknode); - tree name = DECL_NAME (proc_decl); - tree arg_decl; - char *init_struct = (char *) alloca (IDENTIFIER_LENGTH (name) + 20); - - sprintf (init_struct, "__tmp_%s_struct", - IDENTIFIER_POINTER (name)); - arg_decl = lookup_name (get_identifier (init_struct)); - - expand_expr_stmt ( - build_chill_function_call (fn_decl, - build_tree_list (NULL_TREE, force_addr_of (arg_decl)))); - } -} - -/* - * Put a tasking entity (a PROCESS, or SIGNAL) onto - * the list for tasking_setup (). CODE_DECL is the integer code - * variable's DECL, which describes the shadow integer which - * accompanies each tasking entity. STUFFTYPE is a string - * representing the sort of tasking entity we have here (i.e. - * process, signal, etc.). STUFFNUMBER is an enumeration - * value saying the same thing. PROC_DECL is the declaration of - * the entity. It's a FUNCTION_DECL if the entity is a PROCESS, it's - * a TYPE_DECL if the entity is a SIGNAL. - */ -void -add_taskstuff_to_list (code_decl, stufftype, stuffnumber, - proc_decl, entry) - tree code_decl; - const char *stufftype; - tree stuffnumber, proc_decl, entry; -{ - if (pass == 1) - /* tell chill_finish_compile that there's - task-level code to be processed. */ - tasking_list = integer_one_node; - - /* do only in pass 2 so we know in chill_finish_compile whether - to generate a constructor function, and to avoid double the - correct number of entries. */ - else /* pass == 2 */ - { - tree task_node = make_tree_vec (5); - TASK_INFO_PDECL (task_node) = proc_decl; - TASK_INFO_ENTRY (task_node) = entry; - TASK_INFO_CODE_DECL (task_node) = code_decl; - TASK_INFO_STUFF_NUM (task_node) = stuffnumber; - TASK_INFO_STUFF_TYPE (task_node) - = lookup_name (get_identifier (stufftype)); - TREE_CHAIN (task_node) = tasking_list; - tasking_list = task_node; - } -} - -/* - * These next routines are called out of build_generalized_call - */ -tree -build_copy_number (instance_expr) - tree instance_expr; -{ - tree result; - - if (instance_expr == NULL_TREE - || TREE_CODE (instance_expr) == ERROR_MARK) - return error_mark_node; - if (! CH_IS_INSTANCE_MODE (TREE_TYPE (instance_expr))) - { - error ("COPY_NUMBER argument must be INSTANCE expression"); - return error_mark_node; - } - result = build_component_ref (instance_expr, - get_identifier (INS_COPY)); - CH_DERIVED_FLAG (result) = 1; - return result; -} - - -tree -build_gen_code (decl) - tree decl; -{ - tree result; - - if (decl == NULL_TREE || TREE_CODE (decl) == ERROR_MARK) - return error_mark_node; - - if ((TREE_CODE (decl) == FUNCTION_DECL && CH_DECL_PROCESS (decl)) - || (TREE_CODE (decl) == TYPE_DECL && CH_DECL_SIGNAL (decl))) - result = (tree)(DECL_TASKING_CODE_DECL (decl)); - else - { - error ("GEN_CODE argument must be a process or signal name."); - return error_mark_node; - } - CH_DERIVED_FLAG (result) = 1; - return (result); -} - - -tree -build_gen_inst (process, copyn) - tree process, copyn; -{ - tree ptype; - tree result; - - if (copyn == NULL_TREE || TREE_CODE (copyn) == ERROR_MARK) - return error_mark_node; - if (process == NULL_TREE || TREE_CODE (process) == ERROR_MARK) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (copyn)) != INTEGER_TYPE) - { - error ("GEN_INST parameter 2 must be an integer mode"); - copyn = integer_zero_node; - } - - copyn = check_range (copyn, copyn, - TYPE_MIN_VALUE (chill_taskingcode_type_node), - TYPE_MAX_VALUE (chill_taskingcode_type_node)); - - if (TREE_CODE (process) == FUNCTION_DECL - && CH_DECL_PROCESS (process)) - ptype = (tree)DECL_TASKING_CODE_DECL (process); - else if (TREE_TYPE (process) != NULL_TREE - && TREE_CODE (TREE_TYPE (process)) == INTEGER_TYPE) - { - process = check_range (process, process, - TYPE_MIN_VALUE (chill_taskingcode_type_node), - TYPE_MAX_VALUE (chill_taskingcode_type_node)); - ptype = convert (chill_taskingcode_type_node, process); - } - else - { - error ("GEN_INST parameter 1 must be a PROCESS or an integer expression"); - return (error_mark_node); - } - - result = convert (instance_type_node, - build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, ptype, - tree_cons (NULL_TREE, - convert (chill_taskingcode_type_node, copyn), NULL_TREE)))); - CH_DERIVED_FLAG (result) = 1; - return result; -} - - -tree -build_gen_ptype (process_decl) - tree process_decl; -{ - tree result; - - if (process_decl == NULL_TREE || TREE_CODE (process_decl) == ERROR_MARK) - return error_mark_node; - - if (TREE_CODE (process_decl) != FUNCTION_DECL - || ! CH_DECL_PROCESS (process_decl)) - { - error_with_decl (process_decl, "%s is not a declared process"); - return error_mark_node; - } - - result = (tree)DECL_TASKING_CODE_DECL (process_decl); - CH_DERIVED_FLAG (result) = 1; - return result; -} - - -tree -build_proc_type (instance_expr) - tree instance_expr; -{ - tree result; - - if (instance_expr == NULL_TREE || TREE_CODE (instance_expr) == ERROR_MARK) - return error_mark_node; - - if (! CH_IS_INSTANCE_MODE (TREE_TYPE (instance_expr))) - { - error ("PROC_TYPE argument must be INSTANCE expression"); - return error_mark_node; - } - result = build_component_ref (instance_expr, - get_identifier (INS_PTYPE)); - CH_DERIVED_FLAG (result) = 1; - return result; -} - -tree -build_queue_length (buf_ev) - tree buf_ev; -{ - if (buf_ev == NULL_TREE || TREE_CODE (buf_ev) == ERROR_MARK) - return error_mark_node; - if (TREE_TYPE (buf_ev) == NULL_TREE || - TREE_CODE (TREE_TYPE (buf_ev)) == ERROR_MARK) - return error_mark_node; - - if (CH_IS_BUFFER_MODE (TREE_TYPE (buf_ev)) || - CH_IS_EVENT_MODE (TREE_TYPE (buf_ev))) - { - const char *field_name; - tree arg1, arg2; - - if (CH_IS_EVENT_MODE (TREE_TYPE (buf_ev))) - { - field_name = "__event_data"; - arg2 = integer_one_node; - } - else - { - field_name = "__buffer_data"; - arg2 = integer_zero_node; - } - arg1 = build_component_ref (buf_ev, get_identifier (field_name)); - return build_chill_function_call ( - lookup_name (get_identifier ("__queue_length")), - tree_cons (NULL_TREE, arg1, - tree_cons (NULL_TREE, arg2, NULL_TREE))); - } - - error ("QUEUE_LENGTH argument must be a BUFFER/EVENT location."); - return error_mark_node; -} - -tree -build_signal_struct_type (signame, sigmodelist, optsigdest) - tree signame, sigmodelist, optsigdest; -{ - tree decl, temp; - - if (pass == 1) - { - int fldcnt = 0; - tree mode, field_decls = NULL_TREE; - - for (mode = sigmodelist; mode != NULL_TREE; mode = TREE_CHAIN (mode)) - { - tree field; - char fldname[20]; - - if (TREE_VALUE (mode) == NULL_TREE) - continue; - sprintf (fldname, "fld%03d", fldcnt++); - field = build_decl (FIELD_DECL, - get_identifier (fldname), - TREE_VALUE (mode)); - if (field_decls == NULL_TREE) - field_decls = field; - else - chainon (field_decls, field); - } - if (field_decls == NULL_TREE) - field_decls = build_decl (FIELD_DECL, - get_identifier ("__tmp_empty"), - boolean_type_node); - temp = build_chill_struct_type (field_decls); - - /* save the destination process name of the signal */ - IDENTIFIER_SIGNAL_DEST (signame) = optsigdest; - IDENTIFIER_SIGNAL_DATA (signame) = fldcnt; - } - else - { - /* optsigset is only valid in pass 2, so we have to save it now */ - IDENTIFIER_SIGNAL_DEST (signame) = optsigdest; - temp = NULL_TREE; /* Actually, don't care. */ - } - - decl = push_modedef (signame, temp, -1); - if (decl != NULL_TREE) - CH_DECL_SIGNAL (decl) = 1; - return decl; -} - -/* - * An instance type is a unique process identifier in the CHILL - * tasking arena. It consists of a process type and a copy number. - */ -void -build_instance_type () -{ - tree decl1, decl2, tdecl; - - decl1 = build_decl (FIELD_DECL, get_identifier (INS_PTYPE), - chill_taskingcode_type_node); - - TREE_CHAIN (decl1) = decl2 = - build_decl (FIELD_DECL, get_identifier (INS_COPY), - chill_taskingcode_type_node); - TREE_CHAIN (decl2) = NULL_TREE; - - instance_type_node = build_chill_struct_type (decl1); - tdecl = build_decl (TYPE_DECL, ridpointers[(int) RID_INSTANCE], - instance_type_node); - TYPE_NAME (instance_type_node) = tdecl; - CH_NOVELTY (instance_type_node) = tdecl; - DECL_SOURCE_LINE (tdecl) = 0; - pushdecl (tdecl); - - pointer_to_instance = build_chill_pointer_type (instance_type_node); -} - -#if 0 - * - * The tasking message descriptor looks like this C structure: - * - * typedef struct - * { - * short *sc; /* ptr to code integer */ - * int data_len; /* length of signal/buffer data msg */ - * void *data; /* ptr to signal/buffer data */ - * } SignalDescr; - * - * -#endif - -static void -build_tasking_message_type () -{ - tree type_name; - tree temp; - /* We temporarily reset maximum_field_alignment to deal with - the runtime system. */ - unsigned int save_maximum_field_alignment = maximum_field_alignment; - tree field1, field2, field3; - - maximum_field_alignment = 0; - field1 = build_decl (FIELD_DECL, - get_identifier ("_SD_code_ptr"), - build_pointer_type (chill_integer_type_node)); - field2 = build_decl (FIELD_DECL, - get_identifier ("_SD_data_len"), - integer_type_node); - field3 = build_decl (FIELD_DECL, - get_identifier ("_SD_data_ptr"), - ptr_type_node); - TREE_CHAIN (field1) = field2; - TREE_CHAIN (field2) = field3; - temp = build_chill_struct_type (field1); - - type_name = get_identifier ("__tmp_SD_struct"); - tasking_message_type = build_decl (TYPE_DECL, type_name, temp); - - /* This won't get seen in pass 2, so lay it out now. */ - layout_chill_struct_type (temp); - pushdecl (tasking_message_type); - maximum_field_alignment = save_maximum_field_alignment; -} - -tree -build_signal_descriptor (sigdef, exprlist) - tree sigdef, exprlist; -{ - tree fieldlist, typetail, valtail; - tree actuallist = NULL_TREE; - tree signame = DECL_NAME (sigdef); - tree dataptr, datalen; - int parmno = 1; - - if (sigdef == NULL_TREE - || TREE_CODE (sigdef) == ERROR_MARK) - return error_mark_node; - - if (exprlist != NULL_TREE - && TREE_CODE (exprlist) == ERROR_MARK) - return error_mark_node; - - if (TREE_CODE (sigdef) != TYPE_DECL - || ! CH_DECL_SIGNAL (sigdef)) - { - error ("SEND requires a SIGNAL; %s is not a SIGNAL name", - IDENTIFIER_POINTER (signame)); - return error_mark_node; - } - if (CH_TYPE_NONVALUE_P (TREE_TYPE (sigdef))) - return error_mark_node; - - fieldlist = TYPE_FIELDS (TREE_TYPE (sigdef)); - if (IDENTIFIER_SIGNAL_DATA (signame) == 0) - fieldlist = TREE_CHAIN (fieldlist); - - for (valtail = exprlist, typetail = fieldlist; - valtail != NULL_TREE && typetail != NULL_TREE; - parmno++, valtail = TREE_CHAIN (valtail), - typetail = TREE_CHAIN (typetail)) - { - register tree actual = valtail ? TREE_VALUE (valtail) : 0; - register tree type = typetail ? TREE_TYPE (typetail) : 0; - char place[30]; - sprintf (place, "signal field %d", parmno); - actual = chill_convert_for_assignment (type, actual, place); - actuallist = tree_cons (NULL_TREE, actual, actuallist); - } - if (valtail != 0 && TREE_VALUE (valtail) != void_type_node) - { - error ("too many values for SIGNAL `%s'", - IDENTIFIER_POINTER (signame)); - return error_mark_node; - } - else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) - { - error ("too few values for SIGNAL `%s'", - IDENTIFIER_POINTER (signame)); - return error_mark_node; - } - - { - /* build signal data structure */ - tree sigdataname = get_unique_identifier ( - IDENTIFIER_POINTER (signame)); - if (exprlist == NULL_TREE) - { - dataptr = null_pointer_node; - datalen = integer_zero_node; - } - else - { - tree tuple = build_nt (CONSTRUCTOR, - NULL_TREE, nreverse (actuallist)); - tree decl = decl_temp1 (sigdataname, TREE_TYPE (sigdef), - 0, tuple, 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - dataptr = force_addr_of (decl); - datalen = size_in_bytes (TREE_TYPE (decl)); - } - - /* build descriptor pointing to signal data */ - { - tree decl, tuple; - tree tasking_message_var = get_unique_identifier ( - IDENTIFIER_POINTER (signame)); - - tree tasking_code = - (tree)DECL_TASKING_CODE_DECL (lookup_name (signame)); - - mark_addressable (tasking_code); - tuple = build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, - build1 (ADDR_EXPR, - build_chill_pointer_type (chill_integer_type_node), - tasking_code), - tree_cons (NULL_TREE, datalen, - tree_cons (NULL_TREE, dataptr, NULL_TREE)))); - - decl = decl_temp1 (tasking_message_var, - TREE_TYPE (tasking_message_type), 0, - tuple, 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - tuple = force_addr_of (decl); - return tuple; - } - } -} - -void -expand_send_signal (sigmsgbuffer, optroutinginfo, optsendto, - optpriority, signame) - tree sigmsgbuffer; - tree optroutinginfo; - tree optsendto; - tree optpriority; - tree signame; -{ - tree routing_size, routing_addr; - tree filename, linenumber; - tree sigdest = IDENTIFIER_SIGNAL_DEST (signame); - - /* check the presence of priority */ - if (optpriority == NULL_TREE) - { - if (send_signal_prio == NULL_TREE) - { - /* issue a warning in case of -Wall */ - if (extra_warnings) - { - warning ("Signal sent without priority"); - warning (" and no default priority was set."); - warning (" PRIORITY defaulted to 0"); - } - optpriority = integer_zero_node; - } - else - optpriority = send_signal_prio; - } - - /* check the presence of a destination. - optdest either may be an instance location - or a process declaration */ - if (optsendto == NULL_TREE) - { - if (sigdest == NULL_TREE) - { - error ("SEND without a destination instance"); - error (" and no destination process specified"); - error (" for the signal"); - optsendto = convert (instance_type_node, - null_pointer_node); - } - else - { - /* build an instance [sigdest; -1] */ - tree process_name = DECL_NAME (sigdest); - tree copy_number = fold (build (MINUS_EXPR, integer_type_node, - integer_zero_node, - integer_one_node)); - tree tasking_code = (tree)DECL_TASKING_CODE_DECL ( - lookup_name (process_name)); - - optsendto = build (CONSTRUCTOR, instance_type_node, NULL_TREE, - tree_cons (NULL_TREE, tasking_code, - tree_cons (NULL_TREE, copy_number, NULL_TREE))); - /* as our system doesn't allow that and Z.200 specifies it, - we issue a warning */ - warning ("SEND to ANY copy of process `%s'.", IDENTIFIER_POINTER (process_name)); - } - } - else if (! CH_IS_INSTANCE_MODE (TREE_TYPE (optsendto))) - { - error ("SEND TO must be an INSTANCE mode"); - optsendto = convert (instance_type_node, null_pointer_node); - } - else - optsendto = check_non_null (convert (instance_type_node, optsendto)); - - /* check the routing stuff */ - if (optroutinginfo != NULL_TREE) - { - tree routing_name; - tree decl; - - if (TREE_TYPE (optroutinginfo) == NULL_TREE) - { - error ("SEND WITH must have a mode"); - optroutinginfo = integer_zero_node; - } - routing_name = get_unique_identifier ("RI"); - decl = decl_temp1 (routing_name, - TREE_TYPE (optroutinginfo), 0, - optroutinginfo, 0, 0); - /* prevent granting of this type */ - DECL_SOURCE_LINE (decl) = 0; - - routing_addr = force_addr_of (decl); - routing_size = size_in_bytes (TREE_TYPE (decl)); - } - else - { - routing_size = integer_zero_node; - routing_addr = null_pointer_node; - } - /* get filename and linenumber */ - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - /* Now (at last!) we can call the runtime */ - expand_expr_stmt ( - build_chill_function_call (lookup_name (get_identifier ("__send_signal")), - tree_cons (NULL_TREE, sigmsgbuffer, - tree_cons (NULL_TREE, optsendto, - tree_cons (NULL_TREE, optpriority, - tree_cons (NULL_TREE, routing_size, - tree_cons (NULL_TREE, routing_addr, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE))))))))); -} - -#if 0 - * The following code builds a RECEIVE CASE action, which actually - * has 2 different functionalities: - * - * 1) RECEIVE signal CASE action - * which looks like this: - * - * SIGNAL advance; - * SIGNAL terminate = (CHAR); - * SIGNAL sig1 = (CHAR); - * - * DCL user, system INSTANCE; - * DCL count INT, char_code CHAR; - * DCL instance_loc INSTANCE; - * - * workloop: - * RECEIVE CASE SET instance_loc; - * (advance): - * count + := 1; - * (terminate IN char_code): - * SEND sig1(char_code) TO system; - * EXIT workloop; - * ELSE - * STOP; - * ESAC; - * - * Because we don''t know until we get to the ESAC how - * many signals need processing, we generate the following - * C-equivalent code: - * - * /* define the codes for the signals */ - * static short __tmp_advance_code; - * static short __tmp_terminate_code; - * static short __tmp_sig1_code; - * - * /* define the types of the signals */ - * typedef struct - * { - * char fld0; - * } __tmp_terminate_struct; - * - * typedef struct - * { - * char fld0; - * } __tmp_sig1_struct; - * - * static INSTANCE user, system, instance_loc; - * static short count; - * static char char_code; - * - * { /* start a new symbol context */ - * int number_of_sigs; - * short *sig_code []; - * void *sigdatabuf; - * int sigdatalen; - * short sigcode; - * - * goto __rcsetup; - * - * __rcdoit: ; - * int timedout = __wait_signal (&sigcode - * number_of_sigs, - * sig_code, - * sigdatabuf, - * sigdatalen, - * &instance_loc); - * if (sigcode == __tmp_advance_code) - * { - * /* code for advance alternative's action_statement_list */ - * count++; - * } - * else if (sigcode == __tmp_terminate_code) - * { - * /* copy signal's data to where they belong, - * with range-check, if enabled */ - * char_code = ((__tmp_terminate_struct *)sigdatabuf)->fld0; - * - * /* code for terminate alternative's action_statement_list */ - * __send_signal (sig1 ..... ); - * goto __workloop_end; - * } - * else - * { - * /* code here for the ELSE action_statement_list */ - * __stop_process (); - * } - * goto __rc_done; - * - * __rcsetup: - * union { __tmp_terminate_struct terminate; - * __tmp_sig1_struct } databuf; - * short *sig_code_ptr [2] = { &__tmp_advance_code, - * &__tmp_terminate_code }; - * sigdatabuf = &databuf; - * sigdatalen = sizeof (databuf); - * sig_code = &sig_code_ptr[0]; - * number_of_sigs = 2; - * goto __rcdoit; - * - * __rc_done: ; - * } /* end the new symbol context */ - * __workloop_end: ; - * - * - * 2) RECEIVE buffer CASE action: - * which looks like this: - * - * NEWMODE m_s = STRUCT (mini INT, maxi INT); - * DCL b1 BUFFER INT; - * DCL b2 BUFFER (30) s; - * - * DCL i INT, s m_s, ins INSTANCE; - * DCL count INT; - * - * workloop: - * RECEIVE CASE SET ins; - * (b1 IN i): - * count +:= i; - * (b2 in s): - * IF count < s.mini OR count > s.maxi THEN - * EXIT workloop; - * FI; - * ELSE - * STOP; - * ESAC; - * - * Because we don''t know until we get to the ESAC how - * many buffers need processing, we generate the following - * C-equivalent code: - * - * typedef struct - * { - * short mini; - * short maxi; - * } m_s; - * - * static void *b1; - * static void *b2; - * static short i; - * static m_s s; - * static INSTANCE ins; - * static short count; - * - * workloop: - * { /* start a new symbol context */ - * int number_of_sigs; - * void *sig_code []; - * void *sigdatabuf; - * int sigdatalen; - * void *buflocation; - * int timedout; - * - * goto __rcsetup; - * - * __rcdoit: - * timedout = __wait_buffer (&buflocation, - * number_of_sigs, - * sig_code, - * sigdatabuf, - * sigdatalen, - * &ins, ...); - * if (buflocation == &b1) - * { - * i = ((short *)sigdatabuf)->fld0; - * count += i; - * } - * else if (buflocation == &b2) - * { - * s = ((m_s)*sigdatabuf)->fld1; - * if (count < s.mini || count > s.maxi) - * goto __workloop_end; - * } - * else - * __stop_process (); - * goto __rc_done; - * - * __rcsetup: - * typedef struct - * { - * void *p; - * unsigned maxqueuesize; - * } Buffer_Descr; - * union { short b1, - * m_s b2 } databuf; - * Buffer_Descr bufptr [2] = - * { - * { &b1, -1 }, - * { &b2, 30 }, - * }; - * void * bufarray[2] = { &bufptr[0], - * &bufptr[1] }; - * sigdatabuf = &databuf; - * sigdatalen = sizeof (databuf); - * sig_code = &bufarray[0]; - * number_of_sigs = 2; - * goto __rcdoit; - * - * __rc_done; - * } /* end of symbol context */ - * __workloop_end: - * -#endif - -struct rc_state_type -{ - struct rc_state_type *enclosing; - rtx rcdoit; - rtx rcsetup; - tree n_sigs; - tree sig_code; - tree databufp; - tree datalen; - tree else_clause; - tree received_signal; - tree received_buffer; - tree to_loc; - int sigseen; - int bufseen; - tree actuallist; - int call_generated; - int if_generated; - int bufcnt; -}; - -struct rc_state_type *current_rc_state = NULL; - -/* - * this function tells if there is an if to terminate - * or not - */ -int -build_receive_case_if_generated() -{ - if (!current_rc_state) - { - error ("internal error: RECEIVE CASE stack invalid."); - abort (); - } - return current_rc_state->if_generated; -} - -/* build_receive_case_start returns an INTEGER_CST node - containing the case-label number to be used by - build_receive_case_end to generate correct labels */ -tree -build_receive_case_start (optset) - tree optset; -{ - /* counter to generate unique receive_case labels */ - static int rc_lbl_count = 0; - tree current_label_value = - build_int_2 ((HOST_WIDE_INT)rc_lbl_count, 0); - tree sigcodename, filename, linenumber; - - struct rc_state_type *rc_state - = (struct rc_state_type*) xmalloc (sizeof (struct rc_state_type)); - rc_state->rcdoit = gen_label_rtx (); - rc_state->rcsetup = gen_label_rtx (); - rc_state->enclosing = current_rc_state; - current_rc_state = rc_state; - rc_state->sigseen = 0; - rc_state->bufseen = 0; - rc_state->call_generated = 0; - rc_state->if_generated = 0; - rc_state->bufcnt = 0; - - rc_lbl_count++; - if (optset == NULL_TREE || TREE_CODE (optset) == ERROR_MARK) - optset = null_pointer_node; - else - { - if (CH_IS_INSTANCE_MODE (TREE_TYPE (optset)) && CH_LOCATION_P (optset)) - optset = force_addr_of (optset); - else - { - error ("SET requires INSTANCE location"); - optset = null_pointer_node; - } - } - - rc_state->to_loc = build_timeout_preface (); - - rc_state->n_sigs = - decl_temp1 (get_identifier ("number_of_sigs"), - integer_type_node, 0, integer_zero_node, 0, 0); - - rc_state->sig_code = - decl_temp1 (get_identifier ("sig_codep"), - ptr_type_node, 0, null_pointer_node, 0, 0); - - rc_state->databufp = - decl_temp1 (get_identifier ("databufp"), - ptr_type_node, 0, null_pointer_node, 0, 0); - - rc_state->datalen = - decl_temp1 (get_identifier ("datalen"), - integer_type_node, 0, integer_zero_node, 0, 0); - - rc_state->else_clause = - decl_temp1 (get_identifier ("else_clause"), - integer_type_node, 0, integer_zero_node, 0, 0); - - /* wait_signal will store the signal number in here */ - sigcodename = get_identifier ("received_signal"); - rc_state->received_signal = - decl_temp1 (sigcodename, chill_integer_type_node, 0, - NULL_TREE, 0, 0); - - /* wait_buffer will store the buffer address in here */ - sigcodename = get_unique_identifier ("received_buffer"); - rc_state->received_buffer = - decl_temp1 (sigcodename, ptr_type_node, 0, - NULL_TREE, 0, 0); - - /* now jump to the end of RECEIVE CASE actions, to - set up variables for them. */ - emit_jump (rc_state->rcsetup); - - /* define the __rcdoit label. We come here after - initialization of all variables, to execute the - actions. */ - emit_label (rc_state->rcdoit); - - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - /* Argument list for calling the runtime routine. We'll call it - the first time we call build_receive_case_label, when we know - whether to call wait_signal or wait_buffer. NOTE: at this time - the first argument will be set. */ - rc_state->actuallist = - tree_cons (NULL_TREE, NULL_TREE, - tree_cons (NULL_TREE, rc_state->n_sigs, - tree_cons (NULL_TREE, rc_state->sig_code, - tree_cons (NULL_TREE, rc_state->databufp, - tree_cons (NULL_TREE, rc_state->datalen, - tree_cons (NULL_TREE, optset, - tree_cons (NULL_TREE, rc_state->else_clause, - tree_cons (NULL_TREE, rc_state->to_loc, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE)))))))))); - return current_label_value; -} - -static tree -build_receive_signal_case_label (sigdecl, loclist) - tree sigdecl, loclist; -{ - struct rc_state_type *rc_state = current_rc_state; - tree signame = DECL_NAME (sigdecl); - tree expr; - - if (rc_state->bufseen != 0) - { - error ("SIGNAL in RECEIVE CASE alternative follows"); - error (" a BUFFER name on line %d", rc_state->bufseen); - return error_mark_node; - } - rc_state->sigseen = lineno; - rc_state->bufseen = 0; - - if (!IDENTIFIER_SIGNAL_DATA (signame) && loclist != NULL_TREE) - { - error ("SIGNAL `%s' has no data fields", IDENTIFIER_POINTER (signame)); - return error_mark_node; - } - if (IDENTIFIER_SIGNAL_DATA (signame) && loclist == NULL_TREE) - { - error ("SIGNAL `%s' requires data fields", IDENTIFIER_POINTER (signame)); - return error_mark_node; - } - - if (!rc_state->call_generated) - { - tree wait_call; - - TREE_VALUE (rc_state->actuallist) = force_addr_of (rc_state->received_signal); - wait_call = build_chill_function_call (lookup_name - (get_identifier ("__wait_signal_timed")), - rc_state->actuallist); -#if 0 - chill_expand_assignment (rc_state->received_signal, - NOP_EXPR, wait_call); -#endif - build_timesupervised_call (wait_call, rc_state->to_loc); - - rc_state->call_generated = 1; - } - - /* build the conditional expression */ - expr = build (EQ_EXPR, boolean_type_node, - rc_state->received_signal, - (tree)DECL_TASKING_CODE_DECL (sigdecl)); - - if (!rc_state->if_generated) - { - expand_start_cond (expr, 0); - rc_state->if_generated = 1; - } - else - expand_start_elseif (expr); - - if (IDENTIFIER_SIGNAL_DATA (signame)) - { - /* copy data from signal buffer to user's variables */ - tree typelist = TYPE_FIELDS (TREE_TYPE (sigdecl)); - tree valtail, typetail; - int parmno = 1; - tree pointer_type = build_chill_pointer_type (TREE_TYPE (sigdecl)); - tree pointer = convert (pointer_type, rc_state->databufp); - - for (valtail = nreverse (loclist), typetail = typelist; - valtail != NULL_TREE && typetail != NULL_TREE; - parmno++, valtail = TREE_CHAIN (valtail), - typetail = TREE_CHAIN (typetail)) - { - register tree actual = valtail ? TREE_VALUE (valtail) : 0; - register tree type = typetail ? TREE_TYPE (typetail) : 0; - register tree assgn; - char place[30]; - sprintf (place, "signal field %d", parmno); - - assgn = build_component_ref (build1 (INDIRECT_REF, - TREE_TYPE (sigdecl), - pointer), - DECL_NAME (typetail)); - if (!CH_TYPE_NONVALUE_P (type)) - /* don't assign to non-value type. Error printed at signal definition */ - chill_expand_assignment (actual, NOP_EXPR, assgn); - } - - if (valtail == NULL_TREE && typetail != NULL_TREE) - error ("too few data fields provided for `%s'", - IDENTIFIER_POINTER (signame)); - if (valtail != NULL_TREE && typetail == NULL_TREE) - error ("too many data fields provided for `%s'", - IDENTIFIER_POINTER (signame)); - } - - /* last action here */ - emit_line_note (input_filename, lineno); - - return build_tree_list (loclist, signame); -} - -static tree -build_receive_buffer_case_label (buffer, loclist) - tree buffer, loclist; -{ - struct rc_state_type *rc_state = current_rc_state; - tree buftype = buffer_element_mode (TREE_TYPE (buffer)); - tree expr, var; - tree pointer_type, pointer, assgn; - int had_errors = 0; - tree x, y, z, bufaddr; - - if (rc_state->sigseen != 0) - { - error ("BUFFER in RECEIVE CASE alternative follows"); - error (" a SIGNAL name on line %d", rc_state->sigseen); - return error_mark_node; - } - rc_state->bufseen = lineno; - rc_state->sigseen = 0; - - if (! CH_REFERABLE (buffer)) - { - error ("BUFFER in RECEIVE CASE alternative must be a location."); - return error_mark_node; - } - - if (TREE_CHAIN (loclist) != NULL_TREE) - { - error ("buffer receive alternative requires only 1 defining occurence."); - return error_mark_node; - } - - if (!rc_state->call_generated) - { - tree wait_call; - - /* here we change the mode of rc_state->sig_code to - REF ARRAY (0:65535) REF __tmp_DESCR_type. - This is neccesary, cause we cannot evaluate the buffer twice - (once here where we compare against the address of the buffer - and second in build_receive_buffer_case_end, where we use the - address build the descriptor, which gets passed to __wait_buffer). - So we change the comparison from - if (rc_state->received_buffer == &buffer) - to - if (rc_state->received_buffer == - rc_state->sig_codep->[rc_state->bufcnt]->datap). - - This will evaluate the buffer location only once - (in build_receive_buffer_case_end) and therefore doesn't confuse - our machinery. */ - - tree reftmpdescr = build_chill_pointer_type ( - TREE_TYPE (lookup_name ( - get_identifier ("__tmp_DESCR_type")))); - tree idxtype = build_chill_range_type (NULL_TREE, - integer_zero_node, - build_int_2 (65535, 0)); /* should be enough, probably use ULONG */ - tree arrtype = build_chill_array_type (reftmpdescr, - tree_cons (NULL_TREE, idxtype, NULL_TREE), - 0, NULL_TREE); - tree refarrtype = build_chill_pointer_type (arrtype); - - TREE_VALUE (rc_state->actuallist) = force_addr_of (rc_state->received_buffer); - wait_call = build_chill_function_call ( - lookup_name (get_identifier ("__wait_buffer")), - rc_state->actuallist); -#if 0 - chill_expand_assignment (rc_state->received_buffer, - NOP_EXPR, wait_call); -#endif - build_timesupervised_call (wait_call, rc_state->to_loc); - - /* do this after the call, otherwise there will be a mode mismatch */ - TREE_TYPE (rc_state->sig_code) = refarrtype; - - /* now we are ready to generate the call */ - rc_state->call_generated = 1; - } - - x = build_chill_indirect_ref (rc_state->sig_code, NULL_TREE, 0); - y = build_chill_array_ref (x, - tree_cons (NULL_TREE, build_int_2 (rc_state->bufcnt, 0), NULL_TREE)); - z = build_chill_indirect_ref (y, NULL_TREE, 0); - bufaddr = build_chill_component_ref (z, get_identifier ("datap")); - - /* build the conditional expression */ - expr = build (EQ_EXPR, boolean_type_node, - rc_state->received_buffer, - bufaddr); - - /* next buffer in list */ - rc_state->bufcnt++; - - if (!rc_state->if_generated) - { - expand_start_cond (expr, 0); - rc_state->if_generated = 1; - } - else - expand_start_elseif (expr); - - /* copy buffer's data to destination */ - var = TREE_VALUE (loclist); - - if (buftype != NULL_TREE && TREE_CODE (buftype) == ERROR_MARK) - had_errors = 1; - else if (! CH_COMPATIBLE (var, buftype)) - { - error ("incompatible modes in receive buffer alternative."); - had_errors = 1; - } - - if (! CH_LOCATION_P (var)) - { - error ("defining occurence in receive buffer alternative must be a location."); - had_errors = 1; - } - - if (! had_errors) - { - pointer_type = build_chill_pointer_type (TREE_TYPE (var)); - pointer = convert (pointer_type, - rc_state->databufp); - /* no need to check this pointer being NULL */ - assgn = build_chill_indirect_ref (pointer, NULL_TREE, 0); - - chill_expand_assignment (var, NOP_EXPR, assgn); - } - - /* last action here */ - emit_line_note (input_filename, lineno); - - return build_tree_list (loclist, buffer); -} -/* - * SIGNAME is the signal name or buffer location, - * LOCLIST is a list of possible locations to store data in - */ -tree -build_receive_case_label (signame, loclist) - tree signame, loclist; -{ - /* now see what we have got and do some checks */ - if (TREE_CODE (signame) == TYPE_DECL && CH_DECL_SIGNAL (signame)) - return build_receive_signal_case_label (signame, loclist); - - if (TREE_TYPE (signame) != NULL_TREE - && CH_IS_BUFFER_MODE (TREE_TYPE (signame))) - { - if (loclist == NULL_TREE) - { - error ("buffer receive alternative without `IN location'."); - return error_mark_node; - } - return build_receive_buffer_case_label (signame, loclist); - } - - error ("RECEIVE CASE alternative must specify a SIGNAL name or BUFFER location."); - return error_mark_node; -} - -/* - * LABEL_CNT is the case-label counter passed from build_receive_case_start. - * ELSE_CLAUSE defines if the RECEIVE CASE action had an ELSE(1) or not(0). - * BUF_LIST is a tree-list of tree-lists, where TREE_VALUE defines the - * BUFFER location and TREE_PURPOSE defines the defining occurence. - */ -static void -build_receive_buffer_case_end (buf_list, else_clause) - tree buf_list, else_clause; -{ - struct rc_state_type *rc_state = current_rc_state; - tree alist; - tree field_decls = NULL_TREE; /* list of all buffer types, for the union */ - int buffer_cnt = 0; - tree descr_type = lookup_name (get_identifier ("__tmp_DESCR_type")); - tree tuple = NULL_TREE; /* constructors for array of ptrs */ - tree union_type_node = NULL_TREE; - - /* walk thru all the buffers */ - for (alist = buf_list; alist != NULL_TREE; - buffer_cnt++, alist = TREE_CHAIN (alist)) - { - tree value = TREE_VALUE (alist); - tree buffer = TREE_VALUE (value); /* this is the buffer */ - tree data = TREE_VALUE (TREE_PURPOSE (value)); /* the location to receive in */ - tree buffer_descr; - tree buffer_descr_init; - tree buffer_length; - tree field; - char fldname[20]; - - /* build descriptor for buffer */ - buffer_length = max_queue_size (TREE_TYPE (buffer)); - if (buffer_length == NULL_TREE) - buffer_length = infinite_buffer_event_length_node; - buffer_descr_init = build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, force_addr_of (buffer), - tree_cons (NULL_TREE, buffer_length, NULL_TREE))); - buffer_descr = decl_temp1 (get_unique_identifier ("RCbuffer"), - TREE_TYPE (descr_type), 0, - buffer_descr_init, 0, 0); - tuple = tree_cons (NULL_TREE, - force_addr_of (buffer_descr), - tuple); - - /* make a field for the union */ - sprintf (fldname, "fld%03d", buffer_cnt); - field = grok_chill_fixedfields ( - tree_cons (NULL_TREE, get_identifier (fldname), NULL_TREE), - TREE_TYPE (data), NULL_TREE); - if (field_decls == NULL_TREE) - field_decls = field; - else - chainon (field_decls, field); - } - - /* generate the union */ - if (field_decls != NULL_TREE) - { - tree data_id = get_identifier ("databuffer"); - tree data_decl; - - union_type_node = finish_struct ( - start_struct (UNION_TYPE, NULL_TREE), - field_decls); - data_decl = decl_temp1 (data_id, union_type_node, 0, NULL_TREE, 0, 0); - - chill_expand_assignment (rc_state->databufp, NOP_EXPR, - force_addr_of (data_decl)); - - chill_expand_assignment (rc_state->datalen, NOP_EXPR, - size_in_bytes (TREE_TYPE (data_decl))); - } - - /* tell runtime system if we had an else or not */ - chill_expand_assignment (rc_state->else_clause, NOP_EXPR, else_clause); - - /* generate the array of pointers to all buffers */ - { - tree array_id = get_identifier ("buf_ptr_array"); - tree array_type_node = - build_chill_array_type (ptr_type_node, - tree_cons (NULL_TREE, - build_chill_range_type (NULL_TREE, - integer_one_node, - build_int_2 (buffer_cnt, 0)), - NULL_TREE), - 0, NULL_TREE); - tree constr = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (tuple)); - tree array_decl = decl_temp1 (array_id, array_type_node, 0, - constr, 0, 0); - - chill_expand_assignment (build_chill_cast (ptr_type_node, rc_state->sig_code), - NOP_EXPR, - force_addr_of (array_decl)); - chill_expand_assignment (rc_state->n_sigs, NOP_EXPR, - build_int_2 (buffer_cnt, 0)); - } -} - -/* - * SIG_LIST is a tree list. The TREE_VALUEs are VAR_DECLs of - * __tmp_%s_code variables, and the TREE_PURPOSEs are the - * TYPE_DECLs of the __tmp_%s_struct types. LABEL_CNT is the - * case-label counter passed from build_receive_case_start. - */ -static void -build_receive_signal_case_end (sig_list, else_clause) - tree sig_list, else_clause; -{ - struct rc_state_type *rc_state = current_rc_state; - tree alist, temp1; - tree union_type_node = NULL_TREE; - tree field_decls = NULL_TREE; /* list of signal - structure, for the union */ - tree tuple = NULL_TREE; /* constructor for array of ptrs */ - int signal_cnt = 0; - int fldcnt = 0; - - /* for each list of locations, validate it against the - corresponding signal's list of fields. */ - { - for (alist = sig_list; alist != NULL_TREE; - signal_cnt++, alist = TREE_CHAIN (alist)) - { - tree value = TREE_VALUE (alist); - tree signame = TREE_VALUE (value); /* signal's ID node */ - tree sigdecl = lookup_name (signame); - tree sigtype = TREE_TYPE (sigdecl); - tree field; - char fldname[20]; - - if (IDENTIFIER_SIGNAL_DATA (signame)) - { - sprintf (fldname, "fld%03d", fldcnt++); - field = grok_chill_fixedfields ( - tree_cons (NULL_TREE, - get_identifier (fldname), - NULL_TREE), - sigtype, NULL_TREE); - if (field_decls == NULL_TREE) - field_decls = field; - else - chainon (field_decls, field); - - } - - temp1 = (tree)DECL_TASKING_CODE_DECL (sigdecl); - mark_addressable (temp1); - tuple = tree_cons (NULL_TREE, - build1 (ADDR_EXPR, - build_chill_pointer_type (chill_integer_type_node), - temp1), - tuple); - } - } - - /* generate the union of all of the signal data types */ - if (field_decls != NULL_TREE) - { - tree data_id = get_identifier ("databuffer"); - tree data_decl; - union_type_node = finish_struct (start_struct (UNION_TYPE, - NULL_TREE), - field_decls); - data_decl = - decl_temp1 (data_id, union_type_node, 0, NULL_TREE, 0, 0); - - chill_expand_assignment (rc_state->databufp, NOP_EXPR, - force_addr_of (data_decl)); - - chill_expand_assignment (rc_state->datalen, NOP_EXPR, - size_in_bytes (TREE_TYPE (data_decl))); - } - - /* tell runtime system if we had an else or not */ - chill_expand_assignment (rc_state->else_clause, NOP_EXPR, else_clause); - - /* generate the array of all signal codes */ - { - tree array_id = get_identifier ("sig_code_array"); - tree array_type_node - = build_chill_array_type ( - build_chill_pointer_type (chill_integer_type_node), - tree_cons (NULL_TREE, - build_chill_range_type (NULL_TREE, - integer_one_node, - build_int_2 (signal_cnt, 0)), - NULL_TREE), - 0, NULL_TREE); - tree constr = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse (tuple)); - tree array_decl = - decl_temp1 (array_id, array_type_node, 0, constr, 0, 0); - - chill_expand_assignment (rc_state->sig_code, NOP_EXPR, - force_addr_of (array_decl)); - - /* give number of signals to runtime system */ - chill_expand_assignment (rc_state->n_sigs, NOP_EXPR, - build_int_2 (signal_cnt, 0)); - } -} - -/* General function for the end of a RECEIVE CASE action */ - -void -build_receive_case_end (alist, else_clause) - tree alist, else_clause; -{ - rtx rcdone = gen_label_rtx (); - struct rc_state_type *rc_state = current_rc_state; - tree tmp; - int had_errors = 0; - - /* finish the if's, if generated */ - if (rc_state->if_generated) - expand_end_cond (); - - /* check alist for errors */ - for (tmp = alist; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp)) - { - if (TREE_CODE (TREE_VALUE (tmp)) == ERROR_MARK) - had_errors++; - } - - /* jump to the end of RECEIVE CASE processing */ - emit_jump (rcdone); - - /* define the __rcsetup label. We come here to initialize - all variables */ - emit_label (rc_state->rcsetup); - - if (alist == NULL_TREE && !had_errors) - { - error ("RECEIVE CASE without alternatives"); - goto gen_rcdoit; - } - - if (TREE_CODE (alist) == ERROR_MARK || had_errors) - goto gen_rcdoit; - - /* now call the actual end function */ - if (rc_state->bufseen) - build_receive_buffer_case_end (alist, else_clause); - else - build_receive_signal_case_end (alist, else_clause); - - /* now jump to the beginning of RECEIVE CASE processing */ -gen_rcdoit: ; - emit_jump (rc_state->rcdoit); - - /* define the __rcdone label. We come here when the whole - receive case is done. */ - emit_label (rcdone); - - current_rc_state = rc_state->enclosing; - free(rc_state); -} - -/* build a CONTINUE action */ - -void expand_continue_event (evloc) - tree evloc; -{ - tree filename, linenumber, evaddr; - - /* do some checks */ - if (evloc == NULL_TREE || TREE_CODE (evloc) == ERROR_MARK) - return; - - if (! CH_REFERABLE (evloc) || ! CH_IS_EVENT_MODE (TREE_TYPE (evloc))) - { - error ("CONTINUE requires an event location."); - return; - } - - evaddr = force_addr_of (evloc); - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - expand_expr_stmt ( - build_chill_function_call (lookup_name (get_identifier ("__continue")), - tree_cons (NULL_TREE, evaddr, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE))))); -} - -#if 0 - * The following code builds a DELAY CASE statement, - * which looks like this in CHILL: - * - * DCL ev1, ev2 EVENT, ins INSTANCE; - * DCL ev3 EVENT (10); - * DCL count1 INT := 0, count2 INT := 0; - * - * DELAY CASE SET ins; - * (ev1): count1 +:= 1; - * (ev2, ev3): count2 +:= 1; - * ESAC; - * - * Because we don''t know until we get to the ESAC how - * many events need processing, we generate the following - * C-equivalent code: - * - * - * { /* start a new symbol context */ - * typedef struct - * { - * void *p; - * unsigned long len; - * } Descr; - * int number_of_events; - * Descr *event_codes; - * - * goto __dlsetup; - * - * __dldoit: - * void *whatevent = __delay_event (number_of_events, - * event_codes, - * priority, - * &instance_loc, - * filename, - * linenumber); - * if (whatevent == &ev1) - * { - * /* code for ev1 alternative's action_statement_list */ - * count1 += 1; - * } - * else if (whatevent == &ev2 || whatevent == &ev3) - * { - * /* code for ev2 and ev3 alternative's action_statement_list */ - * count2 += 1; - * } - * goto __dl_done; - * - * __dlsetup: - * Descr event_code_ptr [3] = { - * { &ev1, -1 }, - * { &ev2, -1 }, - * { &ev3, 10 } }; - * event_codes = &event_code_ptr[0]; - * number_of_events = 3; - * goto __dldoit; - * - * __dl_done: - * ; - * } /* end the new symbol context */ - * -#endif - -struct dl_state_type -{ - struct dl_state_type *enclosing; - rtx dldoit; - rtx dlsetup; - tree n_events; - tree event_codes; - tree received_event; -}; - -struct dl_state_type *current_dl_state = NULL; - -/* build_receive_case_start returns an INTEGER_CST node - containing the case-label number to be used by - build_receive_case_end to generate correct labels */ -tree -build_delay_case_start (optset, optpriority) - tree optset, optpriority; -{ - /* counter to generate unique delay case labels */ - static int dl_lbl_count = 0; - tree current_label_value = - build_int_2 ((HOST_WIDE_INT)dl_lbl_count, 0); - tree wait_call; - tree actuallist = NULL_TREE; - tree filename, linenumber; - tree to_loc; - - struct dl_state_type *dl_state - = (struct dl_state_type*) xmalloc (sizeof (struct dl_state_type)); - dl_state->enclosing = current_dl_state; - current_dl_state = dl_state; - dl_state->dldoit = gen_label_rtx (); - dl_state->dlsetup = gen_label_rtx (); - - dl_lbl_count++; - - /* check the optional SET location */ - if (optset == NULL_TREE - || TREE_CODE (optset) == ERROR_MARK) - optset = null_pointer_node; - else if (CH_IS_INSTANCE_MODE (TREE_TYPE (optset)) && CH_LOCATION_P (optset)) - optset = force_addr_of (optset); - else - { - error ("SET requires INSTANCE location"); - optset = null_pointer_node; - } - - /* check the presence of the PRIORITY expression */ - if (optpriority == NULL_TREE) - optpriority = integer_zero_node; - else if (TREE_CODE (optpriority) == ERROR_MARK) - optpriority = integer_zero_node; - else if (TREE_CODE (TREE_TYPE (optpriority)) != INTEGER_TYPE) - { - error ("PRIORITY must be of integer type."); - optpriority = integer_zero_node; - } - - /* check for time supervised */ - to_loc = build_timeout_preface (); - - dl_state->n_events = - decl_temp1 (get_identifier ("number_of_events"), - integer_type_node, 0, integer_zero_node, 0, 0); - - dl_state->event_codes = - decl_temp1 (get_identifier ("event_codes"), - ptr_type_node, 0, null_pointer_node, 0, 0); - - /* wait_event will store the signal number in here */ - dl_state->received_event = - decl_temp1 (get_identifier ("received_event"), - ptr_type_node, 0, NULL_TREE, 0, 0); - - /* now jump to the end of RECEIVE CASE actions, to - set up variables for them. */ - emit_jump (dl_state->dlsetup); - - /* define the __rcdoit label. We come here after - initialization of all variables, to execute the - actions. */ - emit_label (dl_state->dldoit); - - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - /* here we go, call the runtime routine */ - actuallist = tree_cons (NULL_TREE, force_addr_of (dl_state->received_event), - tree_cons (NULL_TREE, dl_state->n_events, - tree_cons (NULL_TREE, dl_state->event_codes, - tree_cons (NULL_TREE, optpriority, - tree_cons (NULL_TREE, to_loc, - tree_cons (NULL_TREE, optset, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE)))))))); - - wait_call = build_chill_function_call ( - lookup_name (get_identifier ("__delay_event")), - actuallist); - -#if 0 - chill_expand_assignment (dl_state->received_event, NOP_EXPR, wait_call); -#endif - build_timesupervised_call (wait_call, to_loc); - return current_label_value; -} - -/* - EVENTLIST is the list of this alternative's events - and IF_OR_ELSEIF indicates what action (1 for if and - 0 for else if) should be generated. -*/ -void -build_delay_case_label (eventlist, if_or_elseif) - tree eventlist; - int if_or_elseif; -{ - tree eventp, expr = NULL_TREE; - - if (eventlist == NULL_TREE || TREE_CODE (eventlist) == ERROR_MARK) - return; - - for (eventp = eventlist; eventp != NULL_TREE; - eventp = TREE_CHAIN (eventp)) - { - tree event = TREE_VALUE (eventp); - tree temp1; - - if (event == NULL_TREE || TREE_CODE (event) == ERROR_MARK) - temp1 = null_pointer_node; - else if (! CH_IS_EVENT_MODE (TREE_TYPE (event)) || ! CH_REFERABLE (event)) - { - error ("delay alternative must be an EVENT location."); - temp1 = null_pointer_node; - } - else - temp1 = force_addr_of (event); - - /* build the conditional expression */ - if (expr == NULL_TREE) - expr = build (EQ_EXPR, boolean_type_node, - current_dl_state->received_event, temp1); - else - expr = - build (TRUTH_ORIF_EXPR, boolean_type_node, expr, - build (EQ_EXPR, boolean_type_node, - current_dl_state->received_event, temp1)); - } - if (if_or_elseif) - expand_start_cond (expr, 0); - else - expand_start_elseif (expr); - - /* last action here */ - emit_line_note (input_filename, lineno); -} - -/* - * EVENT_LIST is a tree list. The TREE_VALUEs are VAR_DECLs of - * EVENT variables. LABEL_CNT is the case-label counter - * passed from build_delay_case_start. - */ -void -build_delay_case_end (event_list) - tree event_list; -{ - struct dl_state_type *dl_state = current_dl_state; - rtx dldone = gen_label_rtx (); - tree tuple = NULL_TREE; /* constructor for array of descrs */ - tree acode; - int event_cnt = 0; - - /* if we have an empty event_list, there was no alternatives and we - havn't started an if therefor don't run expand_end_cond */ - if (event_list != NULL_TREE) - /* finish the if's */ - expand_end_cond (); - - /* jump to the end of RECEIVE CASE processing */ - emit_jump (dldone); - - /* define the __dlsetup label. We come here to initialize - all variables */ - emit_label (dl_state->dlsetup); - - if (event_list == NULL_TREE) - { - error ("DELAY CASE without alternatives"); - goto gen_dldoit; - } - - if (event_list == NULL_TREE - || TREE_CODE (event_list) == ERROR_MARK) - goto gen_dldoit; - - /* make a list of pointers (in reverse order) - to the event code variables */ - for (acode = event_list; acode != NULL_TREE; - acode = TREE_CHAIN (acode)) - { - tree event = TREE_VALUE (acode); - tree event_length; - tree descr_init; - - if (event == NULL_TREE || TREE_CODE (event) == ERROR_MARK) - { - descr_init = - tree_cons (NULL_TREE, null_pointer_node, - tree_cons (NULL_TREE, integer_zero_node, NULL_TREE)); - } - else - { - event_length = max_queue_size (TREE_TYPE (event)); - if (event_length == NULL_TREE) - event_length = infinite_buffer_event_length_node; - descr_init = - tree_cons (NULL_TREE, force_addr_of (event), - tree_cons (NULL_TREE, event_length, NULL_TREE)); - } - tuple = tree_cons (NULL_TREE, - build_nt (CONSTRUCTOR, NULL_TREE, descr_init), - tuple); - event_cnt++; - } - - /* generate the array of all event code pointers */ - { - tree descr_type = TREE_TYPE (lookup_name (get_identifier ("__tmp_DESCR_type"))); - tree array_id = get_identifier ("event_code_array"); - tree array_type_node - = build_chill_array_type (descr_type, - tree_cons (NULL_TREE, - build_chill_range_type (NULL_TREE, - integer_one_node, - build_int_2 (event_cnt, 0)), - NULL_TREE), - 0, NULL_TREE); - tree constr = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse (tuple)); - tree array_decl = - decl_temp1 (array_id, array_type_node, 0, constr, 0, 0); - - chill_expand_assignment (dl_state->event_codes, NOP_EXPR, - force_addr_of (array_decl)); - - /* give number of signals to runtime system */ - chill_expand_assignment (dl_state->n_events, NOP_EXPR, - build_int_2 (event_cnt, 0)); - } - - /* now jump to the beginning of DELAY CASE processing */ -gen_dldoit: - emit_jump (dl_state->dldoit); - - /* define the __dldone label. We come here when the whole - DELAY CASE is done. */ - emit_label (dldone); - - current_dl_state = dl_state->enclosing; - free(dl_state); -} - -#if 0 - * The following code builds a simple delay statement, - * which looks like this in CHILL: - * - * DCL ev1 EVENT(5), ins INSTANCE; - * - * DELAY ev1 PRIORITY 7; - * - * This statement unconditionally delays the current - * PROCESS, until some other process CONTINUEs it. - * - * Here is the generated C code: - * - * typedef struct - * { - * void *p; - * unsigned long len; - * } Descr; - * - * static short __tmp_ev1_code; - * - * { /* start a new symbol context */ - * - * Descr __delay_array[1] = { { ev1, 5 } }; - * - * __delay_event (1, &__delay_array, 7, NULL, - * filename, linenumber); - * - * } /* end of symbol scope */ - */ -#endif -void -build_delay_action (event, optpriority) - tree event, optpriority; -{ - int had_errors = 0; - tree to_loc = NULL_TREE; - /* we discard the return value of __delay_event, cause in - a normal DELAY action no selections have to be made */ - tree ev_got = null_pointer_node; - - /* check the event */ - if (event == NULL_TREE || TREE_CODE (event) == ERROR_MARK) - had_errors = 1; - else if (! CH_IS_EVENT_MODE (TREE_TYPE (event)) || ! CH_REFERABLE (event)) - { - error ("DELAY action requires an event location."); - had_errors = 1; - } - - /* check the presence of priority */ - if (optpriority != NULL_TREE) - { - if (TREE_CODE (optpriority) == ERROR_MARK) - return; - if (TREE_CODE (TREE_TYPE (optpriority)) != INTEGER_TYPE) - { - error ("PRIORITY in DELAY action must be of integer type."); - return; - } - } - else - { - /* issue a warning in case of -Wall */ - if (extra_warnings) - { - warning ("DELAY action without priority."); - warning (" PRIORITY defaulted to 0."); - } - optpriority = integer_zero_node; - } - if (had_errors) - return; - - { - tree descr_type; - tree array_type_node; - tree array_decl; - tree descr_init; - tree array_init; - tree event_length = max_queue_size (TREE_TYPE (event)); - tree event_codes; - tree filename = force_addr_of (get_chill_filename ()); - tree linenumber = get_chill_linenumber (); - tree actuallist; - - to_loc = build_timeout_preface (); - - descr_type = TREE_TYPE (lookup_name (get_identifier ("__tmp_DESCR_type"))); - - array_type_node = - build_chill_array_type (descr_type, - tree_cons (NULL_TREE, - build_chill_range_type (NULL_TREE, integer_one_node, - integer_one_node), - NULL_TREE), - 0, NULL_TREE); - if (event_length == NULL_TREE) - event_length = infinite_buffer_event_length_node; - - descr_init = - tree_cons (NULL_TREE, force_addr_of (event), - tree_cons (NULL_TREE, event_length, NULL_TREE)); - array_init = - tree_cons (NULL_TREE, - build_nt (CONSTRUCTOR, NULL_TREE, descr_init), - NULL_TREE); - array_decl = - decl_temp1 (get_unique_identifier ("event_codes_array"), - array_type_node, 0, - build_nt (CONSTRUCTOR, NULL_TREE, array_init), - 0, 0); - - event_codes = - decl_temp1 (get_unique_identifier ("event_ptr"), - ptr_type_node, 0, - force_addr_of (array_decl), - 0, 0); - - actuallist = - tree_cons (NULL_TREE, ev_got, - tree_cons (NULL_TREE, integer_one_node, - tree_cons (NULL_TREE, event_codes, - tree_cons (NULL_TREE, optpriority, - tree_cons (NULL_TREE, to_loc, - tree_cons (NULL_TREE, null_pointer_node, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE)))))))); - - - build_timesupervised_call ( - build_chill_function_call ( - lookup_name (get_identifier ("__delay_event")), - actuallist), to_loc); - } -} - -void -expand_send_buffer (buffer, value, optpriority, optwith, optto) - tree buffer, value, optpriority, optwith, optto; -{ - tree filename, linenumber; - tree buffer_mode_decl = NULL_TREE; - tree buffer_ptr, value_ptr; - int had_errors = 0; - tree timeout_value, fcall; - - /* check buffer location */ - if (buffer == NULL_TREE || TREE_CODE (buffer) == ERROR_MARK) - { - buffer = NULL_TREE; - had_errors = 1; - } - if (buffer != NULL_TREE) - { - if (! CH_IS_BUFFER_MODE (TREE_TYPE (buffer)) || ! CH_REFERABLE (buffer)) - { - error ("send buffer action requires a BUFFER location."); - had_errors = 1; - } - else - buffer_mode_decl = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (buffer))); - } - - /* check value and type */ - if (value == NULL_TREE || TREE_CODE (value) == ERROR_MARK) - { - had_errors = 1; - value = NULL_TREE; - } - if (value != NULL_TREE) - { - if (TREE_CHAIN (value) != NULL_TREE) - { - error ("there must be only 1 value for send buffer action."); - had_errors = 1; - } - else - { - value = TREE_VALUE (value); - if (value == NULL_TREE || TREE_CODE (value) == ERROR_MARK) - { - had_errors = 1; - value = NULL_TREE; - } - if (value != NULL_TREE && buffer_mode_decl != NULL_TREE) - { - if (TREE_TYPE (buffer_mode_decl) != NULL_TREE && - TREE_CODE (TREE_TYPE (buffer_mode_decl)) == ERROR_MARK) - had_errors = 1; - else if (CH_COMPATIBLE (value, TREE_TYPE (buffer_mode_decl))) - { - value = convert (TREE_TYPE (buffer_mode_decl), value); - if (value == NULL_TREE || TREE_CODE (value) == ERROR_MARK) - { - error ("convert failed for send buffer action."); - had_errors = 1; - } - } - else - { - error ("incompatible modes in send buffer action."); - had_errors = 1; - } - } - } - } - - /* check the presence of priority */ - if (optpriority == NULL_TREE) - { - if (send_buffer_prio == NULL_TREE) - { - /* issue a warning in case of -Wall */ - if (extra_warnings) - { - warning ("Buffer sent without priority"); - warning (" and no default priority was set."); - warning (" PRIORITY defaulted to 0."); - } - optpriority = integer_zero_node; - } - else - optpriority = send_buffer_prio; - } - else if (TREE_CODE (optpriority) == ERROR_MARK) - had_errors = 1; - else if (TREE_CODE (TREE_TYPE (optpriority)) != INTEGER_TYPE) - { - error ("PRIORITY must be of integer type."); - had_errors = 1; - } - - if (optwith != NULL_TREE) - { - error ("WITH not allowed for send buffer action."); - had_errors = 1; - } - if (optto != NULL_TREE) - { - error ("TO not allowed for send buffer action."); - had_errors = 1; - } - if (had_errors) - return; - - { - tree descr_type; - tree buffer_descr, buffer_init, buffer_length; - tree val; - - /* process timeout */ - timeout_value = build_timeout_preface (); - - descr_type = lookup_name (get_identifier ("__tmp_DESCR_type")); - - /* build descr for buffer */ - buffer_length = max_queue_size (TREE_TYPE (buffer)); - if (buffer_length == NULL_TREE) - buffer_length = infinite_buffer_event_length_node; - buffer_init = build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, force_addr_of (buffer), - tree_cons (NULL_TREE, buffer_length, NULL_TREE))); - buffer_descr = decl_temp1 (get_unique_identifier ("buffer_descr"), - TREE_TYPE (descr_type), 0, buffer_init, - 0, 0); - buffer_ptr = decl_temp1 (get_unique_identifier ("buffer_ptr"), - ptr_type_node, 0, - force_addr_of (buffer_descr), - 0, 0); - - /* build descr for value */ - if (! CH_REFERABLE (value)) - val = decl_temp1 (get_identifier ("buffer_value"), - TREE_TYPE (value), 0, - value, 0, 0); - else - val = value; - - value_ptr = build_chill_descr (val); - - } - - /* get filename and linenumber */ - filename = force_addr_of (get_chill_filename ()); - linenumber = get_chill_linenumber (); - - /* Now, we can call the runtime */ - fcall = build_chill_function_call ( - lookup_name (get_identifier ("__send_buffer")), - tree_cons (NULL_TREE, buffer_ptr, - tree_cons (NULL_TREE, value_ptr, - tree_cons (NULL_TREE, optpriority, - tree_cons (NULL_TREE, timeout_value, - tree_cons (NULL_TREE, filename, - tree_cons (NULL_TREE, linenumber, NULL_TREE))))))); - build_timesupervised_call (fcall, timeout_value); -} -# if 0 - -void -process_buffer_decls (namelist, mode, optstatic) - tree namelist, mode; - int optstatic; -{ - tree names; - int quasi_flag = current_module->is_spec_module; - - if (pass < 2) - return; - - for (names = namelist; names != NULL_TREE; names = TREE_CHAIN (names)) - { - tree name = TREE_VALUE (names); - tree bufdecl = lookup_name (name); - tree code_decl = - decl_tasking_code_variable (name, &buffer_code, quasi_flag); - - /* remember the code variable in the buffer decl */ - DECL_TASKING_CODE_DECL (bufdecl) = (struct lang_decl *)code_decl; - - add_taskstuff_to_list (code_decl, "_TT_Buffer", - quasi_flag ? NULL_TREE : buffer_code, - bufdecl); - } -} -#endif - -/* - * if no queue size was specified, QUEUESIZE is integer_zero_node. - */ -tree -build_buffer_type (element_type, queuesize) - tree element_type, queuesize; -{ - tree type, field; - if (element_type == NULL_TREE || TREE_CODE (element_type) == ERROR_MARK) - return error_mark_node; - if (queuesize != NULL_TREE && TREE_CODE (queuesize) == ERROR_MARK) - return error_mark_node; - - type = make_node (RECORD_TYPE); - field = build_decl (FIELD_DECL, get_identifier("__buffer_data"), - ptr_type_node); - TYPE_FIELDS (type) = field; - TREE_CHAIN (field) - = build_lang_decl (TYPE_DECL, get_identifier ("__element_mode"), - element_type); - field = TREE_CHAIN (field); - if (queuesize) - { - tree size_field = build_decl (CONST_DECL, get_identifier("__queue_max"), - integer_type_node); - DECL_INITIAL (size_field) = queuesize; - TREE_CHAIN (field) = size_field; - } - CH_IS_BUFFER_MODE (type) = 1; - CH_TYPE_NONVALUE_P (type) = 1; - if (pass == 2) - type = layout_chill_struct_type (type); - return type; -} - -#if 0 -tree -build_buffer_descriptor (bufname, expr, optpriority) - tree bufname, expr, optpriority; -{ - tree bufdecl; - - if (bufname == NULL_TREE - || TREE_CODE (bufname) == ERROR_MARK) - return error_mark_node; - - if (expr != NULL_TREE - && TREE_CODE (expr) == ERROR_MARK) - return error_mark_node; -#if 0 -/* FIXME: is this what we really want to test? */ - bufdecl = lookup_name (bufname); - if (TREE_CODE (bufdecl) != TYPE_DECL - || ! CH_IS_BUFFER_MODE (TREE_TYPE (bufdecl))) - { - error ("SEND requires a BUFFER; `%s' is not a BUFFER name", - bufname); - return error_mark_node; - } -#endif - { - /* build buffer/signal data structure */ - tree bufdataname = get_unique_identifier (IDENTIFIER_POINTER (bufname)); - tree dataptr; - - if (expr == NULL_TREE) - dataptr = null_pointer_node; - else - { - tree decl = - decl_temp1 (bufdataname, TREE_TYPE (bufdecl), 0, - expr, 0, 0); - /* prevent granting of this variable */ - DECL_SOURCE_LINE (decl) = 0; - - dataptr = force_addr_of (decl); - } - - /* build descriptor pointing to buffer data */ - { - tree tasking_message_var = get_unique_identifier (IDENTIFIER_POINTER (bufname)); - tree data_len = (expr == NULL_TREE) ? integer_zero_node : - size_in_bytes (TREE_TYPE (bufdecl)); - tree tasking_code = (tree)DECL_TASKING_CODE_DECL (bufdecl); - tree tuple = build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, - build1 (ADDR_EXPR, - build_chill_pointer_type (chill_integer_type_node), - tasking_code), - tree_cons (NULL_TREE, data_len, - tree_cons (NULL_TREE, dataptr, NULL_TREE)))); - - tree decl = decl_temp1 (tasking_message_var, - TREE_TYPE (tasking_message_type), 0, - tuple, 0, 0); - mark_addressable (tasking_code); - /* prevent granting of this variable */ - DECL_SOURCE_LINE (decl) = 0; - - tuple = force_addr_of (decl); - return tuple; - } - } -} -#endif - -#if 0 -void -process_event_decls (namelist, mode, optstatic) - tree namelist, mode; - int optstatic; -{ - tree names; - int quasi_flag = current_module->is_spec_module; - - if (pass < 2) - return; - - for (names = namelist; names != NULL_TREE; names = TREE_CHAIN (names)) - { - tree name = TREE_VALUE (names); - tree eventdecl = lookup_name (name); - tree code_decl = - decl_tasking_code_variable (name, &event_code, quasi_flag); - - /* remember the code variable in the event decl */ - DECL_TASKING_CODE_DECL (eventdecl) = (struct lang_decl *)code_decl; - - add_taskstuff_to_list (code_decl, "_TT_Event", - quasi_flag ? NULL_TREE : event_code, - eventdecl); - } -} -#endif - -/* Return the buffer or event length of a buffer or event mode. - (NULL_TREE means unlimited.) */ - -tree -max_queue_size (mode) - tree mode; -{ - tree field = TYPE_FIELDS (mode); - for ( ; field != NULL_TREE ; field = TREE_CHAIN (field)) - { - if (TREE_CODE (field) == CONST_DECL) - return DECL_INITIAL (field); - } - return NULL_TREE; -} - -/* Return the buffer element mode of a buffer mode. */ - -tree -buffer_element_mode (bufmode) - tree bufmode; -{ - tree field = TYPE_FIELDS (bufmode); - for ( ; field != NULL_TREE; field = TREE_CHAIN (field)) - { - if (TREE_CODE (field) == TYPE_DECL) - return TREE_TYPE (field); - } - return NULL_TREE; -} - -/* invalidate buffer element mode in case we detect, that the - elelment mode has the non-value property */ - -void -invalidate_buffer_element_mode (bufmode) - tree bufmode; -{ - tree field = TYPE_FIELDS (bufmode); - for ( ; field != NULL_TREE; field = TREE_CHAIN (field)) - { - if (TREE_CODE (field) == TYPE_DECL) - { - TREE_TYPE (field) = error_mark_node; - return; - } - } -} - -/* For an EVENT or BUFFER mode TYPE, with a give maximum queue size QSIZE, - perform various error checks. Return a new queue size. */ - -tree -check_queue_size (qsize) - tree qsize; -{ - if (qsize == NULL_TREE || TREE_CODE (qsize) == ERROR_MARK) - return qsize; - if (TREE_TYPE (qsize) == NULL_TREE - || !CH_SIMILAR (TREE_TYPE (qsize), integer_type_node)) - { - error ("non-integral max queue size for EVENT/BUFFER mode"); - return integer_one_node; - } - if (TREE_CODE (qsize) != INTEGER_CST) - { - error ("non-constant max queue size for EVENT/BUFFER mode"); - return integer_one_node; - } - if (compare_int_csts (pedantic ? LE_EXPR : LT_EXPR, - qsize, - integer_zero_node)) - { - error ("max queue_size for EVENT/BUFFER is not positive"); - return integer_one_node; - } - return qsize; -} - -/* - * An EVENT type is modelled as a boolean type, which should - * allocate the minimum amount of space. - */ -tree -build_event_type (queuesize) - tree queuesize; -{ - tree type = make_node (RECORD_TYPE); - tree field = build_decl (FIELD_DECL, get_identifier("__event_data"), - ptr_type_node); - TYPE_FIELDS (type) = field; - if (queuesize) - { - tree size_field = build_decl (CONST_DECL, get_identifier("__queue_max"), - integer_type_node); - DECL_INITIAL (size_field) = queuesize; - TREE_CHAIN (field) = size_field; - } - CH_IS_EVENT_MODE (type) = 1; - CH_TYPE_NONVALUE_P (type) = 1; - if (pass == 2) - type = layout_chill_struct_type (type); - return type; -} - -/* - * Initialize the various types of tasking data. - */ -void -tasking_init () -{ - extern int ignore_case; - extern int special_UC; - extern tree chill_predefined_function_type; - tree temp, ins_ftype_void; - tree endlink = void_list_node; - tree int_ftype_ptr_int_ptr_ptr_int_ptr_int_ptr_ptr_int; - tree void_ftype_ptr; - tree void_ftype_ptr_ins_int_int_ptr_ptr_int; - tree int_ftype_ptr_ptr_int_ptr_ptr_int; - tree void_ftype_int_int_int_ptr_ptr_ptr_int; - tree int_ftype_ptr_int_ptr_int_ptr_ptr_ptr_int; - tree int_ftype_ptr_int; - - /* type of tasking code variables */ - chill_taskingcode_type_node = short_unsigned_type_node; - - void_ftype_void = - build_function_type (void_type_node, - tree_cons (NULL_TREE, void_type_node, NULL_TREE)); - - build_instance_type (); - ins_ftype_void - = build_function_type (instance_type_node, - tree_cons (NULL_TREE, void_type_node, - build_tree_list (NULL_TREE, void_type_node))); - - builtin_function ("__whoami", ins_ftype_void, - 0, NOT_BUILT_IN, NULL_PTR); - - build_tasking_message_type (); - - temp = build_decl (TYPE_DECL, - get_identifier ("__tmp_TaskingStruct"), - build_tasking_struct ()); - pushdecl (temp); - DECL_SOURCE_LINE (temp) = 0; - - /* any SIGNAL will be compatible with this one */ - generic_signal_type_node = copy_node (boolean_type_node); - - builtin_function ((ignore_case || ! special_UC) ? "copy_number" : "COPY_NUMBER", - chill_predefined_function_type, - BUILT_IN_COPY_NUMBER, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ((ignore_case || ! special_UC) ? "gen_code" : "GEN_CODE", - chill_predefined_function_type, - BUILT_IN_GEN_CODE, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ((ignore_case || ! special_UC) ? "gen_inst" : "GEN_INST", - chill_predefined_function_type, - BUILT_IN_GEN_INST, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ((ignore_case || ! special_UC) ? "gen_ptype" : "GEN_PTYPE", - chill_predefined_function_type, - BUILT_IN_GEN_PTYPE, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ((ignore_case || ! special_UC) ? "proc_type" : "PROC_TYPE", - chill_predefined_function_type, - BUILT_IN_PROC_TYPE, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ((ignore_case || ! special_UC) ? "queue_length" : "QUEUE_LENGTH", - chill_predefined_function_type, - BUILT_IN_QUEUE_LENGTH, BUILT_IN_NORMAL, NULL_PTR); - - int_ftype_ptr_int_ptr_ptr_int_ptr_int_ptr_ptr_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))))))))))); - void_ftype_ptr - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, endlink)); - - int_ftype_ptr_int_ptr_int_ptr_ptr_ptr_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))))))))); - - void_ftype_ptr_ins_int_int_ptr_ptr_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, instance_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink)))))))); - int_ftype_ptr_ptr_int_ptr_ptr_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))))))); - - void_ftype_int_int_int_ptr_ptr_ptr_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink)))))))); - - int_ftype_ptr_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))); - - builtin_function ("__delay_event", int_ftype_ptr_int_ptr_int_ptr_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__queue_length", int_ftype_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__register_tasking", void_ftype_ptr, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__send_signal", void_ftype_ptr_ins_int_int_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__send_buffer", int_ftype_ptr_ptr_int_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__start_process", void_ftype_int_int_int_ptr_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__stop_process", void_ftype_void, 0, NOT_BUILT_IN, - NULL_PTR); - builtin_function ("__wait_buffer", int_ftype_ptr_int_ptr_ptr_int_ptr_int_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - builtin_function ("__wait_signal_timed", int_ftype_ptr_int_ptr_ptr_int_ptr_int_ptr_ptr_int, - 0, NOT_BUILT_IN, NULL_PTR); - - infinite_buffer_event_length_node = build_int_2 (-1, 0); - TREE_TYPE (infinite_buffer_event_length_node) = long_integer_type_node; - TREE_UNSIGNED (infinite_buffer_event_length_node) = 1; -} |