gnupic: Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16


Previous by date: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Dave Tweed
Next by date: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Scott Dattalo
Previous in thread: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Dave Tweed
Next in thread: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Scott Dattalo

Subject: Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16
From: Dave Tweed ####@####.####
Date: 3 Aug 2006 22:57:00 +0100
Message-Id: <E1G8lBY-0005Un-00@pop-canoe.atl.sa.earthlink.net>

[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

Previous by date: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Dave Tweed
Next by date: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Scott Dattalo
Previous in thread: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Dave Tweed
Next in thread: 3 Aug 2006 22:57:00 +0100 Re: [gnupic] SDCC 2.6.0, finds pic14 header files but not pic16, Scott Dattalo


Powered by ezmlm-browse 0.20.