Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
[linux-2.6] / include / asm-xtensa / asmmacro.h
1 /*
2  * include/asm-xtensa/asmmacro.h
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  *
8  * Copyright (C) 2005 Tensilica Inc.
9  */
10
11 #ifndef _XTENSA_ASMMACRO_H
12 #define _XTENSA_ASMMACRO_H
13
14 #include <asm/variant/core.h>
15
16 /*
17  * Some little helpers for loops. Use zero-overhead-loops
18  * where applicable and if supported by the processor.
19  *
20  * __loopi ar, at, size, inc
21  *         ar   register initialized with the start address
22  *         at   scratch register used by macro
23  *         size size immediate value
24  *         inc  increment
25  *
26  * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond]
27  *         ar   register initialized with the start address
28  *         as   register initialized with the size
29  *         at   scratch register use by macro
30  *         inc_log2     increment [in log2]
31  *         mask_log2    mask [in log2]
32  *         cond         true condition (used in loop'cond')
33  *         ncond        false condition (used in b'ncond')
34  *
35  * __loop  as
36  *         restart loop. 'as' register must not have been modified!
37  *
38  * __endla ar, at, incr
39  *         ar   start address (modified)
40  *         as   scratch register used by macro
41  *         inc  increment
42  */
43
44 /*
45  * loop for given size as immediate
46  */
47
48         .macro  __loopi ar, at, size, incr
49
50 #if XCHAL_HAVE_LOOPS
51                 movi    \at, ((\size + \incr - 1) / (\incr))
52                 loop    \at, 99f
53 #else
54                 addi    \at, \ar, \size
55                 98:
56 #endif
57
58         .endm
59
60 /*
61  * loop for given size in register
62  */
63
64         .macro  __loops ar, as, at, incr_log2, mask_log2, cond, ncond
65
66 #if XCHAL_HAVE_LOOPS
67                 .ifgt \incr_log2 - 1
68                         addi    \at, \as, (1 << \incr_log2) - 1
69                         .ifnc \mask_log2,
70                                 extui   \at, \at, \incr_log2, \mask_log2
71                         .else
72                                 srli    \at, \at, \incr_log2
73                         .endif
74                 .endif
75                 loop\cond       \at, 99f
76 #else
77                 .ifnc \mask_log2,
78                         extui   \at, \as, \incr_log2, \mask_log2
79                 .else
80                         .ifnc \ncond,
81                                 srli    \at, \as, \incr_log2
82                         .endif
83                 .endif
84                 .ifnc \ncond,
85                         b\ncond \at, 99f
86
87                 .endif
88                 .ifnc \mask_log2,
89                         slli    \at, \at, \incr_log2
90                         add     \at, \ar, \at
91                 .else
92                         add     \at, \ar, \as
93                 .endif
94 #endif
95                 98:
96
97         .endm
98
99 /*
100  * loop from ar to ax
101  */
102
103         .macro  __loopt ar, as, at, incr_log2
104
105 #if XCHAL_HAVE_LOOPS
106                 sub     \at, \as, \ar
107                 .ifgt   \incr_log2 - 1
108                         addi    \at, \at, (1 << \incr_log2) - 1
109                         srli    \at, \at, \incr_log2
110                 .endif
111                 loop    \at, 99f
112 #else
113                 98:
114 #endif
115
116         .endm
117
118 /*
119  * restart loop. registers must be unchanged
120  */
121
122         .macro  __loop  as
123
124 #if XCHAL_HAVE_LOOPS
125                 loop    \as, 99f
126 #else
127                 98:
128 #endif
129
130         .endm
131
132 /*
133  * end of loop with no increment of the address.
134  */
135
136         .macro  __endl  ar, as
137 #if !XCHAL_HAVE_LOOPS
138                 bltu    \ar, \as, 98b
139 #endif
140                 99:
141         .endm
142
143 /*
144  * end of loop with increment of the address.
145  */
146
147         .macro  __endla ar, as, incr
148                 addi    \ar, \ar, \incr
149                 __endl  \ar \as
150         .endm
151
152
153 #endif /* _XTENSA_ASMMACRO_H */