CC5X BUGS, VERSION 3.X ---------------------- NOTES: This list contains the bugs that produce wrong code. Compiler weaknesses which produce error messages are normally not included in this list. The bugs applies only to the compiler versions termed "Affected", (using from - to notation) and the versions in between these. The version termed "Fixed" is the first version released after the bug has been removed. CC5X version 3.0 was released 20th May 1999. Last updated: 23. September 2024 BUG 208: Code generator bug Affected: 3.8A - 3.8B Fixed: 3.8C Some of the improved code for division and remainder/modulus implemented for code level 2 (option -cl2) are not correct when the operands are located in a struct or in a fixed array item. The problem does not occur when the offset to the struct member or array item is 0. pack.ped16 /= 335; // BUG uTab[2] /= tmp16; // BUG pack.ped16 = tmp16 / 335; // BUG pack.ped16 = tmp16 / pack.pid16; // BUG pack.ped16 = pack.pid16 / tmp16; // BUG pack.pack24 = tmp24 / pack.batt24; // BUG bTab[2] = tmp8 / 10; // BUG pack.ped16 = pack.pid16 % tmp8; // BUG pack.p32 = pack.x32 % tmp8; // BUG pack.ped16 %= 200; // BUG uTab[2] %= 100; // BUG pack.ped16 = tmp16 % 99; // BUG pack.batt24 %= 200; // BUG bTab[2] = tmp8 % 10; // BUG pack.ped16 %= tmp8; // BUG Workaround: Use code level 1 (option -cl1 or #pragma codeLevel 1). Reported by: Vladimir BUG 207: Code generator bug Affected: 3.0I - 3.8 Fixed: 3.8A The compiler will in some cases use a global variable for holding the return value. Unfortunately there is a bug when returning struct and enum types that cause the global variable to be modified before return. The problem occur when returning at least 2 different global variables. For enums the problem also occur when returning a global variable and a constant. The problem disappear for all cases when a local variable is also returned. typedef struct { char mem; } TS1; TS1 sn1, sn2; int v1; TS1 sfunk( void) { if (v1) return sn2; return sn1; } BUG 206: C parsing bug Affected: 3.1G - 3.8 Fixed: 3.8A It is possible to write meaningless code in a multi-assignment expression. uns8 a,b,c,d; a = b + c = d; // meaningless expression a = ++b = c; // the increment has no effect BUG 205: Code generator bug Affected: 3.5E - 3.8 Fixed: 3.8A Wrong code is generated for a multi-assignment expression when the variable at the rightmost assignment also is used in the rightmost expression enabling the use of an instruction writing the result directly to the destination without using the W register. The problem only applies to 8 bit variables. uns8 a,b,c; a = b = b + 1; // Wrong code a = b = (c << 4) | b; // Wrong code // equivalent, but not supported syntax: a = b += 1; a = b |= (c << 4); Reported by: H Syrovátka BUG 204: Const access bug Affected: 3.5E - 3.8 Fixed: 3.8A Accessing const data using 16 bit pointers that also access GPR/RAM is wrong for most devices with 64 banks. Such pointers uses bit 15 to distinguish between RAM access and const access in program memory. Bit 6 of NVMADRH is always active in devices with 64 banks, which then requires bit 15 of the const pointer to be cleared. The problem applies to devices with up to 16k code words. For devices with more code NVMADRH.6 is cleared as required. Reported by: S Nagasue BUG 203: Header file bug Affected: 3.5E - 3.8 Fixed: 3.8A The definition of makro __MOVLB(k) found in file "hexcodes.h" is wrong for devices with 64 banks. Reported by: H Syrovátka BUG 202: Code generator bug Affected: 3.5E - 3.8 Fixed: 3.8A Wrong code is generated for the following code sequence when variable b and c has the same address and thus overlaps. The compiler correcly generates no code for the rightmost assignment but the leftmost assignment fails because b (or c) is not loaded into the W register. The problem only occurs when b is an 8 bit GPR variable. char a, b; char c @ b; a = b = c; Reported by: H Syrovátka BUG 201: Optimization bug Affected: 3.4 - 3.7D Fixed: 3.8 Wrong code is generated for the following code sequence. The problem applies to the enhanced 14 bit core only. INDF0 ^= a0; // Wrong code (MOVIW INDF0++), also for INDF1/FSR1 FSR0 += 1; Workaround: Turn off optimization locally or add code in between. Reported by: H Syrovátka BUG 200: Code generator bug Affected: 3.4 - 3.7C Fixed: 3.7D Accessing a large table using offset between 128 and 256 may result in wrong code or a strange error message. The problem is due to wrong internal type handling. uns16 m16[90]; .. m16[65] = 1000; // Wrong error: Offset out of range m16[(uns8)65] = 1000; // FIX / workaround FSR1 = (char *) &m16[64]; // wrong code FSR1 = (char *) &m16[(uns8)64]; // FIX / workaround Reported by: S Nagasue BUG 199: Code generator bug Affected: 3.4 - 3.7C Fixed: 3.7D Wrong code is generated when assigning 16 bit or larger variables to certain SFR addresses. The problem applies only to the enhanced 14 bit core devices. For a random SFR address the problem is found for 1/80 = 1.25 % of the addresses when using a 16 bit variable. uns16 DAC1REF @ (uns16)&DAC1REFL; // PIC16F1779 .. DAC1REF = val; // Wrong code generated Reported by: Vladimir BUG 198: Code generator bug Affected: 3.3H - 3.7C Fixed: 3.7D Wrong code is generated for the following expressions. uns8 x; x = (x > get_val()); // Wrong code, also for >=, <, <= Reported by: P Trnak BUG 197: ADDFSR bug Affected: 3.4 - 3.7B Fixed: 3.7C This problem applies only to the enhanced core 14 devices. Subtracting 0 from FSR0 and FSR1 fails: FSR0 -= 0; // Wrong code generated Reported by: H Syrovátka BUG 196: Bank bit updating bug Affected: 3.4 - 3.7 Fixed: 3.7A This problem applies only to the enhanced core 14 devices. Bank bit updating may fail when the compiler performs a bank bit update before a conditional goto. Several other conditions have to be satisfied and the problem does not occur frequently. The underlying problem is that bank bit updating on legacy 14 bit core devices are performed using separate Bit Set and Bit Clear instructions on each bank bit. The separate updating for each bit was not upgraded to handle the MOVLB instruction in this case. Example: bank1 uns8 v1_b1; bank2 uns8 v2_b2; bank3 uns8 v3_b3; uns8 f1_b1( void) { return v1_b1; } uns8 f2(void) { v2_b2 ++; if (f1_b1() && // conditional goto (problem starts) v3_b3 != 0) // BUG (incorrect bank updating) return 1; return 2; } Reported by: M Raimbault BUG 195: Local variable allocation bug Affected: 3.4 - 3.5D Fixed: 3.5E Variable allocation of local variables for enhanced 14 bit core devices may fail for banks that contain no global variables. The problem is that space is allocated in the mapped area of the bank if more than 80 bytes is required for local variables in a specific bank. This creates an error when the mapped area (0x70 - 0x7F) is used for another purpose. The workaround is to assign a global variable to RAM banks that contain (a large amount of space for) local variables. Reported by: M Raimbault BUG 194: Bank bit updating bug Affected: 3.0 - 3.6 Fixed: 3.7 Bank bit updating may fail when accessing const data implemented as a return table containing a multiple of 256 RETLW. This happens for access functions implemented directly by application code and access functions generated by the compiler. Further conditions for the bug that the last bank access before the return from the access function is different from the first bank access after the return. A workaround for the bug is to use a manual bank bit update: #pragma updateBank 0 // enter manual bank bit updating BSR = 0; // update bank, enhanced 14 bit core #pragma updateBank 1 Reported by: J Bodin BUG 193: Bank bit updating bug Affected: 3.0 - 3.7 Fixed: 3.7A Using two computed goto regions in a single function may cause wrong bank bit updating when entering the second computed goto region in some cases. The workaround is to inspect the generated code when a double computed goto is used in a single function. Then insert a manual bank bit update if the generated code is not correct. #pragma updateBank 0 // enter manual bank bit updating BSR = 0; // update bank, enhanced 14 bit core #pragma updateBank 1 Reported by: J Bodin BUG 192: Const data bug Affected: 3.5E - 3.5G Fixed: 3.6 Const data access on devices using NVMxxx registers (NVMADRL .. NVMCON1) may fail when data is stored using 14 bit full word. The problem is that bit NVMREGS in register NVMCON1 has to be cleared before reading const data stored in program memory. This bit is set to 0 as default but could be modified in the application code. The workaround is to clear NVMREGS or to disable 14 bit data: #pragma wideConstData 8192 // never use 14 bit data Reported by: D Klingshirn BUG 191: Code generator bug Affected: 3.5E - 3.5F Fixed: 3.5G Wrong code is generated for the following expressions. The problem ONLY applies to the enhanced 14 bit core devices. Examples: uns8 a8, b8, c8; a8 = (b8 >> c8) & 0x03; // BUG a8 = (b8 << c8) | 0x81; // BUG Reported by: P Trnak BUG 190: Code generator bug Affected: 3.4B - 3.5F Fixed: 3.5G Wrong code is generated in some cases for the following expressions. The probability of generating wrong code is low. The problem does NOT apply to the enhanced 14 bit core devices. Examples: uns8 a8, b8; // Constant = { 13, 14, 15, 31, 46, 47 } W = W * Constant; W = a8 * Constant; // The above basic expressions may appear in complex expressions like: b8 = (a8 * Constant) & 0xF; BUG 189: Code generator bug Affected: 3.2N - 3.5F Fixed: 3.5G Wrong code is generated for certain expressions that use Carry to transfer a 'bit' value. Examples: bit TestFunc( void) { uns8 a8, b8, c8; if (...) return a8 + b8 == c8; // BUG Carry = Get8bitValue() != c8; // BUG return Get8bitValue() == c8; // BUG } Reported by: H Syrovátka BUG 188: Code generator bug Affected: 3.4A - 3.5D Fixed: 3.5E Wrong code is generated when loading FSR0 or FSR1 using an 8 bit variable located in bank 2 or above. Examples: bank5 uns8 u8: FSR0 = u8; // BUG FSR0 = (char *) u8; // BUG FSR1 = u8; // BUG FSR1 = (char *) u8; // BUG Reported by: H Syrovátka BUG 187: Code generator bug Affected: 3.3H - 3.5D Fixed: 3.5E Wrong code is generated for the following cases: uns8 u8, a8; u8 = (a8 & 0x0F) >= 0x0A; // Wrong code u8 = (a8 & 0x0F) < 0x04; // Wrong code u8 = ((a8+10) & 0x0F) > 0x0D; // Wrong code u8 = (func() & 0x0F) > 0x0D; // Wrong code u8 = func() >= 0x02; // Wrong code u8 = a8 + (func() >= 0x02); // Wrong code W = func() >= 0x02; // Wrong code .. char func() { return W; } BUG 186: Division bug Affected: 3.0 - 3.5D Fixed: 3.5E Wrong code is generated when dividing with certain constants. The constant must contain at least one 0xFF in any byte position, or LSB equal to 0x01. The error ONLY occur when using code level 0 (option -cl0 or #pragma codeLevel 0). Version 3.3H or older (also all FREE editions) always use code level 0. uns16 v16; uns32 v32; v16 /= 0x02FF; // bug v16 /= 0xFF02; // bug v16 /= 0x0301; // bug v32 /= 0x03FF0303; // bug v32 /= 0x0302FF03; // bug Reported by: G Argraves BUG 185: Code generator bug Affected: 3.1H - 3.5B Fixed: 3.5C Wrong code is generated for some special constant expressions. The general expressions are: var - K1 + (K2 op K3) var + K1 - (K2 op K3) 1. K1, K2 and K2 can be single constants or constant expressions. 2. K1 must be size 2 or larger (int16/uns16). 3. (K2 op K3) must be size 2 or larger (int16/uns16). 4. K1 must be larger than (K2 op K3). Examples: uns8 u8: u8 = u8 - 0x80 + (0x81 - 0x80); // BUG W = (int16)(W - 128U) + (0x81 - 0x80); // BUG W = W + 0x80 - (0x81 - 0x80); // BUG W = W - (0x80 + 3 - 3) + (0x81 - 0x80); // BUG W = W - 0x80 + (2001 - 2000); // BUG Reported by: H Syrovátka BUG 184: Code generator bug Affected: 3.2A - 3.5A Fixed: 3.5B Wrong code is generated for some special conditional expressions using the & operator. The compiler will print a warning telling that the expression is always false or true. The problem only applies to variables of 16 bit or greater when using the > or <= operators. uns16 u16; if ((u16 & 0xF00) > 0xE01) .. // wrong code generated if ((u16 & 0xF00) <= 0xE22) .. // wrong code generated BUG 183: Code generator bug Affected: 3.5A Fixed: 3.5B Wrong code is generated for some conditional expressions using the & operator. The problem applies when the constant or parts of the constant for the & operator is 0x7F or 0xFE. The problem applies to the enhanced 14 bit core only. uns8 u8; uns16 u16; if ((u8 & 0x7F) > 3) .. // wrong code generated if ((u8 & 0xFE) > 3) .. // wrong code generated if ((u16 & 0x7FFF) == 0x5000) .. // wrong code generated Reported by: H Syrovátka BUG 182: Variable overlapping bug Affected: 3.2I - 3.5 Fixed: 3.5A Wrong code is generated when a function parameter is set to overlap with a global variable allocated by the compiler. This problem does not apply to parameters that overlaps with variables set to specific addresses before compilation. uns8 var; void func( uns8 par1 @ var) { .. } // wrong code generated Reported by: H Syrovátka BUG 181: Bank bit updating bug Affected: 3.1H - 3.5 Fixed: 3.5A Bank information is lost when assigning an 8 bits pointer with offset to a 16 bits pointer. The most significant byte of the 16 bits pointer will be set to 0. This creates a bug when the 8 bit pointer access data in bank 2 og higher. size1 char *px1; size2 char *px2; char i; bank2 uns8 globTab2[30]; .. px1 = &globTab2[1]; px2 = &px1[i]; // BUG, MSB set to 0 px2 = &px1[3]; // BUG, MSB set to 0 px1[1] += 1; // OK, bank 2 is accessed px2 = px1; // OK, MSB set to 1 (bank 2 & 3) Reported by: C Belfer BUG 180: Variable overlapping bug Affected: 3.4 - 3.5 Fixed: 3.5A Wrong code is generated when using the variable that overlaps with the WREG for the enhanced 14 bit core. uns8 var @ WREG; var = lsl( var ); // wrong code generated var = rl( var ); // wrong code generated Reported by: H Syrovátka BUG 179: Const access bug Affected: 3.4B - 3.5 Fixed: 3.5A Accessing a const array inside a table struct may cause invalid code to be generated. The problem does not apply to the enhanced 14 bit core. const struct { char dats[10]; } tab[4] = .. .. vx = tab[num_tab].dats[0]; // correct vx = tab[num_tab].dats[1]; // wrong code Reported by: A Marques BUG 178: Indirect access bug Affected: 3.4 - 3.5 Fixed: 3.5A The special purpose registers FSR0 and FSR1 on enhanced 14 bit core devices are not incremented when used as a switch argument. switch( *FSR0++) { .. case .. } switch( *--FSR1) { .. case .. } Reported by: H Syrovátka BUG 177: Indirect access bug Affected: 3.4 - 3.5 Fixed: 3.5A The special purpose registers FSR0 and FSR1 on enhanced 14 bit core devices are sometimes not incremented correctly. This may apply to multiple use of the same register and modify-assignment expressions: *FSR0 = *FSR0++ ^ x; *++FSR0 = *FSR0 ^ x; *FSR1 = *--FSR1 & 55; *FSR0++ &= *FSR1; *FSR0++ ^= 0x7; Reported by: H Syrovátka BUG 176: Indirect access bug Affected: 3.4 - 3.4I Fixed: 3.5 The special purpose registers FSR0 and FSR1 on enhanced 14 bit core devices are sometimes not incremented when used as function parameters. func1( *FSR0++ & 0xF); func1( *--FSR1 + 5); Reported by: H Syrovátka BUG 175: Const data bug Affected: 3.1 - 3.4I Fixed: 3.5 Significant bits are sometimes lost when data are stored as compressed 14 bit elements. The problem may occur for data stored as 8+6 bits. The compiler checks that each second const byte is 6 bit. Wowever, when tables are joined into the same storage, they must be aligned on even addresses. This sometimes fails. The problem does not occur when data are stored as 7+7 bits. Workaround: Avoid using 14 bit compressed data or inspect the const access funtions. #pragma wideConstData 8192 // never compress const data Reported by: P Ceolin BUG 174: Pointer bug Affected: 3.0 - 3.4I Fixed: 3.5 Wrong code is generated in some cases when assigning an address with offset to a 16 bit pointer. The problem applies only to elements larger than 8 bit. uns16 array16[10]; uns8 index; size2 uns16 *p16; p16 = array16 + i; // BUG p16 = &array16[i]; // OK Reported by: H Syrovátka BUG 173: Inline asm bug Affected: 3.4 - 3.4I Fixed: 3.5 The compiler generates wrong code when using the MOVWI/MOVIW instructions with offset for the enhanced 14 bit core. #asm MOVIW 1[INDF0] ; BUG MOVIW 5[INDF0] ; BUG MOVIW -1[INDF0] ; OK #endasm Reported by: H Syrovátka BUG 172: Floating and fixed point bug Affected: 3.0H - 3.4I Fixed: 3.5 Floating and fixed point local variables are not handled correctly when using the 'const' type modifier. Assignments and many operations including math library operations are wrong: const float z = (long)16*16; // BUG const fixed16_8 ee1 = 512; // BUG const fixed16_8 ee2 = 512.0; // OK float x; x = z; // BUG if (z == 3.2) // BUG .. if (z < 3.1) // BUG .. if (z == x) // BUG .. if (z >= x) // BUG .. x *= z; // BUG BUG 171: Fixed point bug Affected: 3.0H - 3.4I Fixed: 3.5 The sign bit is not extended when using type cast on fixed point variables. fixed8_8 as8_8, bs8_8; fixed16_8 as16_8; as16_8 = (fixed16_8)as8_8 + bs8_8; // BUG Reported by: P van der Hulst BUG 170: Bank bit bug Affected: 3.4 - 3.4I Fixed: 3.5 The bank bits are not correctly updated when using skip() on enhanced 14 bit code devices. bank1 char a1; bank0 char a0; .. skip( a1); goto L1; .. #pragma computedGoto 0 L1: a0 = 1; // bank bits not updated return; Reported by: H Syrovátka BUG 169: Indirect access bug Affected: 3.4 - 3.4I Fixed: 3.5 The special purpose registers FSR0 and FSR1 on enhanced 14 bit core devices are not incremented when accessed in conditional statements. char aa; if (*++FSR0 == aa) .. if (*--FSR1 > 10) .. Reported by: H Syrovátka BUG 168: Code generator bug Affected: 3.4 - 3.4H Fixed: 3.4I Wrong code is generated when adding or subtracting a large constant and a signed variable when sign extension is required. int32 as32; int24 as24; int16 bs16; int8 bs8; as32 = bs8 + 0x12340078; // BUG as32 = bs16 + 0x12000078; // BUG as32 = bs8 + 0x010020; // BUG as24 = bs8 - 0x00FFFF; // BUG BUG 167: Optimization bug Affected: 3.4 - 3.4H Fixed: 3.4I Wrong code is generated when adding a constant to a table element larger than 8 bit. The problem applies to the enhanced 14 bit core only. uns16 SensorData[8]; uns8 x; SensorData[x] += 2; // BUG SensorData[x] += 1; // BUG Workaround: Turn off optimization locally: #pragma optimize 0 SensorData[x] += 2; #pragma optimize 1 Reported by: F Morauf BUG 166: Indirect access bug Affected: 3.4 - 3.4H Fixed: 3.4I Wrong code is generated when accessing a table that cross a bank boundary when using an index with offset. The problem applies to the enhanced 14 bit core only. bank5 uns8 tab8[128]; uns8 x, y, z; z = tab8[x + y]; // BUG y = tab8[x + y + 1]; // BUG y = tab8[x + 1]; // BUG y = tab8[(x & 3) + 1]; // BUG Reported by: S Lauckner BUG 165: Fixed point bug Affected: 3.1H - 3.4H Fixed: 3.4I Wrong code is sometimes generated when comparing an unsigned fixed point variable to a constant. The compiler warns that the expression is always true or false in these cases. A similar problem applies to signed and unsigned fixed point variables when the constant is out of range. Then the warning is sometimes wrong (always true instead of always false or opposite). fixedU8_8 delta; fixed8_8 aa; if (delta > 200.1) // BUG .. if (aa > 200.1) // BUG: Constant out of range, wrong warning .. Reported by: P van der Hulst BUG 164: Pointer bug Affected: 3.4 - 3.4G Fixed: 3.4H FSR0H is not always updated when accessing an 8 bit pointer using a constant offset. This also includes access to elements in a structure. The problem applies to the enhanced 14 bit core only. uns8 *psi; W = psi[0]; // BUG W = psi[6]; // BUG id = px->cps; // BUG Reported by: C Belfer BUG 163: Indirect access bug Affected: 3.4 - 3.4G Fixed: 3.4H Wrong code is generated when accessing a large table that uses more than one RAM bank and contains 16 bit or larger data elements. uns16 samples16[256]; uns8 indx; uns16 ind16, diff; samples16[indx++] = diff; // BUG samples16[ind16++] = diff; // BUG Reported by: F Boddeke BUG 162: Inline code bug Affected: 3.4 - 3.4G Fixed: 3.4H Wrong code is generated for the following complex expression when using inline code (no math library call). The expression must be 16 bit or larger and contain (at least) 3 constants. The innermost expression must be subtraction or addition. The next operation must be multiplication. The error occur when the compiler tries to simplify the expression by moving the innermost constant. uns32 nCount, frequency; nCount = ((frequency - 100) * 2) / 12800; Reported by: S Reardon BUG 161: Typedef enum bug Affected: 3.2K - 3.4G Fixed: 3.4H Wrong code is generated when reading enum const data to an enum variable. typedef enum { .. } A_list; const struct state_entry { A_list action; } arrayX[] = { .. }; A_list action; uns8 x; action = arrayX[x].type; // Wrong code generated Workaround: Use "uns8 /*A_list*/ action;". Reported by: C Belfer BUG 160: Fixed point bug Affected: 3.1G - 3.4F Fixed: 3.4G Wrong code is generated when casting a constant expression to a fixed point type. fixed8_8 delta; if (delta > (fixed8_8)(-4.0/256.0)) // BUG .. Workaround: Avoid using fixed point typecast unless required. Reported by: P van der Hulst BUG 159: Const data bug Affected: 3.4 - 3.4F Fixed: 3.4G Wrong code is generated when accessing an 8 bit const pointer that may point to both const data and RAM. This problem applies only to the enhanced 14 bit core. char qt[2]; const char *x = "Hello world! one two three four five"; W = *x; x = qt; W = *x; Reported by: B O'Shaughnessy BUG 158: Multiplication bug Affected: 3.4 - 3.4E Fixed: 3.4F Wrong code is generated when multiplying 16 bit variables by the constants 3, 5 and 6. uns16 a16; a16 = a16*6; // BUG for enhanced core 14 a16 = a16*5; // BUG for enhanced core 14 a16 = a16*3; // BUG for all core types Workaround: Assign the result to another variable: x = a16 * 3; Reported by: M Isler BUG 157: Indirect operation bug Affected: 3.4 - 3.4E Fixed: 3.4F Wrong code is generated for a few specific indirect operations. The problem occurs only when using code level 0. Code level 0 is set by option -cl0 or by #pragma codeLevel 0. struct MyStruct { uns16 v1; uns24 v2; uns32 v3; } s; struct MyStruct *p; char i; p->v1 ++; // bug for indirect increment 16 bit p->v2 ++; // bug for indirect increment 24 bit p->v3 ++; // bug for indirect increment 32 bit p->v2 += 100; // bug when adding 1 byte constant to 24 bit variable p->v2 += i; // bug when adding 1 byte variable to 24 bit variable p->v3 += 100; // bug when adding 1 byte constant to 32 bit variable p->v3 += i; // bug when adding 1 byte variable to 32 bit variable p->v1 -= 255; // bug when subtracting 255 from 16 bit variable Reported by: M Morimoto BUG 156: Const pointer bug Affected: 3.4 - 3.4D Fixed: 3.4E Accessing more than 256 bytes of const data may fail for the new enhanced 14 bit core. The problem is wrong code in the access function when performing a check on the index variable. Workaround: Use option -cl0 or insert #pragma codeLevel 0 at the end of the source code (where the const data is inserted). Reported by: B Casto BUG 155: Const pointer bug Affected: 3.4 - 3.4C Fixed: 3.4D Const pointers may fail when accessing data in RAM for the new enhanced 14 bit core. Reading data through a const pointer will always use an access function. The problem is that FSR0H is not updated when reading data from RAM in the access function. The workaround is to only use 'const' on pointers accessing ROM data (text strings and fixed data tables). Reported by: C Belfer BUG 154: Bank bit updating bug Affected: 3.4 - 3.4C Fixed: 3.4D Bank bit updating may fail in functions using the BRW instruction to perform a computed goto. The BRW instruction is also used for Leanslice tasks to select the state. The workaround is to inspect functions using the BRW instructions and move variables to the same bank in case of wrong bank bit updating. The problem only applies to devices using the new enhanced 14 bit core. Reported by: A Fish BUG 153: Code generator bug Affected: 3.4 - 3.4C Fixed: 3.4D Wrong code is generated for the following special case. The first argument must be a 16 bit or larger variable. The second argument must be indirect access of a similar sized variable. The problem applies only when comparing for equality or not equal. The problem also applies when using a pointer for indirect access. uns16 m16, tab16[10]; char x; if (m16 == tab16[x]) .. BUG 152: Interrupt bug Affected: 3.4 - 3.4C Fixed: 3.4D The new enhanced 14 bit core does not need to save vital registers during interrupt. However, the PCLATH register need to be updated in the interrupt routine before the first GOTO/CALL when using more than one code page. The PCLATH updating is normally located in the 'int_save_registers' macro in INT16CXX.H file. Suggested workaround: interrupt serverX( void) { /* W, STATUS, BSR, FSRx registers and PCLATH are automatically saved in shadow registers */ PCLATH = 0; // handle the interrupt .. } Reported by: M Bogdanowicz BUG 151: Bank bit bug Affected: 3.4 - 3.4B Fixed: 3.4C Bank bit updating may fail for the new enhanced 14 bit core. Bank updating fails when the new bank access is a multiple of 8 steps (8, 16, 24) above or below the current bank setting. This means a that bank updating may fail when accessing RAM or special purpose registers in bank 8 or above, or for the next banked access. bank0 char v0; bank8 char v8; v0 = 0; v8 = 0; // fails because of missing bank updating Reported by: M Bogdanowicz BUG 150: Leanslice bug Affected: 3.4 - 3.4B Fixed: 3.4C Type 2 tasks does not work for the new enhanced 14 bit core. #pragma taskOptions 2 Task task1( void) { .. } Workaround: 1. Use type 1 or type 3 tasks 2. Increment the task state for each type 2 task before calling the taskSlicer (not recommended). Reported by: A Fish BUG 149: Const data bug Affected: 3.1 - 3.4B Fixed: 3.4C Reading const data larger that 8 bit and storing indirectly using a pointer may fail. Only lower 8 bits are stored. uns16 *pDisBuf; const uns16 Segments[] = { 1000, 2000, .. }; char i; .. *pDisBuf = Segments[1]; // Wrong code generated pDisBuf[0] = Segments[i]; // Wrong code generated Reported by: W Mahringer BUG 148: Code generator bug Affected: 3.0H - 3.4A Fixed: 3.4B Multiplying or dividing a return value of 16 bit or larger is not correct when the function is second argument. uns16 u1, u2; uns16 read16( void); .. u1 = u2 * read16(); // Wrong code u1 = read16() * u2; // Correct u1 = u2 / read16(); // Wrong code u1 = u2 % read16(); // Wrong code Reported by: M Isler BUG 147: HEX file bug Affected: 3.4 Fixed: 3.4A The HEX file (INHX32) is not correct for data above word address 0x8000 (config, id and EEPROM data). The cure is to use version 3.4A. BUG 146: Bank update bug Affected: 3.4 Fixed: 3.4A Bank bit updating may fail for the Enhanced 14 bit core. The cure is to use version 3.4A. BUG 145: Code generator bug Affected: 3.2N - 3.3H Fixed: 3.4 Wrong code is generated for the following statement: int8 x, y; x = y >> 4; // wrong code for signed right shift by 4 BUG 144: Pointer bug Affected: 3.0 - 3.3G Fixed: 3.3H The compiler will sometimes not use correct bank for 8 bit pointers. This ONLY applies to pointers in structures. The following cases have been identified. Similar problems occurs when returning pointer addresses and for parameter transfer of pointer addresses. param.pout = &arm3; // point to element in bank 3 px = ¶m.pout->spal; // get address of sub-element e = *px; // wrong bank accessed px = ¶m.pout->ss.unt; // get address of sub-element e = *px; // wrong bank accessed px = ¶m.pout[0].pen; // get address of sub-element e = *px; // wrong bank accessed px = ¶m.pout[0].ss.unt; // get address of sub-element e = *px; // wrong bank accessed arm1.pen = &gva2; // point to element in bank 2 px = &arm1.pen[0]; // get address of sub-element e = *px; // wrong bank accessed param.ptt = &gva2; // point to element in bank 2 px = *param.ptt; // get address of sub-element e = *px; // wrong bank accessed Reported by: L Hedlund BUG 143: DW optimization bug Affected: 3.0E - 3.3G Fixed: 3.3H DW code words inserted are ignored for optimization replacing a sequence of skip and goto with a single skip instruction, causing wrong optimizations. if (bitA) { #asm DW 0x2054 DW 0x2008 #endasm W = 30; } Reported by: V Sulc BUG 142: Assignment of condition bug Affected: 3.0 - 3.3G Fixed: 3.3H Wrong code is generated for the following cases. char ch; ch = !PORTA; ch = !ch; ch = !W; Zero_ = !ch; W = Zero_; Carry = ch >= 5; Carry = ch < 5; ch = ch >= 5; ch = ch == 5; W = !W; Reported by: Z Mijanovic BUG 141: Bit multiplication bug Affected: 3.2N - 3.3D Fixed: 3.3E A bit variable can be index in a byte array. However, when using 16 bit elements or more, wrong code is generated for devices using the 12 bit core. This also applies to the following expressions: uns16 r, u16[2]; char aa; bit bx; r = u16[bx]; // wrong code for 12 bit core devices aa = 10 + bx * 2; // wrong code for 12 bit core devices Reported by: B Senser BUG 140: Pointer increment bug Affected: 3.2N - 3.3 Fixed: 3.3A Incrementing a pointer to a structure in a conditional statement generates wrong code. This also appllies to pointers to floating and fixed point variables. StructX *px; if (++px <= &ElmX[3]) .. // wrong pointer increment Reported by: L Hedlund BUG 139: Variable overlap bug Affected: 3.1D - 3.3 Fixed: 3.3A The bit offset of a bit variable overlapping a bit member in a structure will be wrong. struct { bit B1, B2; } St; bit bit2 @ St.B2; // wrong bit offset used Reported by: L Hedlund BUG 138: Optimization bug Affected: 3.1J - 3.3 Fixed: 3.3A The nop2() instruction is translated to a GOTO, and the optimization may fail when the nop2() is the first conditioal statement in a loop (or the first statement after a GOTO). for (;;) { for (a=1; a; a++) nop2(); } Reported by: S Daniel BUG 137: Const access bug Affected: 3.1H - 3.2R Fixed: 3.3 Accessing const data stored at the beginning (offset 0) in the const data table generated by the compiler is not correct in some special cases. The bug occurs when subtracting a constant that is type casted to 16 bit (or larger) or generated by the sizeof operator. const char verx[] = "Ver 1.0.000"; .. char i, x; x = verx[ i - sizeof(Ack)]; // BUG x = verx[ i - 1L]; // BUG x = verx[ i - (long)2]; // BUG Reported by: A Berndt BUG 136: Return value bug Affected: 3.0F - 3.2R Fixed: 3.3 The return value is not correct when returning the upper part of a variable, and when type casting to a type that is smaller than the variable itself. Also, when returning an expression containing a global (or static) variable first, the global variable will be modified. int24 glob24; int24 funkA(void) { int24 s24; return (long) s24.high16; // BUG, version 3.2N - 3.2R return s24.high16; // BUG return (int8) s24; // BUG return glob24 + 1; // BUG, glob24 modified return glob24 + s24; // BUG, glob24 modified } .. int16 n16 = funkA(); Reported by: G Delage BUG 135: Indirect access bug Affected: 3.0 - 3.2P Fixed: 3.2Q A function call in combination with indirect access is allowed in some cases. However, when the function called modifies the FSR register, the indirect access will be wrong. char i, *ps; i = fx() + *ps; // bug if function fx() modify FSR if (fx() != *ps) // bug if function fx() modify FSR .. Reported by: L Hedlund BUG 134: Local scope bug Affected: 1.1 - 3.2N Fixed: 3.2P The scope of a local variable defined inside an 'if' or 'else if' block is by mistake extended to the first symbol (token) after the block where it is defined. char bb; .. if (aa >= 3) { char bb; .. } bb += 1; // the wrong variable is incremented BUG 133: Fixed point bug Affected: 3.0H - 3.2N Fixed: 3.2P The sign bit is not extended correctly for operations using fixed point of different sizes, and when one operator is an integer. This gives wrong result for negative values. int8 i8; int16 i16; fixed24_8 x24_8; fixedU24_8 u24_8; fixed8_8 x8_8; x24_8 += i16; // wrong: sign of 'i16' is not extended u24_8 += i16; // wrong: sign of 'i16' is not extended x24_8 += i8; // wrong: sign of 'i8' is not extended u24_8 += i8; // wrong: sign of 'i8' is not extended x24_8 += x8_8; // wrong: sign of 'x8_8' is not extended u24_8 += x8_8; // wrong: sign of 'x8_8' is not extended BUG 132: Const parameter bug Affected: 3.0L - 3.2N Fixed: 3.2P Const data transferred by parameters are missing when the function is defined by a prototype without parameter names. void send(const char *); .. send( "abc"); Workaround: Use prototypes with parameter names: void send(const char *str); Reported by: P Spiltoir BUG 131: Operation using bit Affected: 3.2I - 3.2M Fixed: 3.2N The compiler generates wrong code for the following cases. The problem is that illegal instructions are generated which maps to a legal instructions and thus wrong code. Note that the W register is used as a temporary register and the wrong code can therefore appear in parameter transfers and complex statements as shown. bit bitX; char ss, uu; void func1( char px); W = 0x20 + bitX; // basic statement func1( 0x20 + bitX); // parameter transfer using W uu = ss & (10 + bitX); // complex statement using W W = 0x10 - bitX; W = W - bitX; W = uu - bitX; W = bitX + W; uu = bitX + W; uu = W - bitX; W = uu + bitX; Reported by: L Hedlund BUG 130: Bit comparing bug Affected: 3.2I - 3.2M Fixed: 3.2N Comparing 2 bits using the XOR operation is wrong for the following case. bit b1, b2; if (b1 ^ b2) // wrong code generated .. Reported by: D Crespo BUG 129: Pointer error after type cast Affected: 3.0L - 3.2M Fixed: 3.2N Using type cast when assigning a pointer to another pointer may prevent proper access of pointer data. The problem also applies when when passing a pointer argument or returning a pointer. The reason is that the compiler trace such assignments to deside if pointers access the same data. The problem applies to pointer accessing parts of the full address range (8 bit pointers and const pointers). const char *pa, *pb; pa = (const char*) (str+1); BUG 128: Returning a SFR Affected: 3.0H - 3.2M Fixed: 3.2N Returning a Special Function Register may cause this register to be read two times (before and after return). Some SFR's may change between the first and the second reading. The problem mainly applies to functions of return type 'int8' and equivalent types. int8 EE_read( uns8 addr) { EEADR = addr; RD = 1; return EEDATA; } void main(void) { int8 iv = EE_read(0); } Reported by: W Mahringer BUG 127: Bank bit updating problem Affected: 3.0L - 3.2J Fixed: 3.2K The compiler will insert 'const' data access functions in the beginning of each codepage. However, if bank bit updating is switched off by local #pragma statements surrounding the first function on a codepage, then bank bit updating is also switched off for the const access function on this codepage. This problem can be avoided by switching off bank bit updating inside the function or using another function in the beginning of the codepage. #pragma updateBank 0 void function1(void) // first function on a codepage { } #pragma updateBank 1 Reported by: T Satoh BUG 126: Integer to float inaccuracy Affected: 3.0H - 3.2I Fixed: 3.2J Converting integers to floating point numbers does not preserve the expected accuracy for large numbers. Least significant bits are truncated for the following cases. This also applies to negative numbers in the same range. //math32f.h: // Truncation for numbers above 16777215 or 0xFFFFFF // max error : 0.0015% int32 x = 0x010000FF; // decimal: 116777471 float32 f = x; // f is set to 16777216.0 : error 0.0015% //math24f.h: // Truncation for numbers above 65535 or 0xFFFF // max error : 0.39% int24 x = 0x0100FF; // decimal: 65791 float24 f = x; // f is set to 65536.0 : error 0.39% // no error when using 32 bit integers //math16f.h: // Truncation for numbers above 255 or 0xFF int16 x = 0x01FF; // decimal: 511 float16 f = x; // f is set to 1.0 : error is very large BUG 125: Float conversion rounding bug Affected: 3.0H - 3.2I Fixed: 3.2J Floating point numbers in the range 0.5 up to 1.0 (but not including 1.0) and same negative range are not rounded correctly when converted to integers. Rounding only applies when using FpRounding=1. float f = 0.5; int16 x = f; // not rounded to 1 when using FpRounding=1 Reported by: W Leupold BUG 124: Optimization bug Affected: 1.0 - 3.2H Fixed: 3.2I The compiler will remove an infinite loop if the preceeding instruction is a return. if (..) { .. return; } while (1) // infinite loop is removed ; .. Reported by: C Hermann BUG 123: Pointer address bug Affected: 3.1H - 3.2H Fixed: 3.2I The compiler may fail to use the right bank (MSB) for pointers to loations in bank 2 or higher. char *px8; uns16 test @ 0x1C5; // bank 3 px8 = (uns8*) &test + 1; // bug px8 = &test.high8 + 1; // bug *px8 = 0x12; // accessing bank 1 (wrong) Reported by: L Hedlund BUG 122: Pointer address bug Affected: 3.0 - 3.2H Fixed: 3.2I The compiler may fail to adjust the pointer address correct when using items larger than 8 bit. uns16 tab16[3]; char *p8; p8 = tab16 + 1; // bug p8 = &tab16[0] + 1; // ok Reported by: L Hedlund BUG 121: Struct member bug Affected: 3.0L - 3.2H Fixed: 3.2I The compiler fail to access 'const' struct members starting at a large offset (>=256). The problem is relatet to the start position of the member in the structure, and not to the size of the member. const struct { char mt1[150]; char mt2[150]; char mt3[100]; } jTAG = { .. }; char i; i = jTAG.mt3[i]; // fail Reported by: J Bodin BUG 120: Pointer bug Affected: 3.0L - 3.2H Fixed: 3.2I Using internal functions rl() and rr() on pointers may fail to use the right pointer size: size2 char *p2; p2 = rl(p2); // only a single RLF is generated Reported by: J Bodin BUG 119: Header file bug Affected: 3.0 - 3.2H Fixed: 3.2I The 12F683, 16F684 and 16F688 contain a CALIB word at address 0x2008. This is for factory preset only (no configuration word). Therefore the following line should be REMOVED in the header files for these devices (found at line 24). #pragma config_reg2 0x2008 Reported by: S Nagasue BUG 118: Header file bug Affected: 3.0 - 3.2H Fixed: 3.2I The following header file need to be updated. Otherwise the IRP bit is not updated by the compiler when reading or writing tables. IRP need to be set to 0 before accessing RAM in bank 1. Also, internal function clearRAM() will not clear RAM in bank 1 if IRP is 1. MODIFIED: #pragma chip PIC16F818, core 14, code 1024, ram 32 : 0xFF /1 /3 OLD: #pragma chip PIC16F818, core 14, code 1024, ram 32 : 0xFF /0 /3 FAILS ---^ BUG 117: RAM configuration problem Affected: 3.0 - 3.2H Fixed: 3.2I A special RAM configuration will not be interpreted correct for the stated compiler versions. The problem has been detected for header file 16F72.H and is related to the large mapped RAM section of this chip. No other header files cause the problem to appear. File 16F72.H should be modified as follows: MODIFIED: #pragma chip PIC16F72, core 14, code 2048, ram 32 : 0xFF /0 /3 OLD: #pragma chip PIC16F72, core 14, code 2048, ram 32 : 0xBF /0 /3 ^-- FAILS Reported by: T Schofield BUG 116: Optimization bug Affected: 2.1 - 3.2F Fixed: 3.2G When the last GOTO in a computed GOTO array is a goto to the next address, a bug will occur if the last GOTO is located on the next 256 word page. The compiler removes the last GOTO and the reduced table seem to fit into a single page. However, the real table still need code that allow page crossing. Reported by: L Hedlund BUG 115: Multitasking bug Affected: 3.0D - 3.2F Fixed: 3.2G Tasks of type 2 are automatically restarted when using "return;". They should be stopped (and restarted only on command). Reported by: L Hedlund BUG 114: Condition bug Affected: 3.0E - 3.2E Fixed: 3.2F The following condition is always false, but wrong code is generated. if (a & 0) // wrong code generated .. BUG 113: Pointer array bug Affected: 3.1B - 3.2E Fixed: 3.2F The compiler adjusts the pointer size dynamically according to the actual need. However, this does not work for indexed access of pointer in arrays. The problem also applies to const pointers. char *pt[3], *p; p = pt[i]; // fails if size is adjusted to non-default value Workaround: Use a fixed pointer size of pointer arrays: size2 char *pt[3]; Reported by: U Schmid BUG 112: Inline assembly bug Affected: 3.0 - 3.2E Fixed: 3.2F An empty comment (';') followed by a linefeed (LF=0xA=^J) without a carriage return (CR=0xD=^M) first cause the compiler to ignore the next line. This only happen in environments/ editors NOT using CR+LF between each line (Unix/Linux). #asm NOP ; empty comment on next line NOP ; NOP ; this line is ignored (when NOT using CR+LF between lines) #endasm Reported by: J Graeber BUG 111: Linefeed problem Affected: 1.0 - 3.2E Fixed: 3.2F Source code using a single linefeed (LF=0xA=^J) between each line are compiled without problems. However, the generated assembly file will use the single LF after a source code comment when the source code use a single LF. Other assembly lines will always use CR+LF (CR=0xD=^M). The problem is that MPASM may not handle single LF lines correct. Reported by: P Fonsny BUG 110: Pointer increment bug Affected: 3.0 - 3.2E Fixed: 3.2F Pointers are not incremented correct for the following cases: // Type cast ignored, always incremented by 5*sizeof(Test) FSR2 = ((uns8*)Test)+5; FSR2 = ((uns16*)Test)+5; FSR2 = ((float32*)Test)+5; FSR2 = ((StructureB*)Test)+5; // Function pointer argument always incremened by 5 Sub(Test + 5); Sub(((uns16*)Test)+5); Reported by: L Hedlund BUG 109: #pragma bug Affected: 3.2E Fixed: 3.2F Using "#pragma computedGoto 1" right after an "if" statement which has no "else" part may cause the bank bit updating to be wrong. if (..) { .. } #pragma computedGoto 1 skip(..); Workaround: The "#pragma computedGoto 1" is not needed because "skip()" have such functionality built in. The problem disappear by removing the #pragma statement. Reported by: J Souto BUG 108: Optimization bug Affected: 2.0 - 3.2E Fixed: 3.2F Optimization type 8 may cause wrong code in combination with Zero bit testing and RAM bank updating. The problem is that the MOVF instruction that updates the Zero bit is removed. This may typically happen in the beginning of a function when the RAM bank is updated before the Zero bit testing. bank1 uns8 tv; void fx(shrBank uns8 pm) { switch(pm) { // problem in some cases case 0: tv = pm; .. Reported by: L Hedlund BUG 107: Preprocessor bug Affected: 3.1H - 3.2 Fixed: 3.2A Macro stringification does not work for nested macros. The following example is not correct: #define str(s) #s #define xstr(s) str(s) #define foo 4 const char tmp[] = xstr(foo); // should be "4" but is "s" Reported by: B Shaver BUG 106: Pointer bug Affected: 3.0M - 3.2 Fixed: 3.2A Wrong code is generated when using the logical AND operation on the most significant bits in a 16 bit pointer. The following example code show the problem. The first 3 cases applies only to pointers to 8 bit elements. size2 char *px16; size2 uns16 *pg16; if (px16 & 0x800) xx = 10; if ((px16 & 0x600) == 0) xx = 10; if ((px16 & 0x300) >= 0x300) xx = 10; if ((pg16 & 0x300) >= 2) xx = 10; BUG 105: Pointer test bug Affected: 3.0M - 3.2 Fixed: 3.2A Testing high order bits of a 16 bit pointer may generate wrong code. size2 char *p2; if (p2 & 0x100) .. // wrong code generated if (!(p2 & 0x100)) .. // wrong code generated if ((p2 & 0x100) == 0) .. // wrong code generated if ((p2 & 0x100) != 0) .. // wrong code generated if ((p2 & 0x100) > 0) .. // wrong code generated BUG 104: Relocatable assembly bug Affected: 3.1D - 3.2 Fixed: 3.2A The compiler will use wrong table offset for indexed table access if the table is defined relative another object (table) using an offset. This only applies to relocatable assembly. char i, buffer[30]; char at[6] @ buffer[2]; at[i] = 0; // wrong offset used at[2] = 0; // correct Workaround: Use a struct that is located at offset 0. struct { char x[2]; char at[6]; // .. } ss @ buffer[0]; Reported by: G Thornley BUG 103: 'const' pointer bug Affected: 3.0L - 3.2 Fixed: 3.2A Returning a pointer to 'const' data may fail. The happen especially when the function returning the pointer is called before it is defined. Reported by: P Keanly BUG 102: Computed goto bug Affected: 1.1 - 3.2 Fixed: 3.2A When a function contains a computed goto with no banked access before the computed goto and banked access afterwards, then the bank updating may be wrong in some cases. This depends on the updating of the bank register before the function is called, and the "default bank" of the function defined by the compiler during bank bit updating. bank0 char a0, b0; void pro( shrBank char command) { skip(command); goto _A1; goto _T1; .. #pragma computedGoto 0 _A1: a0 += 1; return; _T1: a0 += b0; // bank bit updating could fail here return; .. Workaround: Insert a manual bank bit update before the skip() #if __CC5X__ <= 3200 /* bug fix version 3.2 and earlier */ #pragma updateBank 0 RP0 = 0; RP1 = 0; #pragma updateBank 1 #endif BUG 101: Pointer bug Affected: 3.0L - 3.1K Fixed: 3.2 Assigning an address to a 16 bit pointer will be wrong when an offset is subtracted from the index. size2 char *px; char i; px = &tab[i-2]; BUG 100: Call level bug Affected: 3.1K Fixed: 3.2 The compiler may fail to handle call level checking correct. This happen if there is a function that is called ONCE from main() and ONLY called from main(). The call level checking in functions called from this function will sometimes not be correct. Workaround: Insert the contents of the function directly in main or change the function into a macro. BUG 99: Relocatable assembly bug Affected: 3.0I - 3.1J Fixed: 3.1K The compiler will not update the bank bits after calling a function defined in another module if the following conditions are satisfied. This happen if the function get a wrong status early in the bank bit update algorithm (UNBANKED). Functions are marked UNBANKED if: 1. The function does not contain any banked access 2. The function does not contain any DW statements 3. The function calls are to other UNBANKED functions The problem is that undefined extern functions are also marked UNBANKED in this phase of the algorithm. Workaround: Insert a banked access or a DW statement: #if __CC5X__ < 3200 // CC5X version 3.1 and earlier #asm DW 0 // NOP #endasm #endif Reported by: G Thornley BUG 98: switch bug Affected: 3.1I - 3.1J Fixed: 3.1K Wrong code is generated for the following case: uns8 x; switch (x & 0xE0) // any constant above 0x7F { .. } // also for operators '|' and '^' Workaround: Cast the constant or the expression to 'uns8' switch (x & 0xE0U) switch (x & (uns8) 0xE0) switch ((uns8) (x & 0xE0)) Reported by: K Franke BUG 97: 'const' initialization bug Affected: 3.0M - 3.1J Fixed: 3.1K The compiler may fail to use the right pointer size when initializing const structures and arrays. This happens if the size of the pointer is different from the size of the data it points to. int24 x24; const struct { uns24 *p24; } hyper2[] = { &x24, // wrong size allocated }; BUG 96: Bit operation bug Affected: 3.0 - 3.1I Fixed: 3.1J Wrong code is generated for the following bit operations. This happen when the destination and arguments use the same variable. a.4 |= a.5; // wrong code a.4 &= a.5; // wrong code a.4 |= b.5; // correct a.4 &= b.5; // correct bit x, y; x |= y; // correct x &= y; // correct Reported by: O Kroth BUG 95: Header file bug Affected: 3.1F - 3.1I Fixed: 3.1J Bit LINTX in header file 16C432.h is located at the wrong position (bit 1 instead of correct position which is bit 2). The reason is that PDF document DS41140A from Microchip uses bit 1 (page 13), which is corrected to bit 2 in later document revision DS41140B. #pragma bit LINTX @ LININTF.2 // correct BUG 94: Optimization bug Affected: 3.0I - 3.1I Fixed: 3.1J The nop2() which is translated into a GOTO is removed when the next instruction is a GOTO. nop2(); // removed by mistake goto LABEL; // or a GOTO inserted by the compiler Reported by: K Tanaka BUG 93: List file bug Affected: 3.1G - 3.1I Fixed: 3.1J Data inserted using the DW statement in inline assembly is counted twice when generating the list, COD and assembly file. The addresses printed in the list file will be wrong. The problem also applies when the compiler generates DW statements for 'const' data. #asm DW 0x65 #endasm Reported by: J van Zee BUG 92: Relocatable assembly bug Affected: 3.0H - 3.1H Fixed: 3.1I Relocatable assembly addresses may be wrong in special cases. This happens when the compiler assume that the address is near a 256 byte boundary (offset 1, 0, -1). The compiler preallocates space for variables. However, it is MPLINK that do the actual allocation, and this may be different. The problem applies ONLY when generating relocatable assembly for use by MPASM and MPLINK. char i, *p; char tab1[32]; // assumed to be preallocated at address 32 char tab2[16]; // assumed to be preallocated at address 0xF0 p = &tab1[i-31]; // wrong code (assumed address 1) p = &tab1[i-32]; // wrong code (assumed address 0) p = &tab2[i-33]; // wrong code (assumed address -1) p = &tab2[i+15]; // wrong code (assumed address 0xFF) BUG 91: Relocatable assembly bug Affected: 3.0I - 3.1H Fixed: 3.1I The compiler may generate wrong relocatable assembly code when a RAM address is supplied as an argument to a function. There is no problem for the first argument. The problem applies ONLY when generating relocatable assembly for use by MPASM and MPLINK. char *buffer[5]; char i; cStr( "start", buffer); // wrong relocatable asm code cStr( "start", &buffer[i]); // wrong relocatable asm code Workaround: RAM address argument must be at the first place in the argument list. cStr( buffer, "start"); // correct code generated Reported by: T Schulz BUG 90: Code generator bug Affected: 3.0C - 3.1H Fixed: 3.1I Wrong code is generated for the following special case: char u8; bit bx; u8 = 10 - bx; // wrong code generated BUG 89: Optimization bug Affected: 1.1 - 3.1H Fixed: 3.1I Optimization (type 8) will fail when instruction CLRF have cleared a variable that previously have been loaded into the W register. char a, b, i; a += i; i = 0; b += i; // wrong code generated BUG 88: Floating point bug Affected: 3.1G Fixed: 3.1H Option -cu may cause constant evaluation to fail when at least one of the constants is a floating point constant. float a, b; a = 1 / 0.036; // wrong code when using option -cu a = b * (1.0 / 0.036); // wrong code when using option -cu BUG 87: Assembly file bug Affected: 3.0E - 3.1G Fixed: 3.1H A label that should be placed on a DW statement (inline asm) will be placed on the following instruction instead. The problem also applies to labels generated by the compiler (in case of loops, switch statements etc.). The problem applies to the assembly and list file. The hex file is correct. LABEL1: ; #asm DW 0xFFFF // LABEL1 should have been here in the asm file #endasm nop(); // LABEL1 is put on this statement in the asm file. BUG 86: Pointer bug Affected: 3.0 - 3.1G Fixed: 3.1H The compiler may fail to increment the pointer correctly when the object pointed to is larger than 1 byte. This problem applies to the following cases: int16 *p, *p2; // int16 or any object larger than 1 byte int16 tab[10]; char i; p2 = i + p; // wrong code p2 = 1 + p; // wrong code p2 = &p[1]; // ok p2 = &p[i]; // ok p = &tab[0] + 1; // wrong code p = 1 + &tab[0]; // wrong code p = &tab[0] + i; // wrong code p = i + &tab[0]; // wrong code p = &tab[1]; // ok p = &tab[i]; // ok Workaround: Avoid the stated syntax that cause wrong code. BUG 85: Bug in conditional statement Affected: 3.0 - 3.1G Fixed: 3.1H The compiler will generate wrong code for the following cases. int a; // any signed integer (8-32 bit), and fixed point do { // .. } while (a >= 0); // or a < 0, a > -1, a <= -1 if (a < 0 || a > 10) { // .. } Workaround: Add a dummy condition : ..} while (a >= 0 && 1); if ((a < 0 && 1) || a > 10) { .. Reported by: R Stein BUG 84: Pointer bug Affected: 3.0M - 3.1G Fixed: 3.1H The compiler will fail to set the most significant pointer byte for the following cases. bank0 char b0Buf[50]; bank3 char b3Buf[80]; void writeX(char *lbuf) { *lbuf += 1; } void main(void) { char bp = 5; writeX(&b3Buf[bp+2]); // wrong code writeX(&b3Buf[2+bp]); // wrong code writeX(&b3Buf[bp]); // correct code writeX(&b3Buf[bp]+2); // correct code writeX(b3Buf+bp); // correct code writeX(b3Buf+2+bp); // correct code writeX(b0Buf); // correct code } Workaround: Avoid the stated syntax that cause wrong code. Reported by: D Vonasek BUG 83: Pointer bug Affected: 3.1B - 3.1G Fixed: 3.1H The compiler will fail to set the IRP bit for the following cases. bank3 char b3Buf[80]; void write(char *buf) { buf[2] = 0; // wrong code, IRP set to 0 } void main(void) { char bp = 5; write( b3Buf + bp); // cause wrong code // write(&b3Buf[bp]); // enables correct code char *px = b3Buf + bp; // cause wrong code // px = &b3Buf[bp]; // enables correct code *px = 0; // wrong code, IRP set to 0 } Workaround: Avoid the stated syntax that cause wrong code. Reported by: D Vonasek BUG 82: Type conversion bug Affected: 3.0H - 3.1F Fixed: 3.1G The compiler may fail to use a signed operator (from a math library) when the expression contains two or more constants that need to be calculated first. This will not happen when using inline code. #include "math24.h" int24 m; m /= 600; // ok, signed division operator chosen m /= (800-200); // wrong, unsigned division operator chosen Workaround: m /= (int24) (800-200); Reported by: J Bodin BUG 81: Problem using DW Affected: 3.0E - 3.1F Fixed: 3.1G Inserting instructions using DW may fail in the following case. The compiler does not know what is inserted, but should assume that the data inserted in a function is instructions. func(); // wrong code, GOTO inserted #asm DW XXXX // some instruction, often GOTO fixed address #endasm //nop(); // dummy code at the end of the function removes the bug } Reported by: M Manhart BUG 80: Optimization bug Affected: 3.0 - 3.1F Fixed: 3.1G The compiler will ignore #pragma origin in the following special case, and optimize as if func() follow immediately on the next address after return. // .. else if (a.1) func(); } #pragma origin ADDR void func(void) { // .. } Workaround: Use #pragma optimize 3:0 before and #pragma optimize 3:1 after the conditional call. Reported by: J Mao BUG 79: Version file bug Affected: 3.1F Fixed: 3.1G Using option '-ver#version.h' is not recommended because of incomplete implementation which may make the compiler assume that multiple files are version files. More specific is the included files having same file name length as 'version.h' also threated as version files. Workaround: Use option '-ver' and: #pragma versionFile // next include is version file #include "verfile.c" // or BUG 78: Post-increment bug Affected: 3.0E - 3.1F Fixed: 3.1G The increment (and decrement) instruction will not be executed for the following expressions : return array[ offset++ ]; return *p--; Workaround: Use pre-increment, like (array[++offset-1]). Reported by: Ö Nilsson BUG 77: Type cast bug Affected: 3.0H - 3.1F Fixed: 3.1G Type casting a float constant or float constant expression to integer (signed or unsigned) fails. char a; float f; a = (char) (2.2 + 2.9); // wrong code is produced a = (int) 10.5; // wrong code is produced f = (int) 1.5; // wrong code is produced Workaround: Use the automatic type casting. BUG 76: Pointer bug Affected: 3.1 - 3.1E Fixed: 3.1F Reading 8 bit pointers stored in 'const' tables to a 16 bit pointer fails if signed data is pointed to, and bit 7 of the 8 bit pointer is 1 (i.e. address >= 128). const struct { size1 long *s; } ts[] = { &t, &y }; size2 const long *pl; pl = ts[i].s; // wrong code (attempt to extend "sign" bit) BUG 75: 'const' data bug Affected: 3.0L - 3.1F Fixed: 3.1G Reading 'const' data items larger than 8 bit may fail if the generated data array is above 256 bytes. The error occur when a data item greater than 8 bit cross a 256 byte boundary for the high and low byte parts. Workaround: Read high and low bytes separately when the table is large, or make sure that the data items are aligned. Third alternative is to use smaller tables and ensure that the compiler does not merge them into arrays larger than 256 byte. Reported by: L Hedlund BUG 74: Fixed point typecast bug Affected: 3.0H - 3.1F Fixed: 3.1G Wrong code is generated when performing an operation on two integers, and then assigning the result to a fixed point variable. The code is generated as if destination was an integer. uns8 h,l; fixedU24_8 a; a = h - l; // wrong code is generated (also for '+', etc.) Reported by: D Bakken BUG 73: Bug in complex math statement Affected: 3.0H - 3.1F Fixed: 3.1G When using MATH LIBRARY functions, the compiler may generate code for some complex statements that are not supported. However, there are no error about the wrong code. Typically, such code will include at least two library calls and an inline operation in between these. The code will be wrong only if the inline operation is performed on the second operator (the second parameter of the library call) of the second library call. int16 wi, r; int8 E, PP; wi *= E * PP - r; // wrong code produced Reported by: R Sykora BUG 72: Sign extension bug in math call Affected: 3.0H - 3.1F Fixed: 3.1G When using MATH LIBRARY functions, sign extension may not be fully correct in some special cases. This ONLY occurs when the sign should NOT be extended to the full length of the parameter of the math function called. In most cases this difference will be of theoretical interest only. Example: #include "math24.h" .. uns8 a8, b8; int8 cs8; a8 = cs8 / b8; /* wrong code, routine _divS16_8 is used, and the sign of cs8 is extended to 16 bit. This is only a problem for negative numbers */ BUG 71: Fixed point conversion bug Affected: 3.0H - 3.1E Fixed: 3.1F Wrong code is generated when adding an integer variable to a fixed point constant. Examples: fixed8_8 mpx; int8 a8; mpx = (fixed8_8)a8 + 100.1; // wrong code mpx = a8 + 100.1; // wrong code mpx = 100.50 - a8; // wrong code BUG 70: Return constant bug Affected: 3.0H - 3.1E Fixed: 3.1F When returning 16 bits (or larger) constants, wrong code may be generated with a fairly low probability. This is caused by an incomplete condition in the compiler. There is no problem when returning variables (only for constants). Reported by: A Staufner BUG 69: Relocatable assembly problem Affected: 3.0L - 3.1E Fixed: 3.1F When defining a 'const' table, this table is unfortunately declared by a RES statement in the generated assembly file, which means that RAM space is wasted. const char tab[] = { 0, 1, 2 }; Workaround: Define and access const data in an assembly module. BUG 68: Const table bug Affected: 3.0L - 3.1E Fixed: 3.1F Reading fixed or floating point values from const tables may fail if the type does not match exactly (except for signed/ unsigned differences which cause no problems). fixed24_8 fx24_8; const uns16 u16t[] = { 0, 10000, 300 }; fx24_8 = u16t[2]; // wrong code is produced Workaround: Store the fixed point value in a temporary location that match the type of the const table, and then assign it to the variable with a different type. Reported by: J Bodin BUG 67: Pointer size bug Affected: 3.0M - 3.1D Fixed: 3.1E When a 16 bits pointer is returned from a function, CC5X may fail to decide that the return value should be assigned to a 16 bit pointer. This also applies if an 8 bit address that access upper memory is returned. The problem is that the assignment of return values is not traced properly, and thus the pointer size and class may be wrong. Workaround: The size2 type modifier may be needed on pointers that is assigned return values from functions. BUG 66: extern pointer problems and bugs Affected: 3.0M - 3.1D Fixed: 3.1E CC5X may fail to decide that an extern pointer should be 16 bit (and not 8 bit), and may fail to print error messages when 8 bit extern pointers are used inconsistently between different modules. This is because pointer assignment information is not exchanged between modules. This information is used to decide the pointer size, but the size is decided according to the information available in the current module. It also means that an extern pointer may be 8 bit in one module and 16 bit in another module. This may cause another variable to be overwritten if the pointer decided to be 8 bit when allocated but updated as a 16 bit pointer in a different module. Workaround: Use the size2 type modifier on all extern pointers, or carefully inspect all usage of 8 bit extern pointers. BUG 65: Relocatable assembly and const Affected: 3.0M - 3.1D Fixed: 3.1E It is not possible to access const data from another module because of a linker restriction. This only applies when using option -r to generate relocatable assembly. Unfortunately there are no error when using extern on a const table: extern const char *tab; // no error on 'extern const' Reported by: R Sykora BUG 64: Relocatable assembly file problem Affected: 3.0I - 3.1D Fixed: 3.1E The compiler may put extra instructions in the assembly (and list) file when generating relocatable assembly (option -r) AND changing codepage (page section). This will only occur when more than 20000 bytes of code have been generated when the page change is performed. The extra instructions/code will often be detected by MPASM because the first line of the extra instruction will be random and labels are duplicated. The reason for this problem is that a call to strlen is done when the terminating '\0' is missing in the internal assembly buffer. This will reinsert previous genereated assembly lines. Reported by: D Shu, R Sykora BUG 63: Const data bug Affected: 3.0L - 3.1D Fixed: 3.1E The compiler may fail to decide the proper pointer size when all strings assigned to the const pointer are merged with identical other strings. This seems to be a problem only when the pointer should have been 16 bit. The compiler will warn that "constant is truncated". This simply means that a 16 bit address is assigned a 8 bit pointer (which will not work). Temporary workaround: a) Use command line option -mc2 which sets the default const pointer size to 16 bit. The compiler will still use 8 bit if possible. b) or add a size modifier if the above warning is detected, i.e.: const size2 char *pt; Reported by: D Kay BUG 62: Minor relocatable address problems Affected: 3.0K - 3.1C Fixed: 3.1D The generated code on address operations may be wrong when using relocatable assembly (option -r) for the following case: IRP = &tab1[1] / 256; // correct code W += 50; // wrong, ADDLW LOW(tab1+16) is generated The above problem only apples when trying to manually update IRP or another variable with the MSB (bit 9) of an address. The ADDLW instruction have to follow 2-4 instructions after the above address operation. The problem only apply to the ADDLW instruction in combination with the -r option. Some meaningless address operations also produce wrong code: FSR = &tab1[1] / 16; // wrong code, but meaningless anyway FSR = &tab1[1] % 3; // wrong code, but meaningless anyway FSR = &tab1[1] * 2; // wrong code, but meaningless anyway The problems are shown for table addresses, but applies to address of single variables and structure members also. BUG 61: Problems using extern variables Affected: 3.0K - 3.1C Fixed: 3.1D Missing or wrong code is generated when using more than one extern variables in an expression. This is because extern variables are assigned the same undefined address, and the compiler think they overlap. This problem only occur when using the -r command line option. The EXTERN definition in the assembly file may also be missing. extern char a, b; a = b; // code is missing Reported by: R Sykora BUG 60: Table of const pointers is wrong Affected: 3.0L - 3.1C Fixed: 3.1D When declaring a table of const pointers, the pointers will reside in RAM. It is the data pointed to that may reside in program memory. However, the pointers are accessed as if they reside in program memory. This bug may not be serious, because it is not possible to write to the pointers in the array, and therefore the syntax is unusable for the stated versions. const char *prt[3], *pr; pr = prt[0]; // wrong code is generated prt[1] = "Str"; // error message, but valid C syntax BUG 59: Preincrement code bug Affected: 3.0E - 3.1C Fixed: 3.1D When incrementing or decrementing a signed integer in a conditional statement or a loop condition, the code is generated as if the variable was unsigned: int8 a; if (--a > 0) // wrong code (correct only if 'a' is unsigned) .. Temporary workaround: Do the increment/decrement of a signed integer outside a conditional statement or a loop condition. Reported by: R Sykora BUG 58: Bank updating bug Affected: 3.0H - 3.1C Fixed: 3.1D When using libraries functions, ram bank updating may be wrong in the function (A) following a deleted library function. The condition for this to occur is that the function (A) have a label at the first instruction. Math libraries and application code following '#pragma library 1' may all contain deleted functions. Temporary workaround: Insert nop(); in the beginning of functions following a deleted library function if this function have a label at the first instruction (not the function label). This is detected by inspecting the assembly file: ;#pragma library 1 .. _remS16_16 --> LABEL of deleted function .. ;void vsub(void) vsub --> LABEL of following function ; m001 DECF pm,1 --> THIS LABEL IS CRITICAL! Reported by: R Sykora BUG 57: Wrong documentation Affected: 3.0B - 3.1C Fixed: 3.1D File 'startup.txt', line 70, contains a wrong code for the startup sequence on 12C50X/12CE51X/16C505 windowed devices. The correct one is: #define _MOVLW 0xC00 // not 0x3000 Reported by: R Stout BUG 56: Floating point memory allocation bug Affected: 3.1 - 3.1C Fixed: 3.1D Defining local bit variables in functions that also contain floating point math operations may cause the memory allocation algoritm to fail when allocating local space for the math routines. This only applies to math library routines using the 'sharedM' type modifier. The temporary cure is to avoid defining local bit variables in functions that use floating point math. Bit variables that overlap with other variables does not cause any trouble: bit bx @ lcha.7; Reported by: G Joachim BUG 55: Relocatable assembly bug Affected: 3.0I - 3.1C Fixed: 3.1D This problem applies to local memory allocation when using relocatable assembly (option -r). Local memory is allocated in separate blocks for each ram bank and separate for each call tree. When such a block contains 1-7 bits at the end of the block, wrong code can be generated in some cases, for example bit toggle. This problem is expected to occur very infrequent. The temporary cure is to avoid using bit variables in functions where local variables are located at the deepest stack level. BUG 54: Problem with pointers in const struct Affected: 3.0M - 3.1C Fixed: 3.1D Pointer members in a 'const struct' will not automatically be 'const' pointers. This is wrongly assumed for the stated compiler versions. A pointer in a struct that need to access const data must have the const type modifier, even if the whole struct is const data. BUG 53: Table of long pointers is wrong Affected: 3.0M - 3.1C Fixed: 3.1D Wrong code is generated when accessing a table of long pointers. The index is generated as if the table contained short (8 bit) pointers. This also applies when the long pointer table is inside a struct. long size2 *plt3[3]; long size2 *p6; char i; p6 = plt3[2]; // wrong code p6 = plt3[i]; // wrong code The temporary cure is to NOT use a table of long pointers. BUG 52: Relocatable assembly bug Affected: 3.0I - 3.1C Fixed: 3.1D This problem applies to local memory allocation when using relocatable assembly (option -r). Local memory is allocated in separate blocks for each ram bank and separate for each call tree. When such a block contains less than 8 bits, this block is not properly allocated when using the -r option. The bits are allocated separately and globally without using RES in a UDATA segment. The temporary cure is to add a local char variable or use global bits. BUG 51: Floating point memory allocation bug Affected: 3.0H - 3.1C Fixed: 3.1D Local memory allocation for the floating point library is not always correct when using float-to-int or int-to-float conversion. This problem will make ALL floating point operations fail if it occur. The typical situation is when using the mentioned conversion routines at a deeper call level than any other floating point math operation: The cure is to download new math routines: http://www.bknd.com/files/math32f.h http://www.bknd.com/files/math24f.h http://www.bknd.com/files/math16f.h Reported by: R Matthiesen BUG 50: Pointer table access bug Affected: 3.0M - 3.1C Fixed: 3.1D When accessing an element in a table of pointers, the index will be wrong if the pointer size is different from the default pointer size (which is normally 1, or optionally 2 by using a command line option). This bug also applies to 'const' tables of pointers stored in program memory. struct { size2 char *pt2[5]; char x; } pt; size2 char *xt[5]; size1 char *zt[5]; .. pt.pt2[3] = 0; // wrong code if default pointer size is 1 xt[i] = 0; // wrong code if default pointer size is 1 zt[2] = 0; // wrong code if default pointer size is 2 BUG 49: Missing call level error Affected: 3.0I - 3.1C Fixed: 3.1D Call level error message is missing for functions that are called indirectly from main() and from the interrupt service routine. Workaround: When using functions that are called from more than one call tree, the call level have to be checked manually. This is easiest done by using the -Q command line option, and inspecting the call trees in the last part of the generated *.fcs file. Reported by: D Shu BUG 48: Wrong position for unused label Affected:: 3.0 - 3.1C Fixed: 3.1D The compiler may generate an unused label that is not updated and thus may change position when the compiler insert code for RAM bank updating. This happen if the main() function contains a 'while (1)' statement, and this in the LAST compound statement in main() and there is no functions behind main(). This unused label may cause error messages or disturb optimization locally. The temporary workaround is to use a: nop(); behind the compound while(1) { } statement at the very end of the program. Any statement or alternatively a (dummy) function at the end of the program will do the job. Reported by: F Vereb BUG 47: Floating point bug Affected: 3.0H - 3.1C Fixed: 3.1D Wrong code is generated for the following statements: float fx, fy; fx = 256.0 * fx; // wrong code fx = 2.0 * fy; // wrong code The problem also applies when using 4.0, 8.0, 16.0, 32.0, etc. The bug can be avoided by some minor rewriting: fx = 256 * fx; // correct fx = 2 * fy; // correct fx = fx * 256.0; // correct fx = fy * 2.0; // correct Reported by: Igor BUG 46: Local variable bug Affected: 1.1 - 3.1B Fixed: 3.1C The do-while scope is not ended correctly, which means that the wrong variable is decremented in the following example. char ix = 10; do { uns16 ix = 1; //.. } while (--ix); BUG 45: Const data bug Affected: 3.1 - 3.1B Fixed: 3.1C Reading greater than 8 bit constant data from a table containing more than 256 byte data will not work. Note that the table is generated by the compiler which merges data to get compact code. uns16 data; data = table[i]; // wrong code if more than 256 byte in table Reported by: D Kay BUG 44: Fixed point bug Affected: 3.0H - 3.1B Fixed: 3.1C Wrong code is generated when comparing a fixed point variable to an constant (integer or float). The bug depends on the previous assignment statement, and is not always present. The bug applies to all comparison operators ( == , != , < , <= , > , >= ). fixed16_8 fx; if (fx < 10000) .. // wrong code if (fx < 10000.0) .. // wrong code Reported by: D Kay BUG 43: Const data bug Affected: 3.1 - 3.1B Fixed: 3.1C When using constant data on a device allowing program memory to be read, the compiler will compress the data into 2*7 or 14 bits if possible and if this saves code. However, the instruction sequence accessing the data is not correct. Temporary workaround (see const.txt): #pragma wideConstData 8192 // never compress const data Reported by: A Preston BUG 42: Floating point bug Affected: 3.0H - 3.1B Fixed: 3.1C The following statements: fx = -fx; // 16, 24 or 32 bits floating point variable fx = -fz; is implemented by an inline code sequence which inverts the sign bit. Unfortunately the wrong bit is inverted. Temporary workaround: fd.23 = !fd.23; // fd = -fd; /* 32 bits float */ ff.15 = !ff.15; // ff = -ff; /* 24 bits float */ fs.7 = !fs.7; // fs = -fs; /* 16 bits float */ Reported by: W Peterson BUG 41: ID-location bug Affected: 3.0 - 3.1B Fixed: 3.1C The ID location address is wrong on the 12C508, 12C508A, 12C509, 12C509A, 12CE518, 12CE519. #pragma config ID=0x1234 // wrong address on above devices Temporary workaround: #pragma cdata[0x200] = 0x1, 0x2, 0x3, 0x4 // 12C508, etc #pragma cdata[0x400] = 0x1, 0x2, 0x3, 0x4 // 12C509, etc Reported by: B Madsen BUG 40: Header file bug Affected: 3.0B - 3.1A Fixed: 3.1B One of the header file bit address is not correct for 16F627 and 16F628. #pragma bit RD @ 0x9C.0 // not 0x98.0 #pragma bit WR @ 0x9C.1 // not 0x98.1 #pragma bit WREN @ 0x9C.2 // not 0x98.2 #pragma bit WRERR @ 0x9C.3 // not 0x98.3 Reported by: P Fonsny BUG 39: Struct pointer bug Affected: 3.0 - 3.1A Fixed: 3.1B Loading a struct pointer with an address plus increment is not always correct. struct a { char a; char b; } sa[5], *pa; pa = &sa[0] + i; // wrong code (correct if sizeof(struct a) == 1) pa = &sa[0] + 3; // wrong code (correct if sizeof(struct a) == 1) pa = &sa[1]; // ok pa += 1; // ok, pa is incremented by sizeof(struct a) pa = pa + 1; // does not compile (internal limitation) Reported by: D Bakken BUG 38: Switch bug Affected: 3.0I - 3.1A Fixed: 3.1B A switch statement with no default label and with an immediate end of function after the switch statment will have a faulty default label. void func( char a) { switch (a) { case 0: break; case 1: /.. //.. } /* The default label should have been inserted here, but is instead found at the start of the next function */ } Reported by: P Lalov BUG 37: Floating point comparison bug Affected: 3.0H - 3.1A Fixed: 3.1B Comparing a floating point variable with 0.0 does not work correct for the following cases: if (a >= 0.0) .. // wrong code if (a <= 0.0) .. // wrong code if (a >= 0.0 && ..) .. // wrong code if (a <= 0.0 && ..) .. // wrong code if (a > 0.0 || ..) .. // wrong code if (a < 0.0 || ..) .. // wrong code BUG 36: Floating point comparison bug Affected: 3.0H - 3.1A Fixed: 3.1B The operator '||' will not work when comparing with a floating point constant using operations '<', '<=', '>=' and '>': if ( a > 9.9 || ..) // wrong code Comparing with a floating point constant is handled by inline code, and the implementation did not work with the '||' operator. Reported by: M Schulz BUG 35: Inverting the Carry bit is wrong Affected: 3.0H - 3.1A Fixed: 3.1B Carry = !Carry; // wrong code generated // MOVLW 1 // EORWF STATUS,1 ; Carry,DC,Zero_ are not written The reason for the problem is that Carry, DC and Zero_ are not written when the instruction update one or more of the bits Carry, DC or Zero_. Inverting Zero and DC will not work either. It can be noted that the instruction MOVWF STATUS will write all STATUS bits. NOTE: Operations '<' and '>' in the floating point math libraries 'math32f.h', 'math24f.h' and 'math16f.h' will not work because of this bug. Reported by: I Morrison BUG 34: Wrong negative floating constant Affected: 3.0M - 3.1 Fixed: 3.1A Reading of floating point constants starting with '-.' is not correct (the negative sign is ignored): -.000234 : read as .000245 (wrong) .000234 : correct Reported by: G Joachim BUG 33: Missing code and missing error Affected: 3.0C - 3.1 Fixed: 3.1A Expressions with multiple indexes (or pointers) are not supported by CC5X. However, it is possible to use the same element more than once. The following expression was not detected correctly (incomplete code was generated): char tabA[5], tabB[5]; tabA[i] = tabB[i]; // faulty code and no error tabA[i] = (tabA[i]+1) & 0xF; // correct code Reported by: P Scargill BUG 32: Bank bit updating bug Affected: 3.0C - 3.0P Fixed: 3.1 Bank bit updating fails when using the -bu option or the free edition for the following code: bit1 = bit2 ^ bit3; #asm BTFSS 0x23,bit3 La1 BSF 0x23,bit1 #endasm Reported by: J Quenton BUG 31: Option error Affected: 2.1 - 3.0H Fixed: 3.0I The command line option -p16C73A is handled as -p16C73 by mistake. This also applies to other devices having a letter at the end. The same problem occur when using: #pragma chip PIC16C73A BUG 30: Local variabel allocation bug Affected: 3.0 - 3.0N Fixed: 3.0O Allocation of local variables may fail when using 16 bit or greater local variables or parameters. This will only happen in special cases. The problem is that the addresses will overlap in a wrong way. Reported by: M Koenig BUG 29: Code generation bug Affected: 3.0E - 3.0H Fixed: 3.0I switch (*b++) { case 6: a = 0; // 'a' is incremented instead of 'b' } Incrementing a pointer in a switch statement is handled wrong. Reported by: S Filippopoulos BUG 28: RAM bank updating bug Affected: 2.0 - 3.0H Fixed: 3.0I In some very special cases the RAM bank selection bits may not be correctly updated in the beginning of a function. BUG 27: Assembly file inconsistency Affected: 3.0 - 3.0H Fixed: 3.0I Static variable names inside a function are not renamed in the assembly file when the same static variable name is used more than once. They should have been renamed the same way as local variable names are renamed. However, the hex file is correct. The problem is detected when the generated assembly file is put through an assembler. Reported by: D Lin BUG 26: Multitasking bug Affected: 3.0D - 3.0H Fixed: 3.0I Tasks of type 2 are automatically restarted when they terminate. They should be stopped and restarted only on command. BUG 25: Minor optimization problem Affected: 2.0 - 3.0H Fixed: 3.0I When switching optimization from off to on, the compiler may remove a superfluous GOTO close to the region where optimization is on. The problem also applies for inline assembly. This is assumed to be a problem only when GOTO's are used for generating timing delays (instead of 2*nop()). #pragma optimize 0 .. goto NEXT; // this is removed by mistake NEXT: #pragma optimize 1 #asm .. GOTO NXT ; this is removed by mistake NXT #endasm Reported by: J Bodin BUG 24: Optimization bug Affected: 1.0 - 3.0E Fixed: 3.0F Optimization of infinite empty loops can fail in very special situations. Example code: void err( void) { while(1) {} } /* REQUIRED */ char c; void main(void) { if ( c != 21) { while (1) { } /* REQUIRED */ } while(1) {} /* REQUIRED */ } Reported by: E James BUG 23: Local variable allocation bug Affected: 3.0C - 3.0F Fixed: 3.0G Local variables and parameters in functions of type bit are not allocated. The address is truncated and handled as if the function was not called at all. bit fx( char p) // 'p' is not allocated { char i; // 'i' is not allocated .. } BUG 22: Inline assembly bug Affected: 3.0 - 3.0F Fixed: 3.0G Calling C functions using inline assembly may not work when the called function contains local variables. The problem is that the local variables are not allocated correctly or not allocated at all. This also applies if the called function calls other functions having parameters or local functions. Temporary fix: End inline assembly mode, call the function using C syntax, restart inline assembly mode again. Reported by: C Schillinger BUG 21: Type cast bug Affected: 3.0 - 3.0E Fixed: 3.0F Extending the sign partially is not handled correct for assignment. int8 i; uns32 a = (uns24) i; // wrong code: sign extended to 32 bit BUG 20: Sign extension bug Affected: 3.0 - 3.0E Fixed: 3.0F Negative sign is not extended when assigning arguements to parameters at function call. void func( int16 a); .. int8 b; func( b); // wrong code: neg. sign not extended to 16 bit BUG 19: Increment/decrement bug Affected: 3.0 - 3.0D Fixed: 3.0E Wrong code is generated when incrementing or decrementing a pointer element in a structure. *st.elm++; // equivalent to *(st.elm++), not (*st.elm)++ *st.elm--; // equivalent to *(st.elm--) BUG 18: Structure bug Affected: 3.0 - 3.0D Fixed: 3.0E Wrong code is generated when a whole structure is used as an argument. struct { .. } aa, bb; aa += 1; // illegal code aa = bb; // wrong code BUG 17: Increment/decrement bug Affected: 3.0 - 3.0D Fixed: 3.0E Wrong code is generated when incrementing/decrementing parts of a variable/table in a condition: if (--var.low8) .. // wrong code if (--tab[3]) .. // wrong code BUG 16: Preceedence bug Affected: 3.0 - 3.0D Fixed: 3.0E The if statement if (i == '='|0x80) // is equivalent to ((i == '=')|0x80) which have no meaning. There should have been a warning/error, but code was generated according to the following statement: if (i == ('='|0x80)) which is not equivalent to above condition. BUG 15: Illegal syntax Affected: 3.0 - 3.0D Fixed: 3.0E Illegal syntax combinations for bit access was allowed. a = *p.7; // not valid a = &p.1; // not valid BUG 14: Pointer bug Affected: 3.0 - 3.0D Fixed: 3.0E Arrays of pointers to structures are not handled correct. Error messages are printed in most cases, but wrong code can be generated for: c = tab[0]->elm; BUG 13: Typecasting bugs Affected: 3.0 - 3.0D Fixed: 3.0E Wrong code is generated in some very special situations. First, the second arguement and the destination have to be the same. The second arguement also have to be typecasted to a smaller size. The problems occur only for addition and subtraction as shown. uns16 a16,b16; a16 = b16 + (int8)a16; a16 = b16 - (int8)a16; a16 = (uns16)fx() - (uns8)a16; uns24 a24 = (uns24)fx() - (uns16)a24; BUG 12: Multitasking bug Affected: 3.0D Fixed: 3.0E The preliminary multitasking feature is not able to handle local variables on this version. BUG 11: Inline assembler bug Affected: 3.0 - 3.0D Fixed: 3.0E if (a==2) { nop(); nop(); } #asm incf a,F #endasm Inline assembly statements following an 'if' block was included in the if block by mistake. } ; // temporary fix to this problem. #asm In general, note that inline assembly are NOT interpreted as C statements, and are invisible to the C syntax. Reported by: E James BUG 10: Code generator bug Affected: 3.0C Fixed: 3.0D During upgrading indirect access (*p = swap(*p);), a new bug was inserted for some table accesses in version 3.0C. Incorrect expressions typically involves reading and writing the same element, for instance: tab[10] |= 3; tab[i] += s; tab[2] = tab[2] - 5; BUG 9: Type cast bug Affected: 3.0 - 3.0C Fixed: 3.0D Some complex expressions involving a function call or three arguments or more are not always correctly handled if the result should be more than 8 bit. uns16 a16; uns8 b, t; a16 = (uns16) sub() + 100; // wrong result a16 = (uns16) b - sub(); // wrong result a16 = (b|3) + (uns16) t; // wrong result a16 = (uns16) (b & 0x7F) + t; // wrong result BUG 8: Code generator bug Affected: 3.0 - 3.0B Fixed: 3.0C bit var_2 @ var.2; Bit offset is 0 for all bits defined by the above syntax. BUG 7: Code generator bug Affected: 3.0 - 3.0B Fixed: 3.0C btss(var.2); // wrong code, accessing var.0 btsc(var.3); // wrong code, accessing var.0 Occurs when using btss/btsc to access a bit in variable. Reported by: J Souto BUG 6: Missing type checking Affected: 3.0 - 3.0B Fixed: 3.0C switch(varX) { .. Variables greater than 8 bit is truncated to 8 bit in the switch statement. BUG 5: Missing type checking Affected: 3.0 - 3.0B Fixed: 3.0C varX=func1(); // assumes that 'varX' is 8 bit Wrong code is generated when assigning a return value if varX is different from 8 bit, that is: bit, long, etc. Wrong code is also generated if varX is a hidden register on the 12 bits core (OPTION,TRISA,..). This applies both when func() is a user defined function or an internal function (swap(),rl(),rr()). Reported by: P Scargill BUG 4: Code generator bug Affected: 3.0 - 3.0B Fixed: 3.0C temp=temp+FSR-2; // wrong code generated Occurs when an addition is followed by a subtract constant. No bug when writing: temp+=FSR-2; Reported by: A Widgren BUG 3: Inline assembler bug Affected: 3.0 - 3.0B Fixed: 3.0C Instructions valid for the 14 bit core was accepted for the 12 bits core by mistake. ADDLW 100 // 14 bit core only RETFIE // 14 bit core only RETURN // 14 bit core only SUBLW 100 // 14 bit core only BUG 2: Inline assembler bug Affected: 3.0 - 3.0A Fixed: 3.0B bsf vx+1,7 // wrong code Accessing a bit in a structure or array was translated into wrong code when offset > 0 and bit > 0. Reported by: J Souto BUG 1: Code generation bug Affected: 3.0 Fixed: 3.0A W = rr( e.x); // wrong code (missing offset) l.high8 = rr( l.high8); // wrong code (missing offset) tx[2] = swap( tx[2]); // wrong code (missing offset) The offset in structures, unions, arrays and long variables is missing for the internal functions rl(), rr() and swap(). Reported by: J Souto