// File: /workspace/github_c_makefile_star2_O2/USArmyResearchLab[P]ARL_OpenSHMEM/src/autogen/shmem_broadcast32.c
// Function: shmem_broadcast32
void shmem_broadcast32( void* dest, const void* source, size_t nelems, 
	int pe_root, int pe_start, int log_pe_stride, int pe_size, long* psync)
{
	if (pe_size == 1) return;

	int pe = __shmem.my_pe;

	int pe_root_stride = pe_root << log_pe_stride;

	int32_t* psrc = (int32_t*)dest;

	int pex = pe - pe_start - pe_root_stride;

	int pe_size_stride = pe_size << log_pe_stride;

	if (pex < 0) pex += pe_size_stride;

	if (pex == 0) psrc = (int32_t*)source;

	int pe_end = pe_size_stride + pe_start;

	int maskx = pe_size_stride - 1;

	maskx |= (maskx >> 1);

	maskx |= (maskx >> 2); /* up to 16 PEs */
	maskx |= (maskx >> 4); /* up to 1024 PEs */
	/*maskx |= (maskx >> 8);*/ /* up to 65536 PEs */

	maskx += 1; /* the next largest power of 2 of the largest PE number */

	maskx >>= 1;

	int mask2 = pex & -pex; /* least significant 1 bit */

	if (pex==0) mask2 = maskx;

	int mask1 = (mask2 << 1) - 1;

	__shmem.lock_receive_finished = 0;

	debug("broadcast calling barrier");

	shmem_barrier(pe_start, log_pe_stride, pe_size, psync);

	do {
		if ((pex & mask1) == 0) {

			int pe_to = (pex | mask2) + pe_start + pe_root_stride;

			if (pe_to >= pe_end) pe_to -= pe_size_stride;

			long* remote_lock_receive_finished 
				= (long*)shmem_ptr((void*)&__shmem.lock_receive_finished, pe_to);

			int32_t* remote_dest = (int32_t*)shmem_ptr((void*)dest, pe_to);

			shmemx_memcpy((void*)remote_dest, (void*)psrc, nelems*sizeof(int32_t));

			/// clear lock_receive_finished on receiving PE 
			*remote_lock_receive_finished = 1;
//			__set_spin_lock(remote_lock_receive_finished);

		} else {
			while (!__shmem.lock_receive_finished);
			__shmem.lock_receive_finished = 0;
//			__clear_spin_lock(&__shmem.lock_receive_finished);
		}
		mask1 >>= 1;
		mask2 >>= 1;

	} while (mask1 >> log_pe_stride);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, 0x20(%rsp)
movq %rsi, 0x8(%rsp)
movq %rdi, 0x18(%rsp)
movl 0x70(%rsp), %edx
cmpl $0x1, %edx
je 0x3000
movl %r9d, %r14d
movl %ecx, %r9d
movq 0x78(%rsp), %rax
leaq 0x3328(%rip), %r15      # 0x61f0
movl 0x4(%r15), %esi
movl %r14d, %ecx
shll %cl, %r9d
movl %edx, %ebp
shll %cl, %ebp
addl %r8d, %r9d
movl %r9d, 0x14(%rsp)
subl %r9d, %esi
movl %esi, %edi
sarl $0x1f, %edi
andl %ebp, %edi
addl %esi, %edi
movq 0x8(%rsp), %rcx
cmovneq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rsp)
movl %edi, 0x4(%rsp)
je 0x2f0b
movl %edi, %r13d
negl %r13d
andl %edi, %r13d
jmp 0x2f2b
leal -0x1(%rbp), %ecx
movl %ecx, %esi
sarl %esi
orl %ecx, %esi
movl %esi, %ecx
sarl $0x2, %ecx
orl %esi, %ecx
movl %ecx, %r13d
sarl $0x4, %r13d
orl %ecx, %r13d
incl %r13d
sarl %r13d
leal (%r8,%rbp), %ecx
movl %ecx, 0x10(%rsp)
leal -0x1(,%r13,2), %ebx
movq $0x0, 0x80(%r15)
movl %r8d, %edi
movl %r14d, %esi
movq %rax, %rcx
callq 0x3010
shlq $0x2, 0x20(%rsp)
leaq 0x80(%r15), %rax
movq %rax, 0x28(%rsp)
movl 0x4(%rsp), %edx
movq %rbp, 0x30(%rsp)
testl %edx, %ebx
je 0x2f8a
cmpq $0x0, 0x80(%r15)
je 0x2f73
movq $0x0, 0x80(%r15)
jmp 0x2fec
movl %r13d, %r12d
orl %edx, %r12d
addl 0x14(%rsp), %r12d
cmpl 0x10(%rsp), %r12d
movl %ebp, %eax
movl $0x0, %ecx
cmovll %ecx, %eax
subl %eax, %r12d
movq 0x28(%rsp), %rdi
movl %r12d, %esi
callq 0x1c1c
movl %r14d, %ebp
movq %rax, %r14
movq 0x18(%rsp), %rdi
movl %r12d, %esi
callq 0x1c1c
movq %rax, %rdi
movq 0x8(%rsp), %rsi
movq 0x20(%rsp), %rdx
callq 0x30b8
movl 0x4(%rsp), %edx
movq $0x1, (%r14)
movl %ebp, %r14d
movq 0x30(%rsp), %rbp
sarl %ebx
sarl %r13d
movl %ebx, %eax
movl %r14d, %ecx
sarl %cl, %eax
testl %eax, %eax
jne 0x2f6f
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop