2006-01-10 Roland McGrath <roland@redhat.com>
[glibc-ports.git] / sysdeps / mips / sys / asm.h
blobb590802fd917fc31bcd43218227735231ac8188d
1 /* Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005
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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #ifndef _SYS_ASM_H
22 #define _SYS_ASM_H
24 #include <sgidefs.h>
26 #ifndef CAT
27 # ifdef __STDC__
28 # define __CAT(str1,str2) str1##str2
29 # else
30 # define __CAT(str1,str2) str1/**/str2
31 # endif
32 # define CAT(str1,str2) __CAT(str1,str2)
33 #endif
36 * Macros to handle different pointer/register sizes for 32/64-bit code
38 * 64 bit address space isn't used yet, so we may use the R3000 32 bit
39 * defines for now.
41 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
42 # define PTR .word
43 # define PTRSIZE 4
44 # define PTRLOG 2
45 #elif _MIPS_SIM == _ABI64
46 # define PTR .dword
47 # define PTRSIZE 8
48 # define PTRLOG 3
49 #endif
52 * PIC specific declarations
54 #if _MIPS_SIM == _ABIO32
55 # ifdef __PIC__
56 # define CPRESTORE(register) \
57 .cprestore register
58 # define CPLOAD(register) \
59 .cpload register
60 # else
61 # define CPRESTORE(register)
62 # define CPLOAD(register)
63 # endif
65 # define CPADD(register) \
66 .cpadd register
69 * Set gp when at 1st instruction
71 # define SETUP_GP \
72 .set noreorder; \
73 .cpload $25; \
74 .set reorder
75 /* Set gp when not at 1st instruction */
76 # define SETUP_GPX(r) \
77 .set noreorder; \
78 move r, $31; /* Save old ra. */ \
79 bal 10f; /* Find addr of cpload. */ \
80 nop; \
81 10: \
82 .cpload $31; \
83 move $31, r; \
84 .set reorder
85 # define SETUP_GPX_L(r, l) \
86 .set noreorder; \
87 move r, $31; /* Save old ra. */ \
88 bal l; /* Find addr of cpload. */ \
89 nop; \
90 l: \
91 .cpload $31; \
92 move $31, r; \
93 .set reorder
94 # define SAVE_GP(x) \
95 .cprestore x /* Save gp trigger t9/jalr conversion. */
96 # define SETUP_GP64(a, b)
97 # define SETUP_GPX64(a, b)
98 # define SETUP_GPX64_L(cp_reg, ra_save, l)
99 # define RESTORE_GP64
100 # define USE_ALT_CP(a)
101 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
103 * For callee-saved gp calling convention:
105 # define SETUP_GP
106 # define SETUP_GPX(r)
107 # define SETUP_GPX_L(r, l)
108 # define SAVE_GP(x)
110 # define SETUP_GP64(gpoffset, proc) \
111 .cpsetup $25, gpoffset, proc
112 # define SETUP_GPX64(cp_reg, ra_save) \
113 move ra_save, $31; /* Save old ra. */ \
114 .set noreorder; \
115 bal 10f; /* Find addr of .cpsetup. */ \
116 nop; \
117 10: \
118 .set reorder; \
119 .cpsetup $31, cp_reg, 10b; \
120 move $31, ra_save
121 # define SETUP_GPX64_L(cp_reg, ra_save, l) \
122 move ra_save, $31; /* Save old ra. */ \
123 .set noreorder; \
124 bal l; /* Find addr of .cpsetup. */ \
125 nop; \
126 l: \
127 .set reorder; \
128 .cpsetup $31, cp_reg, l; \
129 move $31, ra_save
130 # define RESTORE_GP64 \
131 .cpreturn
132 /* Use alternate register for context pointer. */
133 # define USE_ALT_CP(reg) \
134 .cplocal reg
135 #endif /* _MIPS_SIM != _ABIO32 */
138 * Stack Frame Definitions
140 #if _MIPS_SIM == _ABIO32
141 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */
142 #endif
143 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
144 # define NARGSAVE 0 /* No caller responsibilities. */
145 #endif
149 * LEAF - declare leaf routine
151 #define LEAF(symbol) \
152 .globl symbol; \
153 .align 2; \
154 .type symbol,@function; \
155 .ent symbol,0; \
156 symbol: .frame sp,0,ra
159 * NESTED - declare nested routine entry point
161 #define NESTED(symbol, framesize, rpc) \
162 .globl symbol; \
163 .align 2; \
164 .type symbol,@function; \
165 .ent symbol,0; \
166 symbol: .frame sp, framesize, rpc
169 * END - mark end of function
171 #ifndef END
172 # define END(function) \
173 .end function; \
174 .size function,.-function
175 #endif
178 * EXPORT - export definition of symbol
180 #define EXPORT(symbol) \
181 .globl symbol; \
182 symbol:
185 * ABS - export absolute symbol
187 #define ABS(symbol,value) \
188 .globl symbol; \
189 symbol = value
191 #define PANIC(msg) \
192 .set push; \
193 .set reorder; \
194 la a0,8f; \
195 jal panic; \
196 9: b 9b; \
197 .set pop; \
198 TEXT(msg)
201 * Print formated string
203 #define PRINT(string) \
204 .set push; \
205 .set reorder; \
206 la a0,8f; \
207 jal printk; \
208 .set pop; \
209 TEXT(string)
211 #define TEXT(msg) \
212 .data; \
213 8: .asciiz msg; \
214 .previous;
217 * Build text tables
219 #define TTABLE(string) \
220 .text; \
221 .word 1f; \
222 .previous; \
223 .data; \
224 1: .asciz string; \
225 .previous
228 * MIPS IV pref instruction.
229 * Use with .set noreorder only!
231 * MIPS IV implementations are free to treat this as a nop. The R5000
232 * is one of them. So we should have an option not to use this instruction.
234 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
235 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
236 # define PREF(hint,addr) \
237 pref hint,addr
238 # define PREFX(hint,addr) \
239 prefx hint,addr
240 #else
241 # define PREF
242 # define PREFX
243 #endif
246 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
248 #if _MIPS_ISA == _MIPS_ISA_MIPS1
249 # define MOVN(rd,rs,rt) \
250 .set push; \
251 .set reorder; \
252 beqz rt,9f; \
253 move rd,rs; \
254 .set pop; \
256 # define MOVZ(rd,rs,rt) \
257 .set push; \
258 .set reorder; \
259 bnez rt,9f; \
260 move rd,rt; \
261 .set pop; \
263 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
264 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
265 # define MOVN(rd,rs,rt) \
266 .set push; \
267 .set noreorder; \
268 bnezl rt,9f; \
269 move rd,rs; \
270 .set pop; \
272 # define MOVZ(rd,rs,rt) \
273 .set push; \
274 .set noreorder; \
275 beqzl rt,9f; \
276 movz rd,rs; \
277 .set pop; \
279 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
280 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
281 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
282 # define MOVN(rd,rs,rt) \
283 movn rd,rs,rt
284 # define MOVZ(rd,rs,rt) \
285 movz rd,rs,rt
286 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
289 * Stack alignment
291 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
292 # define ALSZ 15
293 # define ALMASK ~15
294 #else
295 # define ALSZ 7
296 # define ALMASK ~7
297 #endif
300 * Size of a register
302 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
303 # define SZREG 8
304 #else
305 # define SZREG 4
306 #endif
309 * Use the following macros in assemblercode to load/store registers,
310 * pointers etc.
312 #if (SZREG == 4)
313 # define REG_S sw
314 # define REG_L lw
315 #else
316 # define REG_S sd
317 # define REG_L ld
318 #endif
321 * How to add/sub/load/store/shift C int variables.
323 #if (_MIPS_SZINT == 32)
324 # define INT_ADD add
325 # define INT_ADDI addi
326 # define INT_ADDU addu
327 # define INT_ADDIU addiu
328 # define INT_SUB add
329 # define INT_SUBI subi
330 # define INT_SUBU subu
331 # define INT_SUBIU subu
332 # define INT_L lw
333 # define INT_S sw
334 #endif
336 #if (_MIPS_SZINT == 64)
337 # define INT_ADD dadd
338 # define INT_ADDI daddi
339 # define INT_ADDU daddu
340 # define INT_ADDIU daddiu
341 # define INT_SUB dadd
342 # define INT_SUBI dsubi
343 # define INT_SUBU dsubu
344 # define INT_SUBIU dsubu
345 # define INT_L ld
346 # define INT_S sd
347 #endif
350 * How to add/sub/load/store/shift C long variables.
352 #if (_MIPS_SZLONG == 32)
353 # define LONG_ADD add
354 # define LONG_ADDI addi
355 # define LONG_ADDU addu
356 # define LONG_ADDIU addiu
357 # define LONG_SUB add
358 # define LONG_SUBI subi
359 # define LONG_SUBU subu
360 # define LONG_SUBIU subu
361 # define LONG_L lw
362 # define LONG_S sw
363 # define LONG_SLL sll
364 # define LONG_SLLV sllv
365 # define LONG_SRL srl
366 # define LONG_SRLV srlv
367 # define LONG_SRA sra
368 # define LONG_SRAV srav
369 #endif
371 #if (_MIPS_SZLONG == 64)
372 # define LONG_ADD dadd
373 # define LONG_ADDI daddi
374 # define LONG_ADDU daddu
375 # define LONG_ADDIU daddiu
376 # define LONG_SUB dadd
377 # define LONG_SUBI dsubi
378 # define LONG_SUBU dsubu
379 # define LONG_SUBIU dsubu
380 # define LONG_L ld
381 # define LONG_S sd
382 # define LONG_SLL dsll
383 # define LONG_SLLV dsllv
384 # define LONG_SRL dsrl
385 # define LONG_SRLV dsrlv
386 # define LONG_SRA dsra
387 # define LONG_SRAV dsrav
388 #endif
391 * How to add/sub/load/store/shift pointers.
393 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
394 # define PTR_ADD add
395 # define PTR_ADDI addi
396 # define PTR_ADDU addu
397 # define PTR_ADDIU addiu
398 # define PTR_SUB add
399 # define PTR_SUBI subi
400 # define PTR_SUBU subu
401 # define PTR_SUBIU subu
402 # define PTR_L lw
403 # define PTR_LA la
404 # define PTR_S sw
405 # define PTR_SLL sll
406 # define PTR_SLLV sllv
407 # define PTR_SRL srl
408 # define PTR_SRLV srlv
409 # define PTR_SRA sra
410 # define PTR_SRAV srav
412 # define PTR_SCALESHIFT 2
413 #endif
415 #if _MIPS_SIM == _ABIN32
416 # define PTR_ADD add
417 # define PTR_ADDI addi
418 # define PTR_ADDU add /* no u */
419 # define PTR_ADDIU addi /* no u */
420 # define PTR_SUB add
421 # define PTR_SUBI subi
422 # define PTR_SUBU sub /* no u */
423 # define PTR_SUBIU sub /* no u */
424 # define PTR_L lw
425 # define PTR_LA la
426 # define PTR_S sw
427 # define PTR_SLL sll
428 # define PTR_SLLV sllv
429 # define PTR_SRL srl
430 # define PTR_SRLV srlv
431 # define PTR_SRA sra
432 # define PTR_SRAV srav
434 # define PTR_SCALESHIFT 2
435 #endif
437 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
438 || _MIPS_SIM == _ABI64
439 # define PTR_ADD dadd
440 # define PTR_ADDI daddi
441 # define PTR_ADDU daddu
442 # define PTR_ADDIU daddiu
443 # define PTR_SUB dadd
444 # define PTR_SUBI dsubi
445 # define PTR_SUBU dsubu
446 # define PTR_SUBIU dsubu
447 # define PTR_L ld
448 # define PTR_LA dla
449 # define PTR_S sd
450 # define PTR_SLL dsll
451 # define PTR_SLLV dsllv
452 # define PTR_SRL dsrl
453 # define PTR_SRLV dsrlv
454 # define PTR_SRA dsra
455 # define PTR_SRAV dsrav
457 # define PTR_SCALESHIFT 3
458 #endif
461 * Some cp0 registers were extended to 64bit for MIPS III.
463 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
464 (_MIPS_ISA == _MIPS_ISA_MIPS32)
465 # define MFC0 mfc0
466 # define MTC0 mtc0
467 #endif
468 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
469 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
470 # define MFC0 dmfc0
471 # define MTC0 dmtc0
472 #endif
474 /* The MIPS archtectures do not have a uniform memory model. Particular
475 platforms may provide additional guarantees - for instance, the R4000
476 LL and SC instructions implicitly perform a SYNC, and the 4K promises
477 strong ordering.
479 However, in the absence of those guarantees, we must assume weak ordering
480 and SYNC explicitly where necessary.
482 Some obsolete MIPS processors may not support the SYNC instruction. This
483 applies to "true" MIPS I processors; most of the processors which compile
484 using MIPS I implement parts of MIPS II. */
486 #ifndef MIPS_SYNC
487 # define MIPS_SYNC sync
488 #endif
490 #endif /* sys/asm.h */