-------------------------------------------------------------------------------
* RELEASE 6.20 BUGLIST                                                        *
* Update - 06/26/92                                                           *
*                                                                             *
* This file contains a list of bugs in the release 6.20 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.                                                          *
*                                                                             *
-------------------------------------------------------------------------------
 
 
                                Part 1
 
 COMPILER
-------------------------------------------------------------------------------
 
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);
    }
 
 
4434     V6.20  will fix next release
  Compiler errs when handling a '*p++ (*p--)' operand where 'p' points to a
structure of size two words or less.  For example:
 
        struct small
        {
          int a,b;
        } *ps;
 
        . . .
 
        *ps++ = . . .                   /* ERROR */
 
 
Workaround:  Move the increment.
 
 
        *ps = . . .
        ps++;
 
 
4435     V6.20  will fix next release
  Compiler errs when handling a 'p->nest' operand where 'p' is a pointer to a
structure that contains another structure called 'nest', and 'nest' is not the
first member of the structure.  For example:
 
        struct small
        {
           int a,b;
        };
 
        struct big
        {
           int x;
           struct small nest;
        } *pb;
 
        . . .
 
        pb->nest = . . .                /* ERROR */
 
 
Workaround:  Make 'nest' the first member of the structure or use the following
#define to access the structure.
 
 
        #define NESTED_STRUCT_ACCESS(type, nest_type, p, nest) \
             (* (nest_type *) ((int)p + offsetof(type, nest)))
 
        /* offsetof is defined in <stddef.h> */
 
        NESTED_STRUCT_ACCESS(struct big, struct small, pb, nest) = . . .
 
 
4454     V6.20  will fix next release
  Due to a register tracking problem, the compiler errs when processing code
that consists of a loop that contains only one access of a variable that
is followed by an assignment to that same variable.  For example:
 
        while (i == 0);
        i = 0;                          /* ERROR */
 
Workaround: Declare the variable to be   volatile.
 
 
4467     V6.20  will fix next release
  If your loader cannot load initialized sections into Page 1, data memory,
you may not be able to properly load programs that contain a   .const
section.  The   .const   section is generated by the compiler to hold
run-time constants such as character strings, and as allocation space
for any objects declared with the CONST qualifier.
 
Workaround:
One workaround for this problem would be to load the  .const  section
into program memory and then to copy the section from program to data
memory at run-time (similar to what is done with the  .cinit  section
when the  -c  linker option is used).
 
In order to do this - it requires making changes to the  boot.asm
routine and to the linker command file.  The boot routine must be
modified to perform the copy of the section from its load address to
its run address.  The linker command file must be set-up to specify
both a load and a run address for the  .const  section.
 
For an example showing how this can be done, please contact msgid PTR.
 
 
                                Part 2
 
4501     V6.20  will fix next release
  The compiler fails to detect the error that an object is declared using
an incomplete type, and may subseqently generate a zero sized entry in the
.bss section for the object.
 
e.g.
 
  The C source conatins the following declaration for x,  but type boolean
is never defined anywhere in the file.
 
enum boolean x ;
 
Then the compiler will not flag the error and will generate the following
entry in .bss for the var  x:
 
   .bss x,0
 
 
4567     V6.20  will fix next release
  In some rare instances the compiler may not generate code to restore the
frame pointer, reg AR2, after return from a function call. This problem
only occurs when there is a function containing a switch statement in
the same file where the function call occurred and the switch statement
is located in a function that appears later in the file.
 
Workaround:
 
      Create a dummy function that contains a switch statemetn and
      place the code for this function at the top of the affected
      file. (Note: It is not necessary to call the function).
 
 
4613     V6.20  will fix next release
  The example on p.3-15 of the release notes, showing the use of the UNION
directive to create shared memory for ".bss" sections will cause the
following warning to be issued by the linker
 
>> warning: can't align within UNION - section .bss1 not aligned
>> warning: can't align within UNION - section .bss2 not aligned
 
The problem is due to the fact that the linker's UNION directive does not
properly handle the case when more than one input section contains
either a blocking or alignment flag and the compiler automatically issues
a block directive for a file's .bss section.
 
 
SECTIONS
{
        .text ...
        .cinit ...
        ...
        UNION: run=RAM
        {
          .bss1: {file1.obj(.bss)}
          .bss2: {file2.obj(.bss)}
        }
 
        ...
        }
 
 
4722     V6.20  will fix next release
  In certain expressions that mix signed and unsigned integer types, the
compiler
may not handle sign extension on the accumulator correctly.  For example:
 
        int i;
        unsigned u;
 
        int func()
        {
            return i + u;
        }
 
Workaround: Cast the 'differently' typed members of the expression to the type
you want the  expression to have.
 
            return i + (int) u;
 
 
4723     V6.20  will fix next release
  When the compiler is run under the 'dspcl' option '-ml' (disable the LDPK
optimization) the compiler will incorrectly emit an
 
        .sblock .const
 
directive.  Because the LDPK optimization is disabled, blocking of the '.const'
section is not required.  Using blocking on the '.const' section can cause
unnecessary holes in the data memory space of the executable.
 
 
4724     V6.20  will fix next release
  When the '.cinit' section (used by the compiler to auto-initialize global
variables) of a C program is zero length, the linker, when run under the '-c'
or
'-cr' option, fails to append the section with a word of zero (thereby creating
a  '.cinit' section of length one which contains zero).  This error causes the
'_var_init' routine called by the C startup routine '_c_int0' to fail.
 
Workaround: Create a non-zero length '.cinit' section by declaring a dummy
global variable and explicitly initializing it:
 
        int dummy = 42;
 
 
4725     V6.20  will fix next release
  If you initialize a char pointer with the value of an expression in which
one member of the expression is a literal string constant, the codegen
crashes.
 
i.e.    char *p = "string " + 2;     /* crashes the codegen */
 
 
Workaround:  Initialize the pointer to point to the string literal
             and increment later on in the code.
 
i.e.
        char *p = "string";
 
        func()
        {
           int i;
 
           ...
           p += 2;
 
 
4781     V6.20  will fix next release
  In the rare instance where two integer assignments are performed
back-to-back and the right hand side of the assignments are both
constant expressions and the value of the first expression is
>= 0x8000 and the value of the second expression is exactly equal
to the first expression right shifted by 15, the compiler stores
the incorrect value in the variable for the second assignment.
 
i.e.
 
#define valeura 0x8000
#define valeurb 1
 
routine()
{
unsigned int fin,deb;
deb=valeura;
fin=valeurb;           /* incorrect value stored in "fin" */
}
 
 
Workaround:  A workaround would be to revers the order of the
             assignments:
 
             fin=valeurb; deb=valeura;
 
 
                                Part 3
 
4847     V6.20  will fix next release
  The compiler may fail to generate code for a shift operation, when
the shift is applied to an expression that was calculated in
an immediately preceeding statement and the expression still
resides in the accumulator.
 
i.e.
 
 
    channel = 8 * module + ch;
    b = MCHN + (channel << 3) + 1;   /* This line compiles incorrectly */
                                     /* since value of channel is already */
                                     /* in the accumulator as a result of */
                                     /* the previous statement            */
 
 
Workaround:
 
      1. Use the -ma option. (Although this will alleviate the
         problem it may cause inefficient code generation,
         since this will turn off all register tracking. )
 
      2. Intersperse another instruction between the two offending
         instructions that uses the accumulator.
 
      3. Or if possible simply reuse the expression from the
         first statement in the calculation carried out in the
         second statement
 
         i.e.
 
            b = MCHN + ((8 * module + ch) << 3) + 1
 
 
ASSEMBLER
-------------------------------------------------------------------------------
 
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.
 
 
4594     V6.10  will fix next release
  The following section of assembly code crashes the C5x assembler.
 
        .text
 
 
RPTK    .macro  value
        .word   0bec4h
        .word   value
        .endm
 
        LDP     #0
        LAR     AR1,070h
        MAR     *,AR1
 
        LACC    #1,12
        SACL    *-
        RPT     #(04h-1)
        SACH    *-
 
        .end
 
 
4702     V6.20  will fix next release
  The assembler fails to mark internal labels as relocatable symbols.
Therefore,
the label is never properly resolved at link time.
 
i.e.       $1    NOP
 
                 ...
                 ...
 
                 BGZ     $1         /* Address of label $1 will not be
                                       resolved at link time */
 
Workaround:  Use named labels instead.
 
          loop   NOP
 
                 ...
                 ...
 
                 BGZ     loop
 
 
4782     V6.20  will fix in V6.21
  The assmebler fails to issue a warning for use of the CONF instruction
when the proper version is not selected for the assemble. (This is
a legal instruction for C26 only). Instead of issuing a warning, the
assembler generates an opcode that corresponds to an LAR AR0,dma
instruction. Where the value for the dma is the value selected on the
CONF command.
 
 
LINKER
-------------------------------------------------------------------------------
 
4364     V6.20  will fix next release
  The V6.20 linker errs in setting an incorrect flag in the header
of the object files it creates. This problem will only become
evident when using the  -r  option for intermediate linking.
The linker will issue the message:
 
    "cannot link new style reloc entries"
 
when the intermediate object files are encountered in another
link.
 
Workaround:  Use V6.10 to perform intermediate links and then
             use V6.20 lniker for the final link.  It should
             also be noted that when using V6.10 on intermediate
             links you cannot link in routines from the V6.20
             run-time libraries.  The routines in the run-time
             library are incompatible with the V6.10 linker.
             Therefore, you will have to link the run-time
             library routines in at the final link using V6.20
             of the linker.
 
 
4365     V6.10  Fixed in V6.20
  The linker map shows an output section ( outsec in the example) as having
been "linked" twice into the same memory locations.
 
 
e.g.
 
MEMORY
{
        PAGE 0:   EPROM   (RIX):  origin = 0h,    length = 8000h
                  PSROM   (RWX):  origin = 8000h, length = 2000h
 
        PAGE 1:   DAREA:          origin = 0h,  length = 0E006h
}
 
SECTIONS
{
        outsec  0h : {
                        *(VEC_LOW)
                        . = 18h;
                        *(VEC_HIGH)
                        . = 20h;
                        *(sect1)
                        . = 300h;
                        *(sect2)
                        . = 500h;
                        *(sect3)
                        ..
                        ..
                        . = 6000h;
                        *(sect11)
                        . = 7fffh;
                        *(sect12)
        }

 
 
                                Part 4
 
4397     V6.20  will fix next release
  The LINKER errs in not being able to create and fill holes at the start
of an output section. The lINKER effectively ignores   . +=  when it
appears at the start of the section and allocates subsequent code
over this area.
 
e.g.
 
SECTIONS
{
                .vectors : { }  > CODE  PAGE 0
                   .text : { }  > CODE  PAGE 0
                   .data : { }  > CODE  PAGE 0
 
                   GV$DP0: { }  > RAMB2 PAGE 1
This line ----->   GV$GP0: {.+=09h;}    > RAMB2 PAGE 1
This line ----->   LV$AC4: {.+=0F6h;}   > RAMB0 PAGE 1
 
                   GV$TCB: { }  > DP511 PAGE 1
}
 
 
4719     V6.20  will fix next release
  The banner written by the linker "DSP Fixed Point COFF Linker ..." cannot
be redirected to an output file via ">". For example if the command
"dsplnk test.obj > output", is used, the banner will still ouput to the
screen and will not appear in the file "output".
 
 
Workaround: SUN: use ">&" to redirect both standard out and standard err
 
             i.e.  dsplnk test.obj >& output
 
 
4733     V6.20  will fix in V6.21
  The linker does not generate and fill holes in output sections specified by
" . = " statements when the specifed holes fall inbetween code to
be included in the section.
 
i.e.
        MEMORY {
                    PAGE 0 :   EPROM: origin = 0h,  length = 0800h
 
        ...
 
        SECTIONS{
        outsec  0h :{
                   *(out1)
                   . = 18h;     /* Hole not generated */
                   *(out2)
                   . = 40h;     /* Hole not generated */
                   *(out3) } = 01111h
 
 
This will generate holes of the specifed size at the end of the output
section, rather than within the section as expected.
 
Workaround:  Create seperate output sections with binding addresses at the
             desired addresses and use the fill option on the MEMORY
             definition.
 
             i.e.
 
MEMORY {
        PAGE 0 :  EPROM : origin = 0h,  length = 0800h,fill = 01111h
 
        ...
        ...
 
SECTIONS:
 
    out1        0h: { }
    out2        018h: { }
    out3        040h: { }
 
    ...
    ...
 
 
OPTIMIZER
-------------------------------------------------------------------------------
 
4774     V6.20  will fix next release
  Note: This is an optimization problem only!
The optimizer may cause incorrect code to be generated for while loops
of the form below resulting in infinite loops.
 
volatile unsigned int tmp;
 
void main(void)
{
 tmp=300;
 while (tmp--);
}
 
Workaround:  Compile without optimization.
 
 
4775     V6.20  will fix next release
  Note: This is an optimization problem only!
In some rare instances when a switch statement contains code that makes
function calls, the compiler may generate a bad switch table for the
case statement.
 
typedef struct
{
  int si;
  int lg;
  int *addr;
} debug_t;
 
extern void bidon1(int * bc1);
extern void bidon2(int * bc1);
extern void bidon3(int * bc1);
extern void bidon4(int * bc1);
extern void send  (debug_t *btr1);
extern debug_t * receive(int i);
 
void main (void)
{
  debug_t *msg;
  int *adr,flag;
 
  while(1)
   {
   flag=1;
   msg = (debug_t *)receive(i);
     {
     adr=msg->adr;
     switch(msg->si)
        {
        case 0x96:
        bidon1(adr);
        break;
 
        case 0x98:
        bidon2(adr);
        break;
 
        case 0x90:
 
        ...
        ...
 
 
Workaround:  Compile without optimization.
 
 
DOCUMENTATION
-------------------------------------------------------------------------------
 
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
 
 
                                Part 5
 
4426     V6.20  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.
 
 
4457     V6.20  will fix next release
  The C Compiler User's Guide fails to mention that while the ".const" section
may be linked into either ROM or RAM, due to the way it is accessed, it must be
configured into page 1, not page 0.
 
 
-------------------------------------------------------------------------------

