1 /* Copyright (C) 1997-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
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.
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
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library. If not, see
16 <https://www.gnu.org/licenses/>. */
24 # define __CAT(str1,str2) str1##str2
25 # define CAT(str1,str2) __CAT(str1,str2)
28 /* Redefined as nonempty in the internal header. */
29 #define __mips_cfi_startproc /* Empty. */
30 #define __mips_cfi_endproc /* Empty. */
33 * Macros to handle different pointer/register sizes for 32/64-bit code
35 * 64 bit address space isn't used yet, so we may use the R3000 32 bit
38 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
42 #elif _MIPS_SIM == _ABI64
49 * PIC specific declarations
51 #if _MIPS_SIM == _ABIO32
53 # define CPRESTORE(register) \
55 # define CPLOAD(register) \
58 # define CPRESTORE(register)
59 # define CPLOAD(register)
62 # define CPADD(register) \
66 * Set gp when at 1st instruction
72 /* Set gp when not at 1st instruction */
73 # define SETUP_GPX(r) \
75 move r, $31; /* Save old ra. */ \
76 bal 10f; /* Find addr of cpload. */ \
82 # define SETUP_GPX_L(r, l) \
84 move r, $31; /* Save old ra. */ \
85 bal l; /* Find addr of cpload. */ \
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)
97 # define USE_ALT_CP(a)
98 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
100 * For callee-saved gp calling convention:
103 # define SETUP_GPX(r)
104 # define SETUP_GPX_L(r, l)
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. */ \
112 bal 10f; /* Find addr of .cpsetup. */ \
116 .cpsetup $31, cp_reg, 10b; \
118 # define SETUP_GPX64_L(cp_reg, ra_save, l) \
119 move ra_save, $31; /* Save old ra. */ \
121 bal l; /* Find addr of .cpsetup. */ \
125 .cpsetup $31, cp_reg, l; \
127 # define RESTORE_GP64 \
129 /* Use alternate register for context pointer. */
130 # define USE_ALT_CP(reg) \
132 #endif /* _MIPS_SIM != _ABIO32 */
135 * Stack Frame Definitions
137 #if _MIPS_SIM == _ABIO32
138 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */
140 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
141 # define NARGSAVE 0 /* No caller responsibilities. */
146 * LEAF - declare leaf routine
148 #define LEAF(symbol) \
151 .type symbol,@function; \
153 symbol: .frame sp,0,ra; \
157 * NESTED - declare nested routine entry point
159 #define NESTED(symbol, framesize, rpc) \
162 .type symbol,@function; \
164 symbol: .frame sp, framesize, rpc; \
168 * END - mark end of function
171 # define END(function) \
172 __mips_cfi_endproc; \
174 .size function,.-function
178 * EXPORT - export definition of symbol
180 #define EXPORT(symbol) \
182 symbol: __mips_cfi_startproc
185 * ABS - export absolute symbol
187 #define ABS(symbol,value) \
201 * Print formatted string
203 #define PRINT(string) \
219 #define TTABLE(string) \
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) \
238 # define PREFX(hint,addr) \
241 # define PREF(hint,addr)
242 # define PREFX(hint,addr)
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) \
256 # define MOVZ(rd,rs,rt) \
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) \
272 # define MOVZ(rd,rs,rt) \
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) \
284 # define MOVZ(rd,rs,rt) \
286 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
291 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
302 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
309 * Use the following macros in assemblercode to load/store registers,
321 * How to add/sub/load/store/shift C int variables.
323 #if (_MIPS_SZINT == 32)
325 # define INT_ADDI addi
326 # define INT_ADDU addu
327 # define INT_ADDIU addiu
329 # define INT_SUBI subi
330 # define INT_SUBU subu
331 # define INT_SUBIU subu
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 dsub
342 # define INT_SUBI dsubi
343 # define INT_SUBU dsubu
344 # define INT_SUBIU dsubu
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 sub
358 # define LONG_SUBI subi
359 # define LONG_SUBU subu
360 # define LONG_SUBIU subu
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
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 dsub
377 # define LONG_SUBI dsubi
378 # define LONG_SUBU dsubu
379 # define LONG_SUBIU dsubu
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
391 * How to add/sub/load/store/shift pointers.
393 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
395 # define PTR_ADDI addi
396 # define PTR_ADDU addu
397 # define PTR_ADDIU addiu
399 # define PTR_SUBI subi
400 # define PTR_SUBU subu
401 # define PTR_SUBIU subu
406 # define PTR_SLLV sllv
408 # define PTR_SRLV srlv
410 # define PTR_SRAV srav
412 # define PTR_SCALESHIFT 2
415 #if _MIPS_SIM == _ABIN32
417 # define PTR_ADDI addi
419 # define PTR_SUBI subi
420 #if !defined __mips_isa_rev || __mips_isa_rev < 6
421 # define PTR_ADDU add /* no u */
422 # define PTR_ADDIU addi /* no u */
423 # define PTR_SUBU sub /* no u */
424 # define PTR_SUBIU sub /* no u */
426 # define PTR_ADDU addu
427 # define PTR_ADDIU addiu
428 # define PTR_SUBU subu
429 # define PTR_SUBIU subu
435 # define PTR_SLLV sllv
437 # define PTR_SRLV srlv
439 # define PTR_SRAV srav
441 # define PTR_SCALESHIFT 2
444 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
445 || _MIPS_SIM == _ABI64
446 # define PTR_ADD dadd
447 # define PTR_ADDI daddi
448 # define PTR_ADDU daddu
449 # define PTR_ADDIU daddiu
450 # define PTR_SUB dsub
451 # define PTR_SUBI dsubi
452 # define PTR_SUBU dsubu
453 # define PTR_SUBIU dsubu
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
464 # define PTR_SCALESHIFT 3
468 * Some cp0 registers were extended to 64bit for MIPS III.
470 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) \
471 || (_MIPS_ISA == _MIPS_ISA_MIPS32)
475 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) \
476 || (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
481 /* The MIPS architectures do not have a uniform memory model. Particular
482 platforms may provide additional guarantees - for instance, the R4000
483 LL and SC instructions implicitly perform a SYNC, and the 4K promises
486 However, in the absence of those guarantees, we must assume weak ordering
487 and SYNC explicitly where necessary.
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. */
494 # define MIPS_SYNC sync
497 #endif /* sys/asm.h */