1 /* Implement timing-related actions for CHILL.
2 Copyright (C) 1992, 1993, 1994, 1998, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
33 /* set non-zero if input text is forced to lowercase */
34 extern int ignore_case
;
36 /* set non-zero if special words are to be entered in uppercase */
37 extern int special_UC
;
40 tree abs_timing_type_node
;
41 tree duration_timing_type_node
;
44 static tree rtstime_type_node
= NULL_TREE
;
46 /* the stack for AFTER primval [ DELAY ] IN
47 and has following layout
49 TREE_VALUE (TREE_VALUE (after_stack)) = current time or NULL_TREE (if DELAY specified)
50 TREE_PURPOSE (TREE_VALUE (after_stack)) = the duration location
51 TREE_VALUE (TREE_PURPOSE (after_stack)) = label at TIMEOUT
52 TREE_PURPOSE (TREE_PURPOSE (after_stack)) = label at the end of AFTER action
54 tree after_stack
= NULL_TREE
;
56 /* in pass 1 we need a separate list for the labels */
57 static tree after_stack_pass_1
= NULL_TREE
;
58 static tree after_help
;
63 tree ptr_ftype_durt_ptr_int
;
64 tree int_ftype_abst_ptr_int
;
66 tree long_ftype_int_int_int_int_int_int_int_ptr_int
;
67 tree void_ftype_abstime_ptr
;
68 tree int_ftype_ptr_durt_ptr
;
69 tree void_ftype_durt_ptr
;
70 tree void_ftype_ptr_durt_ptr_int
;
75 ulong_type
= TREE_TYPE (lookup_name (
76 get_identifier ((ignore_case
|| ! special_UC
) ?
79 /* build modes for TIME and DURATION */
80 duration_timing_type_node
= make_unsigned_type (LONG_TYPE_SIZE
);
81 temp
= pushdecl (build_decl (TYPE_DECL
, ridpointers
[(int)RID_DURATION
],
82 duration_timing_type_node
));
83 SET_CH_NOVELTY_NONNIL (duration_timing_type_node
, temp
);
84 abs_timing_type_node
= make_unsigned_type (LONG_TYPE_SIZE
);
85 temp
= pushdecl (build_decl (TYPE_DECL
, ridpointers
[(int)RID_TIME
],
86 abs_timing_type_node
));
87 SET_CH_NOVELTY_NONNIL (abs_timing_type_node
, temp
);
89 /* the mode of time the runtimesystem returns */
90 if (rtstime_type_node
== NULL_TREE
)
92 tree decl1
, decl2
, result
;
94 decl1
= build_decl (FIELD_DECL
,
95 get_identifier ("secs"),
97 DECL_INITIAL (decl1
) = NULL_TREE
;
98 decl2
= build_decl (FIELD_DECL
,
99 get_identifier ("nsecs"),
101 DECL_INITIAL (decl2
) = NULL_TREE
;
102 TREE_CHAIN (decl2
) = NULL_TREE
;
103 TREE_CHAIN (decl1
) = decl2
;
105 result
= build_chill_struct_type (decl1
);
106 pushdecl (temp
= build_decl (TYPE_DECL
,
107 get_identifier ("__tmp_rtstime"), result
));
108 DECL_SOURCE_LINE (temp
) = 0;
109 satisfy_decl (temp
, 0);
110 rtstime_type_node
= TREE_TYPE (temp
);
113 endlink
= void_list_node
;
115 ptr_ftype_durt_ptr_int
116 = build_function_type (ptr_type_node
,
117 tree_cons (NULL_TREE
, duration_timing_type_node
,
118 tree_cons (NULL_TREE
, ptr_type_node
,
119 tree_cons (NULL_TREE
, integer_type_node
,
122 int_ftype_abst_ptr_int
123 = build_function_type (integer_type_node
,
124 tree_cons (NULL_TREE
, abs_timing_type_node
,
125 tree_cons (NULL_TREE
, ptr_type_node
,
126 tree_cons (NULL_TREE
, integer_type_node
,
130 = build_function_type (void_type_node
,
131 tree_cons (NULL_TREE
, ptr_type_node
,
134 long_ftype_int_int_int_int_int_int_int_ptr_int
135 = build_function_type (abs_timing_type_node
,
136 tree_cons (NULL_TREE
, integer_type_node
,
137 tree_cons (NULL_TREE
, integer_type_node
,
138 tree_cons (NULL_TREE
, integer_type_node
,
139 tree_cons (NULL_TREE
, integer_type_node
,
140 tree_cons (NULL_TREE
, integer_type_node
,
141 tree_cons (NULL_TREE
, integer_type_node
,
142 tree_cons (NULL_TREE
, integer_type_node
,
143 tree_cons (NULL_TREE
, ptr_type_node
,
144 tree_cons (NULL_TREE
, integer_type_node
,
147 void_ftype_abstime_ptr
148 = build_function_type (void_type_node
,
149 tree_cons (NULL_TREE
, abs_timing_type_node
,
150 tree_cons (NULL_TREE
, ptr_type_node
,
153 int_ftype_ptr_durt_ptr
154 = build_function_type (integer_type_node
,
155 tree_cons (NULL_TREE
, ptr_type_node
,
156 tree_cons (NULL_TREE
, duration_timing_type_node
,
157 tree_cons (NULL_TREE
, ptr_type_node
,
161 = build_function_type (void_type_node
,
162 tree_cons (NULL_TREE
, duration_timing_type_node
,
163 tree_cons (NULL_TREE
, ptr_type_node
,
166 void_ftype_ptr_durt_ptr_int
167 = build_function_type (void_type_node
,
168 tree_cons (NULL_TREE
, ptr_type_node
,
169 tree_cons (NULL_TREE
, duration_timing_type_node
,
170 tree_cons (NULL_TREE
, ptr_type_node
,
171 tree_cons (NULL_TREE
, integer_type_node
,
174 builtin_function ("_abstime", long_ftype_int_int_int_int_int_int_int_ptr_int
,
175 0, NOT_BUILT_IN
, NULL_PTR
);
176 builtin_function ("__check_cycle", void_ftype_ptr_durt_ptr_int
,
177 0, NOT_BUILT_IN
, NULL_PTR
);
178 builtin_function ("__convert_duration_rtstime", void_ftype_durt_ptr
,
179 0, NOT_BUILT_IN
, NULL_PTR
);
180 builtin_function ("__define_timeout", ptr_ftype_durt_ptr_int
,
181 0, NOT_BUILT_IN
, NULL_PTR
);
182 builtin_function ("_inttime", void_ftype_abstime_ptr
,
183 0, NOT_BUILT_IN
, NULL_PTR
);
184 builtin_function ("__remaintime", int_ftype_ptr_durt_ptr
,
185 0, NOT_BUILT_IN
, NULL_PTR
);
186 builtin_function ("__rtstime", void_ftype_ptr
,
187 0, NOT_BUILT_IN
, NULL_PTR
);
188 builtin_function ("__wait_until", int_ftype_abst_ptr_int
,
189 0, NOT_BUILT_IN
, NULL_PTR
);
204 * if (__wait_until (primval) == 0)
215 tree abstime
, expr
, filename
, fcall
;
217 if (t
== NULL_TREE
|| TREE_CODE (t
) == ERROR_MARK
)
218 abstime
= convert (abs_timing_type_node
, build_int_2 (0, 0));
222 if (TREE_TYPE (abstime
) != abs_timing_type_node
)
224 error ("absolute time value must be of mode TIME");
225 abstime
= convert (abs_timing_type_node
, build_int_2 (0, 0));
227 filename
= force_addr_of (get_chill_filename ());
228 fcall
= build_chill_function_call (
229 lookup_name (get_identifier ("__wait_until")),
230 tree_cons (NULL_TREE
, abstime
,
231 tree_cons (NULL_TREE
, filename
,
232 tree_cons (NULL_TREE
, get_chill_linenumber (), NULL_TREE
))));
233 expr
= build (EQ_EXPR
, integer_type_node
, fcall
, integer_zero_node
);
234 expand_start_cond (expr
, 0);
235 emit_line_note (input_filename
, lineno
);
253 * __check_cycle (&now, primval, filename, lineno);
260 build_cycle_start (t
)
263 tree purpose
= build_tree_list (NULL_TREE
, NULL_TREE
);
264 tree toid
= build_tree_list (purpose
, NULL_TREE
);
266 /* define the label. Note: define_label needs to be called in
267 pass 1 and pass 2. */
268 TREE_VALUE (toid
) = define_label (input_filename
, lineno
,
269 get_unique_identifier ("CYCLE_label"));
272 tree duration_value
, now_location
;
274 if (t
== NULL_TREE
|| TREE_CODE (t
) == ERROR_MARK
)
275 duration_value
= convert (duration_timing_type_node
, build_int_2 (0,0));
279 if (TREE_TYPE (duration_value
) != duration_timing_type_node
)
281 error ("duration primitive value must be of mode DURATION");
282 duration_value
= convert (duration_timing_type_node
, build_int_2 (0,0));
284 TREE_PURPOSE (TREE_PURPOSE (toid
)) = duration_value
;
285 /* define the variable */
286 now_location
= decl_temp1 (get_unique_identifier ("CYCLE_var"),
287 rtstime_type_node
, 0,
289 TREE_VALUE (TREE_PURPOSE (toid
)) = force_addr_of (now_location
);
291 /* build the call to __rtstime */
293 build_chill_function_call (lookup_name (get_identifier ("__rtstime")),
294 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_PURPOSE (toid
)))));
301 build_cycle_end (toid
)
304 tree filename
, linenumber
;
306 /* here we call __check_cycle and then jump to beginning of this
308 filename
= force_addr_of (get_chill_filename ());
309 linenumber
= get_chill_linenumber ();
311 build_chill_function_call (
312 lookup_name (get_identifier ("__check_cycle")),
313 tree_cons (NULL_TREE
, TREE_VALUE (TREE_PURPOSE (toid
)),
314 tree_cons (NULL_TREE
, TREE_PURPOSE (TREE_PURPOSE (toid
)),
315 tree_cons (NULL_TREE
, filename
,
316 tree_cons (NULL_TREE
, linenumber
, NULL_TREE
))))));
317 expand_goto (TREE_VALUE (toid
));
324 * AFTER primval [ DELAY ] IN
333 * struct chill_time __now;
334 * duration dur = primval;
335 * if (! delay_spceified)
336 * __rts_time (&__now);
349 build_after_start (duration
, delay_flag
)
357 value
= tree_cons (NULL_TREE
, NULL_TREE
, NULL_TREE
);
358 purpose
= after_stack_pass_1
;
359 after_stack_pass_1
= TREE_CHAIN (after_stack_pass_1
);
360 after_stack
= tree_cons (purpose
, value
, after_stack
);
362 if (TREE_TYPE (duration
) != duration_timing_type_node
)
364 error ("duration primitive value must be of mode DURATION");
365 duration
= convert (duration_timing_type_node
, build_int_2 (0,0));
367 TREE_PURPOSE (value
) = decl_temp1 (get_identifier ("AFTER_duration"),
368 duration_timing_type_node
, 0,
373 /* in this case we have to get the current time */
374 TREE_VALUE (value
) = decl_temp1 (get_unique_identifier ("AFTER_now"),
375 rtstime_type_node
, 0,
377 /* build the function call to initialize the variable */
379 build_chill_function_call (lookup_name (get_identifier ("__rtstime")),
380 build_tree_list (NULL_TREE
, force_addr_of (TREE_VALUE (value
)))));
385 /* in pass 1 we just save the labels */
386 after_help
= tree_cons (NULL_TREE
, NULL_TREE
, after_help
);
387 after_stack_pass_1
= chainon (after_stack_pass_1
, after_help
);
392 build_after_timeout_start ()
398 /* jump to the end of AFTER action */
399 lookup_and_expand_goto (TREE_PURPOSE (TREE_PURPOSE (after_stack
)));
400 label_name
= TREE_VALUE (TREE_PURPOSE (after_stack
));
401 /* mark we are in TIMEOUT part of AFTER action */
402 TREE_VALUE (TREE_PURPOSE (after_stack
)) = NULL_TREE
;
406 label_name
= get_unique_identifier ("AFTER_tolabel");
407 TREE_VALUE (after_help
) = label_name
;
409 define_label (input_filename
, lineno
, label_name
);
417 /* define the end label */
420 label_name
= TREE_PURPOSE (TREE_PURPOSE (after_stack
));
421 after_stack
= TREE_CHAIN (after_stack
);
425 label_name
= get_unique_identifier ("AFTER_endlabel");
426 TREE_PURPOSE (after_help
) = label_name
;
427 after_help
= TREE_CHAIN (after_help
);
429 define_label (input_filename
, lineno
, label_name
);
433 build_timeout_preface ()
435 tree timeout_value
= null_pointer_node
;
437 if (after_stack
!= NULL_TREE
&&
438 TREE_VALUE (TREE_PURPOSE (after_stack
)) != NULL_TREE
)
442 to_loc
= decl_temp1 (get_unique_identifier ("TOloc"),
443 rtstime_type_node
, 0, NULL_TREE
, 0, 0);
444 timeout_value
= force_addr_of (to_loc
);
446 if (TREE_VALUE (TREE_VALUE (after_stack
)) == NULL_TREE
)
448 /* DELAY specified -- just call __convert_duration_rtstime for
449 given duration value */
451 build_chill_function_call (
452 lookup_name (get_identifier ("__convert_duration_rtstime")),
453 tree_cons (NULL_TREE
, TREE_PURPOSE (TREE_VALUE (after_stack
)),
454 tree_cons (NULL_TREE
, timeout_value
, NULL_TREE
))));
458 /* delay not specified -- call __remaintime which returns the
459 remaining time of duration in rtstime format and check the
462 build_chill_function_call (
463 lookup_name (get_identifier ("__remaintime")),
464 tree_cons (NULL_TREE
, force_addr_of (TREE_VALUE (TREE_VALUE (after_stack
))),
465 tree_cons (NULL_TREE
, TREE_PURPOSE (TREE_VALUE (after_stack
)),
466 tree_cons (NULL_TREE
, timeout_value
, NULL_TREE
))));
467 tree expr
= build (NE_EXPR
, integer_type_node
,
468 fcall
, integer_zero_node
);
469 expand_start_cond (expr
, 0);
470 lookup_and_expand_goto (TREE_VALUE (TREE_PURPOSE (after_stack
)));
474 return timeout_value
;
478 build_timesupervised_call (fcall
, to_loc
)
482 if (to_loc
== null_pointer_node
)
483 expand_expr_stmt (fcall
);
486 tree expr
= build (NE_EXPR
, integer_type_node
, fcall
, integer_zero_node
);
487 expand_start_cond (expr
, 0);
488 lookup_and_expand_goto (TREE_VALUE (TREE_PURPOSE (after_stack
)));