arm: Pass hwcap to ifuncs.
[glibc-ports.git] / sysdeps / mips / sys / asm.h
blob347d738f70c6d92331aa6469c3cb230ac20bdd3b
1 /* Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005, 2012
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ralf Baechle <ralf@gnu.org>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library. If not, see
18 <http://www.gnu.org/licenses/>. */
20 #ifndef _SYS_ASM_H
21 #define _SYS_ASM_H
23 #include <sgidefs.h>
25 #ifndef CAT
26 # define __CAT(str1,str2) str1##str2
27 # define CAT(str1,str2) __CAT(str1,str2)
28 #endif
31 * Macros to handle different pointer/register sizes for 32/64-bit code
33 * 64 bit address space isn't used yet, so we may use the R3000 32 bit
34 * defines for now.
36 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
37 # define PTR .word
38 # define PTRSIZE 4
39 # define PTRLOG 2
40 #elif _MIPS_SIM == _ABI64
41 # define PTR .dword
42 # define PTRSIZE 8
43 # define PTRLOG 3
44 #endif
47 * PIC specific declarations
49 #if _MIPS_SIM == _ABIO32
50 # ifdef __PIC__
51 # define CPRESTORE(register) \
52 .cprestore register
53 # define CPLOAD(register) \
54 .cpload register
55 # else
56 # define CPRESTORE(register)
57 # define CPLOAD(register)
58 # endif
60 # define CPADD(register) \
61 .cpadd register
64 * Set gp when at 1st instruction
66 # define SETUP_GP \
67 .set noreorder; \
68 .cpload $25; \
69 .set reorder
70 /* Set gp when not at 1st instruction */
71 # define SETUP_GPX(r) \
72 .set noreorder; \
73 move r, $31; /* Save old ra. */ \
74 bal 10f; /* Find addr of cpload. */ \
75 nop; \
76 10: \
77 .cpload $31; \
78 move $31, r; \
79 .set reorder
80 # define SETUP_GPX_L(r, l) \
81 .set noreorder; \
82 move r, $31; /* Save old ra. */ \
83 bal l; /* Find addr of cpload. */ \
84 nop; \
85 l: \
86 .cpload $31; \
87 move $31, r; \
88 .set reorder
89 # define SAVE_GP(x) \
90 .cprestore x /* Save gp trigger t9/jalr conversion. */
91 # define SETUP_GP64(a, b)
92 # define SETUP_GPX64(a, b)
93 # define SETUP_GPX64_L(cp_reg, ra_save, l)
94 # define RESTORE_GP64
95 # define USE_ALT_CP(a)
96 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
98 * For callee-saved gp calling convention:
100 # define SETUP_GP
101 # define SETUP_GPX(r)
102 # define SETUP_GPX_L(r, l)
103 # define SAVE_GP(x)
105 # define SETUP_GP64(gpoffset, proc) \
106 .cpsetup $25, gpoffset, proc
107 # define SETUP_GPX64(cp_reg, ra_save) \
108 move ra_save, $31; /* Save old ra. */ \
109 .set noreorder; \
110 bal 10f; /* Find addr of .cpsetup. */ \
111 nop; \
112 10: \
113 .set reorder; \
114 .cpsetup $31, cp_reg, 10b; \
115 move $31, ra_save
116 # define SETUP_GPX64_L(cp_reg, ra_save, l) \
117 move ra_save, $31; /* Save old ra. */ \
118 .set noreorder; \
119 bal l; /* Find addr of .cpsetup. */ \
120 nop; \
121 l: \
122 .set reorder; \
123 .cpsetup $31, cp_reg, l; \
124 move $31, ra_save
125 # define RESTORE_GP64 \
126 .cpreturn
127 /* Use alternate register for context pointer. */
128 # define USE_ALT_CP(reg) \
129 .cplocal reg
130 #endif /* _MIPS_SIM != _ABIO32 */
133 * Stack Frame Definitions
135 #if _MIPS_SIM == _ABIO32
136 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */
137 #endif
138 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
139 # define NARGSAVE 0 /* No caller responsibilities. */
140 #endif
144 * LEAF - declare leaf routine
146 #define LEAF(symbol) \
147 .globl symbol; \
148 .align 2; \
149 .type symbol,@function; \
150 .ent symbol,0; \
151 symbol: .frame sp,0,ra
154 * NESTED - declare nested routine entry point
156 #define NESTED(symbol, framesize, rpc) \
157 .globl symbol; \
158 .align 2; \
159 .type symbol,@function; \
160 .ent symbol,0; \
161 symbol: .frame sp, framesize, rpc
164 * END - mark end of function
166 #ifndef END
167 # define END(function) \
168 .end function; \
169 .size function,.-function
170 #endif
173 * EXPORT - export definition of symbol
175 #define EXPORT(symbol) \
176 .globl symbol; \
177 symbol:
180 * ABS - export absolute symbol
182 #define ABS(symbol,value) \
183 .globl symbol; \
184 symbol = value
186 #define PANIC(msg) \
187 .set push; \
188 .set reorder; \
189 la a0,8f; \
190 jal panic; \
191 9: b 9b; \
192 .set pop; \
193 TEXT(msg)
196 * Print formated string
198 #define PRINT(string) \
199 .set push; \
200 .set reorder; \
201 la a0,8f; \
202 jal printk; \
203 .set pop; \
204 TEXT(string)
206 #define TEXT(msg) \
207 .data; \
208 8: .asciiz msg; \
209 .previous;
212 * Build text tables
214 #define TTABLE(string) \
215 .text; \
216 .word 1f; \
217 .previous; \
218 .data; \
219 1: .asciz string; \
220 .previous
223 * MIPS IV pref instruction.
224 * Use with .set noreorder only!
226 * MIPS IV implementations are free to treat this as a nop. The R5000
227 * is one of them. So we should have an option not to use this instruction.
229 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
230 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
231 # define PREF(hint,addr) \
232 pref hint,addr
233 # define PREFX(hint,addr) \
234 prefx hint,addr
235 #else
236 # define PREF
237 # define PREFX
238 #endif
241 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
243 #if _MIPS_ISA == _MIPS_ISA_MIPS1
244 # define MOVN(rd,rs,rt) \
245 .set push; \
246 .set reorder; \
247 beqz rt,9f; \
248 move rd,rs; \
249 .set pop; \
251 # define MOVZ(rd,rs,rt) \
252 .set push; \
253 .set reorder; \
254 bnez rt,9f; \
255 move rd,rt; \
256 .set pop; \
258 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
259 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
260 # define MOVN(rd,rs,rt) \
261 .set push; \
262 .set noreorder; \
263 bnezl rt,9f; \
264 move rd,rs; \
265 .set pop; \
267 # define MOVZ(rd,rs,rt) \
268 .set push; \
269 .set noreorder; \
270 beqzl rt,9f; \
271 movz rd,rs; \
272 .set pop; \
274 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
275 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
276 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
277 # define MOVN(rd,rs,rt) \
278 movn rd,rs,rt
279 # define MOVZ(rd,rs,rt) \
280 movz rd,rs,rt
281 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
284 * Stack alignment
286 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
287 # define ALSZ 15
288 # define ALMASK ~15
289 #else
290 # define ALSZ 7
291 # define ALMASK ~7
292 #endif
295 * Size of a register
297 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
298 # define SZREG 8
299 #else
300 # define SZREG 4
301 #endif
304 * Use the following macros in assemblercode to load/store registers,
305 * pointers etc.
307 #if (SZREG == 4)
308 # define REG_S sw
309 # define REG_L lw
310 #else
311 # define REG_S sd
312 # define REG_L ld
313 #endif
316 * How to add/sub/load/store/shift C int variables.
318 #if (_MIPS_SZINT == 32)
319 # define INT_ADD add
320 # define INT_ADDI addi
321 # define INT_ADDU addu
322 # define INT_ADDIU addiu
323 # define INT_SUB add
324 # define INT_SUBI subi
325 # define INT_SUBU subu
326 # define INT_SUBIU subu
327 # define INT_L lw
328 # define INT_S sw
329 #endif
331 #if (_MIPS_SZINT == 64)
332 # define INT_ADD dadd
333 # define INT_ADDI daddi
334 # define INT_ADDU daddu
335 # define INT_ADDIU daddiu
336 # define INT_SUB dadd
337 # define INT_SUBI dsubi
338 # define INT_SUBU dsubu
339 # define INT_SUBIU dsubu
340 # define INT_L ld
341 # define INT_S sd
342 #endif
345 * How to add/sub/load/store/shift C long variables.
347 #if (_MIPS_SZLONG == 32)
348 # define LONG_ADD add
349 # define LONG_ADDI addi
350 # define LONG_ADDU addu
351 # define LONG_ADDIU addiu
352 # define LONG_SUB add
353 # define LONG_SUBI subi
354 # define LONG_SUBU subu
355 # define LONG_SUBIU subu
356 # define LONG_L lw
357 # define LONG_S sw
358 # define LONG_SLL sll
359 # define LONG_SLLV sllv
360 # define LONG_SRL srl
361 # define LONG_SRLV srlv
362 # define LONG_SRA sra
363 # define LONG_SRAV srav
364 #endif
366 #if (_MIPS_SZLONG == 64)
367 # define LONG_ADD dadd
368 # define LONG_ADDI daddi
369 # define LONG_ADDU daddu
370 # define LONG_ADDIU daddiu
371 # define LONG_SUB dadd
372 # define LONG_SUBI dsubi
373 # define LONG_SUBU dsubu
374 # define LONG_SUBIU dsubu
375 # define LONG_L ld
376 # define LONG_S sd
377 # define LONG_SLL dsll
378 # define LONG_SLLV dsllv
379 # define LONG_SRL dsrl
380 # define LONG_SRLV dsrlv
381 # define LONG_SRA dsra
382 # define LONG_SRAV dsrav
383 #endif
386 * How to add/sub/load/store/shift pointers.
388 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
389 # define PTR_ADD add
390 # define PTR_ADDI addi
391 # define PTR_ADDU addu
392 # define PTR_ADDIU addiu
393 # define PTR_SUB add
394 # define PTR_SUBI subi
395 # define PTR_SUBU subu
396 # define PTR_SUBIU subu
397 # define PTR_L lw
398 # define PTR_LA la
399 # define PTR_S sw
400 # define PTR_SLL sll
401 # define PTR_SLLV sllv
402 # define PTR_SRL srl
403 # define PTR_SRLV srlv
404 # define PTR_SRA sra
405 # define PTR_SRAV srav
407 # define PTR_SCALESHIFT 2
408 #endif
410 #if _MIPS_SIM == _ABIN32
411 # define PTR_ADD add
412 # define PTR_ADDI addi
413 # define PTR_ADDU add /* no u */
414 # define PTR_ADDIU addi /* no u */
415 # define PTR_SUB add
416 # define PTR_SUBI subi
417 # define PTR_SUBU sub /* no u */
418 # define PTR_SUBIU sub /* no u */
419 # define PTR_L lw
420 # define PTR_LA la
421 # define PTR_S sw
422 # define PTR_SLL sll
423 # define PTR_SLLV sllv
424 # define PTR_SRL srl
425 # define PTR_SRLV srlv
426 # define PTR_SRA sra
427 # define PTR_SRAV srav
429 # define PTR_SCALESHIFT 2
430 #endif
432 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
433 || _MIPS_SIM == _ABI64
434 # define PTR_ADD dadd
435 # define PTR_ADDI daddi
436 # define PTR_ADDU daddu
437 # define PTR_ADDIU daddiu
438 # define PTR_SUB dadd
439 # define PTR_SUBI dsubi
440 # define PTR_SUBU dsubu
441 # define PTR_SUBIU dsubu
442 # define PTR_L ld
443 # define PTR_LA dla
444 # define PTR_S sd
445 # define PTR_SLL dsll
446 # define PTR_SLLV dsllv
447 # define PTR_SRL dsrl
448 # define PTR_SRLV dsrlv
449 # define PTR_SRA dsra
450 # define PTR_SRAV dsrav
452 # define PTR_SCALESHIFT 3
453 #endif
456 * Some cp0 registers were extended to 64bit for MIPS III.
458 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
459 (_MIPS_ISA == _MIPS_ISA_MIPS32)
460 # define MFC0 mfc0
461 # define MTC0 mtc0
462 #endif
463 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
464 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
465 # define MFC0 dmfc0
466 # define MTC0 dmtc0
467 #endif
469 /* The MIPS archtectures do not have a uniform memory model. Particular
470 platforms may provide additional guarantees - for instance, the R4000
471 LL and SC instructions implicitly perform a SYNC, and the 4K promises
472 strong ordering.
474 However, in the absence of those guarantees, we must assume weak ordering
475 and SYNC explicitly where necessary.
477 Some obsolete MIPS processors may not support the SYNC instruction. This
478 applies to "true" MIPS I processors; most of the processors which compile
479 using MIPS I implement parts of MIPS II. */
481 #ifndef MIPS_SYNC
482 # define MIPS_SYNC sync
483 #endif
485 #endif /* sys/asm.h */