-------------------------------------------------------------------------------
*  RELEASE 4.00 BUGLIST                                                       *
*  Update - 3/22/91                                                           *
*  This file contains a list of bugs in the release 4.00 of the 320C30 code   *
*  generation tools.                                                          *
*  All bugs will be fixed in the next production release unless otherwise     *
*  indicated.  There will sometimes be references to internal versions in     *
*  this list.  For that reason you must always refer to the release status    *
*  information (published every two weeks) to verify the availability of a    *
*  specific revision.                                                         *
-------------------------------------------------------------------------------
                            Part One
COMPILER
-------------------------------------------------------------------------------
3619  V4.00  will fix in V4.10
  Wrong code may be generated for binary expressions of the form

   ((cast) <e1>) op <e2>    OR   <e1> op ((cast) <e2>)

where <e1> and <e2> are arbitrary expressions, op is any binary operator,
(cast) is a float-to-int or int-to-float conversion, and the following
additional conditions are met:
   - BOTH <e1> and <e2> contain calls
   - the compiler evaluates the casted expression first (arbitrary)

i.e.            d = dfn( ((float)ifn(i)) / dfn(d) );

Workaround: use an explicit assignment to a temp:
     temp = (cast) <e1>;
     temp op <e2>

3620  V4.00  will fix in V4.10
  The compiler may very rarely generate an illegal parallel MPYx || STx
instruction.  This occurs when a multiply operation in the source code
has all its operands in registers, and an immediately following assignment
stores a register using indirect addressing.

e.g.

   float x;
   register float r4 = 2.0, r5 = 5.0;
   register float *ar4=&y;

   x = 1.234;
   r4 *= r5;     /* Problem occurs here */
   *ar4 = x;
   return(r4);

Workaround: Use the -mx switch on the CL30 command line.

3643  V4.00  will fix in V4.10
  NOTE:  This is a VAX/VMS problem ONLY !

The compiler incorrectly represents the following range of compile time
constants as zeroes.

        e.g.   #define Test17  -1e17       !compiler generates -0.0 for
               #define Test17  -1e18       !these range of exponents
               #define Test17  -1e19       !
               #define Test17  -1e20       ! For any exponentials below e17
                                           ! or above e20 - the correct values
                                           ! will be generated

3651  V4.00  will fix in V4.10
  The compiler generates the wrong address increment for the following
assignment:

       e.g.     static float table [32][32];

                   for (r=0; r<32; r+=2)
                   {
                      for (c=0; c< 32; c++)
                      { table [r   ][c] = 1.;  ! compiler generates parrallel
                        table [r + 1][c] = 0.; ! store with incorrect address
                      }                        ! for second argument
                    }                          !

 Bug Description:
       This error with the optimizer will occur under the following
       conditions.
             1. there is a dereferenced pointer that is incremented by 32

                         e.g.  *(p + 32) = 0;   !The above code is reduced
                                                ! to p = &table by optimizer


       (NOTE:  This error will only occur when the array size is 32

        Workaround:

3658  V4.01  will fix in V4.10
  The code generator may generate the wrong code for statements of this
form.
                   e.g.    return <reg_var> op= <expr>;

where <reg_var> is a register variable and "op=" is an assignment operator
such as +=, *=, etc.  A simple workaround is to simply use the non-assignment
form of the operator:
                   e.g.  return <reg_var> op <expr>;


     e.g.
              results |= 0x10 ; return(results) ;

              The optimizer reduces the above code to:

              return(results |= 0x10);

3667  V4.00  will fix in V4.10
  The compiler incorrectly generates code to prematurely exit a for loop
containing an if-then-else construct when the "if-then-else" statement
is the very last statement in the loop.  This problem may also result
in the generation of a branch or repeat block RPTB with an undefined
label.

    Bug description:   This problem occurs only using optimization level 2

                    1. The repeat loop must be a counting loop
                       (i.e. for (i=0, i<k ; i++) )

                    2. The last statement in the loop must be an
                       if - else pair or its equivalent.

                    3. The path around the loop is result of
                           - an if
                           - or execution of loop zero times
                             (i.e. k==0)

3670  V4.00  will fix in V4.10
  The compiler generates the wrong code for an assignment statement involving
operations in which the right hand expression is a subtraction between
two operands where the first operand is negated. (i.e. expressions
of the form  " -a - b");

          e.g.          c = -a - b;    ====> compiler performs c = (a+b);


                        ;>>>>     c = -a - b;  ! Compiler generates simple add
                              ADDI   R0,R1,R3  ! a + b
                              STI    R3,*+FP(3)! c = a+b

Workaround:

             rewrite statement as

                        c = -(a+b);

3724  V4.00  will fix next release
  Version 4.0 of the C30 Compiler does not save and restore the correct context
for interrupt service routines.  This error will only occur when the sole
content of the function is a "float - int", "int - float" conversion.

      static int result;
      void c_int99()
      {
        float y;               /* R0 is not saved, but is used by
                                  function */

        y = (float) result;

       }

3765  V4.00  will fix in V4.10
  The parser sometimes hangs/crashes when symbols are declared at a local scope
with the same name as prototype parameters used in a function declaration at
the same scope.

main()
{
        float GAM = 0.0;
        float DTR = 0.0;

     void INPUT(float *GAM);

        INPUT(&GAM);

        DTR = 3.141592654 / 180.;
        GAM = GAM * DTR;
}

Workarounds:

    1) Omit the name on the prototype:

        i.e.  void INPUT(float);

    2) Use a different name.

    3) Move function declarations outside the function.

ASSEMBLER
-------------------------------------------------------------------------------
3149  V4.00  will fix in V4.20
  VMS ONLY:  asm30 will not accept macros of this form ...
m_name      $MACRO   type
            addf     *+ar6(7),r0
            $IF      type.v = 0
            $ELSE
            $ENDIF
            $ENDM
                     ---------[ work around ]----------
the macro will work with the addition of a comment:
m_name      $MACRO   type
            addf     *+ar6(7),r0
*           >>>>>>>>>>   add a comment line here <<<<<<<<<<<<<<   *
            $IF      type.v = 0
            $ELSE
            $ENDIF
            $ENDM
                    --------[ note ]--------
  This problem is expected to be remedied when new macro cabailities (now
in development) are incorporated into the TMS320C30 assembler (V4.20).

3606  V4.00  will fix next release
  The assembler will fail with a "Segmentation fault (core dumped)" message
when
a variable defined using an improper .set directive is referenced later in the
code.

  Example:

        .ref    RAM_B0, RAM_B1

n       .set    08h
in      .set    RAM_B0
h       .set    RAM_B0+2        ;known to be incorrect
x       .set    RAM_B0+2+n      ;known to be incorrect

FIRx:   ldi     n,bk                    ;load block size, circular buffer
        ldi     h,ar0                   ;!! Error occurs here
        ldi     x,ar1                   ; at first reference to one of the
                                        ; objects declared with the incorrect
                                        ; .set directives.
        ....

        ...
        .end

3622  V4.00  will fix next release
  A character string passed to a macro using .string directive will only accept
32 characters. One of the characters in the string cannot be a comma because
the comma is assumed to be a delimiter even though it is within the quotes
delimiting the character string.

3736  V4.00  will fix next release
  The assembler does not generate the correct address for a structure element
e.g.
       str      .struct
       i1       .int
        i2      .int
        i3      .int
        slen    .endstruct

        .ref _c_struct         ; deefined in c source
_c_struct       .tag    str
        .text
        .def    _asm_proc
_asm_proc:
        ldi     @_c_struct.i1,r1  /* Incorrect adresses are generated for */
        ldi     @_c_struct.i2,r2  /* These structure elements */
        ldi     @_c_struct.i3,r3
        rets

3795  V4.00  will fix next release
  The ".loop #count" directive may not work for some instructions.

i.e.  the ldf || stf instruction will not be repeated in the following
      code

rdelayf $macro  source, delay, in
        ldf     *:source:++(1), :in:   ; load first sample from memory
        $loop   2
        ldf     *:source:++(1), :in:    ; load next sample from memory
||      stf     :in:, *:delay:++(1)%    ; Store previous one in circular buffer
        $endloop
        stf     :in:, :delay:++(1)%     ; Store last sample in circular buffer
        $endm

3892  V4.00  will fix next release
  If argument strings in macro invocations do not begin with
a numeric character, they are treated as undefined symbols.

ROM30
-------------------------------------------------------------------------------
3860  V4.00  will fix in V4.10
  When using the -w option on ROM30, the addresses generated
for the low order bytes (".lo" file) are incorrect.


LINKER
-------------------------------------------------------------------------------
3574  V4.00  will fix in V5.00
  Linker ignores fill for hole when fill is specified using ABSOLUTE symbol.

    e.g.
               MEMORY {
                         PAGE 0: PROGRAM:    origin = 0000h, length = 10000H
                         PAGE 1: DATA:       origin = 0000h, length = 10000H
                       }

               SECTIONS
                       {
                          PAG0RAM     60H   : {}
                           D_PAGE     0    (DSECT) :
                           {
                                      .+=  DEMO_PGRSZ,
                                      DEMO.OBJ(DEMOPAGE)
                            }
                        }

         NOTE: This applies to ABSOLUTE symbols only. Expressions with
               relocatable symbols are always evaluated after all storage
               allocation (i.e. after SECTIONS directive is processed).

OPTIMIZER
-------------------------------------------------------------------------------
3605  V4.00  will fix in V4.10
  Compiler fails to pass the text of an "asm" statement on to the assembler
when
that "asm" statement appears to be unreachable code.

  e.g.
               BOOL OrderTraceType (void)
               {
                if (Order_Trace_Type == iCpuOrder)
                  return TRUE;
                else
                  return FALSE:
                asm ("    .word   0c80ffffh");  /* is not placed in assembly */
               }

Since the  result of the compare would be to "return" no matter what the
outcome, the statement following the "if -then -else" would never be reached.
The compiler tries to optimize by not generating code for the succeeding
statement, thereby failing to pass the text of the "asm" statement to the
assembler.

3657  V4.01  will fix next release
  The results for optimized and unoptimzed compiler run is different for the
folllowing code.

!! This problem is caused by the optimizer not recognizing the
   cast of the "unsigned" long to a signed "long"
                e.g.
                           #define UP  2.0
                           #define DOWN 3.0
                           #define BAMS2RAD(x)   ((long) (x)/DOWN*UP)
                           float bug()
                           {
                             unsigned long z = 0x1b;
                             float y;

                               y = BAMS2RAD(z); ! Error occurs here.
                               return(y);
                           }
3766  V4.00  will fix next release
  The optimizer sometimes incorrectly reorders expressions involving
additions that have the following form:

       e1 op e2 + e1            -or-         e1 op e2 - e1


        e.g.      *(q + i * m + i)  ====> q[2*i*m]

The optimizer reorders the expressions in the follwoing manner, sometimes
ignoring operator precedence.

                  e1 op e2 + e1   =====> e1 * 2 op e2

                  e1 op e2 - e1   =====> 0 op e2

e.g.
   e1 % e2 + e1    =======>      e1 * 2 % e2

   e1 / e2 + e1    =======>      e1 * 2 / e2

   e1 * e2 + e1    =======>      e1 * e2 * 2


                        e1 op e2 - e1

   e1 % e2 - e1    =======>      0 % e2


Workaround:

     1) Declare variable "e1" as volatile.
-------------------------------------------------------------------------------
