-------------------------------------------------------------------------------
* RELEASE 6.10 BUGLIST                                                        *
* Update - 10/25/91                                                           *
* This file contains a list of bugs in the release 6.10 of the 320C1x/2x/5x   *
* code generation tools.                                                      *
* All bugs will be fixed in the next production release unless othwerwise     *
* 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.                                                          *
-------------------------------------------------------------------------------
 COMPILER
-------------------------------------------------------------------------------
3523     V6.10  will fix next release
 (internal bug)
  The following, fairly major, bug was not detected by the Plum Hall test
suites in the C25 compiler.  It was found in beta test.

                switch ("any unsigned type")
                {
                  case SI1 : stmt1; break;
                  case SI2 : stmt2; break;
                  default  : stmt3;
                }

SI1 and SI2 are small integers.  stmt<x> are program statements.  The
exact number of cases is not significant.

3702     V6.10  will fix next release
  The "modf" run time support routine, sometimes returns the incorrect values.
Note that the following functions call "modf" and may potentially be affected:

 floor    ceiling   fmod   pow   sin   cos   tan

Work around:
1) Extract the source from the source library: "dspar -x rts.src modf.c"
2) Make four changes:

  * Line 18
    Old : if (exp < 1) . . .
    New : if (exp < 0) . . .

  * Line 25
    Old : m1 = (m1 & 0xFF) | 0x80;
    New : delete

  * Line 31 (Line 30 after deletion)
     Old: else           { m1 <<= exp; m1 |= (m0 >> (16 - exp)); m0 <<= exp; }
     New: else if(exp)   { m1 <<= exp; m1 |= (m0 >> (16 - exp)); m0 <<= exp; }

  * Line 32 (Line 31 after deletion)
    Old : m1 &= 0xFF;
    New : m1 &= 0x7F;

  * Line 51 (Line 50 after deletion)
    Old : . . . | ((0x7F + exp) << 7) | ((value < 0) << 15);
    New : . . . | ((0x7F + exp) << 7);

4) Replace the source in the source library: "dspar -r rts.src modf.c"
5) Recompile the function: "dspcl modf.c"
6) Replace the obj

3709     V6.10  will fix next release
  When the compiler generates multiple branches to the same label, the first
path(s) of which do not set the sign extension mode, the later path(s)
which do, the compiler erroneously tracks the sign extension mode at that
label to be that which was set in the later path(s).  The only way to
exercise the bug is with a conditional expression containing the && operator
(or the equivalent if statements).

  if (unsigned_var && signed_var) . . .

  /* Compiler is now wrong in thinking sign extension is set as opposed to */
  /* unknown.  The next statement may execute incorrectly                  */

  if (signed_var) . . .

Workaround: re-arrange the conditional expression to test a signed case
first.

  if (signed_var && unsigned_var) . . .

3710     V6.10  will fix next release
  The runtime library support routine "F$$FTOU" exits abnormally, corrupting
the stack when it is passed a negative value.  This routine is called when
a floating point number is cast as an unsigned integer.

  e.g.     float x; unsigned int i;

            x = -237.6789;
            i = (unsigned int)(x);  /* This statement generates a call to the
                                       F_FTOU routine which fails to exit
                                       normally. */


Workaround:
  1) Extract the code from the source library: "dspar -x flib.src f_ftou.asm"
  2) Make the following change

     Line 231
     Old : B    ZERO
     New : B    ZERO,*-

  3) Re-assemble: "dspa f_ftou.asm"

  4) Replace source in source library: "dspar -r flib.src f_ftou.asm"

  5) Replace the object in the object library: "dspar -r flib.lib f_ftou.obj"

3753     V6.10  will fix next release
  Compiler generates incorrect code for comparisons involving unsigned integers
to which the postfix operators "--" or "++" have been applied.

e.g.
        main()
        {
          unsigned int i1, i2;
          int f;

          while (i1-- > i2) {      /* Causes error */
                  ++f;
          }

          if (i1++ > i2) {         /* Causes error */
                  ++f;
          }
        }

Workaournd : Use the "comma" operator to force compiler to generate the
correct code.

 if (i1-- > i2)        ========>  if ((i1--,i1+1) > i2)

 Suggestion: It may be best to use macros to define the expression so
 that when the fix becomes available, the coding changes only have to
 occur in one place.

        POSTDEC(x) (x--,x+1)
        POSTINC(x) (x++,x-1)

3791     V6.10  will fix next release
  The "offsetof" function generates an error when deriving the offset for
an arrayed item when "offsetof" is called at a global level.

 e.g.
        #include <stddef.h>
        struct s {
                int a;
                int b[10];
        };

        int i1 = offsetof(struct s, a);
        int i2 = offsetof(struct s, b[9]);   /* Error generated here */

        main()
        {
        int i3 = offsetof(struct s, b[9]);   /* No error generated here */
        }

3808     V6.10  will fix next release
  The compiler does not properly check the sign of expressions in a "return"
statement.  This may result in the sign extension mode not being set for
comparisons in which one of the compred items is a function call.

e.g.

                if (f_returns_int(&global) < 0 )
                        never_here();

                int f_returns_int(ptr)
                    int *ptr;

               {
                        return(-1);

                }

Workaround : transform return statement to read

              if (i = -1) return(i);

3811     V6.10  will fix next release
  The compiler generates incorrect code to assign a "casted" address to a
variable of type "long".

 i.e.    l = (long)&c;   /* Doesn't work */

 Workaround: Assign address to an unsigned integer type, then to the long

 i.e.    ui = (unsigned) &c;
         l = ui;

3911     V6.10  will fix next release
  A comparison may not execute correctly if the second operand is
a very large number.
e.g.
        long a
        long b;
        int y;
        main()
        {
                a = 0x00000001;
                b = 0x80000001;

                if (a > b) y=y+1; /* y should be 1 but
                                     overflow causes a problem */
        }

Work around:

1. extract "boot.asm" from rts.src

   dspar -x rts.src boot.asm

2. edit boot.asm to add the SOVM instruction after
   line 32:

              LINE 32: _c_int0:
        ADD   LINE 33: SOVM

3. reassemble "boot.asm" and replace "boot.obj" in "rts.lib"

   dspa boot.asm
   dspar -r rts.lib boot.obj


4. replace "boot.asm" in "rts.src"

   dspar -r rts.src boot.asm

3931     V6.10  will fix next release
  The compiler errs when calculating the difference between two pointers
cast as ints.

        dif = (unsigned int)&x - (unsigned int)&y;

Workaround: Split the assignment up into the following two statements.

        dif = (unsigned int)&x;
        dif -= (unsigned int)&y;

3935     V6.10  will fix next release
  Compiler errs when performing a 32-bit bitwise and (&) operation with a
constant in which the lower 16 bits are zero.

e.g.

        long value1;
        long func1();

        value1 = func1() & 0xffff0000L;  /* value1 will be wrong */

3942     V6.10  will fix next release
  Comparison of unsigned longs is performed incorrectly. The bug is
evidenced when comparing two numbers whose difference is
0x80000000 or greater.

3946     V6.10  will fix next release
  Comparisons will not work for some values of unsigned long integers.

e.g.

        unsigned long i,j
        if (i>j)

Note: This will only be a problem when the difference between
      "i" and "j' is >= 0x80000000.

3956     V6.10  will fix next release
  The compiler errs when assigning a long that is a member of a
global structure, where the long isn't the first member of the
structure, and the left hand argument of the assignment is
either a local variable or is a variable accessed via a pointer.

e.g.

        struct s { int ival;
                   long lval; } g;

        func()
        { long l, *p;

          l = g.lval;
          *p = g.lval;  /* ERROR */
        }

Workaround: Combine the assignment, or otherwise place the
            assignment within an expression.

           l = *p = g.lval;

           call (l = g.lval);

3969     V6.10  will fix next release
  The sign extension mode is not properly set when the right shift
operator is used when a prvious instruction has turned the sign
extension mode off.

e.g.
        unsigned long ux, uy;
        unsigned long int uxl, uyl;
        long xl, yl;

        void main()
        {
          uy = ux >> 1;      /* sign extension mode is turned off */
          uyl = uxl >> 1;    /* sign extension mode still off */

          xl = yl >> 1;      /* sign extension mode is not turned on */
        }

4001     V6.10  will fix next release
  The compiler generates code for the following C statement that causes
the stack to be corrupted.

while ((i++,i-1) < (num -1)) inlist[i-1] = inlist[i];

4040     V6.10  will fix next release
  The compiler generates incorrect code for an "if" statement in which
a variable within the "if" conditional is multiplied by any power
of 2.

e.g.
unsigned char value1;
unsigned char value4;

main()
{
   value1 = 1;
   value4 = 4;

   /* error occurs when multiplying by 2 or any power of 2 */

   if ( value1*2 > value4 )
   {

     /* this part will execute !!! */
        value1++;
   }
}

4157     V6.10  will fix next release
  The compiler does not properly handle intialization of character
string literals that are cast as int.

i.e.

     int i = (int) "123";

!!!! NOTE:  On SUN based systems this code will cause the code gen,
            "dspcg" to terminate abnormally (core dump).

4175     V6.10  will fix next release
  On the PC only, the compiler errs when accessing a member of a structure that
is nested in another structure, and the offset of the inner structure within
the outer structure is greater than or equal to 4096 words.

Workaround:

Change the declaration of the structure such that all of the members that
are themselves structures are declared earlier.

Example:

struct small
{
   int a, b, c;
};

struct big
{
   int ary[5000];
   struct small s;
} g;

    . . .

    g.s.b . . .         /* Generates wrong address */

4185     V6.10  will fix next release
  Compiler errs when handling the == and != operators where one, or both, of
the
of the operands is a call.

Workaround:

Assign the result of the call to a temp and then compare.

4319     V6.10  Fixed in V6.20
  The compiler errs when generating code for the comparison of variables
declared as unsigned short when the comparison takes the form:

       if (ushort op (short = ushort<<val))

Workaround: Perform assignment before comparison.

4344     V6.20  will fix next release
  Compiler errs when handling structure assignment from a call or returning a
structure when the operand is a pointer (this includes array references).
For example:

    struct s struct_call1()
    {
        ...

        *p             = struct_call2();        /* ERROR */
        array1[i]      = struct_call2();        /* ERROR */
        array2[i].nest = struct_call2();        /* ERROR */

        ...

        return *p;                              /* ERROR */
    }

The code generator issues "internal error" messages when handling these
constructs.  Workaround this bug by using temporaries.  For example:

    struct s struct_call1()
    {
        struct s temp;
        ...

        temp = struct_call2();
        *p = temp;                              /* WORKS */

        ...

        temp = *p;
        return *p;                              /* WORKS */
    }


Suggestion:  Use the following #defines to make the changes.  Then to port
to another machine or when a fix becomes available, you need only change
these #defines.

#define STRUCT_ASG(type, left, right) \
        do {                          \
             type temp;               \
             temp = right;            \
             left = temp;             \
           } while (0)

#define STRUCT_RET(type, ret)         \
        do {                          \
             type temp;               \
             temp = ret;              \
             return temp;             \
           } while (0)

    struct s struct_call1()
    {
        ...

        STRUCT_ASG(struct s, *p, struct_call2());

        ...

        STRUCT_RET(struct s, *p);
    }

ASSEMBLER
-------------------------------------------------------------------------------
3660     V6.10  will fix next release
  The ".mlib " macro library directive does not work properly in the assembler.

     Workaround : Put macros onto single file and use
                  ".include" directive

3676     V6.00  will fix next release
  The assembler incorrectly processes structures declared with the ".struct"
directive when the variable is defined in a file other than the file where
it is accessed.

        e.g.      testRec: .struct
                  var1:    .word
                  var2:    .word
                  testLen: .endstruct

                           .bss    test1, testLen
                  test1    .tag    testRec

                           .ref    test2
                  test2    .tag    testRec

                           .text
     0000 1001-            LACC  test1.var2 ; Offset 1, OK
     0001 1000!            LACC  test2.var2 ; Offset 0!!!
     0002 1001!            LACC  test2+testRec.var2 ;1,OK

      !!!! The offsets for tes1.var2 and test2.var2 should be the same.

3788     V6.10  will fix next release
  The assembler is not saving .set symbols when using the -s option.

3818     V6.00  Fixed in V6.10
    !!! Note: This is a VAX/VMS problem only.

  The -x (generate cross reference) option will not work for some
assembler files.  Using it will cuase a VAX/VMS error and ensuing
dump.

3819     V6.00  Fixed in V6.10
  !!!!!Note: This is a VAX/VMS problem only.

The .loop assembler directive does not work. It generates a fatal
error and the message 'CONDITIONAL BLOCK NESTING LEVEL EXCEEDED'

e.g.    .eval  0, x

    coef .loop     ; Coef Table

        .word x*100
        .eval x+1, x
        .break x = 7
        .endloop

3907     V6.10  will fix next release
  The assembler should tag the following instruction as an error
(valid values for MPYK -4096 to 4095)

        MPYK    5000

Instead it is assembled as if the user typed

        MPYK    -3192

3922     V6.10  will fix in V6.11
  Referencing members of a .struct across modules does not
work correctly. This bug was reported in release 5.20
and still exists in 6.10 - bug #3676 on the 6.10 bug
list.

4045     V6.10  will fix next release
  Using the $macro directive to define macros, may cause the
assembler to generate a "BAD Archive " error message when
the macro is used in a macro library.

4132     V6.10  will fix next release
  If the text of a file included via a ".copy" directive contains
a ".end" directive - the assembler generates a PASS1/PASS2 operand
conflict error.

Workaround: Do not place a ".end" directive in the text of a file
            that is to be included via ".copy" in another assembly
            file.

4348     V6.20  will fix next release
  The assembler/linker will not load the page pointer with the correct value
when you write

        LDPK    NAME            ; code in module 1

and 'NAME' is .set to a value in another module.

NAME    .set    42              ; code in module 2

Instead, it sets the page pointer to the upper nine bits of that value
as if 'NAME' were a symbol address.

RTS
-------------------------------------------------------------------------------
3802     V6.10  will fix next release
  The RTS function "strtoul" , which converts a string to an unsigned long,
has a bug in it and it may not return the correct result.

Workaround:  The workaround is to edit the source and replace the object
             file in the library, in the following manner:

    1) Extract source from library:  "dspar -x rts.src strtoul.c"

    2) Edit the source file :  after line 19  add  "cp = *fst;"

    3) Recompile source : "dspcl strtoul.c"

    4) Replace source and object files : "dspar -r rts.lib strtoul.obj"
                                         "dspar -r rts.src strtoul.c"

3968     V6.10  will fix next release
  The structure defined in the LDIV_T run time support library is
incorrect. It should return two long integers. Instead it returns
two regular integers.

Workaround: Make the following changes in the file "stdlib.h"

        1. Edit line 30 to remove "ldiv_t"

Old line 30: typedef struct _div_t { int quot, rem;} div_t, ldiv_t;
New line 30: typedef struct _div_t { int quot, rem;} div_t;

        2. Add the following line (will be line 31)

Line 31: typedef struct _ldiv_t {long quot, rem;} ldiv_t;

        3. Edit line 33 (old line 32)

Old Line 33: div_t ldiv(long _number, long _denom);
New line 33: ldiv_t ldiv(long _number, long_denom);

4041     V6.10  will fix next release
  There is a bug in the two run time support library routines that perform
unsigned division, "/" , and unsigned modulus, "%".  The error will only
occur if the unsigned variable involved has the most significant bit of
the word set.

  unsigned long x,y;

  x = 0x8a08457d;

  y = x / 10;        /* returns incorrect value */

  y = x % 10;        /* returns incorrect value */

LINKER
-------------------------------------------------------------------------------
3691     V6.00  will fix next release
  The "dsplnk" command does not return the correct error exit code when
there is a syntax error or when undefined symbols occur in the link.

  $SEVERITY == "1"              should equal 3

DOCUMENTATION
-------------------------------------------------------------------------------
3904     V6.10  will fix next release
  There is an error on Pg. A-4 of the Assembly Language
Tools User's Guide (SPRU0128B). The UG states that
F_LSYMS flag has value 0010h, it should be 0008h.

4327     V6.10  will fix next release
  The C Compiler User's Guide fails to mention

- On the 'C5x only, the NDX bit of the status register must remain at 0, as at
  reset
- On the 'C5x only, any hand-coded assembly routine called by the compiler
  that uses the INDX register must save and restore it.  If the routine
  does not modify AR0, this save and restore may done by placing these
  instructions immediately before the return to C code:

        LDPK    0
        SMMR    AR0,INDX

The above gudelines must be followed in order to preserve the integrity
of the C environment.

4347     V6.20  will fix next release
  On page 2-41 of the C Compiler User's Guide, the MEMORY directive in the
example should read:

MEMORY
{
  PAGE 0 : PROG : origin = 30h,  length = 0EFD0h
  PAGE 1 : DATA : origin = 800h, length = 0E800h
}

TUTORIAL
-------------------------------------------------------------------------------
3675     V6.00  will fix next release
  The file TUTOR.DOC contains 2 copies of the same text.

3850     V6.10  will fix next release
    Do to a problem with the ".mlib" directive in the assembler
the following changes should be made in the tutorial procedures.

1) Instead of building "filtmac.lib", place the text for both
   FIR.MAC and FIRA.MAC in a single file.

2) Edit line 54 of MAINC25B.ASM to use ".include" directive
   line 54  old: .mlib "filtmac.lib"
            new: .include "file name where FIR.MAC and FIRA.MAC
                           are stored"

3851     V6.10  will fix next release
    The macros "FIR.MAC" and "FIRA.MAC" contain the old macro definition
directives "$MACRO" and "$ENDM".  These should be changed to the
new macro definition directives ".MACRO" and ".ENDM" to be consistent
with V6.10 of the assembler.

ROM
-------------------------------------------------------------------------------
3836     V6.10  will fix next release
  The "dsprom" utility uses the ".obj" file as default -
should default to using ".out" file.

e.g.
                    current operation

  dsprom -t file   ====>   dsprom -t file.obj


                    should be

  dsprom -t file   ====>   dsprom -t file.out
-------------------------------------------------------------------------------
