blob: 178cbb8ae1b9ea9ff1da7598a3dbff4b28efdb54 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* atomic.S: Move this stuff here for better ICACHE hit rates.
2 *
3 * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
4 */
5
Linus Torvalds1da177e2005-04-16 15:20:36 -07006#include <asm/ptrace.h>
7#include <asm/psr.h>
8
9 .text
10 .align 4
11
12 .globl __atomic_begin
13__atomic_begin:
14
15#ifndef CONFIG_SMP
16 .globl ___xchg32_sun4c
17___xchg32_sun4c:
18 rd %psr, %g3
19 andcc %g3, PSR_PIL, %g0
20 bne 1f
21 nop
22 wr %g3, PSR_PIL, %psr
23 nop; nop; nop
241:
25 andcc %g3, PSR_PIL, %g0
26 ld [%g1], %g7
27 bne 1f
28 st %g2, [%g1]
29 wr %g3, 0x0, %psr
30 nop; nop; nop
311:
32 mov %g7, %g2
33 jmpl %o7 + 8, %g0
34 mov %g4, %o7
35
36 .globl ___xchg32_sun4md
37___xchg32_sun4md:
38 swap [%g1], %g2
39 jmpl %o7 + 8, %g0
40 mov %g4, %o7
41#endif
42
43 /* Read asm-sparc/atomic.h carefully to understand how this works for SMP.
44 * Really, some things here for SMP are overly clever, go read the header.
45 */
46 .globl ___atomic24_add
47___atomic24_add:
48 rd %psr, %g3 ! Keep the code small, old way was stupid
49 nop; nop; nop; ! Let the bits set
50 or %g3, PSR_PIL, %g7 ! Disable interrupts
51 wr %g7, 0x0, %psr ! Set %psr
52 nop; nop; nop; ! Let the bits set
53#ifdef CONFIG_SMP
541: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
55 orcc %g7, 0x0, %g0 ! Did we get it?
56 bne 1b ! Nope...
57 ld [%g1], %g7 ! Load locked atomic24_t
58 sra %g7, 8, %g7 ! Get signed 24-bit integer
59 add %g7, %g2, %g2 ! Add in argument
60 sll %g2, 8, %g7 ! Transpose back to atomic24_t
61 st %g7, [%g1] ! Clever: This releases the lock as well.
62#else
63 ld [%g1], %g7 ! Load locked atomic24_t
64 add %g7, %g2, %g2 ! Add in argument
65 st %g2, [%g1] ! Store it back
66#endif
67 wr %g3, 0x0, %psr ! Restore original PSR_PIL
68 nop; nop; nop; ! Let the bits set
69 jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
70 mov %g4, %o7 ! Restore %o7
71
72 .globl ___atomic24_sub
73___atomic24_sub:
74 rd %psr, %g3 ! Keep the code small, old way was stupid
75 nop; nop; nop; ! Let the bits set
76 or %g3, PSR_PIL, %g7 ! Disable interrupts
77 wr %g7, 0x0, %psr ! Set %psr
78 nop; nop; nop; ! Let the bits set
79#ifdef CONFIG_SMP
801: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
81 orcc %g7, 0x0, %g0 ! Did we get it?
82 bne 1b ! Nope...
83 ld [%g1], %g7 ! Load locked atomic24_t
84 sra %g7, 8, %g7 ! Get signed 24-bit integer
85 sub %g7, %g2, %g2 ! Subtract argument
86 sll %g2, 8, %g7 ! Transpose back to atomic24_t
87 st %g7, [%g1] ! Clever: This releases the lock as well
88#else
89 ld [%g1], %g7 ! Load locked atomic24_t
90 sub %g7, %g2, %g2 ! Subtract argument
91 st %g2, [%g1] ! Store it back
92#endif
93 wr %g3, 0x0, %psr ! Restore original PSR_PIL
94 nop; nop; nop; ! Let the bits set
95 jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
96 mov %g4, %o7 ! Restore %o7
97
98 .globl __atomic_end
99__atomic_end: