#ifndef _I386_ASM_H_
#define _I386_ASM_H_
#ifdef _KERNEL_OPT
#include "opt_multiprocessor.h"
#endif
#ifdef __PIC__
#define PIC_PROLOGUE \
pushl %ebx; \
call 1f; \
1: \
popl %ebx; \
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
#define PIC_EPILOGUE \
popl %ebx
#define PIC_PLT(x) x@PLT
#define PIC_GOT(x) x@GOT(%ebx)
#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
#else
#define PIC_PROLOGUE
#define PIC_EPILOGUE
#define PIC_PLT(x) x
#define PIC_GOT(x) x
#define PIC_GOTOFF(x) x
#endif
#ifdef __ELF__
# define _C_LABEL(x) x
#else
# ifdef __STDC__
# define _C_LABEL(x) _ ## x
# else
# define _C_LABEL(x) _x
# endif
#endif
#define _ASM_LABEL(x) x
#define CVAROFF(x, y) _C_LABEL(x) + y
#ifdef __STDC__
# define __CONCAT(x,y) x ## y
# define __STRING(x) #x
#else
# define __CONCAT(x,y) xy
# define __STRING(x) "x"
#endif
#if !defined(_ALIGN_TEXT) && !defined(_KERNEL)
# ifdef _STANDALONE
# define _ALIGN_TEXT .align 1
# elif defined __ELF__
# define _ALIGN_TEXT .align 16
# else
# define _ALIGN_TEXT .align 4
# endif
#endif
#define _ENTRY(x) \
.text; _ALIGN_TEXT; .globl x; .type x,@function; x:
#define _LABEL(x) \
.globl x; x:
#ifdef _KERNEL
#define CPUVAR(off) %fs:__CONCAT(CPU_INFO_,off)
#ifdef __ELF__
#ifdef __STDC__
#define IDTVEC(name) \
ALIGN_TEXT; .globl X ## name; .type X ## name,@function; X ## name:
#define IDTVEC_END(name) \
.size X ## name, . - X ## name
#else
#define IDTVEC(name) \
ALIGN_TEXT; .globl Xname; .type Xname,@function; Xname:
#define IDTVEC_END(name) \
.size Xname, . - Xname
#endif
#else
#ifdef __STDC__
#define IDTVEC(name) \
ALIGN_TEXT; .globl _X ## name; .type _X ## name,@function; _X ## name:
#define IDTVEC_END(name) \
.size _X ## name, . - _X ## name
#else
#define IDTVEC(name) \
ALIGN_TEXT; .globl _Xname; .type _Xname,@function; _Xname:
#define IDTVEC_END(name) \
.size _Xname, . - _Xname
#endif
#endif
#ifdef _STANDALONE
#define ALIGN_DATA .align 4
#define ALIGN_TEXT .align 4
#define SUPERALIGN_TEXT .align 16
#elif defined __ELF__
#define ALIGN_DATA .align 4
#define ALIGN_TEXT .align 16
#define SUPERALIGN_TEXT .align 16
#else
#define ALIGN_DATA .align 2
#define ALIGN_TEXT .align 4
#define SUPERALIGN_TEXT .align 4
#endif
#define _ALIGN_TEXT ALIGN_TEXT
#ifdef GPROF
#ifdef __ELF__
#define MCOUNT_ASM call _C_LABEL(__mcount)
#else
#define MCOUNT_ASM call _C_LABEL(mcount)
#endif
#else
#define MCOUNT_ASM
#endif
#endif
#ifdef GPROF
# ifdef __ELF__
# define _PROF_PROLOGUE \
pushl %ebp; movl %esp,%ebp; call PIC_PLT(__mcount); popl %ebp
# else
# define _PROF_PROLOGUE \
pushl %ebp; movl %esp,%ebp; call PIC_PLT(mcount); popl %ebp
# endif
#else
# define _PROF_PROLOGUE
#endif
#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define NENTRY(y) _ENTRY(_C_LABEL(y))
#define ALTENTRY(x) NENTRY(x)
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
#define LABEL(y) _LABEL(_C_LABEL(y))
#define END(y) .size y, . - y
#define ASMSTR .asciz
#ifdef __ELF__
#define _IDENTSTR(x) .pushsection ".ident","MS",@progbits,1; \
x; \
.popsection
#else
#define _IDENTSTR(x) .text; x
#endif
#ifdef _NETBSD_REVISIONID
#define RCSID(_s) \
_IDENTSTR(.asciz _s); \
_IDENTSTR(.ascii "$"; .ascii "NetBSD: "; .ascii __FILE__; .ascii " "; \
.ascii _NETBSD_REVISIONID; .asciz " $")
#else
#define RCSID(_s) _IDENTSTR(.asciz _s)
#endif
#ifdef NO_KERNEL_RCSIDS
#define __KERNEL_RCSID(_n, _s)
#else
#define __KERNEL_RCSID(_n, _s) RCSID(_s)
#endif
#ifdef __ELF__
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
#endif
#define STRONG_ALIAS(alias,sym) \
.globl alias; \
alias = sym
#ifdef __STDC__
#define WARN_REFERENCES(sym,msg) \
.pushsection .gnu.warning. ## sym; \
.ascii msg; \
.popsection
#else
#define WARN_REFERENCES(sym,msg) \
.pushsection .gnu.warning.sym; \
.ascii msg; \
.popsection
#endif
#endif