Tool News
 
 
 

Tool News

Products Info
Downloads
Tools FAQs
RENESAS TOOL NEWS on November 1, 2005: RSO-SHC-051101D

Notes on Using the C/C++ Compiler Package V.9
for the SuperH RISC Engine Family of MCUs

Please take note of the eleven problems described below in using the C/C++ compiler package V.9 for the SuperH RISC engine family of MCUs.

  1. Versions Concerned
    C/C++ compiler package V.9.00 Release 00 through V.9.00 Release 03 for the SuperH RISC engine family


  2. Problems
    2.1   On defining a structure- or union-type array using the typedef specifier (SHC-0039)
    Consider the case where the typedef declaration is made of a structure or union using its tag name used in its tentative declaration, and then the structure or union is declared. If a structure- or union-type array is defined as of the type specified by the typedef declaration, the boundary alignment number may become incorrect.

    Conditions
    This problem occurs if the following conditions are all satisfied:
    (1)   A typedef declaration is made of a structure or union using its tag name used in its tentative declaration.
    (2)   After the typedef declaration in (1), a structure or union is declared.
    (3)   At least a member of the structure or union in (2) is not of type char, nor unsigned char.
    (4)   An array is defined as of the type specified by the typedef declaration in (1).
    (5)   The pack=1 option is not used. Or the array in (4) is not subject to the #pragma pack 1 preprocessor directive.
    (6)   The array in (4) is not qualified to be volatile, nor const.
    (7)   No member of the structure- or union-type array in (4) is referenced in a function defined within the program file.
    Example C source file:
    ----------------------------------------------
    typedef struct ST ST_A;
    struct ST {
        int x;
    };
    ST_A a[2];
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _a:                            ; static: a
              .RES.B      8        ; To be .RES.L   2
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Make the typedef declaration after defining a structure or union.
    (2)   Reference a member of a structure- or union-type array in a function defined within the program file.
    (3)   Qualify a structure- or union-type array to be volatile.
    (4)   Define a structure- or union-type array as not of the type specified by the typedef declaration.

    2.2   On making an assignment to a bit field of 1 bit wide that is a member of a structure- or union-type array (SHC-0040)
    An incorrect value may be assigned to a bit field of 1 bit wide that is a member of a structure- or union-type array.

    Conditions
    This problem occurs if the following conditions are all satisfied:
    (1)   The cpu=sh2a or cpu=sh2afpu option is used.
    (2)   In the program exists a structure- or union-type array one of whose members is a bit field of 1 bit wide.
    (3)   No structure or union in the array in (2) is 1 or 4 bytes in width.
    (4)   An assignment is made to a bit field of 1 bit wide that is a member of the structure- or union-type array in (2).
    (5)   The assignment in (4) meets either of the following conditions:
    1. Any of the following is used as s subscript of the array in (4); or the assignment is made using a pointer and any of the following is used in address calculation:
      • function call
      • member of a structure or union (including a bit field)
      • relational or equality operator
      • shift operator
      • multiplication, division, or residue operation
      • operation of type long long
      • type conversion from floating to int
      • include function such as addc() or shll() for replacing the value of the T bit in the SR register
    2. After the SHLL instruction is executed, the assignment is made using the BST.B instruction.
    Example C source file:
    ----------------------------------------------
    struct {
        unsigned short a:8;
        unsigned short b:1;
    } ST1[100],ST2[100];
    
    void func(int i,int j) {
        ST1[i].b=ST2[j].b;
    }
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _func:
              MOV.L       L11+2,R6   ; _ST2
              SHLL        R5
              ADD         R5,R6
            BLD.B       #7,@(1,R6) ; Loads value into bit T in register SR
              MOV.L       L11+6,R2   ; _ST1
              SHLL        R4         ; Replaces value of bit T in register SR
              ADD         R4,R2
              BST.B       #7,@(1,R2) ; Assigns replaced value
              RTS/N
    ----------------------------------------------
    Workaround
    Assign the address of the structure- or union-type array concerned to a volatile-qualified variable of type pointer. Then using this pointer, make an assignment to the bit field of 1 bit wide.

    2.3   On the referencing order of volatile-qualified variables (SHC-0041)
    When volatile-qualified variables are referenced, their referencing orders may be changed each other after compilation.

    Conditions
    This problem occurs if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   In the program exists the definition of a funct ion that contains either of the following:
    1. function call
    2. selection statement, iteration statement, conditional operator, or logical operator, with any cpu option except cpu=sh1 being used
    (3)   Before or within the statement or operator in (2), a volatile-qualified variable is referenced.
    (4)   Before the statement or expression containing the reference to the variable in (3), another volatile-qualified variable is referenced.
    Example C source file:
    ----------------------------------------------
    volatile int a,b;
    int c,d;
    
    void func() {
        int x,y;
        do {
          x=a;             // Condition (4)
          y=b;             // Condition (3)
      } while (x != a);    // Condition (2)-b
    }
    ----------------------------------------------
    
    Result of compilation:
    ----------------------------------------------
    _func:
              MOV.L       L13,R4     ; _a
              MOV.L       L13+4,R1   ; _b
    L11:
            MOV.L       @R4,R6     ; Reference in Condition (4) 
                                   ; Reference in Condition (3) 
                                       to be made here not referenced
            MOV.L       @R4,R2     ; Reference in Condition (2)-b
              CMP/EQ      R2,R6
              BF/S        L11
            MOV.L       @R1,R5     ; Here made reference in Condition (3)
              RTS/N
    ----------------------------------------------
    Workaround
    This problem can be circumvented either of the following ways:
    (1)   Use the optimize=0 option, not optimize=1.
    (2)   Immediately before the statement or expression in Condition (2)-a or -b, place an nop() include function or an assignment to another volatile-qualified variable than those in Conditions (3) and (4).


    2.4   On an initial value of a union containing a bit field as one of its members (SHC-0042)

    2.4.1   When a union containing a bit field as one of its members has an initial value, and the bits of a bit field are assigned to the data values to store from lower to upper, the initial value may become incorrect.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   In the program exists a union whose first member is a bit field.
    (2)   The size of the bit field in (1) is not the one specific to the declared type of the bit field.
    (3)   The union in (1) has the initial value of a negative quantity.
    (4)   The bit_order=right option is used. Or the union in (1) is subject to the #pragma bit_order right directive.
    Example C source file:
    ----------------------------------------------
    #pragma bit_order right
    union {
        int a:2;
        int b;
    }u={-1};
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _u:                              ; static: u
              .DATA.L     H'FFFFFFFF ; To be H'00000003
    ----------------------------------------------
    Workaround
    This problem can be circumvented either of the following ways:
    (1)   In front of the first member of the union in Condition (1), declare a structure that has only a bit field as its member whose size is the same as the bit field that is the first member of the union.
    Example:
          union {
               struct {
                   int dummy:2;
               }s;
               int a:2;
               int b;
          }u={-1};
    (2)   Mask the initial value with the bit size of the bit field; then use this as the new one.
    Example:
          union {
              int a:2;
              int b;
          }u={-1&3};

    2.4.2   When a union containing a bit field as one of its members has an initial value, and the initial value has redundant braces {}, the initial value may become incorrect.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   In the program exists a union whose first member is a bit field.
    (2)   The size of the bit field in (1) is not the one specific to the declared type of the bit field.
    (3)   The union in (1) has an initial value.
    (4)   The initial value has redundant braces {}.
    Example C source file:
    ----------------------------------------------
    union {
        char a:3;
        short b;
    }u={{0x8F}};
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _u:                              ; static: u
              .DATA.B     H'8F       ; To be H'E0
              .DATAB.B    1,0
    ----------------------------------------------
    Workaround
    Remove the redundant braces {}.


    2.5   On a function taking a variable number of arguments (SHC-0043)
    When a recursive call is made of a function that takes a variable number of arguments, they may incorrectly be passed to the function.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   A recursive call is made of a function that takes a variable numberof arguments.
    (3)   The argument precedent by two to the variable part of arguments is passed to the function via a register.
    (4)   Before the argument in (3) exists another one passed to the function via the stack.
    (5)   The return value of the function in (2) is of type void, int, or floating.
    (6)   All the arguments in (2) are of type int or floating.
    (7)   A recursive call of a function is made:
    1. within a return statement, or
    2. at the end of the function or immediately before the return statement, with the return value of the function being of type void.
    Example C source file:
    ----------------------------------------------
    long long S;
    void f(long long a1, int a2, int a3, ...) {
        S += a1;
        if (a1!=0) {
            f(a1-1, 0, 0);    /*  Becomes f(0, 0, 0); */
        }
    }
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Use the optimize=0 option, not optimize=1.
    (2)   Qualify at least one of the arguments to be volatile.
    (3)   Declare the function in Condition (2) using the #pragma regsave directive.
    (4)   Arrange arguments so that Condition (3) or (4) might not be met.
    (5)   If Condition (7)-b is met, place an nop() include function immediately after the function call.


    2.6   On the controlling expression of a switch statement being of type long long or unsigned long long (SHC-0044)
    When the controlling expression of a switch statement is of type long long or unsigned long long; and the result of its evaluation is a constant, control may jump to the statement of an incorrect case label or an address error may arise.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   In the program exists a switch statement.
    (2)   The controlling expression of the switch statement in (1) is of type long long or unsigned long long.
    (3)   The controlling expression in (2) is a constant expression.
    (4)   The minimum value of case constants in the switch statement in (1) is 0.
    (5)   The switch statement in (1) is expanded as a table.
    Example C source file:
    ----------------------------------------------
    int func() {
        long long d=1;
        switch(d) {       /* Evaluation of controlling expression 
        case 0:                                  always results in 1 */
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
            return 1;
            break;
        default:
            break;
        }
        return 0;
    }
    ----------------------------------------------
    _func:
              STS.L       PR,@-R15
              MOV         #1,R6      ; H'00000001
              MOV.L       R6,@-R15
              MOV         #0,R1      ; H'00000000
              MOV.L       R1,@-R15
              MOV         #8,R5      ; H'00000008
              MOV.L       R5,@-R15
              MOV.L       L25+2,R4   ; __cmpgt64u
              JSR         @R4
              MOV.L       R1,@-R15
              ADD         #16,R15
              CMP/EQ      #0,R0
              BF          L23
              MOV         #1,R6      ; H'00000001
              MOVA        L26,R0
              MOV.L       @(R0,R6),R1; Accesses an odd address, 
                                         resulting in an address error
              ADD         R1,R0
              JMP         @R0
              NOP
    
    . . . . . . . . . . . . . . . . . . . . . . .
    
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Assign the controlling expression of the switch statement to a volatile-qualified variable, and then substitute this variable for the controlling expression.
    (2)   Add a case label with a smaller value than 0.
    (3)   Use the case=ifthen option.


    2.7   On Using Two or More Integer Constants (SHC-0045)
    If two or more integer constants are used in a block, they may be replaced with incorrect ones after compilation.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   In a block is used an integer constant whose value is within a range from -2,147,483,648 to -129, or from 128 to 2,147,483,647.
    (3)   In the block that contains the integer constant in (2) exists another integer constant, and the difference between the former and the latter falls within a range from -128 to 127. *
    (4)   The types of the integer constants in (2) and (3) are different from each other.
    *   Note that there can exist more than one combination of integer constants in (2) and (3) in a block

    Example C source file:
    ----------------------------------------------
    int func() {
        unsigned short a;
        unsigned short *p;
        a = 65535;
        p = &a;
        *p *= 32767;          // *p set to 32769
        if (*p == 32770) {    // 32769 compared with 32770
            return 1;
        }
        return 0;
    }
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _func:
              MOV.W       L11,R6     ; H'8001
              EXTU.W      R6,R2      ; R2 set to 32769
              ADD         #1,R6      ; R6 set to -32766
              CMP/EQ      R6,R2      ; 32769 compared with -32766
              RTS
              MOVT        R0
    ----------------------------------------------
    Workaround
    This problem can be circumvented either of the following ways:
    (1)   Assign either of the integer constants in Conditions (2) and (3) to a volatile-qualified variable, and then use it.
    (2)   Use the optimize=0 option, not optimize=1.


    2.8   On an Assignment to an Element of a volatile-Qualified Array (SHC-0046)
    If before an if statement and within its then statement exist two assignment expressions that assign variables to the same element of a volatile-qualified array, assignment may be made only once.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   In the program exists an iteration statement.
    (3)   In the iteration statement in (2) above exists an if statement not accompanied with an else statement.
    (4)   Before the if statement and within its then statement in (3) exist two assignment expressions that assign variables to the same element of an array.
    (5)   The array in (4) is qualified to be volatile. Or the array in (4) is an external variable, and the global_volatile=1 option is used.
    Example C source file:
    ----------------------------------------------
    int x, y, z;
    volatile int V[10];
    void func() {
        int i;
        for(i = 0; i < 10; i++) {
            V[i] = x + y;       // 1st assignment
            if(z) {
                V[i] = y + z;   // 2nd assignment
            }
        }
    
    }
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _func:
              MOV.L       R14,@-R15
              MOV.L       L15,R5     ; _x
              MOV.L       L15+4,R4   ; _y
              MOV.L       L15+8,R2   ; _z
              MOV.L       @R5,R14
              MOV.L       @R4,R1
              MOV.L       @R2,R4
              ADD         R1,R14
              ADD         R4,R1
              MOV         #0,R5      ; H'00000000
              MOV         #10,R6     ; H'0000000A
              MOV.L       L15+12,R7  ; _V
    L11:
              TST         R4,R4
    
    
              MOV         R14,R2
              BT          L13
              MOV         R1,R2
    L13:
              ADD         #-1,R6
              MOV         R5,R0
              TST         R6,R6
              MOV.L       R2,@(R0,R7); Assignment always made only once
              ADD         #4,R5
              BF          L11
              RTS
              MOV.L       @R15+,R14
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Place an nop() include function in the then statement of the if statement in Condition (3).
    (2)   Add an else statement to the if statement in Condition (3).
    (3)   Use the optimize=0 option, not optimize=1.


    2.9   On an Iteration Statement Having a volatile-Qualified Controlled Variable (SHC-0047)
    If an iteration statement has a volatile-qualified controlled variable, iteration may be made an incorrect number of times.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   In the program exists an iteration statement.
    (3)   The iteration statement in (2) has a controlled variable of type int; neither long long nor unsigned long long.
    (4)   The controlled variable in (3) is qualified to be volatile. Or the controlled variable in (3) is an external variable, and the global_volatile=1 option is used.
    (5)   The reset expression that resets the controlled variable in (3) is an additive expression (addition or subtraction).
    (6)   In the iteration statement in (2) is made a function call. Or in this iteration statement exists a pointer-type variable pointing to the controlled variable in (3), and this pointer-type variable is reset in the iteration statement.
    Example C source file:
    ----------------------------------------------
     extern void sub();
     volatile int i;
     void func() {
         i = 1;
         while (i) {
             i--;
    
             sub();   // Though i may be reset at origin of function call, 
                      // number of times of iteration is always 1
         }
         return;
     }
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Place an expression that refers to the controlled variable in Condition (3) after the reset expression in Condition (5).
    (2)   Declare the controlled variable in Condition (3) to be long long or unsigned long long.
    (3)   Use the optimize=0 option, not optimize=1.

    2.10   On Using Comma Operators in the Controlling Expression of an Iteration Statement (SHC-0048)
    If comma operators are used in the controlling expression of an iteration statement, the controlling expression may be evaluated from right to left.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   In the program exists an iteration statement.
    (3)   The iteration statement in (2) has a controlled variable of type int; neither long long nor unsigned long long.
    (4)   The reset expression that resets the controlled variable in (3) is an additive expression (addition or subtraction).
    (5)   The iteration statement in (2) is iterated only once.
    (6)   In the controlling expression of the iteration statement in (2) is used comma operators.
    Example C source file:
    ----------------------------------------------
    int A, B;
    void func() {
        int i;
        for (i=0; A++, B+=A, i<1; i++) {  // B+=A executed first; then A++
            B++;
        }
    }
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Use no iteration statement.
    (2)   Declare the controlled variable in Condition (3) to be long long or unsigned long long.
    (3)   Use the optimize=0 option, not optimize=1.


    2.11   On Using the Same Constant before and after a Function Call (SHC-0049)
    If the same constant is used before and after a function call, the value of the constant after the function call may become incorrect.

    Conditions
    This problem may occur if the following conditions are all satisfied:
    (1)   The optimize=1 option is used.
    (2)   Neither the opt_range=noblock option nor the global_alloc=0 option is used.
    (3)   In the program exists an function call.
    (4)   The same constant is used before and after the function call in (3).
    (5)   The constant in (4) is used at least once in an iteration statement.
    (6)   A register whose value is indefinite before and after a function call is assigned to the constant in (4).
    Example C source file:
    ----------------------------------------------
    int array[10];
    void func(int j, int k) {
        int i;
        for (i = 0; i < 10; i++) {
            if (k < 20) {
                sub();
    
            }
            if (j < 20) {
                array[i] = j;
            }
    . . . . . . . . . . . . . . . . . . . . . . . 
        }
    }
    ----------------------------------------------
    Result of compilation:
    ----------------------------------------------
    _func:
    . . . . . . . . . . . . . . . . . . . . . . .
              MOV         R5,R11
              MOV         R4,R12
              MOV         #10,R14
              MOV.L       L17,R13    ; _array
    L11:
              MOV         #20,R1     ; R1 set to 20
              CMP/GE      R1,R11
              BT          L13        ; (A)
              MOV.L       L17+4,R2   ; _sub
              JSR         @R2        ; (B)
              NOP
    L13:
              CMP/GE      R1,R12     ; Even when R1 is reset at origin of 
                                     ; function call in (B), previous value 
                                     ; of R1 must be used if no jump is 
                                     ; made at (A); however, reset value of 
                                     ; R1 is used in error
              BT          L15
    
              MOV.L       R12,@R13
    
    . . . . . . . . . . . . . . . . . . . . . . .
    
    ----------------------------------------------
    Workaround
    This problem can be circumvented any of the following ways:
    (1)   Use the opt_range=noblock option.
    (2)   Use the global_alloc=0 option.
    (3)   Use the optimize=0, not optimize=1.


  3. Schedule of Fixing the Problems
    We plan to fix these problems at the next release of the products. (Scheduled at the end of March, 2006)





© 2008. Renesas Technology Corp., All rights reserved. Privacy | Legal