From: SourceForge.net <no...@so...> - 2005-11-28 04:54:40
|
Bugs item #1367921, was opened at 2005-11-27 20:54 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2005-11-28 08:40:23
|
Bugs item #1367921, was opened at 2005-11-28 05:54 Message generated for change (Comment added) made by frief You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 09:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2005-11-28 09:12:41
|
Bugs item #1367921, was opened at 2005-11-27 20:54 Message generated for change (Comment added) made by jesusc You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 01:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)_asm lcall f _endasm;_asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 00:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2005-11-28 12:23:17
|
Bugs item #1367921, was opened at 2005-11-28 05:54 Message generated for change (Comment added) made by maartenbrock You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: Maarten Brock (maartenbrock) Date: 2005-11-28 13:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 10:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)_asm lcall f _endasm;_asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 09:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2005-11-29 15:35:13
|
Bugs item #1367921, was opened at 2005-11-27 20:54 Message generated for change (Comment added) made by nobody You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-29 07:35 Message: Logged In: NO Thanks for your answers! @maartenbrock The point is, that the "ret" of x() does NEVER return to the caller of x(). It returns to a task, whichs context was pushed to the stack by y(). y() is part of an operating system - it restores the context of the next runnable task. y() trusts in the fact, that it was called and not jumped: at first it pops 2 bytes from the stack, believing these bytes are the return address to it's caller. Then it fills the stack with the new task's context. The last action from y() is, to push the 2 bytes back to the stack so that it's "ret" should leed back to x(). The next 2 bytes on the stack are the address of the new task, and returning to the caller of x() (and using it's ret for the task switch) could/would destroy the new tasks register set. There is no way: y() NEEDS to be called and NOT jumped!!! @frief you are absolutely right - this RTOS changes the program flow! And rule253 changes it too - but this is too much flow-changing! @jesusc and frief yes, I have seen that I can prevent rule253 by adding a neutral operation after the call to y(), or by calling y() via assembler. But is this really the right way?? I needed hours of time to find out what happened. @all maybe my english is too bad to make clear, what the problem is. I wrote my first message only for one reason: informing the SDCC community about a potential risk with rule253. One point is clear: rule253 makes at least RTOS-programming with SDCC very hard. Yesterday I tested SDCC V2.4.0. It seems to be the last version which call/ret's correctly - I like it, and I use it. I will bet, that I can upgrade at the latest to V2.7.0, which will be rule253-free ;). Thanks again for your hints and helps. Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-28 04:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 01:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)_asm lcall f _endasm;_asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 00:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: Jim P. <ji...@jt...> - 2005-11-29 15:48:43
|
> y() is part of an operating system - it restores the context > of the next runnable task. y() trusts in the fact, that it > was called and not jumped: at first it pops 2 bytes from the > stack, believing these bytes are the return address to it's > caller. .. > yes, I have seen that I can prevent rule253 by adding a > neutral operation after the call to y(), or by calling y() > via assembler. But is this really the right way?? Yes, definitely. Statements like "y() trusts in the fact that it was called and not jumped" indicate that you should have fully expected to implement this in assembler from the start. C provides no guarantees when it comes to things like stack layout. Expecting the stack layout to remain unchanged after enabling optimizations? That's like saying GCC can't inline functions. This is not a compiler bug. -jim |
From: SourceForge.net <no...@so...> - 2005-11-29 19:12:52
|
Bugs item #1367921, was opened at 2005-11-28 05:54 Message generated for change (Comment added) made by maartenbrock You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: Maarten Brock (maartenbrock) Date: 2005-11-29 19:17 Message: Logged In: YES user_id=888171 I must be really stupid, but I still don't understand. Isn't x(), the function that called rtos function y(), a part of the context? Shouldn't you preserve the return address and instead return to some address of the other task? Why is it so important to always return to x() and then return to where-ever? Btw. Jim Paris also posted a reply to this thread in the developer mailing list. You can view it through "Mail" in the SF menu. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-29 16:35 Message: Logged In: NO Thanks for your answers! @maartenbrock The point is, that the "ret" of x() does NEVER return to the caller of x(). It returns to a task, whichs context was pushed to the stack by y(). y() is part of an operating system - it restores the context of the next runnable task. y() trusts in the fact, that it was called and not jumped: at first it pops 2 bytes from the stack, believing these bytes are the return address to it's caller. Then it fills the stack with the new task's context. The last action from y() is, to push the 2 bytes back to the stack so that it's "ret" should leed back to x(). The next 2 bytes on the stack are the address of the new task, and returning to the caller of x() (and using it's ret for the task switch) could/would destroy the new tasks register set. There is no way: y() NEEDS to be called and NOT jumped!!! @frief you are absolutely right - this RTOS changes the program flow! And rule253 changes it too - but this is too much flow-changing! @jesusc and frief yes, I have seen that I can prevent rule253 by adding a neutral operation after the call to y(), or by calling y() via assembler. But is this really the right way?? I needed hours of time to find out what happened. @all maybe my english is too bad to make clear, what the problem is. I wrote my first message only for one reason: informing the SDCC community about a potential risk with rule253. One point is clear: rule253 makes at least RTOS-programming with SDCC very hard. Yesterday I tested SDCC V2.4.0. It seems to be the last version which call/ret's correctly - I like it, and I use it. I will bet, that I can upgrade at the latest to V2.7.0, which will be rule253-free ;). Thanks again for your hints and helps. Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-28 13:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 10:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)_asm lcall f _endasm;_asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 09:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2005-11-30 03:45:44
|
Bugs item #1367921, was opened at 2005-11-27 20:54 Message generated for change (Comment added) made by nobody You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-29 19:45 Message: Logged In: NO @maartenbrock not to where-ever, but to the next task! After the task switch is done (by executing the "ret" of x()), x() and y() are dead, and the next task is running. x() will be reactivated, when the next system-tick happens (via timer interrupt). Normally an OS doesn't call the tasks/threads with a "lcall" - it uses a "ret" (after preparing the stack adequately). By the way: asking questions is almost never indicating stupidity! Thanks for the JimParis hint. He thinks, I'm wrong - maybe he is right! Geretings Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-29 10:17 Message: Logged In: YES user_id=888171 I must be really stupid, but I still don't understand. Isn't x(), the function that called rtos function y(), a part of the context? Shouldn't you preserve the return address and instead return to some address of the other task? Why is it so important to always return to x() and then return to where-ever? Btw. Jim Paris also posted a reply to this thread in the developer mailing list. You can view it through "Mail" in the SF menu. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-29 07:35 Message: Logged In: NO Thanks for your answers! @maartenbrock The point is, that the "ret" of x() does NEVER return to the caller of x(). It returns to a task, whichs context was pushed to the stack by y(). y() is part of an operating system - it restores the context of the next runnable task. y() trusts in the fact, that it was called and not jumped: at first it pops 2 bytes from the stack, believing these bytes are the return address to it's caller. Then it fills the stack with the new task's context. The last action from y() is, to push the 2 bytes back to the stack so that it's "ret" should leed back to x(). The next 2 bytes on the stack are the address of the new task, and returning to the caller of x() (and using it's ret for the task switch) could/would destroy the new tasks register set. There is no way: y() NEEDS to be called and NOT jumped!!! @frief you are absolutely right - this RTOS changes the program flow! And rule253 changes it too - but this is too much flow-changing! @jesusc and frief yes, I have seen that I can prevent rule253 by adding a neutral operation after the call to y(), or by calling y() via assembler. But is this really the right way?? I needed hours of time to find out what happened. @all maybe my english is too bad to make clear, what the problem is. I wrote my first message only for one reason: informing the SDCC community about a potential risk with rule253. One point is clear: rule253 makes at least RTOS-programming with SDCC very hard. Yesterday I tested SDCC V2.4.0. It seems to be the last version which call/ret's correctly - I like it, and I use it. I will bet, that I can upgrade at the latest to V2.7.0, which will be rule253-free ;). Thanks again for your hints and helps. Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-28 04:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 01:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)_asm lcall f _endasm;_asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 00:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2006-04-05 15:00:04
|
Bugs item #1367921, was opened at 2005-11-28 05:54 Message generated for change (Comment added) made by maartenbrock You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target >Group: non bugs >Status: Pending >Resolution: Rejected Priority: 5 Submitted By: Nobody/Anonymous (nobody) >Assigned to: Maarten Brock (maartenbrock) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: Maarten Brock (maartenbrock) Date: 2006-04-05 16:59 Message: Logged In: YES user_id=888171 1) SDCC 2.5.5 #1236 now handles "--no-peep --peep-file other.def" as do not use the default rules, but instead only use the rules in other.def. 2) "the next task" is an element in the set "where-ever". I stick with my opinion that a task switch from within x() should not return to x() at all at this point. Instead it should return to the next task immediately, not via x(). Only when it's time to come back to this task it should return to x(). So x() should not be dead when it calls y() to switch tasks but asleep. All in all I do not consider this a bug and therefor set this one pending. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-30 04:45 Message: Logged In: NO @maartenbrock not to where-ever, but to the next task! After the task switch is done (by executing the "ret" of x()), x() and y() are dead, and the next task is running. x() will be reactivated, when the next system-tick happens (via timer interrupt). Normally an OS doesn't call the tasks/threads with a "lcall" - it uses a "ret" (after preparing the stack adequately). By the way: asking questions is almost never indicating stupidity! Thanks for the JimParis hint. He thinks, I'm wrong - maybe he is right! Geretings Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-29 19:17 Message: Logged In: YES user_id=888171 I must be really stupid, but I still don't understand. Isn't x(), the function that called rtos function y(), a part of the context? Shouldn't you preserve the return address and instead return to some address of the other task? Why is it so important to always return to x() and then return to where-ever? Btw. Jim Paris also posted a reply to this thread in the developer mailing list. You can view it through "Mail" in the SF menu. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2005-11-29 16:35 Message: Logged In: NO Thanks for your answers! @maartenbrock The point is, that the "ret" of x() does NEVER return to the caller of x(). It returns to a task, whichs context was pushed to the stack by y(). y() is part of an operating system - it restores the context of the next runnable task. y() trusts in the fact, that it was called and not jumped: at first it pops 2 bytes from the stack, believing these bytes are the return address to it's caller. Then it fills the stack with the new task's context. The last action from y() is, to push the 2 bytes back to the stack so that it's "ret" should leed back to x(). The next 2 bytes on the stack are the address of the new task, and returning to the caller of x() (and using it's ret for the task switch) could/would destroy the new tasks register set. There is no way: y() NEEDS to be called and NOT jumped!!! @frief you are absolutely right - this RTOS changes the program flow! And rule253 changes it too - but this is too much flow-changing! @jesusc and frief yes, I have seen that I can prevent rule253 by adding a neutral operation after the call to y(), or by calling y() via assembler. But is this really the right way?? I needed hours of time to find out what happened. @all maybe my english is too bad to make clear, what the problem is. I wrote my first message only for one reason: informing the SDCC community about a potential risk with rule253. One point is clear: rule253 makes at least RTOS-programming with SDCC very hard. Yesterday I tested SDCC V2.4.0. It seems to be the last version which call/ret's correctly - I like it, and I use it. I will bet, that I can upgrade at the latest to V2.7.0, which will be rule253-free ;). Thanks again for your hints and helps. Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2005-11-28 13:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 2005-11-28 10:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)\ _asm lcall f _endasm;\ _asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-11-28 09:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |
From: SourceForge.net <no...@so...> - 2006-05-06 02:20:21
|
Bugs item #1367921, was opened at 11/27/05 20:54 Message generated for change (Settings changed) made by sf-robot You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&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: msc51(8051) target Group: non bugs >Status: Closed Resolution: Rejected Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Maarten Brock (maartenbrock) Summary: Peephole-rule 253 changes program flow Initial Comment: Peephole-rule 253 changes program flow SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (May 8 2005) (MINGW32) Target: mcs51 Develop: Win-XP-Pro Hi group peephole rule 253.a/b/c "replaced lcall/ret with ljmp" is fatal for non linear program flows (e.g. in RTOS'es)! The C code void x(void) { .... ; do something y(); } will be correctly translated by SDCC as: x: .... lcall y ret ; this ret would start a new context ; instead of returning to caller of x()! and now the peepholer makes from it: x: .... ljmp y ; Peephole 253.b ; replaced lcall/ret with ljmp This is a nice idea, but when y() trusts in finding the return address to x() on the top of the stack, or when y() manipulates the stack (context switch) the sh.t happens! The operating system's function y() looks like this: y: pop callers_return_hi ; Mistake: the x() return pop callers_return_lo ; address was never pushed mov sp, nextcontext ; pop context... ; Do the context switch push callers_return_lo ; this should be x() but push callers_return_hi ; it is: caller of x() ret ; ret to caller of x() ; instead of x()!!! This is a standard operating system flow, and not changeable. Without the peepholer (--no-peep) everything is ok (as it was with SDCC-V2.3), but the code gets much bigger. Also the code (peepholer active) void x(void) { .... ; do something y(); dummy_reg++; } works correct. I think, neither it is possible to disable single peep-rules nor to exchange the complete peeph.def? Unfortunately the compiler switch combination --no-peep --peep-file other.def doesn't solve the problem. Now I switched back to SDCC-V2.3, but I'm sure, that there are more erraneous situations possible with rule 253. Maybe this risky rule should be removed in the next version? Making it possible to exchange the internal peep rules could be helpful also. Greetings Lutz ---------------------------------------------------------------------- >Comment By: SourceForge Robot (sf-robot) Date: 05/05/06 19:20 Message: Logged In: YES user_id=1312539 This Tracker item was closed automatically by the system. It was previously set to a Pending status, and the original submitter did not respond within 30 days (the time period specified by the administrator of this Tracker). ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 04/05/06 07:59 Message: Logged In: YES user_id=888171 1) SDCC 2.5.5 #1236 now handles "--no-peep --peep-file other.def" as do not use the default rules, but instead only use the rules in other.def. 2) "the next task" is an element in the set "where-ever". I stick with my opinion that a task switch from within x() should not return to x() at all at this point. Instead it should return to the next task immediately, not via x(). Only when it's time to come back to this task it should return to x(). So x() should not be dead when it calls y() to switch tasks but asleep. All in all I do not consider this a bug and therefor set this one pending. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 11/29/05 19:45 Message: Logged In: NO @maartenbrock not to where-ever, but to the next task! After the task switch is done (by executing the "ret" of x()), x() and y() are dead, and the next task is running. x() will be reactivated, when the next system-tick happens (via timer interrupt). Normally an OS doesn't call the tasks/threads with a "lcall" - it uses a "ret" (after preparing the stack adequately). By the way: asking questions is almost never indicating stupidity! Thanks for the JimParis hint. He thinks, I'm wrong - maybe he is right! Geretings Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 11/29/05 10:17 Message: Logged In: YES user_id=888171 I must be really stupid, but I still don't understand. Isn't x(), the function that called rtos function y(), a part of the context? Shouldn't you preserve the return address and instead return to some address of the other task? Why is it so important to always return to x() and then return to where-ever? Btw. Jim Paris also posted a reply to this thread in the developer mailing list. You can view it through "Mail" in the SF menu. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 11/29/05 07:35 Message: Logged In: NO Thanks for your answers! @maartenbrock The point is, that the "ret" of x() does NEVER return to the caller of x(). It returns to a task, whichs context was pushed to the stack by y(). y() is part of an operating system - it restores the context of the next runnable task. y() trusts in the fact, that it was called and not jumped: at first it pops 2 bytes from the stack, believing these bytes are the return address to it's caller. Then it fills the stack with the new task's context. The last action from y() is, to push the 2 bytes back to the stack so that it's "ret" should leed back to x(). The next 2 bytes on the stack are the address of the new task, and returning to the caller of x() (and using it's ret for the task switch) could/would destroy the new tasks register set. There is no way: y() NEEDS to be called and NOT jumped!!! @frief you are absolutely right - this RTOS changes the program flow! And rule253 changes it too - but this is too much flow-changing! @jesusc and frief yes, I have seen that I can prevent rule253 by adding a neutral operation after the call to y(), or by calling y() via assembler. But is this really the right way?? I needed hours of time to find out what happened. @all maybe my english is too bad to make clear, what the problem is. I wrote my first message only for one reason: informing the SDCC community about a potential risk with rule253. One point is clear: rule253 makes at least RTOS-programming with SDCC very hard. Yesterday I tested SDCC V2.4.0. It seems to be the last version which call/ret's correctly - I like it, and I use it. I will bet, that I can upgrade at the latest to V2.7.0, which will be rule253-free ;). Thanks again for your hints and helps. Lutz tm...@de... ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 11/28/05 04:23 Message: Logged In: YES user_id=888171 I don't understand what the sh.t is. If you return from y you either end up at the end of x and return immediately to the caller or you return to the caller directly. What's the difference? I'm not saying that this isn't an annoying rule. When debugging it is, because step over doesn't work. The only problem I see in your case is that you want to return to x regardless of where the context left you. ---------------------------------------------------------------------- Comment By: Jesus Calvino-Fraga (jesusc) Date: 11/28/05 01:12 Message: Logged In: YES user_id=603650 One work around would be to call the function in assembly. A macro like this could do the trick: #define MYOS_CALL(f)\ _asm lcall f _endasm;\ _asm ret _endasm And you could call it like this (adding '_' before the function name): void x(void) { .... ; do something MYOS_CALL(_y); } ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 11/28/05 00:40 Message: Logged In: YES user_id=589052 > Peephole-rule 253 changes program flow Well, it's your RTOS which changes program flow:^) Would a define like: #define y() do your_y(); _asm NOP _endasm; while(0) allow you to continue wit 2.5.x? (Peepholes 253.x potentially give you 2 more usable bytes idata in space apart from saving 2 cycles and 1 byte code memory) Greetings, Frieder ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1367921&group_id=599 |