require '_h2ph_pre.ph';

no warnings qw(redefine misc);

unless(defined(&_ARM_ASM_H_)) {
    eval 'sub _ARM_ASM_H_ () {1;}' unless defined(&_ARM_ASM_H_);
    require 'arm/cdefs.ph';
    if(defined(&_KERNEL_OPT)) {
	require './arm/opt_cpuoptions.ph';
    }
    if(defined(&__thumb__)) {
	eval 'sub THUMB_INSN {
	    my($n) = @_;
    	    eval q($n);
	}' unless defined(&THUMB_INSN);
    } else {
	eval 'sub THUMB_INSN {
	    my($n) = @_;
    	    eval q();
	}' unless defined(&THUMB_INSN);
    }
    eval 'sub __BIT {
        my($n) = @_;
	    eval q((1<< ($n)));
    }' unless defined(&__BIT);
    eval 'sub __BITS {
        my($hi,$lo) = @_;
	    eval q(((~((~0)<<(($hi)+1)))((~0)<<($lo))));
    }' unless defined(&__BITS);
    eval 'sub __LOWEST_SET_BIT {
        my($__mask) = @_;
	    eval q((((($__mask) - 1) & ($__mask)) ^ ($__mask)));
    }' unless defined(&__LOWEST_SET_BIT);
    eval 'sub __SHIFTOUT {
        my($__x, $__mask) = @_;
	    eval q(((($__x) & ($__mask)) /  &__LOWEST_SET_BIT($__mask)));
    }' unless defined(&__SHIFTOUT);
    eval 'sub __SHIFTIN {
        my($__x, $__mask) = @_;
	    eval q((($__x) *  &__LOWEST_SET_BIT($__mask)));
    }' unless defined(&__SHIFTIN);
    eval 'sub _C_LABEL {
        my($x) = @_;
	    eval q($x);
    }' unless defined(&_C_LABEL);
    eval 'sub _ASM_LABEL {
        my($x) = @_;
	    eval q($x);
    }' unless defined(&_ASM_LABEL);
    if(defined(&__STDC__)) {
	eval 'sub __CONCAT {
	    my($x,$y) = @_;
    	    eval q($x  $y);
	}' unless defined(&__CONCAT);
	eval 'sub __STRING {
	    my($x) = @_;
    	    eval q($x);
	}' unless defined(&__STRING);
    } else {
	eval 'sub __CONCAT {
	    my($x,$y) = @_;
    	    eval q($x $y);
	}' unless defined(&__CONCAT);
	eval 'sub __STRING {
	    my($x) = @_;
    	    eval q(\\"x\\");
	}' unless defined(&__STRING);
    }
    unless(defined(&_ALIGN_TEXT)) {
	eval 'sub _ALIGN_TEXT () {. &align 2;}' unless defined(&_ALIGN_TEXT);
    }
    unless(defined(&_TEXT_SECTION)) {
	eval 'sub _TEXT_SECTION () {. &text;}' unless defined(&_TEXT_SECTION);
    }
    if(defined(&__arm__)) {
	eval 'sub _ASM_TYPE_FUNCTION () {% &function;}' unless defined(&_ASM_TYPE_FUNCTION);
	eval 'sub _ASM_TYPE_OBJECT () {% &object;}' unless defined(&_ASM_TYPE_OBJECT);
	eval 'sub _THUMB_ENTRY {
	    my($x) = @_;
    	    eval q( &_TEXT_SECTION;  &_ALIGN_TEXT; . &globl $x; . &type $x, &_ASM_TYPE_FUNCTION; . &thumb_func; . &code 16; $x:);
	}' unless defined(&_THUMB_ENTRY);
	eval 'sub _ARM_ENTRY {
	    my($x) = @_;
    	    eval q( &_TEXT_SECTION;  &_ALIGN_TEXT; . &globl $x; . &type $x, &_ASM_TYPE_FUNCTION; . &code 32; $x:);
	}' unless defined(&_ARM_ENTRY);
	if(defined(&__thumb__)) {
	    eval 'sub _ENTRY {
	        my($x) = @_;
    		eval q( &_THUMB_ENTRY($x));
	    }' unless defined(&_ENTRY);
	} else {
	    eval 'sub _ENTRY {
	        my($x) = @_;
    		eval q( &_ARM_ENTRY($x));
	    }' unless defined(&_ENTRY);
	}
	eval 'sub _END {
	    my($x) = @_;
    	    eval q(. &size $x,.-$x);
	}' unless defined(&_END);
	if(defined(&GPROF)) {
	    eval 'sub _PROF_PROLOGUE () { &mov  &ip,  &lr;  &bl  &__mcount;}' unless defined(&_PROF_PROLOGUE);
	} else {
	    eval 'sub _PROF_PROLOGUE () {1;}' unless defined(&_PROF_PROLOGUE);
	}
    }
    if(defined(&__aarch64__)) {
	eval 'sub _ASM_TYPE_FUNCTION () {@ &function;}' unless defined(&_ASM_TYPE_FUNCTION);
	eval 'sub _ASM_TYPE_OBJECT () {@ &object;}' unless defined(&_ASM_TYPE_OBJECT);
	eval 'sub _ENTRY {
	    my($x) = @_;
    	    eval q( &_TEXT_SECTION;  &_ALIGN_TEXT; . &globl $x; . &type $x, &_ASM_TYPE_FUNCTION; $x:);
	}' unless defined(&_ENTRY);
	eval 'sub _END {
	    my($x) = @_;
    	    eval q(. &size $x,.-$x);
	}' unless defined(&_END);
	if(defined(&GPROF)) {
	    eval 'sub _PROF_PROLOGUE () { &stp  &x29,  &x30, [ &sp, -16]!;  &mov  &fp,  &sp;  &bl  &__mcount;  &ldp  &x29,  &x30, [ &sp], 16;;}' unless defined(&_PROF_PROLOGUE);
	} else {
	    eval 'sub _PROF_PROLOGUE () {1;}' unless defined(&_PROF_PROLOGUE);
	}
	if(defined(&__PIC__)) {
	    eval 'sub GOTREF {
	        my($x) = @_;
    		eval q(: &got:$x);
	    }' unless defined(&GOTREF);
	    eval 'sub GOTLO12 {
	        my($x) = @_;
    		eval q(: &got_lo12:$x);
	    }' unless defined(&GOTLO12);
	} else {
	    eval 'sub GOTREF {
	        my($x) = @_;
    		eval q($x);
	    }' unless defined(&GOTREF);
	    eval 'sub GOTLO12 {
	        my($x) = @_;
    		eval q(: &lo12:$x);
	    }' unless defined(&GOTLO12);
	}
    }
    if(defined(&ARMV85_BTI)) {
	eval 'sub _BTI_PROLOGUE () {. &byte 0x5f, 0x24, 0x3, 0xd5;}' unless defined(&_BTI_PROLOGUE);
    } else {
	eval 'sub _BTI_PROLOGUE () {1;}' unless defined(&_BTI_PROLOGUE);
    }
    eval 'sub ENTRY {
        my($y) = @_;
	    eval q( &_ENTRY( &_C_LABEL($y));  &_BTI_PROLOGUE ;  &_PROF_PROLOGUE);
    }' unless defined(&ENTRY);
    eval 'sub ENTRY_NP {
        my($y) = @_;
	    eval q( &_ENTRY( &_C_LABEL($y));  &_BTI_PROLOGUE);
    }' unless defined(&ENTRY_NP);
    eval 'sub ENTRY_NBTI {
        my($y) = @_;
	    eval q( &_ENTRY( &_C_LABEL($y)));
    }' unless defined(&ENTRY_NBTI);
    eval 'sub END {
        my($y) = @_;
	    eval q( &_END( &_C_LABEL($y)));
    }' unless defined(&END);
    eval 'sub ARM_ENTRY {
        my($y) = @_;
	    eval q( &_ARM_ENTRY( &_C_LABEL($y));  &_PROF_PROLOGUE);
    }' unless defined(&ARM_ENTRY);
    eval 'sub ARM_ENTRY_NP {
        my($y) = @_;
	    eval q( &_ARM_ENTRY( &_C_LABEL($y)));
    }' unless defined(&ARM_ENTRY_NP);
    eval 'sub THUMB_ENTRY {
        my($y) = @_;
	    eval q( &_THUMB_ENTRY( &_C_LABEL($y));  &_PROF_PROLOGUE);
    }' unless defined(&THUMB_ENTRY);
    eval 'sub THUMB_ENTRY_NP {
        my($y) = @_;
	    eval q( &_THUMB_ENTRY( &_C_LABEL($y)));
    }' unless defined(&THUMB_ENTRY_NP);
    eval 'sub ASENTRY {
        my($y) = @_;
	    eval q( &_ENTRY( &_ASM_LABEL($y));  &_PROF_PROLOGUE);
    }' unless defined(&ASENTRY);
    eval 'sub ASENTRY_NP {
        my($y) = @_;
	    eval q( &_ENTRY( &_ASM_LABEL($y)));
    }' unless defined(&ASENTRY_NP);
    eval 'sub ASEND {
        my($y) = @_;
	    eval q( &_END( &_ASM_LABEL($y)));
    }' unless defined(&ASEND);
    eval 'sub ARM_ASENTRY {
        my($y) = @_;
	    eval q( &_ARM_ENTRY( &_ASM_LABEL($y));  &_PROF_PROLOGUE);
    }' unless defined(&ARM_ASENTRY);
    eval 'sub ARM_ASENTRY_NP {
        my($y) = @_;
	    eval q( &_ARM_ENTRY( &_ASM_LABEL($y)));
    }' unless defined(&ARM_ASENTRY_NP);
    eval 'sub THUMB_ASENTRY {
        my($y) = @_;
	    eval q( &_THUMB_ENTRY( &_ASM_LABEL($y));  &_PROF_PROLOGUE);
    }' unless defined(&THUMB_ASENTRY);
    eval 'sub THUMB_ASENTRY_NP {
        my($y) = @_;
	    eval q( &_THUMB_ENTRY( &_ASM_LABEL($y)));
    }' unless defined(&THUMB_ASENTRY_NP);
    eval 'sub ASMSTR () {. &asciz;}' unless defined(&ASMSTR);
    if(defined(&__PIC__)) {
	eval 'sub REL_SYM {
	    my($a, $b) = @_;
    	    eval q((($a) - ($b)));
	}' unless defined(&REL_SYM);
	eval 'sub PLT_SYM {
	    my($x) = @_;
    	    eval q($x);
	}' unless defined(&PLT_SYM);
	eval 'sub GOT_SYM {
	    my($x) = @_;
    	    eval q( &PIC_SYM($x,  &GOT));
	}' unless defined(&GOT_SYM);
	eval 'sub GOT_GET {
	    my($x,$got,$sym) = @_;
    	    eval q( &ldr $x, $sym;  &ldr $x, [$x, $got]);
	}' unless defined(&GOT_GET);
	eval 'sub GOT_INIT {
	    my($got,$gotsym,$pclabel) = @_;
    	    eval q( &ldr $got, $gotsym; $pclabel:  &add $got, $got,  &pc);
	}' unless defined(&GOT_INIT);
	if(defined(&__thumb__)) {
	    eval 'sub GOT_INITSYM {
	        my($gotsym,$pclabel) = @_;
    		eval q(. &align 0; $gotsym: . &word  &_C_LABEL( &_GLOBAL_OFFSET_TABLE_) - ($pclabel+4));
	    }' unless defined(&GOT_INITSYM);
	} else {
	    eval 'sub GOT_INITSYM {
	        my($gotsym,$pclabel) = @_;
    		eval q(. &align 0; $gotsym: . &word  &_C_LABEL( &_GLOBAL_OFFSET_TABLE_) - ($pclabel+8));
	    }' unless defined(&GOT_INITSYM);
	}
	if(defined(&__STDC__)) {
	    eval 'sub PIC_SYM {
	        my($x,$y) = @_;
    		eval q($x  (  $y  ));
	    }' unless defined(&PIC_SYM);
	} else {
	    eval 'sub PIC_SYM {
	        my($x,$y) = @_;
    		eval q($x ( $y ));
	    }' unless defined(&PIC_SYM);
	}
    } else {
	eval 'sub REL_SYM {
	    my($a, $b) = @_;
    	    eval q(($a));
	}' unless defined(&REL_SYM);
	eval 'sub PLT_SYM {
	    my($x) = @_;
    	    eval q($x);
	}' unless defined(&PLT_SYM);
	eval 'sub GOT_SYM {
	    my($x) = @_;
    	    eval q($x);
	}' unless defined(&GOT_SYM);
	eval 'sub GOT_GET {
	    my($x,$got,$sym) = @_;
    	    eval q( &ldr $x, $sym;);
	}' unless defined(&GOT_GET);
	eval 'sub GOT_INIT {
	    my($got,$gotsym,$pclabel) = @_;
    	    eval q();
	}' unless defined(&GOT_INIT);
	eval 'sub GOT_INITSYM {
	    my($gotsym,$pclabel) = @_;
    	    eval q();
	}' unless defined(&GOT_INITSYM);
	eval 'sub PIC_SYM {
	    my($x,$y) = @_;
    	    eval q($x);
	}' unless defined(&PIC_SYM);
    }
    eval 'sub RCSID {
        my($x) = @_;
	    eval q(. &pushsection \\".ident\\",\\"MS\\",% &progbits,1; . &asciz $x; . &popsection);
    }' unless defined(&RCSID);
    eval 'sub WEAK_ALIAS {
        my($alias,$sym) = @_;
	    eval q(. &weak $alias; $alias = $sym);
    }' unless defined(&WEAK_ALIAS);
    eval 'sub STRONG_ALIAS {
        my($alias,$sym) = @_;
	    eval q(. &globl $alias; $alias = $sym);
    }' unless defined(&STRONG_ALIAS);
    if(defined(&__STDC__)) {
	eval 'sub WARN_REFERENCES {
	    my($sym,$msg) = @_;
    	    eval q(. &pushsection . ($gnu->{warning}).  $sym; . &ascii $msg; . &popsection);
	}' unless defined(&WARN_REFERENCES);
    } else {
	eval 'sub WARN_REFERENCES {
	    my($sym,$msg) = @_;
    	    eval q(. &pushsection . ($gnu->{warning}). $sym; . &ascii $msg; . &popsection);
	}' unless defined(&WARN_REFERENCES);
    }
    if(defined(&__thumb__)) {
	eval 'sub XPUSH () { &push;}' unless defined(&XPUSH);
	eval 'sub XPOP () { &pop;}' unless defined(&XPOP);
	eval 'sub XPOPRET () { &pop { &pc};}' unless defined(&XPOPRET);
    } else {
	eval 'sub XPUSH () { &stmfd  &sp!,;}' unless defined(&XPUSH);
	eval 'sub XPOP () { &ldmfd  &sp!,;}' unless defined(&XPOP);
	if(defined(&_ARM_ARCH_5)) {
	    eval 'sub XPOPRET () { &ldmfd  &sp!, { &pc};}' unless defined(&XPOPRET);
	} else {
	    eval 'sub XPOPRET () { &ldmfd  &sp!, { &lr};  &mov  &pc,  &lr;}' unless defined(&XPOPRET);
	}
    }
    if(defined(&__aarch64__)) {
	eval 'sub RET () { &ret;}' unless defined(&RET);
    }
 elsif(defined (&_ARM_ARCH_4T)) {
	eval 'sub RET () { &bx  &lr;}' unless defined(&RET);
	eval 'sub RETr {
	    my($r) = @_;
    	    eval q( &bx $r);
	}' unless defined(&RETr);
	if(defined(&__thumb__)) {
	    if(defined(&_ARM_ARCH_7)) {
		eval 'sub RETc {
		    my($c) = @_;
    		    eval q( &it $c;  &__CONCAT( &bx,$c)  &lr);
		}' unless defined(&RETc);
	    }
	} else {
	    eval 'sub RETc {
	        my($c) = @_;
    		eval q( &__CONCAT( &bx,$c)  &lr);
	    }' unless defined(&RETc);
	}
    } else {
	eval 'sub RET () { &mov  &pc,  &lr;}' unless defined(&RET);
	eval 'sub RETr {
	    my($r) = @_;
    	    eval q( &mov  &pc, $r);
	}' unless defined(&RETr);
	eval 'sub RETc {
	    my($c) = @_;
    	    eval q( &__CONCAT( &mov,$c)  &pc,  &lr);
	}' unless defined(&RETc);
    }
    if(defined(&_ARM_ARCH_7)) {
	eval 'sub KMODTRAMPOLINE {
	    my($n) = @_;
    	    eval q( &_ENTRY( &__wrap_  $n)  &movw  &ip, : &lower16:$n;  &movt  &ip, : &upper16:$n;  &bx  &ip);
	}' unless defined(&KMODTRAMPOLINE);
    }
 elsif(defined(&_ARM_ARCH_4T)) {
	eval 'sub KMODTRAMPOLINE {
	    my($n) = @_;
    	    eval q( &_ENTRY( &__wrap_  $n)  &ldr  &ip, [ &pc];  &bx  &ip; . &word $n);
	}' unless defined(&KMODTRAMPOLINE);
    } else {
	eval 'sub KMODTRAMPOLINE {
	    my($n) = @_;
    	    eval q( &_ENTRY( &__wrap_  $n)  &ldr  &pc, [ &pc, -4]; . &word $n);
	}' unless defined(&KMODTRAMPOLINE);
    }
}
1;
