DECUS PROGRAM LIBRARY DECUS NO. 10-213 T'TLE BLISS-11 AUTHOR Carnegie-Mellon University, Wulf, et al Submitted by: Stephen Lieman COMPANY Digital Equipment Corporation Maynard, Massachusetts DATE April 1974 SOURCE LANGUAGE BLISS-10 ATTENTION This is a USER program. Other than requiring that it conform to submittal and review standards, no quality control has been imposed upon this program by DECUS. The DECUS Program Library is a clearing house only; it does not generate or test programs. No warranty, express or implied, is made by the contributor, Digital Equipment Computer Users Society or Digital Equipment Corporation as to the accuracy or functioning of the program or related material, and no respnsibility is assumed by these parties in connection therewith. Bliss-11 Programmer's Manual Addenda et Corriaenda (1) Section 1.3 and Appendix A The BNF description of the syntax of simple expressions should be extended to describe the operators MAX and MIN (2) Sections 1.2, 1.9 and Appendix A Any expression may be labeled (see sections 1.17 and 1.25, Thus the proper syntax for "E" and "exprs" is: E ::= smpl-expr / cntrl-expr / label : E exprs ::= E / E ; exprs / empty (3) Section 1.17 A LEAVE may also refer to the name of the routine in which it occurs, in which it is equlvelent to a RETURN, e.g. ROUTINE R = ... ... LEAVE R WITH 3 ... ! equivalent to RETURN 3 (4) Section 1.19 Coroutine expressions are implemented, See UPDATE.DOC. (5) Sections 1.22.4 end 4.6 The EMT, TRAP, and IOT linkage types have been defined and implemented; see UPDATE.DOC. (6) Section 1.24.3 and Appendix A Register declarations like REGISTER A = n where n is 6 or 7, are illegal; Thus the proper syntax for "reg-part" is: reg-part ::= = num Also, if n is a register that has been "reserved" (see section 3.2), the variable name (in this case may A) may be addressed up-level. (7) Section 1.24.3 and Appendix A All the expressions in a size-part must be compile-time constants. (8) Sections 1.24.4, 1.24.5, and Appendix A MAP and BIND declarations may have alloc-units; these serve roughly the same purpose as in storage allocation declarations (i.e., they supply the velue of BYTES during structure expansion). (9) Section 1.28.2, footnote $REMAINING, $NAME, and $STRING are implemented, See UPDATE.DOC. (10) Section 1.28.3, footnote Macro calls may also use the bracketing pair {}. (11) Section 1.28.4 A new entry should be added to the list of contexts and default separators: 4. Preceding context: a. An operator Separator generated: the same operator (121 Section 1.36 In a REQUIRE declaration, if the entire ppnspec plus the left and right brackets are missing, the default ppn is indeed that of the controlling job, If, however, the left and right brackets are retained, as in: REQUIRE FILNAM.REQ[]; the default ppn is that of the file containing the REQUIRE declaration. (13) Section 2.1.2 HALT takes an (optional) argument, which is moved into R0 and displayed on the console data lights; it may return a value, which is read from the console switch register. (14) Section 2.1.3 SWAP is implemented, See UPDATE.DOC. (15) Section 3.1 0f course, ppn's may he specified both before and after the file names in a command, as with other DEC system programs. (16) Section 3.2 and Appendix A Module head and SWITCHES declarations are available which activate and deactivate production of a symbol table and linkages for SIX12. Conmand Switch: /D, /-D* Module Head: DEBUG,NODEBUG SWITCHES: DEBUG,NOOEBUG (17) Section 3.2 NOOPTIMIZE disables all code motion across mark polnts, with no ewceptions. (18) Appendix D There are two semantically different kinds of declared register variables: the predeclared variables VREG,SP, and PC on the one hand, and the other predeclared variables (R0-R5) and any register variables declared in the program on the other hand. The difference is that however much the program may mention VREG, SP, or PC, the compiled code will make use of registers 0,6, and 7 freely. Other register variables are just like any other varlable; if at some point in the program the variable "R2" (predeclared) is in use, the compiled code does not use register 2 except as directed by the program's use of R2. (19) Typographical errors Section 1.3 list of operators The reference to sect. 1.23 should he to 1.22 Section 1.22.2 pgph. 3 line 3 "allieviates" should be alleviates" Section 1.30 title "REQURE" should be "REQUIRE" Section 3.2 pgph, 13 line 15 "have to computed" should be "have to be computed" UPDATE.DOC This is a list of new features that have been added to the BLISS-11 compiler since the April 1974 printing of the manual, This includes specifications of some features that were included in the manual but not completely described or described as "not implemented yet". ----------------- $NAME AND $STRING ----------------- $STRING('ABCDE') is 'ABCDE' $STRING('AB') is 'AB' $STRING(16962) is '16962' Note the anomaly in the above: in any other context in the compiler, the string 'AB' is exactly equivalent to its ASCII equivalent #181 + (#102)^8, which happens to be decimal 16962. But as arguments to $NAME or $STRING, 'AB' and 16962 are NOT equivalent. $STRING(argl,arg2) is the concatenation of $STRING(arg1) and $STRING(arg2). $STRING for multiple arguments is defined quasi-inductively as above. If the program has earlier declared BIND A = 16962 or BIND A = 'AB' then $STRING(A) is '16962' Only for arguments that are strings, numbers, or symbols BINDed to numbers does $STRING have a value. For other expressions, such as variable names, a warning message is given. Macro names (and formals) in the argument stream are expanded, as usual. $NAME is exactly like $STRINC except that instead of returning a string, it returns a name. GLOBAL $NAME('GRUNT'); $NAME('GRUNT')=3 is exactly equivalent to GLOBAL GRUNT; GRUNT=3 Note, however, that $NAME('RETURN') is NOT equivalent or even related to RETURN; in fact if at the beginning of some block the user declares LOCAL SNAME('RETURN'); he will be unable to use the language reserved word RETURN within the scope of that block! $NAME may be used to generate names that would otherwise not be parsed as names, e.g. EXTERNAL $NAME('A.B'); If the result of a $NAME is a previously declared macro name (or formal), or one of the predeclared special functions ($NAME, $COUNT, etc.), it will NOT be expanded. (This is not the standard way of preventing macro expansion, i.e. for redefinition of the macro name; programs should use $QUOTE for this purpose.) ---------- $REMAINING ---------- Implemented as specified in the manual. ----------------- MEMORY PARAMETERS ----------------- LINKAGE A=BLISS( ... ,MEMORY=GRUNT, ... ); uhere GRUNT is either a literal number (indicating some fixed PDP-11 address), or a variable, which must be declared at the time of the LINKAGE declaration and must have a load-time constant address. The semantic action is that the passing of that parameter in a routine call will involve storing it into the given variable or fixed location, and likewise with accessing the parameter. For instance, LINKAGE A=BLISS(MEMORY=4,MEMORY=B-6); ... ROUTINE A F(ARG1,ARG2]= ... ; ... F(6,7); ... generates MOV #6,@#4 MOV #7,@#B-6 JSR PC,F ---- SWAB ---- SWAB(E] is equivalent to (E)^8 + ((E)^-8 AND #377), and is an invitation to the compiler to generate a PDP-11 SWAB instruction. --------------------- COROUTINE EXPRESSIONS --------------------- The specifications for these are similar but not identical to those for the coroutine expressions of BLISS-10. CREATE e0(el,e2,...,en) AT e3 LENGTH e4 THEN e5 This sets up an instantiation of e0(el,e2,...,en) whose stack is the block of e4 words starting at e3. Should this call on e0 ever execute a RETURN, control will be transferred to routine e5. Note that e5 is a routine address, not a piece of code as in Bliss-10. Also note that when the process so created is executing, its stack base will be location (e3+e4-2), not e3 as on the PDP-10. EXCHJ(e0,e1) e0 must be the stack base of some process already created; e1 becomes the value of whatever EXCHJ expression caused that process to yield control. EXCHJ may be used to start processes previously CREATED. Semantic notes: In Bliss-11, the CREATE expression yields a value, which is (e3+e4-2), that is, a pointer to the stack base of the created process. Two global variables are maintained in connection with coroutine expressions, $BREG - pointer to the current stack base; initialized in the main module. $PREV - pointer to the stack base of the last process to execute an EXCHJ; not initialized. The support routines for CREATE and EXCHJ, namely $CREAT and EXCHJ, are in COROUT.Bll[L130BL98]/A. ------- RESERVE ------- MODULE A(....,RESERVE(m, ...,n),....)= etc., where m and n are integers from 1 to 5 inclusive. The semantic action taken is that the code generated by the compiler does not make use of registers m, ... ,n , except where the program explicitly tells it to do so, by: (1) using the predeclared identifiers R1,...,R5 (2) using variables declared to be specifically in those registers, e.g. REGISTER B=4; ... .B ... (3) accessing or passing routine parameters that are specifically declared to be passed in those registers by a linkage declaration. Note that if the standard out-of-line register saving/restoring routines are called by a module, they must be altered so as not to affect any registers RESERVEd by that module. ----------- GLOBAL BIND ----------- GLOBAL BIND is like BIND, except that the expression whose value is used must be a load time constant, and the output file contains instructions to the assembler to give the BIND symbol the indicated value and make it global. For instance, GLOBAL BIND A=3 generates A = 3; .GLOBL A ----------- BLOCK NAMES ----------- For ease of documentation and error correction, blocks can be "named", NAMEDBLOCK ::= BEGIN \ name \ blockbody END \ name \ | ( \ name \ blockbody ) \ name \ A warning message is issued if the "name"s given to a BEGIN and its matching END (or matching left and right parentheses) do not match, or if a name is given to one but not the other. ----------------------- MODULE NAMES NOW GLOBAL ----------------------- This means just what it says. If your module name is GORP, the output file will contain .GLOBL GORP -------------- NO EXTRA HALTS -------------- The free HALT statement the compiler used to put out at the end of every module, now occurs only (1) in the main module, and (2) in any module in which there is some code outside all routines. --------------------------- REGISTER SAVING & RESTORING --------------------------- The registers saved before a routine body, and restored afteruarde, are now those whose contents are modified by the routine code, (The exceptions to this are that a JSR is considered to modify R0, a JSR R5, for a Hydra linkage is not considered to modify R5, and an instruction that modifies a register may not appear in the code stream because of optimization, i,e. R4=.R4+1; R4=.R4-l; ... causes INC and OEC instructions to be generated which cause R4 to be saved and restored but cause each other to be optimized out of the final code stream. In general, users need not worry about this; only those who wish to have their own register saving and restoring conventions need worry. ------------------- COMPILER CONTRACTED ------------------- DOUBLE, QUAD, and STACKADJUST are no longer reserved words. ------------ ERRORS ADDED ------------ Lots of new error messages have been added, others have been renumbered, others have been deleted. ------------------------------ (OPTIONAL) SPEEDED COMPILATION ------------------------------ Use of /K as a switch in the command string will result in somewhat faster compilation, producing grungier code. The compiler seems to take from 1/2 to 3/4 as much time on large programs with this switch on as it does with the switch off (/-K). The switch is off by default. --- NOP --- The special function NOP() is implemented. It is much like RESET and WAIT, except that the instruction generated is NOP. --------- INLINECOM --------- INLINECOM(string) is like INLINE(string), with some important differences: (1) When output, the string is preceded by a semicolon, and the whole line is preceded and followed by blank lines. (2) No warning message (CAVEAT EMPTOR!) is given when this construct is parsed. (3) The compiler knows that the line generated by this construct is not code, and therefore BR instructions which branch across it are not turned into JMP's. This feature was provided (1) to serve as an optimitation-fence until something better comes along, and (2) to provide a means of putting "landmarks" in the object code -- a desire for this having been expressed by some groups of users. -------------------------- SIX12 SYMBOL TABLE CHANGES -------------------------- The symbol table given to SIX12 no longer includes BINDs to literals. BINDS to symbols and dynamic BINDS are still included. This change is not necessarily permanent. ---------------- STARTING ADDRESS ---------------- The program can now designate a starting address without the need for a MAIN or STACK declaration. This is done by a module-head switch, called START: MODULE A(START=B, ... )= .... ELUDOM When the compiler finally puts out a .END statement, it is .END B Note that if the ussr subsequently forgets to declare (or deliberately omits) a routine or label B, the compiler will not complain. MACRO-11 may complain. ------------------- MTPI,MFPI,MTPD,MFPD ------------------- These four instructions are implemented era special functions, e,g, MTPI(arg). The argument to each is an address which is made the argument of the resulting instruction. For example, MFPD(SP) produces MFPD SP and MTPI(2+.SP) produces MTPI 2(SP). ---------------------- SEGMENTATION AVAILABLE ---------------------- It is possible to force the compiler to generate code suitable for PDP-11/45's with I and D space segmentation. This is done by compiling with either the command string switch /C or the module head switch SEGMENT (/-G and NOSEGMENT is the default). A separate version of SIGENB.MAC, the support routine for the SIGNAL and ENABLE constructs, is available for those who use this feature. ----------------------------- MODULE NAME NOW REALLY GLOBAL ----------------------------- There are two syntaxes for a modular it can be just an expression, or it can be named, e.g, MODULE A( ... ) = ELUDOM In the latter case, the module name A is now available in the module body as if it had been declared (at the outermost level) as a global routine of linkage BLISS. -------------------------------- EMT, TRAP, and IOT LINKAGE TYPES -------------------------------- These have actually been around for some time now, but since they are described in the manual as "undefined" and "unimplemented" I will describe them here. Linkages can be declared with types EMT, TRAP, and IOT, which also double as predefined linkage names themselves. Routines with such linkage types look like routines of the INTERRUPT type, except that they may have formal parameters. Calls may be made, not on the routines themselves, but with the syntax described in section 1.22.5 of the manual, i.e. TRAP(3,argl,arg2) IOT(argl,arg2) With this type of call, the first argument in the list with the TRAP or EMT linkage type is not a routine name, but compile-time constant to be placed in the right half of the TRAP or EMT instruction word; with the IOT linkage type, neither a routine name nor a compile-time constant is used. --------------------------- MORE COMPILE-TIME CONSTANTS --------------------------- The Bliss-11 compiler now looks a little more carefully at INCR and DECR loops; if the FROM and TO parts are compile-time constants, and their relative values are such that the loop body will never be executed, code for loop control and the loop body itself will not be generated, For instance, INCR I FROM 5 TO 3 BY EXPR1 DO EXPR2 is equivalent to BEGIN LOCAL I; EXPRl; -1 END