source: trunk/source/lisp-kernel/arm-asmutils.s

Last change on this file was 16765, checked in by gb, 3 years ago

Export some C-callabble functions rhat implement ARM memory barriers.
(could have used inline asm, but too lazy to rtfm.)

File size: 6.7 KB
Line 
1/*
2 * Copyright 1994-2009 Clozure Associates
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17        .syntax unified
18        .arm   
19
20        include(lisp.s)
21
22        _beginfile
23
24/* Force data from r0, size r1 into the icache */       
25_exportfn(C(flush_cache_lines))
26        __ifdef(`LINUX')
27        __(add r1,r1,r0)
28        __(mov r2,#0)           /* options.  Pass as 0 until we know better */
29        __(mov r12,r7)          /* preserve r7 ;  r12 saved by syscall */
30        __(mov r7,#0x0f0000)     /* __ARM_NR_cacheflush */
31        __(add r7,r7,#2)
32        __(svc #0)
33        __(mov r7,r12)
34        __endif
35        __ifdef(`DARWIN')
36        __(mov r3,#0)
37        __(mov r12,#0x80000000)
38        __(svc #0)
39        __endif   
40        __(bx lr)
41
42_exportfn(C(touch_page))
43        __(str r0,[r0,#0])
44        __(mov r1,#0)
45        __(str r1,[r0,#0])
46        __(mov r0,#1)
47        .globl C(touch_page_end)
48C(touch_page_end):     
49        __(bx lr)
50_endfn       
51                               
52_exportfn(C(current_stack_pointer))
53        __(mov r0,sp)
54        __(bx lr)
55_endfn
56       
57_exportfn(C(count_leading_zeros))
58        __(clz r0,r0)
59        __(bx lr)
60_endfn
61
62_exportfn(C(noop))
63        __(bx lr)
64_endfn
65
66
67
68
69
70/* Atomically store new value (r2) in *r0, if old value == expected (r1). */
71/* Return actual old value. */
72        .globl C(arm_architecture_version)
73_exportfn(C(store_conditional))
740:      __(ldrex r3,[r0])
75        __(cmp r3,r1)
76        __(bne 1f)
77        __(strex ip,r2,[r0])
78        __(cmp ip,#0)
79        __(bne 0b)
80        __(b 2f)
811:   
82        __(ldr r2,.L555)
83.LPIC0:
84        __(add r2,pc,r2)
85        __(ldr ip,.L555+4)
86        __(ldr ip,[r2,ip])
87        __(ldr ip,[ip])
88        __(cmp ip,#7)
89        __(blt 2f)
90        .long 0xf57ff01f
912:      __(mov r0,r3)
92        __(bx lr)   
93.L555:
94        .word _GLOBAL_OFFSET_TABLE_-(.LPIC0+8)
95        .word  C(arm_architecture_version)(GOT)
96
97                                                                                                                           
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121_endfn
122
123/* Atomically store new_value(r1) in *r0 ;  return previous contents */
124/* of *r0. */
125
126_exportfn(C(atomic_swap))
127        __(mov r2,r0)
1280:      __(ldrex r0,[r2])
129        __(strex r3,r1,[r2])
130        __(cmp r3,#0)
131        __(bne 0b)       
132        __(bx lr)
133_endfn
134
135_exportfn(C(atomic_swap_acquire))
136        __(mov r2,r0)
1370:      __(ldrex r0,[r2])
138        __(strex r3,r1,[r2])
139        __(cmp r3,#0)
140        __(wfene)
141        __(bne 0b)
142        __(dmb)       
143        __(bx lr)
144_endfn
145
146_exportfn(C(release_spin_lock))
147        __(mov r1,#0)
148        __(dmb)
149        __(str r1,[r0])
150        __(dsb)
151        __(sev)
152        __(bx lr)
153_endfn
154       
155
156/* Logior the value in *r0 with the value in r1 (presumably a bitmask with exactly 1 */
157/* bit set.)  Return non-zero if any of the bits in that bitmask were already set. */
158       
159_exportfn(C(atomic_ior))
160        __(stmdb sp!,{r4,lr})
1610:      __(ldrex r2,[r0])
162        __(orr r3,r2,r1)
163        __(strex r4,r3,[r0])
164        __(cmp r4,#0)
165        __(bne 0b)
166        __(mov r0,r2)
167        __(ldmia sp!,{r4,pc})
168_endfn
169
170
171/* Logand the value in *r0 with the value in r1 (presumably a bitmask with exactly 1 */
172/* bit set.)  Return the value now in *r0 (for some value of "now" */
173
174_exportfn(C(atomic_and))
1750:      __(ldrex r2,[r0])
176        __(and r2,r2,r1)
177        __(strex r3,r2,[r0])
178        __(cmp r3,#0)
179        __(bne 0b)
180        __(mov r0,r2)
181        __(bx lr)
182_endfn
183               
184       
185        __ifdef(`DARWIN')
186_exportfn(C(enable_fp_exceptions))
187        __(.long 0)
188        __(bx lr)
189_endfn
190       
191_exportfn(C(disable_fp_exceptions))
192        __(.long 0)
193        __(bx lr)
194_endfn
195
196_exportfn(C(pseudo_sigreturn))
197        __(uuo_pseudo_sigreturn())
198        __(b C(pseudo_sigreturn))
199_endfn
200        __endif
201       
202_exportfn(C(save_fp_context))
203        __(uuo_debug_trap(al))
204_endfn         
205_exportfn(C(restore_fp_context))
206        __(uuo_debug_trap(al))
207_endfn         
208_exportfn(C(put_vector_registers))
209        __(uuo_debug_trap(al))
210_endfn         
211_exportfn(C(get_vector_registers))
212        __(uuo_debug_trap(al))
213_endfn
214       
215        __ifdef(`ANDROID')
216_exportfn(rt_sigprocmask)
217        __(stmdb sp!,{r7,lr})
218        __(mov r7,#175)
219        __(svc #0)
220        __(ldmia sp!,{r7,pc})
221_endfn
222        __endif
223       
224
225        __ifdef(`DARWIN')
226/* divide the 64-bit unsigned integer in r0/r1 by the 64-bit unsigned
227   integer in r2/r3; return the 64-bit quotient in r0/r1 and the 64-bit
228   remainder in r2/r3.  Implement this in terms of the libgcc function: 
229
230   unsigned long long __udivti3 (unsigned long long a, 
231                                 unsigned long long b, 
232                                 unsigned long long *c)
233*/       
234_exportfn(C(__aeabi_uldivmod))
235        __(stmdb sp!,{r7,lr})
236        __(mov r7,sp)
237        __(sub sp,sp,#8)
238        __(mov ip,sp)
239        __(push1(ip,sp))
240        __(push1(ip,sp))
241        __(bl C(__udivmoddi4))
242        __(add sp,sp,#8)
243        __(ldmia sp!,{r2,r3})
244        __(ldmia sp!,{r7,pc})
245_endfn               
246        __endif
247
248_exportfn(call_handler_on_main_stack)
249        __(ldr ip,[sp])
250        __(mov lr,r3)
251        __(mov sp,r1)
252        __(bx ip)
253_endfn               
254
255/* zero N (r1) dnodes, starting at the dnode-aligned address in r0 */
256_exportfn(C(zero_dnodes))
257        __(adr r2,9f)
258        __(fldmiad r2,{d0-d7})
259        __(ands r2,r1,#7)
260        __(sub r1,r1,r2)
261        __(b 1f)
2620:      __(subs r2,r2,#1)       
263        __(fstd d0,[r0])
264        __(add r0,r0,#dnode_size)
2651:      __(bne 0b)
266        __(cmp r1,#0)
267        __(b 3f)
2682:      __(subs r1,r1,#8)
269        __(fstmiad r0!,{d0-d7})
2703:      __(bne 2b)
271        __(bx lr)
272        .align 3
2739:      .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
274_endfn             
275
276_exportfn(C(dmb))
277        __(dmb)
278        __(bx lr)
279_endfn
280       
281_exportfn(C(dsb))
282        __(dsb)
283        __(bx lr)
284_endfn
285_exportfn(C(isb))
286        __(isb)
287        __(bx lr)
288_endfn       
289       
290               
291                           
292_exportfn(C(feature_check))
293        .globl C(feature_check_ldrex)
294        .globl C(feature_check_clrex)
295        .globl C(feature_check_fpu)
296C(feature_check_fpu):           
297        __(fcmpd d15,d15)
298C(feature_check_ldrex): 
299        __(ldrex r2,[sp])
300C(feature_check_clrex):         
301        __(.long 0xf57ff01f)    /* clrex */
302        __(bx lr)
303_endfn       
304        _endfile
305
Note: See TracBrowser for help on using the repository browser.