CHAPTER 1 Compiler Support Modules 1.1 Introduction. <<<.... 1.2 to be filled in later ....>>> Threaded Code. When threaded code is generated by the compiler, the "compiled code" produced by the compiler is a list symbolic names and arguments. The symbolic names are entry points into modules in the Fortran Object Time System (OTS). Consider the following example (from the RT11/RSTS/E Fortran User's Guide, page 1-14): Statement #0007 000034 ISN$ 000036 MOF$MS 000042 DIF$IS 000046 CDF$ 000050 ADD$MS 000054 MOD$SM $DATA+#000004 #040400 $DATAP+#000020 $DATA+#000020 This code corresponds to the Fortran statement DBLE=REAL/2. + 3.1415926535D0 at Internal Statement Number (ISN) 0007 of the source program. DBLE is declared Real*8 and REAL is declared REAL*4. Here When executing threaded code, the OTS treats register R4 as a virtual program counter. By loading the address of the first threaded code module into R4 and executing a JMP @(R4)+ instruction, control is passed to the first module and the "program counter" is incremented to point at the next word in memory. If the threaded code requires arguments (as for MOF$MS above), the arguments follow in memory after the entry point name. These arguments are then FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-2 referenced with suitable auto-increment address modes in the OTS module, so that when the OTS module completes its function, a single "JMP @(R4)+" instruction will transfer control to the next module. Using the above example, the following occurs when statement 7 is executed. First, the internal statement number is incremented ($ISN routine). Next a value is moved from memory to the stack (MOF$MS); the address of the value to move is $DATA+#000004, i.e., the variable REAL (see load map on page 1-14 of User's Guide). Next a floating point divide is performed (DIF$IS); the numerator is on top of the stack and the denominator follows immediately in memory (#040400 is the first word of the floating point constat 2.0). Next the value on top of the stack is converted to Real*8 by the module CDF$. Now a double precision add of the double precision constant 3.1415926535D0 to the top of stack is performed (ADD$MS). Note that only constants which fit in one 16-bit word are stored inline; here a memory location in the $DATAP PSECT contains the value. Finally the (Real*8) value on top of the stack is moved to location DBLE ($DATA+#000020) by the module MOD$SM. 1.3 Compiled Code Routines. The symbolic names produced by the compiler are entry points into OTS modules residing in the system library. Entry points are grouped into modules containing similar code. For example, the MOD$SM entry point is in the module $DMOV7 together with the entry point MOD$SP. Such grouping occurs for two reasons. 1. Several function, entry points may perform essentially the same differing only in how arguments grouping saves substantially on code size. are passed to them. Such 2. Certain entry points are likely to be used together. Therefore, grouping into a single module reduces linker overhead when searching the library for unresolved references. 1.3.1 Entry Point Naming Convention. To allow the generated threaded code to be readable, entry point names follow naming conventions which are similar to that of a simple assembly language. The majority of the entry point names follow the form: mmt$xx where mm - the "op code", e.g. MO for move, AD for add, etc. t - the data type, e.g., F for real, I for integer, etc. xx - the "address mode" of the instruction. The following table summarizes the which op-codes for the instructions FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-3 follow this format. OP-CODE AD CC CD CF CI CL CM CO CP DE DI IC JM MO MU NG NM NP SA SU SV TA TS TV X? OPERATION Addition Convert to complex Convert to double Convert to floating Convert to integer Convert to logical Compare Logical complement Copy Decriment Divide Increment Jump Move Multiply Negate the argument DO loop index modification DO loop index modification Subscript calculations Subtract Subscript calculations Transfer array operators Logical tests (compares agains zero) Variable transfer Raise to a power The data type (t) of an operation is determined from the following table. SYMBOL C D F I L Q R DATA TYPE Complex Real*8 Real*4 Integer (*2 or *4) Logical (*1 or *4 unless noted) Most of the modules which follow this naming convention have two arguments. The location of these arguments is specified by the "address mode" part of the symbolic name. Operands may reside on the stack (S), follow in immediately in memory (I), reside in memory (M), be a subroutine parameter (P), or be an intermediate result stored at a particular temporary address (A). The following table shows all combinations which occur in the OTS; not all combinations are permitted with every op-code and data type. Note that special entry points exist for commonly occurring sequences involving the constants 0 and 1 in various data types. FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-4 ADDRESS MODES F I R S T A R G U M E N T SECOND ARGUMENT -----------------------------------------------------------------| Argument Argument Address Parameter Address | | on stack in next in next in next on stack| | word word word | -----------------------------------------------------------------|Argument | SS | SI | SM | SP | SA | |on stack | | | | | | -----------------------------------------------------------------|Argument | IS | II | IM | IP | IA | |in next | | | | | | |word | | | | | | -----------------------------------------------------------------|Address | MS | MI | MM | MP | MA | |in next | | | | | | |word | | | | | | -----------------------------------------------------------------|Parameter*| PS | PI | PM | PP | PA | |in next | | | | | | |word | | | | | | -----------------------------------------------------------------|Moves 0 | 0S | | 0M | 0P | 0A | |into 2nd | | | | | | |argument | | | | | | -----------------------------------------------------------------|Moves R0 | RS | | RM | RP | RA | |into 2nd | | | | | | |argument | | | | | | -----------------------------------------------------------------|Increments| 1S | 1I | 1M | 1P | 1A | |or decre- | | | | | | |ments 2nd | | | | | | |argument | | | | | | -----------------------------------------------------------------|Address | VS | | | | | |in R0 | | | | | | ------------------------------------------------------------------ 1.4 Additional Routines. Although the majority of threaded code routines follow the above naming conventions, many do not. The following is a list of routines which do not follow the above naming conventions. Whereas most of the above modules are referenced only if threaded code is selected, many of the following routines are used for both threaded and inline code. In some cases, the same module has two entry points: one for use with threaded code, and one for use with inline code. The following list is by entry point. A cross-reference listing of entry points and modules may be found in Appendix B. FORTRAN IV OTS (Draft) Compiler Support Modules 1.4.1 Page 1-5 GOTO Statements Conditional branches are used for constructs of the form IF(...) GOTO... where the logical IF has been previously evaluated using one of the Compare or Test modules. BEQ$ BGE$ BGT$ BLE$ BLT$ BNE$ BRA$ JMC$ : : : : : : : : 1.4.2 Branch if equal to zero Branch if greater than or equal Brach if greater than Branch if less than or equal Branch if less than Branch if not equal Unconditional branch (GOTO) Computed GOTO statement Subroutine Support Modules CAI$ : CAL$ : RET$ : $OTIS : $$OTIS 1.4.3 LEQ$ LGE$ LGT$ LLE$ LLT$ LNE$ AND$ EQV$ IOR$ XOR$ : : : : : : : : : : 1.4.4 CALL statement (subroutine name is parameter) CALL statement (normal) Return from a subprogram Subroutine initialization (threaded code) : Subroutine initialization (inline code) Logical Operators. Equal to zero Greater than or equal Greater than Lessthan or equal Lessthan Not equal Logical AND Logical function Inclusive OR Exclusive OR Data Type Converstion. <<<to be completed>>> 1.4.5 DCO$ ECO$ FCO$ GCO$ ICO$ : : : : : I/O Conversion Routines. Formatted Formatted Formatted Formatted Formatted real and double output conversions real and double output conversions real and double output conversions real and double output conversions integer output conversion FORTRAN IV OTS (Draft) Compiler Support Modules LCI$ LCO$ OCI$ OCO$ RCI$ : : : : : 1.4.6 BKS$ : DEC$ : DEF$ : DEO$ : ENC$ : ENO$ : EOF$ : EOL$ : FND$ : IBR$ : IBW$ : IFR$ : IFR$$: IFW$ : IFW$$: ILR$ : ILW$ : IRR$ : IRW$ : IUR$ : IUW$ : RWD$ : ERR$ : END$ : 1.4.7 AIF$ STK$ FUD$ BAH$ END$ FOO$ ISN$ LSN$ PSE$ REL$ STP$ : : : : : : : : : : : Page 1-6 Logical input convertions Logical output convertions Formatted octal input conversions Formatted octal output conversions Formatted real and double input conversion I/O Statement Support Routines. Backspace routine Decode routine Random access I/O Object time decode routine Encode routine object time encode routine End of file processor End of I/O list operator Find for random I/O Object time read routine Object time write routine Initialize formatted read Initialize formatted read (not used in RT-11) Initilize formatted write Initialize formatted write (not used in RT-11) List directed input List directed output Random access I/O read Random access I/O write Unformatted I/O read Unformatted I/O write Rewind file ERR=... exit on READ/WRITE statements. END=... exit on READ/WRITE statements. Miscellaneous. Arithmetic IF statement Arithmetic Statement Function Returns Compiler generated error Pause processor End operation codes Stop processor Adjust ISN counter (unlabeled statement) Adjust ISN counter (labeled statement) Pause processor Same as MOL$IS Stop processor FORTRAN IV OTS (Draft) Compiler Support Modules 1.5 Page 1-7 Comparison of Inline and Threaded Code. An overview of the differences between inline and threaded code is contained in Chapter 2 of the RT-11/RSTS/E Fortran IV User's Guide. The following discussion contains additional details on the differences between the two types of generated code. 1.5.1 Program Size. <<<to be completed>>> 1.5.2 Execution Speed. <<<to be completed>>> 1.5.3 Hardware Considerations. <<<to be completed>>> 1.6 Details of Generated Threaded Code. As mentioned above, one of the chief advantages of threaded code over inline code is that it generally produces smaller sized executable code. Occasionally, very large programs may require "only a little more space" to fit in memory and execute. Assuming all of the standard techniques of suppressing ISN's, overlaying (including OTS modules as described in Chapter x), and other "tricks" have been employed, it may be possible to gain some space by modifying code sequences to avoid loading of some OTS modules. The following sections give Simple examples of Fortran statements and the threaded code entry point each generates. These entry points are grouped by module. By eliminating all coding sequences which generate symbols in a given module, it may be possible to suppress loading of that module. Obvious examples involve the replacement of complex arithmetic if only a few complex operations are needed. Less obvious, is the replacement of subroutine parameters by common blocks, to suppress loading of modules which operate on subroutine parameters. These examples are not exhaustive. It may require several tries to remove references to certain types of coding sequences. Consult Appendix A on module sizes to assess the possible gain from changes in code. In some cases (e.g., complex arithmetic), it may be that the resulting Fortran code requires more space without complex arithmetic than is taken up by the complex modules in the OTS. Note also, that arithmetic modules are always loaded since they are used internally by other OTS routines. FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-8 Variable names in the following examples indicate data type according to: C B D I L R - complex logical*1 double precision integer logical*4 real The code for logical*1 is also applicable for logical*4, however, only the first byte of the logical*4 will be affected. The letter P following any of the above letters means that the variable of that type is a subroutine parameter. The number appearing in parentheses refers to the note at the end of the section. 1.6.1 Multiplication and Division. For division, the first letter of the address mode is the location of the denominator; the second letter is the location of the numerator. For multiplication, the first and second letters correspond to the second and first factors of the multiplication, respectively. MODULES $CDIV - Complex divide DIC$SS C=(C-2)/(C1-3) DIC$IS C=C/2 DIC$MS C=(C-3)/C1 DIC$PS C=(C-3)/CP $CMUL - Complex multiply MUC$SS C=(C-2)*(C1-3) MUC$IS C=C*3 MUC$MS C=C*(C1-3) MUC$PS C=(C-3)*CP $DDIV - Double precision divide DID$SS D=(D-2.)/(D1-3.) DID$IS D=D/2. (1) (1) (1) (1) (1) (1) (1) DID$MS DID$PS D=(D-3.)/D1 D=(D-3.)/CP $DMUL - Double precision multiply MUD$SS D=(D-2)*(D1-3) MUD$IS D=D*3 MUD$MS D=D*(D1-3) MUD$PS D=(D-3)*DP $FDIV - Real divide DIF$SS R=(R-2.)/(R1-3.) DIF$IS R=R/2. DIF$MS R=(R-3.)/R1 (1) (1) (1) (1) (1) (1) (1) FORTRAN IV OTS (Draft) Compiler Support Modules DIF$PS R=(R-3.)/RP $FMULS - Real multiply MUF$SS R=(R-2.)*(R1-3.) MUF$IS R=R*3. MUF$MS R=R*(R1-3.) MUF$PS R=(R-3.)*RP $IDIVS - Integer divide DII$SS I=(I-2)/(I1-3) DII$IS I=I/2 DII$MS I=(I-3)/I1 DII$PS I=(I-3)/IP $IMUL - Integer multiply MUI$SS I=(I-2)*(I1-3) MUI$IS I=I*3 MUI$MS I=I*(I1-3) MUI$PS I=(I-3)*IP Page 1-9 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 1 - Value in parenthesis is on the stack 1.6.2 Addition and Subtraction. The first letter of the address mode refers operand; the second letter to the first operand. MODULES $ADDA - Real add to memory via address ADF$IA ADF$SA ADF$MA ADF$PA SUF$IA SUF$SA SUF$MA SUF$PA $ADDM - Real add to memory ADF$IM R=R+2. ADF$SM R=R+I ADF$MM R=R1+R ADF$PM R=R+RP SUF$IM R=R-2 (1) to the second SUF$SM SUF$MM SUF$PM R=R-R1 $ADDP - Real add to parameter ADF$IP RP=RP+3 FORTRAN IV OTS (Draft) Compiler Support Modules ADF$SP ADF$MP ADF$PP SUF$IP SUF$SP SUF$MP SUF$PP RP=(R+1.0)+RP RP=RP+R1 RP=RP+RP1 RP=RP-3 Page 1-10 (6) RP=RP-R1 RP=RP-RP1 $CADD - Complex add and subtracts ADC$IS C=C+2. ADC$MS C=C+.1 ADC$SS C=(C1+C2)+(C3+C4) ADC$PS C=CP1+(C3+C4) SUC$IS C=C-2. SUC$MS SUC$SS C=(C+1)-5. SUC$PS $DADD - Double precision add and subtract ADD$IS D=D+2. ADD$MS D=D+.1 ADD$SS D=(D1+D2)+(D3+D4) ADD$PS D=DP+(D1+D2) SUD$IS D=D-2. SUD$MS D=D-D1 SUD$SS D=(D1+D2)-(D3+D4) SUD$PS $FADD - Real addition ADF$IS R=1.0+(R1+R2) ADF$MS R=R1+R2+(R3+R4) ADF$SS R=(R1+R2)+(R3+R4) ADF$PS R=RP+(R1+R2)(6) SUF$IS R=(R+1)-5. SUF$MS SUF$SS R=(R1+R2)-(R3+R4) SUF$PS $IADDS - Integer adds ADI$SS I=(I+2)+(I1+3) ADI$SA ADI$SM I=I+(I1+3) ADI$IS I=L+1 ADI$IA ADI$IM I=I+2 ADI$MS I=(I2+3)+I ADI$MA ADI$MM I=I+I1 $IPADD - Integer adds with arguments (2) (6) (6) (5,6) (3) (6) (6) (6) (6) (6) (6) (6) (6) (6) (6) (4) (6) ADI$SP ADI$IP ADI$MP ADI$PS ADI$PM IP=IP+(I+3) IP=IP+3 IP=IP+I I=IP+(I1+I2) I=IP+I (6) (6) FORTRAN IV OTS (Draft) Compiler Support Modules ADI$PA ADI$PP Page 1-11 IP1=IP1+IP2 $IPSUB - Integer subtracts with arguments SUI$SP IP1=(I+I1)-IP1 SUI$IP IP1=3-IP1 SUI$MP IP1=I-IP1 SUI$PS I2=IP1-(I1+I2) SUI$PM I=IP1-I SUI$PA SUI$PP IP1=IP1-IP2 $ISUBS - Integer subtracts SUI$SS I2=(I1+I2)-(I3-I4) SUI$SA SUI$SM I2=(I2+I3)-I4 SUI$IS I2=1-(I1+I2) SUI$IA SUI$IM I=I-2 SUI$MS I=I1-(I2-I4) SUI$MA SUI$MM I=I-I1 (6) (6) (6) (6) (6) (6) 1 - I has been converted to real so is on the stack, R is in memory 2 - .1 is converted to complex so is on the stack, C is in memory 3 - .1 has been converted to double so is on the stack, D is in memory 4 - L has been converted to integer so is on the stack, 1 is immediate 5 - Must convert 5. to complex 6 - Value in parenthasis is on the stack 1.6.3 Relational Operators. In the following, code produced for Logical*1 variables would also be produced for Logical*4 variables, since only the low-order byte of a Logical*4 variable contains a value. Note that comparisons against the constants 0, 0.0, 0.0D0 and .FALSE. generate special (more efficient) code. However, this efficiency in execution is at the expense of loading another OTS module, which can cause an increase in program size. MODULES $CMPD - Double precision comparisons CMD$SS B=(D1+D2).LT.(D3+D4) CMD$IS B=3.DO.LT.(D3+D4) CMD$MS B=D1.LT.(D3+D4) CMD$PS B=DP1.LT.(D3+D4) CMD$SI B=(D4+D5).LT.3.0 CMD$II B=3.DO.LT.2.DO FORTRAN IV OTS (Draft) Compiler Support Modules CMD$MI CMD$PI CMD$SM CMD$IM CMD$MM CMD$PM CMD$SP CMD$IP CMD$MP CMD$PP B=D.LT.3.DO B=DP1.LT.3.DO B=(D1+D7).LT.D B=3.DO.LT.D B=D.LT.D1 B=DP1.LT.D B=(D1+D8).LT.DP1 B=3.DO.LT.DP1 B=D.LT.DP1 B=DP1.LT.DP2 $CMPF - Real comparisons CMF$SS B=(R1+R2).LT.(R3+R4) CMF$IS B=3.0.LT.(R3+R4) CMF$MS B=R1.LT.(R3+R4) CMF$PS B=RP1.LT.(R3+R4) CMF$SI B=(R4+R5).LT.3.0 CMF$II B=3.0.LT.2.0 CMF$MI B=R.LT.3.0 CMF$PI B=RP1.LT.3.0 CMF$SM B=(R1+R7).LT.R CMF$IM B=3.0.LT.R CMF$MM B=R.LT.R1 CMF$PM B=RP1.LT.R CMF$SP B=(R1+R8).LT.RP1 CMF$IP B=3.0.LTRP1 CMF$MP B=R.LT.RP1 CMF$PP B=RP1.LT.RP2 $ICMPS - Integer comparisons CMI$SS B=(I1+I2).LT.(I3+I4) CMI$SI B=(I4+I5).LT.3 CMI$SM B=(I1+I7).LTI CMI$IS B=3.LT.(D3+D5) CMI$II B=3.LT.2 CMI$IM B=3.LT.I CMI$MS B=D1.LT.(D3+D4) CMI$MI B=I.LT.3 CMI$MM B=I.LT.I1 $IPCMP - Integer parameter comparisons CMI$PI B=IP1.LT.3 CMI$PM B=IP1.LT.I CMI$PP B=IP1.LT.IP2 CMI$PS B=IP1.LT.(I3+I5) CMI$MP B=I.LT.IP1 CMI$IP B=3.LT.IP1 CMI$SP B=(I1+I8).LT.IP1 $LCMPI - Immediate logical*1 comparisons Page 1-12 CML$SI CML$MI B=(B1.OR.B2).LT..TRUE. B=B.LT..TRUE. $LCMPP - Logical*1 comparisons to parameter CML$SP B=(B1.OR.B2).LT.BP FORTRAN IV OTS (Draft) Compiler Support Modules CML$IP CML$MP CML$PP Page 1-13 B=.TRUE..LT.BP B=B.LT.BP B=BP1.LT.BP2 $LCMPS - Logical*1 comparisons to stack CML$SS B=(B1.OR.B2).LT.(B3.OR.B4) CML$MS B=B1.LT.(B2.OR.B3) CML$IS B=.TRUE..LT.(B1.OR.B2) CML$SM B=(B1.OR.B2).LT.B CML$MM B=(B.LT.B1 CML$IM B=.TRUE..LT.B $LPCMPS - Logical*1 CML$PS CML$PI CML$PM parameter comparisons B=BP.LT.(B1.OR.B2) B=BP.LT..TRUE. B=BP.LT.B $LTEST - Logical*1 test operators TSL$S B=(B.OR.B1).EQ..FALSE. TSL$M B=B.EQ..FALSE. TSL$I B=.FALSE..EQ..FALSE. TSL$P B=BP.EQ..FALSE. $TESTC - Complex test operators TSC$S B=(C+C1).LT.(0.0,0.0) TSC$M B=C.LT.(0.0,0.0) TSC$I B=(0.0,0.0).LT.(0.0,0.0) TSC$P B=BP.LT.(0.0,0.0) $TESTS - Integer, real, and double tests against 0 TSI$S B=(I+I1).LT.0 TSI$M B=I.LT.0 TSI$I B=0.LT.0 TSI$P B=IP.LT.0 TSF$S B=(R+R1).LT.0.0 TSF$M B=R.LT.0.0 TSF$I B=0.0.LT.0. TSF$P B=RP.LT.0.0 TSD$S B=(D+D1).LT.0.0D0 TSD$M B=D.LT.0.0D0 TSD$I B=0.0 D0.LT.0.0D0 TSD$P B=DP.LT.0.0D0 1.6.4 Exponentiation MODULES $XCI - Complex ** Integer XCI$ C=C**I $XDD - Double precision ** Double Precision (1) FORTRAN IV OTS (Draft) Compiler Support Modules XDD$ XFD$ XDF$ D=D**D R=R**D D=D**R Page 1-14 (2) $XDI - Double precision ** Integer XDI$ D=D**I (1) $XFF - Real ** Real XFF$ R=R**R (1) $XFI - Real ** Integer XFI$ R=R**I (1) $XII - Integer ** Integer XII$ I=I**I (1) 1 - The exponent is pointed to by the top of the stack, and is 2nd on the stack 2 - The exponent is on the top of the stack, and the base is the stack 1.6.5 the 2nd base on Move Operations Move operations typically account for a major part of most Fortran program generated code. Therefore, significantly more modularity and code optimization exists within the various modules for move operations. In particular, a special copy operation exists for duplicating an argument on the stack, and special modules for commonly used constant values exist. Again, execution speed is enhanced at the expense of program size. MODULES $COPY - Create copy of argument CPI$SM CPL$SM CPF$SM CPD$SM I1=(I+3)*(I+3) B1=(B+3)*(B+3) R1=(R+3)*(R+3) D1=(D+3)*(D+3) $DMOV1 - Move double precision immediate to stack MOD$IS D=10.D1+10.D2 $DMOV2 - Move double precision to R0 MOD$0S $DMOV3 - Move double precision zero or immediate to second argument MOD$0P MOD$0A D(J)=0 MOD$0M D=0 MOD$IP DP=1. MOD$IA D(J)=10.D1 MOD$IM D=1. FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-15 $DMOV4 - Move double precision from stack via address MOD$SA D(J)=D(I) $DMOV5 - Move double precision to stack MOD$MS D=D+1. MOD$SS MOD$PS DP=DP-1 MOD$VS (1) $DMOV6 - Move double precision from memory and parameter MOD$MA D(J)=D2 MOD$MM D=D1 MOD$MP MOD$PA MOD$PM MOD$PP DP=DP2 $DMOV7 - Move double precision from stack MOD$SP DP=DP+1 MOD$SM D=D+1. (1) $DMOVR - Move double precision from R(0)-R(3) MOD$RS MOD$RM MOD$RP MOD$RA $FMOV1 - Move real stack to stack MOF$SS $FMOV2 - Move real to stack MOF$IS MOF$0S $FMOV3 - Move real to stack MOF$MS I=.1 MOF$PS R=(RP*2)+1 (2) $FMOV4 - Move real from stack MOF$SA RP(J)=RP(I) $FMOV5 - Move real from immediate MOF$IA R(J)=1 $FMOV6 - Move real from stack MOF$SM R=I MOF$SP RP=RP/R $FMOV7 - Move real from immediate (3) MOF$IM MOF$IP R=1. RP=1. $FMOV8 - Move real zero to second argument MOF$0M R=0 FORTRAN IV OTS (Draft) Compiler Support Modules MOF$0A MOF$0P Page 1-16 R(J)=0 RP=0 $FMOV9 - Move real from memory and parameter MOF$MM R=R1 MOF$MA R(J)=R(2) MOF$MP MOF$PM R=RP-1 MOF$PA RP=RP2 MOF$PP RP=RP2 $FMOVR - Move real from R(0)-R(1) MOF$RS R(J)=ROOT(R) MOF$RM MOF$RA MOF$RP $IMOVR - Move integer from R(0) MOI$RS R=R2-ROOT(I) MOI$RM R=ROOT(M) MOI$RA MOI$RP MOL$RS $IMOVS - Integer move MOI$SS MOI$SM I=.1 MOI$SA I(I1)=I(I2) MOI$IS MOI$IM J=I+5 MOI$IA I(J)=1 MOI$MS R=I MOI$MM I=I1 MOI$MA I(J)=K MOI$0S MOI$0M I=0 MOI$0A I(J)=0 MOI$1S MOI$1M I=1 MOI$1A $IPMOV - Integer and pararmeter moves MOI$SP IP=IP+1 MOI$IP IP=1 MOI$MP IP=I MOI$PS IP=IP+1 MOI$PM I=IP MOI$PA IP(I)=IP2 MOI$PP IP=IP2 MOI$0P IP=0 (7) (7) (7) (4) (6) (5) MOI$1P IP=1 $LMOVR - Moves of logical*1 results MOL$RA MOL$RP FORTRAN IV OTS (Draft) Compiler Support Modules Page 1-17 MOL$RM $LMOVS - Logical*1 moves MOL$SM B=B+1 MOL$SA B(I)=B(I2) MOL$SP BP=BP+1 MOL$IM B=.true. MOL$IP BP=I MOL$IA B(J)=0 MOL$MP MOL$MM B=B1 MOL$MA B(J)=B2 MOL$MP MOL$MS MOL$PM MOL$PA MOL$PP BP=BP2 MOL$PS BP=BP+1 1 - 1. has been converted to double so is on the stack, D in memory 2 - .1 is being put on stack for conversion to integer 3 - I was on stack for conversion to real, is now being moved in memory into 4 - .1 was on stack for conversion to integer, is into memory moved now being R 5 - I was on stack for conversion to real is now being moved to memory 6 - The value of I(I2) is on the stack and the address of X(I1) is on the stack 7 - ROOT is a function 1.6.6 Subscript Calculations Subscript calculations differ according to the dimension of the array, use of subscript vectoring for multidimensional arrays, and the size of the data elements. In addition module sizes vary slightly according to whether bounds checking has been incorporated or not. <<<<< examples will be revised to better distinguish SA vs. SV>>>>> MODULES $DVEC - Double precision subscript operators SAD$IM FORTRAN IV OTS (Draft) Compiler Support Modules SAD$MM SAD$SM SVD$IM SVD$MM SVD$SM Page 1-18 D(J)=D2 D2=D(I+J) D(J)=D(I) D2=D(I+J) $FVEC - *4 subscript operators SAF$IM SAF$MM R(I)=R2 SAF$SM R(I+J)=R2 SVF$IM SVF$MM R(J)=R(I) SVF$SM R2=R(I+J) (1) (2) $IVEC - Integer subscript operators SAI$IM SAI$MM I(J)=I(2) SAI$SM SVI$IM SVI$MM I(J)=I(J2) SVI$SM $LVEC - Logical*1 subscript operators SAL$IM SAL$MM L(J)=L2 SAL$SM SVL$IM SVL$MM SVL$SM $DVECC - Double precision subscript operators involving parameters SAD$IP DP(24)=D2 SAD$MP SAD$SP DP(I+J)=D2 SVD$IP D2=DP(24) SVD$MP SVD$SP D2=DP(I+J) $FVECC - Real subscript operators involving parameters SAF$IP DP(24)=D2 SAF$MP SAF$SP RP(I+J)=R2 SVF$IP R2=RP(24) SVF$MP SVF$SP R2=RP(I+J) $IVECC - Integer subscript operators involving parameters SAI$IP IP(24)=I2 SAI$MP SAI$SP IP(K+J)=I2 SVI$IP SVI$MP SVI$SP I2=I(22) I2=IP(J+K) $LVECC - Logical*1 subscript operators involving parameters FORTRAN IV OTS (Draft) Compiler Support Modules SAL$IP SAL$MP SAL$SP SVL$IP SVL$MP SVL$SP Page 1-19 BP(22)=B2 BP(I+J)=B2 B2=BP(24) B2=BP(I+J) $DVECP - Double subscript operators involving parameters SAD$PM D(IP)=D1 SAD$PP SVD$PM D1=D(IP) SVD$PP $FVECP - Real subscript operators involving parameters SAF$PM R(IP)=R2 SAF$PP SVF$PM R2=R(IP) SVF$PP $IVECP - Integer subscript operators involving parameters SAI$PM I(IP)=I2 SAI$PP SVI$PM I2=I(IP) SVI$PP $LVECP - Logical*1 subscript operators involving parameters SAL$PM B(IP)=B1 SAL$PP SVL$PM B1=B(IP) SVL$PP $QPVEC - Logical*4 and integer*4 subscript operators involving parameters SVQ$PM SVQ$PP $QVEC - Logical*4 and integer*4 subscript operators SVQ$IM SVQ$SM SVQ$MM $QVECP - Logical*4 and integer*4 subscript operators involving parameters SVQ$IP SVQ$SP SVQ$MP 1 - The address of R(J) is on the stack 2 - The value of X(I) is on the stack FORTRAN IV OTS (Draft) Compiler Support Modules 1.6.7 Page 1-20 Miscellaneous Operations MODULES $CNEG - Negate complex value NGC$M C=-C NGC$S C=-C+C2 NGC$P CP1=-CP2 NGC$A (1) $FNEG - Negate real value NGF$S R=-R+R2 NGF$M R=-R NGF$A NGF$P RP1=-RP2 NGD$S D=-D+D2 NGD$M D=-D NGD$A NGD$P DP1=-DP2 $INEG - Negate integer value NGI$S I=-I+I2 NGI$M I=-I NGI$A NGI$P IP1=-IP2 $INCR - Increment and decrement integer values ICI$S I=(I+1)*8 ICI$M I=I+1 ICI$A ICI$P IP1=IP1+1 DCI$S I=(I-1)*8 DCI$M I=I-1 DCI$A DCI$P IP2=IP2-1 $LNOTS - Logical not operators COI$S I=.NOT.(I+I1) COI$M I=.NOT.I COI$P COI$A COL$S B=.NOT.(B.OR.B1) COL$M B=.NOT.B COL$P COL$A 1 - C is first moved to the stack for later adition to c2 CHAPTER 2 Fortran Library Functions All functions in FORTRAN assume that R5 points to an argument block that contains the number of arguments passed followed by the addresses of the arguments. Functions return via the RTS PC instruction. The value is returned via the registers. For example, an integer function returns a value in R0, and a double precision function returns a value in registers R0-R3. The compiler sets up the argument block by generating a series of REL$ calls to put arguments onto the stack. It then generates a CAL$ call followed by the number of arguments given and the name of the function (the function name is a global). A move is then generated to move the result out of the register(s). The following is a list of the FORTRAN functions. MODULE gives the name of the module in which the function is defined. REFERENCES lists entrypoints, external to the module, that are referenced by the module when the function is called. In some cases these entrypoints are called only under certain hardware configurations, these are noted by a conditional statement such as "If no FPU:". FUNCTION MODULE REFERENCES ABS AIMAG AINT ALOG ALOG10 AMAX0 AMAX1 AMIN0 AMIN1 AMOD ATAN ATAN2 CCOS CEXP CLOG CONJC COS CSIN $ABS $AIMAG $AINT $ALOG $ALOG $AMIN0 $AMAX1 $AMIN0 $AMAX1 $AMOD $ATAN $ATAN $CSIN $CEXP $CLOG $CONJC $SIN $CSIN If no FPU: $ADR,$DVR,$IR,$MLR,$SBR If no FPU: $ADR,$DVR,$IR,$MLR,$SBR $IR,$POPR3 $CMR,$RI $IR,$POPR3 $CMR,$RI $DVR,$INTR,$MLR,$POPR3,$SBR If no FPU: $ADR,$DVR,$MLR,$POPR3,$SBR If no FPU: $ADR,$DVR,$MLR,$POPR3,$SBR COS,EXP,SIN,$ADR,$DVR,$FCALL,$MLR,$SBR COS,EXP,MOF$RS,SIN,$FACLL,$MLC,$MLR,$POPR4,$SBR ALOG,ATAN2,CABS,$FCALL If no FPU: $ADR,$DVR,$INTR,$MLR,$SBR COS,EXP,SIN,$ADR,$DVR,$FCALL,$MLR,$SBR FORTRAN IV OTS (Draft) Fortran Library Functions CSQRT DABS DATAN DATAN2 DBLE* DCOS DEXP DIM DLOG DLOG10 DMAX1 DMIN1 DMOD DSIGN DSIN DSQRT EXP FLOAT* IABS IDIM IDINT** IFIX* INT** ISIGN MAX0 MAX1 MIN0 MIN1 MOD RAN REAL SIGN SIN SNGLE SQRT TANH $CSQRT $DABS $DATAN $DATAN $DBLE $DSIN $DEXP $DIM $DLOG $DLOG $DMIN1 $DMIN1 $DMOD $DSIGN $DSIN $DSQRT $EXP $FLOAT $IABS $IDIM $INT $IFIX $INT $ISIGN $MAX0 $AMAX1 $MIN0 $AMAX1 $MOD $RAN $REAL $SIGN $SIN $SNGLE $SQRT $TANH Page 2-2 $ABS,$ADR,$IVR,$FCALL SQR,$ADR,$DVR,$FCALL,$MLR If no FPU: $ADD,$DVD,$MLD,$POPR4,$SBD If no FPU: $ADD,$DVD,$MLD,$POPR4,$SBD If no FPU: $ADD,$DINT,$DVD,$MLD,$POPR4,$SBD If no FPU: $ADD,$DI,$DVD,$ID,$MLD,$POPR4,$SBD $SBR If no FPU: $ADD,$DVD,$ID,$MLD,$POPR4,$SBD If no FPU: $ADD,$DVD,$ID,$MLD,$POPR4,$SBD $CMD $CMD $DVD,$DINT,$MLD,$SBD If no FPU: If no FPU: If no FPU: $IR,$POPR3 $ADD,$DINT,$DVD,$MLD,$POPR4,4SBD $ADD,$DVD $ADR,$DVR,$IR,$MLR,$RI,$SBR $RI $RI $RI $CMR,$RI $CMR,$RI $DVI,$MLI If no FPU: $ADR,$DVR,$INTR,$MLR,$SBR If FIS: $ADR,$DVR EXP,MOF$RS,$ADR,$DVR,$FCALL,$MLR,$SBR * These routines exist but are never called. Instead the calls the appropriate conversion routine directly. compiler ** These functions generate blocks of code that can be avoided by direct conversions. For example, FORTRAN programs should use I=R instead of I=INT(R) or in MACRO simply call $RI. CHAPTER 3 Use of Compiled Code Support Routines 3.1 Introduction Many of the modules for compiled code support may also be used by the Assembly Language programmer to perform common operations. Examples include data type conversion and routines for emulating floating point arithmetic on machines without floating point hardware. This chapter provides the necessary information to use these support modules from assembly language code. 3.2 OTS Initialization <<< to be completed later>>> 3.3 Data Type Conversion Modules exist within the OTS for performing data conversions. The code within these modules is hardware dependent. Therefore by using these modules for data conversion, the assembly language programmer accomplishes two things. First the resulting code is transportable to machines with different hardware configurations (object files must simply be relinked with the appropriate OTS). Second, the resulting code will typically be smaller since code already loaded and used by the Fortran part of a program is being used, rather than duplicating functionality in special subroutines. <<< remainder to be completed>>>> APPENDIX A OTS Module Sizes The following table list OTS module size by PSECT. If a module contains code or data in more than one PSECT, each is listed. In this case, the total module size is that obtained by adding the contribution to each PSECT. The sizes are in decimal words. A.1 OTSCOM (Hardware Independent Modules). Mod Psect Size Mod Psect Size Mod Psect Size $ABS $AMAX1 $ASFRE $BACKS $CABS $CEXP OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 7 60 8 100 74 36 $AIF $AMIN0 $ASSIG $BITDI $CALL $CLOG OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 6 24 138 12 15 34 $AIMAG $AMOD $AOTS $BRAS $CEXIT $CLOSE CLOSTM OTS$I OTS$D OTS$I OTS$I 39 4 16 31 $CLS $CMPF $CONJG $CONVI 14 9 20 5 8 8 43 56 19 35 $CSIN $DATE $DMIN1 $DMOV2 $DMOV5 $DMOVR $ENCOD $EOL $ERRSN EXTEND 10 67 10 131 20 120 65 46 5 12 16 65 83 16 21 $CMPD $CMPLX $CONV5 $CONVL OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$S OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 6 23 1 22 2 178 20 88 9 18 35 20 69 7 31 19 19 14 26 960 139 7 $CNEG $CONV6 $COPY $DABS $DIM $DMOV1 $DMOV4 $DMOV7 $DUMPL EOF $ERRTS $CSQRT $DBLE $DMOD $DMOV3 $DMOV6 $DSIGN $ENDER ERRS ERRSS $FCALL $FIND OTS$I 69 $FIO $FMOV2 $FMOV5 $FMOV8 $FNEG $GETRE OTS$I OTS$I OTS$I OTS$I OTS$I 6 4 8 15 68 $FMOV3 $FMOV6 $FMOV9 $FUD $GOTO OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I 40 484 20 7 6 17 5 16 $FCHNL $FLOAT $FMOV1 $FMOV4 $FMOV7 $FMOVR $GETFI $IABS OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 33 8 5 6 8 11 15 8 OTS Module Sizes A-2 Mod Psect Size Mod Psect Size Mod Psect Size $IADDS $ICMPS $IFIX $LISTI 18 18 11 361 20 33 37 19 12 13 5 12 10 1 30 339 299 18 20 14 $IBR $IDATE $IFR $LISTO OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 27 10 39 7 7 7 19 19 18 9 16 10 15 28 31 77 8 18 12 14 $QVECP $REAL $RETS $RWBLK $SETER $SNGL 25 37 26 240 20 14 11 26 56 4 39 10 10 28 24 271 50 28 20 97 20 8 5 20 140 21 14 $IBW $IDIM $IFW $IMOVR $IMOVR $INEG $IPADD $IPSUB $ISUBS $LCMPP $LNOTS $LTEST $MOD $NXT2 $OBJEN OPNCLO $POPR $PSHD2 $PSHF2 $QPVEC OTS$I 8 OTS$I 45 OTS$I 13 OTS$I 210 OTS$I 26 OTS$P 20 $STACK 64 OTS$S 97 OTS$I 553 OTS$I 13 OTS$I 85 OTS$I 92 OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$O OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I $RAN $RETD $REWIN $SAVRE $SIGN $STOP $SUBR $TCMPL $TRARY $TVIRI $TVIRC OTS$I OTS$I OTS$I OTS$I OTS$I 41 45 88 78 111 $TANH $TESTC $TVIRD $TVIRL $UIO OTS$I OTS$P OTS$I OTS$D OTS$P OTS$I OTS$D OTS$I OTS$I $USERE $VINTX $VIRDN $VIRIN $VIRQN $VIRDP $VIRIP $VTRAN $XDD OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I 10 1 103 79 79 116 88 61 95 $VCTRA OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I 42 19 37 56 12 55 20 121 14 86 78 252 20 40 $VIRFN $VIRLN OTS$I OTS$I 88 88 $VIRFP $VIRLP WAIT $XFF OTS$I OTS$I OTS$I OTS$I 100 87 17 54 $IMOVS $INITI $IPCMP $ISIGN $LCMPS $LMOVR $LOADS $MAX0 $NOVIR $NXT3 $OBJFM OPNSTM $PSHD3 $PSHF3 $QVEC $RANDU $RETDS $RIO $SAV4R SIMRT $TESTS $TVIRF $TVIRQ $UIO $VINTN $VINTP $VIRQP $XCI A.1.1 OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$D OTS$I OTS$I 252 20 91 1 21 65 1 90 138 Page $INCR $INT $IPMOV $ISNLS $LCMPI $LMOVS $LPCMP $MIN0 $NXT1 $NXT4 $OPEN $PAUSE $PSHD1 $PSHF1 $PUTRE Hardware Dependent Modules. When determining the size of OTS modules for NHD/EAE/EIS hardware, it is usually necessary to include the following modules: $DADD $DDIV $DMUL $FADD if if if if any any any any Real*8 Real*8 Real*8 Real*4 additon/subtraction division multiplication addition/subtraction OTS Module Sizes A-3 Page $FDIV if any Real*4 divsion $FMULS if any Real*4 multiplication These modules contain the emulation code for the respective arithmetic operations and are referenced by other OTS modules requiring such arithmetic (e.g., SQRT function). Mod $ADDA $ADDM $ADDP $AINT $ALOG $ATAN $CADD $CDIV $CMUL $CONV1 $CONV2 $CONV3 $CONV4 $CONVF $DADD $DATAN $DDIV $DEXP $DINT $DLOG $DMUL $DSIN $DSQRT $EXP $FADD $FDIV $FMULS $IDIVS $IMUL OTINIT $SIN $SQRT $XDI $XFI Psect OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$P OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I OTS$I . ABS. OTS$I OTS$D OTS$P OTS$I OTS$I OTS$I OTS$I NHD 27 28 28 39 120 215 83 129 82 12 55 43 18 485 20 326 361 247 226 53 194 222 184 66 112 176 105 114 42 30 16 582 3 21 125 62 132 92 Size for each hardware EAE EIS FIS 27 27 54 28 28 46 28 28 45 41 33 33 120 120 120 215 215 215 83 83 83 129 129 129 82 82 82 12 12 12 59 53 53 43 43 43 18 18 18 485 503 503 20 20 20 371 323 323 361 361 361 247 247 247 226 226 226 55 41 41 194 194 194 296 289 289 184 184 184 66 66 66 112 112 112 176 176 36 145 138 17 142 127 17 19 15 15 19 14 14 16 16 16 591 582 614 3 3 3 21 21 21 125 125 125 62 62 44 132 132 132 92 92 92 FPU 46 46 54 15 59 115 53 46 35 10 30 17 12 503 20 49 154 24 114 11 92 23 97 41 74 49 18 17 15 14 16 633 3 21 66 30 40 38 $XII OTS$I 67 67 49 49 49 OTS Module Sizes A-4 A.1.2 Mod $DPVEC $DVECP $FVEC $IPVEC $IVECP $LVEC Page Subscript Calculations. Psect Size Bounds No Bounds OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx Mod Psect $DVEC $FPVEC $FVECP $IVEC $LPVEC $LVECP Size Bounds No Bounds OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx OTS$I xxx xxx