require '_h2ph_pre.ph';

no warnings 'redefine';

unless(defined(&_AMD64_ATOMIC_H)) {
    eval 'sub _AMD64_ATOMIC_H () {1;}' unless defined(&_AMD64_ATOMIC_H);
    if(defined( &_KERNEL)  && !defined( &_LOCORE)) {
	if(defined(&MULTIPROCESSOR)) {
	    eval 'sub LOCK () {"lock";}' unless defined(&LOCK);
	} else {
	    eval 'sub LOCK () {1;}' unless defined(&LOCK);
	}
	eval 'sub x86_atomic_testset_u64 {
	    my($ptr,$val) = @_;
    	    eval q(\\"(assembly code)\\");
	}' unless defined(&x86_atomic_testset_u64);
	eval 'sub x86_atomic_testset_u32 {
	    my($ptr,$val) = @_;
    	    eval q(\\"(assembly code)\\");
	}' unless defined(&x86_atomic_testset_u32);
	eval 'sub x86_atomic_testset_i32 {
	    my($ptr,$val) = @_;
    	    eval q(\\"(assembly code)\\");
	}' unless defined(&x86_atomic_testset_i32);
	eval 'sub x86_atomic_setbits_u32 {
	    my($ptr,$bits) = @_;
    	    eval q({  &__asm  &__volatile( &LOCK \\" orl %1,%0\\" : \\"=m\\" (*$ptr) : \\"ir\\" ($bits)); });
	}' unless defined(&x86_atomic_setbits_u32);
	eval 'sub x86_atomic_clearbits_u32 {
	    my($ptr,$bits) = @_;
    	    eval q({  &__asm  &__volatile( &LOCK \\" andl %1,%0\\" : \\"=m\\" (*$ptr) : \\"ir\\" (~$bits)); });
	}' unless defined(&x86_atomic_clearbits_u32);
	eval 'sub x86_atomic_cas_ul {
	    my($ptr,$expect,$set) = @_;
    	    eval q({ my $res;  &__asm  &volatile( &LOCK \\" cmpxchgq %2, %1\\" : \\"=a\\" ( $res), \\"=m\\" (*$ptr) : \\"r\\" ($set), \\"a\\" ($expect), \\"m\\" (*$ptr) : \\"memory\\"); ( $res); });
	}' unless defined(&x86_atomic_cas_ul);
	eval 'sub x86_atomic_clearbits_u64 {
	    my($ptr,$bits) = @_;
    	    eval q({  &__asm  &__volatile( &LOCK \\" andq %1,%0\\" : \\"=m\\" (*$ptr) : \\"ir\\" (~$bits)); });
	}' unless defined(&x86_atomic_clearbits_u64);
	eval 'sub x86_atomic_testset_ul () { &x86_atomic_testset_u32;}' unless defined(&x86_atomic_testset_ul);
	eval 'sub x86_atomic_testset_i () { &x86_atomic_testset_i32;}' unless defined(&x86_atomic_testset_i);
	eval 'sub x86_atomic_setbits_l () { &x86_atomic_setbits_u32;}' unless defined(&x86_atomic_setbits_l);
	eval 'sub x86_atomic_setbits_ul () { &x86_atomic_setbits_u32;}' unless defined(&x86_atomic_setbits_ul);
	eval 'sub x86_atomic_clearbits_l () { &x86_atomic_clearbits_u32;}' unless defined(&x86_atomic_clearbits_l);
	eval 'sub x86_atomic_clearbits_ul () { &x86_atomic_clearbits_u32;}' unless defined(&x86_atomic_clearbits_ul);
	eval 'sub atomic_setbits_int () { &x86_atomic_setbits_u32;}' unless defined(&atomic_setbits_int);
	eval 'sub atomic_clearbits_int () { &x86_atomic_clearbits_u32;}' unless defined(&atomic_clearbits_int);
	undef(&LOCK) if defined(&LOCK);
    }
}
1;
