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