// File: /workspace/github_c_makefile_star2_O0/georgeweigt[P]eigenmath/eigenmath.c
// Function: power_numbers_factor
void
power_numbers_factor(struct atom *BASE, struct atom *EXPO)
{
	uint32_t *a, *b, *n, *q, *r;
	struct atom *p0;

	if (isminusone(BASE)) {
		power_minusone(EXPO);
		p0 = pop();
		if (car(p0) == symbol(MULTIPLY)) {
			p0 = cdr(p0);
			while (iscons(p0)) {
				push(car(p0));
				p0 = cdr(p0);
			}
		} else
			push(p0);
		return;
	}

	if (isinteger(EXPO)) {
		a = mpow(BASE->u.q.a, EXPO->u.q.a);
		b = mint(1);
		if (isnegativenumber(EXPO))
			push_bignum(MPLUS, b, a); // reciprocate
		else
			push_bignum(MPLUS, a, b);
		return;
	}

	// EXPO.a          r
	// ------ == q + ------
	// EXPO.b        EXPO.b

	q = mdiv(EXPO->u.q.a, EXPO->u.q.b);
	r = mmod(EXPO->u.q.a, EXPO->u.q.b);

	// process q

	if (!MZERO(q)) {
		a = mpow(BASE->u.q.a, q);
		b = mint(1);
		if (isnegativenumber(EXPO))
			push_bignum(MPLUS, b, a); // reciprocate
		else
			push_bignum(MPLUS, a, b);
	}

	mfree(q);

	// process r

	if (MLENGTH(BASE->u.q.a) == 1 && BASE->u.q.a[0] <= 0x7fffffff) {
		// BASE is less than 2^31, hence BASE is a prime number, no root
		push_symbol(POWER);
		push(BASE);
		push_bignum(EXPO->sign, r, mcopy(EXPO->u.q.b)); // r used here, r is not leaked
		list(3);
		return;
	}

	// BASE was too big to factor, try finding root

	n = mroot(BASE->u.q.a, EXPO->u.q.b);

	if (n == NULL) {
		// no root
		push_symbol(POWER);
		push(BASE);
		push_bignum(EXPO->sign, r, mcopy(EXPO->u.q.b)); // r used here, r is not leaked
		list(3);
		return;
	}

	// raise n to rth power

	a = mpow(n, r);
	b = mint(1);

	mfree(n);
	mfree(r);

	if (isnegativenumber(EXPO))
		push_bignum(MPLUS, b, a); // reciprocate
	else
		push_bignum(MPLUS, a, b);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x10770
cmpl $0x0, %eax
je 0x2aa36
movq -0x10(%rbp), %rdi
callq 0x2ac80
callq 0x91d0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0x2a971
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x2a97c
movq 0x34088(%rip), %rax     # 0x5ea00
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq 0x36921(%rip), %rax     # 0x612a8
jne 0x2aa28
movq -0x40(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0x2a9a8
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x2a9b3
movq 0x34051(%rip), %rax     # 0x5ea00
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0x2aa26
movq -0x40(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0x2a9e2
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
jmp 0x2a9ed
movq 0x34017(%rip), %rax     # 0x5ea00
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x9110
movq -0x40(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0x2aa11
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x60(%rbp)
jmp 0x2aa1c
movq 0x33fe8(%rip), %rax     # 0x5ea00
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x2a9bb
jmp 0x2aa31
movq -0x40(%rbp), %rdi
callq 0x9110
jmp 0x2ac77
movq -0x10(%rbp), %rdi
callq 0x9bc0
cmpl $0x0, %eax
je 0x2aa9c
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x8a20
movq %rax, -0x18(%rbp)
movl $0x1, %edi
callq 0x7d10
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x9e30
cmpl $0x0, %eax
je 0x2aa88
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
jmp 0x2aa97
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
jmp 0x2ac77
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8470
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8770
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x1, -0x4(%rax)
jne 0x2aadf
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x2ab31
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x8a20
movq %rax, -0x18(%rbp)
movl $0x1, %edi
callq 0x7d10
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x9e30
cmpl $0x0, %eax
je 0x2ab20
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
jmp 0x2ab2f
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
jmp 0x2ab31
movq -0x30(%rbp), %rdi
callq 0x7e70
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x1, -0x4(%rax)
jne 0x2aba9
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x7fffffff, (%rax)     # imm = 0x7FFFFFFF
ja 0x2aba9
movq 0x36753(%rip), %rdi     # 0x612b0
callq 0x9110
movq -0x8(%rbp), %rdi
callq 0x9110
movq -0x10(%rbp), %rax
movzbl 0x12(%rax), %eax
movl %eax, -0x6c(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x8170
movl -0x6c(%rbp), %edi
movq -0x68(%rbp), %rsi
movq %rax, %rdx
callq 0xe740
movl $0x3, %edi
callq 0x90d0
jmp 0x2ac77
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8f40
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x2ac18
movq 0x366e1(%rip), %rdi     # 0x612b0
callq 0x9110
movq -0x8(%rbp), %rdi
callq 0x9110
movq -0x10(%rbp), %rax
movzbl 0x12(%rax), %eax
movl %eax, -0x7c(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x8170
movl -0x7c(%rbp), %edi
movq -0x78(%rbp), %rsi
movq %rax, %rdx
callq 0xe740
movl $0x3, %edi
callq 0x90d0
jmp 0x2ac77
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x8a20
movq %rax, -0x18(%rbp)
movl $0x1, %edi
callq 0x7d10
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7e70
movq -0x38(%rbp), %rdi
callq 0x7e70
movq -0x10(%rbp), %rdi
callq 0x9e30
cmpl $0x0, %eax
je 0x2ac68
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
jmp 0x2ac77
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
xorl %edi, %edi
callq 0xe740
addq $0x80, %rsp
popq %rbp
retq