|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 156416 (0x26300) Types: TextFile Names: »D82«
└─⟦e634bf8f4⟧ Bits:30005867/disk11.imd Dokumenter (RCSL m.m.) └─⟦this⟧ »D82«
T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 1. INTRODUCTION ...................................... 1 2. SUMMARY OF THE LANGUAGE ........................... 2 3. NOTATION .......................................... 4 4. BASIC VOCABULARY .................................. 6 4.1 Basic Symbols .............................. 6 4.2 Indetifiers ................................ 7 4.3 Numbers .................................... 10 4.4 Strings .................................... 11 4.5 Comments ................................... 12 5. MODULE ............................................ 14 5.1 Module Heading ............................. 14 5.2 Section Specification ...................... 15 5.3 Block ...................................... 17 6. CONSTANT DEFINITIONS .............................. 19 7. DATA TYPES ........................................ 22 7.1 Simple Types ............................... 22 7.1.1 Short ............................. 22 7.1.2 Pshort ............................ 22 7.1.3 Integer ........................... 23 7.1.4 Long .............................. 23 7.1.5 Real .............................. 23 7.2 Structured Types ........................... 24 7.2.1 Arraytype ......................... 25 7.2.2 Recordtype ........................ 26 \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 8. VARIABLES .......................................... 28 8.1 Variable Declaration ........................ 28 8.2 Variable Initialization ..................... 30 8.3 Variable denotation ......................... 32 8.3.1 Simple Variables, Record Variables and Simple Array Variables ......... 33 8.3.2 Structured Array Variables ......... 35 9. EXPRESSIONS ........................................ 37 9.1 Registers ................................... 37 9.2 Operators ................................... 38 9.2.1 Monadic Operators .................. 39 9.2.2 Dyadic Operators ................... 41 9.2.3 Relational Operators ............... 45 9.3 Operands .................................... 47 9.4 Register Expressions ........................ 48 9.5 Relational Expressions ...................... 53 10. PROCEDURE AND REGION DECLARATION ................... 58 10.1 Region Declaration .......................... 58 10.2 Procedure Declaration ....................... 60 11. STATEMENTS ......................................... 66 11.1 Simple Statements ........................... 66 11.1.1 Assignment Statements .............. 67 11.1.2 Goto Statement ..................... 68 11.1.3 Procedure Statement ................ 69 11.1.5 Execute Statement .................. 70 11.1.6 Monitor Statement .................. 71 11.1.7 Pager Statement .................... 72 11.2 Structured Statements ....................... 73 11.2.1 Compound Statement ................. 73 11.2.2 Conditional Statements ............. 74 \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 11.2.2.1 If Statement ............. 74 11.2.2.2 Case Statement .......... 75 11.2.3 Repetitive Statements .............. 76 11.2.3.1 For Statement ............ 76 11.2.3.2 While Statement .......... 89 11.2.3.3 Repeat Statement ......... 79 11.2.3.4 Loop Statement ........... 79 11.2.4 With Statement ..................... 80 12. EXTERNAL REFERENCES AND DEFINITIONS ................. 82 13. SCOPE RULES ........................................ 84 14. CORE LAYOUT AND ADDRESSING TECHNIQUES .............. 85 15. COMPILER DIRECTIVES ................................ 97 A. REFERENCES ......................................... 100 B. LITTERATURE ........................................ 101 \f f_o_r_e_w_o_r_d_ This is a provisional edition of the reference manual for the programming language SPL. The compiler is still in progress and the language is therefore subject to changes. \f 1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_ 1. This manual contains a formal description of the system program- ming language SPL, to be used on the RC8000 computer. SPL is primarily designed to be used for programming systems with severe demands on efficient computer utilization. At the same time it should be an efficient programming tool, offering the programmer the means for solving his problems in a natural way. On the RC8000 computers, software systems with severe demands on efficiency have usually been programmed in the assembly language SLANG while ALGOL has been preferred for almost all other appli- cations. SPL is expected to be used for most kinds of applications that previously were written in assembly language. The design of SPL has been influenced by low level lauguages like PL360, PL4000 and RCMOL. SPL has been designed to use the "language independent programming system" of the RC8000 described in ref.1. This system offers facilities for composing a program of modules possibly written in different languages, and execute the program in a virtual environment. In this manual is described the syntax and the semantics of the SPL language. The descriptions include examples of program text and an outline of the corresponding code generated by the compiler \f 2_._ _ _ _ _ _ _ _ _S_U_M_M_A_R_Y_ _O_F_ _T_H_E_ _L_A_N_G_U_A_G_E_ 2. The main purpose of designing SPL was to produce a language, com- bining efficient program execution with efficient program deve- lopment and maintenance. To support efficient program execution, SPL includes facilities for controlling the use of the hardware to a very high degree. The programmer controlled u_s_e_ _o_f_ _r_e_g_i_s_t_e_r_s_ is supported by desig- ning expressions in a special way, requiring that the programmer explicitly states the register(s) involved in an operation (a computation). The programmer controlled u_s_e_ _o_f_ _i_n_s_t_r_u_c_t_i_o_n_s_ is supported by designing a set of operators (arithmetic and relational opera- tors) each of which corresponds directly to one or a few instruc- tions. The programmer controlled o_b_j_e_c_t_ _a_d_d_r_e_s_s_i_n_g_ is supported impli- citly by offering the programmer facilities for controlling vari- able allocation, program structuring and program segmentation. To ease program development and maintenance, SPL contains a col- lection of structures, known from high level languages. A number of these high level structures are influenced by Pascal. SPL contains s_t_r_u_c_t_u_r_e_d_ _t_y_p_e_s_ (records and arrays) and facilities for directly addressing fields and elements of simple type and "indirectly" addressing nested structures. In SPL conditional and reptitive execution is implemented by r_e_l_a_t_i_o_n_a_l_ _e_x_p_r_e_s_s_i_o_n_s_ controlling s_t_r_u_c_t_u_r_e_d_ _s_t_a_t_e_m_e_n_t_s_. \f SPL contains a p_r_o_g_r_a_m_ _s_t_r_u_c_t_u_r_e_ enabling the programmer to subdivide his program into a main part and a number of p_r_o_c_e_d_u_r_e_s_ and r_e_g_i_o_n_s_. SPL procedures may be equipped with formal parameters offering a number of different p_a_r_a_m_e_t_e_r_ _t_r_a_n_s_f_e_r_ _f_a_c_i_l_i_t_i_e_s_. \f 3_._ _ _ _ _ _ _ _ _N_O_T_A_T_I_O_N_._ 3. The syntax of SPL is described using a modified version of the Backus-Naur Form (BNF). The extensions primarily concern the introduction of special brackets, and . These brackets may contain a number of alterna- tives listed on separate lines, and suffixes may define repeti- tion of the elements inside the brackets. The lower and upper suffixes define the lower and upper bounds of the repetition. The symbol identifier' is often replaced by more descriptive variants like type identifier', procedure identifier' etc. E_x_a_m_p_l_e_s_:_ alternatives: letter' letterordigit' ::= digit' repetition: identifier' ::= letter' letterordigit' 0_U_U_*D_D_D_D_0U_U_5_ (* indicates an unlimited number of repetitions) \f combined use of alternatives and repetitions: letter' 0_U_U_*D_D_5_ identifier' ::= letter' digit' 0_D_D_0U_U_5_ a production occupying several lines: region declaration' ::= region constant definition part' type definition part' variable declaration part' initialization part' procedure declaration part' end \f 4_._ _ _ _ _ _ _ _ _B_A_S_I_C_ _V_O_C_A_B_U_L_A_R_Y_. 4. The casic vocabulary of SPL consists of special symbols, identifiers, numbers, strings and comments. All elements of the basic vocabulary are built up by one or more characters of the ISO 7-bit character set. 4_._1_ _ _ _ _ _ _ _B_a_s_i_c_ _S_y_m_b_o_l_s_. 4.l delimiter symbols: ; : , . ( ) + - * / := :- :-- -' -' = ' ' '= = * *' \f reserved words: and, array, ashift, base, begin, case, compile, const, copy, def, disjoints, do, else, end, endc, endloop, eof, ex, execute, exit, extend, external, extract, f01, f12, f23, f30, float, for, goto, if, iff, ift, iftf, includes, init, integer, land, library, listoff, liston, long, loop, lor, lshift, message, monitor, not, of, or, pager, param, procedure, program, pshort, range, real, record, ref, region, relative, repeat, resident, return, revision, rewrite, round, section, short, size, sref, step, then, type, until, value, var, virtual, w0, w01, w1, w12, w2, w23, w3, w30, when, while, with, xor.\f 4_._2_ _ _ _ _ _ _ _I_d_e_n_t_i_f_i_e_r_s_. 4-2 The syntax of an identifier is: letter' UU*DD identifier' ::= letter' digit' UUoDD small letter' letter' ::= capital letter' a A b B c C d D e E f F g G h H i I j J k K l L m M n N small letters' o capital letters' ::= O p P q Q r R s S t T u U v V w W x X y Y z Z æ Æ ø Ø å Å \f The symbol " _" is blind within identifiers and reserved words. Capital letters are converted to small letters when used within identifiers and reserved words. A reserved word cannot be used as an identifier. E_x_a_m_p_l_e_s_:_ Three versions of the same reserved word: Goto goto go _to legal identifiers: printer300 bit _11 i \f 4_._3_ _ _ _ _ _ _ _N_u_m_b_e_r_s_._ 4.3 SPL contains two kinds of numbers, both obeying the usual decimal notation: - numbers describing integer values - numbers describing floating point values integer number' number' ::= floating number' integer number' ::= radix' 0_U_U_1D_D_D_D_0U_U_5_ unsigned integer' radix' ::= digit'> unsigned integer' ::= digit' digit' 0_U_U_*D_D_D_D_0U_U_5_ floating number' ::= decimal number' decimal number' + 0_U_U_1D_D_5_ e unsigned integer' unsigned integer' - 0_D_D_0U_U_5_ decimal number' ::= unsigned integer' . unsigned integer' 0UU1DDDD0UU5 .unsigned integer' \f E_x_a_m_p_l_e_s_:_ integer values: 1979 1234567890 8>40001 floating point values: 5. 333.33 1e6 3.3333e2 In SPL integer values may be of different types (short, pshort, integer or long). The value of an integer number defines a set of possible types for this number. The actual type is defined by the context, in which the number is used. 4_._4_ _ _ _ _ _ _ _S_t_r_i_n_g_s_._ A sequence of characters enclosed by double quote marks is a t_e_x_t_ c_o_n_s_t_a_n_t_. In case the text constant is to contain a double quote mark this character must be written twice. Any character of the ISO 7-bit character set may be used in a text constant. Characters may be included in a text constant by stating their values as an unsigned integer surrounded by angular brackets and '. \f E_x_a_m_p_l_e_s_._ "abcd 7" is equivalent to "abc100' 7" and "a""b." is equivalent to "a34'b." A printable character value 32-126 surrounded by quote marks is a c_h_a_r_a_c_t_e_r_ _c_o_n_s_t_a_n_t_. A character constant may be used as an inte- ger constant. The value of the character surrounded by quote marks is the value of the character constant. E_x_a_m_p_l_e_s_: >a> is equivalent to 97 and , , is equivalent to 32 4_._5_ _ _ _ _ _ _ _C_o_m_m_e_n_t_s_._ A sequence of characters enclosed by * and *' may be insterted between any two identifiers, numbers, text constants or special symbols. This sequence (including * and *') is considered to be a comment. The character sequence, of course, cannot contain the symbol *'. \f E_x_a_m_p_l_e_s_: * this is a comment *' *1*' * this is a comment *' \f 5_._ _ _ _ _ _ _ _ _M_O_D_U_L_E_._ 5. An SPL module consists of a main block with typedefinitions, va- riable declarations and procedure/region declarations. A proce- dure declaration contains a block of the same structure, thereby introducing local definitions and declarations (scope). Regions also introduce a new scope, but in a special way. The details around scope rules are treated in sec. 13. spl module' ::= moduleheading' section specification' 0UU1DDDD0UU5 block'. 5_._1_ _ _ _ _ _ _ _M_o_d_u_l_e_ _H_e_a_d_i_n_g_._ 5.1 module heading' ::= program title' revision' 0_U_U_1D_D_D_D_0U_U_5_ page heading' 0_U_U_1D_D_D_D_0U_U_5_ semi' external title' ::= identifier' revision' ::= revision unsigned integer'.unsigned integer' page heading' ::= text constant' E_x_a_m_p_l_e_s_: program corusys revision 2.1 "coroutine system"; external mathfunc "functions sine and cosine"; The module heading specifies that the module be either a p_r_o_g_r_a_m_ or merely a collection of procedures among which one or more can be made e_x_t_e_r_n_a_l_ by a define statement (see sec. 12). In external modules all parts but the statement part of the main block are allowed. \f The title in the module heading is the identification of the mo- dule in the link/load-system (ref. 1). Revision and pageheading are for documentation purpose and the revision will be part of the object program. 5_._2_ _ _ _ _ _ _ _S_e_c_t_i_o_n_ _S_p_e_c_i_f_i_c_a_t_i_o_n_._ 5.2 The SPL modules can be physically divided into a number of sec- tions in the sense described in ref. 1. Sections follow the structure of the SPL module in that a section contains the main program (described here) and/or an integral number of procedures (see sec. 10). section specification' ::= storage specification' section section identifier' 0_U_U_1D_D_D_D_0U_U_5_ semi' storage specification' ::= virtual rewrite 0_U_U_1D_D_D_D_0U_U_5_ resident E_x_a_m_p_l_e_s_:_ resident section main; virtual rewrite section virt _procs; The section specification specifies by the name, which section the following variables and code belong to. Each physical section may be collected from objects belonging to one or more section specifications. The default for the section specification of the main program is >resident section main>. \f E_x_a_m_p_l_e_:_ program corusys; f_i_r_s_t_ _p_a_r_t_ _o_f_ _p_h_y_s_i_c_a_l_ _s_e_c_t_i_o_n_ _>_m_a_i_n_>_._ virtual section virt _procs; procedure p... . . procedure q v_i_r_t_u_a_l_ _s_e_c_t_i_o_n_ _>_v_i_r_t_ _p_r_o_c_s_>_ . . resident section main; s_e_c_o_n_d_ _p_a_r_t_ _o_f_ _p_h_y_s_i_c_a_l_ _s_e_c_t_i_o_n_ _>_m_a_i_n_>_._ Sections can be resident, i.e. they remain in primary store throughout the execution of the program, or they can be virtual, i.e. they can be relocated in the primary store and transferred to secondary store when passive, enabling the program to be lar- ger than the available primary store. Virtual sections, which are overwritten, are transferred back to their origin on secondary store when rewrite is specified, other- wise nothing is done. Rewriting is necessary, when the virtual section contains information that is modified (e.g. variables) and must be preserved. \f 5_._3_ _ _ _ _ _ _ _B_l_o_c_k_._ 5.3 block' ::= external part' constant definition part' type definition part' variable declaration part' initialization part' statement part' procedure declaration part' end A block contains definitions and declarations that are local to the block, i.e. only visible inside the block. The block is divi- ded into several parts, which are described in detail in the sub- sequent sections. E_x_t_e_r_n_a_l_ _p_a_r_t_ serves to import into the SPL module objects independently compiled, and export out of the SPL module objects that are going to be used by other modules. (See sec. 12). C_o_n_s_t_a_n_t_ _d_e_f_i_n_i_t_i_o_n_ _p_a_r_t_ serves to define constants, i.e. values that are known at compile time and therefore can be used for >symbolic constants>, dimensioning, compile time direction etc. (see sec. 6). T_y_p_e_ _d_e_f_i_n_i_t_i_o_n_ _p_a_r_t_ serves to define new structured types (ar- rays and records). (See sec. 7). V_a_r_i_a_b_l_e_ _d_e_c_l_a_r_a_t_i_o_n_ _p_a_r_t_ serves to declare local variables and allocate core space for them. (See sec. 8). I_n_i_t_i_a_l_i_z_a_t_i_o_n_ _p_a_r_t_ serves to initialize variables declared in the local variable declaration part. (See sec. 8). \f S_t_a_t_e_m_e_n_t_ _p_a_r_t_ is the executable part of the block. (see sec. 11). P_r_o_c_e_d_u_r_e_ _d_e_c_l_a_r_a_t_i_o_n_ _p_a_r_t_ contains declarations of procedures and regions introducing local blocks (local scope). (See sec. 10). \f 6_._ _ _ _ _ _ _ _ _C_O_N_S_T_A_N_T_ _D_E_F_I_N_I_T_I_O_N_S_._ 6. A constant definition serves to introduce an identifier as a sy- nonym for a constant or a constant expression. Constants are used in various parts of the language, e.g. in parameterizing array- types. constant definition part' ::= const constant definition' 0UU*DDDD0UU5 semi' 0UU1DDDD0UU5 constant definition' ::= constant identifier' = constant expression' semi' range (constant identifier' , constant identifier'0UU*DDDD0UU5 ) constant expression' ::= constant' constant expression' dyadic operator'constant' constant' ::= monadic operator' number' character constant' size specification' constant identifier' ( constant expression' ) size specification' ::= size UUtype'DD UUprocedure identifier'DD \f E_x_a_m_p_l_e_s_:_ printer300 = 2 printer600 = 1 printers = printer600 + printer300 space = > > bit11 = 8>4000 allocsize = size(rec _type) range(init _state, aftersign, afterdigit, error) activate _p = size(p) The basic elements of constant expressions are: n_u_m_b_e_r_s_ (integer numbers in radix 2-10 and floating point numbers) and c_h_a_r_a_c_t_e_r_ c_o_n_s_t_a_n_t_s_. Character constants comprise all printing ISO characters (value 32 - 126) and the value is the ISO value of the character. Elements of a constant expression must have their value defined before they are used. R_a_n_g_e_ serves to associate a set of identifiers with consecutive integer values. The first identifier defines the startvalue. If the startvalue is undefined, it is set to 1. \f E_x_a_m_p_l_e_:_ range (a, b, c); is equivalent to a = 1; b = a+1; c = b+1; E_x_a_m_p_l_e_:_ a = 10; range (a, b, c); is equivalent to a = 10; b = a+1; c = b+1; S_i_z_e_ denotes the size in halfwords of an instance of a type or the size in halfwords of an activation (parameter) record of a procedure. The >type> in >size(type)> must be defined before it is used in further constant definitions or expressions. \f 7_._ _ _ _ _ _ _ _ _D_A_T_A_ _T_Y_P_E_S_._ 7. Types define the set of values or the pattern of a variable. A variable is associated with exactly one type. SPL is provided with a set of simple (basic) types, and struc- tured types that can be built using the simple types. 7_._1_ _ _ _ _ _ _ _S_i_m_p_l_e_ _t_y_p_e_s_._ 7.1 As SPL must not >hide> the underlying computer structure from the programmer, the simple types are defined as the units accessible in one instruction of the RC8000. short pshort simple type' ::= integer long real 7_._1_._1_ _ _ _ _ _S_h_o_r_t_._ 7.1.1 short is a signed integer, which can be held in one halfword (12 bits) and therefore lies in the range -2048:2047. 7_._1_._2_ _ _ _ _ _P_s_h_o_r_t_._ 7.1.2 pshort is an unsigned integer, which can be held in one half- word (12 bits) and therefore lies in the range 0:4095. \f The operations that can be performed on a pshort are load vari- able into register (:=) and store register into variable (-'). Note that as a consequence, it is impossible to use a variable of type pshort directly in arithmetic expressions. 7_._1_._3_ _ _ _ _ _I_n_t_e_g_e_r_._ 7.1.3 integer is a signed integer which can be held in one word (24 bits) and therefore lies in the range -8 388 608:8 388 607 The operations that can be performed on an integer are load vari- able into register (:=), store register into variable (-'), +, -, * , /, and, or, not and comparison. 7_._1_._4_ _ _ _ _ _L_o_n_g_._ 7.1.4 long is a signed integer which can be held in one doubleword (48 bits) and therefore lies in the range: -140 737 488 355 328:140 737 488 355 327. The operations that can be performed on longs are: load variable into register (:=), store register into variable (-') ,+ and -. 7_._1_._5_ _ _ _ _ _R_e_a_l_._ 7.1.5 real is a floating point number, which can be held in one double word (48 bits) with 36 bits mantissa and 12 bits exponent. The range of real is approximately -1.6 * 10UU616DD: 1.6*10UU616DD \f The operations that can be performed on reals are: load variable into register (:=), store register into variable (-'), +, -, * and /. 7_._2_ _ _ _ _ _ _ _S_t_r_u_c_t_u_r_e_d_ _T_y_p_e_s_._ 7.2 Structured types are collections of components of other types, either simple or structured. Structured types are defined in the type definition part and all the component types of a structured type must be previously defined. type definition part' ::= type type definition'semi' 0UU*DDDD15U_U_0UU1DDDD0UU5 type definition' ::= record type identifier' = storage specifier' 0UU1DDDD0UU5 record type' array type identifier' = storage specifier' 0_U_U_1D_D_D_D0UU5 array type' storage specifier' ::= UUvirtualDD UUresidentDD The storage specifier' indicates how instances of the type should be allocated: 1. nothing specified allocate instances in the local section. 2. virtual specified allocate instances as seperate vir- tual sections. 3. resident specified allocate instances in the resident section. \f Note that the storage specifier can only be used at the outermost level, not as a specifier on components of record types. Examples of the allocation of instances of different types are given in sec. 8.1. 7_._2_._1_ _ _ _ _ _A_r_r_a_y_t_y_p_e_._ 7.2.1 An array is a structure consisting of a fixed number of compo- nents of the same type. Components are accessed by their logical index. arraytype'::= UUarray limits' of elementtype'DD UUarray type identifier'DD limits'::= constantexpression'..constantexpression' elementtype' ::= UUsimple type'DD UUrecord type identifier'DD Elements of arrays are either of simple type or record type. Only arrays of one dimension are allowed, and the limits are determined by constantexpressions, i.e. the number of elements in the array is determined at compiletime. E_x_a_m_p_l_e_:_ row = array 1..n of integer; \f 7_._2_._2_ _ _ _ _ _R_e_c_o_r_d_t_y_p_e_._ 7.2.2 A record is a structure consisting of a fixed number of compo- nents of possibly different types, either simple or structured. Each component is denoted by an identifier, called the field- identifier and components are accessed through selection of the field. r_ record type' ::= UUrecord base' 0UU1DDDD0UU5 field' semi' field' 5_ 0UU*DDDD0UU5 endDD UUrecord type identifier'DD DDbase' ::= base =UU field identifier' DDsemi'UU constantexpression' r_ field' ::= field identifier' ,fieldidentifier' 0_U_U_*D_D_D_D_0U_U_5_:type' 0_U_U_1D_D_D_D_0U_U_ 5_ simple type' type' ::= record type idemtifier' array type identifier' \f E_x_a_m_p_l_e_s_._ messages = array 1..4 of integer; inoutmess = record operation, mode: short; first, last, segment: integer; end; iomessbuf = record next, previous, receiver, sender: integer; io: inoutmess; mess: messages; end; Fieldidentifiers have the scope of the recordtype. To be able to have records conforming to existing recordformats with offsets not equal to zero, it is possible to state the off- set explicitly, either as a field in the recordtype or as a num- ber of halfwords (positive or negative). E_x_a_m_p_l_e_:_ processdesc = record base = kind; lower _base, upper _base, kind : integer; name : procname; ... end; For v_i_r_t_u_a_l_ recordtypes, a negative offset is not allowed. \f *********************DISKETTEERROR******************* \f 8_._ _ _ _ _ _ _ _ _V_A_R_I_A_B_L_E_S_._ 8. Variables in an SPL-program must be declared before they are used. Variables can be declared in the block of the main p_r_o_g_r_a_m_, in the local block of a p_r_o_c_e_d_u_r_e_ or in a r_e_g_i_o_n_. 8_._1_ _ _ _ _ _ _ _V_a_r_i_a_b_l_e_ _D_e_c_l_a_r_a_t_i_o_n_._ 8.1 A variable declaration associates an identifier with a type, either simple or structured (defined in a type definition part), and allocates space for it. variable declaration part' ::= r_ var variable identifier' , variable identifier' 0UU*DDDD0UU5 :type'semi' 0UU*DDD D0UU5 0UUu1DDDDd0UUu5 E_x_a_m_p_l_e_._ var i,j: integer; arr: row; message: iomessbuf; Variables are by default allocated in the local s_e_c_t_i_o_n_, i.e. >close> to the code of the statement part of the local block. Structured types can be defined as virtual or resident. In the case of a resident type, space is allocated in the resident part of the program. \f E_x_a_m_p_l_e_:_ type operation = record op: short chain _1, chain _2: integer; ... end; virtual _op: virtual operation; arr _virtual _op: array 1..6 of virtual _op; virtual _op _arr: virtual array 1..3 of operation; var op: operation; op _v: virtual _op virt _operations: arr _virtual _op; operations: virtual _op _arr; In this example allocation will take place as follows: the vari- able >op> will be allocated on the current section (be it resi- dent or virtual), the variable >op _v> is allocated as a seperate virtual section, the variable >virt _operations> are allocated as 6_ _s_e_p_a_r_a_t_e_ virtual sections, while the variable >operations> is allocated as o_n_e_ _s_e_p_a_r_a_t_e_ virtual section. It should be noted that a single virtual section will occupy a multiple of 512 halfwords, both in primary and secondary store. \f 8_._2_ _ _ _ _ _ _ _V_a_r_i_a_b_l_e_ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_._ 8.2 Variables declared in the local block or region can be given ini- tial values in the initialization part of the block or region. initialization part' ::= init initialization' semi' 0UU*DDDD15U_U_U_U01DDDD0UU5 DDinitialization' ::=UU simple initialization' field initialization' simple initialization' ::= initialconstant' variable identifier' = initialconstant', initialconstant' 0_U_U_*D_D_D_D_0U_U_5_ field initialization' ::= variable identifier' = (initialization' ,initialization' 0_U_U_*D_D_D_D_0U_U_5_) initial constant' ::= constant expression' repeat constant expression' 0_U_U_1D_D_D_D_0U_U_5_ text constant' address' virtual address' ::= resident (variable identifier') relative E_x_a_m_p_l_e_:_ i=0; Initializing the array arr with arr(1)=0 and arr(2)=arr(3) = arr(n)= -1: arr = (0, -1 repeat n-1) \f E_x_a_m_p_l_e_:_ Assuming the following definitions and declarations: const n=2 type mk=record mnemonic, modekind: integer; ... end; mktab=array 1..n of mk; var modekind: mktab; The following will initialize the >mnemonic> fields of the array, while leaving the other fields uninitialized: init modekind = (mnemonic = ("tro", "tre")); Variables of structured type are initialized by listing values for each component, either as a simple list, where the components are taken from left to right in lexicographical order, or as an initialization of the components by explicit naming. Variables can be initialized with constants being either: - a c_o_n_s_t_a_n_t_ _e_x_p_r_e_s_s_i_o_n_ (basically numbers and character con- stants) - a t_e_x_t_ _c_o_n_s_t_a_n_t_ - an a_d_d_r_e_s_s_ _c_o_n_s_t_a_n_t_, which is an address of a variable. Either its v_i_r_t_u_a_l_ address (only for virtual objects), its r_e_s_i_d_e_n_t_\f address (only for resident objects) or its r_e_l_a_t_i_v_e_ address on the section it belongs to. 8_._3_ _ _ _ _ _ _ _V_a_r_i_a_b_l_e_ _D_e_n_o_t_a_t_i_o_n_._ 8.3 Variable denotation either denotes an entire variable or a component of structured variable. 8_._3_._1_ _ _ _ _ _S_i_m_p_l_e_ _V_a_r_i_a_b_l_e_s_,_ _R_e_c_o_r_d_ _V_a_r_i_a_b_l_e_s_ _a_n_d_ _S_i_m_p_l_e_ _a_r_r_a_y_ _V_a_r_i_a_b_l_e_s_. 8.3.1 variable identifier' variable' ::= variable element base' (index') variable field base' field' variable element base' ::= array variable identifier' register operand' variable identifier' UU(array type identifier')DD variable field base' ::= record variable identifier' register operand' variable identifier' UU(record type identifier') 0UU1DDDD05 variable field base' field identifier' field identifier' field' ::= array field identifier'(index') simple type' index' ::= UUregister expression'DD UUconstant expression'DD\f E_x_a_m_p_l_e_:_ Denotation of a simple variable: i Selecting an element of an array of integers: arr(5) arr(w1+3) Selecting an element via the reference in w1: w1(row)(w2:= i+5) Selecting a field of a record: message.io.operation message.messages (wl) Selecting a field via the reference in w2: w2(iomessbuf).next Selecting the word referenced by w1: w1.integer Simple variables are denoted by their identifier. Selecting a component of a variable of structured type is denoted by indexing or field designation. Indexing must always yield a simple variable as a result, not an entire array or record. The restriction on arraytypes (cf. 7.2.1) and the above are re- flected in the following: elementtype of arrays used in this con- nection must be simple and when present indexing must be the >outermost> selection. \f As addresses are available to the programmer, a register or inte- ger variable can be used as a basis for component selection. As these >referencevariables> are typeless and as the fieldidenti- fiers of a recordtype only have to be unique inside the recordde- finition itself, it is necessary to qualify the reference with the type of the variable pointed at. Otherwise the same restric- tions as above hold. Using a simple type as a field designator is equivalent to acces- sing a record with the first field having the name of the simple type. F_i_e_l_d_ _d_e_s_i_g_n_a_t_i_o_n_ is a displacement relative to a base position. I_n_d_e_x_i_n_g_ is, in the simple case treated in this section, perfor- med without multiplication. Instead 0 (short, pshort), 1 (inte- ger) or 3 (long, real) address modify instructions are used. 8_._3_._2_ _ _ _ _ _S_t_r_u_c_t_u_r_e_d_ _A_r_r_a_y_ _V_a_r_i_a_b_l_e_s_._ 8.3.2 Directly referencing of components of records in arrays is exclu- ded in the sense of sec. 8.3.1 due to the fact that such access would require a double register for computing the address of a component. To be able to reference components of the record one must get the address of the record into a register or variable, and then use this as a basis for further addressing. structured element' ::= array variable identifier' variable field base' array field identifier' UUU(general index')DDD general index' ::= operand' \f E_x_a_m_p_l_e_:_ w01:- modekind(i); ... w1(mk).modekind...; Note that a long register is needed to compute the address of the structured element, because the computation from logical index to address requires a multiplication. \f 9_._ _ _ _ _ _ _ _ _E_X_P_R_E_S_S_I_O_N_S_._ 9. In SPL all operations performed on data are based on the concept of expressions. In the RC8000 all basic operations involve at least one of the four working registers. To facilitate code opti- mization, SPL expressions explicitly state the working registers involved. 9_._1_ _ _ _ _ _ _ _R_e_g_i_s_t_e_r_s_._ 9.1 The RC8000 contain 4 general working registers (usually denoted w0, w1, w2, w3). These registers are of 24 bits each (the word lenght) and may be used for integer or bit pattern operations. The same four working registers may be used for 48 bit integer operations (longs) or 48 bits floating point operations (reals). When used for 48 bit operations, two registers are concatenated. The exception register is a status register and it may only be used for load, store and test operations (:= , -' and dis- joints). \f integer register' register' ::= long register' real register' exception register' w0 integer register' ::= w1 w2 w3 w01 long register' ::= w12 w23 w30 f01 real register' ::= f12 f23 f30 exception register' ::= ex 9_._2_ _ _ _ _ _ _ _O_p_e_r_a_t_o_r_s_._ 9.2 The operators of SPL define the basic operations that may be per- formed. SPL operators are closely related to the instruction set of the RC8000. The instructions belong to one of the following three groups: 1. monadic instructions operating on working registers only. \f 2. dyadic instructions operating on a register and a memory loca- tion, leaving the result in a register. 3. test instructions comparing a register to the contents of a memory location, These three groups of instructions are reflected by three groups of operators: 1. monadic operators. 2. dyadic operators. 3. relational operators. 9_._2_._1_ _ _ _ _ _M_o_n_a_d_i_c_ _O_p_e_r_a_t_o_r_s_._ 9.2.1 The monadic operators affect one working register, only (an integer register or a concatenated pair of registers forming a real register or a long register). + - monadic operator' ::= round float extend The monadic operators all denote arithmetic operations. The in- terpretation is: \f + leave register unchanged - invert sign round convert real to integer float convert integer to real extend extend integer to long (extend sign) The table below shows the the type conventions for monadic opera- tors. In each entry is listed the result type (of the register) after the operation. An empty entry indicates that the operator does not work on the actual register type. Register type before operation operator integer long real + integer long real - integer real round integer float real extend long \f The instructions used to implement the monadic operators are: Register type before operation operator integer long real + no inst. no inst. no inst. - ac fm -1.0 round cf float ci extend el+el0_U_U_5_*)0_D_D_5_ U_U_*)D_D_extend w01 is executed by: el w0 2 el w0 0 9_._2_._2_ _ _ _ _ _D_y_a_d_i_c_ _O_p_e_r_a_t_o_r_s_._ 9.2.2 The dyadic operators are seperated into two groups: - dyadic operators leaving the type of the register unaffected ("noconversion dyadic operators"). - dyadic operators changing the type of the register during the operation. \f dyadic operator' ::= 0_U_U_5_noconversion dyadic operator'0_D_D_5_ 0_U_U_5_multiply or divide operator'0_D_D_5_ + - and or U_U_noconversion dyadic operator' ::=0_D_D_5_ xor ashift lshift extract multiply or divide operator' ::= 0_U_U_U_*D_D_D_D_D_D_/U_U_U_5_ The operators +, -, * and / have their usual meaning denoting arithmetic computations. The rest of the operations denote bit pattern operations like this: and boolean operation "and" performed at each bit posi- tion. or boolean operation "or" performed at each bit position. xor boolean operation "exclusive or" performed at each bit position. ashift shifts the register contents. When shifting to the right, the sign bit is replicated. \f lshift shifts the register contents. When shifting to the right, zeroes are generated at the left. extract clears all bit positions except the number of bits at the right, as specified by the operand. In the table below is listed all legal combinations of dyadic operator, register type and operand type. For each combination is listed the result type (register type) after the operation. \f 6 operator register type operand type result type integer integer/short integer 0_U_U_+D_D_D_D_-U_U_5_ long long long real real real and integer integer integer or long long long xor ashift integer integer/ integer short constant lshift long integer/ long short constant extract integer short constant integer long short constant long * integer (w) integer long (wpre, w) real real real / long(wre, w) integer integer (wpre) integer (w) real real real (after dividing a long register by an integer, the quotient re- sides in w, while the remainder resides in wpre). \f The instructions used to implement the dyadic operators are: operator short integer long real + ea wa aa fa - es ws ss fs and la la+la or lo lo+lo xor lx lx+lx ashift as ad lshift ls ld extract la la(+al 0) * wm fm / wd fd 9_._2_._3_ _ _ _ _ _R_e_l_a_t_i_o_n_a_l_ _O_p_e_r_a_t_o_r_s_._ 9.2.3 The relational operators all compare an integer register with an operand. The operand must be an integer or a short constant con- taining an integer value or a bit pattern. ' = ' relational operators' ::= = '= includes disjoints The operators ', , =, ', = and '= have their usual meaning: greater, less, equal, unequal, less or equal, greater or equal.\f These operators all concern integer values. The operators "includes" and "disjoints" concern bit patterns and they operate like this: includes is true when at every bit position the register bit is 1, if the corresponding operand bit is 1. ("register" or "operand" = "register") disjoints is true when at every bit position the register bit is 0, if the operand bit is 1. ("register" and "operand" = 0) The instructions used to implement the relational operators are: Operator instruction(s) ' sh sl = se ' sn = sh+jl '= sl+jl includes so disjoint sz (or sx) When used in logical expressions, the code generated may be changed by appending or removing "jl" instructions. \f 9_._3_ _ _ _ _ _ _ _O_p_e_r_a_n_d_s_._ 9.3 An operand represents a numerical value or a bit pattern. An ope- rand is the basic entity of SPL that may be subject to opera- tions. register operand' operand' ::= constant' variable' register operand' ::= 0_U_U_5_register'0_D_D_5_ 0_U_U_5_(register expression')DD E_x_a_m_p_l_e_s_:_ Register operands: w0 (f23:= 3.1416) constants: 29 size(iomessbuf) 1.3e-7 newline variables: i message.io.operation w2(iomessbuf).io.operation w1.long table(w2) \f An operand may represent a numerical value or a bit pattern, de- pending on the kind of the operand. - in case of a register operand, the value resides in a register. When the operand is a register expression surrounded by paran- thesis, the expression is evaluated before using the register contents as an operand. - in case of a constant, the value is explicitly stated as an o- perand (3.1416); it is explicitly stated in the constant defi- nition part (newline = 10) or it is implicitly stated (the size of the record "iomessbuf"). - in case of a variable, the value resides in a memory location pointed out by the variable. 9_._4_ _ _ _ _ _ _ _R_e_g_i_s_t_e_r_ _E_x_p_r_e_s_s_i_o_n_s_._ 9.4 A register expression is a rule for computing a numerical value or a bit pattern leaving the result in a working register. A re- gister expression describes the computation by means of regis- ters, operators and operands. As any numerical or bit computation performed on the RC8000 ope- rates on working registers, the register expression is the base of any SPL algorithm. \f register expression' ::= simple expression' multiply or divide expression' address expression' monadic operator' registeroperand' simple expression' ::= register' := operand' 0_U_U_1D_D_D_D_0U_U_5_ simple expression' noconversion dyadic operator' operand' multiply or divide expression' ::= register' := operand' 0_U_U_1D_D_D_D_0U_U_5_ multiply or divide operator' operand' address expression' ::= structured element' register' 0_U_U_5_:-0_D_D_5_ text constant' 0_U_U_5_:--0_D_D_5_ variable' address expression' noconversion dyadic operator' operand' E_x_a_m_p_l_e_s_:_ Simple expressions. w0 + alfa w1:= tail.shortclock - starttime \f Multiply or divide expressions. w01 * alfa f01 / 3.1416 w23:= tail.shortclock/unitsperday Address expressions. w1:- "some string10'" w1:-- "some string10'" w12:-- datapage (incarnation) + reladdress w3:- tail.document Expressions including monadic operations. round f01 - (w1 + alfa - beta) extend w01 A register expression describes computations by means of regis- ters, operators and operands. These entities are build together according to the syntax description. The result of a register expression is left in a register. All dyadic operators used in register expressions (+, -, and, or, xor, ashift, lshift, ex- tract, * and /) are of equal priority, hence all operations are executed strictly from left to right (including the register as- signments denoted by ":=", ":-" and ":--"). Register expressions surrounded by paranthesis are always evaluated before use. A s_i_m_p_l_e_ _e_x_p_r_e_s_s_i_o_n_ describes a series of operations computing a numeric value or a bit pattern in a given register. The type of the register remains unchanged throughout the expression. The register assignment, denoted by ":=" loads the value of an operand into a register. \f code examples: w0 + alfa wa w0 alfa w1:= tail.shortclock - starttime rl w1 tail.shortclock ws w1 starttime A m_u_l_t_i_p_l_y_ _o_r_ _d_i_v_i_d_e_ _e_x_p_r_e_s_s_i_o_n_ contains a multiplication or a division, eventually preceded by a register assignment. A multi- ply or divide expression may change the type of the register(s) involved. code examples: w01 * alfa wm w1 alfa f01/3.1416 fd w1 xx . . . xx: 3.1416 w23:= tail.shortclock/unitsperday rl w3 tail.shortclock load and el w2 6 extend el w2 4 wd w3 unitsperday \f An a_d_d_r_e_s_s_ _e_x_p_r_e_s_s_i_o_n_ describes some sort of address computation. An address expression always starts by loading an absolute or a virtual address into a register and then continues with simple operations (preserving the type of the register). The address assignments denoted by ":-" and ":--" load the abso- lute respectively the virtual address of an object into the re- gister. (Virtualization and addressing methods are described in detail in chapter 13). Code examples: w1:- "some string10'" al w1 xx . . . xx: "some string10'" w1:-- "some string10'" rl w1 yy . . . yy: virtual address (zz) . . . zz: "some string10'" w1:- tail.document al w1 tail.document \f w12:-- datapage (incarnation) + reladdress rl w2 incarnation wm w2 size (page) wa w2 xx wa w2 reladdress . . . xx: virtual address (datapage (0)) Expressions including monadic operations. Code examples: round f1 cf w1 - (w1 + alfa - beta) wa w1 alfa ws w1 beta ac w1 x1 extend w01 el w0 2 el w0 0 9_._5_ _ _ _ _ _ _ _R_e_l_a_t_i_o_n_a_l_ _E_x_p_r_e_s_s_i_o_n_s_._ 9.5 A relational expression is a rule for combining a series of rela- tions. Each relation holds the value "true" or "false" and the result of the relational expression is "true" or "false". A rela- tion is the comparison of a register value to an operand value. \f relational expression' ::= relational term' lor relational term' 0_U_U_*D_D_D_D_0U_U_5_ relational term' ::= relation' land relation' 0_U_U_*D_D_D_D_0U_U_5_ relation' ::= register expression' register expression'relational operator' 1 operand' not 0 ( relational expression' ) E_x_a_m_p_l_e_s_:_ Relations: w1+i ' alfa w1 and mask includes w2 or pattern not w3 limit Relational terms: w1+i ' alfa land w3 = 0 w1+i ' alfa land not w3 limit Relational expressions: w1 ' alfa lor w3 = 0 w1 = beta lor w1+i ' alfa land not w3 limit \f The result of a relational expression is computed by the opera- tors "lor" (logical or), "land" (logical and) and "not". The relations are evaluated by combinations of tests and branch- ing. As it appears from the syntax, the operators are of different precedences: first: "not" second: "land" third: "lor" Code examples: w1 ' alfa sh w1 alfa jl false true: - w1 and mask includes w2 or pattern la w1 mask lo w2 pattern so w1 x2 jl false true: - not w3 limit sl w3 limit jl true jl false true: - \f w1 ' alfa land w3 = 0 sh w1 alfa jl false se w3 0 jl false true: - w1 ' alfa lor w3 = 0 sh w1 alfa jl xx jl true xx: se w3 0 jl false true: - w1 = beta lor w1+i ' alfa land not w3 limit se w1 beta jl yy jl true yy: wa w1 i sh w1 alfa jl false sl w3 limit jl true jl false true: - As it appears from the code examples, the evaluation of relatio- nal expressions implies that some of the register expressions in- volved will be skipped depending on the values of other relations in the expression. In the last example above for instance, the register expression "w1+i" will not be executed when "w1 = beta". \f Consequently the contents of registers involved in register ex- pressions within a relational expression should be used with ex- treme care at exit from the relational expression. \f 1_0_._ _ _ _ _ _ _ _P_R_O_C_E_D_U_R_E_ _A_N_D_ _R_E_G_I_O_N_ _D_E_C_L_A_R_A_T_I_O_N_._ 10. The procedure declaration part consists of declarations of proce- dures. One or more procedures may constitute a region. In connec- tion with declaration of a procedure or region the storage type may be specified. procedure declaration part' ::= section specification' 0_U_U_1D_D_D_D_0U_U_5_ procedure or region' 0_U_U_*D_D_D_D_0U_U_5_ D_D_procedure or region' ::=U_U_ procedure declaration' region declaration' The storage type may be resident or virtual and specifies the al- location of code and the default allocation of variables. 1_0_._1_ _ _ _ _ _ _R_e_g_i_o_n_ _D_e_c_l_a_r_a_t_i_o_n_._ 10.1 region declaration' ::= region constant definition part' type definition part' variable declaration part' initialization part' procedure declaration part' end \f A region consists of definition of constants and types, declara- tion and initialization of variables and declaration of one or more procedures or regions. The scope of the identifiers in- troduced in the constant or type definition part or variable de- claration part is the region, while the scope of the procedure identifiers introduced in the procedure declaration part is the block, in which the region is a part. A region may be used to define variables and operations on them. The following region declaration defines a stack with some opera- tions on it. The stack is not accessible outside the region. region const stacklenght = ...; type stacktype = array 1.. stacklenght of integer; var stack: stacktype; top: integer; procedure init _stack (return w3); begin *initialize stack to empty*' w3 -' top; w3:= 1 -' top end procedure push (return w3; w0); begin *push the content of w0 on the stack*' w3 -' top; w0 -' stack (w3); w3+1 -' top end \f procedure pop (return w3; w0); begin *pop the content of the stack to w0*' w3 -' top w0:= stack (w3-1); w3 -' top end end *region*' 1_0_._2_ _ _ _ _ _ _P_r_o_c_e_d_u_r_e_ _D_e_c_l_a_r_a_t_i_o_n_._ 10.2 Procedure declarations serve to define parts of programs and to associate identifiers with them so that they can be activated by procedure statements. procedure declaration' ::= procedure heading' block' semi' procedure heading' ::= procedure procedure identifier'(formal param list')semi' formal param list' ::= formal param' ; formal param' 0_U_U_*D_D_D_D_0U_U_5_ formal param' ::= return register' param register register' , register' 0_U_U_*D_D_D_D_0U_U_5_ ref param identifier' , param id.' 0_U_U_*D_D_D_D_0U_U_5_ : type' value \f E_x_a_m_p_l_e_s_:_ const c = ...; type atype = array 1..c of integer; procedure sort(return w3; value n: integer; ref a: atype); *this procedure sorts an integer array by straight selection method at call: n number of elements a array to be sorted *' var sw0l, sw23: long; ar: integer; begin w01 -' sw01; w23 -' sw23; w0:= w3.a -' ar; w2:= w3.n; with ar: atype do for w3:= 1 step 1 until w2 do for w1:= w3+1 step 1 until w2 do if w0:= ar(w1) ' ar(w3) then begin w0 -' ar(w3); w0 -' ar(w1) end; w01:= sw01; w23:= sw23 end \f const low = ...; high = ...; type element _type = record key: integer; . . . end; structure = array low..high of element _type; procedure bin _search (return w3; w0, wl; param w2; ref arr: structure); * search an array by binary search at call: w0 key arr array to be searched at return: w1 0 element not found '0 index for element *' var sw3, struc: integer; sw23: long; begin w3 -' sw3; w2:= w2.arr -' struc; w1:= low -' a; w1:= high + 1 -' b repeat w1:= a+b ashift 1; w23:- struc (structure)(w1); w2:= w3 (element _type).key; if w2 = w0 then goto fin; if w2 ' w0 then w1 -' b else w1+1 -' a until w0:= a = b; w1:= -1; fin: w0:= sw0; w23:= sw23; end; \f A procedure declaration consists of a block and a heading defi- ning the name of the procedure and the name of the parameters which can be used inside the block. No identifier may appear more than once in the formal parameter list. A procedure may be activated from other parts of the block, in which the procedure declaration appears. A formal parameter is of one of the following types: return specifies the register used as link register in the jump to the procedure. This parameter m_u_s_t_ be part of the parameter list. param specifies the allocation of the activation record con- taining the actual value and ref parameters. If not in the parameter list, the activation record is allocated after each call. The parameter m_u_s_t_ occur before any value or ref parameter in the parameter list. register specifies the register which is used for exchanging values between call and procedure. value specifies names of fields in the activation record. When the procedure is called, the field corresponding to a value parameter will contain the value of an ex- pression or variable. The value parameters must be of simple type. ref specifies names of fields in the activation record. When the procedure is called, the field corresponding to a ref parameter will contain the address of a vari- able of simple or structured type. \f A_c_t_i_v_a_t_i_o_n_ _r_e_c_o_r_d_ Together with a procedure declaration is defined a record type, with the same name as the procedure and fields corresponding to the formal parameters of reference or value type. To each formal parameter of value type corresponds a field in the record with the same type and the same name. To each parameter of reference type corresponds an integer field in the record with the name of the formal parameter. The activation record corresponding to the procedure heading procedure pop (return w3; value r: real; value i, j: integer; ref a, b: rtype) is equivalent to the following record type definition pop = record r: real; i, j: integer; a, b: integer; end; In the block of the procedure the formal parameters of ref or value type, are referenced by using return register or param register if present, pointing to the activation record, and in the block of the procedure this register is qualified with the activation record type. \f E_x_a_m_p_l_e_s_:_ In a procedure with the following heading procedure pop (return w3; value i, j: integer; ref a, b; rtype); The formal parameters are referenced by w3.i value of an expression or variable w3.a the address of a variable of type rtype. \f 1_1_._ _ _ _ _ _ _ _S_T_A_T_E_M_E_N_T_S_._ 11. Statements are the units of operations within SPL, and they will normally be executed consequtively as written. The sequence of operation may be broken by go to statements, which define their successor explicitly. Conditional statements may cause certain statements to be skipped, and repetitive statements may cause certain statements to be repeated. Statements may be prefixed by a label which can be referenced by go to statements. statement' ::= 1 simple statement' label identifier': 0 structured statement' 1_1_._1_ _ _ _ _ _ _S_i_m_p_l_e_ _S_t_a_t_e_m_e_n_t_s_._ 11.1 A simple statement is a statement of wich no part constitutes another statement. The empty statement constitutes of no symbols and denotes no action. \f simple statement' ::= assignment statement' register expression' goto statement' procedure statement' execute statement' monitor statement' pager statement' empty statement' empty statement' ::= empty' 1_1_._1_._1_ _ _ _ _A_s_s_i_g_n_m_e_n_t_ _S_t_a_t_e_m_e_n_t_s_._ 11.1.1 The assignment statement serves to replace, or exchange, the current value of a location with the value of a register, speci- fied by a register expression. assignment' assignment statement' ::= exchange' assignment' ::= register expression' -' variable' The current value of the variable is replaced by the value of the register given by register expression. The register and the vari- able must be of identical type. \f exchange' ::= register expression' -' variable' The current value of the variable is exchanged by the value of the register given by register expression. The register and the variable must be of integer type. E_x_a_m_p_l_e_s_:_ w12 -' d w2:= a+2 -' a w1+5 -' x 1_1_._1_._2_ _ _ _ _G_o_t_o_ _S_t_a_t_e_m_e_n_t_._ 11.1.2 A goto statement interrupts the normal sequence of operations by defining its successor explicitly. goto statement' ::= goto label identifier' The scope of a label identifier is the block within the statement part of which it marks a statement, it is therefore not possible to jump into a procedure. E_x_a_m_p_l_e_:_ goto fin \f 1_1_._1_._3_ _ _ _ _P_r_o_c_e_d_u_r_e_ _S_t_a_t_e_m_e_n_t_._ 11.1.3 The procedure statement serves to execute the procedure denoted by the procedure identifier. procedure statement' ::= procedure identifier'(actual' ,actual' 0_U_U_*D_D_D_D_0U_U_5_) register expression' actual' ::= operand' virtual' 0_U_U_1D_D_5_ resident' 0_D_D_0U_U_U_U_5_register'D_D_ The procedure statement contains a list of actual parameters which must correspond to the list of formal parameters defined in the procedure declaration. The correspondence is established by the position of the parameter in the list of actual and formal parameters respectively. Five kinds of parameters exist: return parameter, param parameter, register parameter, ref parameter, and value parameter. If formal parameter is a return parameter, the actual parameter must be a register (link register) and the same as the formal parameter. The register may be prefixed by resident or virtual with the meanings given in sec. 14. At return from a procedure , the link register must be unchanged. If formal parameter is a param parameter, the actual parameter must be a register expression with the register given in the formal parameter. The value must be the address of datastruc-\f ture where the activation record can be allocated. If formal parameter is a register, then the actual parameter must be a register expression with the value in the register given in the formal parameter. If formal parameter is a ref parameter, the actual parameter must be a variable with the type given in the formal parameter. When the procedure is called, the field in the activation record named by the formal reference parameter will contain the address of the variable. If formal parameter is a value parameter, the actual parameter must be a register expression or an operand. The type of the re- gister expression or operand must be as given in the formal para- meter. When the procedure is called, the field in the activation record named by the formal value parameter will contain the value of the expression or the operand. E_x_a_m_p_l_e_s_:_ sort(w3, 100, numbers) put(w1, w2:- head, w3) binsearch(a, w0:= 25, w1, w2:= cur, w3) 1_1_._1_._5_ _ _ _ _E_x_e_c_u_t_e_ _S_t_a_t_e_m_e_n_t_._ 11.1.5 The execute statement serves to generate RC8000 instructions, which no other SPL statement is able to generate. \f execute statement' ::= execute mnemo' register' 0_U_U_1D_D_D_D_0U_U_5_ * 0_U_U_1D_D_D_D_0U_U_5_ operand' mnemo' ::= Any mnemonic code of the RC8000 instruction set (ref. 2). The execute statement generates one instruction with the F field given by mnemo, and the w field given by register, which must be an integer register. Addressing of the operand is explained in sec. 14. The instruction may be preceded by one or more address modify instructions depending on the operand used. It is possible to set the indirect modification bit in the instruction equal one, to force indirect addressing regardless of the operand. E_x_a_m_p_l_e_s_:_ execute ks -5 execute jl w3 *proc 1_1_._1_._6_ _ _ _ _M_o_n_i_t_o_r_ _S_t_a_t_e_m_e_n_t_._ 11.1.6 The monitor statement serves to call a RC8000 monitor procedure. These procedures are described in ref. 3. monitor statement' ::= monitor (constant' , register expression' 0_U_U_*D_D_D_D_0U_U_5_) \f where constant' gives the number of the procedure to be called. The number of register expressions are dependent of the value of the constant. E_x_a_m_p_l_e_:_ monitor (16, w1:- mes, w2, w3:- name) is equivalent to al w1 mes al w3 name jd 111+16 1_1_._1_._7_ _ _ _ _P_a_g_e_r_ _S_t_a_t_e_m_e_n_t_s_._ 11.1.7 The pager statement serves to call a procedure in the pagersys- tem. These procedures are described in ref. 4. pager statement' ::= pager (constant' , register expression' 0_U_U_*D_D_D_D_0U_U_5_) where constant' gives the number of the procedure to be called. The number of register expressions are dependent of the value of the constant. \f 1_1_._2_ _ _ _ _ _ _S_t_r_u_c_t_u_r_e_d_ _S_t_a_t_e_m_e_n_t_s_._ 11.2 Structured statements are constructs composed of other state- ments, which have to be executed eather in sequence, conditional- ly or repeatedly. structured statement' ::= compound statement' conditional statement' repetitive statement' with statement' 1_1_._2_._1_ _ _ _ _C_o_m_p_o_u_n_d_ _S_t_a_t_e_m_e_n_t_._ 11.2.1 The compound statement specifies that its components are to be executed in the same sequence as they are written. The symbols begin and end act as statement brackets. compund statement' ::= begin statement' ;statement' 0_U_U_*D_D_D_D_0U_U_5_ end E_x_a_m_p_l_e_:_ begin w1:= a; w2:= b -' a; w1 -' b end \f 1_1_._2_._2_ _ _ _ _C_o_n_d_i_t_i_o_n_a_l_ _S_t_a_t_e_m_e_n_t_s_._ 11.2.2 A conditional statement selects for execution a single one of its component statements. conditional statement' ::= if statement' case statement' 1_1_._2_._2_._1_ _ _I_f_ _S_t_a_t_e_m_e_n_t_._ 11.2.2.3 The if statement specifies that a statement is to be executed only if a certain relational expression is true. If it is false then either no statement is to be executed or the statement following else is to be executed. if statement' ::= if relational expression' then statement' else statement' 0UU1DDDD0UU5 The syntactic ambiguity arising from the construction if rel.exp.1' then if rel.exp.2' then statement 1' else statement 2' is resolved by interpreting the construction as: \f if rel.exp.1' then begin if rel.exp.2' then statement 1' else statement 2' end; E_x_a_m_p_l_e_s_:_ if w1 0 then -w1 if w1:= a ' b then w1 - b else w1 + b 1_1_._2_._2_._2_ _ _C_a_s_e_ _S_t_a_t_e_m_e_n_t_._11.2.2.2 The case statement consists of a register expression and a list of statements, each being labelled by one or more constants. It specifies that the one statement will be executed, whose label is equal to the value of the register expression. If no such statement exists, the default statement following else is to be executed. If >end> is not followed by >else statement>, the default statement is regarded as empty. case statement' ::= case register expression' of begin case element' semi' case element' 0UU*DDDD0UU5 end else statement' 0_U_U_1D_D_D_D_0U_U_5_ case element' ::= constant expression' ,constant expression' 0_U_U_*D_D_D_D_0U_U_5_ : statement' \f The case statement is implemented as a jump table, with one entry corresponding to each value between the lowest value of the constant expression and the highest. E_x_a_m_p_l_e_:_ case w1 of begin 3,5: w3:= (w2+2).integer; 2,4: w3:= w2+10; 6: w3:= 1 end else w3:= 0; 1_1_._2_._3_ _ _ _ _R_e_p_e_t_i_t_i_v_e_ _S_t_a_t_e_m_e_n_t_s_._ 11.2.3 Repetitive statements specify that certain statements are to be executed repeatedly. repetitive statement' ::= for statement' while statement' repeat statement' loop statement' 1_1_._2_._3_._1_ _ _F_o_r_ _S_t_a_t_e_m_e_n_t_._ 11.2.3.1 The for statement indicates that a statement is to be repeadetly executed while a register is assigned increasing or decreasing values. \f for statement' ::= for register expression' step constantexpression' until operand' do statement' The operand, constant expression and the register holding the value of the register expression must be of integer types and the value of the register should not be changed by the statement. The for statement. for reg.exp step c.exp until op do statement is equivalent to the statements: if c.exp ' 0 and w is the register holding the value of reg.exp: reg.exp l1: if w ' op then goto l2 statement w:= w + c.exp; goto l1; l2: and if c.exp 0: reg.exp l1: if w op then goto l2; statement; w:= w + c.exp; goto l1; l2: \f E_x_a_m_p_l_e_s_:_ for w1:= 32 step 1 until 127 do w2:= 6 ashift 12 + w1 -' tab (w1) 1_1_._2_._3_._2_ _ _W_h_i_l_e_ _S_t_a_t_e_m_e_n_t_._ 11.2.3.2 The while statement indicates that a statement is to be repeated- ly executed while the result of a relational expression is true. while statement' ::= while relational expression' do statement' If the value of the relational expression is false at the beginning, the statement is not executed at all. E_x_a_m_p_l_e_s_:_ while w1:= a(w2:=i) ' u do w2+1 -' i while w1 ' 0 do begin extend w01; w01/2; if w1 extract 1 = 1 then w0:= bits+1 -' bits end \f 1_1_._2_._3_._3_ _ _R_e_p_e_a_t_ _S_t_a_t_e_m_e_n_t_._ 11.2.3.3 The repeat statement indicates that a sequence of statements is to be repeatedly executed until a relational expression becomes true. repeat statement' ::= repeat statement' semi' statement' 0_U_U_*D_D_D_D_0U_U_5_ until relational expression' the statement is executed at least once no matter the value of the relational expression at the beginning. E_x_a_m_p_l_e_:_ repeat w2:= a(w1); w1+1 -' i until w2 = 0 1_1_._2_._3_._4_ _ _L_o_o_p_ _S_t_a_t_e_m_e_n_t_._ 11.2.3.4 The loop statement indicates that a sequence of statements are to be executed repeatedly until a relational expression becomes true loop statement' ::= loop statement'semi' 0_U_U_*D_D_D_D_0U_U_5_ exit' semi'statement' 0_U_U_*D_D_D_D_0U_U_5_ endloop exit' ::= exit if relational expression' \f The sequence of statements between loop and exit is executed at least once. E_x_a_m_p_l_e_s_:_ loop w1:= a+b; extend w01; w01/2; exit if w0:= a(w1) = u; if w0:= a(w1) ' u then w1 -' b else w1+1 -' i endloop 1_1_._2_._4_ _ _ _ _W_i_t_h_ _S_t_a_t_e_m_e_n_t_._ 11.2.4 The with statement qualifies registers and/or variables to be pointers to a given type. with statement' ::= with type assignment' , type assignment' 0_U_U_*D_D_D_D_0U_U_5_ do statement' type assignment' ::= register' variable identifier' UU: type'DD Within the statement of the with statement the registers and/or variables, which must be of integer type, are qualified to be pointers to the specified types, which means that elements or fields may be selected without specifying the type. \f E_x_a_m_p_l_e_:_ with h:head, w1:element do begin w1:= h.first; w3:= w1.next -' h.first end is equivalent to w1:= h(head).first; w3:= w1(element).next -' h(head).first \f 1_2_._ _ _ _ _ _ _ _E_X_T_E_R_N_A_L_ _R_E_F_E_R_E_N_C_E_S_ _A_N_D_ _D_E_F_I_N_I_T_I_O_N_S_._ 12. Program modules written in SPL may be used as part of a composed program possibly including modules written in other languages. As each module may be translated individually, there is a need for exchanging information between modules (procedures or varia- bles defined in one module may be accessed from other modules). Any object that is going to be used outside its own module must explicitly be exported by a define statement as well as any ob- ject defined in foreign modules must explicitly be imported by reference statement before use. external part' ::= external reference part' external secondary reference part' external definition part' external reference part' ::= ref reference' semi' 0_U_U_*D_D_D_D_1U_U_5_ 0_U_U_1D_D_D_D_0U_U_5_ external secondary reference part' ::= sref reference' semi' 0_U_U_*D_D_D_D_1U_U_5_ 0_U_U_1D_D_D_D_0U_U_5_ reference' ::= variable identifier' , variable identifier' 0_U_U_*D_D_D_D_0U_U_5_ : type' procedure procedure identifier' (formal parameter' , formal parameter' 0_U_U_*D_D_D_D_0U_U_5_) \f external definition part' ::= def identifier' , identifier' 0_U_U_*D_D_D_D_0U_U_5_ semi; UU1DDDD0UU E_x_a_m_p_l_e_s_:_ ref userbase: long; currin: zone; procedure sine (return w3; f01); def cosine, tangens; A_n_y_ _o_b_j_e_c_t_ exchanged via ref, sref and def i_s_ _d_e_f_i_n_e_d_ _b_y_ _i_t_s_ a_d_d_r_e_s_s_ within the address space of the program (i.e. no descrip- tion of the object will be exchanged). Thus it is up to the user to make sure that the external objects, he refers to, are of the right kind (procedure, record etc.) and type (long, integer etc.). To facilitate a natural use, a reference to an external object is combined with a local declaration of the object. This declaration defines the use of the object in an SPL milieu and solves the problem of using in one language an object defined in some other language. The solution, however, does not contain full security as the correspondence between definition and use is not checked. \f 1_3_._ _ _ _ _ _ _ _S_C_O_P_E_ _R_U_L_E_S_._ 13. A scope is a part of a program text in which an identifier is used with a single meaning. A scope is either a block or a region. Constant, type, variable and procedure identifiers are introduced by declaration and label identifiers by marking a statement. Procedures and regions may be nested which leads to a hierachy of scopes. When a scope is defined within another scope, there are an outer scope and an inner scope which are nested. An identifier can only be introduced with one meaning in a scope. It can, however, be introduced with another meaning in an inner scope. In that case, the inner meaning applies in the inner scope and the other meaning applies in the outer scope. All identifiers introduced in a block has the block as scope. All constant, type and variable identifiers introduced in a re- gion, has the region as scope, while the scope of the procedure identifiers introduced in a region is the block, in which the region is a part. In a block or region, all identifiers introduced in that scope and all identifiers introduced in an outer scope may be used. \f 1_4_._ _ _ _ _ _ _ _C_O_R_E_ _L_A_Y_O_U_T_ _A_N_D_ _A_D_D_R_E_S_S_I_N_G_ _T_E_C_H_N_I_Q_U_E_S_._ 14. SPL programs are executed in an environment that supports program and data virtualization. An SPL program may contain both resident and virtual sections and the underlying system includes the code and tables that are y necessary for handling the virtualization. The core layout of the environment in which SPL programs are exe- cuted may be outlined like this: \f \f The addressing techniques used in SPL are mainly determined by 0 the addressing facilities of the RC8000 hardware and the under- lying paging system. - absolute addressing the location is referenced by its position relative to the start of memory (= 0). - relative addressing the location is referenced by its position relative to the in- struction counter (current position in program). - index addressing the location is referenced by its position relative to the con- tents of an index register (w1, w2 or w3). (The index register contains an absolute or a virtual address). - indirect addressing the location is referenced by the contents of a word in memory containing an absolute or a virtual address. The word containing the reference may be addressed by one of the former addressing techniques. More complicated addressing schemes may be build up using the "address modification" facility of the RC8000 (see ref. 2). The convention in SPL never to modify registers except when the programmer explicitly states so, implies that several kinds of object addressing are realized by using the address modification facility, combining a series of addressing components. When, at some program points an object is addressed, the addres- sing technique depends on the relative position of the program point and the object. \f Objects may belong to the address space of the program (labels, procedures and variables in a "var part") or they may be referen- ced by user controlled addresses (e.g. data in a user controlled stack or heap). User controlled addresses are assumed to be abso- lute or virtual. In SPL the allocation of variables or the subdivision of programs into program sections (resident or virtual) enables the program- mer to control the addressing techniques to a very high degree. When addressing objects within the address space of a program the following rules apply: 1. Short local when the object and the referring code are both situated on the same section (resident or virtual) with an interval of less than 2048 halfwords, the object is addresses by relative addressing. 2. Long local when the object and the referring code are situated on the sa- me section with an interval of at least 2048 halfwords, an ex- tended relative addressing scheme is used. 3. Resident when the object is situated on a resident section different from the section (resident or virtual) on which the code is situated, the object is addressed by indirect addressing via a reference point. 4. Virtual when the object is situated on a virtual section different from the section (resident or virtual) on which the code is situated, the object is addressed using indirect addressing in two levels (via a reference point and the page table). \f In the following is shown some examples of addressing techniques used in SPL. The examples use the types defined in chapter 7. The examples concern references to a record "iomessbuf" allocated at runtime, and references to variables of a "var-part" like this: var i, bufferref: integer; arr: row; "i" is a simple variable "bufferref" is an integer variable containing the absolute address of an instance of the record "iomessbuf" "arr" is an integer array (Note that arrays are primarily referenced by the first elements allocated - not by the "zero element"). The following notations are used in the examples: * indirect addressing p(label) page table entry (label) d(label) segment relative address (label) r(field) record relative address (field) first logical no. of first element in an array The examples are mainly intended for illustrating the differences between the addressing techniques used. Each table concerns a specific example of object addressing. In the table is shown the code generated according to the relative positions of object and code. \f To understand the examples fully it may be necessary to consult "A language independent programming system for RC8000" (ref. 1) and "RC8000 Macro Assembler, Reference Manual" (ref. 5). w0:= i Object code generated position Short rl w0 i local Long am *relref(i) local rl w0 relref(i) . . . relref(i): i-. Resident rl w0 *ref(i) . . . ref(i): i Virtual am *pagetabref(i) am *0 rl w0 d(i) . . . pagetabref(i): p(i) \f w0:= w2 (iomessbuf).sender Object code generated position irrelevant rl w0 x2+r(sender) The object position is irrelevant as it is up to the programmer to make sure that the object is accessible, and that w2 contains a proper pointer to it. \f w0:= bufferref(iomess).sender pointer code generated position Short am *iomessbuf local rl w0 r(sender) Long am *relref(bufferref) local am *relref(bufferref) rl w0 r(sender) . . . relref(bufferref): bufferref Virtual am *pagetabref(bufferref) am *0 am *d(bufferref) rl w0 r(bufferref) . . . pagetabref(bufferref): p(bufferref) \f w0:= arr (w3) object code generated position Short am x3-first local rl w0 x3-first+arr Long am *relref(arr) local am x3-first+relref(arr) rl w0 x3-first . . . relref(arr): arr-. Resident am *ref(arr) am x3-first rl w0 x3-first . . . ref(arr): arr Virtual am *pagetabref(arr) am *0 am x3-first rl w0 x3-first+d(arr) . . . pagetabref(arr): p(arr) \f As it appears from the examples above, SPL programs may use a wide range of addressing techniques. It is obvious too, that the effenciency of a program depends very much on the addressing technique used. It appears that the most efficient addressing techniques are re- lative addressing within a section and index addressing. Procedure calls are examples of object addressing and the add- ressing techniques used are exactly as for references to vari- ables of simple type. However, procedures introduce a new addressing problem. When re- turning from a procedure the program point immidiately following the procedure call (the return point) must be addressed. In a resident environment, a procedure simply returns by jumping to the absolute address of the link (return) register. In a vir- tual environment, however, the the return point may have disap- peared or moved to some other location, so there may be a need for a new technique. As the technique used in a resident environment is very efficient and as a given procedure may be called from both virtual and re- sident sections the convention is that procedures always return by using the address of the return register. To solve the problem of calling procedures from virtual sections (risking that the return point is moved or overwritten at return) the return register (stated as an actual parameter in the proce- dure statement) may be prefixed by "resident" or "virtual", indi- cating that special techniques are used: \f Resident: A_t_ _c_o_m_p_i_l_e_ _t_i_m_e_ is allocated a resident section (of a few words) used for addressing the return point (at return from the procedure) and for transferring possible parameters. A_t_ _c_a_l_l_ the absolute address of this resident section is loaded into the return register before calling the procedure. A_t_ _r_e_t_u_r_n_ the procedure will jump to the address specified by the return register. In this case it jumps to the resi- dent section. This section contains a piece of code that causes the jump to the return point, addressing through the page table, so that the return point will be addressed properly, no matter the position of the section containing the return point. This solution is cheap in terms of execution time, while it may be fairly expensive in terms of (resident) core space. Virtual: A_t_ _c_a_l_l_ the virtual address of the return point is loaded into the return register before calling the procedure. A_t_ _r_e_t_u_r_n_ the procedure will jump to the address specified by the return register. As this address is virtual an inter- rupt will occur, no matter the position of the section con- taining the return point. However, the interrupt will make sure that the return point is addressed properly. This solution causes an unconditional interrupt at each re- turn, slowing down the program execution. \f No prefixing: In case no prefixing is used, procedure calls and exits are always implemented like this: A_t_ _c_a_l_l_ the absolute address of the return point is loaded into the return (link) register. A_t_ _r_e_t_u_r_n_ the procedure jumps to the address specified by the return register. This solution is optimal in terms of execution time and core space, but it should only be used, when it is obvious that the section containing the return point can not be moved or overwritten before return. \f 1_5_._ _ _ _ _ _ _ _C_O_M_P_I_L_E_R_ _D_I_R_E_C_T_I_V_E_S_._ 15. Compiler directives are included in the very syntax of SPL. At the same time the semantics of compiler directives may involve elements defined outside the directives (i.e. directives are semantically integrated with other elements of the language), directive statement' ::= when directive relation' 0_U_U_1D_D_D_D_0U_U_5_ do directive' iff ift iftf endc eof directive relation' ::= constant expression' relational operator' constant expression' compile liston listoff directive' ::= copy filename' library filename'.subname' message text constant' \f E_x_a_m_p_l_e_s_:_ liston when option1 ' 0 do compile copy stdtypes library mylib.readprocs when option2 ' max do message "option2 too large" The compiler directives of SPL may be simple or conditioned. Con- ditions are relations comparing constant expression. The constant expression may contain named constants defined in a constant de- finition part. The interpretations of the compiler directives are: liston: the source text will be listed from the actual line on- wards. The effect of liston may be overruled by call parameters to the compiler. listoff: opposite to liston. copy: makes the compiler stop reading from the actual source text and switch to the source, stated by its name. Reading from the former source will be resumed when an EM (end medium) character or an eof directive is met. library: makes the compiler switch from the actual source to a named text portion in a named library file. eof: makes the compiler resume reading from the former source. message: makes the compiler display the text constant on current output. Like liston and listoff this directive may be overruled by a call parameter to the compiler. \f compile: is used in connection with a relation to control conditional compilation. If the relation is false the compilation will be switched off. The value of the relation may be used for a series of subdirectives. ift, iff are all subdirectives referring to the current compile iftf, directive. "ift", "iff" and "iftf" all refer to the endc value of the relation connected to this: ift: compile if the relation is true. iff: compile if the relation is false. iftf: compile in any case. endc: close the current condition. Conditioned compilation may include a series of program pieces all controlled by the same relation. The example shown below is of that kind: when option1 ' 0 compile; . . alternative A, part 1 . iftf; . . is always compiled . ift; . . alternative A, part 2 . iff; . . alternative B . endc; \f A_._ _ _ _ _ _ _ _ _R_E_F_E_R_E_N_C_E_S_._ A. 1. Aino Andersen, Phillippe Gauguin, Bent Bæk Jensen: A Language Independent Programming System for RC8000. RCSL 31-D495, april 1978 2. Einar Mossin, Pierce Hazelton: RC8000 Conputer Reference Manual RCSL 31-D383, january 1976 3. Tove Ann Aris, Bo Tveden-Jørgensen: RC8000 Monitor, Part 2, reference manual. RCSL 31-D477, january 1978 4. Peter Jørgensen: 5. Philippe Gauguin: RC8000 Macro Assembler, Reference Manual (in course of preparation). \f B_._ _ _ _ _ _ _ _ _L_I_T_T_E_R_A_T_U_R_E_._ B. Niklaus Wirth: PL360, A Programming Language for the 360 Computers; JACM, january 1968, pp. 37-74. Palle Anderson, Niels Møller Jørgensen, Kaj Lauritsen: PL4000, brugervejledning (in danish) Datalogisk Institut, Københavns Universitet, november 1973. Lars Otto Kjær Nielsen: RCMOL rapport (in danish) Institut for Datateknik, DTH, july 1975. K. Jensen, Niklaus Wirth: Pascal Report, Springer Verlag, 1975. \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 1. INTRODUCTION ........................................ 1 1.1 Macro Assembly Language ....................... 1 1.2 Macro Assembler ............................... 2 2. ASSEMBLY LANGUAGE ................................... 5 2.1 Source Statement Format ....................... 5 2.1.1 Comments ............................. 6 2.1.2 Spaces and Comma ..................... 6 2.1.3 Capital Versus Small Letters ......... 6 2.1.4 Format Notation ...................... 6 2.1.5 General Format of Source Statements .. 8 2.1.6 Special Interpretation of - in Column 1 ............................. 9 2.2 Literals ...................................... 9 2.2.1 Integers ............................. 10 2.2.2 Longs ................................ 11 2.2.3 Reals ................................ 11 2.2.4 Strings .............................. 12 2.2.5 Fields and Field Comparisons ......... 13 2.3 Names ......................................... 14 2.3.1 Reserved Names ....................... 16 2.3.2 User Defined Names ................... 16 2.3.3 Global Names ......................... 16 2.3.4 Local Names .......................... 16 2.3.5 Symbols .............................. 17 2.3.6 Current Location Counter ............. 18 2.4 Expressions ................................... 18 2.4.1 Relocatability ....................... 20 2.4.2 External Symbols ..................... 20 2.4.3 Operators ............................ 21 2.5 Pool Addresses ................................ 27 2.6 Labels and Label Assignments .................. 28 2.7 Constants and Constant Assignments ............ 29 \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_C_O_N_T_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 2.8 Variables and Variable Assignments ............ 30 2.9 Blocks and Scopes ............................. 31 2.10 Sections ...................................... 32 2.10.1 Absolute Section ..................... 33 2.10.2 Resident Sections .................... 33 2.10.3 Virtual Sections ..................... 33 2.10.4 Init Section ......................... 34 2.10.5 Common Sections ...................... 34 3. INSTRUCTION STATEMENTS .............................. 35 3.1 Data and Instruction Formats .................. 35 3.1.1 Data Formats ......................... 35 3.1.2 Working Registers .................... 36 3.1.3 Instruction Format ................... 37 3.1.4 Use of Effective Address ............. 39 3.2 Instruction Statement Format .................. 40 3.3 Addressing Modes .............................. 42 3.3.1 Relative Addressing Mode ............. 42 3.3.2 Resident Addressing Mode ............. 42 3.3.3 Virtual Addressing Mode .............. 43 4. ASSEMBLY DIRECTIVE STATEMENTS ....................... 44 4.1 ASECT. Absolute Section ....................... 45 4.2 BEGIN. Begin of Block ......................... 46 4.3 BLK. Block of Words ........................... 47 4.4 BLKH. Block of Halfwords ...................... 48 4.5 COPY. Copy from Source File ................... 49 4.6 CSECT. Common Section ......................... 50 4.7 DATA. Data Generation ......................... 51 4.8 DATAH. Data Generation in Halfwords ........... 52 4.9 DECLARE. Declaration of Local Symbols ......... 53 4.10 DEF. Declaration of External Definitions ...... 54 4.11 DO. Repetition of Source Lines ................ 55 \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_C_O_N_T_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 4.12 END. End of Block ............................. 57 4.13 ENDC. End of Conditional Assembly ............. 59 4.14 EOF. End of Source File ....................... 60 4.15 ERROR. Error Message .......................... 61 4.16 FPLABEL. File Processor Label ................. 62 4.17 IF. If ........................................ 63 4.18 IFF. If False ................................. 64 4.19 IFN. If Not ................................... 65 4.20 IFT. If True .................................. 66 4.21 IFTF. If True or False ........................ 67 4.22 ISECT. Init Section ........................... 68 4.23 LISTOFF. Listing Level Decrease ............... 69 4.24 LISTON. Listing Level Increase ................ 70 4.25 LISTRDX. Listing Radix ........................ 71 4.26 LOC. Set Location Counter ..................... 72 4.27 MACRO. Macro Definition Head .................. 73 4.28 MESSAGE. Message .............................. 74 4.29 MLIB. Macro Library ........................... 75 4.30 PAGE. New Page ................................ 77 4.31 PFLABEL. Paging File Label .................... 78 4.32 POOL. Pool Generation ......................... 79 4.33 REF. Declaration of External References ....... 80 4.34 REV. Revision Number of Program ............... 81 4.35 RSECT. Resident Section ....................... 82 4.36 SREF. Declaration of Secondary External References .................................... 84 4.37 TEXT. Text Generation ......................... 85 4.38 TITLE. Title of Program ....................... 86 4.39 VSECT. Virtual Section ........................ 87 5. MACROS .............................................. 89 5.1 Macro Call Statement .......................... 89 5.2 Macro Definition Statement .................... 91 \f T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_C_O_N_T_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ 5.3 Macro Work Names .............................. 93 5.4 Macro Programming Hints ....................... 94 5.5 Macro Examples ................................ 95 5.5.1 The ZONE. Macro ...................... 95 5.5.2 The NFAK. Macro ...................... 98 5.5.3 The NDEF. Macro ...................... 101 6. ASSEMBLER PROCESSING ................................ 103 6.1 Object Code ................................... 103 6.2 Listing ....................................... 103 6.3 Assembly Message .............................. 104 6.4 Cross Reference Listing ....................... 105 6.5 Requirements and Capacities ................... 106 APPENDIX A. REFERENCES .......................................... 107 B. ASSEMBLY ALPHABET ................................... 108 C. LIST OF RESERVED NAMES .............................. 109 D. SURVEY OF LISTING LEVEL COUNTER MODIFICATIONS ....... 110 E. ERROR FLAGS ......................................... 111 F. RELOCATION MODIFIERS ON LISTING ..................... 113 G. CALL OF ASSEMBLER ................................... 114 H. MESSAGES FROM ASSEMBLER ............................. 119 I. RC8000 INSTRUCTIONS ................................. 123 J. FILE PROCESSOR ENTRIES .............................. 124 K. CONTENTS OF SYSMACLIB ............................... 126 \f H_._ _ _ _ _ _ _ _ _M_E_S_S_A_G_E_S_ _F_R_O_M_ _A_S_S_E_M_B_L_E_R_._ H. E_r_r_o_r_s_:_ (OK = no, WARNING = yes) ***macro end. no source Check parameter list. ***macro param invalid parameter' Check that parameter. ***macro end. no core Increase process size. ***macro end. no buffers no area processes Check buffer and/or area claim. ***macro end. no program on source file filename' A BEGIN. was not found on the first source file. If the first source specified is the word input, the filename in the message is a working name. ***macro end. connect filetype' filename' result' source object error message work file UUfiletype'::=DD redefinition work file pool work file virtual memory file \f no ressources malfunction not user, not exist result'::= convention error not allowed name format error not a bs file Check the environment, files, claims etc. ***macro end. backup of current input not possible, result' Check disc claims. ***macro end. too may blocklevels Blocks are nested in more than 10 levels. ***macro end. too may blocks Increase process size. ***macro end. too many sections Increase process size. ***macro end. control stack overflow Check for infinite recursion in macro calls. Increase process size. ***macro end. too many macro lines Increase process size. ***macro end. symbol table overflow Increase process size. ***macro end. operating system break Parent break 8. Usually time exceeded. \f ***macro end. hard error, impossible to continue due to: - errors in assembly program - disc ressoures missing or - assembler error In order to locate the point in the source program which causes the error, turn on listing, eventual- ly the pass1 listing, i.e. test.4. W_a_r_n_i_n_g_s_:_ (OK = yes, WARNING = yes) total number if messages from pass2: integer' The program contained errors, the number of errors is shown. O_t_h_e_r_ _M_e_s_s_a_g_e_s_:_ messages from pass no integer' Preceeds the first message from each pass. size: size' size'r size'v size'i size'c The program size in halfwords; absolute, resident, virtual, init, common, respectively. \f I_._ _ _ _ _ _ _ _ _R_C_8_0_0_0_ _I_N_S_T_R_U_C_T_I_O_N_S_._ I. Numeric MNEMO Code NAME AA 56 a_d_d_ d_o_u_b_l_e_ word to double register AC 33 a_d_d_r_e_s_s_ c_o_m_p_l_e_m_e_n_t_e_d_: load into register AD 37 a_r_i_t_h_m_e_t_i_c_ shift of d_o_u_b_l_e_ register AL 11 a_d_d_r_e_s_s_: l_o_a_d_ into register AM 9 a_d_d_r_e_s_s_: m_o_d_i_f_y_ that of next instruction AS 36 a_r_i_t_h_m_e_t_i_c_ shift of s_i_n_g_l_e_ register CF 53 c_o_n_v_e_r_t_ f_l_o_a_t_i_n_g_ point to integer CI 32 c_o_n_v_e_r_t_ i_n_t_e_g_e_r_ to floating point DI 29 d_a_t_a_ i_n_ DL 54 d_o_u_b_l_e_ register: l_o_a_d_ DO 1 d_a_t_a_ o_u_t_ DS 55 d_o_u_b_l_e_ register: s_t_o_r_e_ EA 18 e_x_t_e_n_d_e_d_ halfword: a_d_d_ to register EL 2 e_x_t_e_n_d_e_d_ halfword: l_o_a_d_ into register ES 17 e_x_t_e_n_d_e_d_ halfword: s_u_b_t_r_a_c_t_ from register FA 48 f_l_o_a_t_i_n_g_ point: a_d_d_ to double register FD 52 f_l_o_a_t_i_n_g_ point: d_i_v_i_d_e_ into double register FM 50 f_l_o_a_t_i_n_g_ point: m_u_l_t_i_p_l_y_ by double register FS 49 f_l_o_a_t_i_n_g_ point: s_u_b_t_r_a_c_t_ from double register GG 28 g_e_n_e_r_a_l_ g_e_t_ from processor register GP 47 g_e_n_e_r_a_l_ p_u_t_ into processor register HL 3 h_a_l_f_ register: l_o_a_d_ HS 26 h_a_l_f_ register: s_t_o_r_e_ JD 14 j_u_m_p_ and select d_i_s_a_b_l_e_ limit JE 15 j_u_m_p_ and select e_n_a_b_l_e_ limit JL 13 j_u_m_p_ with l_i_n_k_ in register \f I. Numeric MNEMO code NAME LA 4 l_o_g_i_c_a_l_ a_n_d_: combine word with register LD 39 l_o_g_i_c_a_l_ shift of d_o_u_b_l_e_ register LO 5 l_o_g_i_c_a_l_ o_r_: combine word with register LS 38 l_o_g_i_c_a_l_ shift of s_i_n_g_l_e_ register LX 6 l_o_g_i_c_a_l_ e_x_c_l_u_s_i_v_e_ or: combine word with register ND 35 n_o_r_m_a_l_i_z_e_ d_o_u_b_l_e_ register NS 34 n_o_r_m_a_l_i_z_e_ s_i_n_g_l_e_ register RE 22 r_e_t_u_r_n_ from e_s_c_a_p_e_ RI 12 r_e_t_u_r_n_ from i_n_t_e_r_r_u_p_t_ RL 20 r_e_g_i_s_t_e_r_: l_o_a_d_ RS 23 r_e_g_i_s_t_e_r_: s_t_o_r_e_ RX 25 r_e_g_i_s_t_e_r_: e_x_c_h_a_n_g_e_ with word SE 42 s_k_i_p_ if register e_q_u_a_l_ SH 40 s_k_i_p_ if register h_i_g_h_ SL 41 s_k_i_p_ if register l_o_w_ SN 43 s_k_i_p_ if register n_o_n_e_q_u_a_l_ SO 44 s_k_i_p_ if selected register bits all o_n_e_s_ SP 21 s_k_i_p_ if word not p_r_o_t_e_c_t_e_d_ SS 57 s_u_b_t_r_a_c_t_ d_o_u_b_l_e_ word from double register SX 46 s_k_i_p_ if selected e_x_c_e_p_t_i_o_n_ bits all zeros SZ 45 s_k_i_p_ if selected bits all z_e_r_o_s_ WA 7 w_o_r_d_: a_d_d_ to register WD 24 w_o_r_d_: d_i_v_i_d_e_ into double register WM 10 w_o_r_d_: m_u_l_t_i_p_l_y_ by register giving double register WS 8 w_o_r_d_: s_u_b_t_r_a_c_t_ from register XL 16 e_x_c_e_p_t_i_o_n_ register: l_o_a_d_ from halfword XS 27 e_x_c_e_p_t_i_o_n_ register: s_t_o_r_e_ in halfword ZL 19 z_e_r_o_-_e_x_t_e_n_d_e_d_ halfword: l_o_a_d_ into register \f J_._ _ _ _ _ _ _ _ _F_I_L_E_ _P_R_O_C_E_S_S_O_R_ _E_N_T_R_I_E_S_._ J. \f \f K_._ _ _ _ _ _ _ _ _C_O_N_T_E_N_T_S_ _O_F_ _S_Y_S_M_A_C_L_I_B_._ K. \f \f \f \f \f \f \f «eof»