(root)/
glibc-2.38/
sysdeps/
mips/
sys/
asm.h
       1  /* Copyright (C) 1997-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       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.
       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
      12     Lesser General Public License for more details.
      13  
      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/>.  */
      17  
      18  #ifndef _SYS_ASM_H
      19  #define _SYS_ASM_H
      20  
      21  #include <sgidefs.h>
      22  
      23  #ifndef CAT
      24  # define __CAT(str1,str2) str1##str2
      25  # define CAT(str1,str2) __CAT(str1,str2)
      26  #endif
      27  
      28  /* Redefined as nonempty in the internal header.  */
      29  #define __mips_cfi_startproc /* Empty.  */
      30  #define __mips_cfi_endproc /* Empty.  */
      31  
      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   */
      38  #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
      39  # define PTR .word
      40  # define PTRSIZE 4
      41  # define PTRLOG 2
      42  #elif _MIPS_SIM == _ABI64
      43  # define PTR .dword
      44  # define PTRSIZE 8
      45  # define PTRLOG 3
      46  #endif
      47  
      48  /*
      49   * PIC specific declarations
      50   */
      51  #if _MIPS_SIM == _ABIO32
      52  # ifdef __PIC__
      53  #  define CPRESTORE(register) \
      54  		.cprestore register
      55  #  define CPLOAD(register) \
      56  		.cpload register
      57  # else
      58  #  define CPRESTORE(register)
      59  #  define CPLOAD(register)
      60  # endif
      61  
      62  # define CPADD(register) \
      63  		.cpadd	register
      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;					\
      78  10:							\
      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;					\
      87  l:							\
      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)
      98  #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
      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;					\
     114  10:							\
     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;					\
     123  l:							\
     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
     132  #endif /* _MIPS_SIM != _ABIO32 */
     133  
     134  /*
     135   * Stack Frame Definitions
     136   */
     137  #if _MIPS_SIM == _ABIO32
     138  # define NARGSAVE 4 /* Space for 4 argument registers must be allocated.  */
     139  #endif
     140  #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
     141  # define NARGSAVE 0 /* No caller responsibilities.  */
     142  #endif
     143  
     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;                       \
     153  symbol:		.frame	sp,0,ra;			\
     154  		__mips_cfi_startproc
     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;                       \
     164  symbol:		.frame	sp, framesize, rpc;		\
     165  		__mips_cfi_startproc
     166  
     167  /*
     168   * END - mark end of function
     169   */
     170  #ifndef END
     171  # define END(function)                                   \
     172  		__mips_cfi_endproc;			\
     173  		.end	function;		        \
     174  		.size	function,.-function
     175  #endif
     176  
     177  /*
     178   * EXPORT - export definition of symbol
     179   */
     180  #define	EXPORT(symbol)                                  \
     181  		.globl	symbol;                         \
     182  symbol:		__mips_cfi_startproc
     183  
     184  /*
     185   * ABS - export absolute symbol
     186   */
     187  #define	ABS(symbol,value)                               \
     188  		.globl	symbol;                         \
     189  symbol		=	value
     190  
     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)
     199  
     200  /*
     201   * Print formatted 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;                                  \
     213  8:		.asciiz	msg;                            \
     214  		.previous;
     215  
     216  /*
     217   * Build text tables
     218   */
     219  #define TTABLE(string)                                  \
     220  		.text;                                  \
     221  		.word	1f;                             \
     222  		.previous;                              \
     223  		.data;                                  \
     224  1:		.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   */
     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(hint,addr)
     242  # define PREFX(hint,addr)
     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
     249  # define MOVN(rd,rs,rt)					\
     250  		.set	push;				\
     251  		.set	reorder;			\
     252  		beqz	rt,9f;				\
     253  		move	rd,rs;				\
     254  		.set	pop;				\
     255  9:
     256  # define MOVZ(rd,rs,rt)					\
     257  		.set	push;				\
     258  		.set	reorder;			\
     259  		bnez	rt,9f;				\
     260  		move	rd,rt;				\
     261  		.set	pop;				\
     262  9:
     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;				\
     271  9:
     272  # define MOVZ(rd,rs,rt)					\
     273  		.set	push;				\
     274  		.set	noreorder;			\
     275  		beqzl	rt,9f;				\
     276  		movz	rd,rs;				\
     277  		.set	pop;				\
     278  9:
     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) */
     287  
     288  /*
     289   * Stack alignment
     290   */
     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
     298  
     299  /*
     300   * Size of a register
     301   */
     302  #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
     303  # define SZREG	8
     304  #else
     305  # define SZREG	4
     306  #endif
     307  
     308  /*
     309   * Use the following macros in assemblercode to load/store registers,
     310   * pointers etc.
     311   */
     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
     319  
     320  /*
     321   * How to add/sub/load/store/shift C int variables.
     322   */
     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	sub
     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
     335  
     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
     345  # define INT_L		ld
     346  # define INT_S		sd
     347  #endif
     348  
     349  /*
     350   * How to add/sub/load/store/shift C long variables.
     351   */
     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
     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
     370  
     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
     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
     389  
     390  /*
     391   * How to add/sub/load/store/shift pointers.
     392   */
     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	sub
     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
     413  #endif
     414  
     415  #if _MIPS_SIM == _ABIN32
     416  # define PTR_ADD	add
     417  # define PTR_ADDI	addi
     418  # define PTR_SUB	sub
     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 */
     425  #else
     426  # define PTR_ADDU       addu
     427  # define PTR_ADDIU      addiu
     428  # define PTR_SUBU       subu
     429  # define PTR_SUBIU      subu
     430  #endif
     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  
     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
     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
     465  #endif
     466  
     467  /*
     468   * Some cp0 registers were extended to 64bit for MIPS III.
     469   */
     470  #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) \
     471      || (_MIPS_ISA == _MIPS_ISA_MIPS32)
     472  # define MFC0	mfc0
     473  # define MTC0	mtc0
     474  #endif
     475  #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) \
     476      || (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
     477  # define MFC0	dmfc0
     478  # define MTC0	dmtc0
     479  #endif
     480  
     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
     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  
     497  #endif /* sys/asm.h */