Commit 4ddb0942 authored by Ben Avison's avatar Ben Avison Committed by ROOL
Browse files

Add variants of _swi and _swix that take a va_list

These are typically useful for wrapper functions that want to do something
before and/or after a SWI call, and which therefore need to pass a pointer
to their own variadic arguments into the guts of _swi or _swix.

The pairs of functions _swi and _vswi, and _swix and _vswix, are almost
identical, differing only in argument marshalling.

There being only two additional entries, I didn't think it was worth
introducing a whole new library chunk. Instead, I've tacked them onto the
end of chunk 2 (the basic clib functions).

Note that this means that any applications that use these new entries will
need to take responsibility for RMEnsuring this version of the
SharedCLibrary module and softloading a newer one if necessary.
parent 3b7d39bd
......@@ -213,6 +213,8 @@
Entry _swi, imported, , unveneered
Entry _swix, imported, , unveneered
Entry _vswi, imported, , unveneered
Entry _vswix, imported, , unveneered
; __va_illegal_arg 0
END
......@@ -34,12 +34,18 @@ extern "C"
{
#endif
typedef char *__va_list[1]; /* keep in step with <stdarg.h> */
#pragma -v4
extern int _swi (int swi_no, unsigned int, ...);
extern _kernel_oserror *_swix (int swi_no, unsigned int, ...);
#pragma -v0
extern int _vswi (int swi_no, unsigned int, __va_list);
extern _kernel_oserror *_vswix (int swi_no, unsigned int, __va_list);
#ifdef __cplusplus
}
#endif
......@@ -61,9 +67,11 @@ extern _kernel_oserror *_swix (int swi_no, unsigned int, ...);
* These functions provide a generic method of calling RISC OS SWIs from C or
* C++.
*
* Two functions are provided:
* Four functions are provided:
* _swi for calling SWIs without setting the X bit
* _swix which sets the X bit before calling the SWI.
* _swix which sets the X bit before calling the SWI
* _vswi, like _swi but using a va_list instead of variadic arguments
* _vswix, like _swix but using a va_list instead of variadic arguments.
*
* swi_no is the number of the SWI to be called. This should never have the
* X bit set.
......@@ -142,5 +150,10 @@ extern _kernel_oserror *_swix (int swi_no, unsigned int, ...);
* &workspace_end, &next);
*
* e = _swix(Wimp_SetExtent, _IN(0)|_BLOCK(1), w, minx, miny, maxx, maxy);
*
* va_list ap;
* va_start(ap, flags);
* e = _vswix(swi_no, flags, ap);
* va_end(ap);
*/
......@@ -39,10 +39,29 @@ $name MRS lr, CPSR
EXPORT |_swix|
EXPORT |_swi|
EXPORT |_vswix|
EXPORT |_vswi|
; tedious static _swi(x) entry handling, to avoid generating dynamic code, and
; requiring an expensive XOS_SynchroniseCodeAreas
|_vswix|
ORR r0, r0, #&20000
TST r1, #&FF0 ; check for use of input regs. 4 to 9, or of block param
BNE vswix_even_more_tedious ; if so, do full stuff
SUB sp, sp, #2*4 ; leave a gap so we can use common bottom half
STMDB sp!, {r1, r4-r9, lr} ; save stuff
LDR r14, [r2] ; r14 -> input args
B swix_vswix_common
vswix_even_more_tedious
|_vswi|
SUB sp, sp, #2*4 ; leave a gap so we can use common bottom half
STMDB sp!, {r1, r4-r9, lr} ; save stuff
LDR r14, [r2] ; r14 -> input args
B swi_vswi_common
|_swix|
ORR r0, r0, #&20000
TST r1, #&FF0 ; check for use of input regs. 4 to 9, or of block param
......@@ -50,10 +69,9 @@ $name MRS lr, CPSR
STMFD sp!, {r2, r3} ; put 1st two variadic args on stack
STMDB sp!, {r1, r4-r9, lr} ; save stuff
ADD r14, sp, #8*4 ; r14 -> input args
swix_vswix_common
SUB sp, sp, #5*4 ; so we can use tail code common with dynamic version (and room for regs stash)
ADD r14, sp, #(5+8)*4 ; r14 -> input args
MOV r12, r0 ; target SWI code
STR fp, [sp] ; stash fp
......@@ -78,10 +96,9 @@ swix_even_more_tedious
|_swi|
STMFD sp!, {r2, r3} ; put 1st two variadic args on stack
STMDB sp!, {r1, r4-r9, lr} ; save stuff
ADD r14, sp, #8*4 ; r14 -> input args
swi_vswi_common
SUB sp, sp, #5*4 ; so we can use tail code common with dynamic version (and room for regs stash)
ADD r14, sp, #(5+8)*4 ; r14 -> input args
MOV r12, r0 ; target SWI code
STR fp, [sp] ; stash fp
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment