1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* una_asm.S: Kernel unaligned trap assembler helpers. |
3 | * |
4 | * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net) |
5 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
6 | */ |
7 | |
8 | #include <linux/errno.h> |
9 | |
10 | .text |
11 | |
12 | retl_efault: |
13 | retl |
14 | mov -EFAULT, %o0 |
15 | |
16 | /* int __do_int_store(unsigned long *dst_addr, int size, |
17 | * unsigned long *src_val) |
18 | * |
19 | * %o0 = dest_addr |
20 | * %o1 = size |
21 | * %o2 = src_val |
22 | * |
23 | * Return '0' on success, -EFAULT on failure. |
24 | */ |
25 | .globl __do_int_store |
26 | __do_int_store: |
27 | ld [%o2], %g1 |
28 | cmp %o1, 2 |
29 | be 2f |
30 | cmp %o1, 4 |
31 | be 1f |
32 | srl %g1, 24, %g2 |
33 | srl %g1, 16, %g7 |
34 | 4: stb %g2, [%o0] |
35 | srl %g1, 8, %g2 |
36 | 5: stb %g7, [%o0 + 1] |
37 | ld [%o2 + 4], %g7 |
38 | 6: stb %g2, [%o0 + 2] |
39 | srl %g7, 24, %g2 |
40 | 7: stb %g1, [%o0 + 3] |
41 | srl %g7, 16, %g1 |
42 | 8: stb %g2, [%o0 + 4] |
43 | srl %g7, 8, %g2 |
44 | 9: stb %g1, [%o0 + 5] |
45 | 10: stb %g2, [%o0 + 6] |
46 | b 0f |
47 | 11: stb %g7, [%o0 + 7] |
48 | 1: srl %g1, 16, %g7 |
49 | 12: stb %g2, [%o0] |
50 | srl %g1, 8, %g2 |
51 | 13: stb %g7, [%o0 + 1] |
52 | 14: stb %g2, [%o0 + 2] |
53 | b 0f |
54 | 15: stb %g1, [%o0 + 3] |
55 | 2: srl %g1, 8, %g2 |
56 | 16: stb %g2, [%o0] |
57 | 17: stb %g1, [%o0 + 1] |
58 | 0: retl |
59 | mov 0, %o0 |
60 | |
61 | .section __ex_table,#alloc |
62 | .word 4b, retl_efault |
63 | .word 5b, retl_efault |
64 | .word 6b, retl_efault |
65 | .word 7b, retl_efault |
66 | .word 8b, retl_efault |
67 | .word 9b, retl_efault |
68 | .word 10b, retl_efault |
69 | .word 11b, retl_efault |
70 | .word 12b, retl_efault |
71 | .word 13b, retl_efault |
72 | .word 14b, retl_efault |
73 | .word 15b, retl_efault |
74 | .word 16b, retl_efault |
75 | .word 17b, retl_efault |
76 | .previous |
77 | |
78 | /* int do_int_load(unsigned long *dest_reg, int size, |
79 | * unsigned long *saddr, int is_signed) |
80 | * |
81 | * %o0 = dest_reg |
82 | * %o1 = size |
83 | * %o2 = saddr |
84 | * %o3 = is_signed |
85 | * |
86 | * Return '0' on success, -EFAULT on failure. |
87 | */ |
88 | .globl do_int_load |
89 | do_int_load: |
90 | cmp %o1, 8 |
91 | be 9f |
92 | cmp %o1, 4 |
93 | be 6f |
94 | 4: ldub [%o2], %g1 |
95 | 5: ldub [%o2 + 1], %g2 |
96 | sll %g1, 8, %g1 |
97 | tst %o3 |
98 | be 3f |
99 | or %g1, %g2, %g1 |
100 | sll %g1, 16, %g1 |
101 | sra %g1, 16, %g1 |
102 | 3: b 0f |
103 | st %g1, [%o0] |
104 | 6: ldub [%o2 + 1], %g2 |
105 | sll %g1, 24, %g1 |
106 | 7: ldub [%o2 + 2], %g7 |
107 | sll %g2, 16, %g2 |
108 | 8: ldub [%o2 + 3], %g3 |
109 | sll %g7, 8, %g7 |
110 | or %g3, %g2, %g3 |
111 | or %g7, %g3, %g7 |
112 | or %g1, %g7, %g1 |
113 | b 0f |
114 | st %g1, [%o0] |
115 | 9: ldub [%o2], %g1 |
116 | 10: ldub [%o2 + 1], %g2 |
117 | sll %g1, 24, %g1 |
118 | 11: ldub [%o2 + 2], %g7 |
119 | sll %g2, 16, %g2 |
120 | 12: ldub [%o2 + 3], %g3 |
121 | sll %g7, 8, %g7 |
122 | or %g1, %g2, %g1 |
123 | or %g7, %g3, %g7 |
124 | or %g1, %g7, %g7 |
125 | 13: ldub [%o2 + 4], %g1 |
126 | st %g7, [%o0] |
127 | 14: ldub [%o2 + 5], %g2 |
128 | sll %g1, 24, %g1 |
129 | 15: ldub [%o2 + 6], %g7 |
130 | sll %g2, 16, %g2 |
131 | 16: ldub [%o2 + 7], %g3 |
132 | sll %g7, 8, %g7 |
133 | or %g1, %g2, %g1 |
134 | or %g7, %g3, %g7 |
135 | or %g1, %g7, %g7 |
136 | st %g7, [%o0 + 4] |
137 | 0: retl |
138 | mov 0, %o0 |
139 | |
140 | .section __ex_table,#alloc |
141 | .word 4b, retl_efault |
142 | .word 5b, retl_efault |
143 | .word 6b, retl_efault |
144 | .word 7b, retl_efault |
145 | .word 8b, retl_efault |
146 | .word 9b, retl_efault |
147 | .word 10b, retl_efault |
148 | .word 11b, retl_efault |
149 | .word 12b, retl_efault |
150 | .word 13b, retl_efault |
151 | .word 14b, retl_efault |
152 | .word 15b, retl_efault |
153 | .word 16b, retl_efault |
154 | .previous |
155 | |