From: SourceForge.net <no...@so...> - 2011-06-08 20:47:52
|
Feature Requests item #3074316, was opened at 2010-09-23 21:50 Message generated for change (Comment added) made by spth You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=3074316&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: None Group: None Status: Open Priority: 5 Private: No Submitted By: Philipp Klaus Krause (spth) Assigned to: Philipp Klaus Krause (spth) Summary: reverse order of arguments Initial Comment: There should be a way to reverse the order in which function arguments are stored to the stack. e.g. something like __reversed_args f(int a, int b); This would be useful for interfacing to existing routines e.g. written in asm or residing in some BIOS. Philipp ---------------------------------------------------------------------- >Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 22:47 Message: The handling of A isn't even implemented yet. I haven't looked at it in detail, it could be that a number of bytes of arguments is passed there, not the number of arguments. The interesting part here isn't varargs - the z88dk people don't have many vararg functions, and AFAIK all of them are written in C anyway (so we don't have to use some specific calling convention). This calling convention is mostly needed for "normal" functions, of which there are many in existing libraries, not written in C. Philipp ---------------------------------------------------------------------- Comment By: Bodo Wenzel (bodowenzel) Date: 2011-06-08 21:44 Message: __sccz80 sounds good, because also the number of args is in A - or am I wrong? This also means that all arguments have to be of equal size, otherwise the value is useless. ;-) In the end, this is a very special way to pass varargs just for z88dk. ---------------------------------------------------------------------- Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 20:48 Message: It seems I remembered optlink incorrectly. You're right, we need to rename this. Unfortunately the pascal calling convention is a callee-clean-up convention, while this is a caller-clen-up convention, so we can't call it __pascal. So far I have not found a right-to-left caller-clears-the-stack calling convention name. If nothing better turns up today or tomorrow, I'd propose to rename it __sccz80. Philipp ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2011-06-08 20:28 Message: Ok, so this means it can never be a command line option or pragma to make it default behaviour, which is fine by me. I have one more question: Why is it called __optlink? When I search for that it seems to always mean a right-to-left calling convention and not left-to-right. Usually (always?) the pascal calling convention is left-to-right. ---------------------------------------------------------------------- Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 17:20 Message: The short answear: It works the same for varargs as for any other functions: It doesn't. The long answear: It seems to me that sccz80 passes the number of variable arguments in the register A, and we should probably do the same. Unfortunately, this is a port-specific solution. The motivation for introducing __optlink is this: z88dk people are considering using sdcc instead of the compiler they currently use (z88dk is basically a simple compiler with lots of peepholes and lots and lots of support libraries for Z80-based platforms). However they have a large amount of asm code that expects parameters in reverse order. Using __optlink they would only have to change some headers, and legacy code calling these asm routines would not require further changes. I do not even know if there are varargs in that use-case. Philipp ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2011-06-08 16:58 Message: Ehm, I meant at the receiving end. How does the callee know how far back on the stack the first argument is placed? ---------------------------------------------------------------------- Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 16:46 Message: It works the same for varargs as for any other functions: void g1(int i, ...); void g2(int i, ...) __optlink; void f(void) { g1(1, 2, 3); g2(1, 2, 3); } results in ld hl,#0x0003 push hl ld l, #0x02 push hl ld l, #0x01 push hl call _g1 pop af pop af pop af ld hl,#0x0001 push hl ld l, #0x02 push hl ld l, #0x03 push hl call _g2 pop af pop af pop af Philipp ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2011-06-08 16:40 Message: How does this work with varargs? ---------------------------------------------------------------------- Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 14:12 Message: __optlink now works for function pointers, too. ---------------------------------------------------------------------- Comment By: Philipp Klaus Krause (spth) Date: 2011-06-08 13:45 Message: This has been implemented partially. However so far it works for function declarations only, not definition and doesn't work with function pointers yet: void f(int, int) __optlink; void h(int, int); void (*p)(int, int) __optlink; void (*q)(int, int); void g(void) { f(1, 2); // OK - parameters passed in reverse order h(1, 2); // OK - parameters passed in normal order (*p)(1, 2); // Broken (*q)(1, 2); // OK } Philipp ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=3074316&group_id=599 |