#ifndef _I386_ASM_H_
#define _I386_ASM_H_
#ifdef _KERNEL
#include <gprof.h>
#endif
#ifdef MACH_KERNEL
#include <mach_kdb.h>
#else
#define MACH_KDB 0
#endif
#if defined(MACH_KERNEL) || defined(_KERNEL)
#include <gprof.h>
#endif
#define S_ARG0 4(%esp)
#define S_ARG1 8(%esp)
#define S_ARG2 12(%esp)
#define S_ARG3 16(%esp)
#define FRAME pushl %ebp; movl %esp, %ebp
#define EMARF leave
#define B_ARG0 8(%ebp)
#define B_ARG1 12(%ebp)
#define B_ARG2 16(%ebp)
#define B_ARG3 20(%ebp)
#ifdef ASSEMBLER
#define ALIGN 2,0x90
#endif
#ifndef FALIGN
#define FALIGN ALIGN
#endif
#define LB(x,n) n
#if __STDC__
#ifndef __NO_UNDERSCORES__
#define LCL(x) L ## x
#define EXT(x) _ ## x
#define LEXT(x) _ ## x ## :
#else
#define LCL(x) .L ## x
#define EXT(x) x
#define LEXT(x) x ## :
#endif
#define LBc(x,n) n ## :
#define LBb(x,n) n ## b
#define LBf(x,n) n ## f
#else
#ifndef __NO_UNDERSCORES__
#define LCL(x) Lx
#define EXT(x) _x
#define LEXT(x) _x:
#else
#define LCL(x) .Lx
#define EXT(x) x
#define LEXT(x) x:
#endif
#define LBc(x,n) n:
#define LBb(x,n) nb
#define LBf(x,n) nf
#endif
#define SVC .byte 0x9a; .long 0; .word 0x7
#define RPC_SVC .byte 0x9a; .long 0; .word 0xf
#define String .asciz
#define Value .word
#define Times(a,b) (a*b)
#define Divide(a,b) (a/b)
#define INB inb %dx, %al
#define OUTB outb %al, %dx
#define INL inl %dx, %eax
#define OUTL outl %eax, %dx
#define data16 .byte 0x66
#define addr16 .byte 0x67
#if !GPROF
#define MCOUNT
#elif defined(__SHARED__)
#define MCOUNT ; .data;\
.align ALIGN;\
LBc(x, 8) .long 0;\
.text;\
Gpush;\
Gload;\
leal Gotoff(LBb(x,8)),%edx;\
Egaddr(%eax,_mcount_ptr);\
Gpop;\
call *(%eax);
#else
#define MCOUNT ; .data;\
.align ALIGN;\
LBc(x, 8) .long 0;\
.text;\
movl LBb(x,8),%edx;\
call *EXT(_mcount_ptr);
#endif
#ifdef __ELF__
#define ELF_FUNC(x) .type x,@function
#define ELF_DATA(x) .type x,@object
#define ELF_SIZE(x,s) .size x,s
#else
#define ELF_FUNC(x)
#define ELF_DATA(x)
#define ELF_SIZE(x,s)
#endif
#define Entry(x) .globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x)
#define ENTRY(x) Entry(x) MCOUNT
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \
.align FALIGN; LEXT(x); LEXT(y) \
MCOUNT
#if __STDC__
#define ASENTRY(x) .globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT
#else
#define ASENTRY(x) .globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT
#endif
#define DATA(x) .globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x)
#define End(x) ELF_SIZE(x,.-x)
#define END(x) End(EXT(x))
#define ENDDATA(x) END(x)
#define Enddata(x) End(x)
#ifndef __SHARED__
#define Gpush
#define Gpop
#define Gload
#define Gcall(func) call func
#define Gotoff(lab) lab
#define Gotoff2(l,r) l(r)
#define Gotoff3(l,r,s) l(,r,s)
#define Gaddr(to,lab) movl $lab,to
#define Gcmp(lab,reg) cmpl $lab,reg
#define Gmemload(lab,reg) movl lab,reg
#define Gmemstore(reg,lab,tmp) movl reg,lab
#define Gstack 0
#else
#ifdef __ELF__
#define Gpush pushl %ebx
#define Gpop popl %ebx
#define Gload call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx
#define Gcall(func) call EXT(func)@PLT
#define Gotoff(lab) lab@GOTOFF(%ebx)
#define Gotoff2(l,r) l@GOTOFF(%ebx,r)
#define Gotoff3(l,r,s) l@GOTOFF(%ebx,r,s)
#define Gaddr(to,lab) movl lab@GOT(%ebx),to
#define Gcmp(lab,reg) cmpl reg,lab@GOT(%ebx)
#define Gmemload(lab,reg) movl lab@GOT(%ebx),reg; movl (reg),reg
#define Gmemstore(reg,lab,tmp) movl lab@GOT(%ebx),tmp; movl reg,(tmp)
#define Gstack 4
#else
#define Gpush
#define Gpop
#define Gload
#define Gcall(func) call *9f; .data; .align ALIGN; 9: .long func; .text
#define Gotoff(lab) lab
#define Gotoff2(l,r) l(r)
#define Gotoff3(l,r,s) l(,r,s)
#define Gaddr(to,lab) movl 9f,to; .data; .align ALIGN; 9: .long lab; .text
#define Gcmp(lab,reg) cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text
#define Gmemload(lab,reg) movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text
#define Gmemstore(reg,lab,tmp) movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text
#define Gstack 0
#endif
#endif
#define Egcall(func) Gcall(EXT(func))
#define Egaddr(to,lab) Gaddr(to,EXT(lab))
#define Egcmp(lab,reg) Gcmp(EXT(lab),reg)
#define Egmemload(lab,reg) Gmemload(EXT(lab),reg)
#define Egmemstore(reg,lab,tmp) Gmemstore(reg,EXT(lab),tmp)
#define Lgotoff(lab) Gotoff(LCL(lab))
#define Lgotoff2(l,r) Gotoff2(LCL(l),r)
#define Lgotoff3(l,r,s) Gotoff3(LCL(l),r,s)
#define Lgcmp(lab,reg) Gcmp(LCL(lab),reg)
#define Lgmemload(lab,reg) movl Lgotoff(lab),reg
#define Lgmemstore(reg,lab,tmp) movl reg,Lgotoff(lab)
#ifdef ASSEMBLER
#if MACH_KDB
#include <ddb/stab.h>
#endif
#else
#ifndef __NO_UNDERSCORES__
#define CC_SYM_PREFIX "_"
#else
#define CC_SYM_PREFIX ""
#endif
#endif
#endif