gnupic@linuxhacker.org

gnupic@linuxhacker.org


Subject: More on SDCC/PIC code correctness
From: Rick Mann
Date: Sat, 27 Sep 2003 11:36:38 -0700

Can someone please verify my assertion here?

(Scott, I sent this to you as well since you're the authority; I know 
you don't have a lot of time for this, so please let me know if you'd 
rather I didn't CC you on these).

I have a C source file:

> #include "p16f877.h"
>
> void
> main()
> {
> 	T0IE = 0;
> 	OPTION_REG = 0x73;
> 	
> 	TMR0 = 217;
> 	T0IF = 0;
> 	while (T0IF == 0);
> 	T0IF = 0;
> }

If I compile this with the following command:

% sdcc -mpic14 -p16f877 -I /usr/share/gpasm/header/ turtle.c

It generates the following (incorrect) code:

> ;--------------------------------------------------------
> ; code
> ;--------------------------------------------------------
> code_turtle	code
> ;***
> ;  pBlock Stats: dbName = M
> ;***
> ;entry:  _main	;Function start
> ; 2 exit points
> ;has an exit
> ;1 compiler assigned register :
> ;   r0x21
> ;; Starting pCode block
> _main	;Function start
> ; 2 exit points
> ;#CSRC	turtle.c 9
> ;  T0IE = 0;
> 	BCF	(_T0IE >> 3), (_T0IE & 7)
> ;#CSRC	turtle.c 10
> ;  OPTION_REG = 0x73;
> 	MOVLW	0x73
> 	BSF	STATUS,5
> 	MOVWF	_OPTION_REG
> ;#CSRC	turtle.c 12
> ;  TMR0 = 217;
> 	MOVLW	0xd9
> 	BCF	STATUS,5
> 	MOVWF	_TMR0
> ;#CSRC	turtle.c 13
> ;  T0IF = 0;
> 	BCF	(_T0IF >> 3), (_T0IF & 7)
> ;#CSRC	turtle.c 14
> ;  while (T0IF == 0);
> 	CLRF	r0x21
> 	BTFSS	(_T0IF >> 3), (_T0IF & 7)
> 	INCF	r0x21,F
> _00105_DS_
> 	MOVF	r0x21,W
> 	BTFSS	STATUS,2
> 	GOTO	_00105_DS_
> ;#CSRC	turtle.c 15
> ;  T0IF = 0;
> 	BCF	(_T0IF >> 3), (_T0IF & 7)
> 	RETURN	
> ; exit point of _main
>
> 	end

In particular, the loop compiles to the following incorrect assembly (I 
think it's incorrect; I may be overlooking how it works). I think it's 
incorrect because the actual looping code does not ever include the 
test of T0IF:

> ;#CSRC	turtle.c 14
> ;  while (T0IF == 0);
> 	CLRF	r0x21
> 	BTFSS	(_T0IF >> 3), (_T0IF & 7)
> 	INCF	r0x21,F
> _00105_DS_
> 	MOVF	r0x21,W
> 	BTFSS	STATUS,2
> 	GOTO	_00105_DS_

However, if I specify either the --nogcse or --noinvariant options, it 
generates the following for that same loop:

> _00105_DS_
> ;#CSRC	turtle.c 11
> ;  while (T0IF == 0);
> 	CLRF	r0x21
> 	BTFSS	(_T0IF >> 3), (_T0IF & 7)
> 	INCF	r0x21,F
> 	MOVF	r0x21,W
> 	BTFSS	STATUS,2
> 	GOTO	_00105_DS_

It's wordy, in that it introduces a semaphore that's really unecessary, 
but it's correct, and for now I'll take it. This leads me to believe 
that the optimizer is introducing errors.

I'm happy to run without the optimizations; I can tweak the assembly by 
hand if necessary. Is this a bug that can be fixed in the PIC port of 
SDCC? Am I completely off base?

As always, TIA,

-- 
Rick


gnupic@linuxhacker.org