Subject:
Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16
From:
"mengjin su" ####@####.####
Date:
4 Aug 2006 23:28:34 +0100
Message-Id: <BAY101-F352039DE16EBB2954EAD46D0500@phx.gbl>
I was suprised that my comments would get you guys so much attention.
Actually, it was the comparison result when I was working my own
PIC18Fxxxx C compiler, P18CC, trying to compare the code
efficiency against that from SDCC.
Here is the code output from P18CC:
[Extened intruction set enabled]
----------------------------------------------------------------------------------
segment code, _strcpy, 0, 0
_strcpy::
_strcpy_$1 equ 1
_strcpy_0 equ 3
_strcpy_1 equ 5
subfsr 2, 2
L8:
; ::: 'string.c' #12: while ( *des++ = *src++ )
movss _strcpy_0, _strcpy_$1
movss _strcpy_0+1, _strcpy_$1+1
infsnz _strcpy_0, F
incf _strcpy_0+1, F
movsf _strcpy_1, FSR0L
movsf _strcpy_1+1, FSR0H
infsnz _strcpy_1, F
incf _strcpy_1+1, F
movsf _strcpy_$1, FSR1L
movsf _strcpy_$1+1, FSR1H
movff POSTINC0, INDF1
movsf _strcpy_$1, FSR0L
movsf _strcpy_$1+1, FSR0H
movf POSTINC0, W
bnz L8
addulnk 2
----------------------------------------------------------------------------------
[Extened intruction set disabled]
----------------------------------------------------------------------------------
segment code, _strcpy, 0, 6
_strcpy::
_strcpy_0 equ _strcpy_bankX_data_
_strcpy_1 equ _strcpy_bankX_data_+2
_strcpy_$1 equ _strcpy_bankX_data_+4
lfsr 1, _strcpy_1+1
movlw 4
call __mov_pars
L8:
; ::: 'string.c' #12: while ( *des++ = *src++ )
movff _strcpy_0, _strcpy_$1
movff _strcpy_0+1, _strcpy_$1+1
lfsr 0, _strcpy_0
infsnz POSTINC0, F
incf POSTINC0, F
lfsr 0, _strcpy_1
clrf TABLAT
movlw 1
call __fsr0_fetch2
movff _strcpy_$1, FSR1L
movff _strcpy_$1+1, FSR1H
movff POSTINC0, INDF1
movff _strcpy_$1, FSR0L
movff _strcpy_$1+1, FSR0H
movf POSTINC0, W
bnz L8
return
----------------------------------------------------------------------------------
- Mengjin -
>From: Dave Tweed ####@####.####
>Reply-To: ####@####.####
>To: ####@####.####
>Subject: Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16
>Date: Thu, 03 Aug 2006 17:56:56 -0400
>
>[Following up to myself ...]
>
>I wrote:
> > On processors with multiple memory spaces, you must be careful to take
> > advantage of whatever storage class qualifiers the compiler provides on
> > both variables and the pointers that point to them, in order to give
> > the compiler the information it needs to produce more highly optimized
> > code.
> >
> > I know nothing about the details of SDCC for the PIC, but if there's a
> > way to tell it that both of the pointers can only point to objects in
> > on-chip RAM, I'm sure the generated code will look much better to you.
>
>I got curious, so I downloaded, built and installed SDCC 2.6.0 to try
>this out. I got:
>
>_strcpy_ram:
>; .line 6; strcpy.c void strcpy_ram (near char *des, near char *src)
> MOVFF FSR2L, POSTDEC1
> MOVFF FSR1L, FSR2L
> MOVFF r0x00, POSTDEC1
> MOVFF r0x01, POSTDEC1
> MOVFF r0x02, POSTDEC1
> MOVFF r0x03, POSTDEC1
> MOVFF r0x04, POSTDEC1
> MOVLW 0x02
> MOVFF PLUSW2, r0x00
> MOVLW 0x03
> MOVFF PLUSW2, r0x01
> MOVLW 0x04
> MOVFF PLUSW2, r0x02
> MOVLW 0x05
> MOVFF PLUSW2, r0x03
>_00110_DS_:
>; .line 8; strcpy.c while ((*des++ = *src++)) ;
> MOVFF r0x02, FSR0L
> MOVFF r0x03, FSR0H
> MOVFF INDF0, r0x04
> INCF r0x02, F
> BTFSC STATUS, 0
> INCF r0x03, F
> MOVFF r0x00, FSR0L
> MOVFF r0x01, FSR0H
> MOVFF r0x04, INDF0
> INCF r0x00, F
> BTFSC STATUS, 0
> INCF r0x01, F
> MOVF r0x04, W
> BTFSS STATUS, 2
> GOTO _00110_DS_
> MOVFF PREINC1, r0x04
> MOVFF PREINC1, r0x03
> MOVFF PREINC1, r0x02
> MOVFF PREINC1, r0x01
> MOVFF PREINC1, r0x00
> MOVFF PREINC1, FSR2L
> RETURN
>
>... which is pretty much what I expected. Not a huge improvement, but it
>now uses 2-byte pointers and inline code to do the gets and puts of the
>data bytes.
>
>I'm a bit surprised that the documentation for the generic pointers talks
>about the three distinct memory spaces, but the discussion about memory
>models and pointers only talks about "near" and "far". Seems like a bit
>of a disconnect there.
>
>It's too bad (in this particular case) that the compiler reserves two of
>the three FSRs for managing the C stack. I can see how that's probably
>the best choice for function-calling performance in general. It would be
>interesting to see whether an optimization could be introduced that would
>free up FSR2 inside functions that access their arguments only once (at
>the beginning) for use as a second data pointer. Then you could conceivably
>get code something like this:
>
>_strcpy_ram:
>; .line 6; strcpy.c void strcpy_ram (near char *des, near char *src)
> MOVFF FSR2L, POSTDEC1
> MOVFF FSR1L, FSR2L
> MOVFF FSR2H, POSTDEC1 ; save FSR2 for caller
> MOVF PREINC2, W ; dummy access to adjust pointer
> MOVFF PREINC2, FSR0L ; copy arguments directly to FSRs
> MOVFF PREINC2, FSR0H
> MOVF PREINC2, W ; special handling as FSR2 switches
> MOVFF PREINC2, FSR2H ; from one use to another
> MOVWF FSR2L
>_00110_DS_:
>; .line 8; strcpy.c while ((*des++ = *src++)) ;
> MOVF POSTINC2, W ; do the move as two steps
> MOVWF POSTINC0 ; so we can examine the data byte
> BNZ _00110_DS_
> MOVFF PREINC1, FSR2H ; restore FSR2
> MOVFF PREINC1, FSR2L
> RETURN
>
>I'm pretty sure this would work even with interrupts enabled, as long as
>the ISRs only use FSR1 and preserve FSR2 without assuming anything about
>its contents.
>
>I can't imagine what it would take to describe these optimizations to
>SDCC, and this serves mainly to illustrate why you write your critical
>low-level routines in assembly on most 8-bit machines, especially the
>ones that aren't particularly "C-friendly". Use the C code mainly to
>glue together low-level functions into larger modules and systems.
>
>-- Dave Tweed
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: ####@####.####
>For additional commands, e-mail: ####@####.####
>