H------------------------------------------------------------------------!_Title: Praxis News Issue 3"_File: [PRAXISDOC.NEWS]issue3.txt/_Author: J. M. Duffy _Created: 27-JAN-1981H------------------------------------------------------------------------Introductory Notes:HSince we are using and reporting bugs more than one Praxis compiler, theKconvention of this document will be to explicitly name the version to whichEthe item refers. For example, " ..... generates bad code on VAX." TheKcompilers are: VAX, PDP, and RSX. Any problem statement that does not name@a particular machine will be assumed to refer to ALL compilers. HSince it is worthwile to document how the compilers have actually gottenIbetter, we have added a section called: "Improvements". In that section,Ewe will list new optimizations and improved operations that have been discovered. 'The current status of the compilers is:compiler: Old current New--------- --- ------- --- Vax->Vax 16-sep 03-dec 03-dec Vax->PDP 16-sep 03-dec 03-decF---------------------------------------------------------------------- Compiler Operation Changes:F----------------------------------------------------------------------.Cmp - 3.1: Argument passing changed on PDP-11.D The order of the parameters, as passed to procedures and functions,Khas changed in the new versions. This is VERY IMPORTANT for those that areJinterfaceing to machine language or Fortran routines. In order to make theJcode more similar on the VAX and PDP-11 versions, they have structured theCPDP-11 calling sequence somewhat along the lines of the VAX callingIstandard. Therefore any machine language routine MUST BE RECODED, if itFtakes more that one argument. Let us illustrate by way of an example:  Main module Example Procedure Use_example ( a : integer,  b : inout ref integer,+ c : inout ref array [1..?n] of boolean )$ . . . // body of the procedure endprocedure Declare x, y : integer z : array [1..20] of boolean endeclare ... Use_Example ( x, y, z ) ... endmodule HThe above call to Use_example sets up the stack in the following manner: | . |) | . | Stack offset How to get value:) | . | ------------ ----------------- +---------------+  | 0 | // Dummy value. +---------------+ | Value: 20 | 10 10(sp)  +---------------+ | Address of: z | 6 @6(sp)  +---------------+ | Address of: y | 4 @4(sp) +---------------+ | Value of: x ! 2 2(sp) +---------------+ | Old PC | 0 (sp) +---------------+GThat is how the stack looks when a machine language routine is called. EFor a praxis routine that is to use code brackets, the stack has moreEinformation on it, although the order is the same. Often, the routineF.SAVR1 is called to save the registers R1 thru R5. When this is done, the stack is as follows:  | . |) | . | Stack offset How to get value:) | . | ------------ ----------------- +---------------+  | 0 |  +---------------+ | Value: 20 | 24 24(sp) +---------------+ | Address of: z | 22 @22(sp) +---------------+ | Address of: y | 20 @20(sp) +---------------+ | Value of: x ! 16 16(sp) +---------------+ | Old PC | 14 +---------------+ | Old R5 | 12 +---------------+ | Old R4 | 10 +---------------+ | Old R3 | 6 +---------------+ | Old R2 | 4 +---------------+ | Old R1 ! 2 +---------------+ | .SAVR1 return ! 0  +---------------+ HThe issue can be further complicated if the USE_EXAMPLE routine declaresGany dynamic variables. They would be allocated after the .SAVR1 returnGaddress and shift all of the offsets according to the ammount of space required.,CMP - 3.2: Change in PDP-11 Run-time system.> The code generated for the PDP-11 references a few procedures2in a module called: PRXLIB11. These routines are:) PRX$IN - Prx_Init: Initialize operaton.% PRX$RA - Prx_raise: Raise Exeption.: PRX$AS - Prx_Assert: Raise "Failed Assertion" exception.GThis module is stored in [prxlib]. Until a Full PDP-11 runtime libraryI9is setup, this object module must be explicitly linked. 7This module replaces: COLINI -EThe user should beware that the PRX$IN routine currently does not settEthe stack at any particular location. It is left where the operatingiJsystem, or down line loader last used it. We are working on a new version which will correct this problem.F---------------------------------------------------------------------- ImprovementsF----------------------------------------------------------------------<IMP - 3.1: .SAVR1 not called if no registers used on PDP-11.D If the pdp-11 compiler determines that no registers are used by theIcode generated for a procedure, the register saving routine .SAVR1 is notiGcalled. This improves the time spent calling and returning from simple procedures and functions.  dF---------------------------------------------------------------------- BUGSF----------------------------------------------------------------------BBug - 3.1: Incorrect Error Message on Import of Non-exported Item.? When one item on the Import list is not exported, the compiler-Fincorrectly states that all items on the import list are not exported.-Bug - 3.2: Use Statement Still does not work.,GBug - 3.3: No initialization for static structures with imported types.B If one declares a static variable of a type imported from anotherEmodule and that type has "initially" fields, then the variable is notuEinitialized at all. The correct amount of space is allocated, but no data is stored.dBBug - 3.4: Exponentiation operator (**) generates bad code on VAX.: The use of a statement: X := y ** 3 generates code thatwill not assemble. ABug - 3.5: Exponentiation operator (**)not implemented on PDP-11.t:Bug - 3.6: XOR of 1 bit logicals gives Error 98 on PDP-11. .MBug - 3.7: Use of Dynamic Arrays in Main modules generate bad code on PDP-11.D The pdp-11 code generated for accessing dynamic arrays in the outerFblock of main modules references the AP, which is a VAX register! ThisEproblem shows up at link time rather than at assembly time. The task Cbuilder cannot find the symbol AP. Using static arrays avoids this+ problem. -HBug - 3.8: Range notation in Select statements gives bad code on PDP-11.< Under certain situations, when ranges are specified in caseJstatements, strange run time bugs occur. Regardless of the selected value,Jno action (or the default action) is taken. Below is an example designedIto show what cases work and what cases do not. Although the example beloweEuses integer ranges, the same problem exists with enumerated ranges. m "Here is an example of the problem: main module example_2 declareV x, y : integer initially 2s! my_range is integer range 4..6h enddeclare // These generate BAD code. select x fromo case 1..4 : y := 2 endselect  select x from  case my_range: y := -2 endselect- // These generate correct code. select x from % case 4,5,6: y := -2 // this is ok- endselectA select x from  case 0: y := 3 case 1: y := 6 case 4..6: y := -2 - case 7: y := 4 default: y := 44- endselect  select x from - case 0: y := 0 case 1: y := 6 case 4..6: y := -2 - endselectO select x from- case 4..10 : y := 2 endselect- endmoduleIBy this set of examples, we have pinpointed the problem. First, based ondGthe actual number of choices that between which the choice is made, thebBcompiler decides whether to use a jump table format or a series ofDcompares. It turns out that if the series of compares is used for aIrange-denoted case, then bad code is generated. However, if the range isfDlarge enough, or if there are three or more cases, the compiler willFgenerate the table format. For small ranges, use the individual items,=separated by commas. ( See the first working example above.) r Bbug - 3.10: PDP-11 Registers exhausted on compilcated expressions.@ As previously known, the pdp-11 compiler will sometimes give anKerror when it detects that an expression is too complicated to be evaluatedRIusing the available machine registers. However, we have found some cases Iwhere no message is given, but the code does not assemble. For example:  Main module ptest declareh N=10c) matrix is array [1..n,1..n] of integer- speca : matrix- specb : matrix- spectrum : matrix temp : integer- enddeclare FOR I:= 1 TO N DO- FOR J:= 1 TO N DO- SPECTRUM [I,J]:=0 FOR K:= 1 TO N DO0 //******* does not work (just too complicated.) SPECTRUM [I,J] := a, SPECTRUM [I,J]+ SPECA [I,K] * SPECB[K,J] //******* works% temp := SPECA [I,K]*SPECB[K,J]i. SPECTRUM [I,J] := SPECTRUM [I,J] + temp //******* also workss temp := specb[k,j]- SPECTRUM [I,J] := -& SPECTRUM [I,J]+ SPECA [I,K] * temp ENDFOR- ENDFOR ENDFOR ENDMODULE>Bug - 3.11: Symbol Table names not correct on PDP-11 Listings.A The compiler uses the "RSX" version of the user's symbols in the Jsymbols table list. This means that all uses of the under-score characterGin names get converted to dollar signs. This is not serious, but is anoannoyance. It will be fixed.  fF---------------------------------------------------------------------- Miscellaneous Notes.F----------------------------------------------------------------------!Msc - 3.1: Reference: Syn - 2.1 E It is actually a bug that range literals are not valid in FOR loops.4Msc - 3.2: Symbol Table In "Wrong" place on listing.D It appears that the symbol table for a procedure gets listed not atHthe end of a procedure, but at the start of the next one. This causes aFproblem for those who use the NOVA STANDARD HEADER FORMATS. The symbolEtable often appears in the middle of the next header. Due to the LALRrFparsing technique used in the compiler, it is not the ocurrance of theKENDPROCEDURE keyword that triggers the listing of the symbol table, but the Gstart of the next valid non-comment keyword. One can trick the compiler Ainto puting the table after the end of the procedure by putting aa;semi-colon after the ENDPROCEDURE. ( i.e. Endprocedure; )