/* The procedure cobol_call_gen generates the code necessary to imple- ment the CALL statement. The general format of the CALL state- ment is as follows: C_A_L_L_ {literal-1|identifier-1} [U_S_I_N_G_ data-name-1,[data-name-2]...] The essential difference between CALL literal-1 and CALL identi- fier-1 is the time at which the name of the program to be called is known. In the case of CALL literal-1, the name is known at compile time. Thus, a type 4 link can be created for the program at compile time, which is "snapped" by the Dynamic Linker at ex- ecution time, and thereby replaced by a pointer to the program's entry point. In the case of CALL identifier-1, the name of the program to be called is known only at execution time. Thus, an execution time call to system sybroutine hcs_$make_ptr is neces- sary to obtain a pointer to the program's entry point. In both cases, however, standard MULTICS call conventions are employed to make the actual "call" to the specified program. It should be noted that the content of literal-1 and identifier-1 may consist of a segment name and/or an entry point name as follows: Form 1 segment_name$entry_point_name Form2 entry_point_name Form 1 must be used if the name of the segment containing the program and the name of the program's entry point are different, but it may also be used if they are the same. Form 2 may only be used if the name of the segment containing the program and the name of the program's entry point are identical. U__s_a_g_e:_ declare cobol_call_gen entry (ptr); call cobol_call_gen(in_token_ptr); */ /* G__e_n_e_r_a_t_e_d_C__o_d_e:_ CALL identifier-1 To implement CALL identifier-1, it is necessary to call system subroutine hcs_$make_ptr to obtain a pointer to the entry point of the program named by identifier-1. This subroutine returns an error code indicative of the system's success (code = 0) or fail- ure (code /= 0) to obtain the pointer. Code is therefore generat- ed to examine the returned error code and to report any problem to the user via the run-time routine cobol_error_. The sequences of code shown below are used to make the call to hcs_$make_ptr and to examine the error code returned by it. The call to cobol_ error_ is generated by cobol_gen_error. Five parameters are passed to hcs_$make_ptr. They are: caller_ptr by standard usage a null ptr (Input). seg_name the name of the segment to be located (Input). e_p_name the name of the entry point to be located (Input). e_p_ptr the pointer to the segment entry point specified by seg_name and e_p_name (Output). error_code the returned error code (Output). The argument list passed to hcs_$make_ptr must include pointers to descriptors for the parameters as well as pointers to the par- ameters themselves inasmuch as seg_name and e_p_name are describ- ed as char(*). Sequence 1-1 The code comprising Sequence 1-1 establishes pointers in the ar- gument list to be passed to hsc_$make_ptr for all parameters ex- cept seg_name and e_p_name. epp2 n_relp,ic* spri2 pr6|M+2 epp2 pr6|M+2 spri2 pr6|M+10 epp2 pr6|M spri2 pr6|M+16 epp2 pr6|40 spri2 pr6|M+18 epp2 ptr_d_relp,1c spri2 pr6|M+20 spri2 pr6|M+26 epp2 fb_d_relp,ic spri2 pr6|M+28 Sequence 1-2 The function of Sequence 1-2 is to develop a pointer to identifi- er-1 in pointer register 2 and to store this in the argument list to be passed to hcs_$make_ptr as the pointer to seg_name. If identifier-1 does not contain a $, it will also be stored in the argument list as the pointer to e_p_name (see Sequence 1-3). The address of identifier-1 will always involve the contents of a pointer register (pri) and a word offset (wo), which may be zero. It may also involve a character offset (co) and/or the contents of the a, q, or some index register (ra). Thus, there are four possibilities for the code sequence used to develop the pointer to identifier-1, as follows: A - No character offset, no register epp2 pri|wo spri2 pr6|M+12 B - Character offset, no register epp2 pri|wo lda co,dl a9bd pr2|0,a spri2 pr6|M+12 c - No character offset, register epp2 pri|wo a9bd pr2|0,ra spri2 pr6|M+12 D - Character offset, register epp2 pri|wo a9bd pr2|0,ra lda co,dl a9db pr2|0,a spri2 pr6|M+12 In the event that identifier-1 is a variable length data item, instructions to compute its length and store the result in an index register will have been generated by a utility called by cobol_call_gen prior to the generation of Sequence 1-2 code. In this case, Sequence 1-2 code will include two additional instruc- tions to store the length from the index register into location pr6|42 in the caller's stack frame. These instructions are as follows: stz pr6|42 sxln pr6|42 Sequence 1-3 This code sequence performs the following functions: - Develops a pointer to e_p_name and stores it in the argument list. - Determines the length of and develops descriptors for seg_ name and e_p_name. - Develops pointers to descriptors for all parameters to be passed to hcs_$make_ptr and stores them in the argument list. - Invokes cobol call operator call_ext_out_desc. scm (pr,[rl]),(du),mask(0) adsc9 pr2|0,{l or xn} vfd o9/044,27/0 arg pr6|M+5 ttn 16,ic lda pr6|M+5 ora 174080,du sta pr6|M+6 lda pr6|M+5 ada 1,dl a9bd pr2|0,a spri2 pr6|M+14 neg ada l,dl or pr6|42 ora 174080,du sta pr6|M+7 epp2 pr6|M+6 spri2 pr6|M+22 epp2 pr6|M+7 tra 7,ic spri2 pr6|M+14 ldq l,dl or pr6|42 orq 174080,du stq pr6|M+6 epp2 pr6|M+6 spri2 pr6|M+22 spri2 pr6|M+24 eax1 pr6|M+8 fld 10240,dl epp2 pr4|m_pt_e,* tsx0 pr0|call_eod Sequence 2-0 The function of the code generated by Sequence 2-0, either di- rectly or by utilities called by cobol_call_gen, is to examine the error code returned by hcs_$make_ptr and, in the event that it is not zero, to report the nature of the error to the user. [Code generated by cobol_reg_manager$after_op to reset pr3, pr4, ] [and, if necessary, pr5. ] lda pr6|M+4 tze call_relp,ic [Code generated by cobol_gen_error to call cobol_error_ and] [reset pr3, pr4, and, if necessary, pr5. ] tra seq1-1_relp,ic The symbols used in the above code sequences are defined as follows: M is the word offset in the caller's stack frame of the next available even-numbered word. n_relp is the offset, relative to the instruction in which it is used, of a null pointer in the Constant Sec- tion of the Text Segment. ptr_d_relp is the offset, relative to the instruction in which it is used, of a pointer descriptor located in the Constant Segment of the Text Segment. fb_d_relp is the offset, relative to the instruction in which it is used, of a descriptor for a real fixed binary short quantity located in the Constant Section of the Text Segment. call_relp is the offset, relative to the instruction in which it is used, of the first instruction of the standard MULTICS call sequence generated to call identifier-1. seq1-1_relp is the offset, relative to the instruction in which it is used, of the first instruction of Sequence 1-1. m_pt_e is the offset, relative to the base of the MULTICS Linkage Section, of a pointer (initially a link created by a call to cobol_make_link$type_4) to the entry point of subroutine hcs_$make_ptr. call_eod is the location, relative to the label operator_table in cobol_operators, of the first instruction of the cobol call operator call_ext_out_desc. The current value of call_eod is 5. All other symbols are defined as used. Standard MULTICS call A standard MULTICS call is used in the implementation of both CALL literal-1 and CALL identifier-1. The code generated to im- plement a standard MULTICS call comprises three sequences of in- structions. Sequences 1 and 2 are omitted, however, if the GO statement does not contain the USING phrase. Sequence 1 - The function of this sequence of instructions is to create pointers to the USING phrase operands and place them in an argument list in the caller's stack frame. Sequence 1a is used for operands defined in the File Section, Working-Storage Sec- tion, or Communication Section. Sequence 1b is used for operands defined in the COBOL Linkage Section. The appropriate sequence, 1a or 1b, is generated once per operand in the order of its ap- pearance in the USING phrase. Consequently, the pointers are similarly arranged in the argument list. It should be noted that two words are reserved at the top of the argument list for a header which is inserted by the appropriate cobol call operator (see Sequence 3). Sequence 1a epp2 oprnd_z spri2 pr6|N+2z Sequence 1b [epp1 pr6|26,*] see note epp2 pr1|2y,* spri2 pr6|N+2z Note: pr6|26 contains a pointer to the argument list passed to the caller by it's caller. This instruction is generated only once per call when the first USING phrase operand de- fined in the COBOL Linkage Section is encountered. Sequence 2 - The function of this sequence of instructions is to create pointers to descriptors for the USING phrase operands and place them in the argument list following the pointers generated by Sequence 1 instructions. The sequence is repeated as required to place one pointer per operand into the argument list. Sequence 2 epp2 desc_l,ic spri2 pr6|N+2zt+2za spri2 pr6|N+2zt+2zb spri2 pr6|N+2zt+2zc . . . . . . . . . . . . . . . Sequence 3 - The function of this sequence of instructions is to establish the conditions necessary for invoking an appropriate cobol call operator. Sequence 3a is used when the optional USING phrase is present. It invokes the operator call_ext_out_desc. Sequence 3b is used when the optional USING phrase is not pre- sent. It invokes the operator call_ext_out. Sequence 3a eax1 pr6|N fld 2**11 zt,dl epp2 e_p_ptr,* tsx0 pr0|call_eod Sequence 3b eax1 pr6|46 fld 0,dl epp2 e_p_ptr,* tsx0 pr0|call_eo In the above sequences - N is the offset in the caller's stack frame of the first word of the argument list to be passed to the program named in literal-1 or identifier-1. It must be located on a double word boundary. zt is the total number of operands in the CALL statement USING phrase. z is a number designating the position of an operand in the CALL statement USING phrase; z = 1, 2, 3, ... zt. oprnd_z is the zth operand of the CALL statement USING phrase. y is a number designating the position of operand z of the CALL statement USING phrase in the Procedure Division header USING phrase when operand z is defined in the COBOL Linkage Section. desc_l is a descriptor for a character string of length l. zx for x = a, b, c, ..., are the positions within the CALL statement USING phrase of those operands whose length is l characters. e_p_ptr is a pointer to the entry point of the program named in literal-1 or identifier-1. In the case of literal-1, this pointer is located in the MULTICS linkage section and is initially a type 4 link created at compile time. In the case of identifier-1, the pointer is located in the caller's stack frame. Its value is determined by an execution time call to system subroutine hcs_$make_ptr. call_eop is the location, relative to the label operator_table in cobol_operators, of the first instruction of the cobol call operator call_ext_out_desc. The current value of call_eod is 5. call_eo is the location, relative to the label operator_table in cobol_operators, of the first instruction of the cobol call operator call_ext_out. The current value of call_eo is 6. R__e_l_o_c_a_t_i_o_n_I__n_f_o_r_m_a_t_i_o_n:_ All instructions generated directly by procedure cobol_call_gen (as opposed to being generated by a utility called cobol_call_gen) are non-relocatable with the following exceptions: The left hand (address) half of the instruction epp2 pr4|m_ptr,* in Sequence 3_1. The left hand (address) half of the instruction epp2 e_p_ptr,* in Sequence 3 when it is generated to implement CALL literal-1. In both cases the entity referenced is a type 4 link located in the Linkage Section using pointer register 4. The relocation code generated for these instruction halfwords is "10100"b. */ /* D__a_t_a:_ Items in cobol_$incl.cobol used (u) and/or set (s) by cobol_call_gen: cobol_ptr (u) next_tag (u/s) text_wd_off (u) */ /* Input structure used for cobol_pointer_register$get. */ declare 1 register_request aligned static, 2 what_pointer fixed bin aligned init(1), 2 assigned_ptr fixed bin aligned, 2 lock fixed bin aligned init(1), 2 switch fixed bin aligned init(0), 2 segno fixed bin aligned init(0), 2 offset fixed bin aligned init(0), 2 reset fixed bin aligned; /* where: what_pointer is the number of the desired pointer register. (Input) assigned_ptr is the number of the register assigned. (Output) lock specifies locking requirements. (1 - lock requested register). (Input) switch specifies the significance of segno and offset. (0 - segno and word offset are not supplied). (Input) segno is the segment number that the pointer register is to contain. (Input) offset is the word or character offset that the pointer reginter is to contain. (Input) */ */ ----------------------------------------------------------- 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 */