summaryrefslogtreecommitdiff
path: root/asmcall.s
blob: 15231872894716f51daf589d901fe2b75e616b5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
; This source code in this file is licensed to You by Castle Technology
; Limited ("Castle") and its licensors on contractual terms and conditions
; ("Licence") which entitle you freely to modify and/or to distribute this
; source code subject to Your compliance with the terms of the Licence.
; 
; This source code has been made available to You without any warranties
; whatsoever. Consequently, Your use, modification and distribution of this
; source code is entirely at Your own risk and neither Castle, its licensors
; nor any other person who has contributed to this source code shall be
; liable to You for any loss or damage which You may suffer as a result of
; Your use, modification or distribution of this source code.
; 
; Full details of Your rights and obligations are set out in the Licence.
; You should have received a copy of the Licence with this source code file.
; If You have not received a copy, the text of the Licence is available
; online at www.castle-technology.co.uk/riscosbaselicence.htm
; 
; > s.asmcall RCC 24-Mar-88
;
; This makes it possible to call code which scribbles on all the
; registers with a standard ARM procedure call, e.g. from C.
;
; If the code called also scribbles on lk, you must regain control
; by forcing it to branch to asmcall_exit.
;
; NB it relies on scribbling on memory addressed pc-relative, so it
; won't work if the code area is not writable.
;

r0  RN	0
r1  RN	1
r2  RN	2
r3  RN	3
r4  RN	4
ip  RN 12
lk  RN 14
pc  RN 15

    AREA |C$$code|, CODE, READONLY
    EXPORT  asmcall_call
    EXPORT  asmcall_exit

asmcall_savedregs
	DCD	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  ; 11 words for registers
asmcall_call
	;  Enter with r0: thing to call
	;	      r1, r2, r3: parameters for it

	ADR	ip, asmcall_savedregs
	STMIA	ip, {r4-lk}
	MOV	ip, r0
	MOV	r0, r1
	MOV	r1, r2
	MOV	r2, r3
	MOV	lk, pc
	MOV	pc, ip
asmcall_exit
	NOP		; 2 spurious instructions here in case the caller
	NOP		; forgets to allow for prefetch ...
	ADR	ip, asmcall_savedregs
	LDMIA	ip, {r4-lk}
	MOV	pc, lk
    END