CC8E BUGS --------- 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. CC8E version 1.0 was released 27th February 2002. Last updated: 23. September 2024 BUG 136: Code generator bug Affected: 1.8A - 1.8B Fixed: 1.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 135: Code generator bug Affected: 1.0 - 1.8A Fixed: 1.8B Wrong code is generated for some cases when calculating the address in a table of elements larger than 8 bits. The problem only occur when the index is multiplyed with a constant. uns8 ger; uns16 tabX[10]; uns16 *pm, x16; pm = tabX + ger*2; // wrong code generated pm = &tabX[ger*2]; // wrong code generated pm = &tabX[2*ger]; // ok x16 = tabX[ger*2]; // ok Reported by: H Saathoff BUG 134: Code generator bug Affected: 1.0 - 1.8 Fixed: 1.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 133: C parsing bug Affected: 1.0F - 1.8 Fixed: 1.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 132: Interrupt vector table bug Affected: 1.7 Fixed: 1.8 It is possible to define an interrupt prototype function when the interrupt function is located after the interrupt vector table. However, if the interrupt function defined by the interrupt prototype is missing then there should have been an error message but this is missing for stated version. BUG 131: Instruction encoding bug Affected: 1.7 Fixed: 1.8 The binary encoding of the access bank for the MOVFF/MOVFFL instructions are wrong for the enhanced 18 devices using SFR registers at low addresses and RAM with an offset. This applies to the HEX, LST and COF/COD files. It is possible to use MPASMX to generate a correct HEX file using the generated ASM file. Reported by: S Nagasue BUG 130: Code generator bug Affected: 1.0 - 1.6G Fixed: 1.7 It is possible to write improper code for SFR registers. In these cases the SFR register is used as a temporary register during the calculation. This may lead to undesired side effects. PORTD = (data & 0x0F) << shift; PORTC = (data | 0x5) - vx; BUG 129: Missing computed goto errors Affected: 1.6 - 1.6G Fixed: 1.7 Error messages for certain computed goto error situations are missing. This applies to skipL() when the table contain single or triple word instructions, and to skip() when the table contain double or triple word instructions. BUG 128: RAM allocation bug Affected: 1.6 - 1.6G Fixed: 1.7 Allocating variables in bank 31 for the enhanced 18 bit devices will fail. These variables are mapped to the access bank. The problem applies to both local and global variables. bank31 char vb31; // BUG: mapped to the access bank The workaround is to assign variables to fixed addresses in bank 31: char vb31 @ 0x1F00; BUG 127: Code generator bug Affected: 1.0 - 1.6F Fixed: 1.6G Accessing a large table using offset between 128 and 256 may result in wrong code or a strange error. 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 126: Code generator bug Affected: 1.6 - 1.6F Fixed: 1.6G The compiler will not generate MOVFFL when optimization is turned off using option -u. The problem applies to the enhanced PIC18 devices only. Workaround: If optimization needs to be turned off, use #pragma optimize 0 BUG 125: Code generator bug Affected: 1.2B - 1.6F Fixed: 1.6G Wrong code is generated for the following expressions. uns8 x; x = (x > get_val()); // Wrong code, also for >=, <, <= Reported by: P Trnak BUG 124: Pointer bug Affected: 1.3 - 1.6E Fixed: 1.6F Using an 8 bits pointer in combination with a 16 bit index may access data in the wrong bank. The workaround is to use an 8 bit index when using 8 bit pointers. #define AS 12 uns16 adata[AS] @ 0x0230; // located in bank 2 uns16 *p_adata; uns16 ix16; p_adata = adata; p_adata[ix16] = 55; // wrong bank accessed Reported by: S Nagasue BUG 123: Bank bit update bug Affected: 1.6 - 1.6 Fixed: 1.6A This problem applies only to the enhanced core 18 devices with more than 16 RAM banks (> 4k RAM/SFR space). Swithing a multiple of 16 RAM banks up or down will result in a missing bank update instruction. bank5 uns8 a5 = 0; bank21 uns8 a21 = 0; // missing bank bit update a5 += 1; // missing bank bit update BUG 122: Undesired code generated Affected: 1.0 - 1.5 Fixed: 1.6 Many special function registers (SFR's) requires special code sequences for certain accesses. Unfortunately the compiler will not generate this code for some operations. For the following operation the problem applies to SFR's that does not reside in the access bank: if (RXB1CON == 0) .. // including != 0, > 0, >= 1, < 1 The compiler will generate MOVF RXB1CON,1,1 instead of MOVF RXB1CON,W,1. The first one will write the read value back to the register. This could in worst case cause undesired effects depending on what function the register has. For bit assignment the problem applies to SFR's residing below address 0xF00: B2EIDL.0 = bitA; B2EIDL.1 = !bitA; B2EIDL.2 = bitA & bitB; B2EIDL.3 = bitA | bitB; B2EIDL.4 = bitA && bitB; B2EIDL.5 = bitA || bitB; The compiler will clear (or set) the destination first, and then set (or clear) it depending on the state of the argument. The correct operation for SFR's is a single set or clear depending on the argument. BUG 121: Bank bit updating bug Affected: 1.0 - 1.5 Fixed: 1.6 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 #pragma updateBank 1 Reported by: J Bodin BUG 120: Bank bit updating bug Affected: 1.0 - 1.6 Fixed: 1.6A 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 #pragma updateBank 1 Reported by: J Bodin BUG 119: Code generator bug Affected: 1.1F - 1.4E Fixed: 1.4F 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 118: Code generator bug Affected: 1.2B - 1.4D Fixed: 1.4E 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 117: Code generator bug Affected: 1.0G - 1.4B Fixed: 1.4C 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 116: Code generator bug Affected: 1.1A - 1.4A Fixed: 1.4B 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 115: Variable overlapping bug Affected: 1.3D - 1.4 Fixed: 1.4A 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 114: Const data bug Affected: 1.0 - 1.4 Fixed: 1.4A Accessing a large table (> 256 bytes) of const strings stored in a single table may fail. Only the first 256 bytes will be accessed. const struct { char str[10]; } Cbus[] = { "String1", .. "String30" }; // 10 * 30 = 300 bytes .. char k; writeString( &Cbus[k].str[0]); // wrong code generated BUG 113: Interrupt bug Affected: 1.0F - 1.4 Fixed: 1.4A The compiler tries to trace the register usage during interrupt in order to give advice about register saving and restoring. However, usage of the LFSR instruction is not detected. This means that detection of table access could be wrong. Consequently, the compiler does not tell that the FSR0H must be saved and restored, but will instead tell that it is not required to save this register. This is wrong. Reported by: S Caliebe BUG 112: Floating and fixed point bug Affected: 1.0 - 1.3F Fixed: 1.4 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 111: Fixed point bug Affected: 1.0 - 1.3F Fixed: 1.4 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 110: Table index bug Affected: 1.0 - 1.3E Fixed: 1.3F The bank information on 8 bit pointers are lost when using an index variable greater than 8 bit. The code generated is wrong when accessing data in a single bank different from bank 0. bank7 uns8 package[20]; uns8 *pTmp = &package[0]; uns16 i; pTmp[i] = 10; // BUG Workaround: Use 8 bit index or a type cast to 8 bit (pTmp[(uns8)i]). Reported by: B Damm BUG 109: Code generator bug Affected: 1.1F - 1.3E Fixed: 1.3F Wrong code is generated for 8 bit signed right shift by 4 when using the W-register. int8 a, b, c; W = (int8)W >> 4; // WRONG CODE a = (b + c) >> 4; // WRONG CODE BUG 108: Indirect access bug Affected: 1.0 - 1.3E Fixed: 1.3F Wrong code is generated when accessing a table that cross a bank boundary when using an index with offset. uns8 tab8[128] @ 0x2E0; uns8 x, y, z; z = tab8[x + y]; y = tab8[x + y + 1]; BUG 107: Fixed point bug Affected: 1.0F - 1.3E Fixed: 1.3F 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 106: HEX file bug Affected: 1.0 - 1.3D Fixed: 1.3E The compiler does not insert a type 04 record to separate 64k code blocks unless a #pragma origin statement is used in the source code. Workaround: Use #pragma origin to separate each 64k code block .. functions in first 64k code block #pragma origin 0x10000 .. functions in last 64k code block Reported by: V Malan BUG 105: Inline code bug Affected: 1.3 - 1.3D Fixed: 1.3E 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 104: Typedef enum bug Affected: 1.1E - 1.3D Fixed: 1.3E 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 103: Fixed point bug Affected: 1.0F - 1.3D Fixed: 1.3E 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 102: Const data bug Affected: 1.0 - 1.3B Fixed: 1.3C 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 101: Code generator bug Affected: 1.0 - 1.3 Fixed: 1.3B 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 = u2 % read16(); // Wrong code BUG 100: Code generator bug Affected: 1.1F - 1.2B Fixed: 1.3 Wrong code is generated for the following statement: int8 x, y; x = y >> 4; // wrong code for signed right shift by 4 BUG 99: Pointer bug Affected: 1.0 - 1.2A Fixed: 1.2B 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 98: DW optimization bug Affected: 1.0 - 1.2A Fixed: 1.2B 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 97: Assignment of condition bug Affected: 1.0 - 1.2A Fixed: 1.2B Wrong code is generated for the following cases. char ch, ux; ch = !ch; W = !W; ch = ch >= 5; ch = ch == 5; Zero_ = !W; Zero_ = !ch; ux = ch == 1 && ux > 42; Carry = ch >= ux; Carry = ch <= ux; Reported by: Z Mijanovic BUG 96: Carry bug Affected: 1.0 - 1.2A Fixed: 1.2B Carry is not updated when the least significant byte of the constant added is zero. The carry bit is then wrongly added at next stage of the addition. uns16 tmp; uns8 x; uns8 One( void); tmp = One() + 0x700; // wrong carry tmp = (x & 3) + 0x700; // wrong carry Reported by: L Hedlund BUG 95: Pointer increment bug Affected: 1.1F - 1.2 Fixed: 1.2A 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 94: Variable overlap bug Affected: 1.0 - 1.2 Fixed: 1.2A 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 93: Optimization bug Affected: 1.0I - 1.2 Fixed: 1.2A The nop2() instruction is translated to a branch always, and the optimization may fail when the nop2() is the first conditioal statement in a loop (or the first statement after a GOTO or branch). for (;;) { for (a=1; a; a++) nop2(); } Reported by: S Daniel BUG 92: Code generator bug Affected: 1.0 - 1.2 Fixed: 1.2A Instruction MOVFF is used when destination is PCL, TOSL, TOSH and TOSU. PCL = x; // MOVFF not allowed Workaround: Use WREG as temorary register: W = x; PCL = W; Reported by: N Upphed BUG 91: Indirect access bug Affected: 1.0 - 1.1F Fixed: 1.2 Wrong assembly is generated when using the same special purpose index register (FSR0,FSR1,FSR2) more than one time in the same expression. *FSR1++ = *FSR1; // wrong code *FSR1 = *FSR1 & 0xF0; // wrong code *FSR2 = *(FSR2++) + 1; // wrong code Reported by: L Hedlund BUG 90: Inline assembly bug Affected: 1.1A - 1.1F Fixed: 1.2 Wrong assembly is generated for inline assembly when loading the FSR2 register using the LFSR instruction. #asm LFSR 2, 0x100 // wrong code, FSR1 is loaded #endasm Workaround: Use C coding: FSR2 = 0x100; Reported by: D Klemer BUG 89: Return value bug Affected: 1.0 - 1.1F Fixed: 1.2 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 1.1F only 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 88: Indirect access bug Affected: 1.0 - 1.1F Fixed: 1.2 FSR0H is not cleared after the clearRAM() function on devices containing exactly 256 bytes of RAM (access RAM + bank 0). This must be done because FSR0H is not updated for indirect access to save code. FSR0H should remain 0 in all parts of the application for these devices. Workaround: Insert statement FSR0H = 0; right after clearRAM(); Reported by: F Tilte BUG 87: Indirect access bug Affected: 1.0 - 1.1F Fixed: 1.2 A function call in combination with indirect access is allowed in some cases. However, when the function called modifies the FSR0 register, the indirect access will be wrong. char i, *ps; i = fx() + *ps; // bug if function fx() modify FSR0 if (fx() != *ps) // bug if function fx() modify FSR0 .. Reported by: L Hedlund BUG 86: Variable overlapping bug Affected: 1.0 - 1.1F Fixed: 1.2 The address (bank) of a variable which overlaps another variable is wrong when a bank border is crossed when defining the new overlapping variable as follows. bank5 uns8 largeTab[500]; uns8 itemX @ largeTab[499]; itemX = 10; // bug largeTab[499] = 20; // ok Workaround: Use an absolute address for the basic object: uns8 largeTab[500] @ 0x500; Reported by: L Hedlund BUG 85: Local scope bug Affected: 1.0 - 1.1F Fixed: 1.2 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 84: Indirect access bug Affected: 1.0 - 1.1F Fixed: 1.2 Sign extension is not correct for indirect access of signed integer data items that are smaller than the other operand. int16 i16; int24 i24; uns8 u8; int8 tab[5]; int16 tab16[2]; i16 += tab[u8]; // wrong sign extension i24 += tab16[u8]; // wrong sign extension Reported by: L Hedlund BUG 83: Fixed point bug Affected: 1.0 - 1.1F Fixed: 1.2 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 82: Const parameter bug Affected: 1.0 - 1.1F Fixed: 1.2 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 81: Fixed point library bug Affected: 1.0 - 1.1F Fixed: 1.2 The fixed point math library multiplication routines are wrong for the following cases. #include "math24x.h" fixed16_8 sa, sb, sc; fixedU16_8 ua, ub, uc; sa = sb * sc; // operator _xmul16_8() ua = ub * uc; // operator _xmulU16_8() Reported by: M seven BUG 80: Bit comparing bug Affected: 1.1D - 1.1E Fixed: 1.1F 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 79: Pointer error after type cast Affected: 1.0 - 1.1E Fixed: 1.1F 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 78: Returning a SFR Affected: 1.0 - 1.1E Fixed: 1.1F 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 77: Missing carry for 16-bit address Affected: 1.0 - 1.1E Fixed: 1.1F Carry from LSB to MSB address is not generated when a constant (instead of the address operator &) in combination with an 8 bit index variable. The reason is that the compiler have no information about the address range of the array and make the wrong assumption that no bank boundary is crossed. char idx; size2 char *p2; FSR2 = 0x1F0 + idx; FSR1 = 0xE0 + idx; p2 = 0xE5 + idx; Reported by: J Souto BUG 76: Integer to float inaccuracy Affected: 1.0 - 1.1D Fixed: 1.1E 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 75: Float conversion rounding bug Affected: 1.0 - 1.1D Fixed: 1.1E 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 74: Optimization bug Affected: 1.0 - 1.1D Fixed: 1.1E Optimization type 8 may fail in combination with assigning bit variables or bit return values. This happen when W is loaded in advance with the 8 bit value tested. bit b; char x; x = 10; .. b = (x == 0); // bug return (x == 0); // bug Reported by: J Bodin BUG 73: Optimization bug Affected: 1.0 - 1.1C Fixed: 1.1D 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 72: Pointer address bug Affected: 1.0 - 1.1C Fixed: 1.1D The compiler may fail to use the right bank (MSB) for pointers to loations in bank 1 or higher. char *px8; uns16 test @ 0x345; px8 = (uns8*) &test + 1; px8 = &test.high8 + 1; // bug *px8 = 0x12; // accessing bank 0 (wrong) Reported by: L Hedlund BUG 71: Pointer address bug Affected: 1.0 - 1.1C Fixed: 1.1D 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 70: Struct member bug Affected: 1.0 - 1.1C Fixed: 1.1D The compiler fail to access struct members starting at a large offset (>=256). Bank bit updating and indirect access will be wrong. The problem is relatet to the start position of the member in the structure, and not to the size of the member. The problem also applies to 'const' data. bank2 struct { char mt1[300]; char mt2[100]; } jTAG; char i; jTAG.mt1[0] = 0; // ok jTAG.mt1[299] = 0; // ok jTAG.mt2[0] = 0; // fail jTAG.mt2[99] = 0; // fail jTAG.mt2[i] = 0; // fail Reported by: J Bodin BUG 69: Pointer bug Affected: 1.0 - 1.1C Fixed: 1.1D 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 RLCF is generated Reported by: J Bodin BUG 68: Configuration and ID bug Affected: 1.0 - 1.1B Fixed: 1.1C Using the ~ operator or negative values when specifying the CONFIG and ID bytes may cause trouble. The next configuration or ID byte may not be correct if it is an odd address. #pragma config[2] = ~0x3 & ~0x80 // config[3] will be wrong BUG 67: Optimization bug Affected: 1.0 - 1.1B Fixed: 1.1C 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 byte 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 66: Code generator bug Affected: 1.0F - 1.1B Fixed: 1.1C Wrong code is generated when using both indirect read and increment of a 16 bit or larger element. uns16 t16, timer[5], *px16; uns8 idx; t16 = --timer[idx]; t16 = --px16[0]; t16 = --px16[idx]; Reported by: R Heikens BUG 65: Code generator bug Affected: 1.0 - 1.1B Fixed: 1.1C Wrong code is generated for some conditions when using the CPFSLT or CPFSGT instructions. This happens for the following cases when using operators '<', '>' and '||' in combination with an expression as follows: if (var > expression || .. if (var < expression || .. if (expression < var || .. if (expression > var || .. There is no problem for the && operator or when using a variable or a constant instead of an expression. Typical expressions are 'a+20', 'b&3', 'b+c-d'. Reported by: T Björkman BUG 64: Multitasking bug Affected: 1.0 - 1.1B Fixed: 1.1C Tasks of type 2 are automatically restarted when using "return;". They should be stopped (and restarted only on command). Reported by: L Hedlund BUG 63: Condition bug Affected: 1.0 - 1.1A Fixed: 1.1B The following condition is always false, but wrong code is generated. if (a & 0) // wrong code generated .. BUG 62: Inline assembly bug Affected: 1.0 - 1.1A Fixed: 1.1B Bank bit updating in inline assembly regions containing branch instructions (Bnn) and relative call (RCALL) may fail. These instructions are unfortunately ignored when the compiler decides the RAM bank updating. BUG 61: Inline assembly bug Affected: 1.0 - 1.1A Fixed: 1.1B Relative call (RCALL) in inline assembly is not detected when the compiler check the call level. The generated function call structure file (*.fcs) will also miss such relative calls. BUG 60: Multitasking bug Affected: 1.0D - 1.1 Fixed: 1.1A A wrong computed goto for tasks of type 2 is generated if the compiler decide to insert a bank update instruction before reading the task variable. Reported by: L Hedlund BUG 59: Multitasking bug Affected: 1.0 - 1.1A Fixed: 1.1B Tasks of type 2 containing exactly 128 states does not execute correct when in the stopped state. The computed coto is not correct for this combination. Reported by: L Hedlund BUG 58: Pointer array bug Affected: 1.0 - 1.1A Fixed: 1.1B 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 57: Multitasking bug Affected: 1.0D - 1.1A Fixed: 1.1B The code generated for computed goto in a task is not correct in a special case when the short form is used, and LSB of the MOVF PCL,W instruction is 0xFA or 0xFC (MSB address can be any value). Workaround: #pragma alignLsbOrigin can be used to align the LSB of the task function start address. Reported by: L Hedlund BUG 56: Inline assembly bug Affected: 1.0 - 1.1A Fixed: 1.1B 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 55: Linefeed problem Affected: 1.0 - 1.1A Fixed: 1.1B 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 54: Pointer increment bug Affected: 1.0 - 1.1A Fixed: 1.1B 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 53: Code generator bug Affected: 1.0 - 1.1A Fixed: 1.1B Inline multiplication is wrong when the first argument have a fixed offset (part of a structure or array). Result = (uns16)S.Operand * 8; // Wrong code (wrong offset) Workaround: It is possible to define an overlapping help variable and multiply by this instead: uns8 helpVar @ S.Operand; Result = (uns16)helpVar * 8; Reported by: L Hedlund BUG 52: #pragma bug Affected: 1.1A Fixed: 1.1B 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 51: Optimization bug Affected: 1.0 - 1.1A Fixed: 1.1B 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 50: Const pointer bug Affected: 1.0 - 1.1 Fixed: 1.1A MSB is not updated correctly when assigning a const address to a 16 bit const pointer. const long tl1[] = { -1, .. }; long tlR[10]; const long *pl; char i; pl = &tlR[i]; pl = &tl1[i]; l = *pl; BUG 49: Preprocessor bug Affected: 1.0G - 1.1 Fixed: 1.1A 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 48: Pointer bug Affected: 1.0 - 1.1 Fixed: 1.1A 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 47: Relocatable assembly bug Affected: 1.0 - 1.1 Fixed: 1.1A 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 46: Relocatable assembly bug Affected: 1.1 Fixed: 1.1A Wrong relocatable code is generated when assigning an address of a table residing in bank 2 and upwards to a 16 bit pointer. This only happen when the index expression contain a positive offset. size2 char *p2; bank2 char tab2[10]; p2 = &tab2[i+2]; // wrong relocatable code generated p2 = &tab2[i]; // ok BUG 45: Indexing bug Affected: 1.0 - 1.1 Fixed: 1.1A The compiler will add a constant offset in an index expression to the table address. Wrong code is generated when a wrap to another bank occur in combination with an index expression using at least 2 variables. Carry is missing for one of the additions. bank2 char buffer[10]; char p, l, c; c = buffer[p+l-3]; // BUG if LSB of buffer address < 3 Workaround: Reduce the index complexity or change the buffer address. char tmp = p+l-3; c = buffer[tmp]; Reported by: K Franke BUG 44: Compare for inequality bug Affected: 1.0 - 1.1 Fixed: 1.1A Comparing a 24 or 32 bit variable and a constant for inequality may fail. The condition is that at least one byte including the most significant byte of the constant is 0, and at least one of the other bytes are 0, 1 or 0xFF. uns32 b32; if (b32 != 0x00000055) b32 ++; Workaround: Rewrite and compare for equality if (b32 == 0x00000055) ; else b32 ++; Reported by: K Franke BUG 43: 'const' pointer bug Affected: 1.0 - 1.1 Fixed: 1.1A 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 42: Computed goto bug Affected: 1.0 - 1.1 Fixed: 1.1A 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( accessBank 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 __CC8E__ <= 1100 /* bug fix version 1.1 and earlier */ #pragma updateBank 0 BSR = 0; #pragma updateBank 1 #endif BUG 41: Assembly file bug Affected: 1.0 - 1.0I Fixed: 1.1 When using the -As option to disable symbolic address information, wrong assembly format is generated for the LFSR instruction. Besides, the arguments of the MOVFF are printed without bank information (LSB only). BUG 40: Relocatable assembly bug Affected: 1.0 - 1.0I Fixed: 1.1 The compiler will most probably generate wrong relocatable assembly code when accessing items stored in a table, except when the table is located in bank 0. bank1 uns8 tab[12]; uns8 i, tr; tr = tab[i]; // wrong relocatable asm generated Reported by: F Prenner BUG 39: Relocatable assembly bug Affected: 1.0 - 1.0I Fixed: 1.1 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 __CC8E__ < 1100 // CC8E version 1.0 #asm DW 0 // NOP #endasm #endif Reported by: G Thornley BUG 38: switch bug Affected: 1.0H - 1.0I Fixed: 1.1 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 37: 'const' initialization bug Affected: 1.0 - 1.0I Fixed: 1.1 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 36: Code generator bug Affected: 1.0 - 1.0I Fixed: 1.1 The compiler will generate wrong code when using indexed or indirect access on a value of 16 bit or larger together with an inline operation that use a loop. This applies to some division, shift and multiplication operations. Example: tx[i] = a / b; tx[i] = a << b; a = b * tx[i]; Reported by: P Thomsen BUG 35: Header file bug Affected: 1.0A - 1.0I Fixed: 1.1 Several bit names for the ADCON0 register are placed in a wrong position. The most important of these is the GO bit. This applies to the following devices: 18F6520, 18F6620, 18F6720, 18F8520, 18F8620, 18F8720 18C601, 18C801 These header files was corrected on the 16. October 2003. Reported by: M Widlok BUG 34: Bit operation bug Affected: 1.0 - 1.0H Fixed: 1.0I 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 33: Code generator bug Affected: 1.0 - 1.0H Fixed: 1.0I The code for subtracting a variable from a constant and storing the result back to the same variable may be wrong when the least significant byte of the constant is 255 (0xFF). uns16 x16; uns24 x24; uns32 x32; x16 = 0x10FF - x16; // wrong code generated x24 = 0x1000FF - x24; // wrong code generated x32 = 0x102030FF - x32; // wrong code generated Reported by: G Leuthold BUG 32: Address bug Affected: 1.0 - 1.0H Fixed: 1.0I When locating variables of 16 bit or greater in the upper half of the access bank (address >= 0xF60/0xF80), wrong code is generated because the variable is mistakenly mapped into bank 0. uns16 ADRES @ 0xFC3; // mistakenly placed in bank 0 Reported by: T Waclawczyk BUG 31: List file bug Affected: 1.0F - 1.0H Fixed: 1.0I 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 30: Relocatable assembly bug Affected: 1.0 - 1.0G Fixed: 1.0H 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 and -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[16]; // assumed to be preallocated at address 0 char tab2[16]; // assumed to be preallocated at address 0xF0 char tab3[10]; // assumed to be preallocated at address 0x101 p = &tab1[0]; p = &tab1[i]; p = &tab1[1]; p = &tab1[i+1]; // wrong code (assumed address 1) p = &tab2[15]; // wrong code (assumed address 0xFF) p = &tab2[i+15]; p = &tab3[i]; // wrong code (assumed address 0x101) BUG 29: Relocatable assembly bug Affected: 1.0 - 1.0G Fixed: 1.0H 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 28: Code generator bug Affected: 1.0 - 1.0G Fixed: 1.0H Wrong code is generated for the following special case: char u8; bit bx; u8 = 10 - bx; // wrong code generated BUG 27: Optimization bug Affected: 1.0 - 1.0G Fixed: 1.0H Optimization (type 8) will fail when certain instructions have modified a variable that previously have been loaded into the W register. char a, b, i; a += i; // All the following instructions will disturb optimization i = 0; // CLRF #asm o+ CLRF WREG #endasm i = -i; // NEGF #asm o+ NEGF WREG #endasm i = 0xFF; // SETF W.1 = !W.1; // Bit toggle i.1 = !i.1; // Bit toggle #asm o+ MOVFF c,WREG // version 1.0 - 1.0A only #endasm i = c; // MOVFF #asm o+ RCALL sub #endasm // This and similar statements can be disturbed b += i; // wrong code generated (WREG or 'i' have changed) BUG 26: Floating point bug Affected: 1.0F Fixed: 1.0G 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 25: Assembly file bug Affected: 1.0 - 1.0F Fixed: 1.0G 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 24: Pointer bug Affected: 1.0 - 1.0F Fixed: 1.0G 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 char i; p2 = i + p; // wrong code p2 = 1 + p; // wrong code p2 = &p[1]; // ok p2 = &p[i]; // ok Workaround: Avoid the stated syntax that cause wrong code. BUG 23: Bug in do .. while condition Affected: 1.0 - 1.0F Fixed: 1.0G 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 22: Pointer bug Affected: 1.0 - 1.0F Fixed: 1.0G The compiler will fail to set the FSR0H byte correctly for the following cases. bank3 char b3Buf[80]; void write(char *buf) { buf[2] = 0; // wrong code, FSR0H 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, FSR0H set to 0 } Workaround: Avoid the stated syntax that cause wrong code. Reported by: D Vonasek BUG 21: Code generator bug Affected: 1.0F Fixed: 1.0G The compiler will generate wrong code for some shift operations involving the W register, and in a few additional cases as shown. Note that the compiler will automatically use the W register for temporary values. Therefore the bug may appear also in complex expressions that contains the stated subexpressions, and in "return ;" statements. uns8 a, b, c; uns16 b16; W = b << c; // no code generated a = W << c; // wrong code W = a >> 2; // wrong code W = a >> 3; // wrong code W = a >> 5; // wrong code W = a >> 6; // wrong code a = b16 >> 14; // wrong code a = b16 >> 15; // wrong code Workaround: Avoid using the W register for the stated expressions. a = a >> 3; // correct Reported by: L Hedlund BUG 20: Type conversion bug Affected: 1.0 - 1.0E Fixed: 1.0F 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 19: Problem using DW Affected: 1.0 - 1.0E Fixed: 1.0F 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 18: Version file bug Affected: 1.0 - 1.0E Fixed: 1.0F 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 17: Post-increment bug Affected: 1.0 - 1.0E Fixed: 1.0F 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 16: Type cast bug Affected: 1.0 - 1.0E Fixed: 1.0F 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 15: Optimization bug Affected: 1.0 - 1.0A Fixed: 1.0B 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 14: 'const' data bug Affected: 1.0 - 1.0D Fixed: 1.0E 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 13: Script file bug Affected: 1.0 - 1.0D Fixed: 1.0E When using option -r2, the compiler will generate a partial script file for the low priority interrupt routine and the page item. However, the end address of the page definition is not correct (it must be multiplied by 2). The generated script file can not be used directly. Workaround: Edit the main script file to create fixed end address for 'intserv18' and fixed start for 'page' definition. This may have to be adjusted according to the size of the low priority interrupt routine. BUG 12: Computed goto bug Affected: 1.0 - 1.0C Fixed: 1.0D The code generated for the built in skip(), skipM() and skipL() functions are not complete in some cases. The problem is the need to update PCLATH and PCLATH first. This can be done by an instruction that read PCL. Microchip have announced that the ADDWF PCL instruction which actually performs a read-modify- write operation does not update PCLATH and PCLATH. Unfortunately this was assumed and thus the code is not complete in those cases that use the shortest skip code sequence. skip(i); // skip a certain number of code words forward .. BUG 11: Low level pointer bug Affected: 1.0 - 1.0C Fixed: 1.0D Code is sometimes not generated when assigning a low level pointer. This applies when the least significant byte of the destination or source address is 0, and when using two low level pointers in the assignment. char k; // located on the first location of a bank k = *TBLPTR; // incomplete code generated *FSR0++ = k; // no code is generated *++FSR1 = k; // no code is generated k = *FSR2--; // no code is generated *FSR1++ = *FSR2--; // no code is generated *FSR0-- = *TBLPTR--; // incomplete code generated BUG 10: Fixed point typecast bug Affected: 1.0 - 1.0C Fixed: 1.0D 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 9: Accessing pointers partly Affected: 1.0 - 1.0C Fixed: 1.0D Wrong code is generated when accessing pointer parts when the pointer is 2 bytes or larger. This only applies when the size of the data elements accessed are smaller than the size of the pointer itself. size2 char *px; px.high8 = 0; // wrong code FSR1.high8 = 0; // wrong code TBLPTR.mid8 = 0; // wrong code BUG 8: Ram bank update bug Affected: 1.0 - 1.0C Fixed: 1.0D The compiler may fail to update the ram bank under special conditions. Typically there will be function call followed by a conditional statement and a variable access. The bank will sometimes not be correct for the variable access. The example code will reproduce the bug, but this also depends on the surrounding code. var0 = 0; // 'var0' is in bank 0 function1(0); // bank is 1 on return if (flag == 3) // 'flag' is in access bank var1 = 10; // 'var1' is in bank 1 : BUG: BANK NOT UPDATED var0 ++; Reported by: D Fuentes BUG 7: Math library bugs with optim is off Affected: 1.0 - 1.0C Fixed: 1.0D When optimization is turned OFF, many math operations will not work. This applies to both integer, floating and fixed point operations. The reason is that the DECF instruction is used to control iteration when optimization if OFF rather than the DECFSZ used when optimization is on. Unfortunately DECF changes the Carry bit (on PIC17/18) and this introduces a bug in the operations that require the Carry bit to survive from one iteration to the next. The problem applies to divide operations for all math libraries, and remainder operations on integers. Also on fixed and floating point multiplication when SIZE optimization is switched on. The TEMPORARY WORKAROUND is to always use optimization when compiling the math libraries (and turn optimization off after including the math libraries if optimization need to be off in the user code for some reason). Reported by: E. Kapsalis BUG 6: INHX32 format problem Affected: 1.0 - 1.0C Fixed: 1.0D The record that defines the upper 16 bit address does not use low order first, which means a difference compared to the data records. :0200000400F00A correct high address change (to 0x00F0xxxx) :02000004F0000A wrong address change Reported by: V. di pietri BUG 5: Access bank bugs Affected: 1.0A - 1.0C Fixed: 1.0D Some devices (PIC18Fxx8, and PIC18Fxx20) use another access bank layout (0x00 - 0x5F, 0xF60 - 0xFFF) where the access bank is divided at address 0x60 rather than 0x80 which was used on earlier PIC18 devices. Unfortunately the upgrade done on CC8E was not complete, leading to memory allocation bugs on items crossing address 0x60 (especially for local variables). Temporary workaround: char dummyVar1 @ 0x060; Reported by: M. Åkerblom BUG 4: Bug in conditional expression Affected: 1.0 - 1.0B Fixed: 1.0C When using the '>' operator followed by the '||' operator, for example a statement like (a > b || ..), wrong code is generated. Reported by: C. Forrest BUG 3: Sign extension bug in math call Affected: 1.0 - 1.0A Fixed: 1.0B 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 2: clearRAM() does not work Affected: 1.0 - 1.0A Fixed: 1.0B RAM is not cleared because the loop iteration condition is not correct (only the first location is cleared). This problem does not apply to devices with 1, 2, 4 and 8 RAM banks. Reported by: V. di pietri BUG 1: Return constant bug Affected: 1.0 Fixed: 1.0A 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. The problem applies to constants only.