// File: /workspace/github_c_makefile_star2_O0/michaelforney[P]cproc/expr.c
// Function: assignexpr
struct expr *
assignexpr(struct scope *s)
{
	struct expr *e, *l, *r, *tmp, *bit;
	enum tokenkind op;

	l = condexpr(s);
	if (l->kind == EXPRBINARY || l->kind == EXPRCOMMA || l->kind == EXPRCAST)
		return l;
	switch (tok.kind) {
	case TASSIGN:     op = TNONE; break;
	case TMULASSIGN:  op = TMUL;  break;
	case TDIVASSIGN:  op = TDIV;  break;
	case TMODASSIGN:  op = TMOD;  break;
	case TADDASSIGN:  op = TADD;  break;
	case TSUBASSIGN:  op = TSUB;  break;
	case TSHLASSIGN:  op = TSHL;  break;
	case TSHRASSIGN:  op = TSHR;  break;
	case TBANDASSIGN: op = TBAND; break;
	case TXORASSIGN:  op = TXOR;  break;
	case TBORASSIGN:  op = TBOR;  break;
	default:
		return l;
	}
	if (!l->lvalue)
		error(&tok.loc, "left side of assignment expression is not an lvalue");
	next();
	r = assignexpr(s);
	if (!op)
		return mkassignexpr(l, r);
	/* rewrite `E1 OP= E2` as `T = &E1, *T = *T OP E2`, where T is a temporary slot */
	if (l->kind == EXPRBITFIELD) {
		bit = l;
		l = l->base;
	} else {
		bit = NULL;
	}
	tmp = mkexpr(EXPRTEMP, mkpointertype(l->type, l->qual), NULL);
	tmp->lvalue = true;
	tmp->u.temp = NULL;
	e = mkassignexpr(tmp, mkunaryexpr(TBAND, l));
	l = mkunaryexpr(TMUL, tmp);
	if (bit) {
		bit->base = l;
		l = bit;
	}
	r = mkbinaryexpr(&tok.loc, op, l, r);
	e->next = mkassignexpr(l, r);
	return mkexpr(EXPRCOMMA, l->type, e);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8b40
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x9, (%rax)
je 0x91a4
movq -0x20(%rbp), %rax
cmpl $0xc, (%rax)
je 0x91a4
movq -0x20(%rbp), %rax
cmpl $0x8, (%rax)
jne 0x91b1
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x93a5
leaq 0x18ff0(%rip), %rax     # 0x221a8
movl (%rax), %eax
addl $-0x63, %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0xa, %eax
ja 0x923f
movq -0x48(%rbp), %rax
leaq 0x102bd(%rip), %rcx     # 0x19490
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, -0x3c(%rbp)
jmp 0x924c
movl $0x4b, -0x3c(%rbp)
jmp 0x924c
movl $0x50, -0x3c(%rbp)
jmp 0x924c
movl $0x51, -0x3c(%rbp)
jmp 0x924c
movl $0x4c, -0x3c(%rbp)
jmp 0x924c
movl $0x4d, -0x3c(%rbp)
jmp 0x924c
movl $0x52, -0x3c(%rbp)
jmp 0x924c
movl $0x53, -0x3c(%rbp)
jmp 0x924c
movl $0x4a, -0x3c(%rbp)
jmp 0x924c
movl $0x5a, -0x3c(%rbp)
jmp 0x924c
movl $0x5b, -0x3c(%rbp)
jmp 0x924c
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x93a5
movq -0x20(%rbp), %rax
testb $0x1, 0x4(%rax)
jne 0x926f
leaq 0x18f4b(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x108c3(%rip), %rsi     # 0x19b2b
movb $0x0, %al
callq 0x11190
callq 0xd540
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x929d
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x93b0
movq %rax, -0x8(%rbp)
jmp 0x93a5
movq -0x20(%rbp), %rax
cmpl $0x4, (%rax)
jne 0x92bc
movq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x92c4
movq $0x0, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x20(%rbp), %rax
movl 0x10(%rax), %esi
callq 0x11760
movq %rax, %rsi
movl $0xe, %edi
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movb $0x1, 0x4(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rsi
movl $0x4a, %edi
callq 0x9410
movq -0x50(%rbp), %rdi
movq %rax, %rsi
callq 0x93b0
movq %rax, -0x18(%rbp)
movq -0x30(%rbp), %rsi
movl $0x4b, %edi
callq 0x9410
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x9354
movq -0x20(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
movq %rax, -0x20(%rbp)
movl -0x3c(%rbp), %esi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq 0x18e42(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
callq 0x95f0
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x93b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rdx
movl $0xc, %edi
callq 0x9040
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nop