comparison dyncall/dyncall_call_sparc.s @ 192:cf8134a20759

- b/c no preproc needed, changed some files from .S -> .s - some format/whitespace cleanup for readability, some declutter
author Tassilo Philipp
date Tue, 14 Mar 2017 14:14:47 +0100
parents dyncall/dyncall_call_sparc.S@b11b0735b09f
children 91db39538e78
comparison
equal deleted inserted replaced
191:2f7a7f3472cb 192:cf8134a20759
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
30 @@@ this should all go in manual
31
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);
50 %i0 , %i1 , %i2
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:
100 XX: should be 16 byte aligned (min stack frame size is 172).
101 168: on stack argument 6
102 136: input argument 0 spill
103 128: struct/union poiner return value
104 0: 16 registers save area
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
126 .set REGSIZE, 4
127 .set ALIGN, 16
128 .set CALLVM_size, 12
129 .set CALLVM_dataoff, 16
130
131 .text
132 .global dcCall_sparc
133 dcCall_sparc:
134
135 /* Basic Prolog: supports up to 6 arguments. */
136
137 /* o0-1: callvm,target */
138 or %o0, %g0, %o3 /* %o3: callvm */
139 or %o1, %g0, %o0 /* %o0: target */
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
147 /* Compute a matching stack size (approximate): o3 = align(92+o1,16) */
148 add %o1, (16+1+6)*REGSIZE+ALIGN-1, %o3
149 and %o3, -ALIGN, %o3
150 neg %o3
151
152 /* Prolog. */
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. */
154
155 /* Load output registers. */
156 ld [%i2 ],%o0
157 ld [%i2+REGSIZE*1 ],%o1
158 ld [%i2+REGSIZE*2 ],%o2
159 ld [%i2+REGSIZE*3 ],%o3
160 ld [%i2+REGSIZE*4 ],%o4
161 ld [%i2+REGSIZE*5 ],%o5
162
163 /* Copy on stack? */
164 sub %i1, REGSIZE*6, %i1 /* i1 = decrement copy size by 6 regs (=6 regs x 4 bytes = 24 bytes total). */
165 cmp %i1, 0
166 ble .do_call
167 nop
168
169 /* Copy loop: */
170 add %i2, REGSIZE*6, %i2 /* i2 = address of 7th word of args buffer. */
171 or %g0, %g0, %l0 /* l0 = offset initialized to 0. */
172 add %sp, (16+1+6)*REGSIZE, %l2 /* l2 = argument area on stack space (7th word). (64+4+6*4 = byte offset 92). */
173 .next:
174 ld [%i2+%l0],%l1 /* Read from arg buffer(%i2) to %l1. */
175 st %l1, [%l2+%l0] /* Write %l1 to stack space(%l2). */
176 add %l0, REGSIZE, %l0 /* Increment offset. */
177 sub %i1, REGSIZE, %i1 /* Decrement copy size. */
178 cmp %i1, 0
179 bgt .next
180 nop
181 .do_call:
182 call %i0 /* Call target. */
183 nop
184 or %o0, %g0, %i0
185 or %o1, %g0, %i1
186 jmpl %i7 + 8, %g0 /* optimized restore;retl;nop */
187 restore
188