#ifndef _MACHINE_ASM_H_
#define _MACHINE_ASM_H_
#include <sys/cdefs.h>
#define _C_LABEL(x) x
#define _ASM_LABEL(x) x
#ifndef _ALIGN_TEXT
# define _ALIGN_TEXT .align 2
#endif
#ifndef _STANDALONE
#define STOP_UNWINDING .cantunwind
#define _FNSTART .fnstart
#define _FNEND .fnend
#define _SAVE(...) .save __VA_ARGS__
#else
#define STOP_UNWINDING
#define _FNSTART
#define _FNEND
#define _SAVE(...)
#endif
#define _ASM_TYPE_FUNCTION #function
#define _ASM_TYPE_OBJECT #object
#define GLOBAL(x) .global x
#ifdef __thumb__
#define _FUNC_MODE .code 16; .thumb_func
#else
#define _FUNC_MODE .code 32
#endif
#define _LEENTRY(x) .type x,_ASM_TYPE_FUNCTION; _FUNC_MODE; x:
#define _LEEND(x)
#define _EENTRY(x) GLOBAL(x); _LEENTRY(x)
#define _EEND(x) _LEEND(x)
#define _LENTRY(x) .text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART
#define _LEND(x) .size x, . - x; _FNEND
#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x); _FNSTART
#define _END(x) _LEND(x)
#define ENTRY(y) _ENTRY(_C_LABEL(y));
#define EENTRY(y) _EENTRY(_C_LABEL(y));
#define ENTRY_NP(y) _ENTRY(_C_LABEL(y))
#define EENTRY_NP(y) _EENTRY(_C_LABEL(y))
#define END(y) _END(_C_LABEL(y))
#define EEND(y) _EEND(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y));
#define ASLENTRY(y) _LENTRY(_ASM_LABEL(y));
#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y));
#define ASLEENTRY(y) _LEENTRY(_ASM_LABEL(y));
#define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y))
#define ASLENTRY_NP(y) _LENTRY(_ASM_LABEL(y))
#define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y))
#define ASLEENTRY_NP(y) _LEENTRY(_ASM_LABEL(y))
#define ASEND(y) _END(_ASM_LABEL(y))
#define ASLEND(y) _LEND(_ASM_LABEL(y))
#define ASEEND(y) _EEND(_ASM_LABEL(y))
#define ASLEEND(y) _LEEND(_ASM_LABEL(y))
#define ASMSTR .asciz
#if defined(PIC)
#define PLT_SYM(x) PIC_SYM(x, PLT)
#define GOT_SYM(x) PIC_SYM(x, GOT)
#define GOT_GET(x,got,sym) \
ldr x, sym; \
ldr x, [x, got]
#define GOT_INIT(got,gotsym,pclabel) \
ldr got, gotsym; \
pclabel: add got, pc
#ifdef __thumb__
#define GOT_INITSYM(gotsym,pclabel) \
.align 2; \
gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+4)
#else
#define GOT_INITSYM(gotsym,pclabel) \
.align 2; \
gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+8)
#endif
#ifdef __STDC__
#define PIC_SYM(x,y) x ## ( ## y ## )
#else
#define PIC_SYM(x,y) x(y)
#endif
#else
#define PLT_SYM(x) x
#define GOT_SYM(x) x
#define GOT_GET(x,got,sym) \
ldr x, sym;
#define GOT_INIT(got,gotsym,pclabel)
#define GOT_INITSYM(gotsym,pclabel)
#define PIC_SYM(x,y) x
#endif
#undef __FBSDID
#if !defined(lint) && !defined(STRIP_FBSDID)
#define __FBSDID(s) .ident s
#else
#define __FBSDID(s)
#endif
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
#ifdef __STDC__
#define WARN_REFERENCES(sym,msg) \
.stabs msg ## ,30,0,0,0 ; \
.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
#else
#define WARN_REFERENCES(sym,msg) \
.stabs msg,30,0,0,0 ; \
.stabs __STRING(sym),1,0,0,0
#endif
# define RET bx lr
# define RETeq bxeq lr
# define RETne bxne lr
# define RETc(c) bx##c lr
#define ISB isb
#define DSB dsb
#define DMB dmb
#define WFI wfi
#if defined(__ARM_ARCH_7VE__) || defined(__clang__)
#define MSR_ELR_HYP(regnum) msr elr_hyp, lr
#define ERET eret
#else
#define MSR_ELR_HYP(regnum) .word (0xe12ef300 | regnum)
#define ERET .word 0xe160006e
#endif
#endif