1e5ea9a9b7d287dc487ef209c799b73336aa8b08
[jlayton/glibc.git] / sysdeps / mips / sys / asm.h
1 /* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ralf Baechle <ralf@gnu.org>.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef _SYS_ASM_H
21 #define _SYS_ASM_H
22
23 #include <sgidefs.h>
24
25 #ifndef CAT
26 #ifdef __STDC__
27 #define __CAT(str1,str2) str1##str2
28 #else
29 #define __CAT(str1,str2) str1/**/str2
30 #endif
31 #define CAT(str1,str2) __CAT(str1,str2)
32 #endif
33
34 /*
35  * Macros to handle different pointer/register sizes for 32/64-bit code
36  *
37  * 64 bit address space isn't used yet, so we may use the R3000 32 bit
38  * defines for now.
39  */
40 #define PTR     .word
41 #define PTRSIZE 4
42 #define PTRLOG  2
43
44 /*
45  * PIC specific declarations
46  */
47 #ifdef __PIC__
48 #define CPRESTORE(register)                             \
49                 .cprestore register
50 #define CPADD(register)                                 \
51                 .cpadd  register
52 #define CPLOAD(register)                                \
53                 .cpload register
54 #else
55 #define CPRESTORE(register)
56 #define CPADD(register)
57 #define CPLOAD(register)
58 #endif
59
60 /*
61  * LEAF - declare leaf routine
62  */
63 #define LEAF(symbol)                                    \
64                 .globl  symbol;                         \
65                 .align  2;                              \
66                 .type   symbol,@function;               \
67                 .ent    symbol,0;                       \
68 symbol:         .frame  sp,0,ra
69
70 /*
71  * NESTED - declare nested routine entry point
72  */
73 #define NESTED(symbol, framesize, rpc)                  \
74                 .globl  symbol;                         \
75                 .align  2;                              \
76                 .type   symbol,@function;               \
77                 .ent    symbol,0;                       \
78 symbol:         .frame  sp, framesize, rpc
79
80 /*
81  * END - mark end of function
82  */
83 #define END(function)                                   \
84                 .end    function;                       \
85                 .size   function,.-function
86
87 /*
88  * EXPORT - export definition of symbol
89  */
90 #define EXPORT(symbol)                                  \
91                 .globl  symbol;                         \
92 symbol:
93
94 /*
95  * ABS - export absolute symbol
96  */
97 #define ABS(symbol,value)                               \
98                 .globl  symbol;                         \
99 symbol          =       value
100
101 #define PANIC(msg)                                      \
102                 .set    push;                           \
103                 .set    reorder;                        \
104                 la      a0,8f;                          \
105                 jal     panic;                          \
106 9:              b       9b;                             \
107                 .set    pop;                            \
108                 TEXT(msg)
109
110 /*
111  * Print formated string
112  */
113 #define PRINT(string)                                   \
114                 .set    push;                           \
115                 .set    reorder;                        \
116                 la      a0,8f;                          \
117                 jal     printk;                         \
118                 .set    pop;                            \
119                 TEXT(string)
120
121 #define TEXT(msg)                                       \
122                 .data;                                  \
123 8:              .asciiz msg;                            \
124                 .previous;
125
126 /*
127  * Build text tables
128  */
129 #define TTABLE(string)                                  \
130                 .text;                                  \
131                 .word   1f;                             \
132                 .previous;                              \
133                 .data;                                  \
134 1:              .asciz  string;                         \
135                 .previous
136
137 /*
138  * MIPS IV pref instruction.
139  * Use with .set noreorder only!
140  *
141  * MIPS IV implementations are free to treat this as a nop.  The R5000
142  * is one of them.  So we should have an option not to use this instruction.
143  */
144 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
145 #define PREF(hint,addr)                                 \
146                 pref    hint,addr
147 #define PREFX(hint,addr)                                \
148                 prefx   hint,addr
149 #else
150 #define PREF
151 #define PREFX
152 #endif
153
154 /*
155  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
156  */
157 #if _MIPS_ISA == _MIPS_ISA_MIPS1
158 #define MOVN(rd,rs,rt)                                  \
159                 .set    push;                           \
160                 .set    reorder;                        \
161                 beqz    rt,9f;                          \
162                 move    rd,rs;                          \
163                 .set    pop;                            \
164 9:
165 #define MOVZ(rd,rs,rt)                                  \
166                 .set    push;                           \
167                 .set    reorder;                        \
168                 bnez    rt,9f;                          \
169                 move    rd,rt;                          \
170                 .set    pop;                            \
171 9:
172 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
173 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
174 #define MOVN(rd,rs,rt)                                  \
175                 .set    push;                           \
176                 .set    noreorder;                      \
177                 bnezl   rt,9f;                          \
178                 move    rd,rs;                          \
179                 .set    pop;                            \
180 9:
181 #define MOVZ(rd,rs,rt)                                  \
182                 .set    push;                           \
183                 .set    noreorder;                      \
184                 beqzl   rt,9f;                          \
185                 movz    rd,rs;                          \
186                 .set    pop;                            \
187 9:
188 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
189 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
190 #define MOVN(rd,rs,rt)                                  \
191                 movn    rd,rs,rt
192 #define MOVZ(rd,rs,rt)                                  \
193                 movz    rd,rs,rt
194 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
195
196 /*
197  * Stack alignment
198  */
199 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
200 #define ALSZ    7
201 #define ALMASK  ~7
202 #endif
203 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
204     (_MIPS_ISA == _MIPS_ISA_MIPS5)
205 #define ALSZ    15
206 #define ALMASK  ~15
207 #endif
208
209 /*
210  * Size of a register
211  */
212 #ifdef __mips64
213 #define SZREG   8
214 #else
215 #define SZREG   4
216 #endif
217
218 /*
219  * Use the following macros in assemblercode to load/store registers,
220  * pointers etc.
221  */
222 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
223 #define REG_S sw
224 #define REG_L lw
225 #define PTR_SUBU subu
226 #define PTR_ADDU addu
227 #endif
228 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
229     (_MIPS_ISA == _MIPS_ISA_MIPS5)
230 #define REG_S sd
231 #define REG_L ld
232 /* We still live in a 32 bit address space ...  */
233 #define PTR_SUBU subu
234 #define PTR_ADDU addu
235 #endif
236
237 /*
238  * How to add/sub/load/store/shift C int variables.
239  */
240 #if (_MIPS_SZINT == 32)
241 #define INT_ADD add
242 #define INT_ADDI        addi
243 #define INT_ADDU        addu
244 #define INT_ADDIU       addiu
245 #define INT_SUB add
246 #define INT_SUBI        subi
247 #define INT_SUBU        subu
248 #define INT_SUBIU       subu
249 #define INT_L           lw
250 #define INT_S           sw
251 #define LONG_SLL        sll
252 #define LONG_SLLV       sllv
253 #define LONG_SRL        srl
254 #define LONG_SRLV       srlv
255 #define LONG_SRA        sra
256 #define LONG_SRAV       srav
257 #endif
258
259 #if (_MIPS_SZINT == 64)
260 #define INT_ADD dadd
261 #define INT_ADDI        daddi
262 #define INT_ADDU        daddu
263 #define INT_ADDIU       daddiu
264 #define INT_SUB dadd
265 #define INT_SUBI        dsubi
266 #define INT_SUBU        dsubu
267 #define INT_SUBIU       dsubu
268 #define INT_L           ld
269 #define INT_S           sd
270 #define LONG_SLL        dsll
271 #define LONG_SLLV       dsllv
272 #define LONG_SRL        dsrl
273 #define LONG_SRLV       dsrlv
274 #define LONG_SRA        dsra
275 #define LONG_SRAV       dsrav
276 #endif
277
278 /*
279  * How to add/sub/load/store/shift C long variables.
280  */
281 #if (_MIPS_SZLONG == 32)
282 #define LONG_ADD        add
283 #define LONG_ADDI       addi
284 #define LONG_ADDU       addu
285 #define LONG_ADDIU      addiu
286 #define LONG_SUB        add
287 #define LONG_SUBI       subi
288 #define LONG_SUBU       subu
289 #define LONG_SUBIU      subu
290 #define LONG_L          lw
291 #define LONG_S          sw
292 #define LONG_SLL        sll
293 #define LONG_SLLV       sllv
294 #define LONG_SRL        srl
295 #define LONG_SRLV       srlv
296 #define LONG_SRA        sra
297 #define LONG_SRAV       srav
298 #endif
299
300 #if (_MIPS_SZLONG == 64)
301 #define LONG_ADD        dadd
302 #define LONG_ADDI       daddi
303 #define LONG_ADDU       daddu
304 #define LONG_ADDIU      daddiu
305 #define LONG_SUB        dadd
306 #define LONG_SUBI       dsubi
307 #define LONG_SUBU       dsubu
308 #define LONG_SUBIU      dsubu
309 #define LONG_L          ld
310 #define LONG_S          sd
311 #define LONG_SLL        dsll
312 #define LONG_SLLV       dsllv
313 #define LONG_SRL        dsrl
314 #define LONG_SRLV       dsrlv
315 #define LONG_SRA        dsra
316 #define LONG_SRAV       dsrav
317 #endif
318
319 /*
320  * How to add/sub/load/store/shift pointers.
321  */
322 #if (_MIPS_SZLONG == 32)
323 #define PTR_ADD add
324 #define PTR_ADDI        addi
325 #define PTR_ADDU        addu
326 #define PTR_ADDIU       addiu
327 #define PTR_SUB         add
328 #define PTR_SUBI        subi
329 #define PTR_SUBU        subu
330 #define PTR_SUBIU       subu
331 #define PTR_L           lw
332 #define PTR_S           sw
333 #define PTR_SLL         sll
334 #define PTR_SLLV        sllv
335 #define PTR_SRL         srl
336 #define PTR_SRLV        srlv
337 #define PTR_SRA         sra
338 #define PTR_SRAV        srav
339
340 #define PTR_SCALESHIFT  2
341 #endif
342
343 #if (_MIPS_SZLONG == 64)
344 #define PTR_ADD dadd
345 #define PTR_ADDI        daddi
346 #define PTR_ADDU        daddu
347 #define PTR_ADDIU       daddiu
348 #define PTR_SUB         dadd
349 #define PTR_SUBI        dsubi
350 #define PTR_SUBU        dsubu
351 #define PTR_SUBIU       dsubu
352 #define PTR_L           ld
353 #define PTR_S           sd
354 #define PTR_SLL         dsll
355 #define PTR_SLLV        dsllv
356 #define PTR_SRL         dsrl
357 #define PTR_SRLV        dsrlv
358 #define PTR_SRA         dsra
359 #define PTR_SRAV        dsrav
360
361 #define PTR_SCALESHIFT  3
362 #endif
363
364 /*
365  * Some cp0 registers were extended to 64bit for MIPS III.
366  */
367 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
368 #define MFC0    mfc0
369 #define MTC0    mtc0
370 #endif
371 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
372     (_MIPS_ISA == _MIPS_ISA_MIPS5)
373 #define MFC0    dmfc0
374 #define MTC0    dmtc0
375 #endif
376
377 #endif /* sys/asm.h */