2014-12-19 Steve Ellcey <sellcey@imgtec.com>
[glibc.git] / sysdeps / mips / sys / asm.h
bloba618d4974d1f9fd6cc8662a6720adebad972d8e5
1 /* Copyright (C) 1997-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ralf Baechle <ralf@gnu.org>.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef _SYS_ASM_H
20 #define _SYS_ASM_H
22 #include <sgidefs.h>
24 #ifndef CAT
25 # define __CAT(str1,str2) str1##str2
26 # define CAT(str1,str2) __CAT(str1,str2)
27 #endif
29 /* Redefined as nonempty in the internal header. */
30 #define __mips_cfi_startproc /* Empty. */
31 #define __mips_cfi_endproc /* Empty. */
34 * Macros to handle different pointer/register sizes for 32/64-bit code
36 * 64 bit address space isn't used yet, so we may use the R3000 32 bit
37 * defines for now.
39 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
40 # define PTR .word
41 # define PTRSIZE 4
42 # define PTRLOG 2
43 #elif _MIPS_SIM == _ABI64
44 # define PTR .dword
45 # define PTRSIZE 8
46 # define PTRLOG 3
47 #endif
50 * PIC specific declarations
52 #if _MIPS_SIM == _ABIO32
53 # ifdef __PIC__
54 # define CPRESTORE(register) \
55 .cprestore register
56 # define CPLOAD(register) \
57 .cpload register
58 # else
59 # define CPRESTORE(register)
60 # define CPLOAD(register)
61 # endif
63 # define CPADD(register) \
64 .cpadd register
67 * Set gp when at 1st instruction
69 # define SETUP_GP \
70 .set noreorder; \
71 .cpload $25; \
72 .set reorder
73 /* Set gp when not at 1st instruction */
74 # define SETUP_GPX(r) \
75 .set noreorder; \
76 move r, $31; /* Save old ra. */ \
77 bal 10f; /* Find addr of cpload. */ \
78 nop; \
79 10: \
80 .cpload $31; \
81 move $31, r; \
82 .set reorder
83 # define SETUP_GPX_L(r, l) \
84 .set noreorder; \
85 move r, $31; /* Save old ra. */ \
86 bal l; /* Find addr of cpload. */ \
87 nop; \
88 l: \
89 .cpload $31; \
90 move $31, r; \
91 .set reorder
92 # define SAVE_GP(x) \
93 .cprestore x /* Save gp trigger t9/jalr conversion. */
94 # define SETUP_GP64(a, b)
95 # define SETUP_GPX64(a, b)
96 # define SETUP_GPX64_L(cp_reg, ra_save, l)
97 # define RESTORE_GP64
98 # define USE_ALT_CP(a)
99 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
101 * For callee-saved gp calling convention:
103 # define SETUP_GP
104 # define SETUP_GPX(r)
105 # define SETUP_GPX_L(r, l)
106 # define SAVE_GP(x)
108 # define SETUP_GP64(gpoffset, proc) \
109 .cpsetup $25, gpoffset, proc
110 # define SETUP_GPX64(cp_reg, ra_save) \
111 move ra_save, $31; /* Save old ra. */ \
112 .set noreorder; \
113 bal 10f; /* Find addr of .cpsetup. */ \
114 nop; \
115 10: \
116 .set reorder; \
117 .cpsetup $31, cp_reg, 10b; \
118 move $31, ra_save
119 # define SETUP_GPX64_L(cp_reg, ra_save, l) \
120 move ra_save, $31; /* Save old ra. */ \
121 .set noreorder; \
122 bal l; /* Find addr of .cpsetup. */ \
123 nop; \
124 l: \
125 .set reorder; \
126 .cpsetup $31, cp_reg, l; \
127 move $31, ra_save
128 # define RESTORE_GP64 \
129 .cpreturn
130 /* Use alternate register for context pointer. */
131 # define USE_ALT_CP(reg) \
132 .cplocal reg
133 #endif /* _MIPS_SIM != _ABIO32 */
136 * Stack Frame Definitions
138 #if _MIPS_SIM == _ABIO32
139 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */
140 #endif
141 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
142 # define NARGSAVE 0 /* No caller responsibilities. */
143 #endif
147 * LEAF - declare leaf routine
149 #define LEAF(symbol) \
150 .globl symbol; \
151 .align 2; \
152 .type symbol,@function; \
153 .ent symbol,0; \
154 symbol: .frame sp,0,ra; \
155 __mips_cfi_startproc
158 * NESTED - declare nested routine entry point
160 #define NESTED(symbol, framesize, rpc) \
161 .globl symbol; \
162 .align 2; \
163 .type symbol,@function; \
164 .ent symbol,0; \
165 symbol: .frame sp, framesize, rpc; \
166 __mips_cfi_startproc
169 * END - mark end of function
171 #ifndef END
172 # define END(function) \
173 __mips_cfi_endproc; \
174 .end function; \
175 .size function,.-function
176 #endif
179 * EXPORT - export definition of symbol
181 #define EXPORT(symbol) \
182 .globl symbol; \
183 symbol: __mips_cfi_startproc
186 * ABS - export absolute symbol
188 #define ABS(symbol,value) \
189 .globl symbol; \
190 symbol = value
192 #define PANIC(msg) \
193 .set push; \
194 .set reorder; \
195 la a0,8f; \
196 jal panic; \
197 9: b 9b; \
198 .set pop; \
199 TEXT(msg)
202 * Print formated string
204 #define PRINT(string) \
205 .set push; \
206 .set reorder; \
207 la a0,8f; \
208 jal printk; \
209 .set pop; \
210 TEXT(string)
212 #define TEXT(msg) \
213 .data; \
214 8: .asciiz msg; \
215 .previous;
218 * Build text tables
220 #define TTABLE(string) \
221 .text; \
222 .word 1f; \
223 .previous; \
224 .data; \
225 1: .asciz string; \
226 .previous
229 * MIPS IV pref instruction.
230 * Use with .set noreorder only!
232 * MIPS IV implementations are free to treat this as a nop. The R5000
233 * is one of them. So we should have an option not to use this instruction.
235 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
236 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
237 # define PREF(hint,addr) \
238 pref hint,addr
239 # define PREFX(hint,addr) \
240 prefx hint,addr
241 #else
242 # define PREF(hint,addr)
243 # define PREFX(hint,addr)
244 #endif
247 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
249 #if _MIPS_ISA == _MIPS_ISA_MIPS1
250 # define MOVN(rd,rs,rt) \
251 .set push; \
252 .set reorder; \
253 beqz rt,9f; \
254 move rd,rs; \
255 .set pop; \
257 # define MOVZ(rd,rs,rt) \
258 .set push; \
259 .set reorder; \
260 bnez rt,9f; \
261 move rd,rt; \
262 .set pop; \
264 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
265 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
266 # define MOVN(rd,rs,rt) \
267 .set push; \
268 .set noreorder; \
269 bnezl rt,9f; \
270 move rd,rs; \
271 .set pop; \
273 # define MOVZ(rd,rs,rt) \
274 .set push; \
275 .set noreorder; \
276 beqzl rt,9f; \
277 movz rd,rs; \
278 .set pop; \
280 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
281 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
282 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
283 # define MOVN(rd,rs,rt) \
284 movn rd,rs,rt
285 # define MOVZ(rd,rs,rt) \
286 movz rd,rs,rt
287 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
290 * Stack alignment
292 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
293 # define ALSZ 15
294 # define ALMASK ~15
295 #else
296 # define ALSZ 7
297 # define ALMASK ~7
298 #endif
301 * Size of a register
303 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
304 # define SZREG 8
305 #else
306 # define SZREG 4
307 #endif
310 * Use the following macros in assemblercode to load/store registers,
311 * pointers etc.
313 #if (SZREG == 4)
314 # define REG_S sw
315 # define REG_L lw
316 #else
317 # define REG_S sd
318 # define REG_L ld
319 #endif
322 * How to add/sub/load/store/shift C int variables.
324 #if (_MIPS_SZINT == 32)
325 # define INT_ADD add
326 # define INT_ADDI addi
327 # define INT_ADDU addu
328 # define INT_ADDIU addiu
329 # define INT_SUB sub
330 # define INT_SUBI subi
331 # define INT_SUBU subu
332 # define INT_SUBIU subu
333 # define INT_L lw
334 # define INT_S sw
335 #endif
337 #if (_MIPS_SZINT == 64)
338 # define INT_ADD dadd
339 # define INT_ADDI daddi
340 # define INT_ADDU daddu
341 # define INT_ADDIU daddiu
342 # define INT_SUB dsub
343 # define INT_SUBI dsubi
344 # define INT_SUBU dsubu
345 # define INT_SUBIU dsubu
346 # define INT_L ld
347 # define INT_S sd
348 #endif
351 * How to add/sub/load/store/shift C long variables.
353 #if (_MIPS_SZLONG == 32)
354 # define LONG_ADD add
355 # define LONG_ADDI addi
356 # define LONG_ADDU addu
357 # define LONG_ADDIU addiu
358 # define LONG_SUB sub
359 # define LONG_SUBI subi
360 # define LONG_SUBU subu
361 # define LONG_SUBIU subu
362 # define LONG_L lw
363 # define LONG_S sw
364 # define LONG_SLL sll
365 # define LONG_SLLV sllv
366 # define LONG_SRL srl
367 # define LONG_SRLV srlv
368 # define LONG_SRA sra
369 # define LONG_SRAV srav
370 #endif
372 #if (_MIPS_SZLONG == 64)
373 # define LONG_ADD dadd
374 # define LONG_ADDI daddi
375 # define LONG_ADDU daddu
376 # define LONG_ADDIU daddiu
377 # define LONG_SUB dsub
378 # define LONG_SUBI dsubi
379 # define LONG_SUBU dsubu
380 # define LONG_SUBIU dsubu
381 # define LONG_L ld
382 # define LONG_S sd
383 # define LONG_SLL dsll
384 # define LONG_SLLV dsllv
385 # define LONG_SRL dsrl
386 # define LONG_SRLV dsrlv
387 # define LONG_SRA dsra
388 # define LONG_SRAV dsrav
389 #endif
392 * How to add/sub/load/store/shift pointers.
394 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
395 # define PTR_ADD add
396 # define PTR_ADDI addi
397 # define PTR_ADDU addu
398 # define PTR_ADDIU addiu
399 # define PTR_SUB sub
400 # define PTR_SUBI subi
401 # define PTR_SUBU subu
402 # define PTR_SUBIU subu
403 # define PTR_L lw
404 # define PTR_LA la
405 # define PTR_S sw
406 # define PTR_SLL sll
407 # define PTR_SLLV sllv
408 # define PTR_SRL srl
409 # define PTR_SRLV srlv
410 # define PTR_SRA sra
411 # define PTR_SRAV srav
413 # define PTR_SCALESHIFT 2
414 #endif
416 #if _MIPS_SIM == _ABIN32
417 # define PTR_ADD add
418 # define PTR_ADDI addi
419 # define PTR_SUB sub
420 # define PTR_SUBI subi
421 #if __mips_isa_rev < 6
422 # define PTR_ADDU add /* no u */
423 # define PTR_ADDIU addi /* no u */
424 # define PTR_SUBU sub /* no u */
425 # define PTR_SUBIU sub /* no u */
426 #else
427 # define PTR_ADDU addu
428 # define PTR_ADDIU addiu
429 # define PTR_SUBU subu
430 # define PTR_SUBIU subu
431 #endif
432 # define PTR_L lw
433 # define PTR_LA la
434 # define PTR_S sw
435 # define PTR_SLL sll
436 # define PTR_SLLV sllv
437 # define PTR_SRL srl
438 # define PTR_SRLV srlv
439 # define PTR_SRA sra
440 # define PTR_SRAV srav
442 # define PTR_SCALESHIFT 2
443 #endif
445 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
446 || _MIPS_SIM == _ABI64
447 # define PTR_ADD dadd
448 # define PTR_ADDI daddi
449 # define PTR_ADDU daddu
450 # define PTR_ADDIU daddiu
451 # define PTR_SUB dsub
452 # define PTR_SUBI dsubi
453 # define PTR_SUBU dsubu
454 # define PTR_SUBIU dsubu
455 # define PTR_L ld
456 # define PTR_LA dla
457 # define PTR_S sd
458 # define PTR_SLL dsll
459 # define PTR_SLLV dsllv
460 # define PTR_SRL dsrl
461 # define PTR_SRLV dsrlv
462 # define PTR_SRA dsra
463 # define PTR_SRAV dsrav
465 # define PTR_SCALESHIFT 3
466 #endif
469 * Some cp0 registers were extended to 64bit for MIPS III.
471 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
472 (_MIPS_ISA == _MIPS_ISA_MIPS32)
473 # define MFC0 mfc0
474 # define MTC0 mtc0
475 #endif
476 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
477 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
478 # define MFC0 dmfc0
479 # define MTC0 dmtc0
480 #endif
482 /* The MIPS architectures do not have a uniform memory model. Particular
483 platforms may provide additional guarantees - for instance, the R4000
484 LL and SC instructions implicitly perform a SYNC, and the 4K promises
485 strong ordering.
487 However, in the absence of those guarantees, we must assume weak ordering
488 and SYNC explicitly where necessary.
490 Some obsolete MIPS processors may not support the SYNC instruction. This
491 applies to "true" MIPS I processors; most of the processors which compile
492 using MIPS I implement parts of MIPS II. */
494 #ifndef MIPS_SYNC
495 # define MIPS_SYNC sync
496 #endif
498 #endif /* sys/asm.h */