/* The procedure cobol_perform_gen generates the code necessary to im- plement the COBOL PERFORM statement. The general format of the PERFORM statement is as follows: Format 1 - P_E_R_F_O_R_M_ procedure-name-1 [{T_H_R_U_|T_H_R_O_U_G_H_} procedure-name-2] Format 2 - P_E_R_F_O_R_M_ procedure-name-1 [{T_H_R_U_|T_H_R_O_U_G_H_} procedure-name-2] {identifier-10|integer-1} T_I_M_E_S_ Format 3 - P_E_R_F_O_R_M_ procedure-name-1 [{T_H_R_U_|T_H_R_O_U_G_H_} procedure-name-2] U_N_T_I_L_ condition-1 Format 4 - P_E_R_F_O_R_M_ procedure-name-1 [{T_H_R_U_|T_H_R_O_U_G_H_} procedure-name-2] V_A_R_Y_I_N_G_ {identifier-1|index-name-1} F_R_O_M_ {identifier-2|index-name-2|literal-1} B_Y_ {identifier-3|literal-2} U_N_T_I_L_ condition-1 [A_F_T_E__R_ {identifier-4|index-name-3} F_R_O_M_ {identifier-5|index-name-4|literal-3} B_Y_ {identifier-6|literal-4} U_N_T_I_L_ condition-2 [A_F_T_E_R_ {identifier-7|index-name-5} F_R_O_M_ {identifier-8|index-name-6|literal-5} B_Y_ {identifier-9|literal-6} U_N_T_I_L_ condition-3]] In all formats, the beginning of the PERFORM range is defined as the first statement of the procedure named procedure-name-1 or, in terms of executable code, the first instruction generated to implement the first statement of procedure-name-1. Similarly, in all formats, the end of the PERFORM range is defined as the last statement of the procedure named procedure-name-2, if the THROUGH phrase is present, or the last statement of the procedure named procedure-name-1, if it is not. In terms of executable code, this corresponds to the last instruction generated to implement the last statement of the appropriate procedure. If procedure- name-1 (or -2) is a paragraph-name, then the last statement in the PERFORM range is the last statement of the paragraph. If procedure-name-1 (or -2) is a section-name, then the last state- ment in the PERFORM range is the last statement of the last para- graph of the section. If, as a consequence of executing a PERFORM statement, a transfer of control is indicated, the transfer is made to the first in- struction in the PERFORM range. This transfer of control occurs only once for each execution of a PERFORM statement. A subse- quent transfer of control following the execution of the last in- struction in the PERFORM range to the next executable statement following the PERFORM statement is implied and must be explicitly implemented. If, however, control passes to a procedure which has been named as containing the last statement in a PERFORM range by means other than a PERFORM statement, then control must pass through the last statement of the procedure to the next ex- ecutable statement as if no PERFORM statement mentioned the pro- cedure. In this connection, it should be noted that there is no next executable statement following: 1. The last statement in a Declarative Section when the para- graph in which it appears is not being executed under the control of some other COBOL statement. 2. The last statement in a program when the paragraph in which it appears is not being executed under the control of some other COBOL statement. 3. The last statement in a size procedure when the procedure is not being executed under the control of some other COBOL statement. (Size procedures and control statements which execute then are compiler sefined.) This modifiable program flow is implemented by inserting an al- terable GO after the last instruction of each PERFORM range de- fined in the program. These end-of-perform range alterable GO's are initialized, upon first entry into the program as part of the current run-unit, to pass control to the next executable state- ment except for those cases defined above for which there is no next executable statement. For these exceptional cases, the al- terable GO's are initialized to transfer control to a sequence of instructions which calls a procedure (signal_) to signal an ap- propriate error to the user. The setting of the end-of-perform range alterable GO's is otherwise controlled by code generated to implement the PERFORM statements. In programs conforming to the rules of COBOL, the end-of-perform range alterable GO's are al- ways reset at the completion of the PERFORM statement to pass control to the next executable statement or to an error signal- ling routine, as appropriate, regardless of any modifications that may have been made to implement the PERFORM statement. If the rules regarding PERFORM statements are not followed, the al- terable GO's at the end of involved PERFORM ranges may not be properly reset and unspecified alteration of control flow will occur. The instructions necessary for implementing end-of-perform range alterable GO's are generated in-line immediately after the gener- ation of the last instruction of each procedure which is at the end of a PERFORM range (see cobol_paragraph_gen, cobol_section_gen, and cobol_end_gen). The instructions necessary for initializing the end-of-perform range alterable GO's are generated (by cobol_seginit_ gen) after the processing of Minpral5 and the initial value min- pral file. This procedure also generates the code necessary to "perform" size routines used in "addressing" identifiers defined with the occurs depending clause. The call is made as it would be for a Format 1 PERFORM statement except that the format number in the end_stmt token is set to seven. U__s_a_g_e:_ declare cobol_perform_gen entry (ptr); call cobol_perform_gen (in_token_ptr); */ /* G__e_n_e_r_a_t_e_d_C__o_d_e:_ The code generated to implement the PERFORM statement is a func- tion of format and segment initialization requirements. Segment initializtion is required when procedure-name-1 is in a segment different from that containing the PERFORM statement and this segment is an independent segment containing explicit alterable GO's (GO statements referenced by ALTER statements). Format 1 - No Intializaation Required eaxn loc_a_relp,ic Set alterable GO at end of PNn to sxln target_a_PNn return control to inst at loc_a tra PN1_relp,ic Transfer to PN1 loc_a eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn Initialization Required eaxn loc_a_relp Set alterable GO at end of PNn to sxln target_a_PNn return control inst at loc_a eaa PN1_relp,ic Load addr PN1 in a-reg bits 0-17 tra i_segm_relp,ic Transfer to init code for seg containing PN1 loc_a eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn Format 2 - No Initialization Required Convert identifier-10 to fixed binary. This code is generated by the move generator if the identifier is long or short binary. The code generated by the MOVE generator is not shown here. If the identifier is packed or unpacked decimal, then the following code sequence is generated: dtb (ar),(ar) ndsc9 id_10,l ndsc9 id_10_fb,4 If the identifier is overpunch sign data, then it is first converted to an unpacked decimal trailing sign temporary. This temporary is then converted to a binary by generating the same instructions shown above for packed or unpacked decimal. tmoz loc_b_relp,ic Tra to inst at loc_b if 0 or neg [The preceding instructions are not generated if integer-1 is used instead of identifier-10 ] stz count Store 0 in temp used to count times performed eaxn loc_a_relp Set alterable GO at end of PNn to sxln target_a_PNn return control inst at loc_a tra PN1_relp1,ic Transfer to PN1 loc_a ldq count Add one to count of times performed adq 1,dl and compare to number of times stq count specified in PERFORM cmpq id_10_fb statement [If integer-1 is used instead of identifier-10, then cmpq id_10_fb becomes cmpq integer-1,dl ] tnz PN1_relp2,ic Tra to PN1 if not performed times required eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn loc_b Initialization Required Convert identifier-10 to fixed binary. This code is generated by the move generator if the identifier is long or short binary. The code generated by the MOVE generator is not shown here. If the identifier is packed or unpacked decimal, then the following code sequence is generated: dtb (ar),(ar) ndsc9 id_10,l ndsc9 id_10_fb,4 If the identifier is overpunch sign data, then it is first converted to an unpacked decimal trailing sign temporary. This temporary is then converted to a binary by generating the same instructions shown above for packed or unpacked decimal. tmoz loc_b_relp,ic Tra to inst at loc_b if 0 or neg [The preceding instructions are not generated if integer-1 is used instead of identifier-10 ] stz count Store 0 in temp used to count times performed eaxn loc_a_relp Set alterable GO at end of PNn to sxln target_a_PNn return control inst at loc_a eaa PN1_relp1,ic Load addr of PN1 in a-reg bits 0-17 tra i_segm_relp,ic Transfer to init code for seg containing PN1 loc_a ldq count Add one to count of times performed adq 1,dl and compare to number of times stq count specified in PERFORM cmpq id_10_fb statement [If integer-1 is used instead of identifier-10, then cmpq id_10_fb becomes cmpq integer-1,dl ] tnz PN1_relp2,ic Tra to PN1 if not performed times required eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn loc_b Format 3 - No Initialization Required eaxn loc_a_relp,ic Set alterable GO at end of PNn to sxln target_a_PNn return control to inst at loc_a loc_a[Instructions generated by cobol_arithop_gen and/or cobol_compare] [_gen to implement condition-1. Tags created by PD Syntax ] [for "condition true" are equated to loc_b and for "condi- ] [tion false" are equated to PN1. ] loc_b eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn Initialization Required stz count Store 0 in count to indicate init required eaxn loc_a_relp,ic Set alterable GO at end of PNn to sxln target_a_PNn return control to inst at loc_a loc_a[Instructions generated by cobol_arithop_gen and/or cobol_compare] [_gen to implement condition-1. Tags created by PD Syntax ] [for "condition true" are equated to loc_b and for "condi- ] [tion false" are equated to loc_i. ] loc_b eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn tra loc_d_relp,ic Transfer to loc_d loc_i ldq count Examine count and transfer tnz PN1_relp1,ic to PN1 if it is not 0 aos count Otherwise add 1 to count eaa PN1_relp2,ic Load addr of PN1 in a-reg bits 0-17 tra i_segm_relp,ic Transfer to init code for segment containing PN1 loc_d Format 4 - The sequence of instructions given below is for the most complex form of Format 4. Code generated for the less complex forms can be deduced from it, however. epbp2 0,ic Store ptr to base of Text spri2 pr6|M Segment in pr6|M tra loc_s_relp,ic Transfer to inst at loc_s loc_e[Call to cobol_error_ generated by cobol_process_error to ] [report "BY" identifier equal to zero. ] rtcd pr6|M Transfer to addr stored in pr6|M loc_s[Instructions generated by cobol_move_gen or cobol_set_gen to ] [initialize identifier-1 or index-name-1 to identifier-2, ] [index-name-2, or literal-1; identifier-4 or index-name-3 ] [to identifier-5, index-name-4, or literal-3; and identi- ] [fier-7 or index-name-5 to identifier-8, index-name-6, or ] [literal-5. ] {stz count Store 0 in count to indicate init required. } eaxn loc_a_relp,ic Set alterable GO at end of PNn to sxln target_a_PNn return control to inst at loc_a tra con_1_relp,ic and transfer to inst at con_1 loc_a[Instructions generated by cobol_compare_gen to implement ] [equivalent COBOL statement "if identifier-9 is not zero ] [go to inc_3.". Omitted if literal-6 is specified. ] stc2 pr6|M Store addr inc_3 in pr6|M and tra loc_e_relp,ic transfer to loc_e. These inst are omitted if literal-6 is specified. inc_3[Instructions generated by cobol_add_gen or cobol_set_gen to in- ] [crement identifier-7 or index-name-5 by identifier-9 or ] [literal-6. ] con_3[Instructions generated by cobol_arithop_gen and/or cobol_compare] [_gen to implement condition-3. Tags created by PD Syntax ] [for "condition true" are equated to tru_3 and for "condi- ] [tion false" are equated to loc_i if initialization is re- ] [quired and to PN1 if initialization is not required. ] tru_3[Instructions generated by cobol_move_gen or cobol_set_gen to ] [initialize identifier-7 or index-name-5 to identifier-8, ] [index-name-6, or literal-5. ] [Instructions generated by cobol_compare_gen to implement ] [equivalent COBOL statement "if identifier-6 is not zero ] [go to inc_2.". Omitted if literal-4 is specified. ] stc2 pr6|M Store addr inc_2 in pr6|M and tra loc_e_relp,ic transfer to loc_e. These inst are omitted if literal-4 is specified. inc_2[Instructions generated by cobol_add_gen or cobol_set_gen to in- ] [crement identifier-4 or index-name-3 by identifier-6 or ] [literal-4. ] con_2[Instructions generated by cobol_arithop_gen and/or cobol_compare] [_gen to implement condition-2. Tags created by PD Syntax ] [for "condition true" are equated to tru_2 and for "condi- ] [tion false" are equated to con_3. ] tru_2[Instructions generated by cobol_move_gen or cobol_set_gen to ] [initialize identifier-4 or index-name-3 to identifier-5, ] [index-name-4, or literal-3. ] [Instructions generated by cobol_compare_gen to implement ] [equivalent COBOL statement "if identifier-3 is not zero ] [go to inc_1.". Omitted if literal-2 is specified. ] stc1 pr6|M Store addr inc_1 in pr6|M and tra loc_e_relp,ic transfer to loc_e. These inst are omitted if literal-2 is specified. inc_1[Instructions generated by cobol_add_gen or cobol_set_gen to in- ] [crement identifier-1 or index-name-1 by identifier-3 or ] [literal-2. ] con_1[Instructions generated by cobol_arithop_gen and/or cobol_compare] [_gen to implement condition-1. Tags created by PD Syntax ] [for "condition true" are equated to tru_1 and for "condi- ] [tion false" are equated to con_2. ] tru_1 eaxn t_relp,ic Reset alterable GO at end sxln target_a_PNn of PNn {tra loc_n_relp,ic Transfer to loc_n loc_i ldq count Examine count and transfer tnz PN1_relp1,ic to PN1 if it is not 0 aos count Otherwise add 1 to count eaa PN1_relp2,ic Load addr of PN1 in a-reg bits 0-17 tra i_segm_relp,ic Transfer to init code for segment containing PN1 } loc_n Instructions in {} are included only if segment initialization is required. In initializing the "varying" or "after" identifiers to their current "from" values, cobol_move_gen is employed only if the ident- ifier is a numeric data item and the "from" operand is not an index-name. In all other cases, cobol_set_gen is employed. To in- crement the "varying" or "after" identifiers, cobol_add_gen is em- ployed if the identifier is a numeric data item and cobol_set_gen is employed if it is an index-name. where: PNn is procedure-name-n for n = 1 or 2. target-a-PNn is a 36-bit variable allocated in the program's COBOL data segment. It is uniquely associated with procedure-name-n (n = 1 or 2). PN1_relp is the offset, relative to the instruction in which PN1_relp1 the symbol is used, of the first instruction gener- PN1_relp2 ated to implement procedure-name-1. t_relp is the offset, relative to the instruction in which it appears, of an instruction defined by a tag uni- quely associated with target_a_PNn. (Usually, this is the instruction immediately following the end-of- perform range alterable GO at the end of procedure- name-1.) id_10 is identifier-10. id_10_fb designates a location in the COBOL data segment where id_10 is stored as a fixed bin quantity. count designates a location in the COBOL data segment where a count is kept of the number of times that the procedures in the PERFORM range have been per- formed for Format 2 statements. For Formats 3 and 4 when segment initialization is required, count = 0 indicates that the initial transfer of control has not yet been made and count = 1, that it has. loc_x_relp is the offset, relative to the instruction in which it appears, of the instruction whose address is loc_x for x = a, b, c, ..... con_n_relp is the offset, relative to the instruction in which it appears, of the instruction whose address is con_n for n = 1, 2, or 3. i_segm_relp is the offset, relative to the instruction in which it appears, of the first instruction of the code generated to initialize segm (the segment contain- ing procedure PN1). M is the word offset of a word in the stack in which the return address is stored prior to calling cobol_error_ in Format 4 statements. D__i_s_c_u_s_s_i_o_n:_ The number and nature of the tokens pointed to by the array in_token.token_ptr depends upon the format of the PERFORM state- ment which they describe. The following list indicates what may be expected for each format: Format 1 - tokens for PERFORM PN1 PN2 EOS Format 2 - tokens for PERFORM PN1 PN2 ID EOS Format 3 - tokens for PERFORM PN1 PN2 condition EOS Format 4 - tokens for PERFORM PN1 PN2 ID1 ID2 ID3 condition [AFTER ID4 ID5 ID6 condition AFTER ID7 ID8 ID9 condition] EOS Where the tokens for --- PERFORM and AFTER are type-1 Reserved Word. PN1 and PN2 are type-18 Procedure Reference. PN2 equals PN1 if no THROUGH phrase is present in the original statement. condition comprises a sequence of tokens representing the condi- tional expression or expressions that are present in Formats 3 and 4. These tokens may be of the following types: 9 Data Definition 1 Reserved word (for FIGURATIVE CONSTANT ZERO) 2 Numeric Literal 3 Alphanumeric Literal 10 Index-Name 31 Tag Equivalence 30 Internal Tag Definition 19 EOS with 13 (branch) or 28 (arithmetic operator) in the verb field ID is a type-9 Data Definition or a type-2 Numeric Literal. ID1, ID4, and ID7 may individually be either a type-9 Data Defini- tion or a type-10 Index-Name. ID2, ID5, and ID8 may individually be a type-9 Data Defintion, a type-10 Index-Name, or a type-2 Numeric Literal, or a type-1 token for the reserved word ZERO. ID3, ID6, and ID9 may individually be either a type-9 Data Defini- tion or a type-2 Numeric Literal. EOS represents a type-19 token. D__a_t_a:_ Items in cobol_$incl.pl1 used (u) and/or set (s) by cobol_perform_gen: cobol_ptr (u) next_tag (u/s) perform_list_ptr (u) priority_no (u) seg_init_list_ptr (u) temp_token_ptr (u/s) text_wd_off (u) */ */ ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull and Bull HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by Bull HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved */