|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 185088 (0x2d300) Types: TextFile Names: »ftnpass73tx «
└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code └─⟦75ff9bef3⟧ └─⟦this⟧ »ftnpass73tx «
;/ ; alan wessel ; rc finsensvej 9 ; pass 7, ; aw 85 s. a1200, b0, c0 ; slang names, a-names for symslang k = e0 ; e-names in file processor ; introduction. ; pass 7 of the rc4000 fortran compiler is written in symbolic ; slang which allows proper names and discriminates these on ; the first 8 characters. the code must therefore be transformed ; into slang code by the symslang program. ; the use of slang and the 12-bit address part in rc4000 restricts ; the order of code parts and definitions. to find a particular ; code, help may be found in the index of contents, and also in ; the alphabetically ordered action address table, where the ; corresponding code is referenced. ; the arrangement of the process area at translation is: ; 1. file processor ; 2. pass 0, resident part ; 3. pass 7, resident part, see contents ; 4a. pass 7, initiation ; 4b. action stack and operand stack ; 5. *** used operands in forward stack ; 6. *** performed actions in backward stack. ; the *** indicates that this is a test facility. \f ;/ contents ; contents. ; introduction 1 ; contents 2 ; purpose and funtioning of pass 7 3 ; structure of pass 7 output 4 ; definition of names 5 ; directing bytes for pass 8 5 ; running system entries 9 ; general pass or pass 0 10 ; types, kinds, and registers 11 ; pass 7 start of instructions 12 ; words for test printing 12 ; error messages 13 ; testing, and end statement 14 ; actions for initiation and termination 16 ; pass end, unit initiation and end line 16 ; declarations for arrays and zones 18 ; data initiation 19 ; operand stack 20 ; definition of names in operand stack 20 ; description of contents of the operand stack 22 ; operand actions 24 ; register operations 24 ; operand descriptor actions 26 ; operand exchanging 27 ; load and release operands 28 ; operand address handling 30 ; working variables 32 ; input, output, and copying 35 ; transmission of lists, copying of single bytes 35 ; input of operands 36 ; output of operands 38 ; internal variables for pass 7 41 ; stepping stones and pass 7 pointers 42 ; main control on directing bytes from pass 6 43 ; standard actions 44 ; action stack actions 46 ; interrupt handling in pass 7 47 ; actions on executable statements 48 ; arithmetic 48 ; description of results 50 ; array and zone variables 51 ; relations 52 ; masking and shift 54 ; storing 55 ; constant operand test, and conversions in pass 7 56 ; if statements 57 ; do statements 58 ; actions for procedure calls 59 ; call of procedures 59 ; parameter transmission 60 ; return from program units 62 ; test initiation 63 ; action address table, alphabetic list of actions 64 ; auxiliary action table, alphabetically ordered 67 ; special action table 69 ; main action table 70 ; initiation of pass 7 74 \f ;/purpose and function ; purpose and functioning of pass 7. ; the purpose of pass 7 is to transform the byte string from pass 6 ; into a string for pass 8 suited for generation of machine code. ; pass 7 disposes the use of registers and of working variables by ; keeping track of the operands. ; pass 6 delivers a sequence of bytes which is an inverse polish ; representation of the fortran program. the structure of the byte ; string is divided into elements of the classes: operators, operands, ; and lists, when these classes are taken in their widest sense. ; 1. operators: a. the operator directing byte ; b. sometimes followed by one or more parameter bytes ; 2. operands : a. the operand directing byte ; b. a number of bytes describing the operand ; 3. lists : a. the list directing byte ; b. a byte giving the number of bytes in the list ; c. the list consisting of a number of bytes, see 3b ; a detailed description of pass 6 output is given in pass 6, chapter 3. ; pass 7 will act on the directing bytes from pass 6 by fetching the ; corresponding action entry from the action table (see at the end ; of pass 7) and put it into the action stack. then the first action ; of this entry is performed. ; each action entry consists of actlng (at present 4) actions, each ; action consists of a standard action and a parameter for this ; packed into one byte as: parameter < b0 + standard action. ; the standard actions are: ; ; name parameter function ; doo reference to code some pass 7 code is activated ; out directing byte for pass 8 the byte is output ; aux auxiliary action entry new actions are put into stack ; con auxiliary action entry current actions are overwritten ; nex - next directing byte from pass 6 ; err - error in action table ; operators from pass 6 generally activates code and will often ; operate on the operand stack. ; operands are entered into an operand stack. the structure of ; this is described in the operand stack section. ; lists are usually just copied to pass 8. \f ;/structure of output ; structure of pass 7 output. ; the output from pass 7 is made to suit the backwards working pass 8. ; the structure of the output may be described in syntactic form in ; which :a:b: means that the prestanding element may occur from a to ; b times, and a * for b indicates an unlimited number of times. ; <pass 7 output> ::= ( <operator> ( <operand> ):0:*: ) ; ( <label directing byte> ) ; ( <list> ) :1:*: ; <operator> ::= ( <parameter byte> ):0:*: <operator dir.byte> ; <operand> ::= ( <parameter byte> ):1:*: <operand dir.byte> ; <label dir.byte>::= <integer label number> ; <list> ::= (<byte>):n:n: <integer byte n> <list dir.byte> ; the directing bytes are defined in the section directing bytes. ; the structure of the operands are: ; <operand> ::= ( (<integer> ) ( opx0 ) ) ; ( (-s:variable> ) ( opx1 ) ) ; ( ( opx2 ) ) ; ( ( opx3 ) ) ; ( ( opx0i ) ) ; ( ( opx2i ) ) ; ( ( opx3i ) ) ; ( <comno><c:variable> opcommon ) ; ( <external number> opext ) ; ( < 2 bytes > literal2 ) ; ( < 4 bytes > literal4 ) ; ( < 8 bytes > literal8 ) ; the transformation of pass 7 output into generated code is described ; somewhere ; special nomenclature. ; in the description and comments to the code the following symbols ; are used ; ; symbol meaning ; a: absolute address of ; c: relative within common ; d: relative within description ; g: relative within global segment ; r: relative on present segment ; s: relative to stack pointer, x2-relative ; -s: indicating negative sign of s: ; t: relative to stack pointer 2, i.e. in array/zone area \f ;/directing bytes ; directing bytes for pass 8. ; --------------------------- ; the definition of the directing bytes for pass 8 are placed ; as the first symslang names. in this way the a-names of the ; symslang translation includes the value of the directing byte. ; the symslang identifier listing will then hold: ; a <directing byte value> <directing byte name> ; when directing bytes are used as parameters to the standard ; action out only, the definition includes the b0-shift. b0=3 ; structure of action: action parameter < b0 + main action ; for output dir.byte: dirbyte value < b0 + out ;count , name ; c0=0 ; ; units, lists, entries. c0=c0+1, end7 =c0 ; end pass 7 c0=c0+1, pass7 =c0<b0; pass 7 start for pass 8 c0=c0+1, unit7 =c0<b0; begin program unit c0=c0+1, funit7 =c0<b0; end program unit c0=c0+1, newline =c0<b0; new line c0=c0+1, glolist =c0<b0; list of global entries c0=c0+1, comlist =c0<b0; list of commons c0=c0+1, comzones =c0<b0; list of zones in commons c0=c0+1, extlist =c0<b0; list of externals c0=c0+1, entryvalue=c0<b0; list of local entry points c0=c0+1, labvarinit=c0<b0; list of label variables c0=c0+1, entrypoint=c0<b0; main entry point c0=c0+1, dataentry =c0<b0; data entry point c0=c0+1, dataexist =c0 ; data in program unit c0=c0+1, suite =c0<b0; reserve suite on segment ; ; declarations. c0=c0+1, entry =c0<b0; entry declaration c0=c0+1, label =c0<b0; label declaration c0=c0+1, locinit =c0<b0; initiate local array/zone c0=c0+1, rlw1 =c0 ; register load w1 c0=c0+1, cominit =c0<b0; initiate common array/zone c0=c0+1, zoninit =c0<b0; initiate local zone c0=c0+1, starray =c0<b0; initiate parameter array c0=c0+1, extzone =c0<b0; external zone ; ; operands. c0=c0+1, opx0 =c0 ; direct indexing c0=c0+1, opx1 =c0 ; c0=c0+1, opx2 =c0 ; c0=c0+1, opx3 =c0 ; c0=c0+1, opx0i =c0 ; indirect indexing c0=c0+1, opx2i =c0 ; c0=c0+1, opx3i =c0 ; c0=c0+1, opcommon =c0 ; common operand c0=c0+1, opext =c0 ; external operand (standard variable) c0=c0+1, literal2 =c0 ; 2 byte operand c0=c0+1, literal4 =c0 ; 4 byte operand c0=c0+1, literal8 =c0 ; 8 byte operand \f ;/directing bytes 2 ; ; register w1, arithmetic, masking. c0=c0+1, hlw1 =c0 ; logical arithmetic c0=c0+1, hsw1 =c0 ; c0=c0+1, rsw1 =c0 ; register store w1 c0=c0+1, loadw1 =c0 ; register load w1, address of value c0=c0+1, addw1 =c0 ; integer or address arithmetic c0=c0+1, subw1 =c0 ; c0=c0+1, dosub =c0<b0; subtract and complement c0=c0+1, mulw1 =c0 ; c0=c0+1, divw1 =c0 ; c0=c0+1, alw1 =c0<b0; load address c0=c0+1, acw1 =c0<b0; complement c0=c0+1, lsw1 =c0 ; shift single c0=c0+1, ldw1 =c0 ; shift double c0=c0+1, notw1 =c0 ; not single c0=c0+1, notw01 =c0 ; not double c0=c0+1, law1 =c0 ; and single c0=c0+1, law01 =c0 ; and double c0=c0+1, low1 =c0 ; or single c0=c0+1, low01 =c0 ; or double c0=c0+1, dlw1 =c0 ; double register c0=c0+1, dsw1 =c0 ; c0=c0+1, faw1 =c0 ; real arithmetic c0=c0+1, fsw1 =c0 ; c0=c0+1, fmw1 =c0 ; c0=c0+1, fdw1 =c0 ; c0=c0+1, aaw1 =c0 ; long arithmetic c0=c0+1, ssw1 =c0 ; c0=c0+1, signlong =c0 ; w0 := sign(long) c0=c0+1, signdoub =c0 ; w0 := sign(double) ; ; registers w0, w2, w3, uv, dr. c0=c0+1, loadw0 =c0 ; w0 c0=c0+1, rlw3 =c0<b0; w3 c0=c0+1, rsw3 =c0<b0; c0=c0+1, addw3 =c0<b0; c0=c0+1, regtouv =c0<b0; uv register c0=c0+1, reguv0 =c0<b0; c0=c0+1, uvtow01 =c0 ; c0=c0+1, drload =c0 ; dr register c0=c0+1, drstore =c0 ; c0=c0+1, draddr =c0<b0; ; ; conversion. c0=c0+1, iconvl =c0<b0; integer to long c0=c0+1, lconvi =c0<b0; long to integer c0=c0+1, ifloatr =c0<b0; integer to real c0=c0+1, rtrunci =c0<b0; real to integer c0=c0+1, rconvc =c0<b0; real to complex c0=c0+1, ctruncr =c0<b0; complex to real \f ;/directing bytes 3 ; ; skip, relation, check. c0=c0+1, shw0 =c0 ; sh w0 c0=c0+1, shw1 =c0 ; sh w1 c0=c0+1, slw1 =c0 ; sl w1 c0=c0+1, ; (not used) c0=c0+1, relation =c0<b0; relation skip c0=c0+1, amodify =c0 ; am instruction c0=c0+1, chlower =c0<b0; check lower index c0=c0+1, zindex =c0<b0; check zone index c0=c0+1, zrechk =c0<b0; check zone record length c0=c0+1, chzono =c0<b0; check number of zones ; ; jumps, points. c0=c0+1, xxforw =c0<b0; bypass label forwards c0=c0+1, goforw =c0 ; goto bypass label forwards c0=c0+1, xxback =c0<b0; bypass label backwards (data statement, optimised) c0=c0+1, gosimpl =c0<b0; goto label c0=c0+1, goif =c0<b0; goto arithmetical c0=c0+1, goiforw =c0<b0; goto conditional c0=c0+1, prepjump =c0<b0; prepare jump c0=c0+1, xxbackw =c0<b0; bypass label backwards (general form) c0=c0+1, gobackw =c0<b0; goto bypass label backwards c0=c0+1, goexternal=c0 ; goto external procedure c0=c0+1, goformal =c0 ; goto formal procedure ; ; statements. c0=c0+1, complist =c0<b0; computed goto list c0=c0+1, rsw2 =c0<b0; first do-loop := false c0=c0+1, domul =c0<b0; test sign of do c0=c0+1, doclear =c0<b0; w0w1 := 0 c0=c0+1, dogofor =c0<b0; conditional goto after-do-loop c0=c0+1, xxchang =c0<b0; exchange the top two xx-labels c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, ; (not used) c0=c0+1, parproc =c0 ; parameter procedure c0=c0+1, lastused =c0 ; set parameter formals c0=c0+1, point01 =c0<b0; call c0=c0+1, return =c0<b0; return from program unit \f ;/directing bytes 4 ; ; formats. c0=c0+1, begfor =c0<b0; format begin c0=c0+1, contfor =c0<b0; format continue c0=c0+1, openfor =c0<b0; format open c0=c0+1, closfor =c0<b0; format closed ; ; call running system. c0=c0+1, gors =c0<b0; jump to running system, ; ; trouble. c0=c0+1, trouble =c0 ; trouble c0=c0+1, troublop =c0 ; trouble operand ; directing bytes also used in out actions opx0a = opx0 <b0 opx1a = opx1 <b0 opx2a = opx2 <b0 opx3a = opx3 <b0 opx2ia = opx2i <b0 rlw1a = rlw1 <b0 rsw1a = rsw1 <b0 loadw1a = loadw1 <b0 addw1a = addw1 <b0 subw1a = subw1 <b0 mulw1a = mulw1 <b0 lsw1a = lsw1 <b0 loadw0a = loadw0 <b0 dlw1a = dlw1 <b0 dsw1a = dsw1 <b0 drloada = drload <b0 shw0a = shw0 <b0 chupper = shw1 <b0 amodifa = amodify<b0 goforwa = goforw <b0 troubla = trouble<b0 \f ;/running system entries ; running system entries ; ---------------------- ; entry to running system is described to pass 8 as: ; <running system number> gors frsno = 150 ; base number for fortran running ; ; system entries (see also pass8, pass9) coxadd = (:frsno+14:) ; complex arithmetic coxsub = (:frsno+15:) ; coxmul = (:frsno+16:) ; coxdiv = (:frsno+17:) ; dbladd = (:frsno+10:) ; double arithmetic dblsub = (:frsno+11:) ; dblmul = (:frsno+12:) ; dbldiv = (:frsno+13:) ; longmul = (:frsno+ 0:) ; long arithmetic longdiv = (:frsno+ 1:) ; iexpoi = (:frsno+ 2:)<b0 ; exponentiation lexpoi = (:frsno+ 3:)<b0 ; rexpoi = 2 <b0 ; rexpor = 1 <b0 ; dexpod = (:frsno+ 4:)<b0 ; lfloatr = 46 <b0 ; conversions lfloatd = (:frsno+ 5:)<b0 ; rtruncl = 47 <b0 ; rconvl = 43 ; (rounding real to long) rconvd = (:frsno+ 6:)<b0 ; dtruncl = (:frsno+ 7:)<b0 ; dtruncr = (:frsno+ 8:)<b0 ; readinit = (:frsno+18:)<b0 ; read readcall = (:frsno+20:)<b0 ; writeinit= (:frsno+19:)<b0 ; write writecall= (:frsno+21:)<b0 ; gopoint = 53 <b0 ; goto point endreg = 6 <b0 ; end register expression endaddr = 8 <b0 ; end address expression initzone = 9 <b0 ; zone initiation zonerel = 10 <b0 ; zone release noroom = 17 <b0 ; array index error stop = 45 <b0 ; stop fortran run \f ;/general pass names ; gpa: general pass entries. ; -------------------------- ; obs may be substituted by stepping stones ; name function of jl.w3 name. unchanged reg take = e2 ; w2 := next input byte 0 1 give = e3 ; output byte (w0) 0 1 2 ees0 = e87+1000 ; warning.yes message0 = e4 ; message(w1=a:text) 0 2 alarm = e5 ; alarm (w1=a:text) 0 2 intpass0 = e36 ; interrupt(w2=a:dump words), terminate carret = e1 ; count in gpa:lineno 0 1 2 printbyte= e16 ; print byte (w0) 0 1 2 endpass = e7 ; terminate pass writechar= e12 ; writechar(w0=char) 0 1 2 writetext= e13 ; writetext(w1=a:text) 0 2 writeint = e14 ; write integer(w0=integer) 0 1 2 ; name variable holding lineno = e6 ; actual line number stackover= e10 ; text: process too small modebits = e17 ; mode of translation modebit2 = e29 ; (more modebits) chindex = 1<3 ; bit when index check spillbit = 1<6 ; bit when interrupt on integer overflow truncbit = 1<0 ; bit when truncation instead of rounding loadmap = 1<3 ; bit when loadmap wanted lastword = e9+4; a:last word for use by pass 7 \f ;/definitions ; definition of types and kinds ; ---------------------------- notype = 0 logical = 1 integer = 2 real = 3 long = 4 double = 5 complex = 6 undefin = 7 ; undefined used when trouble ; kinds for parameter transmission etc pproc = 0 ; procedure parray = 16 ; zone array and array-type pzone = 23 ; zone psimple = 24 ; simple-type plabel = 31 ; label procval = -3 ; a:value of procedure is stored in x2+procval parbytes= 4 ; number of return description bytes in calls ; names on registers and register parts ; ------------------------------------- reg0 = 0 , reg0last = 1 , byte0 = 0 reg1 = 2 reg2 = 4 , reg2last = 5 reg3 = 6 , reg3last = 7 ; sizes of common descriptions, as transmitted between ; pass 6 and pass 8 comsize = 12 ; size of common description entrsize= 12 ; size of entry description extsize = 12 ; size of external description zcomsize= 17 ; size of zone-common description \f ;/pass 7 start ; pass 7 start of instructions ; ---------------------------- w. start7: length7 ; length of pass 7 in bytes h. entry7 ; pass 7 entry relative to start7 7<1 +0 ; pass number<1 + no change of direction w. entry7 = k - start7 jl. init7. ; goto initialise via stepping stone ; words for print addresses for test output ; the following words are placed at the start of pass 7 to be used when ; calling the file processor utility program: print when testing the ; performance of pass 7 ; with the present file processor (system 1) and pass 0 (1.7.70) ; the first word of pass 7 is in byte 2658 of the process area. ; when the etest is included a nice printing of the core area ; dumped to the area pass7dump is given by: ; head 1 ; u = set bs pass7dump 0 0 0 7.0 ; print u 2658.2688 2664.2666.i integer 2668.2670.i ; head 1 ; message pass7 operand stack and used operands ; print u byte words.5 2672.2674.i 2676.2678.i ; head 1 ; message pass7 performed actions backwards stack ; print u byte words.4 2680.2682.i ppp1: 0 ; a:pointer and stepping stone area ppp2: 0 ; pwk1: 0 ; a:work pointers pwk2: 0 ; pop1: 0 ; a:operand stack area pop2: 0 ; pup1: 0 ; a:used operands area pup2: 0 ; pac1: 0 ; a:actions performed area pac2: 0 ; opprint = 200 popinit = 100 pupinit = opprint+800 pacinit =-2000 \f ;/error messages conindex: <:constant index<0>:> ; constant index error checked in pass 7 overflow: <:overflow<0>:> ; overflow in constant arithmetic notdone: <:not implemented<0>:> ; unknown byte from pass 6 stacktxt: <:run stack full<0>:> ; running stack will exceed 2048 bytes ; <:operand stack<0>:> ; operand stack not empty ; <:more actions<0>:> ; action stack not empty ; <:stack pointer<0>:> ; w1 <> opandtop ; <:wrong standard action:>; error in action tables ; <:process too small:> ; too many operands in stack ; other messages are given when tests are included runstack: al.w1 stacktxt. ; running stack overflow. jl. alarm. ; gpa:alarm notimplx: ; directing byte not implemented. am notdone -overflow; overmess: ; overflow in constant arithmetic. am overflow-conindex; errconix: ; error in constant index. al.w1 conindex. ; w1 := a:text errmess: ; ; error message during pass 7. ; ; call: w1 := a:text ; ; jl.w3 errmess. ; ; exit: w1 := a:top operand descriptor ; ; w0,w2 unchanged ; ; output ; ; ; ; line xxx error message ds.w0 save30. ; save w3 and w0 jl.w3 message. ; gpa:message(error text) al w0 trouble ; jl.w3 outbyte. ; gpa:outbyte(trouble) rl.w0 save30. ; restore w0 rl.w1 opandtop. ; w1 := a:top operand descriptor jl. (savew3.) ; return \f ;/testing ; pass 7 includes test facilities for running in of the code: atest= 1 ; counting the number of inbytes to and outbytes from ; pass 7, the result is given as the 4.th and 5.th values ; in pass information. ; storage requirement: 18 words ; time requirement : 9 milliseconds per segment(512 bytes) btest= 1 ; testing of stacks empty at statement end ; error messages: opstack error operand stack not empty ; or under limit ; more actions last actions not performed ; storage requirement: 34 words ctest= 1 ; testing that the w1-register holds the address of the ; top operand descriptor ; error message: top not in w1 ; storage requirement: 29 words dtest= 1 ; testing wrong entries to tables and stacks ; error message: action stack error actions in operand stack ; storage requirement: 17 words etest=-1 ; comprising the thorough test output in the process area ; should only be used for reasonably small test programs ; 1. zeroing of non-resident part of pass 7 and rest of ; process area at initiation ; 2. zeroing of operand entries at time of release ; this spoils the use of multiple assignment in programs ; 3. preparation of the printing of test output stored in ; the process area: ; a. operand descriptions at time of release ; b. performed actions as 2 bytes: standard action, parameter ; storage requirement: 70 words ; the xtest is included in the slang translation when the value >= 0 ; while it is excluded by giving xtest a negative value. ; the tests are placed in such a way that no definition of names ; are included, thus all symslang or slang names are defined and ; an automatic generation of the compressed byte value - symslang ; name table is possible. \f ;/testing 2 endstatx: ; end statement. al w2 0 ; set working variable pointers rs.w2 workrel. ; workrel = 0 rs.w2 worklev. ; worklevel = 0 rl.w2 workinit. ; present bottom of working variables rs.w2 workfree. ; workfree = workinit c. btest rl.w1 opandtop. ;*** sn.w1 (opandbot.);*** if operandstack empty jl. actest. ;*** then goto test action stack sh.w1 (opandbot.);*** if w1 < opandbot rl.w1 opandbot. ;*** then w1 := opandbot rs.w1 opandtop. ;*** set opandtop al.w3 0 ;*** return to here if not empty al w2 opfault ;*** set error check hs w2 x1+opcheck ;*** se.w1 (opandbot.);*** if opstack not empty jl. topdownx. ;*** then reduce opstack al.w1 optext. ;*** error message(opstack not empty) jl.w3 errmess. ;*** z. actest: c. btest rl.w1 acstabot. ;*** a:action stack al w1 x1+actlng ;*** ; rl w2 x1 ;*** last actions se w2 0 ;*** if more proper actions jl. acterror. ;*** then goto error in action stack sn.w1 (acstatop.);*** if action stack pointer at bottom z. jl. curract. ; then goto current actions acterror: c. btest al.w3 curract. ; set return rs.w1 acstatop. ;*** acstatop := acstabot + action length al.w1 actext. ;*** jl.w3 errmess. ;*** error message(more actions) z. jl. curract. ; goto current actions optext: c. btest, <:operand stack<0>:> z. ;*** actext: c. btest, <:more actions<0>:> z. ;*** ; *** test facility for operand stack ; a message is given when w1 <> opandtop ; call jl.w3 topinw1. , see stepping stones ; exit w1 := opandtop , w0,w2 unchanged topinw1x: c. ctest sn.w1 (opandtop.) ; if w1 = opandtop jl x3 ; then return ds.w0 topin0. ; save w30 al.w1 topmess. ; w1 := a:text jl.w3 message. ; gpa:message ac.w0 start7. ; - a:pass7 start wa.w0 topin3. ; program relative of call point jl.w3 printbyte. ; gpa:printbyte rl.w0 topin0. ; restore w0 rl.w1 opandtop. ; w1 := a:opandtop jl. (topin3.) ; return z. topin3: 0 ; return address topin0: 0 ; save w0 topmess: <:stack pointer:> ; error message \f ;/ pass end and unit initiation passendx: ; end of pass 7. c. etest rl.w1 opandmax. ;*** set test print pointers correct sn w1 0 ;*** rl.w1 opandtop. ;*** rs.w1 pop2. ;*** rl.w1 opused. ;*** al w1 x1+oplength ;*** rs.w1 pup2. ;*** rl.w1 watch. ;*** wa.w1 opandlim. ;*** rs.w1 pac1. ;*** z. c. atest rl.w1 passin. ;*** rs.w1 e9. ;*** pass information 1 = no.of inbytes rl.w1 passout. ;*** rs.w1 e9.+2 ;*** pass information 2 = no.of outbytes z. jl. endpass. ; gpa:end pass \f ;/pass end and unit initiation 2 areasx: ; output pass information. jl.w3 inbyte. ; gpa:inbyte(first byte of buf.inf) hs.w2 savebyte. ; jl.w3 inbyte. ; gpa:inbyte(second byte of buf.inf) hs.w2 savelast. ; savebyte := buffer length jl.w3 inbyte. ; w2 := maximal parameter number ls w2 2 ; 4 bytes for each parameter(formal) al w2 x2+parbytes ; + bytes for parameter information rs.w2 savew2. ; savew2 := size of parameter area al w0 x2 ; for use by initiation of in-output jl.w3 outbyte. ; outbyte(parameter area - 2) rl.w2 workmax. ; w2 := -s:free stack variable ws.w2 savebyte. ; -size of array and zone area ws.w2 savew2. ; -size of parameter area rl.w0 modebit2. ; w0 := modebit2; so w0 loadmap ; if loadmap not wanted then jl. outlit2. ; output(-stacksize) as two byte literal; al.w1 localtxt. ; jl.w3 writetext. ; writetext (<:local variables:>); ac w0 x2 ; w0 := stacksize; sz w0 1 ; if stacksize odd then ba.w0 1 ; make stacksize even; jl.w3 writeint. ; write integer (stacksize); 32<12+8 ; jl. outlit2. ; output(-stacksize) as two byte literal; localtxt: <:<10>local variables: <0>:> spacetxt: <: :> h. ; listelem: 0, r. zcomsize ; w. ; txtcommon: 8<12 + comsize , <:<10>common list:<0>:> txtextern: extsize , <:<10>external list:<0>:> txtzcomm: 8<12 + zcomsize , <:<10>zone common list:<0>:> outextx: am txtextern-txtcommon; outcomx: am txtcommon-txtzcomm; outzcomx: al.w2 txtzcomm.+2 ; w2 := start of heading text; rs.w2 savew2. ; save heading address; bz w0 x2-2 ; get index for size-word; hs.w0 sizendx. ; bz w1 x2-1 ; param := size of descriptor; rs.w1 savew1. ; common-descr size := param; rs.w1 savew0. ; printed := descr size; nxtentry: ; next entry: rl.w1 savebyte. ; ws.w1 savew0. ; sh w1 -1 ; if no.list size < printed then jl. restlist. ; goto copy rest of list; al w1 0 ; count := 0; copylist: ; jl.w3 inbyte. ; w2 := gpa:inbyte; hs.w2 x1+listelem. ; listelem(count) := byte; al w0 x2 ; w0 := inbyte; jl.w3 outbyte. ; gpa:outbyte(inbyte); al w1 x1+1 ; increase(count); se.w1 (savew1.) ; if count <> descr size then jl. copylist. ; goto copylist; wa.w1 savew0. ; printed := printed rs.w1 savew0. ; + descr size; rl.w0 modebit2. ; if loadmap not wanted then so w0 loadmap ; jl. nxtentry. ; goto next entry; al w1 0 ; rx.w1 savew2. ; heading := false; se w1 0 ; if old heading <> 0 then jl.w3 writetext. ; writetext (heading); al w0 10 ; jl.w3 writechar. ; writechar (newline); al w2 ; size index ; w2 := index; sizendx = k-1 sn w2 0 ; if index <> 0 then jl. entrname. ; rl.w0 x2+listelem. ; jl.w3 writeint. ; write integer (listelem.index); 32<12+11 ; entrname: al.w1 spacetxt. ; jl.w3 writetext. ; writetext(name of common); jl. nxtentry. ; goto next entry; restlist: ; copy rest of list: wa.w1 savew1. ; w1 := number of rest bytes; jl.w3 inoutn. ; copy n bytes; jl. saveoutx. ; goto outbyte(no.list size); getentrx: ; copy whole entry-list to stack: rl.w2 opandlim. ; ws.w2 savebyte. ; reserve room for entry-list; rs.w2 opandlim. ; al.w1 stackover. ; sh.w2 (opandbot.) ; if no room for list then jl.w3 alarm. ; alarm (<:stack overflow:>); al w1 0 ; count := 0; readlist: ; jl.w3 inbyte. ; w2 := gpa:inbyte; am. (opandlim.) ; hs w2 x1+oplength ; entry-list(count) := byte; al w0 x2 ; w0 := inbyte; jl.w3 outbyte. ; gpa:outbyte(inbyte); al w1 x1+1 ; increase(count); se.w1 (savebyte.) ; if count <> savebyte then jl. readlist. ; goto readlist; jl. saveoutx. ; goto outbyte (no.list size); newltxt: <:<10> <0>:> entrytxt: <:<10><10><10>entry list:<0>:> outentrx: ; output part of entry point list: jl.w3 inbyte. ; w2 := number of local entries := inbyte; rl.w0 modebit2. ; so w0 loadmap ; if loadmap not wanted then jl. curract. ; goto current actions; al.w1 entrytxt. ; jl.w3 writetext. ; writetext (<:entry list:>); ; al w2 1 ; **** preliminary **** ; jl.w3 inbyte. ; w2 := number of local entries := inbyte; entrnxt: ; next entry: al.w1 newltxt. ; jl.w3 writetext. ; writetext (newline + spaces); rl.w1 opandlim. ; al w0 x1+entrsize ; release part of stack; rs.w0 opandlim. ; al w1 x1+oplength ; jl.w3 writetext. ; writetext (name of entry); al w2 x2-1 ; decrease (number of entries); se w2 0 ; if number of entries <> 0 then jl. entrnxt. ; goto next entry; jl. curract. ; goto current actions; uninitx: ; initialise for program unit. al w0 0 ; hs.w0 datatrue. ; datatrue := 0 c. etest rl.w2 opandbot. ;*** initiate print words for testing rs.w2 pop1. al w2 x2+opprint rs.w2 pup1. rl.w2 opandbot. al w2 x2+popinit rs.w2 pop2. al w2 x2+pupinit rs.w2 pup2. rl.w2 opandlim. rs.w2 pac2. al w2 x2+pacinit rs.w2 pac1. al.w2 init7. rs.w2 ppp1. al.w2 opused. rs.w2 ppp2. al.w2 workfree. rs.w2 pwk1. al.w2 workrel. rs.w2 pwk2. ;*** end initiate print words z. jl. curract. ; goto current actions endlinex: ; count line number. al.w3 curract. ; set return do current actions jl. carret. ; goto gpa:car return \f ;/ declarations declbegx: ; begin declare array or zone. jl.w3 inbyte. ; gpa:inbyte rs.w2 savebyte. ; savebyte := inbyte al w1 2 ; jl.w3 inoutn. ; copy 2 bytes al w0 literal2 ; jl. outcurr. ; outbyte(literal2); goto current act loczonex: ; local zone information. al w1 5 ; al.w3 curract. ; set return jl. inoutn. ; copy 5 bytes paramarx: ; parameter array declaration. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop rl.w2 type. ; rs.w2 savetype. ; savetype := type of array jl.w3 inbyte. ; w2 := -s:a:array0 hs w2 x1+opcopy ; opcopy := w2 jl. arrayopx. ; get rest of array descriptor ; 6 bytes is read into operand stack initarrx: ; initiate parameter array. ; ; entry: savetype := type of array rl.w2 savetype. ; w2 := type of array al w0 2.10011 ; w0 := real type mask se w2 real ; if type <> real al w0 2.10111 ; then w0 := not real type mask jl.w3 outbyte. ; gpa:outbyte(type mask) al w0 2.10000 ; w0 := compare base mask wa.w0 savetype. ; w0 := compare type mask (:=w0+type) jl.w3 outbyte. ; gpa:outbyte(compare mask) bl.w2 x2+sort. ; w2 := sort(type) bl.w0 x2+length. ; w0 := length(sort) jl. outcurr. ; outbyte(length); goto current action fixarrx: ; calculate test for fix array. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop rl w2 x1+opupper ; ws w2 x1+oplower ; am. (type.) ; bl.w3 sort. ; w3 := length(sort); ac w3 x3 ; ls w2 x3 ; test := (upper-lower) shift (-length); jl. outlit2. ; output test as 2 byte literal pzarrayx: ; zone/zone array as parameter. bl.w0 savelast. ; w0 := savebyte (no.zones descr) al.w3 nextact. ; parameter kind decides return := se w0 0 ; if zone then next actions al.w3 curract. ; else (zone array) current actions sl w0 0 ; if not adjustable zone array jl. inbyte. ; then dummy gpa:inbyte ; return al w2 zparact ; jl. newspact. ; goto enter adj.zone array actions \f ;/ declarations ixformlx: ; check size of formal array: ; resulting sequence: ; ls w1 length (or rl w3 length) ; ; w0 = size of actual array ; ; w1 = size of formal array ; sh w1 (0) ; sh w1 0 ; jl. indexalarm. al w0 0 ; jl.w3 outbyte. ; outbyte(0); al w0 opx0i ; jl.w3 outbyte. ; outbyte(opx0i); al w0 chlower>b0 ; jl.w3 outbyte. ; outbyte(chlower); al w2 0 ; jl.w3 outconst. ; outconst(0); jl. curract. ; goto current action; \f ;/ data initiation dataexix: ; if data statement in program unit datatrue= k+1 ; then outbyte(dataexist). al w0 0 ; w0 := datatrue (initial value = 0) sn w0 dataexist ; if datatrue = dataexist jl.w3 outbyte. ; then gpa:outbyte(dataexist) jl. curract. ; goto current actions datax: ; set data exists. al w0 dataexist ; hs.w0 datatrue. ; datatrue := dataexist jl. curract. ; goto current actions datasetx: ; make pointers to data array. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop rl.w2 type. ; bl.w2 x2+sort. ; w2 := sort(type of data array) rs.w2 savesort. ; savesort := sort jl.w3 datalast. ; save data last in work rs.w2 workrel. ; workrel := -s:work(data last) rl.w3 worklev. ; worklev = worklev + 1 al w3 x3+1 ; rs.w3 worklev. ; al.w3 curract. ; set return to current actions jl. towork2x. ; save data pointer in work databytx: ; byte length of data array to set. rl w2 x1+opcon ; w2 := constant before data star am. (savesort.) ; ls w2 0 ; w2 := constant shift sort(datarray) jl. outlit2. ; goto output bytelength as literal2 datavalx: ; update data pointer, store value. am. (savesort.) ; bl.w2 length. ; w2 := length(savesort) jl.w3 outconst. ; outbyte(length); outbyte(opx0) am. (savesort.) ; bl.w0 regstore. ; w0 := regstore(savesort) jl. outcurr. ; outbyte(regstore); goto current act datasuix: ; send sort of data. rl.w0 savesort. ; w0 := sort of data to initiate jl. outcurr. ; outbyte(sort); goto current actions \f ;/operand stack ; operand stack, definition of elements and variables ; --------------------------------------------------- ; obs if the organisation of the operand stack layout is changed ; the action opexch may have to be revised opcopy = 0 , opcomno = 0 , oplabel = 0 opplace = 1 , opcomrel = 1 opzoneno = 2 opbytix = 3 opupper = 5 oplower = 7 , oprange = 7 , opcon = 7 opcheck = 8 , opdescr = opcheck+1 ; opcheck,opdescr must be in common word oplength = 10 ; length of operand stack entry ; operand kinds ; ------------- ; obs change of the numeration of kinds must ; be accompanied by changes in tables: ; toparts, addrset, workbyte c0 = 0 ; kind: operand: c0 = c0+1, labelk = c0 ; label c0 = c0+1, labvark = c0 ; label variable c0 = c0+1, simlock = c0 ; simple local variable c0 = c0+1, simcomk = c0 ; simple common variable c0 = c0+1, simformk = c0 ; simple formal variable c0 = c0+1, arrayk = c0 ; array c0 = c0+1, rangek = c0 ; range c0 = c0+1, subconk = c0 ; subscripted with constant subscript c0 = c0+1, subscrk = c0 ; subscripted with variable subscript ;c0 = c0+1, suboptk = c0 ; subscripted optimised --- not implemented c0 = c0+1, zonek = c0 ; zone c0 = c0+1, arreqzk = c0 ; array equivalenced to zone c0 = c0+1, externk = c0 ; external c0 = c0+1, extformk = c0 ; formal external c0 = c0+1, constk = c0 ; constant or literal ; operand description checkbits. w.;------------------------------ inw01 = 1<0 ; in w01 register inuv = 1<1 ; in uv register indr = 1<2 ; in dr register addr = 1<3 ; address inwork = 1<4 ; in working storage opfault = 1<10 ; error operand \f ;/operand stack 2 ; operand description masks and operands. w.;--------------------------------------- sortmask : 2.111 ; sort mask nopsort : 8.7770 ; 1-complement of sort mask getkind = -3 ; remove sort by shift logsort = 0 intsort = 1 realsort = 2 longsort = 2 drsort = 3 subconm = subconk>getkind ; subscrm = subscrk>getkind ; simlocm = simlock>getkind ; constint = constk >getkind + intsort ; constant integer check bits \f ;/operand stack 3 ; structure of the operand stack. ; the special nomenclature and the names used in the description ; of the operand stack is described above. ; the operand stack holds entries of oplength bytes. ; the opdescr byte holds: operand kind < -getkind + sort of operand ; the opcheck byte holds: checkbits telling the whereabouts of operands ; the rest of each operand stack entry is used to describe the operand ; in different ways for each kind, only the bytes used are described: ; kind byte content ; label oplabel label number ; label variable opplace -s:label variable ; simple local opplace -s:variable ; -s:work(expression) ; simple common opcomno common number ; opcomrel c:common variable ; simple formal opplace +s:a:actual variable ; array opcopy -s:a:array element 0 ; opplace -s:a:array element 0 ; -s:work(dope vector) ; opupper (word) upper limit constant ; -s:upper limit adjustable ; oplower (word) lower limit constant ; -s:lower limit adjustable ; range opplace -s:work(range in dope vector) ; oprange (word) range constant ; -s:range variable ; subscr constant as array except: ; opplace -s:a:array element 0 ; -s:work(a:element) ; opbytix (word) constant byte index ; subscripted as array except: ; opplace -s:a:array element 0 ; -s:work(a:element) ; zone opcopy -s:work(zone array index i) ; opplace -s:a:zone 0 descriptor ; -s:work(a:zone i descriptor) ; opzoneno number of zones, 0 simple zone ; -s:adjustable number of zones ; array eq zone opcopy zone descriptor displacement ; opplace -s:a:zone 0 descriptor ; -s:work(dope vector) ; opbytix (word) array to record base displacement ; opupper as array ; oplower as array ; external opplace external number ; formal external opplace +s:formal \f ;/operand stack 4 ; constants: ; opplace -s:work(constant) ; literal1 opcon-1 0 ; opcon byte1 of logical constant ; literal2 opcon-1 byte1 ; opcon byte2 of integer constant ; literal4 opcon-3 byte1 ; opcon byte4 of real/long constant ; literal8 opcon-7 byte1 ; opcon byte8 of double/complex constant ; the array kind includes both local and common arrays. ; the zone kind comprises all zone variants: zone z, zone array zz, ; zone array element zz(i), zone record z(r), and zone array record ; zz(i,r) ; whenever an operand has entered calculations the resulting expression ; is described as a simple local entity. \f ;/operand actions occuvx: ; set register uv occupied. ; ; call and exit as occ01x rs.w1 useuv. ; useuv := a:operand descriptor al w0 inuv ; w0 := in uv mask bit jl. setcheck. ; goto set checkbits occdrx: ; set register dr occupied. ; ; call and exit as occ01x rs.w1 usedr. ; usedr := a:operand descriptor al w0 indr ; w0 := in dr mask bit jl. setcheck. ; goto set checkbits occ01x: ; set register w01 occupied. ; ; call: w1 := a:operand descriptor ; ; jl.w3 reg01set. ; ; exit: w1,w2 unchanged ; ; rs.w1 use01. ; use01 := a:operand descriptor al w0 inw01 ; w0 := in w01 mask bit jl. setcheck. ; goto set checkbits setaddrx: al w0 addr ; set address operand. setcheck: ; set checkbit in operand check. ; ; entry: w0 := bit to set ; ; w1 := a:operand descriptor rs.w2 savew2. ; save register 2 bz w2 x1+opcheck ; get checkbits so w2 (reg0) ; if bit not set ba w2 reg0last ; then add bit hs w2 x1+opcheck ; save checkbits rl.w2 savew2. ; restore register 2 jl x3 ; return addrof: ; cancel address checkbit. ; ; call: w1 := a:operand descriptor ; ; jl.w3 addrof. al w2 zerorel ; w2 := dummy zero to use regoff al w0 addr ; w0 := checkbit describing address jl. regoff. ; goto cancel bit (reg not used) regdrofx: ; set dr register not used. ; ; call: w1 := a:operand descriptor ; ; jl.w3 regdroff. ; ; exit: w1 unchanged al w2 usedrrel ; w2 := register relative to use01 al w0 indr ; w0 := bit describing dr register jl. regoff. ; goto set register not used reguvofx: ; set uv register not used. ; ; call: w1 := a:operand descriptor ; ; jl.w3 reguvoff. ; ; exit: w1 unchanged al w2 useuvrel ; w2 := register relative to use01 al w0 inuv ; w0 := bit describing uv register jl. regoff. ; goto set register not used reg01ofx: ; set register w01 not used. ; ; call: w1 := a:operand descriptor ; ; jl.w3 reg01off. ; ; exit: w1 unchanged ; ; al w2 0 ; w2 := use01 - use01 al w0 inw01 ; remove reg01 \f ;/operand actions 2 regoff: ; set register not used. ; ; entry: w1 := a:operand descriptor ; ; w2 := usereg - use01 ; ; w0 := bit to be removed ls w0 12 ; shift to first byte of register 0 lx.w0 allones. ; w0 := ones except bit to be removed la w0 x1+opdescr ; w0 := operand descriptor without bit rs w0 x1+opdescr ; set operand descriptor al w0 0 ; rs.w0 x2+use01. ; usereg := 0 jl x3 ; return rescuuvx: ; rescue uv register if used. ; ; call: jl.w3 rescuuvx. ; ; exit: w1 := a:operand in uv rl.w1 useuv. ; w1 := a:operand using uv sn w1 0 ; if uv not used jl x3 ; then return uvover01: rs.w3 over3. ; save w3 jl.w3 rescu01x. ; rescue register 01 if used al w0 uvtow01 ; jl.w3 outbyte. ; gpa:outbyte(uv to w01) rl.w1 useuv. ; w1 := a:operand in uv register jl.w3 reguvofx. ; set uv register not used rl.w3 over3. ; set return jl. occ01x. ; operand is now in register 01 rescudrx: ; rescue dr register if used. ; ; call: jl.w3 rescudrx. ; ; exit: w1 := a:operand in dr register rl.w2 usedr. ; w2 := a:operand in dr register sn w2 0 ; if dr register not used jl x3 ; then return draway: rl.w1 usedr. ; w1 := a:operand using dr rs.w3 over3. ; save return jl.w3 rescu01x. ; rescue register 01 if used rl.w1 usedr. ; w1 := a:operand using dr register jl.w3 towork8x. ; move dr register to work area jl.w3 regdrofx. ; set dr register not used jl. (over3.) ; return over3: 0 ; for saving of return address rescu01x: ; rescue 01 register if used. ; ; call: jl.w3 rescu01x. ; ; exit: w1 := a:operand in 01 rl.w2 use01. ; w2 := a:operand using 01 sn w2 0 ; if register 01 not used jl x3 ; then return ww01away: rl.w1 use01. ; w1 : a:operand using 01 rs.w3 resc3. ; save return from rescue 01 al.w3 regsaved. ; set return to register saved bz w2 x1+opcheck ; sz w2 addr ; if register holds address jl. towork2x. ; then save in 2 bytes rl.w2 sortmask. ; la w2 x1+opdescr ; w2 := sort(operand in w01) jl.w3 toworkp. ; move operand in w01 to work area regsaved: jl.w3 reg01ofx. ; set 01 register not used jl. (resc3.) ; return resc3: 0 ; for saving return address \f ;/operand actions 3 resinuvx: ; result in uv. jl.w3 addrof. ; remove address checkbit jl.w3 reg01ofx. ; remove in register 01 jl.w3 regdrofx. ; remove in dr register jl.w3 occuvx. ; set in uv register jl. curract. ; goto current actions typ8x: am double-real ; set double/complex type. typ4x: am real-integer ; set real /long type. typintx: al w2 integer ; set integer type. rs.w2 type. ; type := w2 jl. curract. ; goto current actions ; ; set operand sort in descriptor. ; ; call: w1 := a:operand descriptor ; ; jl.w3 setqqq. set8x: am double-real ; w2 := double or complex type set4x: am real-integer ; w2 := long or real type setintx: al w2 integer ; w2 := integer type rs.w2 type. ; type := chosen type al.w3 curract. ; set return toptype: ; insert operand sort in descriptor. ; ; call: w1 := a:operand descriptor rl.w2 type. ; jl.w3 toptype. topsort: ; call: w1 := a:operand ; w2 := type ; ; jl.w3 topsort. ; ; exit: w1 unchanged ; w2 := type ; ; rl w0 x1+opdescr ; get operand descriptor la.w0 nopsort. ; w0 := operand descriptor & nopsort topdescr: ; ba.w0 x2+sort. ; + operand sort hs w0 x1+opdescr ; set operand descriptor with sort jl x3 ; return topoldx: ; old operand description to top. ; ; used with multiple assignment ; ; only part of the description moved ; ; entry: w1 := a:operand to be set jl.w3 topfreex. ; release operand top jl.w3 topupx. ; but point at same entry rl w0 x1+opdescr+oplength; rs w0 x1+opdescr ; operand descriptor := old ditto rl w0 x1+opplace+oplength; rs w0 x1+opplace ; operand place word := old ditto al.w3 curract. ; set return to current actions bz w0 x1+opcheck ; w0 := checkbits so w0 indr ; if operand in 01 register jl. occ01x. ; then occupy 01 register jl. occdrx. ; else occupy dr register topkind: ; get kind of top operand. rl.w1 opandtop. ; w1 := a:top operand descriptor opkind: bz w2 x1+opdescr ; ls w2 getkind ; w2 := kind(top operand) jl x3 ; return \f ;/operand actions 4 topnextx: ; exchange top and next operand. rl.w1 opandtop. ; w1 := a: top operand al w2 x1-oplength ; w2 := a:next operand exchcurr: al.w3 curract. ; set return opexchx: ; exchange 2 operand stack elements. ; ; call: w1 := a:element a (10 bytes) ; ; w2 := a:element b (10 bytes) ; ; jl.w3 opexchx. ; ; exit: w0,w1,w2 unchanged ds.w0 save30. ; save w0 and return rl.w0 use01. ; w0 := a:element in w01 sn w0 x1 ; if element a in w01 rs.w2 use01. ; then use01 := w2 sn w0 x2 ; if element b in w01 rs.w1 use01. ; then use01 := w1 rl.w0 useuv. ; w0 := a:element in uv sn w0 x1 ; if element a in uv rs.w2 useuv. ; then useuv := w2 sn w0 x2 ; if element b in uv rs.w1 useuv. ; then useuv := w1 rl.w0 usedr. ; w0 := element in dr register sn w0 x1 ; if element a in dr rs.w2 usedr. ; then usedr := w2 sn w0 x2 ; if element b in dr rs.w1 usedr. ; then usedr := w1 dl w0 x2+2 ; exchange a(0:3) and b(0:3) rx w3 x1 ; ... rx w0 x1+2 ; ... ds w0 x2+2 ; ... dl w0 x2+6 ; exchange a(4:7) and b(4:7) rx w3 x1+4 ; ... rx w0 x1+6 ; ... ds w0 x2+6 ; ... rl w0 x2+8 ; exchange a(8:9) and b(8:9) rx w0 x1+8 ; ... rs w0 x2+8 ; ... dl.w0 save30. ; restore w30 jl x3 ; return ; ; top operand to register. toplogx: al w2 logical ; logical jl. topset. ; top01x: al w2 real ; real or long jl. topset. ; top1x: al w2 integer ; integer or address topset: rl.w1 opandtop. ; w1 := a:top operand descriptor jl.w3 topsort. ; set sort in operand descriptor jl. topget. ; w2 := type ; goto get top topregx: rl.w1 opandtop. ; w1 := a:top operand descriptor rl.w2 type. ; w2 := type \f ;/ operand actions 5 topget: ; get top operand. ; ; entry: w1 := a:operand descriptor ; ; w2 := type bz.w2 x2+sort. ; w2 := sort of top operand rs.w2 savesort. ; save sort sn w2 drsort ; if sort = drsort jl. gettodr. ; then goto get to dr register rl.w0 use01. ; top operand to register 01. sn w0 0 ; if register 01 not used jl. free01. ; then goto register 01 free se w0 x1 ; if top operand not in reg 01 jl. getaway. ; then goto get away to work bz w0 x1+opcheck ; w0 := top operand checkbits so w0 addr ; if top operand already in register jl. curract. ; then goto current actions bl.w0 x2+regload. ; w0 := regload(sort) jl.w3 outbyte. ; outbyte(register load) jl.w3 addrof. ; cancel address checkbit al w0 0 ; al.w3 addrinw1. ; set return from outbyte jl. outbyte. ; outbyte(0); goto address in reg 1 getaway: jl.w3 ww01away. ; move operand in w01 to work area rl.w1 opandtop. ; w1 := a:top operand descriptor free01: bz w2 x1+opcheck ; w2 := checkbits for top operand so w2 inuv ; if not in uv register jl. load01. ; then goto load 01 register al.w3 curract. ; set return to current actions jl. uvover01. ; move uv register to w01 gettodr: jl.w3 rescu01x. ; save w01 if used rl.w1 opandtop. ; w1 := a: top operand descriptor rl.w0 usedr. ; top operand to dr register. sn w0 0 ; if dr register not used jl. loaddr. ; then goto load dr register sn w0 x1 ; if dr register used for top operand jl. curract. ; then goto current actions jl.w3 draway. ; move dr register to work area rl.w1 opandtop. ; w1 := a:top operand descriptor loaddr: bz w2 x1+opcheck ; w2 := checkbits for top operand am occdrx-occ01x ; w3 := a:occupy dr register action load01: al.w3 occ01x. ; w3 := a:occupy 01 register action rs.w3 savew3. ; savew3 := a:occupy action am. (savesort.) ; bz.w0 regload. ; jl.w3 outbyte. ; outbyte(register load(sort of top)) al.w3 outopx. ; set return so w2 addr+inwork ; if not operand address in work jl. (savew3.) ; then occupy register; out operand jl.w3 addrof. ; else cancel address checkbit jl.w3 (savew3.) ; occupy register rl.w3 addrwork. ; w3 := indirect addressing work jl. outopy. ; goto output operand ; ; continue current actions h. ; register load byte table. regload: hlw1 ; logical loadw1 ; integer or address dlw1 ; long or real drload ; double or complex w. \f ;/operand actions 6 topfreex: ; release top operand. rl.w1 opandtop. ; w1 := old opandtop bz w2 x1+opcheck ; w2 := operand opcheck sn w2 0 ; if no checkbits jl. topdownx. ; then goto reduce operand stack ds.w3 savew3. ; save return and checkbits sz w2 inwork ; if operand in work jl.w3 downwork. ; then release work dl.w3 savew3. ; restore return and checkbits al w0 0 ; w0 := 0 (register not used) sz w2 inw01 ; if operand in register 01 rs.w0 use01. ; then reg01 not used sz w2 inuv ; if operand in uv rs.w0 useuv. ; then uv not used sz w2 indr ; if operand in dr rs.w0 usedr. ; then dr not used topdownx: ; reduce operand stack. ; call: w1 := a:operand top descr ; jl.w3 topdownx. ; exit w1 := a:new operand top d ; w0,w2 unchanged c. etest, ds.w0 topd30. ; *** test c. ctest, jl.w3 topinw1. z. ; *** test w1 = a:top operand descriptor rs.w2 topdw2. ;*** rl.w2 opused. ;*** al w2 x2+oplength ;*** operand to used operand area rs.w2 opused. ;*** dl w0 x1+2 ;*** move operand ds w0 x2+2 ;*** dl w0 x1+6 ;*** ds w0 x2+6 ;*** rl w0 x1+8 ;*** rs w0 x2+8 ;*** rl.w2 topdw2. ;*** ld w0 65 ;*** set ds w0 x1+2 ;*** operand ds w0 x1+6 ;*** descriptor rs w0 x1+8 ;*** := 0 dl.w0 topd30. ;*** z. toplowx: ;entry for next rl.w1 opandtop. ; sl.w1 (opandbot.) ; allow only 1 record underflow al w1 x1-oplength ; w1 := a:new operand top descriptor rs.w1 opandtop. ; opandtop := w1 jl x3 ; return topdw2: 0 ;*** topdw3: 0 ;*** topd30: 0 ;*** \f ;/ operand actions 7 getaddrx: rl.w1 opandtop. ; get address of top operand. ; ; call: jl. getaddrx. ; ; w1 := a:operand descriptor rl.w2 use01. ; w2 := a:operand in 01 register rs.w1 savew1. ; save a:operand descriptor se.w2 (savew1.) ; if other operand in 01 register jl.w3 rescu01x. ; then rescue 01 register rl.w1 savew1. ; restore a:operand descriptor jl.w3 opkind. ; w2 := kind(operand) al w3 2.1111 ; mask index la w2 reg3 ; bl.w2 x2+addrset. ; w2 := address set action al w2 x2+aux ; make auxiliary action jl. singlact. ; goto perform single action addrset = k-3 ; table of address set actions. h. ; index is kind(operand) addrsim ; simple local addrget ; simple common addrget ; simple formal addrget ; array 0 ; range addrget ; subscripted constant addrsim ; subscripted variable addrop ; zone addrget ; array equivalenced zone addrget ; external 0 ; formal external addrcon ; constant w. h. ; sort of operand, table. ; index is type sort: intsort ; 0 no type logsort ; 1 logical intsort ; 2 integer realsort ; 3 real longsort ; 4 long drsort ; 5 double drsort ; 6 complex intsort ; 7 undefined, treated as integer h. ; length of operand, table. ; index is sort of operand length: 1 ; 0 type is logical 2 ; 1 integer 4 ; 2 real, long 8 ; 3 double, complex w. \f ;/operand actions 8 ; the following decision table explains the addrout action ; operand checkbits ; addr in01 inuv indr (work) actions taken ; y y - - - a1. continue ; y n y - - a2. rescuuv ; y n n - - a3. outbyte(al w1); out top operand ; n y - - - a4. rescu01; goto a3 ; n n y - - a5. rescuuv; goto a4 ; n n n y - a6. rescudr; goto a3 ; n n n n - a3. outbyte(al w1); out top operand addroutx: ; make address in register 1. bz w2 x1+opcheck ; w2 := operand checkbits sz w2 inwork ; if inwork checkbit al w2 x2-inwork ; then remove inwork al w3 2.1111 ; mask checkbits la w2 reg3 ; bl.w2 x2+detab. ; take action from decision table detabase: jl. x2 ; goto chosen action deta6: jl.w3 rescudrx. ; call rescue dr register to work jl. deta3. ; goto decision action 3 deta5: jl.w3 rescuuvx. ; call rescue uv register to w01 deta4: jl.w3 rescu01x. ; call rescue 01 register to work deta3: al w2 addrget ; auxiliary al w1 address al w2 x2+con ; make continuation action jl. singlact. ; goto perform single action deta2: jl.w3 rescuuvx. ; call rescue uv register to w01 jl. curract. ; goto current actions detab: ; decision table for addrout action. ; ; the table must be changed if checkbits alters h. ; addr indr inuv in01 deta3 -detabase ; n n n n deta4 -detabase ; n n n y deta5 -detabase ; n n y n deta4 -detabase ; n n y y deta6 -detabase ; n y n n deta4 -detabase ; n y n y deta5 -detabase ; n y y n deta4 -detabase ; n y y y deta3 -detabase ; y n n n curractd ; y n n y deta2 -detabase ; y n y n curractd ; y n y y deta3 -detabase ; y y n n curractd ; y y n y deta2 -detabase ; y y y n curractd ; y y y y w. \f ;/working variables ; working variables w.;----------------- ; working variables are disposed during pass 7 and will be placed ; between the simple local variables + descriptor words and the ; array buffers + zone areas. ; in the running program the working variables are referred to rela- ; tively to x2, the addresses being described -s:work ; the following variables appears in the working variable procedures workinit: 0 ; holding the initial -s:worknext - one word ; ; for each general do-loop in program unit workfree: 0 ; holding -s:worknext, i.e. the address part of ; ; the next working variable. ; ; the initial value -s: first free stackword ; ; is deduced from pass information <no.bytes for ; ; simple variables etc.> workmax: 0 ; holding the maximal absolute value of workfree ; ; during the passing of the present program unit. ; ; the terminal value is pass 8 information worklev: 0 ; counter for work group releasing workrel: 0 ; variable for releasing of groups of works ; ; used in connection with workdown. worksetx: ; initialise work. al w2 0 ; rs.w2 worklev. ; work level counter := 0 rs.w2 workrel. ; work release := 0 jl.w3 inbyte. ; w2 := gpa:inbyte( -s:free ) bl w2 reg2last ; extend sign of w2 rs.w2 workinit. ; workinit = -s:free rs.w2 workfree. ; workfree := -s:free rs.w2 workmax. ; workmax := -s:free jl. curract. ; goto current actions datalast: ; data last pointer to work. zinworkx: ; zone index to work. al w0 opcopy ; w0 := op.index for work information c. ctest rs.w3 savew3. ;*** jl.w3 topinw1. ;*** *** test w1 = opandtop rl.w3 savew3. ;*** z. al w2 intsort ; w2 := sort integer jl. towork. ; goto register to work \f ;/working variables 2 ; ; save register in work. ; work address to opplace. towork8x: am 1 ; 8 byte operands, drstore towork4x: am 1 ; 4 byte operands, dsw1 towork2x: am 1 ; 2 byte operands, rsw1 towork1x: al w2 0 ; 1 byte operands, hsw1 toworkp: al w0 opplace ; w0 := operand index towork: ; register to work. ; ; work address to operand descriptor. ; ; call: w0 := op.index for -s:work ; ; w1 := a:operand descriptor ; ; w2 := sort ; ; exit: w2 := -s:work rs.w3 savew3. ; save return hs.w0 workopix. ; save operand index for -s:work bl.w0 x2+regstore. ; w0 := regstore directing byte jl.w3 outbyte. ; gpa:outbyte(regstore) sn w2 logsort ; if sort = logical sort workint: al w2 intsort ; then sort = integer sort bl.w2 x2+length. ; ac w2 (reg2) ; w2 :=-length(sort),i.e.work bytes bz w3 x1+opdescr ; if kind = array eq zone ls w3 getkind ; sn w3 arreqzk ; then am 2 ; save opplace al.w3 workop. ; set continue ; ; reserve work. workres: ; call: w2 := - no.bytes to reserve ; ; jl.w3 workres. ; ; exit: w2 := -s:work (stack relative) wa.w2 workfree. ; w2 := workfree - no.bytes sh w2 -2048 ; if local stack overflow jl. runstack. ; then goto run stack exceeded sh.w2 (workmax.) ; if new workfree < workmax rs.w2 workmax. ; then workmax := new workfree(w2) rx.w2 workfree. ; w2 := -s:work ; workfree := w2 jl x3 ; return workopix = k+1 ; set index of work information workop: hs w2 x1 ; operand(index ) := -s:work al w0 x2 ; w0 := -s:work jl.w3 outbyte. ; gpa:outbyte(-s:work) al w0 opx2 ; jl.w3 outbyte. ; gpa:outbyte(opx2) al w0 inwork ; set in work jl.w3 setcheck. ; operand(descriptor) with inwork bz w0 x1+opcheck ; get checkbits sz w0 addr ; if address saved in work jl. (savew3.) ; then return bz w3 x1+opdescr ; if kind = array eq zone ls w3 getkind ; se w3 zonek ; or kind = zone then sn w3 arreqzk ; save kind jl. (savew3.) ; la.w3 sortmask. ; w3 := operand sort al w3 x3+simlocm ; + simple local kind hs w3 x1+opdescr ; value in work is simple local jl. (savew3.) ; return for towork h. regstore: hsw1 ; store logical rsw1 ; store integer, address dsw1 ; store long , real drstore ; store double , complex w. \f ;/working variables 3 worknotx: ; set do not release work. rl.w0 workfree. ; rl.w2 worklev. ; al w2 x2+1 ; rs.w2 worklev. ; work level := work level + 1 sn w2 1 ; if first work level then rs.w0 workrel. ; workrel := -s:first free work jl x3 ; return downwork: ; release work holding operand. ; ; call: w1 := a:operand ; ; jl.w3 downwork ; ; exit: w2 := -s:work bz w2 x1+opdescr ; w2 := operand descriptor ls w2 getkind ; w2 := kind(operand) bl.w2 x2+workbyte. ; w2 := workbyte(kind) am x1 ; bl w2 x2 ; w2 := operand(-s:work) sh.w2 (workfree.) ; if -s:work < workfree jl x3 ; then return rl.w0 workrel. ; <>0 means wait to release work sn w0 0 ; if immediate work release jl. workback. ; then goto work release sl.w2 (workrel.) ; if -s:work > workrel rs.w2 workrel. ; then workrel := -s:work jl x3 ; return workdwnx: ; release group of working storage. rl.w2 worklev. ; al w2 x2-1 ; rs.w2 worklev. ; work level := work level - 1 se w2 0 ; if not last work level jl x3 ; then return rx.w2 workrel. ; w2 := workrel; workrel := 0 workback: ; release working variable(s). rs.w2 workfree. ; release, i.e. set workfree back jl x3 ; return h. workbyte: ; table holding index in operand description ; ; for byte giving stack address of work. ; ; obs: content depending of enumeration of kinds opplace ; not used opplace ; label opplace ; label variable opplace ; simple local, expression opplace ; simple common opplace ; simple formal opplace ; array opplace ; range opplace ; subscripted constant opplace ; subscripted variable ;-1 ; subscripted optimised opcopy ; zone opplace ; array eq zone opplace ; external opplace ; formal external opplace ; constant w. \f ;/copy outlistx: ; transmit list. jl.w3 inbyte. ; w2 := gpa:inbyte rs.w2 savebyte. ; savebyte := no.list bytes al w1 x2 ; w1 := no.list bytes jl.w3 inoutn. ; call copy w1 bytes jl. saveoutx. ; outbyte(no.); goto current actions copy1x: inout1: ; copy 1 byte. call: jl.w3 inout1. al w0 x3 ; w0 := return address jl.w3 inbyte. ; w2 := gpa:inbyte rl w3 reg0 ; w3 := return address from outbyte al w0 x2 ; w0 := inbyte jl. outbyte. ; gpa:outbyte(inbyte) inoutn: ; copy n bytes. ; call: w1:=n ; jl.w3 inoutn. rs.w3 savew3. ; save return al.w3 0 ; for al w1 x1-1 ; n := n - 1 sl w1 0 ; while n >= 0 jl. inout1. ; do inout1 (return to for) jl. (savew3.) ; return from inoutn copy3x: al w1 3 ; copy 3 bytes. al.w3 curract. ; set return to current actions jl. inoutn. ; goto copy n=3 bytes \f ;/input operands saveinx: ; save inbyte in savebyte. jl.w3 inbyte. ; w2 := gpa:inbyte rs.w2 savebyte. ; savebyte := 0, inbyte jl. curract. ; goto current actions opsetx: ; set operand description in stack. dl.w3 (acstatop.) ; operand description kind bz w0 reg3last ; = next action used as parameter ls w0 -getkind ; move kind ld w3 -12 ; remove description kind ds.w3 (acstatop.) ; save rest of actions jl.w3 topupx. ; w1 := operand stack pointer rs w0 x1+opdescr ; set operand description jl. curract. ; goto current actions arrayopx: ; array operand to stack. jl.w3 inbyte. ; w2 := gpa:inbyte hs w2 x1+opplace ; operand(top,opplace) := inbyte al w0 x1+oplower ; w0 := a:last byte to set al w1 x1+opupper-2 ; w1 :: a=first byte before upper jl. opbytes. ; goto input operand bytes to stack zoneopx: ; zone operand to stack. al w0 x1+opzoneno ; w0 := a:last byte to set jl. atplace. ; goto set first at opplace subcnopx: ; constant subscripted operand. al w0 x1+opbytix ; w0 := a:last byte to set atplace: al w1 x1+opplace-1 ; w1 := a:first byte is before opplace jl. opbytes. ; goto input operand bytes to stack arrqzx: ; array equivalenced to zone. al w0 x1+oplower ; w0 := a:last byte to set jl. atcopy. ; goto set first at opcopy simqzx: ; simple equivalenced to zone. al w0 x1+opbytix ; w0 := a:last byte to set atcopy: al w1 x1+opcopy-1 ; w1 := a:first byte is before opcopy jl. opbytes. ; goto input operand bytes to stack constopx: ; constant operand to stack. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop ld w0 65 ; for the sake of constant arithmetic ds w0 x1+opcon ; zero in last 4 bytes of constant al w0 constk<b0 ; rs w0 x1+opdescr ; operand desriptor := constant val jl.w3 toptype. ; insert operand sort ; w2 := type al w0 x1+opcon ; w0 := a:last byte of constant rl w1 reg0 ; bl.w2 x2+sort. ; w1 := w0 - length(sort(type)) bs.w1 x2+length. ; w1 := a:first byte of constant - 1 \f ;/input operands 2 opbytes: al w1 x1+1 ; w1 := a:byte to be set jl.w3 inbyte. ; w2 := gpa:inbyte hs w2 x1 ; opstack(top,byte) := inbyte se w0 x1 ; if more bytes to set jl. opbytes. ; then goto input operand bytes rl.w1 opandtop. ; else w1 := a:top operand jl. curract. ; goto current actions copyopx: ; copy of operand place. rl.w1 opandtop. ; x1 := operand stack pointcr bl w0 x1+opplace ; hs w0 x1+opcopy ; opcopy := opplace jl. curract. ; goto current actions topupx: ; increase operand stack pointer. rl.w1 opandtop. ; x1 := operand stack pointer al w1 x1+oplength ; + oplength rs.w1 opandtop. ; a:next operand stack entry c. etest, sl.w1 (opandmax.) ; *** *** test max opandstack rs.w1 opandmax. z. ; *** sh.w1 (opandlim.) ; if not over operand stack limit jl x3 ; then return al.w1 stackover. ; else stack overflow alarm jl.w3 alarm. ; gpa:alarm simcopx: ; simple common operand. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop jl.w3 inbyte. ; w2 := gpa:inbyte hs w2 x1+opcomno ; opstack(top,comno) := inbyte placeopx: ; operand addressing information. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop jl.w3 inbyte. ; w2 := gpa:inbyte setplace: hs w2 x1+opplace ; opstack(top,opplace) := inbyte jl. curract. ; goto current actions labelopx: ; label operand. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop rl.w2 labelno. ; hs w2 x1+oplabel ; opstack(top,oplabel) := labelno jl. curract. ; goto current actions rangeopx: ; put ranges into operand stack. jl.w3 inbyte. ; w2 := no.indices morange: al w2 x2-1 ; w2 := no.ranges sh w2 0 ; if no.ranges = 0 jl. curract. ; then goto current actions hs.w2 rangeno. ; rangeno := no.ranges jl.w3 topupx. ; call increase operandstack pointer al w2 rangek>getkind; rs w2 x1+opdescr ; opstack(top,opdescr) := range kind jl.w3 inbyte. ; gpa:inbyte hs w2 x1+oprange-1 ; opstack(top,rangebyte1) := inbyte jl.w3 inbyte. ; gpa:inbyte hs w2 x1+oprange ; opstack(top,rangebyte2) := inbyte rangeno = k+1 al w2 0 ; w2 := no.ranges jl. morange. ; goto more ranges \f ;/output operands saveoutx: ; output savebyte. rl.w0 savebyte. ; w0 := savebyte jl. outcurr. ; outbyte; goto current actions outlit2: ; output 2 byte literal. bl w0 reg2 ; entry: w2 := 2 byte literal jl.w3 outbyte. ; gpa:outbyte(first byte) bl w0 reg2last ; jl.w3 outbyte. ; gpa:outbyte(last byte) al w0 literal2 ; jl. outcurr. ; outbyte(literal2); goto current act zonedisx: ; out zone descriptor displacement. bz w2 x1+opcopy ; w2 := zone descr displ jl. outconst. ; goto output constant zonenox: ; output zone number operand. bl w2 x1+opzoneno ; w2 := zone number operand zonout: sl w2 0 ; if zone number = constant jl. outconst. ; then goto output constant byte al w0 x2 ; else jl.w3 outbyte. ; outbyte(-s:zoneno) al w0 opx2 ; jl. outcurr. ; outbyte(opx2 indirect); goto current act znosavex: ; output zone number from savebyte. bl.w2 savelast. ; w2 := zone number operand jl. zonout. ; goto output zone number zonerecx: ; get zone record base address. rl.w3 addrwork. ; indirect addressing to get base addr jl. outopy. ; output operand outarrbx: ; output array base addr. of param. jl.w3 topkindy. ; getkind se w2 arreqzk ; if kind=arrey eq zone jl. outbasex. ; bl w0 x1+opplace ; then get base jl. outbyx2. ; of zone outcopyx: ; output data last pointer. outzinx: ; output zone array index. outbasex: ; output array base address. ; operand(opcopy) := -s:a:array0 c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop bl w0 x1+opcopy ; w0 := -s:a:array0 outbyx2: jl.w3 outbyte. ; gpa:outbyte al w0 opx2 ; w0 := operand x2 marked jl. outcurr. ; outbyte(opx2); goto current actions ; ; output 2 byte operand parts. ; ; array to rec.base displacement zrbytix: am opbytix-oprange ; zone byteindex rel. rec.base rangex: am oprange-oplower ; range lowerx: am oplower-opupper ; lower limit upperx: al w3 opupper ; upper limit am x3 ; rl w0 x1 ; w0 := operand descriptor part rl.w2 varx2. ; w2 := variable in stack sh w0 -1 ; if not sign bit of operand part sn w3 opbytix ; or byteindex rl.w2 lit2. ; then w2 := 2 byte literal setopy: ls w3 12 ; w3 := operand index to first byte wa w3 reg2 ; w3 := w3 + w2 jl. outopy. ; goto outopy \f ;/output operands 2 outbytop: jl.w3 outbyte. ; gpa:outbyte outopx: ; output operand. rl.w1 opandtop. ; w1 := a:top operand descriptor bz w2 x1+opdescr ; w2 := operand descriptor rl.w0 sortmask. ; la w0 reg2 ; w0 := sort of operand ls w2 getkind ; w2 := kind of operand sn w2 constk ; if kind = constant kind wa w2 reg0 ; then w2 := w2 + sort am x2 ; make byteindex to toparts table rl.w3 x2+toparts. ; get output description se w3 0 ; if outop operation jl. outopy. ; then goto out top operand al.w3 outopx. ; else set return to top op jl. topdownx. ; reduce operand stack outopy: ; entry: w1 := a:operand descriptor ; ; w3 := word as in toparts ; ; number of bytes <18 + ; ; operand index <12 + ; ; operand byte descriptor hs.w3 outopz. ; save operand byte descriptor ls w3 -6 ; split w3:in components: bz w2 reg3 ; w2 := number of bytes bz w3 reg3last ; ls w3 -6 ; w3 := index of last output byte wa w1 reg3 ; w1 := a:last output byte ac w2 x2 ; w2 := - number of bytes to output wa w2 reg1 ; w2 := a:first output byte - 1 outbytes: al w2 x2+1 ; w2 := a:output byte bl w0 x2 ; w0 := output byte jl.w3 outbyte. ; gpa:outbyte se w1 x2 ; if not last byte jl. outbytes. ; then goto output bytes outopz = k+1 ; al w0 ; operand descriptor byte rl.w1 opandtop. ; w1 := a:top operand descriptor sh w0 0 ; if not operand directing byte jl. outspec. ; then goto special output bz w2 x1+opcheck ; w2 := operand checkbits so w2 addr ; if value operand jl. outcurr. ; then outbyte; goto current acti al w0 opx2i ; w0 := x2 indirect addressing sn w2 inw01 ; if address in register w1 addrinw1: al w0 opx1 ; then w0 := x1 addressing jl. outcurr. ; outbyte; goto current actions outspec: sn w0 0 ; if no output jl. curract. ; then goto current actions ac w0 (reg0) ; w0 := - special operand jl.w3 outbyte. ; gpa:outbyte rl.w3 modif2. ; w3 := modification entry jl. outopy. ; goto output operand sortconx: ; output sort constant operand. ; ; call: savetype := type ; ; jl.w3 sortcon. am. (savetype.) ; bl.w2 sort. ; w2 := sort(savetype) jl. concurr. ; output sort constant ; goto current actions out12x: am 10 ; output constant 12 operand. out2x: am 1 ; output constant 2 operand. out1x: al w2 1 ; output constant 1 operand. concurr: al.w3 curract. ; set return \f ;/output operands 3 outconst: ; output constant operand. ; ; call: w2 := constant ; ; jl.w3 outconst. ; ; exit: w1,w2 unchanged rs.w3 savew3. ; save w3 return address al w0 x2 ; jl.w3 outbyte. ; gpa:outbyte(constant) al w0 opx0 ; jl.w3 outbyte. ; gpa:outbyte(opx0) jl. (savew3.) ; return h. toparts: ; table for output of operands. ; ; the value describes the operand ; ; to be output from the operand ; ; stack ; ; a: number of bytes to output<18 ; ; b: + index of last operandbyte<12 ; ; c: + operand directing byte ; ; if c < 0 special actions are taken ;a b c ; kind of operand 1 <6+ opplace , troublop ; 0 not used 1 <6+ oplabel , 0 ; 1 label 1 <6+ opplace , opx2 ; 2 label variable 1 <6+ opplace , opx2 ; 3 simple local variable 2 <6+ opcomrel, opcommon ; 4 simple common variable addrwork: ; address in work, treated as 1 <6+ opplace , opx2i ; 5 simple formal variable 1 <6+ opplace , opx2 ; 6 array 0 , 0 ; 7 range 1 <6+ opplace , -opx2i ; 8 subscripted, constant subscript 1 <6+ opplace , opx2 ; 9 subscripted, variable subscript ;0 , 0 ; -- subscripted, optimise subscript 1 <6+ opplace , opx2 ; 10 zone 1 <6+ opplace , opx2 ; 11 array equivalenced to zone 1 <6+ opplace , opext ; 12 external 1 <6+ opplace , opx2 ; 13 formal external 1 <6+ opcon , opx0 ; 14 constant, sort 0: logical 2 <6+ opcon , literal2 ; 15 constant, sort 1: integer 4 <6+ opcon , literal4 ; 16 constant, sort 2: real, long 8 <6+ opcon , literal8 ; 17 constant, sort 3: double, compl lit2: 2<6 , literal2 ; 2 byte literal without index varx2: 1<6 , opx2 ; stack variable without index modif2: 2 <6+ opbytix , amodify ; 2 byte modifier w. \f ;/ internal variables ; variables for saving w.;------------------- savew0: 0 ; save register w0 savew1: 0 ; save register w1 savew2: 0 ; save register w2 savew3: 0 ; save register w3 save30: 0 ; for double store w0 (w30) savetype: 0 ; save type of directing byte savesort: 0 ; save sort of directing byte, i.e. of operand savelast = k + 1 ; address of last byte in savebyte savebyte: 0 ; save input byte ; internal variables type: 0 ; type of typedependant directing bytes labelno: 0 ; label number, internal representation ; use of registers. ; ---------------- ; the planned use of the registers during execution of the program ; is mirrored in the variables: use01: 0 ; the content of these pointers will be usedr: 0 ; a:operandstack(element) in case the register useuv: 0 ; is used use3 : 0 ; otherwise zero. zero : 0 ; for use in cancelling address checkbit use01rel = use01 - use01 usedrrel = usedr - use01 useuvrel = useuv - use01 use3rel = use3 - use01 zerorel = zero - use01 ; mask constants w.;------------- actmask: askmask: typemask: 2.111 ; 3 bit masks allones: 8.77777777 ; 24 1-bits ; action parameters ask0w1 = (: 1<3 + 0 :)<b0 ; for logical and, see relations ask7w1 = (: 1<3 + 7 :)<b0 ; for logical or , see relations ; action table + auxiliary action table ; acttab ; first action table entry ; acttabhi ; last action table entry actlng = 4 ; 4 bytes in action entry ; auxtab ; first auxiliary table entry ; auxtabhi ; last auxiliary table entry ; maxact = (:acttabhi - acttab:)/actlng \f ;/stepping stones and pointers ; stepping stones addrofy: jl. addrof. ; goto cancel address bit topdowny: jl. topdownx. ; goto reduce operand stack topsorty: jl. topsort. ; goto insert sort in description topkindy: jl. topkind. ; goto insert kind in top operand toptypey: jl. toptype. ; goto inset sort in top operand rescu01y: jl. rescu01x. ; goto rescue 01 register errindex: jl. errconix. ; goto error in constant index errover: jl. overmess. ; goto error in constant arithmetic message: rs.w0 svw0. ; save w0 ; goto gpa:message rs.w1 svw1. ; save w1 al w1 -1000 ; al w0 2 ; set rs.w0 x1+ees0. ; warning.yes rl.w0 svw0. ; get saved w0 rl.w1 svw1. ; get saved w1 am -2048 ; jl. message0.+2048; goto gpa:message svw0: 0 svw1: 0 intpass: jl. intpass0. ; goto gpa:interrupt handling topinw1: jl. topinw1x. ; goto test top operand descriptor opexchy: jl. opexchx. ; goto operand exchange init7: jl. init7y. ; goto initialise inbyte: ; stepping stone inbyte. c. atest rs.w1 keep. ;*** rl.w1 passin. ;*** al w1 x1+1 ;*** count input bytes rs.w1 passin. ;*** rl.w1 keep. ;*** z. am -2048 ; jl. take.+2048 ; gpa:inbyte outbyte: ; stepping stone outbyte. c.atest rs.w1 keep. ;*** rl.w1 passout. ;*** al w1 x1+1 ;*** count output bytes rs.w1 passout. ;*** rl.w1 keep. ;*** z. am -2048 ; jl. give.+2048 ; gpa:outbyte watch: 0 ;*** counter for actions keep: 0 ;*** save register 1 passin: 0 ;*** count pass input passout: 0 ;*** count pass output ; addresses and pointers w.;---------------------- ; action stack acstabot: 0 ; bottom , init = a:action stack acstalim: 0 ; limit , init = a:operand stack acstatop: 0 ; pointer, init = a:action stack ; operand stack opandbot: 0 ; bottom , init = a:operand stack - oplength opandlim: 0 ; limit , init = a:lastword - oplength opandtop: 0 ; pointer, init = a:operand 0 - oplength opandmax: 0 ;*** for testing of pass 7 opused: 0 ;*** operand counter \f ;/main control ; main administration on pass 6 directing bytes. ; ---------------------------------------------- ; the directing bytes for pass 7 are divided into 3 groups: ; ; 0 ,typedep ,dirmax ; ----------------------,---------------------,----------------> ; type independant type dependant labels ; ; the value of the directing byte is related to the main action ; table or to the label number ; ; ; type independant : (index to) main action ; type dependant : typedep + (main action - typedep)<b0 + type ; ; typedep ; value of first type dependant directing byte ; dirmax : maximal value of directing byte from pass 6 dirbyte: jl.w3 inbyte. ; directing byte. w2:=gpa:inbyte sl w2 dirmax ; if dirbyte >= first label byte jl. labelset. ; then goto get label action sl w2 typedep ; if dirbyte is type dependant jl. typebyte. ; then goto extract type ls w2 2 ; action table index := 4*dirbyte jl. actload. ; goto load action typebyte: al w2 x2+typedepn ; w2 := (actno - typedep)<3 + type al w3 2.111 ; typemask la w3 reg2 ; w3 := extracted type rs.w3 type. ; type := extracted type ws.w2 type. ; (actno - typedep)<3 ls w2 -1 ; 4*actno - 4*typedep al w2 x2+typedep4 ; index:= 4*actno actload: dl.w0 x2+acttab. ; w30 := action entry jl. getact. ; goto get next action labelset: ; label operand. rs.w2 labelno. ; labelno := dirbyte al w2 labelact ; label action entry jl. getspact. ; goto get special action \f ;/main control 2 ; get action entry w.;--------------- nextact: al w3 -actlng ; next action entry. wa.w3 acstatop. ; w3 := action stack top - 1 sn.w3 (acstabot.) ; if action stack empty jl. dirbyte. ; then goto take directing byte setatop: rs.w3 acstatop. ; set action stack top curract: dl.w0 (acstatop.) ; w30 := current actions getact: bz w2 reg0last ; w2 := next action removact: ld w0 -12 ; remove action ds.w0 (acstatop.) ; current actions := rest actions singlact: ; treat and split action rl.w3 actmask. ; action kind mask la w3 reg2 ; w3 := action kind ls w2 -b0 ; w2 := action parameter c. etest ds.w1 savew1. ;*** test: action and parameter in print area ds.w3 savew3. ;*** save registers sn w3 nex ;*** if take next action jl. watchend. ;*** then goto do not save action se w3 out ;*** if not action outbyte ls w2 b0 ;*** then w2last := slang byte value hs w3 reg2 ;*** w2first := standard action rl.w1 watch. ;*** al w1 x1-2 ;*** watch := watch - 2 rs.w1 watch. ;*** wa.w1 opandlim. ;*** rs w2 x1 ;*** save action taken in watch area dl.w1 savew1. ;*** restore registers dl.w3 savew3. ;*** z. watchend: bl.w3 x3+standact. ; standard action address acbranch: jl.w3 x3 ; call standard action jl. curract. ; continue current actions ; set auxiliary actions in action stack: aux w.;------------------------------------------ ; auxact is a standard action that takes an action entry from the ; auxiliary action entry table, increases the action stack pointer, ; and starts these new actions ; w2 := byte index of auxiliary action table auxact: ; get auxiliary actions. ; w2 := byteindex to auxact table dl.w0 x2+auxtab. ; w30 := auxiliary actions newact: ; enter new actions. ; entry: w30 := action entry al w2 actlng ; each action entry of actlng bytes wa.w2 acstatop. ; action stack pointer increased c. dtest sh.w2 (acstalim.);*** if trying to spoil operand stack jl. acstaok. ;*** then al.w1 actover. ;*** jl.w3 message. ;*** gpa:message rl.w1 opandtop. ;*** z. acstaok: ; rs.w2 acstatop. ; action stack pointer jl. getact. ; goto get next action actover: <:action stack error<0>:> \f ;/main control 3 ; get continuation actions to action stack: con w.;--------------------------------------------- ; contact is a standard action used only when an action entry ; must be continued with further actions ; contact is used instead of auxact to avoid having finished (empty) ; actions in the action stack as the continuation actions overwrites ; the current actions. (the action stack pointer is not increased.) ; w2 := byte index of auxiliary action table contact: ; get continuation (aux)actions. ; ; w2 :=byteindex to auxact table dl.w0 x2+auxtab. ; w30 := auxiliary continuation acts jl. getact. ; goto get next action ; perform general action: doo w.;---------------------------- ; perform is a standard action that transfers control to a general ; action code of pass 7 ; w2 := byteindex to the action address table ; the action address table contains the addresses of the general ; actions relative to the action base address: base perform: bl.w3 x2+aat. ; w3 := actbase: pass 7 action code base: jl.w3 x3 ; goto chosen action jl. curract. ; return to current action ; output byte: out w.;------------------ ; byteout is a standard action that outputs one byte to pass 8 ; w2 := value of output byte byteout: al w0 x2 ; w0 := output byte outcurr: al.w3 curract. ; set return to current actions jl. outbyte. ; gpa:outbyte ; error in action table w.;--------------------- ; message on error in action table erract: al.w1 actmess. ; w1 := a:text al.w3 curract. ; set return jl. message. ; gpa:message actmess: <: wrong standard action :> standact: ; standard action table h. ; --------------------- ;name standact ; function nex = 0, nextact-acbranch ; next action from action stack aux = 1, auxact -acbranch ; auxiliary actions (w2) to action stack con = 2, contact-acbranch ; continue actions (w2) to action stack doo = 3, perform-acbranch ; perform jump to named action of pass 7 out = 4, byteout-acbranch ; outbyte (w2) by call of general pass err = 5, erract -acbranch ; err = 6, erract -acbranch ; err = 7, erract -acbranch ; w. \f ;/action stack actions leavex: ; leave action in action stack. ; ; this naughty action will leave ; ; the rest of the current actions ; ; in the action stack al w3 actlng ; each action entry holds actlng bytes wa.w3 acstatop. ; increase action stack pointer rs.w3 acstatop. ; jl. dirbyte. ; goto read next directing byte changex: ; change of action suite. ; ; the following action is taken instead ; ; of the first action in the previous ; ; entry rl.w3 acstatop. ; bz w2 x3+1 ; w2 := following action al w3 x3-actlng ; rs.w3 acstatop. ; reduce action stack dl.w0 (acstatop.) ; w30 := previous action entry jl. removact. ; goto remove action newspact: ; enter special actions. dl.w0 x2+spact. ; w30 := special actions jl. newact. ; goto enter new actions getspact: ; get special actions. dl.w0 x2+spact. ; w30 := special actions jl. getact. ; goto insert these actions curractd = curract - detabase \f ;/interrupt in pass 7 intrupt: ; interrupt handling in pass 7. 0 ; working register 0 0 ; working register 1 0 ; working register 2 0 ; working register 3 0 ; exception register intretur: 0 ; instruction counter intcause: 0 ; cause of interrupt jl. 2,r.(:intrupt.+e100+2:)>1 al.w2 intrupt. ; w2 := a:interrupt dump words rl.w0 intcause. ; w0 := cause of interrupt value se w0 0 ; if cause = protection violation or sl w0 5 ; cause <> arithmetic overflow jl. intpass. ; then transfer interrupt to gpa mulflow: jl.w3 errover. ; error message:overflow, trouble ; ; w1 := a:top operand description ; ; w2 is unimportant, not restored ld w0 65 ; w30 := zeroed dummy constant jl. (intretur.) ; return intflow: ; integer overflow in multiplication. ; ; software interrupt (hand made) rs.w3 intretur. ; save return wm w0 x1+opcon ; multiply constants sh w0 -1 ; make the test on w3 am -1 ; all bits of w3 equal sign of w0 se w3 0 ; if overflow in multiplication jl. mulflow. ; then goto interrupt action jl. (intretur.) ; else return intdiv: ; integer division: ; (extend sign) rs.w3 intretur. ; save(return); bl w3 reg0 ; bl w3 reg3 ; w3 := sign(w0); wd w0 x1+opcon ; w3w0 := result of division; jl. (intretur.) ; return; \f ;/arithmetic multx: am 2 ; multiply. arith number := 2 plusx: al w2 0 ; add. arith number := 0 hs.w2 arithno. ; save arithmetical operator number rl.w1 opandtop. ; al w1 x1-oplength ; w1 := a:next operand descriptor rl.w2 type. ; w2 := type(operator) bz.w0 x2+sort. ; w0 := sort(operator) sn w0 drsort ; if sort = drsort am usedr-use01 ; then test dr register sn.w1 (use01.) ; if next operand in register(sort) jl. exchange. ; then goto exchange top and next jl. aritype. ; else goto choose operation dividex: am 2 ; divide. arith number := 3 minusx : al w2 1 ; subtract. arith number := 1 hs.w2 arithno. ; save arithmetical number exchange: rl.w1 opandtop. ; w1 := a:top operand descriptor al w2 x1-oplength ; w2 := a:next operand descriptor jl.w3 opexchx. ; exchange top and next operand aritype: rl.w2 type. ; ls w2 2 ; w2 := 4*type arithno = k+1 ; al w2 x2 ; + arithmetical operator number hs.w2 arisult. ; save table index bl.w0 x2+operator. ; w0 := operator(type,arith.no.) hs.w0 aribyte. ; save operator information rl.w1 opandtop. ; w1:= a:top operand descriptor sh w0 0 ; if running system arithmetic jl. addruv. ; then goto next opand addr to uv bz w0 x1+opdescr ; make description(top) .and. la w0 x1+opdescr-oplength; description(next) ls w0 getkind ; w0 := kind(top .and. next) sn w0 constk ; if two constant operands jl. arithin7. ; then perform arithmetic now jl. curract. ; else goto current actions addruv: jl.w3 worknotx. ; set release work after rs call rl.w2 type. ; sh w2 long ; if type < double am addr2uv ; then 2 addresses to uv register al w2 addrnext ; next address to uv actions jl. newspact. ; goto enter special action h. operator = k - 8 ; table of operator bytes. ; ; minus indicates running system arithmetic ; ; the definition of operator is k-8 as ; ; no type and logical type will not occur ; + , - , * , / , type addw1 , subw1 , mulw1 , divw1 ; integer faw1 , fsw1 , fmw1 , fdw1 ; real aaw1 , ssw1 , -longmul , -longdiv ; long -dbladd , -dblsub , -dblmul , -dbldiv ; double -coxadd , -coxsub , -coxmul , -coxdiv ; complex trouble , trouble , trouble , trouble ; error w. \f ;/ arithmetic 2 arithin7: ; constant arithmetic in pass 7. ; ; w2 := 4*type + arith.operator number ; ; w1 := a:top operand descriptor am x2 ; 2*w2 is byte index to table rl.w0 x2+arinstr. ; load slang instruction(operator) rs.w0 aricode. ; insert slang instruction jl.w3 toplowx. ; reduce operand stack dl w0 x1+opcon+oplength; take 4 byte of constant operand 1 aricode: 0 ; arithmetical instruction inserted ds w0 x1+opcon ; save result as constant top operand conbase: jl. nextact. ; goto next action entry arinstr = k - 16 ; table of slang instructions for arithmetic in 7. ; ; the definition of arinstr can be k-16 as ; ; no type and logical type will not occur wa w0 x1+opcon ; integer + ws w0 x1+opcon ; integer - mulset: wm w0 x1+opcon ; integer *, spill.no jl.w3 intdiv-aricode; integer / fa w0 x1+opcon ; real + fs w0 x1+opcon ; real - fm w0 x1+opcon ; real * fd w0 x1+opcon ; real / aa w0 x1+opcon ; long + ss w0 x1+opcon ; long - mulspill: jl.w3 intflow-aricode; integer * , spill.yes aribyte = k+1 ; generate code for arithmetic. arithopx: al w0 ; w0 := operator(type,arith.no.) sl w0 0 ; if not running system arithmetic jl. outbytop. ; then goto outbyte and outop ac w0 (0) ; w0 := -(-running system number) jl.w3 outbyte. ; outbyte(running system number) al w0 gors>b0 ; jl. outcurr. ; outbyte(go running system) squarex: ; multiply if operand ** 2. jl.w3 topkind. ; w1 := a:top operand descriptor ; ; w2 := kind(top operand) se w2 constk ; if kind <> constant jl. curract. ; then goto current actions rl w2 x1+opcon ; w2 := constant exponent se w2 2 ; if not squaring jl. curract. ; then goto current actions jl.w3 topdownx. ; reduce operand stack jl.w3 toptype. ; insert sort in operand descriptor jl.w3 rescu01x. ; rescue 01 register if used jl.w3 topupx. ; increase operand stack al w2 x1-oplength ; w2 := a:radicand descriptor dl w0 x2+2 ; ds w0 x1+2 ; dl w0 x2+6 ; make copy of radicand descriptor ds w0 x1+6 ; rl w0 x2+8 ; nb: change code if oplength changes rs w0 x1+8 ; al w2 squaract ; get multiplication action jl. getspact. ; goto insert special actions \f ;/describe result getuv: rs.w3 pickw3. ; uv to 01 register. jl.w3 occuvx. ; occupy uv register jl.w3 rescuuvx. ; rescue uv register jl. (pickw3.) ; return getdr: rs.w3 pickw3. ; dr register to work. jl.w3 occdrx. ; occupy dr register jl.w3 rescudrx. ; rescue dr register jl. (pickw3.) ; return pickw3: 0 ; for return conresx: ; send constant to work. rl.w2 sortmask. ; la w2 x1+opdescr ; w2 := sort(constant) al w0 x2+simlocm ; w0 := simpel local description with sort rs w0 x1+opdescr ; set description hs.w2 consort. ; save constant sort sn w2 drsort ; if sort = drsort am regdrofx-reg01ofx; then release dr register jl.w3 reg01ofx. ; else release 01 register al.w3 curract. ; set return consort = k+1 ; al w2 ; w2 := sort of constant jl. toworkp. ; send constant to work area simresx: ; describe simple result. rl.w2 type. ; w2 := type ls w2 2 ; w2 := 4*type setres: hs.w2 arisult. ; set table index descresx: ; set descriptor of arithmetic result. rs.w3 savew3. ; save return c. ctest, jl.w3 topinw1. z. ; *** bz w2 x1+opcheck ; w2 := operand checkbits sz w2 inwork ; if operand in work sz w2 indr ; if operand in drreg jl. 4 ; then dont release jl.w3 downwork. ; then goto release work jl.w3 addrof. ; (remove addrbit, in case of long etc) al w0 simlocm ; rs w0 x1+opdescr ; set description simpel local jl.w3 toptype. ; insert sort in descriptor; w2:=type rl.w3 savew3. ; set return arisult = k+1 ; al w2 ; w2 := table index bl.w2 x2+arireg. ; w2 := occupyx - occ01x jl. x2+occ01x. ; goto occupy action arireg = k-8 ; table of resulting register. h.; ; no type and logical type do not occur occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; integer occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; real occ01x-occ01x,occ01x-occ01x,getuv -occ01x,getuv -occ01x; long occdrx-occ01x,occdrx-occ01x,occdrx-occ01x,occdrx-occ01x; double occdrx-occ01x,occdrx-occ01x,occdrx-occ01x,occdrx-occ01x; complex occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; trouble uvres = k-arireg, getuv -occ01x ; result in uv register drres = k-arireg, occdrx-occ01x ; result in dr register w. powresx: ; describe result of exponentiation. rl.w2 type. ; w2 := type of exponentiation result sn w2 double ; if type is double am drres-uvres ; then result in dr register al w2 uvres ; else result in uv register jl. setres. ; goto set result of calculation \f ;/array and zone variables indicx: ; array indexing. c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop am. (type.) ; type of array to be subscripted bl.w2 sort. ; w2 := sort(type) bl w0 x1+opdescr ; w0 := operand description se w0 constint ; if operand not constant integer jl. varindex. ; then goto variable index rl w0 x1+opupper-oplength; w0 := next(upper) sh w0 0 ; if next opand adjustable array jl. varindex. ; then goto variable index ; ; constant subscript variable. rl w0 x1+opcon ; w0 := constant integer index jl.w3 topdownx. ; call reduce operand stack ls w0 x2 ; w0 := byteindex for array sh w0(x1+opupper) ; if byteindex > upper sh w0(x1+oplower) ; or byteindex <= lower jl.w3 errindex. ; then goto error in const index rs w0 x1+opbytix ; operand byteindex := byteindex al w2 x2+subconm ; w2 := subscript constant + sort rs w2 x1+opdescr ; operand description := w2 jl. nextact. ; goto next action (skip indic act) zqindexx: ; zone equivalenced to array. am. (type.) ; bl.w2 sort. ; w2 := sort(type) varindex: ; variable array subscript. hs.w2 shindex1. ; save sort of array al w2 indexact ; index operand action jl. newspact. ; goto enter special actions shindex1 = k+1 shindexx: ; shift index to byteindex. al w2 ; w2 := sort of array al w0 lsw1 ; jl.w3 outbyte. ; gpa:outbyte(lsw1) jl.w3 outconst. ; call outconst(sort) checkix: ; check index. jl. ; switch set at initiation ;(1) jl. curract. ; if index.no then goto current act ;(2) jl. swindex. ; if index.yes then swindex: al w2 checkact ; check index action jl. newspact. ; goto enter special actions zelemx: ; zone element as simple local addr. al w0 simlocm ; w0 := simple local descriptor al w2 real ; w2 := type real jl. setdescr. ; goto set operand descriptor asubscrx: ; set subscripted operand address. al w0 subscrm ; w0 := subscripted descriptor rl.w2 type. ; w2 := type setdescr: ; set operand descriptor. ; ; entry: w0 := description (-sort) ; ; w2 := type c. ctest, jl.w3 topinw1. z. ; *** *** test w1 = opandtop jl.w3 topdescr. ; insert sort in description addrin1x: ; set address bit and occupy w01: jl.w3 setaddrx. ; set address in checkbits al.w3 curract. ; set return to current actions jl. occ01x. ; call set w01 used \f ;/relations ; relation. ; relations appear in logical expressions. a special case of these ; are single relations in logical if statements which are given a ; special treatment. x relationoperator y will come to pass 7 ; in the form x y relation relask+(= 0<10+ ask<3 + type) ; or in logif x y relation ifask+(= 1<10+ ask<3 + type) ; the parameter for relation being described in the parenthesis. ; if either x og y is evaluated in a register the generated code is ; optimised. if y is in register or neither x nor y is evaluated ; test1 is used on register ww decided by the operands type. ; if x is in register the top and next operands are exchanged and ; test2 is used ; program operator test 1 test 2 , ask code ; .and. , 0 so ww 1 ; .lt. < 1 (001) 4 (100) , 1 sh ww 0 ; .le. <= 3 (011) 6 (110) , 2 se ww 0 ; .eq. = 2 (010) 2 (010) , 3 sh ww -1 ; .ge. >= 6 (110) 3 (011) , 4 sl ww 0 ; .gt. > 4 (100) 1 (001) , 5 sn ww 0 ; .ne. <> 5 (101) 5 (101) , 6 sl ww 1 ; .or. , 7 sz ww 1 ifrelask: 0 ; byte1 = ifrel, byte2 = ask relx: jl.w3 inbyte. ; w2 := gpa:inbyte := parameter al w0 2.111 ; typemask la w0 reg2 ; rs.w0 type. ; type := parameter & typemask ls w2 2 ; ifrel to last bit of first byte rs.w2 ifrelask. ; save ifrel ls w2 -5 ; ask in unit position la.w2 askmask. ; w2 := ask hs.w2 ifrelask.+1 ; ask := ask from parameter al w0 1 ; arith.number for minus := 1 hs.w0 arithno. ; set arithmetical operator number al w0 x1-oplength ; w0 := a:operand next se.w0 (use01.) ; if opnext not in register jl. aritype. ; then goto minus exchanged bz.w2 x2+askturn. ; hs.w2 ifrelask.+1 ; ask := inverse relation jl. exchange. ; call minus askturn = k-1 ; relation turn table. ; 1, 2, 3, 4, 5, 6 ; ask of given relation h. 4, 2, 6, 1, 5, 3 ; ask of turned relation w. \f ;/ relations 2 relsignx: ; make test on sign ; ; top operand must be in register rl.w2 type. ; w2 := type (not logical or complex) ; ; a fast test for integer and real ; ; the code depends on real < long sh w2 real ; if integer or real jl. relww. ; then goto relww al w0 signlong ; w0 := se w2 long ; if long then signlong al w0 signdoub ; else signdoub ; ; register 01 is unused at call ; ; of double minus jl.w3 outbyte. ; gpa:outbyte(w0) relww: al w0 0 ; ww := 0 sn w2 integer ; if type = integer al w0 1<3 ; then ww := 1 ba.w0 ifrelask.+1 ; + ask jl.w3 outbyte. ; gpa:outbyte( ww<3 + ask ) bl.w0 ifrelask. ; w0 := logical if or relation se w0 0 ; if logical if jl. logifrel. ; then goto logical if jl.w3 occ01x. ; else relation in w1 al.w2 logical ; w2 := logical al.w3 curract. ; set return jl. toplogx. ; top operand is logical logifrel: al w0 goiforw>b0 ; jl.w3 outbyte. ; gpa:outbyte(goiforw) al.w3 nextact. ; set return, cancel normal actions jl. topfreex. ; goto release top operand \f ;/masking and shift notx: ; not. rl.w2 type. ; w2 := type al w0 notw1 ; w0 := notw1 sl w2 real ; if type real or long al w0 notw01 ; then w0 := notw01 jl. outcurr. ; outbyte(notww) ; goto current actions orsplitx: am actlng ; or. modifier of or-entry andx: al w3 0 ; and. split depending on type rl.w2 type. ; se w2 logical ; if type = not logical jl. maskexpr. ; then goto mask expression al w2 x3+andlogact ; get and/or logical actions jl. getspact. ; goto get special actions maskexpr: se w3 0 ; w3 := if andmask then 0 al w3 low1-law1 ; else orbyte - andbyte hs.w3 maskmod. ; save maskmod rl.w1 opandtop. ; w1 := a:top operand descriptor al w2 x1-oplength ; w2 := a:next operand se.w2 (use01.) ; if next operand in register jl.w3 opexchx. ; then exchange top and next jl. curract. ; goto current actions maskx: ; masking. rl.w2 type. ; w2 := masking type al w3 0 ; se w2 integer ; w3 := if type integer then 0 al w3 law01-law1 ; else andlong - andinteger maskmod = k+1 al w3 x3 ; w3 := w3 + maskmod al w0 x3+law1 ; w0 := law1,low1,law01,low01 jl. outbytop. ; goto outbyte and top operand shiftx: ; shift. rl.w2 type. ; w2 := shifting type al w0 lsw1 ; se w2 integer ; w0 := if integer then lsw1 al w0 ldw1 ; else ldw1 jl. outbytop. ; outbyte and out operand \f ;/storing storex: ; outbyte (register store(type)). ; entry: type := type of operand am. (type.) ; bz.w2 sort. ; w2 := sort(type) bl.w0 x2+regstore. ; w0 := register store(sort) jl. outbytop. ; goto outbyte and output top operand \f ;/constant test and conversion monoconx: ; test constant operand. ; ; entry: w1 := a:operand descriptor ; ; exit: w1 is unchanged ; ; if operand is a constant ; ; then next action is performed ; ; else next action is skipped bz w2 x1+opdescr ; w2 := operand descriptor byte ls w2 getkind ; w2 := kind of operand dl.w0 (acstatop.) ; w30 := current actions se w2 constk ; if kind <> constant ld w0 -12 ; then skip next action jl. getact. ; goto get next action ; conversion of constant operands performed during translation ; to save run time conversions conrtoix: ; convert real constant to integer. ; entry: w1 := a:operand descriptor dl w0 x1+opcon ; w30 := real constant truncmod: jl. truncate. ; *** modified if trunc.no *** ; cf w0 0 ; w0 := integer(real) rs w0 x1+opcon ; set integer constant in stack jl. setintx. ; goto set integer operand in stack truncate: ; truncate real constant to integer: al w2 x3 ; w2 := sign(operand); sh w2 -1 ; fm.w0 neg1point. ; w3w0 := abs (operand) fs.w0 point5. ; - 0.5; cf w0 0 ; w0 := entier (abs(operand)); sh w2 -1 ; ac w0 (0) ; w0 := ifix(operand); rs w0 x1+opcon ; set integer constant in stack; jl. setintx. ; goto set integer operand in stack; f. neg1point: -1.0 ; floating negate sign point5: 0.5 ; floating half w. conitorx: ; convert integer constant to real. ; entry: w1 := a:operand descriptor rl w0 x1+opcon ; w0 := integer constant ci w0 0 ; w30 := real(integer) jl. con4. ; goto stack 4 byte constant operand conitolx: ; convert integer constant to long. ; entry: w1 := a:operand descriptor rl w0 x1+opcon ; w0 := integer constant bl w3 reg0 ; w3 := first byte of w0, sign extend bl w3 reg3 ; w3 := extended sign of w0 con4: ds w0 x1+opcon ; set 4 byte constant in stack jl. set4x. ; goto set 4 byte conltoix: ; convert long constant to integer. ; ; entry: w1 := a:operand descriptor dl w0 x1+opcon ; w30 := long constant ad w0 24 ; shift error will produce interrupt jl. curract. ; constant is still in operand stack \f ;/if statements ifsplitx: ; if. split depending on type rl.w2 type. ; se w2 logical ; if type = not logical jl. curract. ; goto current actions al w2 iflogact ; replace actions by iflog actions jl. getspact. ; goto get special action ifarithx: ; arithmetical if. rl.w2 type. ; al w0 0 ; w0 := choose(w0) sn w2 integer ; if type = integer al w0 1<3 ; then w0 := choose(w1) rs.w0 savebyte. ; if integer then w1 else w0 sh w2 real ; if type = integer or real jl. curract. ; then goto current actions bl.w0 x2+signtow0. ; w0 := byte to get sign to w0 jl. outcurr. ; outbyte ; goto current actions signtow0 = k-long ; table of directing bytes to make h. signlong ; w0 := sign of long in w01 signdoub ; w0 := sign of double in dr ctruncr ; w0 := real part of complex in dr trouble ; not used w. arifposx: am 2 ; output parameter for goif. arif0x: al w0 4 ; ask := if pos then 6 else 4 ba.w0 savelast. ; param := ww + ask jl. outcurr. ; outbyte ; goto current actions compgox: ; computed goto action. jl.w3 inbyte. ; w2 := gpa:inbyte(no.labels) rs.w2 savebyte. ; savebyte := no.labels rs.w1 savew1. ; savew1 := a:last label operand al w0 oplength ; wm.w0 savebyte. ; w0 := oplength * no.labels ws w1 reg0 ; w1 := a:operand before labels rs.w1 opandtop. ; release all labels from opandstack labloop: al w1 x1+oplength ; for w1 := a:next label operand bl w0 x1+oplabel ; do jl.w3 outbyte. ; gpa:outbyte(label) al w0 0 ; hs w0 x1+oplabel ; cancel label se.w1 (savew1.) ; while w1 <> a:last label operand jl. labloop. ; rl.w1 opandtop. ; effectuate label release jl. saveoutx. ; outbyte(no.labels);goto current act \f ;/do statements c. -1 ; the following optimization has not been adopted by the ; new implementation dospactx: ; do special action on sign of step. rl w0 x1+opcon ; w0 := step al w2 -1 ; w2 := -1 sh w0 -1 ; if step < 0 al w2 1 ; then w2 :=1 hs.w2 signstep. ; w2 := -sign(step) jl.w3 topfreex. ; reduce operand top signstep = k+1 ; al w2 ; w2 = -sign(step) bz w0 x1+opdescr ; ls w0 getkind ; w0 := kind(operandtop) se w0 constk ; if kind <> constant jl. dospvar. ; then goto variable until ac w0 x2 ; w0 := sign(step) wa w0 x1+opcon ; + untilconstant rs w0 x1+opcon ; operandtop := skipconstant jl. dospskip. ; else dospvar: al w0 addw1 ; jl.w3 outbyte. ; gpa:outbyte(addw1) jl.w3 outconst. ; outconstant(-sign(step)) dospskip: al w0 slw1 ; sl w2 0 ; w0 := if step > 0 then slw1 al w0 shw1 ; else shw1 al.w3 curract. ; set return jl. outcurr. ; outbyte(skip) ; goto current act z. ; doexchx: ; alter operand stack: rl.w1 opandtop. ; al w2 x1-3*oplength ; exchange (top, next3); jl.w3 opexchy. ; (i.e. step, boolean first) al w1 x1-oplength ; al w2 x1-oplength ; exchange (next1, next2); jl.w3 opexchy. ; (i.e. until, control) jl. curract. ; goto current actions; \f ;/call of procedures callx: ; call. rl.w1 opandtop. ; w1 := a:operand descriptor bl w2 x1+opdescr ; w2 := operand description ls w2 getkind ; w2 := kind of called procedure al w0 goexternal ; if external call hs.w0 callsave. ; callsave := goexternal sn w2 externk ; jl. outopx. ; goto output top operand al w0 goformal ; else (formal call) hs.w0 callsave. ; callsave := goformal jl.w3 outbyte. ; outbyte(goformal) jl. outopx. ; goto output top operand callresx: ; make result of call. callsave = k+1 al w0 ; w0 := goformal or goexternal sn w0 goexternal ; if w0 = goexternal jl.w3 outbyte. ; then outbyte(goexternal) rl.w2 type. ; w2 := type of called program unit al.w3 curract. ; set return to current actions se w2 undefin ; if type = undefined sn w2 notype ; or type = notype jl. topdowny. ; then goto reduce operand stack al w0 simlocm ; simple local description rs w0 x1+opdescr ; operand description is simple local jl.w3 topsorty. ; set sort of result al w0 xxforw>b0 ; jl.w3 outbyte. ; gpa:outbyte(xxforw) al.w3 nextact. ; set return to next action sh w2 long ; if logical,integer,real, or long jl. getuv. ; then result in uv register jl. getdr. ; else result in double register parcount: 0 ; parameter counter. parpoint: 0 ; parameter pointer. parnox: ; parameter number initiation. al w2 lastused ; hs.w2 lastout. ; lastout := lastused jl.w3 inbyte. ; w2 := gpa:inbyte rs.w2 parcount. ; parcount := total parameter number rs.w2 parpoint. ; parpoint:= total no. of parameters rl.w3 opandtop. ; w3:=address of top operand (last param) loopx: rl.w2 parpoint. ; for i:=parpoint-1 step -1 until 1 do al w2 x2-1 ; begin sh w2 0 ; w3:=address of next parameter jl. afloopx. ; if w3.checkbits=inwork+addr+inw01 rs.w2 parpoint. ; then clear inw01 al w3 x3-oplength ; end bz w2 x3+opcheck ; sn w2 inwork+addr+inw01; al w2 inwork+addr ; hs w2 x3+opcheck ; jl. loopx. ; afloopx: rl.w2 parcount. ; w2:=total number of parameters ls w2 2 ; 4*parameter number al w2 x2+parbytes ; +bytes reserved for return info rs.w2 parpoint. ; parpoint := s:last parameter byte jl.w3 worknotx. ; set release work after call jl. curract. ; goto current actions parnoutx: ; outbyte(no.of parameters). al w0 0 ; jl.w3 outbyte. ; gpa:outbyte(0) easier for pass 8 rl.w0 parcount. ; jl. outcurr. ; outbyte(no.of parameters) parlow4x: am -2 ; parameter pointer back 2 formals. parlow2x: al w0 -2 ; parameter pointer back 1 formal. wa.w0 parpoint. ; next parpoint := parpoint - 4 bytes rx.w0 parpoint. ; w0 := parpoint; parpoint := next do. jl. outcurr. ; outbyte(+s:formal); goto current actions \f ;/ parameter transmission setlastx: ; set lastused for parameter formals. lastout = k+1 ; al w0 ; lastused(at first call) or zero sn w0 0 ; if lastused has been output jl. curract. ; then goto current actions al w2 0 ; hs.w2 lastout. ; lastout := 0 jl. outcurr. ; outbyte(lastused); goto current act arrzonex: ; parameter can be array equival zone. jl.w3 topkindy. ; w2 := kind(top operand) se w2 arreqzk ; if kind <> array equival. zone jl. curract. ; then goto current actions al w2 arrezact ; actions for array eq zone am -1000 ; setpping stone rl.w3 sortmask.+1000; lapperi: set kind to simpel local la w3 x1+opdescr ; w3=operand sort+ al w3 x3+simlocm ; simple local kind hs w3 x1+opdescr ; jl. newspact. ; goto enter special actions rangoutx: ; send ranges to dope vector in work. jl.w3 rescu01y. ; save register 01 if used jl.w3 topkindy. ; w2 := kind(top operand) se w2 rangek ; if kind <> range jl. nextact. ; then goto previous action entry jl. curract. ; else goto current actions psubarrx: ; choose array or zone subscripted. jl.w3 topkindy. ; w2 := kind(top operand) se w2 simlock ; if kind <> zone(element) am arrspact ; then subscripted array action al w2 subzone ; else subscripted zone action jl. newspact. ; goto enter special actions psubadrx: ; remove address checkbit. jl.w3 addrofy. ; cancel address checkbit jl. outbasex. ; goto output top operand neglngx: ; output negative length of element. rl.w2 type. ; w2 := type am sort-base ; bl.w2 x2+base. ; w2 := sort(type); am length-base ; bl.w2 x2+base. ; w2 := length(sort(type)); ac w0 x2 ; w0 := - length; jl. outcurr. ; outbyte(-length); goto current act simspltx: ; split on simpel label parameter. jl.w3 rescu01y. ; save register 01 if used rl.w2 type. ; w2 := type(simpel parameter) sn w2 notype ; if type = label jl. curract. ; then goto current actions al w2 parsimct ; simpel parameter action jl. getspact. ; goto get special actions parextx: ; set external in formal. al w2 ; w2 := kind(procedure parameter) al w0 parproc ; (prepare external procedure) sn w2 externk ; if kind = external then jl. outcurr. ; outbyte(parproc) al w2 parform ; else ls w2 -b0 ; jl. contact. ; continue actions(parform); prcspltx: ; set formal external in formal. jl.w3 rescu01y. ; save register 01 if used jl.w3 topkindy. ; w2 := kind(top operand) hs.w2 parextx.+1 ; parext := kind(procedure parameter) sn w2 externk ; if kind = external jl. curract. ; then goto current actions al w0 dlw1 ; jl. outcurr. ; outbyte(dlw1); goto current actions \f ;/ parameter transmission 2 ; ; make formal 1 of parameter words. kindprcx: am -1<5+pproc -plabel ; kind procedure kindlabx: am plabel-psimple; kind label (type := 0) kindsimx: al w2 psimple ; kind simple wa.w2 type. ; + type jl. outconst. ; goto output constant byte arrforml: 4<12 + parray ; doperel<12 + kind array-type kindarrx: rl.w2 arrforml. ; formal 1 for parameter array wa.w2 type. ; + type jl. outlit2. ; goto output literal 2 constant zonforml: 6<12 + pzone ; doperel<12 + kind zone kindzonx: rl.w2 zonforml. ; formal 1 for zone jl. outlit2. ; goto output literal 2 constant kindzarx: al w2 0 ; jl. addzar. ; goto add zone array kind zarspltx: ; split on adjustable zone. bl w2 x1+opzoneno ; w2 := number of zones sl w2 0 ; if not adjustable zone array jl. zarload. ; then goto zone array param al w2 adjzarct ; adjustable zone array action jl. getspact. ; goto get special actions zarload: al w0 loadw0 ; jl.w3 outbyte. ; gpa:outbyte(loadw0) ls w2 12 ; number of zones < 12 addzar: al w2 x2+parray ; + kind zone array jl. outlit2. ; goto output literal 2 constant \f ;/return from program unit retexitx: ; return, release zones. jl.w3 inbyte. ; w2 := release zones<2 + sort of unit hs.w2 returno. ; save sort of unit so w2 1<2 ; if no release zones jl. curract. ; then goto current actions al w2 x2-1<2 ; remove release zone bit hs.w2 returno. ; save sort of unit al w2 auxrelz ; special action aux+relzone jl. newspact. ; goto enter special action returno = k+1 ; choose return from sort of unit. retwayx: al w2 ; w2 := sort of unit ls w2 2 ; byteindex for return action al w2 x2+subrout ; load special action jl. newspact. ; goto enter return actions loadresx: ; load function result. al w0 procval ; value in x2+procval at run time jl. outcurr. ; outbyte ; goto current actions \f ;/test initiation w. testinit: ld w0 65 ;*** initiate test. c. atest ds.w0 passout. ;*** in and out counters = 0 z. zerofill: c. etest ds w0 x2 ;*** al w2 x2-4 ;*** fill action and opstack with sl w2 (reg1) ;*** zeroes. jl. zerofill. ;*** z. c. dtest al.w1 opstack. ;*** rs.w1 acstalim. ;*** rs.w1 opandbot. ;*** leave oplength for extra actions rs.w1 opandtop. ;*** ; initialize bottom- and next lower operand to reasonable values al w0 3<3 ; kind:=simloc rs w0 x1+opdescr ; rs w0 x1+opdescr-oplength ; al w0 -7 ; addr. in stack hs w0 x1+opplace ; hs w0 x1+opplace-oplength ; z. c. etest al w1 x1+opprint ;*** rs.w1 opused. ;*** z. rl.w1 opandtop. ; w1 := a:top operand descriptor jl. dirbyte. ; goto get first directing byte init7y: jl. init7x. ; go on to initiation \f ;/action address table aat: ; action address table h. ; -------------------- ;action name definition page addrin1 =(:k-aat:)<b0, addrin1x-base; 51 set address bit and occupy w01 addrout =(:k-aat:)<b0, addroutx-base; 31 make address in register 1 and =(:k-aat:)<b0, andx -base; 54 and,split on type areas =(:k-aat:)<b0, areasx -base; 17 area pass information arifpos =(:k-aat:)<b0, arifposx-base; 57 output parameter for goif arif0 =(:k-aat:)<b0, arif0x -base; 57 output parameter for goif arithop =(:k-aat:)<b0, arithopx-base; 49 arithmetical operations arrayop =(:k-aat:)<b0, arrayopx-base; 36 array operand to stack arrqz =(:k-aat:)<b0, arrqzx -base; 36 array equivalenced zone arrzone =(:k-aat:)<b0, arrzonex-base; 60 split if array equival zone asubscr =(:k-aat:)<b0, asubscrx-base; 51 set element address call =(:k-aat:)<b0, callx -base; 59 call program unit callres =(:k-aat:)<b0, callresx-base; 59 make result of call change =(:k-aat:)<b0, changex -base; 46 change of action suite compgo =(:k-aat:)<b0, compgox -base; 57 computed goto conitol =(:k-aat:)<b0, conitolx-base; 56 integer to long constant conitor =(:k-aat:)<b0, conitorx-base; 56 integer to real constant conltoi =(:k-aat:)<b0, conltoix-base; 56 long to integer constant conres =(:k-aat:)<b0, conresx -base; 50 send constant to work area conrtoi =(:k-aat:)<b0, conrtoix-base; 56 real to integer constant constop =(:k-aat:)<b0, constopx-base; 36 constant operand copyop =(:k-aat:)<b0, copyopx -base; 37 copy of operand place copy1 =(:k-aat:)<b0, copy1x -base; 35 copy one byte copy3 =(:k-aat:)<b0, copy3x -base; 35 copy three bytes data =(:k-aat:)<b0, datax -base; 19 set dataexist databyt =(:k-aat:)<b0, databytx-base; 19 make length of data array dataexi =(:k-aat:)<b0, dataexix-base; 19 if data output dataexist dataset =(:k-aat:)<b0, datasetx-base; 19 make data array pointers datasui =(:k-aat:)<b0, datasuix-base; 19 send sort of data dataval =(:k-aat:)<b0, datavalx-base; 19 update data pointer declbeg =(:k-aat:)<b0, declbegx-base; 18 declare array or zone descres =(:k-aat:)<b0, descresx-base; 50 set description of result divide =(:k-aat:)<b0, dividex -base; 48 division doexch =(:k-aat:)<b0, doexchx -base; 58 alter operand stack endline =(:k-aat:)<b0, endlinex-base; 16 end of program line endstat =(:k-aat:)<b0, endstatx-base; 15 end of program statement fixarr =(:k-aat:)<b0, fixarrx -base; 18 make test for fix array getaddr =(:k-aat:)<b0, getaddrx-base; 30 get address of operand getentr =(:k-aat:)<b0, getentrx-base; 17 get entry point list ifarith =(:k-aat:)<b0, ifarithx-base; 57 arithmetical if ifsplit =(:k-aat:)<b0, ifsplitx-base; 57 if,split on type indic =(:k-aat:)<b0, indicx -base; 51 array indexing initarr =(:k-aat:)<b0, initarrx-base; 18 initiate param array ixforml =(:k-aat:)<b0, ixformlx-base; 18 check size of formal array kindarr =(:k-aat:)<b0, kindarrx-base; 61 set kind array kindlab =(:k-aat:)<b0, kindlabx-base; 61 set kind label kindprc =(:k-aat:)<b0, kindprcx-base; 61 set kind procedure kindsim =(:k-aat:)<b0, kindsimx-base; 61 set kind simple kindzar =(:k-aat:)<b0, kindzarx-base; 61 set kind zone (array adj) kindzon =(:k-aat:)<b0, kindzonx-base; 61 set kind zone(zone array) labelop =(:k-aat:)<b0, labelopx-base; 37 label operand leave =(:k-aat:)<b0, leavex -base; 46 leave action in stack loadres =(:k-aat:)<b0, loadresx-base; 62 load function result loczone =(:k-aat:)<b0, loczonex-base; 18 copy local zone info lower =(:k-aat:)<b0, lowerx -base; 38 output array lower limit \f ;/action address table 2 mask =(:k-aat:)<b0, maskx -base; 54 masking minus =(:k-aat:)<b0, minusx -base; 48 subtraction monocon =(:k-aat:)<b0, monoconx-base; 56 next action if const opand mult =(:k-aat:)<b0, multx -base; 48 multiplication neglng =(:k-aat:)<b0, neglngx -base; 60 negative length of element not =(:k-aat:)<b0, notx -base; 54 not notimpl =(:k-aat:)<b0, notimplx-base; 13 not implemented occdr =(:k-aat:)<b0, occdrx -base; 24 dr register occupied occuv =(:k-aat:)<b0, occuvx -base; 24 register uv occupied occ01 =(:k-aat:)<b0, occ01x -base; 24 register 01 occupied opset =(:k-aat:)<b0, opsetx -base; 36 set operand description orsplit =(:k-aat:)<b0, orsplitx-base; 54 or,split on type outarrb =(:k-aat:)<b0, outarrbx-base; 38 output array base for param outbase =(:k-aat:)<b0, outbasex-base; 38 output array base outcom =(:k-aat:)<b0, outcomx -base; 17 copy common list outcopy =(:k-aat:)<b0, outcopyx-base; 38 output operand copy outentr =(:k-aat:)<b0, outentrx-base; 17 output entry list outext =(:k-aat:)<b0, outextx -base; 17 output external list outlist =(:k-aat:)<b0, outlistx-base; 35 copying of lists outop =(:k-aat:)<b0, outopx -base; 39 output operand (general) outzin =(:k-aat:)<b0, outzinx -base; 38 output zone array index out1 =(:k-aat:)<b0, out1x -base; 39 output the constant 1 out2 =(:k-aat:)<b0, out2x -base; 39 output the constant 2 out12 =(:k-aat:)<b0, out12x -base; 39 output the constant 12 paramar =(:k-aat:)<b0, paramarx-base; 18 parameter array declare parext =(:k-aat:)<b0, parextx -base; 60 set external in formal parlow2 =(:k-aat:)<b0, parlow2x-base; 59 parameter pointer back 1 formal parlow4 =(:k-aat:)<b0, parlow4x-base; 59 parameter pointer back 2 parno =(:k-aat:)<b0, parnox -base; 59 initiate param.pointer parnout =(:k-aat:)<b0, parnoutx-base; 59 output no.of parameters passend =(:k-aat:)<b0, passendx-base; 16 end pass7, call pass8 placeop =(:k-aat:)<b0, placeopx-base; 37 operand addressing info plus =(:k-aat:)<b0, plusx -base; 48 addition powres =(:k-aat:)<b0, powresx -base; 50 set exponentiation result prcsplt =(:k-aat:)<b0, prcspltx-base; 60 set formal external in formal psubadr =(:k-aat:)<b0, psubadrx-base; 60 no address in param array psubarr =(:k-aat:)<b0, psubarrx-base; 60 array or zone subscripted pzarray =(:k-aat:)<b0, pzarrayx-base; 18 zone(array) as parameter range =(:k-aat:)<b0, rangex -base; 38 output range rangeop =(:k-aat:)<b0, rangeopx-base; 37 range operands to stack rangout =(:k-aat:)<b0, rangoutx-base; 60 ranges to dope vector in work regdrof =(:k-aat:)<b0, regdrofx-base; 24 dr register free reg01of =(:k-aat:)<b0, reg01ofx-base; 24 01 register free rel =(:k-aat:)<b0, relx -base; 52 relation,may be optimised relsign =(:k-aat:)<b0, relsignx-base; 53 test sign of relation rescudr =(:k-aat:)<b0, rescudrx-base; 25 rescue dr register rescuuv =(:k-aat:)<b0, rescuuvx-base; 25 rescue uv register rescu01 =(:k-aat:)<b0, rescu01x-base; 25 rescue 01 register resinuv =(:k-aat:)<b0, resinuvx-base; 26 result in uv register retexit =(:k-aat:)<b0, retexitx-base; 62 return release zones retway =(:k-aat:)<b0, retwayx -base; 62 choose sort of return savein =(:k-aat:)<b0, saveinx -base; 36 save inbyte saveout =(:k-aat:)<b0, saveoutx-base; 38 output saved byte setint =(:k-aat:)<b0, setintx -base; 26 set operand sort in descr setlast =(:k-aat:)<b0, setlastx-base; 60 lastused for parameter set up set4 =(:k-aat:)<b0, set4x -base; 26 set operand sort in descr set8 =(:k-aat:)<b0, set8x -base; 26 set operand sort in sescr \f ;/ action address table 3 shift =(:k-aat:)<b0, shiftx -base; 54 shift shindex =(:k-aat:)<b0, shindexx-base; 51 shift integer index simcop =(:k-aat:)<b0, simcopx -base; 37 simple common operand simqz =(:k-aat:)<b0, simqzx -base; 36 simple equivalenced zone simres =(:k-aat:)<b0, simresx -base; 50 set simple result simsplt =(:k-aat:)<b0, simspltx-base; 60 split on label parameter sortcon =(:k-aat:)<b0, sortconx-base; 39 output sort constant square =(:k-aat:)<b0, squarex -base; 49 multiply if **2 store =(:k-aat:)<b0, storex -base; 55 outbyte regstore subcnop =(:k-aat:)<b0, subcnopx-base; 36 constant subscripted op topdown =(:k-aat:)<b0, topdownx-base; 29 reduce operand stack topfree =(:k-aat:)<b0, topfreex-base; 29 release top operand toplog =(:k-aat:)<b0, toplogx -base; 27 top logical to register toplow =(:k-aat:)<b0, toplowx -base; 29 topdown in next action topnext =(:k-aat:)<b0, topnextx-base; 27 exchange top and next topold =(:k-aat:)<b0, topoldx -base; 26 save part of old descr topreg =(:k-aat:)<b0, topregx -base; 27 top to register topup =(:k-aat:)<b0, topupx -base; 37 increase operand stack top1 =(:k-aat:)<b0, top1x -base; 27 top to register w1 typint =(:k-aat:)<b0, typintx -base; 26 set integer type typ4 =(:k-aat:)<b0, typ4x -base; 26 set real or long type typ8 =(:k-aat:)<b0, typ8x -base; 26 set double or complex towork2 =(:k-aat:)<b0, towork2x-base; 33 save register in work uninit =(:k-aat:)<b0, uninitx -base; 17 initiate new program unit upper =(:k-aat:)<b0, upperx -base; 38 output array upper limit workdwn =(:k-aat:)<b0, workdwnx-base; 34 reduce workpointer worknot =(:k-aat:)<b0, worknotx-base; 34 protect work workset =(:k-aat:)<b0, worksetx-base; 32 initiate workpointers zarsplt =(:k-aat:)<b0, zarspltx-base; 61 pslit on adjustable zone outzcom =(:k-aat:)<b0, outzcomx-base; 17 output zone common list zelem =(:k-aat:)<b0, zelemx -base; 51 zone element as simple zinwork =(:k-aat:)<b0, zinworkx-base; 32 zone index to work znosave =(:k-aat:)<b0, znosavex-base; 38 output zone no. saved zonedis =(:k-aat:)<b0, zonedisx-base; 38 output zone descr displ zoneno =(:k-aat:)<b0, zonenox -base; 38 output zone no. operand zoneop =(:k-aat:)<b0, zoneopx -base; 36 zone operand to stack zonerec =(:k-aat:)<b0, zonerecx-base; 38 get zone record base address zrbyti =(:k-aat:)<b0, zrbytix -base; 38 output zone rec byteindex zqindex =(:k-aat:)<b0, zqindexx-base; 51 zone equivalenced array \f ;/ auxiliary action table w. aut: ; auxiliary action entry table. h. ; ----------------------------- auxtab = k + 3 ; auxtab is used for addressing ; ; of an auxiliary table entry ; the auxiliary table entries consist each of 4 bytes describing ; an action. ; the name of the auxiliary action is defined relatively to the ; out name of the auxiliary action entry table. ; care must be taken that names are defined when used in expressions ; therefore the auxiliary table is divided into 2 alfabetically ordered ; parts. both must be placed before the general action entry table. ; (these restrictions are caused by slang.) ; the action table can have a maximum of 2**7=128 entries at present ; part 1 of auxiliary action table ; auxiliary name , action4 , action3 , action2 , action1 chforml=(:k-aut:)<b0, 0 ,doo+topfree,doo+ixforml,out+chupper free2 =(:k-aut:)<b0, 0 , 0 ,doo+topfree,doo+topfree gocond =(:k-aut:)<b0, 0 ,doo+topdown,doo+outop ,out+goif outopf =(:k-aut:)<b0, 0 , 0 ,doo+topfree,doo+outop pardow2=(:k-aut:)<b0,out+opx3a ,doo+parlow2,out+rsw1a ,doo+setlast pardow4=(:k-aut:)<b0,out+opx3a ,doo+parlow4,out+dsw1a ,doo+setlast parform=(:k-aut:)<b0, 0 , 0 ,doo+topfree,aux+pardow4 parfor1=(:k-aut:)<b0, 0 , 0 ,doo+topfree,aux+pardow2 power =(:k-aut:)<b0, 0 , 0 ,doo+powres ,out+gors reg01uv=(:k-aut:)<b0, 0 , 0 ,doo+reg01of,out+regtouv topint =(:k-aut:)<b0, 0 , 0 ,doo+setint ,doo+topreg topregf=(:k-aut:)<b0, 0 , 0 ,doo+topfree,doo+topreg top1f =(:k-aut:)<b0, 0 , 0 ,doo+topfree,doo+top1 top4 =(:k-aut:)<b0,doo+set4 ,doo+occ01 ,doo+topreg ,doo+rescu01 top8 =(:k-aut:)<b0,doo+set8 ,doo+occdr ,doo+topreg ,doo+rescudr zoneq2 =(:k-aut:)<b0,doo+zelem ,out+zrechk ,doo+zonedis,out+addw3 zoneq1 =(:k-aut:)<b0,con+zoneq2 ,doo+outop ,out+rlw3 ,doo+zrbyti c. (:(:k-aut:) a. 2.11:) - 1 m.*** formaterror of auxiliary action table part 1 z. ; part 2 of auxiliary action table addrcon=(:k-aut:)<b0, 0 ,doo+addrout,doo+conres ,doo+topreg addrget=(:k-aut:)<b0, 0 , 0 ,doo+outop ,out+alw1 addrop =(:k-aut:)<b0, 0 , 0 ,doo+outop ,out+rlw1a addrsim=(:k-aut:)<b0, 0 , 0 , 0 ,doo+addrout adjarr1=(:k-aut:)<b0,con+chforml,doo+sortcon,out+rlw3 ,doo+lower arifneg=(:k-aut:)<b0,doo+topdown,doo+outop ,out+gosimpl,aux+gocond arrbase=(:k-aut:)<b0,doo+outbase,out+rsw1a ,doo+lower ,out+subw1a arrezp =(:k-aut:)<b0,doo+zrbyti ,out+addw1a ,out+opx1a ,out+0 arrfor1=(:k-aut:)<b0, 0 , 0 ,doo+kindarr,out+loadw0a arrinit=(:k-aut:)<b0,out+starray,doo+initarr,doo+outop ,out+dlw1a asslab =(:k-aut:)<b0,doo+topdown,doo+outop ,out+rsw1a ,doo+topdown byteix =(:k-aut:)<b0, 0 , 0 ,doo+sortcon,out+lsw1a callout=(:k-aut:)<b0,doo+workdwn,out+point01,doo+parnout,doo+setlast ctor =(:k-aut:)<b0, 0 ,out+ctruncr,doo+regdrof,aux+top4 datacon=(:k-aut:)<b0,out+opx3a ,out+0 ,doo+dataval,out+addw3 datafin=(:k-aut:)<b0,doo+outcopy,out+rsw1a ,doo+outcopy,out+addw1a datanew=(:k-aut:)<b0, 0 , 0 ,doo+dataset,doo+lower dataux2=(:k-aut:)<b0,out+suite ,doo+datasui,doo+outop ,out+rsw3 dataux1=(:k-aut:)<b0,con+datacon,doo+outop ,out+rlw3 ,aux+topregf declare=(:k-aut:)<b0,out+opx2a ,doo+saveout,out+rsw1a ,doo+declbeg doass =(:k-aut:)<b0, 0 ,doo+store ,aux+topregf,doo+setint dofirst=(:k-aut:)<b0,doo+topup ,doo+outop ,out+dogofor,doo+toplow doinit2=(:k-aut:)<b0,out+xxchang,out+xxbackw,out+goforwa,doo+towork2 doinit1=(:k-aut:)<b0,con+doinit2,out+opx0a ,out+0<b0 ,out+alw1 doinit =(:k-aut:)<b0, 0 ,con+doinit1, simlock ,doo+opset doloop =(:k-aut:)<b0, 0 ,out+xxforw ,doo+outop ,out+rsw2 domult1=(:k-aut:)<b0, 0 , 0 ,con+outopf ,out+domul domult =(:k-aut:)<b0,con+domult1,out+opx1a ,out+0<b0 ,out+acw1 doparr =(:k-aut:)<b0,con+parform,aux+arrfor1,doo+getaddr,doo+towork2 doplow =(:k-aut:)<b0, 0 ,doo+towork2,doo+lower ,out+loadw1a doprang=(:k-aut:)<b0,doo+topfree,doo+towork2,doo+range ,out+loadw1a dopupp =(:k-aut:)<b0, 0 ,doo+towork2,doo+upper ,out+loadw1a \f ;/auxiliary action table 2 dostep3=(:k-aut:)<b0, 0 ,con+free2 ,doo+arithop,doo+minus dostep2=(:k-aut:)<b0,con+dostep3,doo+store ,doo+arithop,doo+plus dostep1=(:k-aut:)<b0,con+dostep2,aux+outopf ,out+doclear,doo+doexch dostep =(:k-aut:)<b0, 0 ,con+dostep1,doo+rescu01,doo+topreg dotest =(:k-aut:)<b0, 0 , 0 ,out+goiforw,out+3<b0 dtol =(:k-aut:)<b0,out+gors ,out+dtruncl,doo+resinuv,aux+top4 dtor =(:k-aut:)<b0,out+gors ,out+dtruncr,doo+resinuv,aux+top4 formal =(:k-aut:)<b0, 0 ,out+opx2a ,doo+copy1 ,out+dlw1a funcval=(:k-aut:)<b0, 0 , 0 ,out+opx2ia ,doo+loadres goaddr =(:k-aut:)<b0, 0 , 0 ,out+gors ,out+endaddr ;gocond see auxiliary table start itol =(:k-aut:)<b0, 0 , 0 ,out+iconvl ,aux+top4 itolin7=(:k-aut:)<b0, 0 , 0 ,doo+set4 ,doo+conitol itorin7=(:k-aut:)<b0, 0 , 0 ,doo+set4 ,doo+conitor itor =(:k-aut:)<b0,out+ifloatr,aux+top4 ,con+itorin7,doo+monocon lowerix=(:k-aut:)<b0, 0 ,con+byteix ,doo+out1 ,out+subw1a ltod =(:k-aut:)<b0,con+power ,out+lfloatd,aux+reg01uv,aux+top8 ltoi =(:k-aut:)<b0, 0 , 0 ,out+lconvi ,aux+topint ltor =(:k-aut:)<b0, 0 ,out+gors ,out+lfloatr,aux+loadres ltoiin7=(:k-aut:)<b0, 0 , 0 ,doo+setint ,doo+conltoi nexaddr=(:k-aut:)<b0, 0 ,doo+topup ,doo+getaddr,doo+toplow ;outopf - parfor2 see auxiliary table start pararr =(:k-aut:)<b0,con+doparr ,doo+arrzone,doo+outarrb,out+loadw1a parlab =(:k-aut:)<b0, 0 ,con+parform,doo+kindlab,out+loadw0a parzone=(:k-aut:)<b0,doo+znosave,out+chzono ,doo+pzarray,doo+savein procfor=(:k-aut:)<b0, 0 ,con+parform,doo+kindprc,out+loadw0a rangpar=(:k-aut:)<b0, 0 ,con+rangpar,aux+doprang,doo+rangout relasub=(:k-aut:)<b0,doo+descres,doo+arithop,aux+topregf,doo+rel relzone=(:k-aut:)<b0, 0 , 0 ,out+gors ,out+zonerel rpowi =(:k-aut:)<b0, 0 ,con+power ,out+rexpoi ,doo+typ4 rsuv0 =(:k-aut:)<b0, 0 ,out+reguv0 ,aux+nexaddr,aux+reg01uv rsuv01 =(:k-aut:)<b0,con+rsuv0 ,doo+getaddr,doo+rescu01,doo+rescuuv rtoc =(:k-aut:)<b0,doo+powres ,out+rconvc ,doo+reg01of,aux+top8 rtod =(:k-aut:)<b0,con+power ,out+rconvd ,aux+reg01uv,aux+top8 rtoiin7=(:k-aut:)<b0, 0 , 0 ,doo+setint ,doo+conrtoi rtoi =(:k-aut:)<b0,out+rtrunci,aux+topint ,con+rtoiin7,doo+monocon rtol =(:k-aut:)<b0, 0 ,out+gors ,out+rtruncl,doo+topreg saveset=(:k-aut:)<b0, 0 ,out+opx2a ,doo+saveout,out+rsw1a shift12=(:k-aut:)<b0, 0 , 0 ,doo+out12 ,out+lsw1a simeqz =(:k-aut:)<b0, 0 ,aux+zoneq1 ,out+loadw1a,doo+rescu01 sspower=(:k-aut:)<b0,doo+topfree,aux+rsuv01 ,doo+worknot,doo+rescu01 subform=(:k-aut:)<b0, 0 ,con+parfor1,doo+kindsim,out+addw1a submove=(:k-aut:)<b0,con+subform,out+opx0a ,out+5<b0 ,out+lsw1a subrest=(:k-aut:)<b0,con+submove,out+opx1a ,doo+neglng ,out+acw1 subz1 =(:k-aut:)<b0,con+subrest,out+amodifa,out+4<b0 ,out+0 ;topint,top8,top4 see auxiliary table start xdexpod=(:k-aut:)<b0,con+power ,out+dexpod ,aux+sspower,doo+typ8 xipow =(:k-aut:)<b0, 0 ,con+rtoi ,aux+rpowi ,aux+sspower xitor =(:k-aut:)<b0,con+xipow ,doo+typ4 ,doo+topup ,aux+itor zarform=(:k-aut:)<b0, 0 ,doo+zoneno ,out+loadw1a,aux+pardow2 zarset =(:k-aut:)<b0,con+parfor1,doo+kindzar,out+addw1a ,aux+shift12 zcomma =(:k-aut:)<b0,doo+outop ,out+addw1a ,out+zindex ,doo+zoneno zinzar =(:k-aut:)<b0,con+zarset ,doo+out1 ,out+addw1a ,doo+outzin ;zoneq2,zoneq1 see auxiliary table start zrbase =(:k-aut:)<b0,doo+out2 ,out+lsw1a ,doo+outop ,out+rlw3 c. (:(:k-aut:) a. 2.11:) - 1 m.*** formaterror of auxiliary action table part 2 z. \f ;/special action table w. sat: ; special action entry table h. ;---------------------------- spact = k + 3 ; the following action entries are used when in an action a different ; suite of actions should be taken. ; action name , action4 , action3 , action2 , action1 iflogact = k-sat ; same as andlogact. obs orlogact must follow andlogact= k-sat , 0 ,out+goiforw,out+ask0w1 ,aux+topregf orlogact = k-sat , 0 ,out+goiforw,out+ask7w1 ,aux+topregf addrnext = k-sat ,con+reg01uv,aux+nexaddr,doo+rescu01,doo+rescuuv addr2uva = k-sat , 0 ,doo+topfree,doo+change ,aux+rsuv01 adjzarct = k-sat , 0 , 0 ,con+zarset ,aux+zarform auxrelz = k-sat , 0 , 0 , 0 ,con+relzone arrezact = k-sat ,con+arrezp ,out+rlw1a ,doo+zonedis,out+addw1a checkact = k-sat ,doo+lower ,out+chlower,doo+upper ,out+chupper indexact = k-sat , 0 ,doo+shindex,doo+topfree,doo+top1 labelact = k-sat , 0 ,doo+labelop, labelk ,doo+opset parsimct = k-sat ,con+parform,doo+kindsim,out+loadw0a,doo+getaddr squaract = k-sat ,doo+descres,doo+arithop,aux+topregf,doo+mult subarr = k-sat ,con+subrest,doo+upper ,out+subw1a ,doo+psubadr subzone = k-sat ,con+subz1 ,doo+zonerec,out+subw1a ,doo+zonerec zparact = k-sat ,con+saveset,out+opx2ia ,doo+copy1 ,out+loadw1a subrout = k-sat , 0 , 0 , 0 ,con+goaddr uvfunct = k-sat ,out+gors ,out+endreg ,aux+funcval,out+dlw1a drfunct = k-sat ,con+goaddr ,out+draddr ,aux+funcval,out+drloada ; the subrout, uvfunct, and drfunct actions must be in sequence ; see retway action addr2uv = addr2uva - addrnext arrspact = subarr - subzone c. (:(:k-sat:) a. 2.11:) - 1 m.*** formaterror special action table z. \f ;/ main action table ; action table. h.;------------- acttab = k-1 ; the order of the action table corresponds to the values of the ; directing bytes from pass 6. the action entry is put into the action ; stack. ; each action table entry consists of a double word holding 4 ; actions of 1 byte each and action 1 in the last byte. ; the structure of an action is: action name<b0 + standard action ; the standard actions are: ; 0 : next action entry from action stack, if empty new dir.byte ; aux: place auxiliary actions in action stack ; con: continuation actions to action stack ; doo: perform named instructions of pass 7 code ; out: output (directing) byte for pass 8 ; action4 , action3 , action2 , action1 ; byte from pass 6 ; ; h0+ unit separator. 0 , 0 ,doo+uninit ,out+unit7 ; 0 begin unit 0 , 0 , 0 ,out+funit7 ; 1 end unit 0 ,doo+passend,out+pass7 ,doo+copy1 ; 2 end pass ; ; h1+ lists. 0 ,out+glolist,doo+getentr,doo+savein ; 0 global entries 0 ,out+comlist,doo+outcom ,doo+savein ; 1 common list 0 ,out+comzones,doo+outzcom,doo+savein ; 2 zones in common 0 ,out+extlist,doo+outext ,doo+savein ; 3 external list 0 , doo+dataexi ,out+entryvalue,doo+outlist; 4 local entries 0 , 0 ,out+labvarinit,doo+outlist; 5 label var.list ; ; h2+ declarations. con+parzone,aux+saveset,aux+formal ,doo+savein ; 0 parameter zone 0 , 0 ,con+declare,out+locinit; 1 local array out+zoninit,doo+loczone,aux+declare,out+locinit; 2 local zone 0 , 0 ,con+declare,out+cominit; 3 common array 0 , 0 ,con+declare,out+cominit; 4 common zone 0 ,out+extzone,doo+copy1 ,doo+copy1 ; 5 external zone ; ; h3+ parameter array. doo+lower ,out+rsw1a ,aux+lowerix,aux+top1f ; 0 adjustable lower doo+upper ,out+rsw1a ,aux+byteix ,aux+top1f ; 1 adjustable upper 0 , 0 ,con+arrbase,aux+arrinit; 2 initiate array con+chforml,aux+byteix ,doo+fixarr ,out+loadw1a; 3 fixedlimit array ixcheck1=k-1; (the action is blind if index.no) con+adjarr1,out+subw1a ,doo+upper ,out+rlw1a ; 4 adjustable array ixcheck2=k-1; (the action is blind if index.no) ; ; h4+ data. con+datafin,doo+topfree,doo+databyt,out+loadw1a; 0 data star con+dataux2,doo+outcopy,out+rsw3 ,aux+dataux1; 1 data single con+dataux2,doo+outcopy,out+xxback ,aux+dataux1; 2 data multiple 0 , 0 ,doo+topdown,doo+workdwn; 3 data array end \f ;/action table 2 ; action4 , action3 , kind , action1 ; ; ; h5+ operands. 0 ,doo+placeop, simlock ,doo+opset ; 0 local simple 0 ,doo+simcop , simcomk ,doo+opset ; 1 common simple 0 ,doo+placeop, simformk ,doo+opset ; 2 formal simple doo+copyop ,doo+subcnop, subconk ,doo+opset ; 3 simple eq array con+simeqz ,doo+simqz , simlock ,doo+opset ; 4 simple eq zone 0 ,doo+placeop, labvark ,doo+opset ; 5 label variable 0 ,doo+placeop, simlock ,doo+opset ; 6 procedure name doo+copyop ,doo+arrayop, arrayk ,doo+opset ; 7 array 0 ,doo+arrqz , arreqzk ,doo+opset ; 8 array eq zone 0 ,doo+zoneop , zonek ,doo+opset ; 9 zone 0 ,doo+placeop, externk ,doo+opset ; 10 external 0 ,doo+placeop, extformk ,doo+opset ; 11 formal external ; 0 ,doo+statfop, statfunk ,doo+opset ; - statem.func ; 0 ,doo+statfop, simlock ,doo+opset ; - stat.func.form ; , action2 , ; h7+ end bytes. 0 , 0 , 0 ,doo+endstat; 0 end statement 0 , 0 ,out+newline,doo+endline; 1 end line 0 , 0 , 0 ,doo+notimpl; 2 0 , 0 , 0 ,out+xxforw ; 3 end logical if con+arifneg,doo+arif0 ,aux+gocond ,doo+arifpos; 4 end arith. if 0 ,out+openfor,doo+copy1 ,doo+copy1 ; 5 open format 0 ,out+closfor,doo+copy1 ,doo+copy1 ; 6 closed format 0 , 0 , 0 ,out+entrypoint; 7 main entry 0 , 0 ,doo+data,out+dataentry ; 8 data entry 0 , 0 , 0 ,out+xxforw ; 9 end formal decl ; ; h8+ format. 0 ,out+begfor ,doo+copy1 ,doo+copy1 ; 0 format begin 0 ,out+contfor,doo+copy1 ,doo+copy1 ; 1 format continue ; ; h9+ parameters. con+parform,doo+kindzon,out+loadw0a,doo+getaddr; 0 par zone 0 ,con+parform,doo+zarsplt,doo+getaddr; 1 par zone array ;con+zinzar ,out+subw1a ,aux+zarform,doo+getaddr; 2 par zone indic (not used) 0 , 0 , 0 ,doo+notimpl; (2 par zone indic not impl) ; ; h10+ zone commas. doo+towork2,aux+zcomma ,out+chupper,aux+top1f ; 0 zone indic comma out+zrechk ,doo+zelem ,aux+zrbase ,aux+top1f ; 1 zone subscript ; ; h11+ parameterno. doo+parno ,doo+rescu01,doo+rescuuv,doo+rescudr; 0 parameter count ; ; h12+ array range. 0 , 0 , 0 ,doo+rangeop; 0 ranges ; ; h13+ enter + exit. 0 , 0 ,doo+topdown,out+entry ; 0 entry 0 ,doo+retway ,doo+retexit,out+return ; 1 return 0 ,out+gors ,out+stop ,aux+top1f ; 2 stop ; ; h14+ goto + labels. con+asslab ,doo+outop ,out+prepjump,doo+topnext; 0 assign label 0 , 0 ,out+label ,doo+copy1 ; 1 declare label 0 ,doo+topdown,doo+outop ,out+gosimpl; 2 goto label 0 ,out+gors ,out+gopoint,aux+top1f ; 3 goto assigned 0 ,out+complist,doo+compgo ,aux+top1f ; 4 goto computed ; ; h15+ logical ops. out+relation,doo+relsign,doo+topreg,aux+relasub; 0 relation 0 , 0 ,out+xxforw ,doo+toplog ; 1 logpoint \f ;/action table 3 ; action4 , action3 , action2 , action1 ; ; ; h16+ do. 0 , 0 ,con+doloop ,aux+doinit ; 0 do general 0 , 0 , 0 , 0 ; 1 do special 0 , 0 ,con+dofirst,doo+rescu01; 2 do equal general 0 , 0 , 0 , 0 ; 3 do equal special 0 , 0 ,out+xxforw ,aux+doass ; 4 do init general doo+topnext,aux+doloop ,aux+doinit ,aux+doass ; 5 do init special 0 , 0 , 0 , 0 ; 6 do until con+dotest ,aux+domult ,aux+dostep ,doo+setint ; 7 do step 0 ,out+xxforw ,out+gobackw,out+xxchang; 8 do terminate ; ; h17+ read-write. out+xxforw ,out+gors ,out+readinit ,aux+callout; 0 read initiate out+xxforw ,out+gors ,out+writeinit,aux+callout; 1 write initiate out+xxforw ,out+gors ,out+readcall ,aux+callout; 2 read call out+xxforw ,out+gors ,out+writecall,aux+callout; 3 write call ; ; h18+ implied do. 0 , 0 , 0 ,con+doinit ; 0 implied begin 0 , 0 , 0 ,con+doloop ; 1 implied do ; ; h19+ trouble. 0 , 0 , 0 ,out+troubla; 0 trouble 0 , simlock ,doo+opset ,out+troubla; 1 trouble operand ; ; h20+ conversion. con+itol ,con+itolin7,doo+monocon,doo+typint ; 0 i conv l 0 , 0 ,con+itor ,doo+typint ; 1 i float r 0 ,con+rtod ,aux+itor ,doo+typint ; 2 i float d 0 ,con+rtoc ,aux+itor ,doo+typint ; 3 i float c con+ltoi ,con+ltoiin7,doo+monocon,doo+typ4 ; 4 l conv i 0 , 0 ,con+ltor ,doo+typ4 ; 5 l float r 0 , 0 ,con+ltod ,doo+typ4 ; 6 l float d 0 ,con+rtoc ,aux+ltor ,doo+typ4 ; 7 l float c 0 , 0 ,con+rtoi ,doo+typ4 ; 8 r trunc i 0 , 0 ,con+rtol ,doo+typ4 ; 9 r trunc l 0 , 0 ,con+rtod ,doo+typ4 ; 10 r conv d 0 , 0 ,con+rtoc ,doo+typ4 ; 11 r conv c 0 ,con+rtoi ,aux+dtor ,doo+typ8 ; 12 d trunc i 0 , 0 ,con+dtol ,doo+typ8 ; 13 d trunc l 0 , 0 ,con+dtor ,doo+typ8 ; 14 d trunc r 0 ,con+rtoc ,aux+dtor ,doo+typ8 ; 15 d conv c 0 ,con+rtoi ,aux+ctor ,doo+typ8 ; 16 c trunc i 0 ,con+rtol ,aux+ctor ,doo+typ8 ; 17 c trunc l 0 , 0 ,con+ctor ,doo+typ8 ; 18 c conv r 0 ,con+rtod ,aux+ctor ,doo+typ8 ; 19 c conv d 0 ,doo+topup ,doo+leave ,doo+toplow ; 20 next ; ; h29+ exponents. con+xitor ,doo+toplow ,doo+square ,doo+typint ; 0 integer**integer con+rpowi ,aux+sspower,doo+square ,doo+typ4 ; 1 real **integer con+power ,out+lexpoi ,aux+sspower,doo+typ4 ; 2 long **integer con+xdexpod,aux+rtod ,aux+itor ,doo+typint ; 3 double **integer con+power ,out+rexpor ,aux+sspower,doo+typ4 ; 4 real **real 0 , 0 ,con+xdexpod,doo+rescudr; 5 double **double 0 ,con+xdexpod,aux+rtod ,doo+typ4 ; 6 double **real ; ; h30+ pass info. 0 , 0 ,doo+outentr,doo+workset; 0 area simple 0 , 0 ,doo+copy3 ,doo+areas ; 1 area c. (:(:k-1-acttab:) a. 2.11:) - 1 m.*** formaterror main action table z. \f ;/ action table 4 typedep4 = k + 3 - acttab ; byteindex of first type action typedep = typedep4 > 2 typedepn = -(:(:typedep+7:)>3:)<3 ; action4 , action3 , action2 , action1 ; typedependant bytes. ; ; h21+ data init. con+datanew,out+addw1a ,doo+outop ,out+loadw1a; 0 data initiate ; ; h22+ arithmetic. 0 , 0 , 0 ,doo+notimpl; 0 monadic minus doo+descres,doo+arithop,aux+topregf,doo+minus ; 1 dyadic minus doo+descres,doo+arithop,aux+topregf,doo+plus ; 2 plus doo+descres,doo+arithop,aux+topregf,doo+mult ; 3 multiply doo+descres,doo+arithop,aux+topregf,doo+divide ; 4 divide ; ; h23+ logicals. 0 , 0 ,doo+not ,doo+topreg ; 0 not doo+simres ,doo+mask ,aux+topregf,doo+and ; 1 and doo+simres ,doo+mask ,aux+topregf,doo+orsplit; 2 or doo+simres ,doo+shift ,aux+topregf,doo+topnext; 3 shift ; ; h24+ assignments. 0 ,doo+topfree,doo+store ,aux+topregf; 0 assignment 0 ,doo+topold ,doo+store ,aux+topregf; 1 multiple assign ; ; h25+ subscript. doo+asubscr,doo+outop ,out+addw1a ,doo+indic ; 0 indic 0 ,con+zoneq1 ,out+addw1a ,doo+zqindex; 1 zone eq array ; ; h26+ out+xxforw ,doo+callres,doo+call ,aux+callout; 0 call ; ; h27+ parameters. con+parlab ,doo+outop ,out+prepjump,doo+simsplt; 0 par simple doo+psubarr,out+subw1a ,aux+pardow2,doo+getaddr; 1 par subscr array con+pararr ,aux+dopupp ,aux+doplow ,aux+rangpar; 2 par array con+procfor,doo+parext ,doo+outop ,doo+prcsplt; 3 par procedure ; ; h28+ if. doo+ifarith,doo+topfree,doo+topreg ,doo+ifsplit; 0 if ; ; h6+ constant. 0 ,doo+constop, constk ,doo+opset ; 0 ; ; h31+ pararameter array. 0 ,doo+paramar, arrayk ,doo+opset ; 0 dirmax = (:k+3 - acttab - typedep4:)<1 - typedepn ; maximal value for pass 6 directing bytes c. (:(:k+3-acttab-typedep4:) a. 2.11:) - 1 m.*** formaterror typedependant action table z. \f ;/initiation of pass 7 w. actstack = k + actlng - 2 ; action stack. ; ; 5 double word entries are; ; ; reserved for the action stack opstack = actstack + 5*actlng +2; operand stack. ; ; entries of oplength are placed in ; ; the operand stack init7x: ; initiate pass 7. ; ; the code is overwritten by the ; ; action and operand stacks al w0 end7 ; am. (endbyte.) ; jl.w3 endbyte. ; gpa:outbyte(end of pass 7) am. (mode2.) ; rl.w2 mode2. ; w2 := gpa:more modebits for compilation rl.w0 cfw00. ; w0 := simple convert real to integer; so w2 truncbit ; if trunc.no then am. (trcinit.) ; rs.w0 trcinit. ; modify code; am. (mode.) ; set index check switch. rl.w2 mode. ; w2 := gpa:modebits for compilation al w0 swindex-checkix; w0 := set switch to take index act so w2 chindex ; if index.no al w0 curract-checkix; then w0 := switch to current act am. (ixcheck.) ; hs.w0 ixcheck. ; set index check switch al w0 doo+topfree ; w0 := dummy action so w2 chindex ; if index.no then rs.w0 ixcheck1. ; make no indexcheck with so w2 chindex ; formal- or actual arrays; rs.w0 ixcheck2. ; ; ; prepare arithmetic interrupt. al w0 -1 ; interrupt bit1 := bit2 := 1 so w2 spillbit ; if spill.no ls w0 -2 ; then bit1 := 0 ; bit2 := 1 am. (intinit.) ; al.w3 intinit. ; w3 := a:interrupt sequence jd 1<11 + 0 ; call monitor: set interrupt ; ; only bit1 and bit2 of w0 is used ; ; high precision set in pass 2 am. (mulinit.) ; rl.w1 mulinit. ; constant integer arithmetic instruction sh w0 0 ; if spill.yes am. (mulsoft.) ; rs.w1 mulsoft. ; then set software interrupt in mult \f ;/initiation 2 ; ; initiate pointers. al.w1 actstack. ; w1 := a:action stack am. (aastatop.) ; rs.w1 aastatop. ; action table top pointer al w1 x1-actlng ; am. (aastabot.) ; rs.w1 aastabot. ; initiate action stack bottom al.w1 opstack.-oplength ; w1 := a:operand stack - oplength am. (ooandbot.) ; rs.w1 ooandbot. ; operand stack bottom am. (ooandtop.) ; rs.w1 ooandtop. ; operand stack top pointer am. (last.) ; lastword defined at end rl.w2 last. ; w1 := a:last word to use al w2 x2-oplength ; - oplength am. (ooandlim.) ; rs.w2 ooandlim. ; operand stack limit jl. testinit. ; goto get directing byte endbyte: outbyte. ; distances used for far reaching mode: modebits. ; mode2: modebit2. ; trcinit: truncmod. ; cfw00: cf w0 0 ; (simple conversion) ixcheck: checkix.+1 ; intinit: intrupt. ; mulinit: mulspill. ; mulsoft: mulset. ; aastabot: acstabot. ; aastatop: acstatop. ; ooandbot: opandbot. ; ooandtop: opandtop. ; ooandlim: opandlim. ; last: lastword. ; distance to pass 0 lastword length7 = k - start7 ; length of pass in bytes e30 = e30 + length7 ; length := length + length pass 7; ; end of pass 7 instructions i. m. rc 83.08.29 fortran, pass 7 e. ▶EOF◀