From: SourceForge.net <no...@so...> - 2006-11-08 16:05:08
|
Bugs item #1579535, was opened at 2006-10-18 09:52 Message generated for change (Comment added) made by sbryden You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1579535&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: pic14 target Group: fixed Status: Open Resolution: Fixed Priority: 5 Private: No Submitted By: Simon Bryden (sbryden) Assigned to: Nobody/Anonymous (nobody) Summary: Bank selection fails for registers with multiple names Initial Comment: SDCC : pic16/pic14 2.6.1 #4408 (Oct 15 2006) (UNIX) Because variables with different names are stored only once by the function newReg(), attempts later to find the associated register during bank fixing fail for other names. For example, given the following code: #include <pic16f628.h> int main() { RCSTA=0; TRISA=0; ADEN=1; while (1); } The variable RCSTA is stored, but the bit ADEN, which resolves to RCSTA_bits is not stored, because it already exists under the name RCSTA. Thus the bank selection fails (silently) for that assignment, and the bank (which was set to 1 for the assignment to TRISA is incorrect.) A fix is to modify the function newReg as follows: --- ralloc.c.orig 2006-10-18 11:50:06.000000000 +0200 +++ ralloc.c 2006-10-18 11:15:53.000000000 +0200 @@ -351,6 +351,7 @@ //printf( "%s: already present: %s\n", __FUNCTION__, name ); return (dReg); } +#if 0 dReg = regWithIdx( dynDirectRegs, rIdx, 0 ); if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 ); if (dReg) @@ -358,7 +359,7 @@ //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx ); return (dReg); } - +#endif dReg = Safe_calloc(1,sizeof(regs)); dReg->type = type; dReg->pc_type = pc_type; The #if 0 block removes the check and causes the multiply-named register to be hashed multiple times. I'm not sure whether this breaks anything else, or whether this is an optimisation which should be handled otherwise. Simon simon -AT- brydens.net ---------------------------------------------------------------------- >Comment By: Simon Bryden (sbryden) Date: 2006-11-08 16:05 Message: Logged In: YES user_id=222462 Hi Raphael, Thanks for fixing this - alas there is still a problem. Try this: #include <pic16f628.h> int main() { GIE=0; } [compile with sdcc -apic14 -p16f628] This fails with: sdcc: pcode.c:4761: DoBankSelect: Assertion `!"Could not get register from instruction."' failed. This happens whenever a bit from INTCON or STATUS is referenced via the _bits bitfield. I suspect that the root cause might be gleaned by looking at getRegFromInstruction: regs * getRegFromInstruction(pCode *pc) { regs *r; if(!pc || !isPCI(pc) || !PCI(pc)->pcop || PCI(pc)->num_ops == 0 ) return NULL; switch(PCI(pc)->pcop->type) { case PO_STATUS: case PO_FSR: case PO_INDF: case PO_INTCON: case PO_BIT: case PO_GPR_TEMP: case PO_SFR_REGISTER: case PO_PCL: case PO_PCLATH: return PCOR(PCI(pc)->pcop)->r; case PO_GPR_REGISTER: case PO_GPR_BIT: case PO_DIR: r = PCOR(PCI(pc)->pcop)->r; if (r) return r; return dirregWithName(PCI(pc)->pcop->name); case PO_LITERAL: break; case PO_IMMEDIATE: r = PCOI(PCI(pc)->pcop)->r; if (r) return r; return dirregWithName(PCI(pc)->pcop->name); default: break; } return NULL; } In the case of an INTCON bit, the case PO_GPR_BIT is hit, but PCOR(PCI(pc)->pcop)->r is zero. Since this only fails with the registers INTCON and STATUS as far as I can tell, and since they are explicitly mentioned above as a separate case... In any case, I hope this helps you to track down the problem. Otherwise I'm really pleased about the stability of sdcc for pic14. You guys have done a great job! Regards, Simon. ---------------------------------------------------------------------- Comment By: Simon Bryden (sbryden) Date: 2006-11-08 14:24 Message: Logged In: YES user_id=222462 Hi Raphael, Thanks for fixing this - alas there is still a problem. Try this: #include <pic16f628.h> int main() { GIE=0; } [compile with sdcc -apic14 -p16f628] This fails with: sdcc: pcode.c:4761: DoBankSelect: Assertion `!"Could not get register from instruction."' failed. This happens whenever a bit from INTCON or STATUS is referenced via the _bits bitfield. I suspect that the root cause might be gleaned by looking at getRegFromInstruction: regs * getRegFromInstruction(pCode *pc) { regs *r; if(!pc || !isPCI(pc) || !PCI(pc)->pcop || PCI(pc)->num_ops == 0 ) return NULL; switch(PCI(pc)->pcop->type) { case PO_STATUS: case PO_FSR: case PO_INDF: case PO_INTCON: case PO_BIT: case PO_GPR_TEMP: case PO_SFR_REGISTER: case PO_PCL: case PO_PCLATH: return PCOR(PCI(pc)->pcop)->r; case PO_GPR_REGISTER: case PO_GPR_BIT: case PO_DIR: r = PCOR(PCI(pc)->pcop)->r; if (r) return r; return dirregWithName(PCI(pc)->pcop->name); case PO_LITERAL: break; case PO_IMMEDIATE: r = PCOI(PCI(pc)->pcop)->r; if (r) return r; return dirregWithName(PCI(pc)->pcop->name); default: break; } return NULL; } In the case of an INTCON bit, the case PO_GPR_BIT is hit, but PCOR(PCI(pc)->pcop)->r is zero. Since this only fails with the registers INTCON and STATUS as far as I can tell, and since they are explicitly mentioned above as a separate case... In any case, I hope this helps you to track down the problem. Otherwise I'm really pleased about the stability of sdcc for pic14. You guys have done a great job! Regards, Simon. ---------------------------------------------------------------------- Comment By: Raphael Neider (tecodev) Date: 2006-10-28 23:49 Message: Logged In: YES user_id=1115835 Fixed in r4441 by creating proper aliases for registers with multiple names. > Thus the bank selection fails (silently) for that assignment Also fixed, DoBankselect now fails 'noisily' ;-) Thanks and regards, Raphael ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1579535&group_id=599 |