// File: /workspace/github_cpp_makefile_star2_O2/ksherlock[P]wdc-utils/link.cpp
// Function: expr_error(bool, expression const&, char const*)
inline void expr_error(bool fatal, const expression &e, const char *msg) {
	warnx("%s:%04x %s", sections[e.section].name.c_str(), e.offset, msg);

	// pretty-print the expression...
	bool underflow = false;

	struct pair { std::string name; int precedence = 0; };

	std::vector<pair> stack;

	int p;
	for (auto &x : e.stack) {
		auto tag = x.tag;
		switch(tag) {

			case OP_VAL: {
				p = 0;
				char buffer[6];
				snprintf(buffer, sizeof(buffer), "$%02x", x.value);
				stack.emplace_back(pair{buffer, p});
				break;
			}
			case OP_SYM: {
				p = 0;
				stack.emplace_back(pair{symbols[x.section].name, p});
				break;
			}
			case OP_LOC: {
				p = 0;
				std::string tmp = sections[x.section].name;
				if (x.value) {
					char buffer[6];
					snprintf(buffer, sizeof(buffer), "$%02x", x.value);
					tmp.push_back('+');
					tmp.append(buffer);
					p = 3;
				}
				stack.emplace_back(pair{tmp, p});
				break;
			}

			case OP_NOT:
			case OP_NEG:
			case OP_FLP: {
				static const std::string ops[] = {
					".NOT.", "-", "\\"
				};
				p = 0;
				if (stack.empty()) {
					underflow = true;
				} else {
					auto &back = stack.back();
					if (p < back.precedence) {
						back.name = parenthesize(back.name);
					}
					back.name = ops[tag - OP_UNA] + back.name;
					back.precedence = p;
				}
				break;
			}

			case OP_EXP:
			case OP_MUL:
			case OP_DIV:
			case OP_MOD:
			case OP_SHR:
			case OP_SHL:
			case OP_ADD:
			case OP_SUB:
			case OP_AND:
			case OP_OR:
			case OP_XOR:
			case OP_EQ:
			case OP_GT:
			case OP_LT:
			case OP_UGT:
			case OP_ULT: {
				static const pair ops[] = {
					{ "**", 1 },
					{ "*", 2 },
					{ "/", 2 },
					{ ".MOD.", 2 },
					{ ">>", 2 },
					{ "<<", 2 },
					{ "+", 3 },
					{ "-", 3 },
					{ "&", 4 },
					{ "|", 5 },
					{ "^", 5 },
					{ "=", 6 },
					{ ">",  6},
					{ "<",  6},
					{ ".UGT.",  6},
					{ ".ULT.", 6 }
				};


				p = ops[tag - OP_BIN].precedence;
				if (stack.size() < 2) {
					underflow = true;
				} else {
					pair b = std::move(stack.back());
					stack.pop_back();
					pair &a = stack.back();

					if (p < b.precedence) b.name = parenthesize(b.name);
					if (p < a.precedence) a.name = parenthesize(a.name);

					a.name += ops[tag - OP_BIN].name + b.name;
					a.precedence = p;
				}
				break;
			}
			default:
				fprintf(stderr, "Unrecognized expression op %02x\n", tag);
				break;
		}

	}
	if (stack.size() == 1) {
		fprintf(stderr, "Expression: %s\n", stack.front().name.c_str());
	} else if (stack.empty() || underflow) {
		fprintf(stderr, "Expression underflow error.\n");
		fatal = true;
	} else {
		fprintf(stderr, "Expression overflow error.\n");
		fatal = true;
	}

	if (fatal) flags.errors++;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdx, %rcx
movq %rsi, %r14
movl %edi, 0x54(%rsp)
movl (%rsi), %eax
movl 0x4(%rsi), %edx
movq 0xfcfd(%rip), %rsi      # 0x15310
imulq $0x68, %rax, %rax
movq (%rsi,%rax), %rsi
leaq 0x8211(%rip), %rdi      # 0xd833
movq $0x0, 0x18(%rsp)
xorl %eax, %eax
callq 0x2280
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq 0x10(%r14), %rbx
movq 0x18(%r14), %rbp
leaq 0x7a87(%rip), %r14      # 0xd0d8
leaq 0x80(%rsp), %r15
leaq 0xfed0(%rip), %rax      # 0x15530
movq %rax, 0xc0(%rsp)
leaq 0xff39(%rip), %rax      # 0x155a8
movq %rax, 0x10(%rsp)
leaq 0x100bd(%rip), %rax     # 0x15738
movq %rax, 0xb8(%rsp)
leaq 0x100d6(%rip), %rax     # 0x15760
movq %rax, 0xb0(%rsp)
leaq 0x100ef(%rip), %rax     # 0x15788
movq %rax, 0xa8(%rsp)
leaq 0x10108(%rip), %rax     # 0x157b0
movq %rax, 0xa0(%rsp)
movq %rbp, 0x48(%rsp)
cmpq %rbp, %rbx
je 0x5ce3
movl (%rbx), %r12d
leal -0x1(%r12), %eax
cmpl $0x22, %eax
ja 0x59d5
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
movb 0x10122(%rip), %al      # 0x15800
testb %al, %al
je 0x59f9
movq 0x38(%rsp), %rsi
movq %rsi, %rax
subq 0x30(%rsp), %rax
cqto
pushq $0x28
popq %rcx
idivq %rcx
movb $0x1, %cl
cmpq $0x2, %rax
jb 0x59c5
addl $-0x14, %r12d
imulq $0x28, %r12, %r12
leaq 0xfe6a(%rip), %rax      # 0x15580
movl 0x20(%r12,%rax), %r14d
addq $-0x28, %rsi
leaq 0x58(%rsp), %rdi
callq 0x66c0
movq 0x38(%rsp), %rdi
addq $-0x28, %rdi
movq %rdi, 0x38(%rsp)
callq 0x2130
movq 0x38(%rsp), %rbp
cmpl 0x78(%rsp), %r14d
jge 0x576e
movq %r15, %rdi
movq %r15, %r13
leaq 0x58(%rsp), %r15
movq %r15, %rsi
callq 0x666a
movq %r15, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x2130
leaq -0x28(%rbp), %r13
cmpl -0x8(%rbp), %r14d
jge 0x579e
leaq 0x80(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x666a
movq %r13, %rdi
movq %r15, %rsi
callq 0x22d0
movq %r15, %rdi
callq 0x2130
leaq 0xfddb(%rip), %rax      # 0x15580
addq %rax, %r12
leaq 0x80(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
leaq 0x58(%rsp), %rdx
callq 0x6343
movq %r13, %rdi
movq %r15, %rsi
callq 0x2470
movq %r15, %rdi
callq 0x2130
movl %r14d, -0x8(%rbp)
leaq 0x58(%rsp), %rdi
callq 0x2130
movq 0x18(%rsp), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rbp
leaq 0x78e4(%rip), %r14      # 0xd0d8
jmp 0x59c5
movb 0xfd71(%rip), %al       # 0x15570
testb %al, %al
je 0x5c51
movq 0x38(%rsp), %r14
cmpq %r14, 0x30(%rsp)
je 0x588c
leaq -0x28(%r14), %r15
cmpl $0x0, -0x8(%r14)
leaq 0x58(%rsp), %r13
jle 0x5841
movq %r13, %rdi
movq %r15, %rsi
callq 0x666a
movq %r15, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x2130
addl $-0xa, %r12d
shlq $0x5, %r12
leaq 0xfcc0(%rip), %rax      # 0x15510
addq %rax, %r12
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x6343
movq %r15, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x2130
andl $0x0, -0x8(%r14)
movq 0x18(%rsp), %rax
movl %eax, %ecx
leaq 0x7851(%rip), %r14      # 0xd0d8
jmp 0x596f
movb $0x1, %cl
jmp 0x57ed
movl 0x8(%rbx), %eax
imulq $0x68, %rax, %rsi
addq 0xfa6f(%rip), %rsi      # 0x15310
movq %r15, %rdi
callq 0x2300
movl 0x4(%rbx), %ecx
testl %ecx, %ecx
leaq 0x58(%rsp), %r15
je 0x5979
movq %r15, %rdi
pushq $0x6
popq %rsi
leaq 0x7f78(%rip), %rdx      # 0xd83e
xorl %eax, %eax
callq 0x2380
leaq 0x80(%rsp), %r12
movq %r12, %rdi
pushq $0x2b
popq %rsi
callq 0x2220
movq %r12, %rdi
movq %r15, %rsi
callq 0x2440
pushq $0x3
popq %rbp
jmp 0x597b
movl 0x4(%rbx), %ecx
movq %r15, %rdi
pushq $0x6
popq %rsi
leaq 0x7f3b(%rip), %rdx      # 0xd83e
xorl %eax, %eax
callq 0x2380
movq %r15, %rsi
leaq 0x58(%rsp), %r15
movq %r15, %rdi
leaq 0xf(%rsp), %rdx
callq 0x5fc6
andl $0x0, 0x78(%rsp)
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x662e
jmp 0x5960
movl 0x8(%rbx), %eax
imulq $0x30, %rax, %rsi
addq 0xfa1f(%rip), %rsi      # 0x15360
leaq 0x58(%rsp), %r15
movq %r15, %rdi
callq 0x2300
andl $0x0, 0x78(%rsp)
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x662e
movq %r15, %rdi
callq 0x2130
movq 0x18(%rsp), %rax
movl %eax, %ecx
leaq 0x80(%rsp), %r15
jmp 0x59c5
xorl %ebp, %ebp
leaq 0x58(%rsp), %r15
movq %r15, %rdi
leaq 0x80(%rsp), %rsi
callq 0x2300
movl %ebp, 0x78(%rsp)
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x662e
movq %r15, %rdi
callq 0x2130
leaq 0x80(%rsp), %r15
movq %r15, %rdi
callq 0x2130
movq 0x18(%rsp), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rbp
addq $0xc, %rbx
movl %ecx, %eax
movq %rax, 0x18(%rsp)
jmp 0x56b5
movq 0xf5fc(%rip), %rax      # 0x14fd8
movq (%rax), %rdi
leaq 0x7e8f(%rip), %rsi      # 0xd875
movl %r12d, %edx
xorl %eax, %eax
callq 0x2320
movq 0x18(%rsp), %rax
movl %eax, %ecx
jmp 0x59c5
leaq 0xfe00(%rip), %rdi      # 0x15800
callq 0x23f0
testl %eax, %eax
je 0x56e6
leaq 0xfb6c(%rip), %rdi      # 0x15580
leaq 0x7e33(%rip), %rsi      # 0xd84e
leaq 0x58(%rsp), %rdx
callq 0x5fc6
movl $0x1, 0xfb71(%rip)      # 0x155a0
leaq 0xfb72(%rip), %rdi      # 0x155a8
leaq 0x7e12(%rip), %rsi      # 0xd84f
movq %r15, %rdx
callq 0x5fc6
movl $0x2, 0xfb79(%rip)      # 0x155c8
leaq 0xfb7a(%rip), %rdi      # 0x155d0
leaq 0x7df4(%rip), %rsi      # 0xd851
leaq 0xf(%rsp), %rdx
callq 0x5fc6
movl $0x2, 0xfb7f(%rip)      # 0x155f0
leaq 0xfb80(%rip), %rdi      # 0x155f8
leaq 0x7dd4(%rip), %rsi      # 0xd853
leaq 0x2f(%rsp), %rdx
callq 0x5fc6
movl $0x2, 0xfb85(%rip)      # 0x15618
leaq 0xfb86(%rip), %rdi      # 0x15620
leaq 0x7db8(%rip), %rsi      # 0xd859
leaq 0x2e(%rsp), %rdx
callq 0x5fc6
movl $0x2, 0xfb8b(%rip)      # 0x15640
leaq 0xfb8c(%rip), %rdi      # 0x15648
leaq 0x7d99(%rip), %rsi      # 0xd85c
leaq 0x2d(%rsp), %rdx
callq 0x5fc6
movl $0x2, 0xfb91(%rip)      # 0x15668
leaq 0xfb92(%rip), %rdi      # 0x15670
leaq 0x7d7a(%rip), %rsi      # 0xd85f
leaq 0x2c(%rsp), %rdx
callq 0x5fc6
movl $0x3, 0xfb97(%rip)      # 0x15690
leaq 0xfb98(%rip), %rdi      # 0x15698
leaq 0x7d43(%rip), %rsi      # 0xd84a
leaq 0x2b(%rsp), %rdx
callq 0x5fc6
movl $0x3, 0xfb9d(%rip)      # 0x156b8
leaq 0xfb9e(%rip), %rdi      # 0x156c0
leaq 0x7d38(%rip), %rsi      # 0xd861
leaq 0x2a(%rsp), %rdx
callq 0x5fc6
movl $0x4, 0xfba3(%rip)      # 0x156e0
leaq 0xfba4(%rip), %rdi      # 0x156e8
leaq 0x7d18(%rip), %rsi      # 0xd863
leaq 0x29(%rsp), %rdx
callq 0x5fc6
movl $0x5, 0xfba9(%rip)      # 0x15708
leaq 0xfbaa(%rip), %rdi      # 0x15710
leaq 0x7cf8(%rip), %rsi      # 0xd865
leaq 0x28(%rsp), %rdx
callq 0x5fc6
movl $0x5, 0xfbaf(%rip)      # 0x15730
leaq 0xfbb0(%rip), %rdi      # 0x15738
leaq 0x7cd8(%rip), %rsi      # 0xd867
leaq 0x27(%rsp), %rdx
callq 0x5fc6
movl $0x6, 0xfbb5(%rip)      # 0x15758
leaq 0xfbb6(%rip), %rdi      # 0x15760
leaq 0x7ca9(%rip), %rsi      # 0xd85a
leaq 0x26(%rsp), %rdx
callq 0x5fc6
movl $0x6, 0xfbbb(%rip)      # 0x15780
leaq 0xfbbc(%rip), %rdi      # 0x15788
leaq 0x7c8a(%rip), %rsi      # 0xd85d
leaq 0x25(%rsp), %rdx
callq 0x5fc6
movl $0x6, 0xfbc1(%rip)      # 0x157a8
leaq 0xfbc2(%rip), %rdi      # 0x157b0
leaq 0x7c74(%rip), %rsi      # 0xd869
leaq 0x24(%rsp), %rdx
callq 0x5fc6
movl $0x6, 0xfbc7(%rip)      # 0x157d0
leaq 0xfbc8(%rip), %rdi      # 0x157d8
leaq 0x7c58(%rip), %rsi      # 0xd86f
leaq 0x23(%rsp), %rdx
callq 0x5fc6
movl $0x6, 0xfbcd(%rip)      # 0x157f8
leaq -0x373e(%rip), %rdi     # 0x24f4
xorl %esi, %esi
leaq 0xf615(%rip), %rdx      # 0x15250
callq 0x2230
leaq 0xfbb9(%rip), %rdi      # 0x15800
callq 0x21b0
jmp 0x56e6
leaq 0xf918(%rip), %rdi      # 0x15570
callq 0x23f0
testl %eax, %eax
je 0x5807
leaq 0xf8a4(%rip), %rdi      # 0x15510
leaq 0x7bd1(%rip), %rsi      # 0xd844
leaq 0x58(%rsp), %rdx
callq 0x5fc6
leaq 0xf8ac(%rip), %rdi      # 0x15530
leaq 0x7bbf(%rip), %rsi      # 0xd84a
leaq 0x80(%rsp), %rdx
callq 0x5fc6
leaq 0xf8b1(%rip), %rdi      # 0x15550
leaq 0x7ba6(%rip), %rsi      # 0xd84c
leaq 0xf(%rsp), %rdx
callq 0x5fc6
leaq -0x37ec(%rip), %rdi     # 0x24cb
xorl %esi, %esi
leaq 0xf590(%rip), %rdx      # 0x15250
callq 0x2230
leaq 0xf8a4(%rip), %rdi      # 0x15570
callq 0x21b0
movq 0x48(%rsp), %rbp
leaq 0x80(%rsp), %r15
jmp 0x5807
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
cmpq $0x28, %rdx
jne 0x5d1d
movq 0xf2d8(%rip), %rcx      # 0x14fd8
movq (%rcx), %rdi
movq (%rax), %rdx
leaq 0x7b89(%rip), %rsi      # 0xd896
xorl %eax, %eax
callq 0x2320
cmpb $0x0, 0x54(%rsp)
jne 0x5d52
jmp 0x5d58
cmpq %rcx, %rax
sete %al
orb 0x18(%rsp), %al
movq 0xf2aa(%rip), %rcx      # 0x14fd8
movq (%rcx), %rcx
testb $0x1, %al
je 0x5d40
leaq 0x7b6a(%rip), %rdi      # 0xd8a6
pushq $0x1c
jmp 0x5d49
leaq 0x7b7c(%rip), %rdi      # 0xd8c3
pushq $0x1b
popq %rsi
pushq $0x1
popq %rdx
callq 0x2460
incl 0xf570(%rip)            # 0x152c8
leaq 0x30(%rsp), %rdi
callq 0x66de
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
leaq 0xf7d2(%rip), %rax      # 0x15550
movq %rax, 0xc0(%rsp)
jmp 0x5d8b
movq %rax, %r14
leaq 0xf77e(%rip), %rbx      # 0x15510
movq 0xc0(%rsp), %r15
addq $-0x20, %r15
movq %r15, %rdi
callq 0x2130
cmpq %rbx, %r15
jne 0x5d9a
jmp 0x5db0
movq %rax, %r14
leaq 0xf7b9(%rip), %rdi      # 0x15570
jmp 0x5e3e
movq %rax, %r14
leaq 0xfa12(%rip), %rax      # 0x157d8
movq %rax, 0xa0(%rsp)
jmp 0x5dd3
movq %rax, %r14
movq 0xa0(%rsp), %rax
movq %rax, 0xa8(%rsp)
jmp 0x5de8
movq %rax, %r14
movq 0xa8(%rsp), %rax
movq %rax, 0xb0(%rsp)
jmp 0x5dfd
movq %rax, %r14
movq 0xb0(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0xf75f(%rip), %rbx      # 0x15580
movq 0x10(%rsp), %r15
addq $-0x28, %r15
movq %r15, %rdi
callq 0x2130
cmpq %rbx, %r15
jne 0x5e26
leaq 0xf9c2(%rip), %rdi      # 0x15800
callq 0x21a0
jmp 0x5f24
movq %rax, %r14
jmp 0x5e0d
movq %rax, %r14
leaq 0xf8b9(%rip), %rax      # 0x15710
jmp 0x5e15
movq %rax, %r14
leaq 0xf885(%rip), %rax      # 0x156e8
jmp 0x5e15
movq %rax, %r14
leaq 0xf851(%rip), %rax      # 0x156c0
jmp 0x5e15
movq %rax, %r14
leaq 0xf81d(%rip), %rax      # 0x15698
jmp 0x5e15
movq %rax, %r14
leaq 0xf7e9(%rip), %rax      # 0x15670
jmp 0x5e15
movq %rax, %r14
leaq 0xf7b5(%rip), %rax      # 0x15648
jmp 0x5e15
movq %rax, %r14
leaq 0xf781(%rip), %rax      # 0x15620
jmp 0x5e15
movq %rax, %r14
leaq 0xf74a(%rip), %rax      # 0x155f8
jmp 0x5e15
movq %rax, %r14
leaq 0xf713(%rip), %rax      # 0x155d0
jmp 0x5e15
movq %rax, %r14
jmp 0x5e1a
movq %rax, %r14
jmp 0x5e37
jmp 0x5eef
movq %rax, %r14
leaq 0x58(%rsp), %rdi
callq 0x2130
jmp 0x5ef2
jmp 0x5efc
jmp 0x5f17
jmp 0x5efc
jmp 0x5f17
jmp 0x5efc
jmp 0x5efc
movq %rax, %r14
leaq 0x80(%rsp), %rdi
jmp 0x5f1f
movq %rax, %r14
jmp 0x5f24
jmp 0x5f17
jmp 0x5f17
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x2130
jmp 0x5f1a
movq %rax, %r14
leaq 0x58(%rsp), %rdi
callq 0x2130
leaq 0x30(%rsp), %rdi
callq 0x66de
movq %r14, %rdi
callq 0x23c0