From: Diego M. M. <ti...@ti...> - 2003-10-27 19:24:46
|
what is wrong with my code (function delay_ms)? somebody can help me? thanks! #define __16F877 #include <p16f877.h> typedef unsigned int word; word at 0x2007 __CONFIG =3D _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF; void delay_ms(int t) { while ( t > 0 ) { T0IF =3D 0; TMR0 =3D ~39; while(!T0IF); t--; } } void Setup(void) { GIE =3D 0; ADCON1 =3D 6; TRISA =3D 0xff; TRISB =3D 0x00; TRISC =3D 0xb9; OPTION_REG =3D 0x86; } void main() { Setup(); while(1) { if (RB5) { RB5 =3D 0; delay_ms(4); } else { RB5 =3D 1; delay_ms(4); } } } -- Diego Manenti Martins T=E9cnico em eletr=F4nica CREA/SC 63164-0 ti...@ti... ________________________________________________ Webmail Unetvale Internet - www.unetvale.com.br |
From: Paul B. <pau...@su...> - 2003-10-27 20:37:54
|
Well, I haven't analysed all the code but one thing sticks out. I think y= ou ought to change all the '&'s for '|'s. Paul :-) p.s. Or use assembler ;-) ----- Original Message -----=20 From: "Diego Manenti Martins" <ti...@ti...> To: <sdc...@li...> Sent: Monday, October 27, 2003 8:21 PM Subject: [Sdcc-user] what is wrong? what is wrong with my code (function delay_ms)? somebody can help me? thanks! #define __16F877 #include <p16f877.h> typedef unsigned int word; word at 0x2007 __CONFIG =3D _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF; void delay_ms(int t) { while ( t > 0 ) { T0IF =3D 0; TMR0 =3D ~39; while(!T0IF); t--; } } void Setup(void) { GIE =3D 0; ADCON1 =3D 6; TRISA =3D 0xff; TRISB =3D 0x00; TRISC =3D 0xb9; OPTION_REG =3D 0x86; } void main() { Setup(); while(1) { if (RB5) { RB5 =3D 0; delay_ms(4); } else { RB5 =3D 1; delay_ms(4); } } } -- Diego Manenti Martins T=E9cnico em eletr=F4nica CREA/SC 63164-0 ti...@ti... ________________________________________________ Webmail Unetvale Internet - www.unetvale.com.br ------------------------------------------------------- This SF.net email is sponsored by: The SF.net Donation Program. Do you like what SourceForge.net is doing for the Open Source Community? Make a contribution, and help us add new features and functionality. Click here: http://sourceforge.net/donate/ _______________________________________________ Sdcc-user mailing list Sdc...@li... https://lists.sourceforge.net/lists/listinfo/sdcc-user |
From: Diego M. M. <ti...@ti...> - 2003-10-27 23:18:35
|
no, the configuration code is ok, i like to program in assembly, but when i work with more than 2k of memory, i have a lot of trouble with some "pagesel", so i want to program in c to dont forget the pagesels :) Paul Bartlett wrote: > Well, I haven't analysed all the code but one thing sticks out. I think you > ought to change all the '&'s for '|'s. > > Paul :-) > > p.s. Or use assembler ;-) > > ----- Original Message ----- > From: "Diego Manenti Martins" <ti...@ti...> > To: <sdc...@li...> > Sent: Monday, October 27, 2003 8:21 PM > Subject: [Sdcc-user] what is wrong? > > > what is wrong with my code (function delay_ms)? > somebody can help me? > thanks! > > #define __16F877 > #include <p16f877.h> > > typedef unsigned int word; > word at 0x2007 __CONFIG = _CP_OFF & _WDT_OFF & _BODEN_ON & > _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & > _LVP_OFF & _DEBUG_OFF & _CPD_OFF; > > > > void delay_ms(int t) > { > while ( t > 0 ) > { > T0IF = 0; > TMR0 = ~39; > while(!T0IF); > t--; > } > } > > void Setup(void) > { > GIE = 0; > > ADCON1 = 6; > > TRISA = 0xff; > TRISB = 0x00; > TRISC = 0xb9; > > OPTION_REG = 0x86; > } > > void main() > { > Setup(); > > while(1) > { > if (RB5) > { > RB5 = 0; > delay_ms(4); > } > else > { > RB5 = 1; > delay_ms(4); > } > } > } > > -- > Diego Manenti Martins > Técnico em eletrônica > CREA/SC 63164-0 > ti...@ti... > > ________________________________________________ > Webmail Unetvale Internet - > www.unetvale.com.br > > > > ------------------------------------------------------- > This SF.net email is sponsored by: The SF.net Donation Program. > Do you like what SourceForge.net is doing for the Open > Source Community? Make a contribution, and help us add new > features and functionality. Click here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user > > > > ------------------------------------------------------- > This SF.net email is sponsored by: The SF.net Donation Program. > Do you like what SourceForge.net is doing for the Open > Source Community? Make a contribution, and help us add new > features and functionality. Click here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user > > -- Diego Manenti Martins Técnico em eletrônica CREA/SC 63164-0 ti...@ti... |
From: Paul B. <pau...@su...> - 2003-10-28 00:48:24
|
Hi Diego, Forget the c/assembler argument for a moment but your following directive is going to generate precisely zero: > > typedef unsigned int word; > > word at 0x2007 __CONFIG = _CP_OFF & _WDT_OFF & _BODEN_ON & > > _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & > > _LVP_OFF & _DEBUG_OFF & _CPD_OFF; If I'm wrong, I profusely grovel and apologise. I should know better. Paul :-) p.s. I'm really trying to help. P |
From: Diego M. M. <ti...@ti...> - 2003-10-28 01:22:48
|
the resultant config word is 0x3f72 :) Paul Bartlett wrote: > Hi Diego, > > Forget the c/assembler argument for a moment but your following directive is > going to generate precisely zero: > > >>>typedef unsigned int word; >>>word at 0x2007 __CONFIG = _CP_OFF & _WDT_OFF & _BODEN_ON & >>>_PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & >>>_LVP_OFF & _DEBUG_OFF & _CPD_OFF; > > > If I'm wrong, I profusely grovel and apologise. I should know better. > > Paul :-) > > p.s. I'm really trying to help. > > P > > > > ------------------------------------------------------- > This SF.net email is sponsored by: The SF.net Donation Program. > Do you like what SourceForge.net is doing for the Open > Source Community? Make a contribution, and help us add new > features and functionality. Click here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user > -- Diego Manenti Martins Técnico em eletrônica CREA/SC 63164-0 ti...@ti... |
From: Paul B. <pau...@su...> - 2003-10-28 10:05:42
|
Bugger. The flags are active *low*. Ok, I'm grovelling... > > the resultant config word is 0x3f72 > :) Paul :-) |
From: Diego M. M. <ti...@ti...> - 2003-10-29 22:48:34
|
i make the tmr2 work corretly but tmr1 i couldn't. is there some bug with tmr1 in sdcc? Diego Manenti Martins wrote: > what is wrong with my code (function delay_ms)? > somebody can help me? > thanks! > > #define __16F877 > #include <p16f877.h> > > typedef unsigned int word; > word at 0x2007 __CONFIG = _CP_OFF & _WDT_OFF & _BODEN_ON & > _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & > _LVP_OFF & _DEBUG_OFF & _CPD_OFF; > > > > void delay_ms(int t) > { > while ( t > 0 ) > { > T0IF = 0; > TMR0 = ~39; > while(!T0IF); > t--; > } > } > > void Setup(void) > { > GIE = 0; > > ADCON1 = 6; > > TRISA = 0xff; > TRISB = 0x00; > TRISC = 0xb9; > > OPTION_REG = 0x86; > } > > void main() > { > Setup(); > > while(1) > { > if (RB5) > { > RB5 = 0; > delay_ms(4); > } > else > { > RB5 = 1; > delay_ms(4); > } > } > } > -- Diego Manenti Martins Técnico em eletrônica CREA/SC 63164-0 ti...@ti... |
From: David H. <ac...@lo...> - 2003-10-30 14:21:45
|
Man, I must be an old man, I'm still fussing around with my little Z80, and while I do use the PIC16F877 for this project as well, I'm more interested in understanding the SDCC for the Z80 at this point. Question: Are there current users on the list that have experience with the compiler on a Z80 that can tell me how to setup the compiler for a little better optimization / code output? I'm porting to SDCC from the Hi-Tech Z80 cross-compiler for CP/M, and the original code is about 20% tighter and in timing tests, 40% faster. =20 Now obviously this is all subjective to the code used, but I am beginning to wonder... Here is a code snippet of a timing test: void timing( unsigned int timeval ) { static unsigned int i, j, k; for ( j =3D 1; j <=3D timeval; j++ ) for ( i =3D 1; i <=3D 15; i++ ) { for ( i =3D 1; i <=3D 7; i++ ) { if ( interrupted ) k =3D 1; } } Which gets compiled into this assembly output. _timing_start:: _timing: push ix ld ix,#0 add ix,sp ;timing.c:33: for ( j =3D 1; j <=3D timeval; j++ )^M ; genAssign ld iy,#_timing_j_1_1 ld 0(iy),#0x01 ld 1(iy),#0x00 ; genLabel 00107$: ; genCmpGt ; AOP_STK for ld a,4(ix) ld iy,#_timing_j_1_1 sub a,0(iy) ld a,5(ix) sbc a,1(iy) jp c,00111$ ;timing.c:37: for ( i =3D 1; i <=3D 7; i++ ) { ; genAssign ld iy,#_timing_i_1_1 ld 0(iy),#0x01 ld 1(iy),#0x00 ; genLabel 00103$: ; genCmpGt ld a,#0x07 ld iy,#_timing_i_1_1 sub a,0(iy) ld a,#0x00 sbc a,1(iy) ld a,#0x00 rla ; genIfx or a,a jp nz,00109$ ;timing.c:39: if ( interrupted )^M ; genIfx xor a,a ld iy,#_interrupted or a,0(iy) jp z,00105$ ;timing.c:40: k =3D 1;^M ; genAssign ld iy,#_timing_k_1_1 ld 0(iy),#0x01 ld 1(iy),#0x00 ; genLabel 00105$: ;timing.c:37: for ( i =3D 1; i <=3D 7; i++ ) {^M ; genPlus ; genPlusIncr ld iy,#_timing_i_1_1 ld c,0(iy) ld b,1(iy) inc bc ; genAssign ld e,c ld d,b ; genAssign ld 0(iy),e ld 1(iy),d ; genGoto jp 00103$ ; genLabel 00109$: ;timing.c:33: for ( j =3D 1; j <=3D timeval; j++ )^M ; genPlus ; genPlusIncr ld iy,#_timing_j_1_1 inc 0(iy) jp nz,00118$ inc 1(iy) 00118$: ; genGoto jp 00107$ ; genLabel 00111$: ; genEndFunction pop ix ret _timing_end:: Which seems *REALLY* inefficient. Now I know that the peephole optimizer in the assembler can help some... But it doesn't seem like much. =20 Is SDCC the wrong compiler to use for the Z80? Is it more suited for the PICs? -Ace Ni-Wumpf Ltd. > -----Original Message----- > From: sdc...@li...=20 > [mailto:sdc...@li...] On Behalf Of=20 > Diego Manenti Martins > Sent: Wednesday, October 29, 2003 3:47 PM > To: sdc...@li... > Subject: Re: [Sdcc-user] what is wrong? >=20 >=20 > i make the tmr2 work corretly but tmr1 i couldn't. is there some bug=20 > with tmr1 in sdcc? >=20 > Diego Manenti Martins wrote: > > what is wrong with my code (function delay_ms)? > > somebody can help me? > > thanks! > >=20 > > #define __16F877 > > #include <p16f877.h> > >=20 > > typedef unsigned int word; > > word at 0x2007 __CONFIG =3D _CP_OFF & _WDT_OFF & _BODEN_ON &=20 > _PWRTE_ON=20 > > & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF; > >=20 > >=20 > >=20 > > void delay_ms(int t) > > { > > while ( t > 0 ) > > { > > T0IF =3D 0; > > TMR0 =3D ~39; > > while(!T0IF); > > t--; > > } > > } > >=20 > > void Setup(void) > > { > > GIE =3D 0; > >=20 > > ADCON1 =3D 6; > >=20 > > TRISA =3D 0xff; > > TRISB =3D 0x00; > > TRISC =3D 0xb9; > >=20 > > OPTION_REG =3D 0x86; > > } > >=20 > > void main() > > { > > Setup(); > >=20 > > while(1) > > { > > if (RB5) > > { > > RB5 =3D 0; > > delay_ms(4); > > } > > else > > { > > RB5 =3D 1; > > delay_ms(4); > > } > > } > > } > >=20 >=20 > --=20 > Diego Manenti Martins > T=E9cnico em eletr=F4nica > CREA/SC 63164-0 > ti...@ti... >=20 >=20 >=20 > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program.=20 > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and help us help > YOU! Click Here: http://sourceforge.net/donate/=20 > _______________________________________________ > Sdcc-user mailing list > Sdc...@li...=20 > https://lists.sourceforge.net/lists/listinfo/s> dcc-user >=20 |
From: Erik P. <epe...@iv...> - 2003-10-30 15:36:00
|
On Thu, 30 Oct 2003, David Humphrey wrote: > I must be an old man, I'm still fussing around with my little Z80, and > while I do use the PIC16F877 for this project as well, I'm more > interested in understanding the SDCC for the Z80 at this point. > > Question: Are there current users on the list that have experience with > the compiler on a Z80 that can tell me how to setup the compiler for a > little better optimization / code output? I'm porting to SDCC from the > Hi-Tech Z80 cross-compiler for CP/M, and the original code is about 20% > tighter and in timing tests, 40% faster. > > Now obviously this is all subjective to the code used, but I am > beginning to wonder... Here is a code snippet of a timing test: > > void timing( unsigned int timeval ) > { > static unsigned int i, j, k; > > for ( j = 1; j <= timeval; j++ ) > for ( i = 1; i <= 15; i++ ) { > for ( i = 1; i <= 7; i++ ) { > if ( interrupted ) > k = 1; > } > } > > Which gets compiled into this assembly output. [omitted] > > Which seems *REALLY* inefficient. Now I know that the peephole > optimizer in the assembler can help some... But it doesn't seem like > much. > > Is SDCC the wrong compiler to use for the Z80? Is it more suited for > the PICs? I'm not sure which is scarier to look at; the Z80 code generator in SDCC or the assembly code it generates. The Z80's registers and addressing modes are rather irregular when compared to the 8051 or PIC and this has led to a rather convoluted and exception filled code generator. At the moment, I've mainly just been squashing bugs so that the Z80 code generator produces correct code, but eventually I would like to improve the quality as well. As you've pointed out, this really needs to be done at at higher level than the peephole optimizer. If you are comparison shopping for free z80 C compilers, you might also want to look at http://www.z88dk.org Erik |
From: David H. <ac...@lo...> - 2003-10-30 21:02:25
|
Well Erik, I appreciate the response, and I for one can vouch for the code "correctness". I have completed the port from my older platform to using the SDCC compiler, and it functions correctly. The application is about 6000 lines of 'C' code running on a board I designed to act as a pinball machine CPU. Everything is running well, although I use *very* few library routines as you can imagine, and that is where I have found hassles with a compiler in the past (include files, and libraries for the platform). You have done great! On the other hand, I tried the Z88DK as well, and found the code generated to be just as sloppy, and the constraints a little worse than the SDCC project. I may well wind up in the Hi-Tech 'C' world paying for the license, and that doesn't bother me, but I really need to prove out the hardware first before optimizing the code for performance (hence justifying the outlay.) Any other cross-compilers to try? Or is there something I can do to this one to help? -Ace > -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...] On Behalf Of > Erik Petrich > Sent: Thursday, October 30, 2003 10:38 AM > To: sdc...@li... > Subject: Re: [Sdcc-user] The Z80 port, optimizations > > > On Thu, 30 Oct 2003, David Humphrey wrote: > > > I must be an old man, I'm still fussing around with my > little Z80, and > > while I do use the PIC16F877 for this project as well, I'm more > > interested in understanding the SDCC for the Z80 at this point. > > > > Question: Are there current users on the list that have experience > > with the compiler on a Z80 that can tell me how to setup > the compiler > > for a little better optimization / code output? I'm > porting to SDCC > > from the Hi-Tech Z80 cross-compiler for CP/M, and the > original code is > > about 20% tighter and in timing tests, 40% faster. > > > > Now obviously this is all subjective to the code used, but I am > > beginning to wonder... Here is a code snippet of a timing test: > > > > void timing( unsigned int timeval ) > > { > > static unsigned int i, j, k; > > > > for ( j = 1; j <= timeval; j++ ) > > for ( i = 1; i <= 15; i++ ) { > > for ( i = 1; i <= 7; i++ ) { > > if ( interrupted ) > > k = 1; > > } > > } > > > > Which gets compiled into this assembly output. > [omitted] > > > > Which seems *REALLY* inefficient. Now I know that the peephole > > optimizer in the assembler can help some... But it doesn't > seem like > > much. > > > > Is SDCC the wrong compiler to use for the Z80? Is it more > suited for > > the PICs? > > I'm not sure which is scarier to look at; the Z80 code > generator in SDCC or the assembly code it generates. The > Z80's registers and addressing modes are rather irregular > when compared to the 8051 or PIC and this has led to a rather > convoluted and exception filled code generator. > > At the moment, I've mainly just been squashing bugs so that > the Z80 code generator produces correct code, but eventually > I would like to improve the quality as well. As you've > pointed out, this really needs to be done at at higher level > than the peephole optimizer. > > If you are comparison shopping for free z80 C compilers, you > might also want to look at http://www.z88dk.org > > Erik > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and help us help > YOU! Click Here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/s> dcc-user > |
From: Groepaz <gr...@gm...> - 2003-10-31 02:38:50
|
On Thursday 30 October 2003 22:02, David Humphrey wrote: > On the other hand, I tried the Z88DK as well, and found the code > generated to be just as sloppy, and the constraints a little worse than > the SDCC project. > > I may well wind up in the Hi-Tech 'C' world paying for the license, and > that doesn't bother me, but I really need to prove out the hardware > first before optimizing the code for performance (hence justifying the > outlay.) > > Any other cross-compilers to try? Or is there something I can do to > this one to help? if there is some free one other than sdcc and z88dk i'd be interisted aswell... i've been working on porting the contiki operating system (contiki.sf.net) to the gameboy and the spectrum - z88dk was pretty much unuseable for that task (to many compiler limitations) and sdcc needed a handful of weirdo patches in the code, but it atleast worked in the end :) gpz btw is there still anyone developing the gbz80 port? |
From: Michael H. <mic...@ju...> - 2003-10-31 07:55:40
|
On Friday, October 31, 2003, at 03:21 AM, David Humphrey wrote: > Man, > > Here is a code snippet of a timing test: > > void timing( unsigned int timeval ) > { > static unsigned int i, j, k; > > for ( j = 1; j <= timeval; j++ ) > for ( i = 1; i <= 15; i++ ) { > for ( i = 1; i <= 7; i++ ) { > if ( interrupted ) > k = 1; > } > } Most of the inefficiency is from using 'static unsigned int'. As the variable is static the compiler can't load anything into registers and can't perform any optimisation. The above code generates 54 non-comment-non-label lines of assembly. Changing to 'unsigned int' cuts this to 36. Changing to 'unsigned char' (as all values will fit within 8 bits) cuts this to 29, the quite reasonable: _timing: push ix ld ix,#0 add ix,sp ;call.c:8: for ( j = 1; j <= timeval; j++ ) ld c,#0x01 00110$: ld l,c ld h,#0x00 ld a,4(ix) sub a,l ld a,5(ix) sbc a,h jp c,00114$ ;call.c:9: for ( i = 1; i <= 15; i++ ) ld b,#0x01 00106$: ld a,#0x0F sub a,b ld a,#0x00 rla or a,a jp nz,00112$ ;call.c:12: for ( i = 1; i <= 7; i++ ) ld e,#0xFF ;call.c:16: k = 1; 00102$: dec e ;call.c:12: for ( i = 1; i <= 7; i++ ) xor a,a or a,e jp nz,00102$ ;call.c:9: for ( i = 1; i <= 15; i++ ) ld b,#0x01 jp 00106$ ; genLabel 00112$: ;call.c:8: for ( j = 1; j <= timeval; j++ ) inc c jp 00110$ 00114$: pop ix ret Note that most of these instructions are also much more efficient than their counterparts, so the speed per line will be higher. There were some parts that could be optimised, such as remembering the state of IY and removing redundant loads like the gbz80 backend does, but that would be better done through a re-write and making IY a full fledged pointer register. That will teach me to take the 8051 backend and port it directly :) -- Michael |
From: Paul B. <pau...@su...> - 2003-10-31 10:16:52
|
Well, I'm no compiler expert (sadly) but started writing Z80 assembler nearly 25 years ago and have done so since off and on. It's a little sad when you realise that you can disassemble some code sequences in your head from a hex memory dump... I question the decision to use the index registers to access the stack frame. These are long instructions with prefixes that just waste time. One possible optimisation that occurs to me is to allocate fixed memory addresses for automatic data where possible. Obviously recursive calls would need careful consideration but in most cases picking up variables from fixed addresses would be much more efficient. These may well be naive comments and if so, I apologise..... Paul :-) > -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...]On > Behalf Of David > Humphrey > Sent: 30 October 2003 14:22 > To: sdc...@li... > Subject: [Sdcc-user] The Z80 port, optimizations > > > Man, > > I must be an old man, I'm still fussing around with > my little Z80, and > while I do use the PIC16F877 for this project as > well, I'm more > interested in understanding the SDCC for the Z80 at > this point. > > Question: Are there current users on the list that > have experience with > the compiler on a Z80 that can tell me how to setup > the compiler for a > little better optimization / code output? I'm > porting to SDCC from the > Hi-Tech Z80 cross-compiler for CP/M, and the original > code is about 20% > tighter and in timing tests, 40% faster. > > Now obviously this is all subjective to the code > used, but I am > beginning to wonder... Here is a code snippet of a > timing test: > > void timing( unsigned int timeval ) > { > static unsigned int i, j, k; > > for ( j = 1; j <= timeval; j++ ) > for ( i = 1; i <= 15; i++ ) { > for ( i = 1; i <= 7; i++ ) { > if ( interrupted ) > k = 1; > } > } > > Which gets compiled into this assembly output. > > _timing_start:: > _timing: > push ix > ld ix,#0 > add ix,sp > ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M > ; genAssign > ld iy,#_timing_j_1_1 > ld 0(iy),#0x01 > ld 1(iy),#0x00 > ; genLabel > 00107$: > ; genCmpGt > ; AOP_STK for > ld a,4(ix) > ld iy,#_timing_j_1_1 > sub a,0(iy) > ld a,5(ix) > sbc a,1(iy) > jp c,00111$ > ;timing.c:37: for ( i = 1; i <= 7; i++ ) { > ; genAssign > ld iy,#_timing_i_1_1 > ld 0(iy),#0x01 > ld 1(iy),#0x00 > ; genLabel > 00103$: > ; genCmpGt > ld a,#0x07 > ld iy,#_timing_i_1_1 > sub a,0(iy) > ld a,#0x00 > sbc a,1(iy) > ld a,#0x00 > rla > ; genIfx > or a,a > jp nz,00109$ > ;timing.c:39: if ( interrupted )^M > ; genIfx > xor a,a > ld iy,#_interrupted > or a,0(iy) > jp z,00105$ > ;timing.c:40: k = 1;^M > ; genAssign > ld iy,#_timing_k_1_1 > ld 0(iy),#0x01 > ld 1(iy),#0x00 > ; genLabel > 00105$: > ;timing.c:37: for ( i = 1; i <= 7; i++ ) {^M > ; genPlus > ; genPlusIncr > ld iy,#_timing_i_1_1 > ld c,0(iy) > ld b,1(iy) > inc bc > ; genAssign > ld e,c > ld d,b > ; genAssign > ld 0(iy),e > ld 1(iy),d > ; genGoto > jp 00103$ > ; genLabel > 00109$: > ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M > ; genPlus > ; genPlusIncr > ld iy,#_timing_j_1_1 > inc 0(iy) > jp nz,00118$ > inc 1(iy) > 00118$: > ; genGoto > jp 00107$ > ; genLabel > 00111$: > ; genEndFunction > pop ix > ret > _timing_end:: > > > Which seems *REALLY* inefficient. Now I know that > the peephole > optimizer in the assembler can help some... But it > doesn't seem like > much. > > Is SDCC the wrong compiler to use for the Z80? Is it > more suited for > the PICs? > > > -Ace > Ni-Wumpf Ltd. > > -----Original Message----- > > From: sdc...@li... > > [mailto:sdc...@li...] On Behalf Of > > Diego Manenti Martins > > Sent: Wednesday, October 29, 2003 3:47 PM > > To: sdc...@li... > > Subject: Re: [Sdcc-user] what is wrong? > > > > > > i make the tmr2 work corretly but tmr1 i couldn't. > is there some bug > > with tmr1 in sdcc? > > > > Diego Manenti Martins wrote: > > > what is wrong with my code (function delay_ms)? > > > somebody can help me? > > > thanks! > > > > > > #define __16F877 > > > #include <p16f877.h> > > > > > > typedef unsigned int word; > > > word at 0x2007 __CONFIG = _CP_OFF & _WDT_OFF & > _BODEN_ON & > > _PWRTE_ON > > > & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & > _DEBUG_OFF & _CPD_OFF; > > > > > > > > > > > > void delay_ms(int t) > > > { > > > while ( t > 0 ) > > > { > > > T0IF = 0; > > > TMR0 = ~39; > > > while(!T0IF); > > > t--; > > > } > > > } > > > > > > void Setup(void) > > > { > > > GIE = 0; > > > > > > ADCON1 = 6; > > > > > > TRISA = 0xff; > > > TRISB = 0x00; > > > TRISC = 0xb9; > > > > > > OPTION_REG = 0x86; > > > } > > > > > > void main() > > > { > > > Setup(); > > > > > > while(1) > > > { > > > if (RB5) > > > { > > > RB5 = 0; > > > delay_ms(4); > > > } > > > else > > > { > > > RB5 = 1; > > > delay_ms(4); > > > } > > > } > > > } > > > > > > > -- > > Diego Manenti Martins > > Técnico em eletrônica > > CREA/SC 63164-0 > > ti...@ti... > > > > > > > > ------------------------------------------------------- > > This SF.net email is sponsored by: SF.net Giveback Program. > > Does SourceForge.net help you be more productive? Does it > > help you create better code? SHARE THE LOVE, and > help us help > > YOU! Click Here: http://sourceforge.net/donate/ > > _______________________________________________ > > Sdcc-user mailing list > > Sdc...@li... > > https://lists.sourceforge.net/lists/listinfo/s> dcc-user > > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and > help us help > YOU! Click Here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user |
From: David H. <ac...@lo...> - 2003-10-31 12:28:34
|
Interesting idea Paul, There are certainly two issues here, and Michael is absolutely right, by using different variables, the code generated could be a lot tighter. The "static" declarations kept the variables out of the stack for the old compiler, which is what I needed, and I think Michael is telling me that this implimentation won't put them on the stack if I pull that modifier out. Additionally, there are two comparisons being made there, where one will definitely need to be an "Int" comparison, the other can *certainly* be an "unsigned char" comparison. So... I will try taking out the "static" declaration, and add in a new variable (RAM is cheap on this new board design - don't the rest of you guys wish you had it this easy!), to handle the inner loop and make it an unsigned char. The important thing I believe I have learned here is the way that the compiler works in area of subroutine variable allocation. ***I think*** Am I hearing this right Michael, that a variable in a subroutine will be allocated at of the Data segment? And THANKS!!!! by the way for the help. I can certainly tighten up my code for this compiler, I did it for the old one... -David Ni-Wumpf Ltc. > -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...] On Behalf Of > Paul Bartlett > Sent: Friday, October 31, 2003 5:18 AM > To: sdc...@li... > Subject: RE: [Sdcc-user] The Z80 port, optimizations > > > Well, I'm no compiler expert (sadly) but started writing Z80 > assembler nearly 25 years ago and have done so since off and > on. It's a little sad when you realise that you can > disassemble some code sequences in your head from a hex memory dump... > > I question the decision to use the index registers to access > the stack frame. These are long instructions with prefixes > that just waste time. > > One possible optimisation that occurs to me is to allocate > fixed memory addresses for automatic data where possible. > Obviously recursive calls would need careful consideration > but in most cases picking up variables from fixed addresses > would be much more efficient. > > These may well be naive comments and if so, I apologise..... > > Paul :-) > > > -----Original Message----- > > From: sdc...@li... > > [mailto:sdc...@li...]On > > Behalf Of David > > Humphrey > > Sent: 30 October 2003 14:22 > > To: sdc...@li... > > Subject: [Sdcc-user] The Z80 port, optimizations > > > > > > Man, > > > > I must be an old man, I'm still fussing around with > > my little Z80, and > > while I do use the PIC16F877 for this project as > > well, I'm more > > interested in understanding the SDCC for the Z80 at > > this point. > > > > Question: Are there current users on the list that > > have experience with > > the compiler on a Z80 that can tell me how to setup > > the compiler for a > > little better optimization / code output? I'm > > porting to SDCC from the > > Hi-Tech Z80 cross-compiler for CP/M, and the original > > code is about 20% > > tighter and in timing tests, 40% faster. > > > > Now obviously this is all subjective to the code > > used, but I am > > beginning to wonder... Here is a code snippet of a > > timing test: > > > > void timing( unsigned int timeval ) > > { > > static unsigned int i, j, k; > > > > for ( j = 1; j <= timeval; j++ ) > > for ( i = 1; i <= 15; i++ ) { > > for ( i = 1; i <= 7; i++ ) { > > if ( interrupted ) > > k = 1; > > } > > } > > > > Which gets compiled into this assembly output. > > > > _timing_start:: > > _timing: > > push ix > > ld ix,#0 > > add ix,sp > > ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M > > ; genAssign > > ld iy,#_timing_j_1_1 > > ld 0(iy),#0x01 > > ld 1(iy),#0x00 > > ; genLabel > > 00107$: > > ; genCmpGt > > ; AOP_STK for > > ld a,4(ix) > > ld iy,#_timing_j_1_1 > > sub a,0(iy) > > ld a,5(ix) > > sbc a,1(iy) > > jp c,00111$ > > ;timing.c:37: for ( i = 1; i <= 7; i++ ) { > > ; genAssign > > ld iy,#_timing_i_1_1 > > ld 0(iy),#0x01 > > ld 1(iy),#0x00 > > ; genLabel > > 00103$: > > ; genCmpGt > > ld a,#0x07 > > ld iy,#_timing_i_1_1 > > sub a,0(iy) > > ld a,#0x00 > > sbc a,1(iy) > > ld a,#0x00 > > rla > > ; genIfx > > or a,a > > jp nz,00109$ > > ;timing.c:39: if ( interrupted )^M > > ; genIfx > > xor a,a > > ld iy,#_interrupted > > or a,0(iy) > > jp z,00105$ > > ;timing.c:40: k = 1;^M > > ; genAssign > > ld iy,#_timing_k_1_1 > > ld 0(iy),#0x01 > > ld 1(iy),#0x00 > > ; genLabel > > 00105$: > > ;timing.c:37: for ( i = 1; i <= 7; i++ ) {^M > > ; genPlus > > ; genPlusIncr > > ld iy,#_timing_i_1_1 > > ld c,0(iy) > > ld b,1(iy) > > inc bc > > ; genAssign > > ld e,c > > ld d,b > > ; genAssign > > ld 0(iy),e > > ld 1(iy),d > > ; genGoto > > jp 00103$ > > ; genLabel > > 00109$: > > ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M > > ; genPlus > > ; genPlusIncr > > ld iy,#_timing_j_1_1 > > inc 0(iy) > > jp nz,00118$ > > inc 1(iy) > > 00118$: > > ; genGoto > > jp 00107$ > > ; genLabel > > 00111$: > > ; genEndFunction > > pop ix > > ret > > _timing_end:: > > |
From: David H. <ac...@lo...> - 2003-10-31 13:37:23
|
OK Michael, You are right, that is quite a bit better looking code. I do like the stack initialization / finalization code for subroutines that are used for this compiler (a big complaint with the *old* Hi-Tech compiler; 0000 DD E5 50 push ix 0002 DD 21 00 00 51 ld ix,#0 0006 DD 39 52 add ix,sp and the comparison between 'int's is pretty tight as well; 0063 FD 21r00s00 149 ld iy,#_timing_j_1_1 < here IX is the stack ptr. and we are comparing to a value on the stack > 0060 DD 7E 04 148 ld a,4(ix) 0067 FD 96 00 150 sub a,0(iy) 006A DD 7E 05 151 ld a,5(ix) 006D FD 9E 01 152 sbc a,1(iy) 0070 DAr87s00 153 jp c,00111$ The compiler wisely used register colouring to get rid of one variable (unsigned char), and allocated space for the other int. I see from the code that indeed this temporary variable gets put into the data segment, something I like a lot better than using the stack for variables in subroutines of real small stack systems: 17 .area _DATA 0000 18 _timing_j_1_1: 0000 19 .ds 2 <BTW for readers seeing this thread anew, the 'C' code that this asm is taken from is: void timing( unsigned int timeval ) { static unsigned int j; unsigned char i, k; for ( j = 1; j <= timeval; j++ ) for ( i = 1; i <= 7; i++ ) { if ( interrupted ) k = 1; } } :-) > The question all this brings to mind is: Is there a way to control what segment these temporary variables are assigned from? As I can see, this goes into the DATA segment. And I can't think of a better area, but a nagging doubt comes to mind that warns me that w/out overlaying some of this data area, I could be getting into trouble. I *know* there are issues with this, and Paul was bringing up one solution, but if there were a way to allow the coder to specify what data area could be safely overlayed with another in subroutine calls, we *may* be able to save data space allocation... -David Ni-Wumpf ltd. |
From: Michael H. <mic...@ju...> - 2003-10-31 21:12:17
|
On Saturday, November 1, 2003, at 02:37 AM, David Humphrey wrote: > The question all this brings to mind is: Is there a way to control what > segment these temporary variables are assigned from? As I can see, > this > goes into the DATA segment. Right. First some terminology. In this code: int a; static int b; void foo(void) { static int c; int d; ... } 'a' is a global, 'b' is a static variable, 'c' is a function local static variable, and 'd' is a local variable. Well, at least that's what I call them. Only 'd' is temporary - all others live for the life of the program. 'a' can be touched from anywhere. 'b' can be touched by anything in this file. 'c' can be touched within this function and is preserved across function calls. 'd' can be touched within this function and is re-created on every call. It shouldn't be too hard to modify the compiler to emit the function local statics into their own segment, but unless you know the call graph (i.e. what calls what) you can't overlay the statics from one function with the statics from another. In fact, I'm not sure you can every overlay local static variables. Note that local variables are implicitly overlayed as they all live on the stack and only live as long as a function is being called. -- Michael |
From: Michael H. <mic...@ju...> - 2003-10-31 21:18:11
|
On Saturday, November 1, 2003, at 01:28 AM, David Humphrey wrote: > Am I hearing this right Michael, that a variable in a subroutine will > be > allocated at of the Data segment? See my previous post, but in short: * Locals go on the stack * Anything else, including static locals go in BSS or DATA. As an aside, here's basically how the register allocator works: * IX is the frame pointer and points to the stack. This makes accessing things on the stack really easy as you can just offset against it. * HL is the temporary register - kind of like a bigger ACC. * IY is used for temporary pointers, such as pointers to statics or globals. * BC and DE are used as working registers. If the compiler can it will allocate local variables into these first and onto the stack second. IX is convenient but slow - I'm interested in how other compilers have done it but there's not much that can be done now. The gbz80 backend uses HL as a combined IX and IY but it has much easier ways of accessing the stack directly. If your variables are local then the compiler can pull all types of tricks to speed things up. The design is also stack based, not register bank based like the 8051 port mainly because the Z80 doesn't have a register bank :) Right, back to lurking for another year. -- Michael > And THANKS!!!! by the way for the help. I can certainly tighten up my > code for this compiler, I did it for the old one... > > > -David > Ni-Wumpf Ltc. > >> -----Original Message----- >> From: sdc...@li... >> [mailto:sdc...@li...] On Behalf Of >> Paul Bartlett >> Sent: Friday, October 31, 2003 5:18 AM >> To: sdc...@li... >> Subject: RE: [Sdcc-user] The Z80 port, optimizations >> >> >> Well, I'm no compiler expert (sadly) but started writing Z80 >> assembler nearly 25 years ago and have done so since off and >> on. It's a little sad when you realise that you can >> disassemble some code sequences in your head from a hex memory dump... >> >> I question the decision to use the index registers to access >> the stack frame. These are long instructions with prefixes >> that just waste time. >> >> One possible optimisation that occurs to me is to allocate >> fixed memory addresses for automatic data where possible. >> Obviously recursive calls would need careful consideration >> but in most cases picking up variables from fixed addresses >> would be much more efficient. >> >> These may well be naive comments and if so, I apologise..... >> >> Paul :-) >> >>> -----Original Message----- >>> From: sdc...@li... >>> [mailto:sdc...@li...]On >>> Behalf Of David >>> Humphrey >>> Sent: 30 October 2003 14:22 >>> To: sdc...@li... >>> Subject: [Sdcc-user] The Z80 port, optimizations >>> >>> >>> Man, >>> >>> I must be an old man, I'm still fussing around with >>> my little Z80, and >>> while I do use the PIC16F877 for this project as >>> well, I'm more >>> interested in understanding the SDCC for the Z80 at >>> this point. >>> >>> Question: Are there current users on the list that >>> have experience with >>> the compiler on a Z80 that can tell me how to setup >>> the compiler for a >>> little better optimization / code output? I'm >>> porting to SDCC from the >>> Hi-Tech Z80 cross-compiler for CP/M, and the original >>> code is about 20% >>> tighter and in timing tests, 40% faster. >>> >>> Now obviously this is all subjective to the code >>> used, but I am >>> beginning to wonder... Here is a code snippet of a >>> timing test: >>> >>> void timing( unsigned int timeval ) >>> { >>> static unsigned int i, j, k; >>> >>> for ( j = 1; j <= timeval; j++ ) >>> for ( i = 1; i <= 15; i++ ) { >>> for ( i = 1; i <= 7; i++ ) { >>> if ( interrupted ) >>> k = 1; >>> } >>> } >>> >>> Which gets compiled into this assembly output. >>> >>> _timing_start:: >>> _timing: >>> push ix >>> ld ix,#0 >>> add ix,sp >>> ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M >>> ; genAssign >>> ld iy,#_timing_j_1_1 >>> ld 0(iy),#0x01 >>> ld 1(iy),#0x00 >>> ; genLabel >>> 00107$: >>> ; genCmpGt >>> ; AOP_STK for >>> ld a,4(ix) >>> ld iy,#_timing_j_1_1 >>> sub a,0(iy) >>> ld a,5(ix) >>> sbc a,1(iy) >>> jp c,00111$ >>> ;timing.c:37: for ( i = 1; i <= 7; i++ ) { >>> ; genAssign >>> ld iy,#_timing_i_1_1 >>> ld 0(iy),#0x01 >>> ld 1(iy),#0x00 >>> ; genLabel >>> 00103$: >>> ; genCmpGt >>> ld a,#0x07 >>> ld iy,#_timing_i_1_1 >>> sub a,0(iy) >>> ld a,#0x00 >>> sbc a,1(iy) >>> ld a,#0x00 >>> rla >>> ; genIfx >>> or a,a >>> jp nz,00109$ >>> ;timing.c:39: if ( interrupted )^M >>> ; genIfx >>> xor a,a >>> ld iy,#_interrupted >>> or a,0(iy) >>> jp z,00105$ >>> ;timing.c:40: k = 1;^M >>> ; genAssign >>> ld iy,#_timing_k_1_1 >>> ld 0(iy),#0x01 >>> ld 1(iy),#0x00 >>> ; genLabel >>> 00105$: >>> ;timing.c:37: for ( i = 1; i <= 7; i++ ) {^M >>> ; genPlus >>> ; genPlusIncr >>> ld iy,#_timing_i_1_1 >>> ld c,0(iy) >>> ld b,1(iy) >>> inc bc >>> ; genAssign >>> ld e,c >>> ld d,b >>> ; genAssign >>> ld 0(iy),e >>> ld 1(iy),d >>> ; genGoto >>> jp 00103$ >>> ; genLabel >>> 00109$: >>> ;timing.c:33: for ( j = 1; j <= timeval; j++ )^M >>> ; genPlus >>> ; genPlusIncr >>> ld iy,#_timing_j_1_1 >>> inc 0(iy) >>> jp nz,00118$ >>> inc 1(iy) >>> 00118$: >>> ; genGoto >>> jp 00107$ >>> ; genLabel >>> 00111$: >>> ; genEndFunction >>> pop ix >>> ret >>> _timing_end:: >>> > > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and help us help > YOU! Click Here: http://sourceforge.net/donate/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user > |