asm_help.h   [plain text]


/*
 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

#ifndef	_ARCH_ARM_ASM_HELP_H_
#define	_ARCH_ARM_ASM_HELP_H_

#include	<architecture/arm/reg_help.h>

#ifdef	__ASSEMBLER__

#if defined(__arm__)

#define ALIGN						\
	.align	2

#define	ROUND_TO_STACK(len)				\
	(((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)

/*
 * Macros for declaring procedures
 *
 * Use of these macros allows ctags to have a predictable way
 * to find various types of declarations.  They also simplify
 * inserting appropriate symbol table information.
 *
 * NOTE: these simple stubs will be replaced with more
 * complicated versions once we know what the linker and gdb
 * will require as far as register use masks and frame declarations.
 * These macros may also be ifdef'ed in the future to contain profiling
 * code.
 *
 */

/*
 * TEXT -- declare start of text segment
 */
#define	TEXT						\
	.text

/*
 * DATA -- declare start of data segment
 */
#define DATA						\
	.data

/*
 * LEAF -- declare global leaf procedure
 * NOTE: Control SHOULD NOT FLOW into a LEAF!  A LEAF should only
 * be jumped to.  (A leaf may do an align.)  Use a LABEL() if you
 * need control to flow into the label.
 */
#define	LEAF(name, localvarsize)			\
	.globl	name					;\
	ALIGN						;\
name:

/*
 * X_LEAF -- declare alternate global label for leaf
 */
#define	X_LEAF(name, value)				\
	.globl	name					;\
	.set	name,value

/*
 * P_LEAF -- declare private leaf procedure
 */
#define	P_LEAF(name, localvarsize)			\
	ALIGN						;\
name:

/*
 * LABEL -- declare a global code label
 * MUST be used (rather than LEAF, NESTED, etc) if control
 * "flows into" the label.
 */
#define	LABEL(name)					\
	.globl	name					;\
name:

/*
 * NESTED -- declare procedure that invokes other procedures
 */
#define	NESTED(name, localvarsize)			\
	.globl	name					;\
	ALIGN						;\
name:

/*
 * X_NESTED -- declare alternate global label for nested proc
 */
#define	X_NESTED(name, value)				\
	.globl	name					;\
	.set	name,value

/*
 * P_NESTED -- declare private nested procedure
 */
#define	P_NESTED(name, localvarsize)			\
	ALIGN						;\
name:

/*
 * END -- mark end of procedure
 */
#define	END(name)

/*
 * Storage definition macros
 * The main purpose of these is to allow an easy handle for ctags
 */

/*
 * IMPORT -- import symbol
 */
#define	IMPORT(name)					\
	.reference	name

/*
 * ABS -- declare global absolute symbol
 */
#define	ABS(name, value)				\
	.globl	name					;\
	.set	name,value

/*
 * P_ABS -- declare private absolute symbol
 */
#define	P_ABS(name, value)				\
	.set	name,value

/*
 * EXPORT -- declare global label for data
 */
#define	EXPORT(name)					\
	.globl	name					;\
name:

/*
 * BSS -- declare global zero'ed storage
 */
#define	BSS(name,size)					\
	.comm	name,size

/*
 * P_BSS -- declare private zero'ed storage
 */
#define	P_BSS(name,size)				\
	.lcomm	name,size

#if defined(__DYNAMIC__)
#define GET_ADDRESS(reg,var)		\
	ldr	reg, 4f						;\
3:	ldr	reg, [pc, reg]				;\
	b	5f							;\
4:	.long	6f - (3b + 8)			;\
5:									;\
	.non_lazy_symbol_pointer		;\
6:									;\
	.indirect_symbol var			;\
	.long 0							;\
	.text							;\
	.align 2
#else
#define GET_ADDRESS(reg,var)		\
	ldr	reg, 3f						;\
	b	4f							;\
3:	.long var						;\
4:
#endif

#if defined(__DYNAMIC__)
#define BRANCH_EXTERNAL(var)		\
	.globl	var						;\
	GET_ADDRESS(ip, var)			;\
	bx	ip
#else
#define BRANCH_EXTERNAL(var)		;\
.globl	var							;\
	b	var
#endif

#if defined(__DYNAMIC__)
#define CALL_EXTERNAL(var)			\
	.globl	var						;\
	GET_ADDRESS(ip,var)				;\
	mov	lr, pc						;\
	bx	ip
#else
#define CALL_EXTERNAL(var)			\
	.globl	var						;\
	bl	var
#endif

#define ENTRY_POINT(name)			\
	.align 2						;\
	.globl  name					;\
	.text							;\
name:

#endif	/* __ASSEMBLER__ */

#endif	/* _ARCH_ARM_ASM_HELP_H_ */