1/*        $NetBSD: pio_subr.S,v 1.18 2020/07/06 10:31:24 rin Exp $    */
2
3/*
4 * Copyright (c) 2003 Matt Thomas
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#ifdef _KERNEL_OPT
32#include "opt_ppcarch.h"
33#endif
34
35/*
36 * Assembly note:
37 *        We use rotlw instead of slw because rotlw ignores bit 26 and slw
38 *        doesn't.  However, this may make the high bits of the offset rotate
39 *        in the low bits but if that happens then the offset was too large
40 *        to being with.
41 */
42#ifdef DEBUG
43#define   DBGSYNC   sync
44#else
45#define   DBGSYNC   /* nothing */
46#endif
47
48#undef DBGSYNC
49#if defined(PPC_IBM4XX) && !defined(PPC_IBM440)
50#define   DBGSYNC /* nothing; eieio is implemented as sync */
51#else
52#define   DBGSYNC   msync
53#endif
54#define   eieio     mbar 0
55
56/* LINTSTUB: include <sys/param.h> */
57/* LINTSTUB: include <sys/types.h> */
58/* LINTSTUB: include <sys/bus.h> */
59
60/* LINTSTUB: Func: void out8(volatile u_int8_t *a, u_int8_t v) */
61
62ENTRY(out8)
63          stbx      %r4,0,%r3
64          eieio                         /* memory barrier (reorder protection) */
65          DBGSYNC                       /* force exceptions */
66          blr                           /* return */
67
68/* LINTSTUB: Func: void bsw1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v) */
69/* LINTSTUB: Func: void bsw1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v) */
70
71ENTRY(bsw1_s)
72          lwz       %r0,0(%r3)          /* get log2(stride) */
73          rotlw     %r5,%r5,%r0         /* shift offset */
74ENTRY(bsw1)
75          stbx      %r6,%r4,%r5         /* store value */
76          eieio                         /* memory barrier (reorder protection) */
77          DBGSYNC                       /* force exceptions */
78          blr                           /* return */
79
80/* LINTSTUB: Func: void out16(volatile u_int16_t *a, u_int16_t v) */
81
82ENTRY(out16)
83          sth       %r4,0(%r3)
84          eieio                         /* memory barrier (reorder protection) */
85          DBGSYNC                       /* force exceptions */
86          blr                           /* return */
87
88/* LINTSTUB: Func: void bsw2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v) */
89/* LINTSTUB: Func: void bsw2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v) */
90
91ENTRY(bsw2_s)
92          lwz       %r0,0(%r3)          /* get log2(stride) */
93          rotlw     %r5,%r5,%r0         /* shift offset */
94ENTRY(bsw2)
95          sthx      %r6,%r4,%r5         /* store value */
96          eieio                         /* memory barrier (reorder protection) */
97          DBGSYNC                       /* force exceptions */
98          blr                           /* return */
99
100/* LINTSTUB: Func: void out32(volatile u_int32_t *a, u_int32_t v) */
101
102ENTRY(out32)
103          stw       %r4,0(%r3)
104          eieio                         /* memory barrier (reorder protection) */
105          DBGSYNC                       /* force exceptions */
106          blr                           /* return */
107
108/* LINTSTUB: Func: void bsw4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v) */
109/* LINTSTUB: Func: void bsw4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v) */
110
111ENTRY(bsw4_s)
112          lwz       %r0,0(%r3)          /* get log2(stride) */
113          rotlw     %r5,%r5,%r0         /* shift offset */
114ENTRY(bsw4)
115          stwx      %r6,%r4,%r5         /* store value */
116          eieio                         /* memory barrier (reorder protection) */
117          DBGSYNC                       /* force exceptions */
118          blr                           /* return */
119
120/* LINTSTUB: Func: void bsw8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v) */
121/* LINTSTUB: Func: void bsw8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v) */
122ENTRY(bsw8_s)
123          lwz       %r0,0(%r3)          /* get log2(stride) */
124          rotlw     %r5,%r5,%r0         /* shift offset */
125ENTRY(bsw8)
126#ifdef __ARCH64__
127          stdx      %r6,%r4,%r5         /* store value */
128#else
129          trap                          /* die */
130#endif
131          eieio                         /* memory barrier (reorder protection) */
132          DBGSYNC                       /* force exceptions */
133          blr                           /* return */
134
135/* LINTSTUB: Func: void out16rb(volatile u_int16_t *a, u_int16_t v) */
136
137ENTRY(out16rb)
138          sthbrx    %r4,0,%r3
139          eieio                         /* memory barrier (reorder protection) */
140          DBGSYNC                       /* force exceptions */
141          blr                           /* return */
142
143/* LINTSTUB: Func: void bsw2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v) */
144/* LINTSTUB: Func: void bsw2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v) */
145
146
147ENTRY(bsw2rb_s)
148          lwz       %r0,0(%r3)          /* get log2(stride) */
149          rotlw     %r5,%r5,%r0         /* shift offset */
150ENTRY(bsw2rb)
151          sthbrx    %r6,%r4,%r5         /* store value */
152          eieio                         /* memory barrier (reorder protection) */
153          DBGSYNC                       /* force exceptions */
154          blr                           /* return */
155
156/* LINTSTUB: Func: void out32rb(volatile u_int32_t *a, u_int32_t v) */
157
158ENTRY(out32rb)
159          stwbrx    %r4,0,%r3
160          eieio                         /* memory barrier (reorder protection) */
161          DBGSYNC                       /* force exceptions */
162          blr                           /* return */
163
164/* LINTSTUB: Func: void bsw4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v) */
165/* LINTSTUB: Func: void bsw4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v) */
166
167ENTRY(bsw4rb_s)
168          lwz       %r0,0(%r3)          /* get log2(stride) */
169          rotlw     %r5,%r5,%r0         /* shift offset */
170ENTRY(bsw4rb)
171          stwbrx    %r6,%r4,%r5         /* store value */
172          eieio                         /* memory barrier (reorder protection) */
173          DBGSYNC                       /* force exceptions */
174          blr                           /* return */
175
176/* LINTSTUB: Func: void bsw8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v) */
177/* LINTSTUB: Func: void bsw8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v) */
178
179ENTRY(bsw8rb_s)
180          lwz       %r0,0(%r3)          /* get log2(stride) */
181          rotlw     %r5,%r5,%r0         /* shift offset */
182ENTRY(bsw8rb)
183#ifdef __ARCH64__
184          stdbrx    %r6,%r4,%r5         /* store value */
185#else
186          trap                          /* die */
187#endif
188          eieio                         /* memory barrier (reorder protection) */
189          DBGSYNC                       /* force exceptions */
190          blr                           /* return */
191
192/* LINTSTUB: Func: int in8(const volatile u_int8_t *a) */
193
194ENTRY(in8)
195          lbz       %r3,0(%r3)
196          eieio                         /* memory barrier (reorder protection) */
197          DBGSYNC                       /* force exceptions */
198          blr                           /* return */
199
200/* LINTSTUB: Func: int bsr1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
201/* LINTSTUB: Func: int bsr1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
202
203ENTRY(bsr1_s)
204          lwz       %r0,0(%r3)          /* get log2(stride) */
205          rotlw     %r5,%r5,%r0         /* shift offset */
206ENTRY(bsr1)
207          lbzx      %r3,%r4,%r5         /* load value */
208          eieio                         /* memory barrier (reorder protection) */
209          DBGSYNC                       /* force exceptions */
210          blr                           /* return */
211
212/* LINTSTUB: Func: int in16(const volatile u_int16_t *a) */
213
214ENTRY(in16)
215          lhz       %r3,0(%r3)
216          eieio                         /* memory barrier (reorder protection) */
217          DBGSYNC                       /* force exceptions */
218          blr                           /* return */
219
220/* LINTSTUB: Func: int bsr2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
221/* LINTSTUB: Func: int bsr2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
222
223ENTRY(bsr2_s)
224          lwz       %r0,0(%r3)          /* get log2(stride) */
225          rotlw     %r5,%r5,%r0         /* shift offset */
226ENTRY(bsr2)
227          lhzx      %r3,%r4,%r5         /* load value */
228          eieio                         /* memory barrier (reorder protection) */
229          DBGSYNC                       /* force exceptions */
230          blr                           /* return */
231
232/* LINTSTUB: Func: int in32(const volatile u_int32_t *a) */
233
234ENTRY(in32)
235          lwz       %r3,0(%r3)
236          eieio                         /* memory barrier (reorder protection) */
237          DBGSYNC                       /* force exceptions */
238          blr                           /* return */
239
240/* LINTSTUB: Func: int bsr4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
241/* LINTSTUB: Func: int bsr4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
242
243ENTRY(bsr4_s)
244          lwz       %r0,0(%r3)          /* get log2(stride) */
245          rotlw     %r5,%r5,%r0         /* shift offset */
246ENTRY(bsr4)
247          lwzx      %r3,%r4,%r5         /* load value */
248          eieio                         /* memory barrier (reorder protection) */
249          DBGSYNC                       /* force exceptions */
250          blr                           /* return */
251
252/* LINTSTUB: Func: u_int64_t bsr8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
253/* LINTSTUB: Func: u_int64_t bsr8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
254
255ENTRY(bsr8_s)
256          lwz       %r0,0(%r3)          /* get log2(stride) */
257          rotlw     %r5,%r5,%r0         /* shift offset */
258ENTRY(bsr8)
259#ifdef __ARCH64__
260          lwdx      %r3,%r4,%r5         /* load value */
261#else
262          trap
263#endif
264          eieio                         /* memory barrier (reorder protection) */
265          DBGSYNC                       /* force exceptions */
266          blr                           /* return */
267
268/* LINTSTUB: Func: int in16rb(const volatile u_int16_t *a) */
269
270ENTRY(in16rb)
271          lhbrx     %r3,0,%r3
272          eieio                         /* memory barrier (reorder protection) */
273          DBGSYNC                       /* force exceptions */
274          blr                           /* return */
275
276/* LINTSTUB: Func: int bsr2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
277/* LINTSTUB: Func: int bsr2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
278
279ENTRY(bsr2rb_s)
280          lwz       %r0,0(%r3)          /* get log2(stride) */
281          rotlw     %r5,%r5,%r0         /* shift offset */
282ENTRY(bsr2rb)
283          lhbrx     %r3,%r4,%r5         /* load value */
284          eieio                         /* memory barrier (reorder protection) */
285          DBGSYNC                       /* force exceptions */
286          blr                           /* return */
287
288/* LINTSTUB: Func: int in32rb(const volatile u_int32_t *a) */
289
290ENTRY(in32rb)
291          lwbrx     %r3,0,%r3
292          eieio                         /* memory barrier (reorder protection) */
293          DBGSYNC                       /* force exceptions */
294          blr                           /* return */
295
296/* LINTSTUB: Func: int bsr4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
297/* LINTSTUB: Func: int bsr4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
298
299ENTRY(bsr4rb_s)
300          lwz       %r0,0(%r3)          /* get log2(stride) */
301          rotlw     %r5,%r5,%r0         /* shift offset */
302ENTRY(bsr4rb)
303          lwbrx     %r3,%r4,%r5         /* load value */
304          eieio                         /* memory barrier (reorder protection) */
305          DBGSYNC                       /* force exceptions */
306          blr                           /* return */
307
308/* LINTSTUB: Func: u_int64_t bsr8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
309/* LINTSTUB: Func: u_int64_t bsr8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) */
310
311ENTRY(bsr8rb_s)
312          lwz       %r0,0(%r3)          /* get log2(stride) */
313          rotlw     %r5,%r5,%r0         /* shift offset */
314ENTRY(bsr8rb)
315#ifdef __ARCH64__
316          ldbrx     %r3,%r4,%r5         /* load value */
317#else
318          trap
319#endif
320          eieio                         /* memory barrier (reorder protection) */
321          DBGSYNC                       /* force exceptions */
322          blr                           /* return */
323
324/* LINTSTUB: Func: void bswm1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int8_t *addr, bus_size_t len) */
325/* LINTSTUB: Func: void bswm1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int8_t *addr, bus_size_t len) */
326/* LINTSTUB: Func: void outs8(volatile u_int8_t *dst, const u_int8_t *src, size_t len) */
327
328ENTRY(bswm1_s)
329          lwz       %r0,0(%r3)          /* get log2(stride) */
330          rotlw     %r5,%r5,%r0         /* shift offset */
331ENTRY(bswm1)
332          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
333          mr        %r4,%r6             /* move addr to argument 1 register */
334          mr        %r5,%r7             /* move count to argument 2 register */
335ENTRY(outs8)
336          cmpwi     %r5,0               /* len == 0? */
337          beqlr-                        /*   return if len == 0 */
338          addi      %r5,%r5,-1          /* len -= 1 */
339          add       %r5,%r5,%r4         /* len += src */
340          addi      %r4,%r4,-1          /* pre-decrement */
3411:        lbzu      %r0,1(%r4)          /* load and increment */
342          stb       %r0,0(%r3)          /* store */
343          cmplw     %r4,%r5             /* at the end? */
344          bne+      1b                  /*   nope, do another pass */
345          eieio                         /* memory barrier (reorder protection) */
346          DBGSYNC                       /* force exceptions */
347          blr                           /* return */
348
349/* LINTSTUB: Func: void bswm2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *addr, bus_size_t len) */
350/* LINTSTUB: Func: void bswm2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *addr, bus_size_t len) */
351/* LINTSTUB: Func: void outs16(volatile u_int16_t *dst, const u_int16_t *src, size_t len) */
352
353ENTRY(bswm2_s)
354          lwz       %r0,0(%r3)          /* get log2(stride) */
355          rotlw     %r5,%r5,%r0         /* shift offset */
356ENTRY(bswm2)
357          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
358          mr        %r4,%r6             /* move addr to argument 1 register */
359          mr        %r5,%r7             /* move count to argument 2 register */
360ENTRY(outs16)
361          cmpwi     %r5,0               /* len == 0? */
362          beqlr-                        /*   return if len == 0 */
363          addi      %r5,%r5,-1          /* len -= 1 */
364          slwi      %r5,%r5,1 /* len *= 2 */
365          add       %r5,%r5,%r4         /* len += src */
366          addi      %r4,%r4,-2          /* pre-decrement */
3671:        lhzu      %r0,2(%r4)          /* load and increment */
368          sth       %r0,0(%r3)          /* store */
369          cmplw     %r4,%r5             /* at the end? */
370          bne+      1b                  /*   nope, do another pass */
371          eieio                         /* memory barrier (reorder protection) */
372          DBGSYNC                       /* force exceptions */
373          blr                           /* return */
374
375/* LINTSTUB: Func: void bswm4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *addr, bus_size_t len) */
376/* LINTSTUB: Func: void bswm4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *addr, bus_size_t len) */
377/* LINTSTUB: Func: void outs32(volatile u_int32_t *dst, const u_int32_t *src, size_t len) */
378
379ENTRY(bswm4_s)
380          lwz       %r0,0(%r3)          /* get log2(stride) */
381          rotlw     %r5,%r5,%r0         /* shift offset */
382ENTRY(bswm4)
383          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
384          mr        %r4,%r6             /* move addr to argument 1 register */
385          mr        %r5,%r7             /* move count to argument 2 register */
386ENTRY(outs32)
387          cmpwi     %r5,0               /* len == 0? */
388          beqlr-                        /*   return if len == 0 */
389          addi      %r5,%r5,-1          /* len -= 1 */
390          slwi      %r5,%r5,2 /* len *= 4 */
391          add       %r5,%r5,%r4         /* len += src */
392          addi      %r4,%r4,-4          /* pre-decrement */
3931:        lwzu      %r0,4(%r4)          /* load and increment */
394          stw       %r0,0(%r3)          /* store */
395          cmplw     %r4,%r5             /* at the end? */
396          bne+      1b                  /*   nope, do another pass */
397          eieio                         /* memory barrier (reorder protection) */
398          DBGSYNC                       /* force exceptions */
399          blr                           /* return */
400
401/* LINTSTUB: Func: void bswm8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *addr, bus_size_t len) */
402/* LINTSTUB: Func: void bswm8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *addr, bus_size_t len) */
403
404#ifdef _LP64
405ENTRY(bswm8_s)
406          ld        %r0,0(%r3)          /* get log2(stride) */
407          rotld     %r5,%r5,%r0         /* shift offset */
408ENTRY(bswm8)
409          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
410          mr        %r4,%r6             /* move addr to argument 1 register */
411          mr        %r5,%r7             /* move count to argument 2 register */
412ENTRY(outs64)
413          cmpdi     %r5,0               /* len == 0? */
414          beqlr-                        /*   return if len == 0 */
415          addi      %r5,%r5,-1          /* len -= 1 */
416          sldi      %r5,%r5,2 /* len *= 4 */
417          add       %r5,%r5,%r4         /* len += src */
418          addi      %r4,%r4,-4          /* pre-decrement */
4191:        ldu       %r0,4(%r4)          /* load and increment */
420          std       %r0,0(%r3)          /* store */
421          cmplw     %r4,%r5             /* at the end? */
422          bne+      1b                  /*   nope, do another pass */
423          eieio                         /* memory barrier (reorder protection) */
424          DBGSYNC                       /* force exceptions */
425          blr                           /* return */
426#else
427ENTRY(bswm8_s)
428ENTRY(bswm8)
429          trap                          /* die */
430#endif
431
432/* LINTSTUB: Func: void bswm2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *addr, bus_size_t len) */
433/* LINTSTUB: Func: void bswm2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *addr, bus_size_t len) */
434/* LINTSTUB: Func: void outs16rb(volatile u_int16_t *dst, const u_int16_t *src, size_t len) */
435
436ENTRY(bswm2rb_s)
437          lwz       %r0,0(%r3)          /* get log2(stride) */
438          rotlw     %r5,%r5,%r0         /* shift offset */
439ENTRY(bswm2rb)
440          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
441          mr        %r4,%r6             /* move addr to argument 1 register */
442          mr        %r5,%r7             /* move count to argument 2 register */
443ENTRY(outs16rb)
444          cmpwi     %r5,0               /* len == 0? */
445          beqlr-                        /*   return if len == 0 */
446          addi      %r5,%r5,-1          /* len -= 1 */
447          slwi      %r5,%r5,1 /* len *= 2 */
448          add       %r5,%r5,%r4         /* len += src */
449          addi      %r4,%r4,-2          /* pre-decrement */
4501:        lwzu      %r0,2(%r4)          /* load and increment */
451          sthbrx    %r0,0,%r3 /* store (byte-reversed) */
452          cmplw     %r4,%r5             /* at the end? */
453          bne+      1b                  /*   nope, do another pass */
454          eieio                         /* memory barrier (reorder protection) */
455          DBGSYNC                       /* force exceptions */
456          blr                           /* return */
457
458/* LINTSTUB: Func: void bswm4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *addr, bus_size_t len) */
459/* LINTSTUB: Func: void bswm4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *addr, bus_size_t len) */
460/* LINTSTUB: Func: void outs32rb(volatile u_int32_t *dst, const u_int32_t *src, size_t len) */
461
462ENTRY(bswm4rb_s)
463          lwz       %r0,0(%r3)          /* get log2(stride) */
464          rotlw     %r5,%r5,%r0         /* shift offset */
465ENTRY(bswm4rb)
466          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
467          mr        %r4,%r6             /* move addr to argument 1 register */
468          mr        %r5,%r7             /* move count to argument 2 register */
469ENTRY(outs32rb)
470          cmpwi     %r5,0               /* len == 0? */
471          beqlr-                        /*   return if len == 0 */
472          addi      %r5,%r5,-1          /* len -= 1 */
473          slwi      %r5,%r5,2 /* len *= 4 */
474          add       %r5,%r5,%r4         /* len += src */
475          addi      %r4,%r4,-4          /* pre-decrement */
4761:        lwzu      %r0,4(%r4)          /* load and increment */
477          stwbrx    %r0,0,%r3 /* store (byte-reversed) */
478          cmplw     %r4,%r5             /* at the end? */
479          bne+      1b                  /*   nope, do another pass */
480          eieio                         /* memory barrier (reorder protection) */
481          DBGSYNC                       /* force exceptions */
482          blr                           /* return */
483
484/* LINTSTUB: Func: void bswm8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *addr, bus_size_t len) */
485/* LINTSTUB: Func: void bswm8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *addr, bus_size_t len) */
486ENTRY(bswm8rb_s)
487ENTRY(bswm8rb)
488          trap
489
490/* LINTSTUB: Func: void bsrm1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t *addr, bus_size_t len) */
491/* LINTSTUB: Func: void bsrm1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t *addr, bus_size_t len) */
492/* LINTSTUB: Func: void ins8(const volatile u_int8_t *src, u_int8_t *dst, size_t len) */
493
494ENTRY(bsrm1_s)
495          lwz       %r0,0(%r3)          /* get log2(stride) */
496          rotlw     %r5,%r5,%r0         /* shift offset */
497ENTRY(bsrm1)
498          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
499          mr        %r4,%r6             /* move addr to argument 1 register */
500          mr        %r5,%r7             /* move count to argument 2 register */
501ENTRY(ins8)
502          cmpwi     %r5,0               /* len == 0? */
503          beqlr-                        /*   return if len == 0 */
504          addi      %r5,%r5,-1          /* len -= 1 */
505          add       %r5,%r5,%r4         /* len += src */
506          addi      %r4,%r4,-1          /* pre-decrement */
5071:        lbz       %r0,0(%r3)          /* load value */
508          stbu      %r0,1(%r4)          /* store and increment */
509          cmplw     %r4,%r5             /* at the end? */
510          bne+      1b                  /*   nope, do another pass */
511          eieio                         /* memory barrier (reorder protection) */
512          DBGSYNC                       /* force exceptions */
513          blr                           /* return */
514
515/* LINTSTUB: Func: void bsrm2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *addr, bus_size_t len) */
516/* LINTSTUB: Func: void bsrm2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *addr, bus_size_t len) */
517/* LINTSTUB: Func: void ins16(const volatile u_int16_t *src, u_int16_t *dst, size_t len) */
518
519ENTRY(bsrm2_s)
520          lwz       %r0,0(%r3)          /* get log2(stride) */
521          rotlw     %r5,%r5,%r0         /* shift offset */
522ENTRY(bsrm2)
523          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
524          mr        %r4,%r6             /* move addr to argument 1 register */
525          mr        %r5,%r7             /* move count to argument 2 register */
526ENTRY(ins16)
527          cmpwi     %r5,0               /* len == 0? */
528          beqlr-                        /*   return if len == 0 */
529          addi      %r5,%r5,-1          /* len -= 1 */
530          slwi      %r5,%r5,1 /* len *= 2 */
531          add       %r5,%r5,%r4         /* len += src */
532          addi      %r4,%r4,-2          /* pre-decrement */
5331:        lhz       %r0,0(%r3)          /* load value */
534          sthu      %r0,2(%r4)          /* store and increment */
535          cmplw     %r4,%r5             /* at the end? */
536          bne+      1b                  /*   nope, do another pass */
537          eieio                         /* memory barrier (reorder protection) */
538          DBGSYNC                       /* force exceptions */
539          blr                           /* return */
540
541/* LINTSTUB: Func: void bsrm4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *addr, bus_size_t len) */
542/* LINTSTUB: Func: void bsrm4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *addr, bus_size_t len) */
543/* LINTSTUB: Func: void ins32(const volatile u_int32_t *src, u_int32_t *dst, size_t len) */
544
545ENTRY(bsrm4_s)
546          lwz       %r0,0(%r3)          /* get log2(stride) */
547          rotlw     %r5,%r5,%r0         /* shift offset */
548ENTRY(bsrm4)
549          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
550          mr        %r4,%r6             /* move addr to argument 1 register */
551          mr        %r5,%r7             /* move count to argument 2 register */
552ENTRY(ins32)
553          cmpwi     %r5,0               /* len == 0? */
554          beqlr-                        /*   return if len == 0 */
555          addi      %r5,%r5,-1          /* len -= 1 */
556          slwi      %r5,%r5,2 /* len *= 4 */
557          add       %r5,%r5,%r4         /* len += src */
558          addi      %r4,%r4,-4          /* pre-decrement */
5591:        lwz       %r0,0(%r3)          /* load value */
560          stwu      %r0,4(%r4)          /* store and increment */
561          cmplw     %r4,%r5             /* at the end? */
562          bne+      1b                  /*   nope, do another pass */
563          eieio                         /* memory barrier (reorder protection) */
564          DBGSYNC                       /* force exceptions */
565          blr                           /* return */
566
567/* LINTSTUB: Func: void bsrm8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *addr, bus_size_t len) */
568/* LINTSTUB: Func: void bsrm8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *addr, bus_size_t len) */
569ENTRY(bsrm8_s)
570ENTRY(bsrm8)
571          trap
572
573/* LINTSTUB: Func: void bsrm2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *addr, bus_size_t len) */
574/* LINTSTUB: Func: void ins16rb(const volatile u_int16_t *src, u_int16_t *dst, size_t len) */
575
576ENTRY(bsrm2rb_s)
577          lwz       %r0,0(%r3)          /* get log2(stride) */
578          rotlw     %r5,%r5,%r0         /* shift offset */
579ENTRY(bsrm2rb)
580          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
581          mr        %r4,%r6             /* move addr to argument 1 register */
582          mr        %r5,%r7             /* move count to argument 2 register */
583ENTRY(ins16rb)
584          cmpwi     %r5,0               /* len == 0? */
585          beqlr-                        /*   return if len == 0 */
586          addi      %r5,%r5,-1          /* len -= 1 */
587          slwi      %r5,%r5,1 /* len *= 2 */
588          add       %r5,%r5,%r4         /* len += src */
589          addi      %r4,%r4,-2          /* pre-decrement */
5901:        lhbrx     %r0,0,%r3 /* load value (byte reversed) */
591          sthu      %r0,2(%r4)          /* store and increment */
592          cmplw     %r4,%r5             /* at the end? */
593          bne+      1b                  /*   nope, do another pass */
594          eieio                         /* memory barrier (reorder protection) */
595          DBGSYNC                       /* force exceptions */
596          blr                           /* return */
597
598/* LINTSTUB: Func: void bsrm4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *addr, bus_size_t len) */
599/* LINTSTUB: Func: void bsrm4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *addr, bus_size_t len) */
600/* LINTSTUB: Func: void ins32rb(const volatile u_int32_t *src, u_int32_t *dst, size_t len) */
601ENTRY(bsrm4rb_s)
602          lwz       %r0,0(%r3)          /* get log2(stride) */
603          rotlw     %r5,%r5,%r0         /* shift offset */
604ENTRY(bsrm4rb)
605          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
606          mr        %r4,%r6             /* move addr to argument 1 register */
607          mr        %r5,%r7             /* move count to argument 2 register */
608ENTRY(ins32rb)
609          cmpwi     %r5,0               /* len == 0? */
610          beqlr-                        /*   return if len == 0 */
611          addi      %r5,%r5,-1          /* len -= 1 */
612          slwi      %r5,%r5,2 /* len *= 4 */
613          add       %r5,%r5,%r4         /* len += src */
614          addi      %r4,%r4,-4          /* pre-decrement */
6151:        lwbrx     %r0,0,%r3 /* load value (byte reversed) */
616          stwu      %r0,4(%r4)          /* store and increment */
617          cmplw     %r4,%r5             /* at the end? */
618          bne+      1b                  /*   nope, do another pass */
619          eieio                         /* memory barrier (reorder protection) */
620          DBGSYNC                       /* force exceptions */
621          blr                           /* return */
622
623/* LINTSTUB: Func: void bsrm8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *addr, bus_size_t len) */
624/* LINTSTUB: Func: void bsrm8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *addr, bus_size_t len) */
625ENTRY(bsrm8rb_s)
626ENTRY(bsrm8rb)
627          trap
628
629/* LINTSTUB: Func: void bswr1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c); */
630/* LINTSTUB: Func: void bswr1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c); */
631ENTRY(bswr1_s)
632          lwz       %r0,0(%r3)          /* get log2(stride) */
633          li        %r8,1               /* distance between dst bytes */
634          rotlw     %r5,%r5,%r0         /* shift offset */
635          rotlw     %r8,%r8,%r0         /* shift distance */
636          b         .Lbswr1_enter
637ENTRY(bswr1)
638          li        %r8,1               /* distance between dst bytes */
639.Lbswr1_enter:
640          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
641          cmpwi     %r7,0               /* len == 0? */
642          beqlr-                        /*   return if len == 0 */
643          addi      %r7,%r7,-1          /* len -= 1 */
644          add       %r7,%r7,%r6         /* len += src */
645          addi      %r6,%r6,-1          /* pre-decrement */
646          sub       %r3,%r3,%r8
6471:        lbzu      %r0,1(%r6)          /* load and increment */
648          stbux     %r0,%r3,%r8         /* store and add distance */
649          cmplw     %r6,%r7             /* at the end? */
650          bne+      1b                  /*   nope, do another pass */
651          eieio                         /* memory barrier (reorder protection) */
652          DBGSYNC                       /* force exceptions */
653          blr                           /* return */
654
655/* LINTSTUB: Func: void bswr2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c); */
656/* LINTSTUB: Func: void bswr2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c); */
657ENTRY(bswr2_s)
658          lwz       %r0,0(%r3)          /* get log2(stride) */
659          li        %r8,2               /* distance between dst halfwords */
660          rotlw     %r5,%r5,%r0         /* shift offset */
661          rotlw     %r8,%r8,%r0         /* shift distance */
662          b         .Lbswr2_enter
663ENTRY(bswr2)
664          li        %r8,2               /* distance between dst halfwords */
665.Lbswr2_enter:
666          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
667          cmpwi     %r7,0               /* len == 0? */
668          beqlr-                        /*   return if len == 0 */
669          addi      %r7,%r7,-1          /* len -= 1 */
670          slwi      %r7,%r7,1 /* len *= 2 */
671          add       %r7,%r7,%r6         /* len += src */
672          addi      %r6,%r6,-2          /* pre-decrement */
673          sub       %r3,%r3,%r8
6741:        lhzu      %r0,2(%r6)          /* load and increment */
675          sthux     %r0,%r3,%r8         /* store and add distance */
676          cmplw     %r6,%r7             /* at the end? */
677          bne+      1b                  /*   nope, do another pass */
678          eieio                         /* memory barrier (reorder protection) */
679          DBGSYNC                       /* force exceptions */
680          blr                           /* return */
681
682/* LINTSTUB: Func: void bswr2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c); */
683/* LINTSTUB: Func: void bswr2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c); */
684ENTRY(bswr2rb_s)
685          lwz       %r0,0(%r3)          /* get log2(stride) */
686          li        %r8,2               /* distance between dst halfwords */
687          rotlw     %r5,%r5,%r0         /* shift offset */
688          rotlw     %r8,%r8,%r0         /* shift distance */
689          b         .Lbswr2rb_enter
690ENTRY(bswr2rb)
691          li        %r8,2               /* distance between dst halfwords */
692.Lbswr2rb_enter:
693          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
694          cmpwi     %r7,0               /* len == 0? */
695          beqlr-                        /*   return if len == 0 */
696          addi      %r7,%r7,-1          /* len -= 1 */
697          slwi      %r7,%r7,1 /* len *= 2 */
698          add       %r7,%r7,%r6         /* len += src */
699          addi      %r6,%r6,-2          /* pre-decrement */
7001:        lhzu      %r0,2(%r6)          /* load and increment */
701          sthbrx    %r0,0,%r3 /* store (reversed) */
702          add       %r3,%r3,%r8         /* dst += distance */
703          cmplw     %r6,%r7             /* at the end? */
704          bne+      1b                  /*   nope, do another pass */
705          eieio                         /* memory barrier (reorder protection) */
706          DBGSYNC                       /* force exceptions */
707          blr                           /* return */
708
709/* LINTSTUB: Func: void bswr4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c); */
710/* LINTSTUB: Func: void bswr4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c); */
711ENTRY(bswr4_s)
712          lwz       %r0,0(%r3)          /* get log2(stride) */
713          li        %r8,4               /* distance between dst halfwords */
714          rotlw     %r5,%r5,%r0         /* shift offset */
715          rotlw     %r8,%r8,%r0         /* shift distance */
716          b         .Lbswr4_enter
717ENTRY(bswr4)
718          li        %r8,4               /* distance between dst halfwords */
719.Lbswr4_enter:
720          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
721          cmpwi     %r7,0               /* len == 0? */
722          beqlr-                        /*   return if len == 0 */
723          addi      %r7,%r7,-1          /* len -= 1 */
724          slwi      %r7,%r7,2 /* len *= 4 */
725          add       %r7,%r7,%r6         /* len += src */
726          addi      %r6,%r6,-4          /* pre-decrement */
727          sub       %r3,%r3,%r8
7281:        lwzu      %r0,4(%r6)          /* load and increment */
729          stwux     %r0,%r3,%r8         /* store and add distance */
730          cmplw     %r6,%r7             /* at the end? */
731          bne+      1b                  /*   nope, do another pass */
732          eieio                         /* memory barrier (reorder protection) */
733          DBGSYNC                       /* force exceptions */
734          blr                           /* return */
735
736/* LINTSTUB: Func: void bswr4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c); */
737/* LINTSTUB: Func: void bswr4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c); */
738ENTRY(bswr4rb_s)
739          lwz       %r0,0(%r3)          /* get log2(stride) */
740          li        %r8,4               /* distance between dst halfwords */
741          rotlw     %r5,%r5,%r0         /* shift offset */
742          rotlw     %r8,%r8,%r0         /* shift distance */
743          b         .Lbswr4rb_enter
744ENTRY(bswr4rb)
745          li        %r8,4               /* distance between dst halfwords */
746.Lbswr4rb_enter:
747          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
748          cmpwi     %r7,0               /* len == 0? */
749          beqlr-                        /*   return if len == 0 */
750          addi      %r7,%r7,-1          /* len -= 1 */
751          slwi      %r7,%r7,2 /* len *= 4 */
752          add       %r7,%r7,%r6         /* len += src */
753          addi      %r6,%r6,-4          /* pre-decrement */
7541:        lwzu      %r0,4(%r6)          /* load and increment */
755          stwbrx    %r0,0,%r3 /* store (reversed) */
756          add       %r3,%r3,%r8         /* dst += distance */
757          cmplw     %r6,%r7             /* at the end? */
758          bne+      1b                  /*   nope, do another pass */
759          eieio                         /* memory barrier (reorder protection) */
760          DBGSYNC                       /* force exceptions */
761          blr                           /* return */
762
763/* LINTSTUB: Func: void bswr8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c); */
764/* LINTSTUB: Func: void bswr8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c); */
765/* LINTSTUB: Func: void bswr8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c); */
766/* LINTSTUB: Func: void bswr8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c); */
767ENTRY(bswr8_s)
768ENTRY(bswr8rb_s)
769          lwz       %r0,0(%r3)
770          rotlw     %r5,%r5,%r0
771ENTRY(bswr8)
772ENTRY(bswr8rb)
773          trap
774
775/* LINTSTUB: Func: void bsrr1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c); */
776/* LINTSTUB: Func: void bsrr1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c); */
777ENTRY(bsrr1_s)
778          lwz       %r0,0(%r3)          /* get log2(stride) */
779          li        %r8,1               /* distance between src bytes */
780          rotlw     %r5,%r5,%r0         /* shift offset */
781          rotlw     %r8,%r8,%r0         /* shift distance */
782          b         .Lbsrr1_enter
783ENTRY(bsrr1)
784          li        %r8,1               /* distance between src bytes */
785.Lbsrr1_enter:
786          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
787          cmpwi     %r7,0               /* len == 0? */
788          beqlr-                        /*   return if len == 0 */
789          addi      %r7,%r7,-1          /* len -= 1 */
790          add       %r7,%r7,%r6         /* len += src */
791          addi      %r6,%r6,-1          /* pre-decrement */
792          sub       %r3,%r3,%r8
7931:        lbzux     %r0,%r3,%r8         /* load value and add distance */
794          stbu      %r0,1(%r6)          /* store and increment */
795          cmplw     %r6,%r7             /* at the end? */
796          bne+      1b                  /*   nope, do another pass */
797          eieio                         /* memory barrier (reorder protection) */
798          DBGSYNC                       /* force exceptions */
799          blr                           /* return */
800
801/* LINTSTUB: Func: void bsrr2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c); */
802/* LINTSTUB: Func: void bsrr2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c); */
803ENTRY(bsrr2_s)
804          lwz       %r0,0(%r3)          /* get log2(stride) */
805          li        %r8,2               /* distance between src halfwords */
806          rotlw     %r5,%r5,%r0         /* shift offset */
807          rotlw     %r8,%r8,%r0         /* shift distance */
808          b         .Lbsrr2_enter
809ENTRY(bsrr2)
810          li        %r8,2               /* distance between src halfwords */
811.Lbsrr2_enter:
812          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
813          cmpwi     %r7,0               /* len == 0? */
814          beqlr-                        /*   return if len == 0 */
815          addi      %r7,%r7,-1          /* len -= 1 */
816          slwi      %r7,%r7,1 /* len *= 2 */
817          add       %r7,%r7,%r6         /* len += src */
818          addi      %r6,%r6,-2          /* pre-decrement */
819          sub       %r3,%r3,%r8
8201:        lhzux     %r0,%r3,%r8         /* load value and add distance */
821          sthu      %r0,2(%r6)          /* store and increment */
822          cmplw     %r6,%r7             /* at the end? */
823          bne+      1b                  /*   nope, do another pass */
824          eieio                         /* memory barrier (reorder protection) */
825          DBGSYNC                       /* force exceptions */
826          blr                           /* return */
827
828/* LINTSTUB: Func: void bsrr2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c); */
829/* LINTSTUB: Func: void bsrr2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c); */
830ENTRY(bsrr2rb_s)
831          lwz       %r0,0(%r3)          /* get log2(stride) */
832          li        %r8,2               /* distance between source halfwords */
833          rotlw     %r5,%r5,%r0         /* shift offset */
834          rotlw     %r8,%r8,%r0         /* shift distance */
835          b         .Lbsrr2rb_enter
836ENTRY(bsrr2rb)
837          li        %r8,2               /* distance between source halfwords */
838.Lbsrr2rb_enter:
839          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
840          cmpwi     %r7,0               /* len == 0? */
841          beqlr-                        /*   return if len == 0 */
842          addi      %r7,%r7,-1          /* len -= 1 */
843          slwi      %r7,%r7,1 /* len *= 2 */
844          add       %r7,%r7,%r6         /* len += src */
845          addi      %r6,%r6,-2          /* pre-decrement */
8461:        lhbrx     %r0,0,%r3 /* load value (reversed) */
847          add       %r3,%r3,%r8         /* src += distance */
848          sthu      %r0,2(%r6)          /* store and increment */
849          cmplw     %r6,%r7             /* at the end? */
850          bne+      1b                  /*   nope, do another pass */
851          eieio                         /* memory barrier (reorder protection) */
852          DBGSYNC                       /* force exceptions */
853          blr                           /* return */
854
855/* LINTSTUB: Func: void bsrr4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c); */
856/* LINTSTUB: Func: void bsrr4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c); */
857ENTRY(bsrr4_s)
858          lwz       %r0,0(%r3)                    /* get log2(stride) */
859          li        %r8,4               /* distance between src words */
860          rotlw     %r5,%r5,%r0         /* shift offset */
861          rotlw     %r8,%r8,%r0         /* shift distance */
862          b         .Lbsrr4_enter
863ENTRY(bsrr4)
864          li        %r8,4               /* distance between src words */
865.Lbsrr4_enter:
866          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
867          cmpwi     %r7,0               /* len == 0? */
868          beqlr-                        /*   return if len == 0 */
869          addi      %r7,%r7,-1          /* len -= 1 */
870          slwi      %r7,%r7,2 /* len *= 4 */
871          add       %r7,%r7,%r6         /* len += src */
872          addi      %r6,%r6,-4          /* pre-decrement */
873          sub       %r3,%r3,%r8
8741:        lwzux     %r0,%r3,%r8         /* load value and add distance */
875          stwu      %r0,4(%r6)          /* store and increment */
876          cmplw     %r6,%r7             /* at the end? */
877          bne+      1b                  /*   nope, do another pass */
878          eieio                         /* memory barrier (reorder protection) */
879          DBGSYNC                       /* force exceptions */
880          blr                           /* return */
881
882/* LINTSTUB: Func: void bsrr4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c); */
883/* LINTSTUB: Func: void bsrr4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c); */
884ENTRY(bsrr4rb_s)
885          lwz       %r0,0(%r3)          /* get log2(stride) */
886          li        %r8,4               /* distance between src words */
887          rotlw     %r5,%r5,%r0         /* shift offset */
888          rotlw     %r8,%r8,%r0         /* shift distance */
889          b         .Lbsrr4rb_enter
890ENTRY(bsrr4rb)
891          li        %r8,4               /* distance between src words */
892.Lbsrr4rb_enter:
893          add       %r3,%r4,%r5         /* add offset to handle & place in argument 0 */
894          mr        %r4,%r6             /* move addr to argument 1 register */
895          cmpwi     %r7,0               /* len == 0? */
896          beqlr-                        /*   return if len == 0 */
897          addi      %r7,%r7,-1          /* len -= 1 */
898          slwi      %r7,%r7,2 /* len *= 4 */
899          add       %r7,%r7,%r6         /* len += src */
900          addi      %r6,%r6,-4          /* pre-decrement */
9011:        lwbrx     %r0,0,%r3 /* load value (reversed) */
902          add       %r3,%r3,%r8         /* src += distance */
903          sthu      %r0,4(%r6)          /* store and increment */
904          cmplw     %r6,%r7             /* at the end? */
905          bne+      1b                  /*   nope, do another pass */
906          eieio                         /* memory barrier (reorder protection) */
907          DBGSYNC                       /* force exceptions */
908          blr                           /* return */
909
910/* LINTSTUB: Func: void bsrr8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c); */
911/* LINTSTUB: Func: void bsrr8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c); */
912/* LINTSTUB: Func: void bsrr8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c); */
913/* LINTSTUB: Func: void bsrr8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c); */
914ENTRY(bsrr8_s)
915ENTRY(bsrr8rb_s)
916          lwz       %r0,0(%r3)
917          rotlw     %r5,%r5,%r0
918ENTRY(bsrr8)
919ENTRY(bsrr8rb)
920          trap
921
922/* LINTSTUB: Func: void bssr1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v, bus_size_t c); */
923/* LINTSTUB: Func: void bssr1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v, bus_size_t c); */
924ENTRY(bssr1_s)
925          lwz       %r0,0(%r3)          /* get log2(stride) */
926          li        %r8,1               /* distance between src bytes */
927          rotlw     %r5,%r5,%r0         /* shift offset */
928          rotlw     %r8,%r8,%r0         /* shift distance */
929          b         .Lbssr1_enter
930ENTRY(bssr1)
931          li        %r8,1               /* distance between src bytes */
932.Lbssr1_enter:
933          cmpwi     %r7,0               /* len == 0? */
934          beqlr-                        /*   return if len == 0 */
9351:        addi      %r7,%r7,-1          /* len -= 1 */
936          stbx      %r6,%r4,%r5         /* store value */
937          add       %r5,%r5,%r8         /* add offset */
938          cmpwi     %r7,0               /* len == 0? */
939          bne+      1b                  /*   nope, do another pass */
940          eieio                         /* memory barrier (reorder protection) */
941          DBGSYNC                       /* force exceptions */
942          blr                           /* return */
943
944/* LINTSTUB: Func: void bssr2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t v, bus_size_t c); */
945/* LINTSTUB: Func: void bssr2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t v, bus_size_t c); */
946ENTRY(bssr2_s)
947          lwz       %r0,0(%r3)          /* get log2(stride) */
948          li        %r8,2               /* distance between src halfwords */
949          rotlw     %r5,%r5,%r0         /* shift offset */
950          rotlw     %r8,%r8,%r0         /* shift distance */
951          b         .Lbssr2_enter
952ENTRY(bssr2)
953          li        %r8,2               /* distance between src halfwords */
954.Lbssr2_enter:
955          cmpwi     %r7,0               /* len == 0? */
956          beqlr-                        /*   return if len == 0 */
9571:        addi      %r7,%r7,-1          /* len -= 1 */
958          sthx      %r6,%r4,%r5         /* store value */
959          add       %r5,%r5,%r8         /* add offset */
960          cmpwi     %r7,0               /* len == 0? */
961          bne+      1b                  /*   nope, do another pass */
962          eieio                         /* memory barrier (reorder protection) */
963          DBGSYNC                       /* force exceptions */
964          blr                           /* return */
965
966/* LINTSTUB: Func: void bssr2rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t v, bus_size_t c); */
967/* LINTSTUB: Func: void bssr2rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int16_t v, bus_size_t c); */
968ENTRY(bssr2rb_s)
969          lwz       %r0,0(%r3)          /* get log2(stride) */
970          li        %r8,2               /* distance between src halfwords */
971          rotlw     %r5,%r5,%r0         /* shift offset */
972          rotlw     %r8,%r8,%r0         /* shift distance */
973          b         .Lbssr2rb_enter
974ENTRY(bssr2rb)
975          li        %r8,2               /* distance between src halfwords */
976.Lbssr2rb_enter:
977          cmpwi     %r7,0               /* len == 0? */
978          beqlr-                        /*   return if len == 0 */
9791:        addi      %r7,%r7,-1          /* len -= 1 */
980          sthbrx    %r6,%r4,%r5         /* store value */
981          add       %r5,%r5,%r8         /* add offset */
982          cmpwi     %r7,0               /* len == 0? */
983          bne+      1b                  /*   nope, do another pass */
984          eieio                         /* memory barrier (reorder protection) */
985          DBGSYNC                       /* force exceptions */
986          blr                           /* return */
987
988/* LINTSTUB: Func: void bssr4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t v, bus_size_t c); */
989/* LINTSTUB: Func: void bssr4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t v, bus_size_t c); */
990ENTRY(bssr4_s)
991          lwz       %r0,0(%r3)          /* get log2(stride) */
992          li        %r8,4               /* distance between src words */
993          rotlw     %r5,%r5,%r0         /* shift offset */
994          rotlw     %r8,%r8,%r0         /* shift distance */
995          b         .Lbssr4_enter
996ENTRY(bssr4)
997          li        %r8,4               /* distance between src words */
998.Lbssr4_enter:
999          cmpwi     %r7,0               /* len == 0? */
1000          beqlr-                        /*   return if len == 0 */
10011:        addi      %r7,%r7,-1          /* len -= 1 */
1002          stwx      %r6,%r4,%r5         /* store value */
1003          add       %r5,%r5,%r8         /* add offset */
1004          cmpwi     %r7,0               /* len == 0? */
1005          bne+      1b                  /*   nope, do another pass */
1006          eieio                         /* memory barrier (reorder protection) */
1007          DBGSYNC                       /* force exceptions */
1008          blr                           /* return */
1009
1010/* LINTSTUB: Func: void bssr4rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t v, bus_size_t c); */
1011/* LINTSTUB: Func: void bssr4rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int32_t v, bus_size_t c); */
1012ENTRY(bssr4rb_s)
1013          lwz       %r0,0(%r3)          /* get log2(stride) */
1014          li        %r8,4               /* distance between src words */
1015          rotlw     %r5,%r5,%r0         /* shift offset */
1016          rotlw     %r8,%r8,%r0         /* shift distance */
1017          b         .Lbssr4rb_enter
1018ENTRY(bssr4rb)
1019          li        %r8,4               /* distance between src words */
1020.Lbssr4rb_enter:
1021          cmpwi     %r7,0               /* len == 0? */
1022          beqlr-                        /*   return if len == 0 */
10231:        addi      %r7,%r7,-1          /* len -= 1 */
1024          stwbrx    %r6,%r4,%r5         /* store value */
1025          add       %r5,%r5,%r8         /* add offset */
1026          cmpwi     %r7,0               /* len == 0? */
1027          bne+      1b                  /*   nope, do another pass */
1028          eieio                         /* memory barrier (reorder protection) */
1029          DBGSYNC                       /* force exceptions */
1030          blr                           /* return */
1031
1032/* LINTSTUB: Func: void bssr8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t v, bus_size_t c); */
1033/* LINTSTUB: Func: void bssr8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t v, bus_size_t c); */
1034/* LINTSTUB: Func: void bssr8rb_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t v, bus_size_t c); */
1035/* LINTSTUB: Func: void bssr8rb(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, const u_int64_t v, bus_size_t c); */
1036ENTRY(bssr8_s)
1037ENTRY(bssr8rb_s)
1038          lwz       %r0,0(%r3)
1039          rotlw     %r5,%r5,%r0
1040ENTRY(bssr8)
1041ENTRY(bssr8rb)
1042          trap
1043
1044/* LINTSTUB: Func: void bscr1_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1045/* LINTSTUB: Func: void bscr1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1046ENTRY(bscr1_s)
1047          lwz       %r0,0(%r3)          /* get log2(stride) */
1048          b         .Lbscr1_enter
1049ENTRY(bscr1)
1050          li        %r0,0               /* non stride */
1051.Lbscr1_enter:
1052          li        %r9,1               /* distance between src bytes */
1053          rotlw     %r9,%r9,%r0                   /* shift distance */
1054          cmpwi     %r8,0               /* len == 0? */
1055          beqlr-                        /*   return if len == 0 */
1056          rotlw     %r5,%r5,%r0         /* shift src offset */
1057          rotlw     %r7,%r7,%r0         /* shift dest offset */
1058          add       %r10,%r4,%r5        /* calculate src end address */
1059          add       %r11,%r6,%r7        /* calculate dest end address */
1060          mtctr     %r8
1061          cmpw      %r10,%r11 /* compare end address */
1062          blt       2f                  /* jump if h + o < h2 + o2 */
1063
1064                                        /* h + o >= h2 + o2 */
10651:        lbzx      %r12,%r4,%r5        /* load value */
1066          stbx      %r12,%r6,%r7        /* store value */
1067          add       %r5,%r5,%r9         /* src offset += 1 */
1068          add       %r7,%r7,%r9         /* dest offset += 1 */
1069          bdnz+     1b                  /* jump if len != 0 */
1070          b         .Lbscr1_end         /* end */
1071
1072                                        /* h + o < h2 + o2 */
10732:        addi      %r8,%r8,-1          /* len -= 1 */
1074          rotlw     %r8,%r8,%r0         /* shift len */
1075          add       %r5,%r10,%r8        /* src offset = o + len - 1 */
1076          add       %r7,%r11,%r8        /* dest offset = o2 + len - 1 */
10773:        lbzx      %r12,%r4,%r5        /* load value */
1078          stbx      %r12,%r6,%r7        /* store value */
1079          sub       %r5,%r5,%r9         /* src offset -= 1 */
1080          sub       %r7,%r7,%r9         /* dest offset -= 1 */
1081          bdnz+     3b                  /* jump if len != 0 */
1082.Lbscr1_end:
1083          eieio                         /* memory barrier (reorder protection) */
1084          DBGSYNC                       /* force exceptions */
1085          blr                           /* return */
1086
1087/* LINTSTUB: Func: void bscr2_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1088/* LINTSTUB: Func: void bscr2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1089ENTRY(bscr2_s)
1090          lwz       %r0,0(%r3)                    /* get log2(stride) */
1091          b         .Lbscr2_enter
1092ENTRY(bscr2)
1093          li        %r0,0               /* non stride */
1094.Lbscr2_enter:
1095          li        %r9,2               /* distance between src halfwords */
1096          rotlw     %r9,%r9,%r0                   /* shift distance */
1097          cmpwi     %r8,0               /* len == 0? */
1098          beqlr-                        /*   return if len == 0 */
1099          rotlw     %r5,%r5,%r0         /* shift src offset */
1100          rotlw     %r7,%r7,%r0         /* shift dest offset */
1101          add       %r10,%r4,%r5        /* calculate src end address */
1102          add       %r11,%r6,%r7        /* calculate dest end address */
1103          mtctr     %r8
1104          cmpw      %r10,%r11 /* compare end address */
1105          blt       2f                  /* jump if h + o < h2 + o2 */
1106
1107                                        /* h + o >= h2 + o2 */
11081:        lhzx      %r12,%r4,%r5        /* load value */
1109          sthx      %r12,%r6,%r7        /* store value */
1110          add       %r5,%r5,%r9         /* src offset += 2 */
1111          add       %r7,%r7,%r9         /* dest offset += 2 */
1112          bdnz+     1b                  /* jump if len != 0 */
1113          b         .Lbscr2_end         /* end */
1114
1115                                        /* h + o < h2 + o2 */
11162:        addi      %r8,%r8,-1          /* len -= 1 */
1117          rotlw     %r8,%r8,%r0         /* shift len */
1118          add       %r5,%r10,%r8        /* src offset = o + len - 1 */
1119          add       %r7,%r11,%r8        /* dest offset = o2 + len - 1 */
11203:        lhzx      %r12,%r4,%r5        /* load value */
1121          sthx      %r12,%r6,%r7        /* store value */
1122          sub       %r5,%r5,%r9         /* src offset -= 2 */
1123          sub       %r7,%r7,%r9         /* dest offset -= 2 */
1124          bdnz+     3b                  /* jump if len != 0 */
1125.Lbscr2_end:
1126          eieio                         /* memory barrier (reorder protection) */
1127          DBGSYNC                       /* force exceptions */
1128          blr                           /* return */
1129
1130/* LINTSTUB: Func: void bscr4_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1131/* LINTSTUB: Func: void bscr4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1132ENTRY(bscr4_s)
1133          lwz       %r0,0(%r3)          /* get log2(stride) */
1134          b         .Lbscr4_enter
1135ENTRY(bscr4)
1136          li        %r0,0               /* non stride */
1137.Lbscr4_enter:
1138          li        %r9,4               /* distance between src words */
1139          rotlw     %r9,%r9,%r0         /* shift distance */
1140          cmpwi     %r8,0               /* len == 0? */
1141          beqlr-                        /*   return if len == 0 */
1142          rotlw     %r5,%r5,%r0         /* shift src offset */
1143          rotlw     %r7,%r7,%r0         /* shift dest offset */
1144          add       %r10,%r4,%r5        /* calculate src end address */
1145          add       %r11,%r6,%r7        /* calculate dest end address */
1146          mtctr     %r8
1147          cmpw      %r10,%r11 /* compare end address */
1148          blt       2f                  /* jump if h + o < h2 + o2 */
1149
1150                                        /* h + o >= h2 + o2 */
11511:        lwzx      %r12,%r4,%r5        /* load value */
1152          stwx      %r12,%r6,%r7        /* store value */
1153          add       %r5,%r5,%r9         /* src offset += 4 */
1154          add       %r7,%r7,%r9         /* dest offset += 4 */
1155          bdnz+     1b                  /* jump if len != 0 */
1156          b         .Lbscr4_end         /* end */
1157
1158                                        /* h + o < h2 + o2 */
11592:        addi      %r8,%r8,-1          /* len -= 1 */
1160          rotlw     %r8,%r8,%r0         /* shift len */
1161          add       %r5,%r10,%r8        /* src offset = o + len - 1 */
1162          add       %r7,%r11,%r8        /* dest offset = o2 + len - 1 */
11633:        lwzx      %r12,%r4,%r5        /* load value */
1164          stwx      %r12,%r6,%r7        /* store value */
1165          sub       %r5,%r5,%r9         /* src offset -= 4 */
1166          sub       %r7,%r7,%r9         /* dest offset -= 4 */
1167          bdnz+     3b                  /* jump if len != 0 */
1168.Lbscr4_end:
1169          eieio                         /* memory barrier (reorder protection) */
1170          DBGSYNC                       /* force exceptions */
1171          blr                           /* return */
1172
1173/* LINTSTUB: Func: void bscr8_s(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1174/* LINTSTUB: Func: void bscr8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_space_handle_t h2, bus_size_t o2, bus_size_t len); */
1175ENTRY(bscr8_s)
1176ENTRY(bscr8)
1177          trap
1178
1179