newlib-cygwin/newlib/libc/machine/mips/machine/asm.h

362 lines
10 KiB
C

/*
* Copyright (c) 1996-2007 MIPS Technologies, Inc.
* Copyright (C) 2009 CodeSourcery, LLC.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with
* the distribution.
* * Neither the name of MIPS Technologies Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* asm.h: various macros to help assembly language writers
*/
#ifndef _MIPS_ASM_H_
#define _MIPS_ASM_H_
/* ABI specific stack frame layout and manipulation. */
#if _MIPS_SIM==_ABIO32 && ! __mips64
/* Standard O32 */
#define SZREG 4 /* saved register size */
#define REG_S sw /* store saved register */
#define REG_L lw /* load saved register */
#define SZARG 4 /* argument register size */
#define NARGSAVE 4 /* arg register space on caller stack */
#define ALSZ 7 /* stack alignment - 1 */
#define ALMASK (~7) /* stack alignment mask */
#define LOG2_STACK_ALGN 3 /* log2(8) */
#define SZPTR 4 /* pointer size */
#define LOG2_SZPTR 2 /* log2(4) */
#define PTR_S sw /* store pointer */
#define PTR_L lw /* load pointer */
#define PTR_SUBU subu /* decrement pointer */
#define PTR_ADDU addu /* increment pointer */
#define PTR .word /* pointer type pseudo */
#elif _MIPS_SIM==_ABIO32 && __mips64
/* Algorithmics O32+64-bit */
#define SZREG 8 /* saved register size */
#define REG_S sd /* store saved register */
#define REG_L ld /* load saved register */
#define SZARG 4 /* argument register size */
#define NARGSAVE 4 /* arg register space on caller stack */
#define ALSZ 7 /* stack alignment - 1 */
#define ALMASK (~7) /* stack alignment mask */
#define LOG2_STACK_ALGN 3 /* log2(8) */
#define SZPTR 4 /* pointer size */
#define LOG2_SZPTR 2 /* log2(4) */
#define PTR_S sw /* store pointer */
#define PTR_L lw /* load pointer */
#define PTR_SUBU subu /* decrement pointer */
#define PTR_ADDU addu /* increment pointer */
#define PTR .word /* pointer type pseudo */
#elif _MIPS_SIM==_ABIO64
/* Cygnus O64 */
#define SZREG 8 /* saved register size */
#define REG_S sd /* store saved register */
#define REG_L ld /* load saved register */
#define SZARG 8 /* argument register size */
#define NARGSAVE 4 /* arg register space on caller stack */
#define ALSZ 7 /* stack alignment - 1 */
#define ALMASK (~7) /* stack alignment mask */
#define LOG2_STACK_ALGN 3 /* log2(8) */
#define SZPTR 4 /* pointer size */
#define LOG2_SZPTR 2 /* log2(4) */
#define PTR_S sw /* store pointer */
#define PTR_L lw /* load pointer */
#define PTR_SUBU subu /* decrement pointer */
#define PTR_ADDU addu /* increment pointer */
#define PTR .word /* pointer type pseudo */
#elif _MIPS_SIM==_ABIN32
/* Standard N32 */
#define SZREG 8 /* saved register size */
#define REG_S sd /* store saved register */
#define REG_L ld /* load saved register */
#define SZARG 8 /* argument register size */
#define NARGSAVE 0 /* arg register space on caller stack */
#define ALSZ 15 /* stack alignment - 1 */
#define ALMASK (~15) /* stack alignment mask */
#define LOG2_STACK_ALGN 4 /* log2(16) */
#define SZPTR 4 /* pointer size */
#define LOG2_SZPTR 2 /* log2(4) */
#define PTR_S sw /* store pointer */
#define PTR_L lw /* load pointer */
#define PTR_SUBU subu /* decrement pointer (SGI uses sub) */
#define PTR_ADDU addu /* increment pointer (SGI uses add) */
#define PTR .word /* pointer type pseudo */
#elif _MIPS_SIM==_ABI64
/* Standard N64 */
#define SZREG 8 /* saved register size */
#define REG_S sd /* store saved register */
#define REG_L ld /* load saved register */
#define SZARG 8 /* argument register size */
#define NARGSAVE 0 /* arg register space on caller stack */
#define ALSZ 15 /* stack alignment - 1 */
#define ALMASK (~15) /* stack alignment mask */
#define LOG2_STACK_ALGN 4 /* log2(16) */
#define SZPTR 8 /* pointer size */
#define LOG2_SZPTR 3 /* log2(8) */
#define PTR_S sd /* store pointer */
#define PTR_L ld /* load pointer */
#define PTR_SUBU dsubu /* decrement pointer */
#define PTR_ADDU daddu /* increment pointer */
#define PTR .dword /* pointer type pseudo */
#else
#error Unknown ABI
#endif
/* Concatenate two names. */
#ifdef __STDC__
# define _ASMCONCAT(A, B) A ## B
#else
# define _ASMCONCAT(A, B) A/**/B
#endif
/* Name of reset code section. */
#ifndef _RESET_SECTION
# define _RESET_SECTION .section .reset, "ax", @progbits
#endif
#ifndef _RESET_SECTION_NAMED
/* No function section support for now, since binutils fails to cope with
external branches. */
# define _RESET_SECTION_NAMED(name) .pushsection .reset, "ax", @progbits
#endif
/* Name of boot code section. */
#ifndef _BOOT_SECTION
# define _BOOT_SECTION .section .boot, "ax", @progbits
#endif
#ifndef _BOOT_SECTION_NAMED
/* No function section support for now, since binutils fails to cope with
external branches. */
# define _BOOT_SECTION_NAMED(name) .pushsection .boot, "ax", @progbits
#endif
/* Name of standard code section. */
#ifndef _NORMAL_SECTION_UNNAMED
# define _NORMAL_SECTION_UNNAMED .section .text, "ax", @progbits
#endif
#ifndef _NORMAL_SECTION_NAMED
# ifdef _FUNCTION_SECTIONS_
# define _NORMAL_SECTION_NAMED(name) .pushsection .text ##.name, "ax", @progbits
# else
# define _NORMAL_SECTION_NAMED(name) .pushsection .text, "ax", @progbits
# endif
#endif
/* Default code section. */
#ifndef _TEXT_SECTION_NAMED
# if defined(_RESETCODE)
# define _TEXT_SECTION_NAMED _RESET_SECTION_NAMED
# elif defined(_BOOTCODE)
# define _TEXT_SECTION_NAMED _BOOT_SECTION_NAMED
# else
# define _TEXT_SECTION_NAMED _NORMAL_SECTION_NAMED
# endif
#endif
#ifndef _TEXT_SECTION
# if defined(_RESETCODE)
# define _TEXT_SECTION _RESET_SECTION
# elif defined(_BOOTCODE)
# define _TEXT_SECTION _BOOT_SECTION
# else
# define _TEXT_SECTION _NORMAL_SECTION_UNNAMED
# endif
_TEXT_SECTION
#endif
/*
* Leaf functions declarations.
*/
/* Global leaf function. */
#define LEAF(name) \
_TEXT_SECTION_NAMED(name); \
.globl name; \
.balign 4; \
.ent name; \
name:
/* Static/Local leaf function. */
#define SLEAF(name) \
_TEXT_SECTION_NAMED(name); \
.balign 4; \
.ent name; \
name:
/* Weak leaf function. */
#define WLEAF(name) \
_TEXT_SECTION_NAMED(name); \
.weakext name; \
.balign 4; \
.ent name; \
name:
/* Weak alias leaf function. */
#define ALEAF(name,alias) \
_TEXT_SECTION_NAMED(name); \
.weakext alias,name; \
.balign 4; \
.ent name; \
name:
/*
* Alternative function entrypoints.
*/
/* Global alternative entrypoint. */
#define AENT(name) \
.globl name; \
.balign 4; \
.aent name; \
name:
#define XLEAF(name) AENT(name)
/* Local/static alternative entrypoint. */
#define SAENT(name) \
.balign 4; \
.aent name; \
name:
#define SXLEAF(name) SAENT(name)
/*
* Leaf functions declarations.
*/
/* Global nested function. */
#define NESTED(name, framesz, rareg) \
_TEXT_SECTION_NAMED(name); \
.globl name; \
.balign 4; \
.ent name; \
.frame sp, framesz, rareg; \
name:
/* Static/Local nested function. */
#define SNESTED(name, framesz, rareg) \
_TEXT_SECTION_NAMED(name); \
.balign 4; \
.ent name; \
.frame sp, framesz, rareg; \
name:
/* Weak nested function. */
#define WNESTED(name, framesz, rareg) \
_TEXT_SECTION_NAMED(name); \
.weakext name; \
.balign 4; \
.ent name; \
.frame sp, framesz, rareg; \
name:
/* Weak alias nested function. */
#define ANESTED(name, alias, framesz, rareg) \
_TEXT_SECTION_NAMED(name); \
.weakext alias, name; \
.balign 4; \
.ent name; \
.frame sp, framesz, rareg; \
name:
/*
* Function termination
*/
#define END(name) \
.size name,.-name; \
.end name; \
.popsection
#define SEND(name) END(name)
#define WEND(name) END(name)
#define AEND(name,alias) END(name)
/*
* Global data declaration.
*/
#define EXPORT(name) \
.globl name; \
.type name,@object; \
name:
/*
* Global data declaration with size.
*/
#define EXPORTS(name,sz) \
.globl name; \
.type name,@object; \
.size name,sz; \
name:
/*
* Weak data declaration with size.
*/
#define WEXPORT(name,sz) \
.weakext name; \
.type name,@object; \
.size name,sz; \
name:
/*
* Global data reference with size.
*/
#define IMPORT(name, size) \
.extern name,size
/*
* Global zeroed data.
*/
#define BSS(name,size) \
.type name,@object; \
.comm name,size
/*
* Local zeroed data.
*/
#define LBSS(name,size) \
.lcomm name,size
/*
* Insert call to _mcount if profiling.
*/
#ifdef __PROFILING__
#define _MCOUNT \
.set push; \
.set noat; \
move $1,$31; \
jal _mcount; \
.set pop
#else
#define _MCOUNT
#endif
#endif