! Changes made by PDS Oct 90 ! 1) Revisions to deactivated JAT/JAF code ! 2) Reactivation of JAT/JAF code ! 3) Update of Min Elevel ! ! NB `MOVE WORD` DESCRIPTORS ARE NOT GENERATED ! ALL VALUES ARE CONVERTED TO BYTES ! NEED TO ALTER `OP(MVW)` TO HANDLE WORD DESCRIPTORS. ! !* 23-10-90 :- Source clear to date to provide sound basis for WP2 (AA) !* Rename as i29gen30. !* !* V67 ILAN/???? Estkresult to use size given for integer !* types instead of assuming 4. ccomp134 !* !* V58 CCOMP130 ILAN0377 reload bform changed by LoadItem !* in note index. !* !* V57 CCOMP128 ILAN/0376 Force load index for negative !* subscript in note index. Instr generating routines !* assume unsigned. !* !* 09-07-90 :- Correct code at F(RegModAddr) in routine:Set BD for !* instances where the Stk_Cmval field is non-zero !* ie take account of constant modifier (see bug: ilan0355) !* 16-05-90 :- Eprocptr now an integerfn; fix for ccvs.extn33131 !* 09-05-90 :- Remove lines in EDbytes which check if length is 8, and if !* so does 2 called of Ed4 !* 24/apr/90 - Source clear V032 by scaling in oprx(regmodaddr) !* Source clearance for bug V030 to fn storeop !* 19/apr/90 - only load RHS to Breg if LHS=dirval and RHS=addr... !* 17/Apr/90 I29GEN29V5A !* made source cleareance to routine Note Index for bug V029 !* !* SOURCE CLEARANCE TO VERSION 5002 made on version 5001 file. !* !* 20/Feb/90 !* ! Added tracing to function Edbytes. !* !* 16/Feb/90 !* ! Fixed byg v019,ilan0329 by deleting PD4 call in EDataRef !* !* 3/Nov/89 !* ! Increase limits generally: ! ! 1/ Stkmax goes from 48 to 64. ( Size of Estack ) ! 2/ maxlab goes from 100 to 120. ( max labels per function ) ! 3/ Swmax goes from 40 to 90. ( max switches per function ) ! 4/ maxtemp goes from 256 to 300. ( max temporaries per ? ) ! !* I29GEN29v2 !* !* Src 10 CCOMP75 ZC864 Char or short in local struct and used as ! ILAN/0260 an array subscript, wrongly thought to ! occupy a word like elementary variables. ! 2 parts in extractmod and note index. ! The Stk_type field should be regarded as applying ! to the Modifier rather than the whole operand ! where a modifier is present. Where two operands ! are merged as in note index the _type field is ! set appropriately. ! ! Src 13 CCOMP69 ZC824 Locals chars and params are kept in 4 bytes, ! but if their address is passed to another ! function , it thinks it is only 1 byte. ! This can lead to incorrect top bytes. ! Fix is to mask after load to acc in ! Load Item. ! ! SRC 15 CCOMP57 A0008 Save regs before jump. ! Call Freeregs in Ejump after label jump: ! ! SRC 16 CCOMP68 ZC845 Compare with literal zero is no good for ! unsigned < <= > >= because jat/jaf ! are for signed comparism. ! Fall back on old code in these cases. ! ComparewithZero altered. ! ! SRC 17 CCOMP86 A0020 > 128k of Gla. ! 1/ Give an appropriate error message. ! Alter fn Glaspace to call ! Cerror(" PLT too large ",140... ! ! SRC 24 CCOMP95 A0039 Old switch jump code subtracted lower switch ! bound and got integer underflow if it was ! V. large negative. Add extra instruction ! to keep code safe. ! ! SRC 25 CCOMP64 ZC847 (*ptrtoptr)->structelement generates bad code. ! Side effect of triad addref is defer of array ! code leading to more complex eform than seen ! before. Add code to 'set bd' to cope with ! REGMODADDR. ! ! SRC 26 CCOMP91 ZC874 Withdraw new code for exploiting JAT/JAF ! 1/ return from ComparewithZero immediately ! with result = 0. ! 2/ relies on change to cobj not to generate ! JWtrue, JWfalse. ! 3/ Alter eop(logneg) to be like 40 and really ! establish a logical. ! ! SRC 32 Allow note index litval. ! !*************************************************************************** !* I29GEN29 Returning label Id from Eproc causes problem if later used !* as param to Eprocref. !* !* 22 Jun 89 : For C never return a negative Id (ie label no) from Eproc. !* !* I29GEN28 Fix _ASM() action on primary operators with non-default !* kp and kpp variants. !* !* 21 Jun 89 : Use supplied kp and kpp in primary operators when non-zero. !* !* I29GEN27 Add missing line to Ejump() !* !* 20 Jun 89 : At Op(JRGZ) etc in Ejump unlock register after Load Item. !* !* I29GEN26 Fix longstanding Eproc bug. !* !* 18 Jun 89 : In Eproc, when Id = -1 don't corrupt it by the call to ExName. !* !* I29GEN25 Fix _BUILTIN_ bug which caused crash when func ptr dereferenced. !* Fix "freeing unused temp" problem. !* Fix "params stacked in wrong order" problem. !* Fix "operand has no B&D" problem !* !* 17 Jun 89 : At F(RegVal) in Set BD add F(RegAddr) since identical for code !* generation purposes. !* In PushParam cope with param already in register and ACC holding !* previous param. !* !* 15 Jun 89 : In Op(DUPL) rearrange code so that IndTempModVal item with reg !* as modifier gets usage count of Temp part updated. !* !* 14 Jun 89 : Initialise _BUILTIN_asm's id value to 7FFFFFFF rather than 0. !* !* I29GEN23 Redirect maths library calls when appropriate - Spec Issue 068 !* Add support for inline assembler calls. Bug fixes. !* !* 9 Jun 89 : In Load Item unlock register after discovering it is a parameter. !* !* 5 Jun 89 : In MultiplyByLit enhance check for register form when lit is !* zero - YC820. !* !* 1 Jun 89 : Add general support for builtin functions plus specific routine !* for inline assembler. !* !* 30 May 89 : In FindExternalName change mathslib references to ANSI versions !* if appropriate. !* !* I29GEN22 Object code improvements and Plum Hall error correction. !* !* 19 May 89 : Add call of Establish Logical if reqd at start of Cop(ECRESTORE). !* Remove call of Stackr in Cop(LOGNEG) since CCset is being set. !* !* 18 May 89 : Add code at Eop(INDEX) to catch compile-time calculations. !* !* I29GEN21 Plum Hall corrections + #pragma ICLCALL change. !* !* 15 May 89 : Reinstate Elevel -= 1 at Cop(LOGVAL). !* !* 12 May 89 : In Elabel check for possibility of ACC being a runtime parameter !* and store it at TOS if so. Do same in Ejump. !* !* I29GEN20 Plum Hall corrections !* !* 3 May 89 : Allow for second (unused) operand to ECPROCCALL (as Graham's !* memo of some time ago. !* !* 3 May 89 : Reinstate Stackr(ACCR, 4) at Cop(LOGSTK) since LOGSTK preceeded !* by Elabel which destroys register memory. !* !* I29GEN19 Incorporate patches !* !* 10 Apr 89 : Incorporate 40.01 patches YC740, YC753, YC770, YC774 and !* YC775 !* !* I29GEN18 !* !* 7 Apr 89 : Add new C jumps JWFALSE AND JWTRUE to Ecjump. !* Use _Type field in Estkfmt to distinguish local scalar !* shorts and chars from local struct members. !* Remove some unnecessary masking instructions. !* !* I29GEN17 More performance improvements !* !* 4 Apr 89 : Make ecjump just call ejump - do not set CCset !* !* 4 Apr 89 : Allow short form of ADB at label Modify in Set BD !* !* 4 apr 89 : Check for local scalar chars and shorts in Set BD and !* treat as words !* !* I29GEN16 Performance improvements !* !* I29GEN15 for Release 40.01 !* !* 3 May 88 : Bug XC699 / RL557 !* Just return if ProgFaulty <> 0 in ESwitchEntry, !* ESwitchDef and ESwitchJump. !* !* 2 May 88 : Bug XC693 / HC058 !* Add actions 6 & 7 to EDebugAction. !* !* 1 May 88 : Spec Issue 050 !* Don't mask size errors in MPSR issued by Eproc and mask RHS !* operands in Storeop if LHS < 4 bytes. !* !* 29 Apr 88 : Spec Issue 012 !* Implement new C-specific Ecode op ESTRLEN which consumes !* the pointer at ETOS and stacks the length of the string !* pointed at. !* !* 8 Apr 88 : Bug XC??? / HC050 !* Check / save ACC before use in EDebugAction. !* !* 6 Apr 88 : Bug XC647 / DA002 !* In Eprecall return if ProgFaulty <> 0 !* !* 31 Mar 88 : Bug XC654 / DA003 !* Fix ESTBITS when Ecdupflag set. !* !* 30 Mar 88 : Implement CJFALSE in EJump. !* !* 15 Mar 88 : Add EDebugAction and ENextCA for ITS. !* !* I29GEN13 !* !* 8 Feb 88 : Bug XC603 / RL550 !* In CompiletimeCalc include all register based operand forms !* in operand checks. !* !* 29 Jan 87 : Bug XC.../RL303 !* At RegModAddr case in SetBD, end up by going to appropriate !* temporary case instead of always going to F(IndTempModVal). !* !* 26 Jan 87 : Bug XC.../RL296 !* In ExtractMod and OpRX don't forget to check for !* a constant modifier. !* !* 26 Jan 88 : Bug XC609 / RL289 !* Don't forget the constant modifier when address rather than !* value reqd at F(DirModAddr) in Set BD. !* !* 20 Jan 88 : Bug XC591 / RL286 !* Add separate code for F(AddrDirMod) in Set BD. !* !* 6 Jan 88 : I29GEN11 for Release 30.01 !* !* 22 Dec 87 : At Cop(ECPROCCALL) invalidate all regs after call. !* !* 22 Dec 87 : Bug XC436 / VX022 !* Make EXname maintain a list of known external names and not !* just generate a new reference as a matter of course. !* !* 17 Dec 87 : I29GEN10 for Release 25.06 !* !* 17 Dec 87 : In Storeop move the checking/invalidating of the base regs !* to after the store is emitted. !* !* 11 Dec 87 : Bug XC... / RX043 !* At Op(DUPL) correct bug where Lstk_Reg's Ruse entry was !* updated rather than Lstk_Modreg's entry. !* !* 7 Dec 87 : I29GEN09 for Release 25.05 !* !* 3 Dec 87 : Move fix up of GLA+8 to UST from Einitialise to Eterminate !* and only do it if UST has been created! !* !* 3 Dec 87 : In Einitialise don't generate fix ups to DIAG, STATIC !* or CNST on VME. !* !* 2 Dec 87 : Bug CX... / HX027 !* In New Temp check base regs in case they are holding a !* previous version of the temp being reused. !* !* 2 Dec 87 : Bug XC... / HX026 !* Try to make Convert UU a bit more sensible. !* !* 30 Nov 87 : I29GEN08 for Release 25.04 !* !* 29 Nov 87 : Bug XC493 / RX015 !* Set the Regflag bit in the RegModAdr => IndRegModVal entry !* of table Erefform. !* !* 27 Nov 87 : Bug XC511 / VX036 !* At Op(DUPL) add code to deal explicitly with IndRegModVal. !* !* 27 Nov 87 : Bug XC489 / RX011 !* Add code at Op(DUPL) and Op(DISCARD) to deal with modifiers !* which are temporaries. !* !* 25 Nov 87 : Bug XC489 / RX011 !* In sparse jump unlock ACC after loading switch expression. !* !* 25 Nov 87 : Bug XC422 / HX020 !* In Note Index at F(IndDirVal) do NOT follow the Fortran path !* for C. !* !* 25 Nov 87 : Bug XC428 / HX024 !* In Convert IR sign extend I if it is less than a word. !* !* 25 Nov 87 : Bug XC427 / HX023 !* Near Lengthen: in Binary Op unlock ACC after lengthening RHS. !* !* 25 Nov 87 : Bug XC429 / HX025 !* At Cop(U...ST) mask the result if it is less than a word. !* !* 25 Nov 87 : Bug XC424 / HX021 !* At Op(DUPL) don't load the item for all modified operands, only !* the ..addr.. forms. !* !* 25 Nov 87 : Bug XC405 / VX009 !* Add CheckConflict and use it to invalidate XNB/CTB if reqd !* when doing a store into a direct operand. Invalidate these !* regs unconditionally when doing an indirect store or struct !* assign. !* !* 25 Nov 87 : Bug XC425 / HX022 !* Add TNCRU to Ecodes and Enames and support it in Eop(). !* !* 4 Nov 87 : I29GEN07 Release 25.03 !* !* 4 Nov 87 : Use ECODES23 & ENAMES23 to pick up UMULT. !* !* 4 Nov 87 : I29GEN06 !* !* 4 Nov 87 : Bug XC385 / RX006 !* Insert test for CCset at Cop(CEVAL). !* !* 30 Oct 87 : At Cop(ELDBITS) don't perform the AND for fields which start !* at LHS of a word (since the USH has zero filled). !* !* 26 Oct 87 : Fix bug in Convert II whereby conversions to non-word sizes !* used wrong shift amounts. !* !* 26 Oct 87 : Bug C363 / HX006 !* In Convert IU go via Convert II if oldsize < newsize. !* !* 23 Oct 87 : In Note Index at F(IndDirVal) make C follow the Fortran path !* - it used to but at some point CMcP commented out the test. !* !* 22 Oct 87 : Bug C360 / HX003 !* At Op(DUPL) in Eop set [Mod]Base to zero in the two cases !* where a new temporary is created. !* !* 22 Oct 87 : Extend reuse of temporaries scheme to deal with DUPL 'd temps. !* !* 22 Oct 87 : Bug C358 / HX001 !* In Epromote check for CCset and call Establish Logical if reqd. !* !* 22 Oct 87 : I29GEN05 Release 25.02 !* !* 22 Oct 87 : Bug C... / HX013 !* In Convert UR reload ACC with LSD or LSS not LUH ! !* !* 22 Oct 87 : Bug C365 / HX008 !* In Convert II when reducing the size get the USH & ISH round !* the right way. !* !* 20 Oct 87 : Add code to Convert II & Convert UI to deal with literal opnds. !* Initialise Depth in EInitialise. !* !* 19 Oct 87 : Replace New Temp and introduce Free Temp in new temporary-reuse !* scheme. !* In Binary Op ensure operands get sign extended if required for !* the integer compare Eops. !* Add some constant-folding to Int Unary Op. !* !* 12 Oct 87 : I29GEN04 !* !* 12 Oct 87 : In ESparseSwitch fix descriptor up to Ad, not 0. !* !* 12 Oct 87 : At Op(EDUPSTORE) don't make size of duplicate 4 regardless - !* mucks up later CVTxx ops. !* !* 12 Oct 87 : In Eswitch check for CCset and call Establish Logical if reqd. !* !* 7 Oct 87 : In Elabel remove test for non-empty Estack (a la Gould). !* !* 6 Oct 87 : In Set BD set Cmval field to zero after each use of it. !* !* 6 Oct 87 : Add test of CCset to Cop(LOGNEG). !* Revise Convert RI (was wrong in case of 4-byte reals). !* !* 6 Oct 87 : In Eproc always assign an external-type value to Id for C if !* Id is -1 on entry. !* !* 5 Oct 87 : Add code to Cop(ESTBITS) to check Ecdupflag. !* !* 5 Oct 87 : Extend MinElevel array to cater for ECDUP. !* !* 5 Oct 87 : In Eproc set the program mask to ignore size errors for C. !* !* 4 Oct 87 : Major surgery on the CVT... Eops. !* !* 4 Oct 87 : Tidy up diagnostic printing. !* !* 4 Oct 87 : I29GEN03 !* !* 2 Oct 87 : Steal some enhancements to Cop(ECSTORE) from Gould compiler. !* !* 2 Oct 87 : In Edataref zeroise the word to contain the reference. !* !* 1 Oct 87 : Change implementation of Cop(ECPROCCALL) to suit VME C. !* !* 1 Oct 87 : In Load Modifier take constant modifier into account if !* modifier mode is LitVal. !* !* 30 Sep 87 : At two places in Set BD set Stk_Cmval to 0 after use. !* !* 30 Sep 87 : Correct a fault in the call of Bounded Jump from Efswitchjump !* for C (was subtracting one from upper). !* !* 29 Sep 87 : In OpRX recognise a LB from ACC (form Regaddr,Regval,Fregval) !* and turn it into ST B. !* !* 29 Sep 87 : Improve code generated for PUSHBYTES Eop (use CYD). !* !* 29 Sep 87 : Add Compiletimecalc to fold expressions involving (integer) !* literals. Also change spec of Multiply by Lit. !* !* 29 Sep 87 : Implement EZERO Eop. !* !* 27 Sep 87 : In Eop at xxxxST cases change Opcode-UADDST to Opcode-IADDST !* in unsigned branch. !* !* 27 Sep 87 : Alter Ecall2 for C - only reload CTB if required and load !* DR from LNB+3 before an internal call. !* !* 25 Sep 87 : Store current LNB at (LNB+3) for C. !* !* 23 Sep 87 : Use ECODES20A & ENAMES20A !* Implement UREM & UDIV and change UADDST, USUBST, UMULST to !* do unsigned operations. !* Call Setbaseofarea at AddrDirModVal case in SetBD. !* !* 22 Sep 87: I29GEN02 !* !* 22 Sep 87 : Add ESparseSwitch and SparseJump !* !* 21 Sep 87 : I29GEN01 !* !* 14 Sep 87 : In EfswitchJump make the bounded jump call a special for C. !* !* In Eproc don't generate the J +3 and LD (XNB+3) if language is C. !* In EXname zeroise the 8 bytes of GLA claimed for ext proc ref. !* In Efswitchjump cater for C's eccentricities. !* At F(RegModAddr) in OpRX add code to cope with Breg being the Reg... . !* At Op(DUPL) deal with IndRegVal as for RegAddr & FregVal. !* In BinaryOp ensure LHS is simple RegVal before generating a BREG instruction !* In SetBD move cases TempAddr & DirAddr to be same as TempVal & DirVal. !* Add frig to Note Index to cater for C's misuse of EINDEX. !* Make Basereg return the correct value in its last statement. !* Make boundedjump issue a CPB rather than a UCP. !* Altered Eproc to set up a 'display' (of current stack frame) for C !* Introduced Convert IU to support CVTIU and CVTUI. !* Brought up to date with ecodes19 ! !* modified 16/07/86 !* %constinteger increports=1 %owninteger Report=0 %owninteger Decode %owninteger Language !* %constinteger IMP = 1 %constinteger FORTRAN = 2 %constinteger CCOMP = 11 %constinteger PASCAL = 14 !* !*********************************************************************** !* Exports * !*********************************************************************** !* %routinespec Einitialise(%integer Lang, Avertext, Astackca, Aglaca, Options) %routinespec Eterminate(%integer adareasizes) %routinespec Ecommon(%integer area, %stringname Name) %routinespec Eendcommon(%integer area, Length) %routinespec Elinestart(%integer lineno) %routinespec Elinedecode %routinespec Emonon %routinespec Emonoff %routinespec Efaulty %integerfnspec Estkmarker %routinespec Esetmarker(%integer Markerid, New Value) %integerfnspec Eswapmode !* %routinespec Estklit(%integer Val) %routinespec Estkconst(%integer Len, Ad) %routinespec Estkdir(%integer Area, Offset, Adid, Bytes) %routinespec Estkind(%integer Area, Offset, Adid, Bytes) %routinespec Estkglobal(%integer Level, Offset, Adid, Bytes) %routinespec Estkpar(%integer Level, Offset, Adid, Bytes) %routinespec Estkparind(%integer Level, Offset, Adid, Bytes) %routinespec Estkresult(%integer Class, Type, Bytes) %routinespec Erefer(%integer Offset, Bytes) %routinespec Epromote(%integer Level) %routinespec Edemote(%integer Level) %routinespec Estkaddr(%integer Area, Offset, Adid, Bytes) !* %routinespec Elabel(%integer id) %routinespec Ediscardlabel(%integer id) %routinespec Ejump(%integer Opcode, Labelid) %routinespec Etwjump(%integer Opcode, Lab1, Lab2, Lab3) %routinespec ESparseSwitch(%integer Lower, Upper, Entries, Switchid, %c Errlabid, %integername SSTad) %routinespec Eswitch(%integer Lower, Upper, Switchid, Errlabid, %integername SSTad) %routinespec EswitchJump(%integer Switchid) %routinespec EfswitchJump(%integer Switchid) %routinespec Eswitchentry(%integer Switchid, Entry) %routinespec Eswitchdef(%integer Switchid) %routinespec EswitchLabel(%integer Switchid, Entry, Labelid) !* %routinespec Ed1(%integer area, Disp, Val) %routinespec Ed2(%integer area, Disp, Val) %routinespec Ed4(%integer area, Disp, Val) %routinespec Edbytes(%integer area, Disp, len, ad) %routinespec Edpattern(%integer area, Disp, ncopies, len, ad) %routinespec Efix(%integer area, disp, tgtarea, tgtdisp) !* %externalintegerfnspec EXname(%integer type, %string(255)%name Xref) %routinespec Eprecall(%integer Id) %routinespec Ecall(%integer Id, Numpars, Paramsize) %routinespec Ecall2(%integer Id,Extlevel,Numpars,paramsize) %routinespec Eprocref(%integer Id, Level) %routinespec Esave(%integer Asave, %integername Key) %routinespec Erestore(%integer Asave, Key, Existing) !* %integerfnspec Enextproc %routinespec Eproc(%stringname Name, %integer Props, Numpars, Paramsize, Astacklen, %integername Id) %routinespec Eprocend(%integer Localsize, Diagdisp, Astacklen) %routinespec Eentry(%integer Index,Numpars,Paramsize, Localsize, Diagdisp, %stringname Name) !* %routinespec Edataentry(%integer Area, Offset, Length, %stringname Name) %routinespec Edataref(%integer Area, Offset, Length, %stringname Name) !* %routinespec Eop(%integer Opcode) %routinespec Ef77op(%integer Opcode) %routinespec Epasop(%integer Opcode) %routinespec Eccop(%integer Opcode) %integerfnspec EDebugAction(%integer action, param) %integerfnspec ENextCA !* !* !*********************************************************************** !* Imports * !*********************************************************************** !* ! %include "put29_specs" {*********************} {* 2900 EMAS *} {* PUT INTERFACE *} {* February 1984 *} {*********************} { This is those low level code and object generation routines which are common} { to our compilers in the EMAS environment. } {* Standard code planting routines *} ! HEALTH WARNING ! ****** ******* ! ! If the PUT code planting routines area called drirectly rather than ! through th internal interfaces (OpLIT2,PSORLF1,OpBREG2 etc) The automatic ! invalidation of tracked registers is by-passed. You will have to maintain ! the tracking information on a DIY basis. If in doubt always use the INTERnal ! versions ! {* Primary format *} %externalroutinespec Plf1(%integer OpCode,KP,KPP,N) { Plant the 32 bit form, regardless of N } %externalroutinespec OpDir(%integer Op,Reg, N) ! Plant direct form of primary, Reg eqv to K'' in PLI %externalroutinespec OpDRMod(%integer Op, Reg, N) ! Plant indirect form, desc in DR modified, of primary instruction ! Reg is again equivalent to K'' %externalroutinespec OpDesc(%integer Op, Reg, N) ! Plant indirect form, desc in store, of primary instruction ! Reg is again equivalent to K'' %externalroutinespec OpDescMod(%integer Op, Reg, N) ! Plant indirect form, desc in store modified, of primary instruction ! Reg is again equivalent to K'' {* Secondary instructions *} %externalroutinespec Op2FilMsk(%integer Op,H,N,Mask,Filler) ! Plant secondary 32 bit format instruction %externalroutinespec Op2NoFM(%integer Op, H, N) ! Plant secondary 16 bit format instruction {* Tertiary instructions *} %externalroutinespec Op3Lit(%integer OP,Reg,N,Mask) ! Plant a tertiary 32 bit format instruction %externalroutinespec Op3NoL(%integer Op, Reg, Mask) ! Plant a tertiary 16 bit format instruction {* Special, commonly used instruction formats *} %externalroutinespec OpLit(%integer Op,N) { Plant a direct primary format instruction with literal operand. } %externalroutinespec OpLnb(%integer Op,N) { Plant the a direct primary format instruction with (LNB+N) operand.} %externalroutinespec OpLnbDesc(%integer Op,N) { Plant the short form of indirect primary format instruction with } { ((LNB+N)) operand. } %externalroutinespec OpTos(%integer Op) ! equiv to OPDIR(OPCODE,TOS,0) %externalroutinespec OpBreg(%integer Op) { Equiv to OpDir(Op,Breg,0) } %externalroutinespec OpPc(%integer OpCode,%integername Base) %externalintegerfnspec PMarker %externalroutinespec PSetOpD(%integer MarkValue, NewValue) %externalroutinespec PLabel(%integer LabelId) { Note a label at CA, LabelId being assigned by the code generator } %externalroutinespec PJump(%integer Op, LabelId) { Plant jump instruction, filling in address for backward jumps } %externalroutinespec Pmaskjump(%integer op,mask,Labelid) { Plant conditional jumps via the masked form rather than the sfl mnemonic} %externalroutinespec PSwitch(%integer Label, Lower, Upper,%C %integername Glaca) { Note a Case and plant a jump for it. Label identifies the Case } { Lower and Upper are the bounds and Reg is Xnb or Ctb, pointing at Gla } { The value of the Case expression is assumed to be in the Acc } %externalroutinespec PSLabel(%integer Label, Index) { Fill in entry Index in the jump table for Case Label with CA } %externalroutinespec PSDefault(%integer Label) { Fill in all currently undefined entries for Case Label with CA } {* Put Interface Passing of Data *} %externalroutinespec PDBytes(%integer CurArea, Disp , len, ad) %externalroutinespec PD4(%integer Area, Disp, Value) ! Plant a 4 byte value at Disp in Area, using unbuffered areas %externalroutinespec PDPattern(%integer Area, Disp, NCopies, Len, Ad) {* Put Interface RELOCATION and REFERENCES *} %externalintegerfnspec PXname(%integer type,%string(255) %name s,%integer Glaca) { Create an external code reference } { Xrefs are used many times so establish mapping to integer ID early} { and save on holding/passing of strings } %externalroutinespec Pfix(%integer Hostarea, Disp, TgtArea,TgtDisp) { A relocation request: set word in area, displacement = 'disp' bytes, } { the address of area 'targetareaid', displacement = targetdisp.} %externalroutinespec PfixI(%integer Op,TgtArea,TgtDisp) { Plant a relocated instruction, where the operand is PC relative?} %externalroutinespec PDXRef(%string(255) Name, %integer Area, Disp, Minlength) { Define an external data reference } %externalroutinespec PDataEntry(%string(255)%name Name,%integer Area, %c Maxlen, Disp) ! The next five routines deal with PROCEDURES %externalintegerfnspec PNextSymbol { reserve a space in the symbol table } %externalroutinespec Pentry(%integer Id,Main,%string(*)%name s,%c %integername Glaca) %externalroutinespec Pproc(%string(255) %name name, %integer props, %c %integername ID,Glaca) { Start a new procedure } { PROPS&1 = external } { PROPS&2 = No ASFW } { PROPS>>31 = Main entry } %externalroutinespec PProcEnd(%integer LocalSize) { End of routine } !%externalintegerfnspec PProcXref(%string(255) Name) { Define an external reference, for use by PCall } !%externalroutinespec PLoadProc(%integer Id, Op) { Load address of a descriptor for a procedure into Acc, using Op } { Op must be one of Lss,Lb,Lda,Lxn or Lct } !%externalroutinespec PCall(%integer Id, Reg) { Plant a call to the routine previously specified to PNextSymbol, } { PProc or PProcXRef. Assumes Reg holds Gla start address. } %externalintegerfnspec Pcommon(%string(255) %name Name) %externalroutinespec PEndCommon(%integer Id,Length) %externalroutinespec Pfaulty { Code generator has encountered a user error. Code requests should no } { longer be checked and minimum work done in PUT } %externalroutinespec PLineStart(%integer Line) { Updates latest line number } %externalroutinespec PInitialise(%integer Version,Release,Language) { Start code generation } %externalroutinespec PCtable(%integer len,Ad) {Must be called immediately before PTerminate} { Adds the constant area to back of code and turns all refs to consts} {Specified as area 10 instead oc XNB or CTB into PC+n forms} %externalroutinespec PTerminate(%integer AdAreaSizes) { Code generator closes with this call } { Set Code size etc. } ! PGenerate - final phase of compilation is create object file %externalroutinespec PGenerateObject(%string(255) %name objfilename ) { Not really needed on EMAS} %externalroutinespec PMonON %externalroutinespec PMonOFF %externalroutinespec PTraceOn ! put on Heap(Line,CA,Recodestart) %externalroutinespec PTraceOff ! Put on Heap(-1,CA,Recodestart) %externalintegerfnspec PNextCA ! return next code offset {* Pseudo - Operations *} %externalroutinespec Op3Extra(%integer OpCode, Reg, N) { Plant the tertiary equivalent of the SFL conditional jumps } { The following consts represent these areas in this interface } %constinteger Code = 1, Gla = 2, { Unused = 3 } SST = 4, UST = 5, Diags = 6, Static = 7, IoTab = 8, ZGST = 9, Cnst = 10 %externalroutinespec LPut312(%integer val) %externalroutinespec LPut314(%integer val) %externalroutinespec PFixLabel(%integer label) %externalroutinespec OpPCRel(%integer op, kp, kpp, label) ! %include "ebits_ecodes23" ! !************************************************************************ !* * !* G.E.Millard * !* ECODES23 21/10/87 * !* * !************************************************************************ ! {00} %constinteger HALT = 0 ! !--------------------------------------- generic int operations ------- ! {01} %constinteger IADD = 1 { (Etos-1) + (Etos) => (Etos) } {02} %constinteger ISUB = 2 { (Etos-1) - (Etos) => (Etos) } {03} %constinteger IMULT = 3 { (Etos-1) * (Etos) => (Etos) } {04} %constinteger IDIV = 4 { (Etos-1) / (Etos) => (Etos) } {05} %constinteger INEG = 5 { - (Etos) => (Etos) } {06} %constinteger IABS = 6 { abs( (Etos) ) => (Etos) } {07} %constinteger IREM = 7 { remainder from } { (Etos-1) / (Etos)=> (Etos) } ! {08} %constinteger IAND = 8 { (Etos-1) & (Etos) => (Etos) } {09} %constinteger IOR = 9 { (Etos-1) ! (Etos) => (Etos) } {0A} %constinteger INOT = 10 { ~ (Etos) => (Etos) } {0B} %constinteger IXOR = 11 { (Etos-1) !! (Etos) => (Etos) } {0C} %constinteger ISHLL = 12 { (Etos-1) << (Etos) => (Etos) } {0D} %constinteger ISHRL = 13 { (Etos-1) >> (Etos) => (Etos) } {0E} %constinteger ISHLA = 14 { arithmetic left shift } {0F} %constinteger ISHRA = 15 { arithmetic right shift } ! {10} %constinteger IGT = 16 { if } {11} %constinteger ILT = 17 { (Etos-1) (Etos) } {12} %constinteger IEQ = 18 { then } {13} %constinteger INE = 19 { true (1) => (Etos) } {14} %constinteger IGE = 20 { else } {15} %constinteger ILE = 21 { false (0) => (Etos) } {16} %constinteger BNOT= 22 { (Etos) = BNOT (Etos) 0<->1 } ! {18} %constinteger JIGT = 24 { if } {19} %constinteger JILT = 25 { (Etos-1) (Etos) } {1A} %constinteger JIEQ = 26 { then } {1B} %constinteger JINE = 27 { ->