Commit | Line | Data |
---|---|---|
173d6681 CZ |
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 | ||
367b8112 | 14 | #include <variant/core.h> |
173d6681 CZ |
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 */ |