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