Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_call_sparc.s @ 521:a2de1d0a73f3
- more test code generator code sharing/abstraction/simplifications
author | Tassilo Philipp |
---|---|
date | Wed, 13 Apr 2022 10:06:40 +0200 |
parents | 91db39538e78 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncall | |
5 File: dyncall/dyncall_call_sparc.S | |
6 Description: Call kernel for sparc processor architecture. | |
7 License: | |
8 | |
9 Copyright (c) 2011-2015 Daniel Adler <dadler@uni-goettingen.de> | |
10 | |
11 Permission to use, copy, modify, and distribute this software for any | |
12 purpose with or without fee is hereby granted, provided that the above | |
13 copyright notice and this permission notice appear in all copies. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
22 | |
23 */ | |
24 | |
25 | |
26 | |
27 | |
28 /* --------------------------------------------------------------------------- | |
29 | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
30 @@@ this should all go in manual |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
31 |
0 | 32 call kernel for sparc 32-bit |
33 ---------------------------- | |
34 tested on linux/debian [gcc54.fsffrance.org - thanx to the farm!] | |
35 | |
36 new C Interface: | |
37 void dcCall_sparc (DCCallVM* callvm, DCpointer target); | |
38 %i0 %1 | |
39 | |
40 we need to do that, due to the special property of sparc, its 'register windows' | |
41 that propagate input registers.. | |
42 otherwise, we would have a 'void' return-value layer which results in failure | |
43 to propagate back return values. | |
44 instead of implementing 'dummy'-C return-values, we call directly. | |
45 | |
46 in sparc, this is simply a leaf-function layer using %o3. | |
47 | |
48 old C Interface: | |
49 void dcCall_sparc (DCpointer target, DCsize size, DCpointer data); | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
50 %i0 , %i1 , %i2 |
0 | 51 |
52 | |
53 Input: | |
54 i0 callvm | |
55 i1 target | |
56 | |
57 old Input: | |
58 i0 target | |
59 i1 size | |
60 i2 data | |
61 | |
62 Description: | |
63 We need to raise a dynamic stack frame. | |
64 Therefore we need to compute the stack size in the context of the caller as a leaf note (using o3 in addition). | |
65 Then we raise the frame. | |
66 | |
67 sparc: | |
68 - big endian | |
69 | |
70 sparc V8: | |
71 - integer/pointer: 32 32-bit integers. | |
72 - float: 8 quad precision, 16 double precision, 32 single precision. | |
73 | |
74 sparc V9: | |
75 - integer/pointer: 32 64-bit integers. | |
76 | |
77 plan9: | |
78 - completely different scheme - similar to mips/plan9. | |
79 - registers are named r0 .. r31 | |
80 r1 stack pointer | |
81 r2 static base register | |
82 .. to be continued.. | |
83 | |
84 Stack Layout 32-Bit Model: | |
85 - sp+92 seventh argument | |
86 - sp+68 first argument | |
87 - sp+64 | |
88 - 16 registers save area (in/local). | |
89 | |
90 XX: should be 8 byte aligned (min stack frame size is 96). | |
91 ... | |
92 92: on stack argument 6 | |
93 88: input argument 5 spill | |
94 ... | |
95 68: input argument 0 spill | |
96 64: struct/union pointer return value | |
97 0: 16 registers save area | |
98 | |
99 Stack Layout 64-Bit Model: | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
100 XX: should be 16 byte aligned (min stack frame size is 172). |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
101 168: on stack argument 6 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
102 136: input argument 0 spill |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
103 128: struct/union poiner return value |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
104 0: 16 registers save area |
0 | 105 |
106 | |
107 | |
108 Register Usage: | |
109 %sp or %o6: stack pointer, always 8 (or 16?)-byte aligned. | |
110 %fp or %i6: frame pointer. | |
111 %i0 and %o0: integer and pointer return values. | |
112 %i7 and %o7: return address. (caller puts return address to %o7, callee uses %i7) | |
113 %f0 and %f1: return value (float). | |
114 %i0..%i5: input argument registers | |
115 %o0..%o5: output argument registers | |
116 %g0: always zero, writes to it have no effect. | |
117 | |
118 Register Mappings: | |
119 r0-7 -> globals | |
120 r8-15 -> outs | |
121 r16-r23 -> locals | |
122 r24-r31 -> ins | |
123 | |
124 */ | |
125 | |
249
91db39538e78
- replaced `.set' directives used to set symbol values in assembly files with (seemingly) more portable `=' syntax (e.g. older versions of Sun's `as' don't handle `.set')
Tassilo Philipp
parents:
192
diff
changeset
|
126 REGSIZE = 4 |
91db39538e78
- replaced `.set' directives used to set symbol values in assembly files with (seemingly) more portable `=' syntax (e.g. older versions of Sun's `as' don't handle `.set')
Tassilo Philipp
parents:
192
diff
changeset
|
127 ALIGN = 16 |
91db39538e78
- replaced `.set' directives used to set symbol values in assembly files with (seemingly) more portable `=' syntax (e.g. older versions of Sun's `as' don't handle `.set')
Tassilo Philipp
parents:
192
diff
changeset
|
128 CALLVM_size = 12 |
91db39538e78
- replaced `.set' directives used to set symbol values in assembly files with (seemingly) more portable `=' syntax (e.g. older versions of Sun's `as' don't handle `.set')
Tassilo Philipp
parents:
192
diff
changeset
|
129 CALLVM_dataoff = 16 |
0 | 130 |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
131 .text |
0 | 132 .global dcCall_sparc |
133 dcCall_sparc: | |
134 | |
135 /* Basic Prolog: supports up to 6 arguments. */ | |
136 | |
137 /* o0-1: callvm,target */ | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
138 or %o0, %g0, %o3 /* %o3: callvm */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
139 or %o1, %g0, %o0 /* %o0: target */ |
0 | 140 ld [%o3+CALLVM_size], %o1 /* %o1: size */ |
141 add %o3, CALLVM_dataoff, %o2 /* %o2: data */ | |
142 /*o0-2:target,size,data*/ | |
143 | |
144 /*leaf functions: may use the first six output registers.*/ | |
145 /*o3-5:free to use */ | |
146 | |
154 | 147 /* Compute a matching stack size (approximate): o3 = align(92+o1,16) */ |
0 | 148 add %o1, (16+1+6)*REGSIZE+ALIGN-1, %o3 |
149 and %o3, -ALIGN, %o3 | |
150 neg %o3 | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
151 |
0 | 152 /* Prolog. */ |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
153 save %sp, %o3, %sp /* min stack size (16+1+6)*sizeof(ptr)=92 paddded to 8-byte alignment => min frame size of 96 bytes. */ |
0 | 154 |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
155 /* Load output registers. */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
156 ld [%i2 ],%o0 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
157 ld [%i2+REGSIZE*1 ],%o1 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
158 ld [%i2+REGSIZE*2 ],%o2 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
159 ld [%i2+REGSIZE*3 ],%o3 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
160 ld [%i2+REGSIZE*4 ],%o4 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
161 ld [%i2+REGSIZE*5 ],%o5 |
0 | 162 |
163 /* Copy on stack? */ | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
164 sub %i1, REGSIZE*6, %i1 /* i1 = decrement copy size by 6 regs (=6 regs x 4 bytes = 24 bytes total). */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
165 cmp %i1, 0 |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
166 ble .do_call |
0 | 167 nop |
168 | |
169 /* Copy loop: */ | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
170 add %i2, REGSIZE*6, %i2 /* i2 = address of 7th word of args buffer. */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
171 or %g0, %g0, %l0 /* l0 = offset initialized to 0. */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
172 add %sp, (16+1+6)*REGSIZE, %l2 /* l2 = argument area on stack space (7th word). (64+4+6*4 = byte offset 92). */ |
0 | 173 .next: |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
174 ld [%i2+%l0],%l1 /* Read from arg buffer(%i2) to %l1. */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
175 st %l1, [%l2+%l0] /* Write %l1 to stack space(%l2). */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
176 add %l0, REGSIZE, %l0 /* Increment offset. */ |
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
177 sub %i1, REGSIZE, %i1 /* Decrement copy size. */ |
0 | 178 cmp %i1, 0 |
179 bgt .next | |
180 nop | |
181 .do_call: | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
182 call %i0 /* Call target. */ |
0 | 183 nop |
154 | 184 or %o0, %g0, %i0 |
185 or %o1, %g0, %i1 | |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
186 jmpl %i7 + 8, %g0 /* optimized restore;retl;nop */ |
0 | 187 restore |
192
cf8134a20759
- b/c no preproc needed, changed some files from .S -> .s
Tassilo Philipp
parents:
179
diff
changeset
|
188 |