[comp.sys.transputer] Bug in Inmos TDS version D700D

larsac@daimi.dk (01/10/89)

To all users of the D700D product release of TDS:

There seems to be a serious bug in the D700D compiler.

The problem arises when using mutiple assignments, where the righthand 
side consist of a list of expressions. It must be emphased, that the 
expresions involved has to be of some complexity, in order to produce
the error.

For example, the following program segment is ok

     INT a, b, c:
     SEQ
       a, b, c := 1, 2, 3

    
but the one below sets the transputer error flag during compilation

     INT a, b, c:
     SEQ
       a, b, c := ((a+47)-47), ((b+147)-147), ((c+124)-124)


The problem is not restricted to expressions of type INT, also REAL64 
is affected. REAL32 has not been tested.

Another (more subtle) error, that may be a sideeffect of the one above,
is the return of a expresionlist in functions.

Take for example the segment below:

     INT, INT FUNCTION Id(VAL INT a, b)
       VALOF
         SKIP
         RESULT a, b
     :

     INT i, j:
     SEQ
       i := 1
       j := 2
       i, j := Id(i, j)

This will work as expected, ie the values of i and j will remain the same
after the call of Id. Likewise will the segment
 
     INT, INT FUNCTION Id(VAL INT a, b) 
       VALOF 
         SKIP 
         RESULT ((a+47)-47),((b+147)-147)
     :   
 
     INT i, j:   
     SEQ 
       i := 1 
       j := 2 
       i, j := Id(i, j)  
 
but if we instead take the segment

     REAL64, REAL64 FUNCTION Id(VAL REAL64 a, b) 
       VALOF 
         SKIP 
         RESULT ((a+47.0(REAL64))-47.0(REAL64),((b+147.0(REAL64)-147.0(REAL64))
     :   
 
     REAL64 i, j:  
     SEQ 
       i := 1.0 (REAL64) 
       j := 2.0 (REAL64) 
       i, j := Id(i, j) 
 
will the values of i and j after the call of Id be 2.0 and 1.0 respectively,
ie the expressionlist returned by Id is reversed.

A set of variations of the error can be obtained, by mixing INT and REAL64
in the expressionlist. This way all results, from correct ones, over 
reversal of the list, to undefined values, can be generated.

Note that these errors do not set the transputer error flag, it 'just' 
produces some inpredictible results at runtime.
 

One way to avoid the errors seems to be:
  
  Do not use multiple assignments.
  In case you have to (functions returning more than one argument), you
  can rewrite the functions, such that there is no (complex) expressions
  in the RESULT section. That is, instead of the REAL64 function above that 
  failed, you could write

     REAL64, REAL64 FUNCTION Id(VAL REAL64 a, b)  
       REAL64 r1, r2:
       VALOF  
         SEQ
           r1 := ((a+47.0(REAL64))-47.0(REAL64))
           r2 := ((b+147.0(REAL64))-147.0(REAL64))
         RESULT r1, r2
     :
 
     REAL64 i, j:   
     SEQ  
       i := 1.0 (REAL64)    
       j := 2.0 (REAL64)  
       i, j := Id(i, j)  
  
  which will work properly.


Our system consists of a B007 motherboard, attached to a IBM XT286, mounted
with one B404 TRAM running the TDS and and a number of B401 TRAM's. 
The TDS version i the D700D release, dated 9th May 1988.

----------

Now we are at it: Is there anyone, who has experience with the GUY 
construct inside functions?
We have a problem adressing function parameters using their symbolic
names. The compiler accepts the names, but it seems to produce some
wrong code.
There seems to be some problems adressing function parameters with their
symbolic names. That is, the function, 

     REAL64 FUNCTION test(VAL REAL64 a)
       REAL64 r:
       VALOF
         r := a
         RESULT r
     :

produces the following disassembled code

     AJW -3
     LDL 4     -- begin assignment
     FPLDNLDB 
     LDLP 0
     FPSTNLDB  -- end assignment
     LDLP 0
     FPLDNLDB
     AJW 3
     RET

while the following function, that should do the same job,

     REAL64 FUNCTION testGUY(VAL REAL64 a)
       REAL64 r:
       VALOF
         GUY -- r := a
           LDL a
           FPLDNLDB
           LDL r
           FPSTNLDB
         RESULT r
     :

produces following:

     AJW -3
     LDL 4     -- begin assignment
     LDNL 0    -- WHAT ???
     FPLDNLDB
     LDLP 0
     FPSTNLDB  -- end assignment
     LDLP 0
     FPLDNLDB
     AJW 3
     RET



---------------------------------------------------------------

With our best wishes:

                         Henrik Tolboel, Lars Christiansen 

                         Computer Science Department
                         University of Aarhus
                         Ny Munkegade
                         DK 8000 Aarhus C
                         Denmark

conor@inmos.co.uk (Conor O'Neill) (01/14/89)

In article <1893@daimi.dk> larsac@daimi.dk 
(Henrik Tolboel and Lars Christiansen)
pointed out a few problems with the D700D compiler.

The first is to do with multiple assignment:
>but the one below sets the transputer error flag during compilation
>
>     INT a, b, c:
>     SEQ
>       a, b, c := ((a+47)-47), ((b+147)-147), ((c+124)-124)

This is a known bug. It is caused by the `unnecessary' brackets on the
right hand side of the assignment. The following code is OK:

       a, b, c := (a+47)-47, (b+147)-147, (c+124)-124


The second problem is also a known bug. The compiler can sometimes
create incorrect code when compiling a FUNCTION on a T800 which returns
multiple results, at least one of which is REAL.
As the original poster correctly observed, the problem can be overcome
by copying all `complicated' result values into local variables, 
and returning those. For example:

>  REAL64, REAL64 FUNCTION Id(VAL REAL64 a, b) 
>    VALOF 
>      SKIP 
>      RESULT ((a+47.0(REAL64))-47.0(REAL64)),((b+147.0(REAL64))-147.0(REAL64))
>  :   
 
This can be overcome by re-writing as

>  REAL64, REAL64 FUNCTION Id(VAL REAL64 a, b)  
>    REAL64 r1, r2:
>    VALOF  
>      SEQ
>        r1 := ((a+47.0(REAL64))-47.0(REAL64))
>        r2 := ((b+147.0(REAL64))-147.0(REAL64))
>      RESULT r1, r2
>  :
 
Both of these problems have been fixed, and any new releases of the
D700D will not have these problems.

Contact your distributor for an up-to-date bug list.

The problem concerning GUY code was caused by forgetting that
FPLDNLDB requires a POINTER to the variable to be loaded. 
Remember that GUY code is not exactly assembler; when you write
LDL a, the compiler inserts enough code to load a onto the stack.
It does not simply insert a LDL instruction, if a is not a local variable.
Similarly, LDLP a is translated to whatever sequence of instructions is
necessary to load the address of a onto the stack.
So to get the same effect as

     REAL64 FUNCTION test(VAL REAL64 a)
       REAL64 r:
       VALOF
         r := a
         RESULT r
     :

you need to write

     REAL64 FUNCTION testGUY(VAL REAL64 a)
       REAL64 r:
       VALOF
         GUY -- r := a
           LDLP a
           FPLDNLDB
           LDLP r
           FPSTNLDB
         RESULT r
     :

which both produce the following:

     AJW -3
     LDL 4     -- begin assignment
     FPLDNLDB
     LDLP 0
     FPSTNLDB  -- end assignment
     LDLP 0
     FPLDNLDB
     AJW 3
     RET

Conor O'Neill, Software group, INMOS Ltd.