Imported Upstream version 3.2.2
[debian/gnuradio] / gcell / include / gcell / spu / gc_spu_macs.h
1 /* -*- asm -*- */
2 /*
3  * Copyright 2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifndef INCLUDED_GC_SPU_MACS_H
23 #define INCLUDED_GC_SPU_MACS_H
24
25 /*
26  * This file contains a set of macros that are generally useful when
27  * coding in SPU assembler
28  *
29  * Note that the multi-instruction macros in here may overwrite
30  * registers 77, 78, and 79 without warning.
31  */
32
33 /*
34  * defines for all registers
35  */
36 #define r0      $0
37 #define r1      $1
38 #define r2      $2
39 #define r3      $3
40 #define r4      $4
41 #define r5      $5
42 #define r6      $6
43 #define r7      $7
44 #define r8      $8
45 #define r9      $9
46 #define r10     $10
47 #define r11     $11
48 #define r12     $12
49 #define r13     $13
50 #define r14     $14
51 #define r15     $15
52 #define r16     $16
53 #define r17     $17
54 #define r18     $18
55 #define r19     $19
56 #define r20     $20
57 #define r21     $21
58 #define r22     $22
59 #define r23     $23
60 #define r24     $24
61 #define r25     $25
62 #define r26     $26
63 #define r27     $27
64 #define r28     $28
65 #define r29     $29
66 #define r30     $30
67 #define r31     $31
68 #define r32     $32
69 #define r33     $33
70 #define r34     $34
71 #define r35     $35
72 #define r36     $36
73 #define r37     $37
74 #define r38     $38
75 #define r39     $39
76 #define r40     $40
77 #define r41     $41
78 #define r42     $42
79 #define r43     $43
80 #define r44     $44
81 #define r45     $45
82 #define r46     $46
83 #define r47     $47
84 #define r48     $48
85 #define r49     $49
86 #define r50     $50
87 #define r51     $51
88 #define r52     $52
89 #define r53     $53
90 #define r54     $54
91 #define r55     $55
92 #define r56     $56
93 #define r57     $57
94 #define r58     $58
95 #define r59     $59
96 #define r60     $60
97 #define r61     $61
98 #define r62     $62
99 #define r63     $63
100 #define r64     $64
101 #define r65     $65
102 #define r66     $66
103 #define r67     $67
104 #define r68     $68
105 #define r69     $69
106 #define r70     $70
107 #define r71     $71
108 #define r72     $72
109 #define r73     $73
110 #define r74     $74
111 #define r75     $75
112 #define r76     $76
113 #define r77     $77
114 #define r78     $78
115 #define r79     $79
116 #define r80     $80
117 #define r81     $81
118 #define r82     $82
119 #define r83     $83
120 #define r84     $84
121 #define r85     $85
122 #define r86     $86
123 #define r87     $87
124 #define r88     $88
125 #define r89     $89
126 #define r90     $90
127 #define r91     $91
128 #define r92     $92
129 #define r93     $93
130 #define r94     $94
131 #define r95     $95
132 #define r96     $96
133 #define r97     $97
134 #define r98     $98
135 #define r99     $99
136 #define r100    $100
137 #define r101    $101
138 #define r102    $102
139 #define r103    $103
140 #define r104    $104
141 #define r105    $105
142 #define r106    $106
143 #define r107    $107
144 #define r108    $108
145 #define r109    $109
146 #define r110    $110
147 #define r111    $111
148 #define r112    $112
149 #define r113    $113
150 #define r114    $114
151 #define r115    $115
152 #define r116    $116
153 #define r117    $117
154 #define r118    $118
155 #define r119    $119
156 #define r120    $120
157 #define r121    $121
158 #define r122    $122
159 #define r123    $123
160 #define r124    $124
161 #define r125    $125
162 #define r126    $126
163 #define r127    $127
164
165
166 #define lr      r0      // link register
167 #define sp      r1      // stack pointer
168                         // r2 is environment pointer for langs that need it (ALGOL)
169
170 #define retval  r3      // return values are passed in regs starting at r3
171
172 #define arg1    r3      // args are passed in regs starting at r3
173 #define arg2    r4
174 #define arg3    r5
175 #define arg4    r6
176 #define arg5    r7
177 #define arg6    r8
178 #define arg7    r9
179 #define arg8    r10
180 #define arg9    r11
181 #define arg10   r12
182
183 //  r3 -  r74 are volatile (caller saves)
184 // r74 -  r79 are volatile (scratch regs possibly destroyed by fct prolog/epilog)
185 // r80 - r127 are non-volatile (callee-saves)
186
187 // scratch registers reserved for use by the macros in this file.
188
189 #define _gc_t0  r79
190 #define _gc_t1  r78
191 #define _gc_t2  r77
192
193 /*
194  * ----------------------------------------------------------------
195  *                          pseudo ops
196  * ----------------------------------------------------------------
197  */
198 #define PROC_ENTRY(name)                \
199         .text;                          \
200         .p2align 4;                     \
201         .global name;                   \
202         .type   name, @function;        \
203 name:
204
205 /*
206  * ----------------------------------------------------------------
207  *                  aliases for common operations
208  * ----------------------------------------------------------------
209  */
210
211 // Move register (even pipe, 2 cycles)
212 #define MR(rt, ra)                      or      rt, ra, ra;
213
214 // Move register (odd pipe, 4 cycles)
215 #define LMR(rt, ra)                     rotqbyi rt, ra, 0;
216
217 // return
218 #define RETURN()                        bi      lr;
219
220 // hint for a return
221 #define HINT_RETURN(ret_label)          hbr     ret_label, lr;
222
223 // return if zero
224 #define BRZ_RETURN(rt)                  biz     rt, lr;
225
226 // return if not zero
227 #define BRNZ_RETURN(rt)                 binz    rt, lr;
228
229 // return if halfword zero
230 #define BRHZ_RETURN(rt)                 bihz    rt, lr;
231
232 // return if halfword not zero
233 #define BRHNZ_RETURN(rt)                bihnz   rt, lr;
234
235
236 /*
237  * ----------------------------------------------------------------
238  * modulo like things for constant moduli that are powers of 2
239  * ----------------------------------------------------------------
240  */
241
242 // rt = ra & (pow2 - 1)
243 #define MODULO(rt, ra, pow2) \
244         andi    rt, ra, (pow2)-1;
245
246 // rt = pow2 - (ra & (pow2 - 1))
247 #define MODULO_NEG(rt, ra, pow2) \
248         andi    rt, ra, (pow2)-1;               \
249         sfi     rt, rt, (pow2);
250
251 // rt = ra & -(pow2)
252 #define ROUND_DOWN(rt, ra, pow2) \
253         andi    rt, ra, -(pow2);
254
255 // rt = (ra + (pow2 - 1)) & -(pow2)
256 #define ROUND_UP(rt, ra, pow2) \
257         ai      rt, ra, (pow2)-1;               \
258         andi    rt, rt, -(pow2);
259
260 /*
261  * ----------------------------------------------------------------
262  * Splat - replicate a particular slot into all slots
263  * Altivec analogs...
264  * ----------------------------------------------------------------
265  */
266
267 // replicate byte from slot s [0,15]
268 #define VSPLTB(rt, ra, s) \
269         ilh     _gc_t0, (s)*0x0101;             \
270         shufb   rt, ra, ra, _gc_t0;
271
272 // replicate halfword from slot s [0,7]
273 #define VSPLTH(rt, ra, s) \
274         ilh     _gc_t0, 2*(s)*0x0101 + 0x0001;  \
275         shufb   rt, ra, ra, _gc_t0;
276
277 // replicate word from slot s [0,3]
278 #define VSPLTW(rt, ra, s) \
279         iluh    _gc_t0, 4*(s)*0x0101 + 0x0001;  \
280         iohl    _gc_t0, 4*(s)*0x0101 + 0x0203;  \
281         shufb   rt, ra, ra, _gc_t0;
282         
283 // replicate double from slot s [0,1]
284 #define VSPLTD(rt, ra, s) \
285         /* sp is always 16-byte aligned */ \
286         cdd     _gc_t0, 8(sp);          /* 0x10111213 14151617 00010203 04050607 */ \
287         rotqbyi rt, ra, ra, (s) << 3;   /* rotate double into preferred slot     */ \
288         shufb   rt, rt, rt, _gc_t0;
289
290 /*
291  * ----------------------------------------------------------------
292  * lots of min/max variations...
293  *
294  * On a slot by slot basis, compute the min or max
295  *
296  * U - unsigned, else signed
297  * B,H,{} - byte, halfword, word
298  * F float
299  * ----------------------------------------------------------------
300  */
301
302 #define MIN_SELB(rt, ra, rb, rc)        selb    rt, ra, rb, rc;
303 #define MAX_SELB(rt, ra, rb, rc)        selb    rt, rb, ra, rc;
304         
305         // words
306
307 #define MIN(rt, ra, rb) \
308         cgt     _gc_t0, ra, rb; \
309         MIN_SELB(rt, ra, rb, _gc_t0)
310         
311 #define MAX(rt, ra, rb) \
312         cgt     _gc_t0, ra, rb; \
313         MAX_SELB(rt, ra, rb, _gc_t0)
314
315 #define UMIN(rt, ra, rb) \
316         clgt    _gc_t0, ra, rb; \
317         MIN_SELB(rt, ra, rb, _gc_t0)
318         
319 #define UMAX(rt, ra, rb) \
320         clgt    _gc_t0, ra, rb; \
321         MAX_SELB(rt, ra, rb, _gc_t0)
322
323         // bytes
324         
325 #define MINB(rt, ra, rb) \
326         cgtb    _gc_t0, ra, rb; \
327         MIN_SELB(rt, ra, rb, _gc_t0)
328         
329 #define MAXB(rt, ra, rb) \
330         cgtb    _gc_t0, ra, rb; \
331         MAX_SELB(rt, ra, rb, _gc_t0)
332
333 #define UMINB(rt, ra, rb) \
334         clgtb   _gc_t0, ra, rb; \
335         MIN_SELB(rt, ra, rb, _gc_t0)
336         
337 #define UMAXB(rt, ra, rb) \
338         clgtb   _gc_t0, ra, rb; \
339         MAX_SELB(rt, ra, rb, _gc_t0)
340
341         // halfwords
342         
343 #define MINH(rt, ra, rb) \
344         cgth    _gc_t0, ra, rb; \
345         MIN_SELB(rt, ra, rb, _gc_t0)
346         
347 #define MAXH(rt, ra, rb) \
348         cgth    _gc_t0, ra, rb; \
349         MAX_SELB(rt, ra, rb, _gc_t0)
350
351 #define UMINH(rt, ra, rb) \
352         clgth   _gc_t0, ra, rb; \
353         MIN_SELB(rt, ra, rb, _gc_t0)
354         
355 #define UMAXH(rt, ra, rb) \
356         clgth   _gc_t0, ra, rb; \
357         MAX_SELB(rt, ra, rb, _gc_t0)
358
359         // floats
360         
361 #define FMIN(rt, ra, rb) \
362         fcgt    _gc_t0, ra, rb; \
363         MIN_SELB(rt, ra, rb, _gc_t0)
364         
365 #define FMAX(rt, ra, rb) \
366         fcgt    _gc_t0, ra, rb; \
367         MAX_SELB(rt, ra, rb, _gc_t0)
368
369 // Ignoring the sign, select the values with the minimum magnitude
370 #define FMINMAG(rt, ra, rb) \
371         fcmgt   _gc_t0, ra, rb; \
372         MIN_SELB(rt, ra, rb, _gc_t0)
373         
374 // Ignoring the sign, select the values with the maximum magnitude
375 #define FMAXMAG(rt, ra, rb) \
376         fcmgt   _gc_t0, ra, rb; \
377         MAX_SELB(rt, ra, rb, _gc_t0)
378
379
380 #endif /* INCLUDED_GC_SPU_MACS_H */