// File: /workspace/github_cpp_makefile_star2_O2/JohnCGriffin[P]BrainForked/bf_main.cpp
// Function: bf::execute(std::vector<bf::Instruction, std::allocator<bf::Instruction>>&)
static void execute(Instructions&  _instructions)
    {
	std::map<Action,void*> addrs;

	// Note that initialization in modern manner chokes clang/g++
	// when in c++14/17.  Direct assignment one by one seems to work.
	addrs[ADVANCE]	    = &&_ADVANCE;
	addrs[DECR1MX]	    = &&_DECR1MX;
	addrs[FALSEJUMP]    = &&_FALSEJUMP;
	addrs[GIVE]	    = &&_GIVE;
	addrs[INCR1MX]	    = &&_INCR1MX;
	addrs[INCR]	    = &&_INCR;
	addrs[M1ZERO]	    = &&_M1ZERO;
	addrs[MOVEWHILE]    = &&_MOVEWHILE;
	addrs[MOVE]	    = &&_MOVE;
	addrs[MXDECR1]	    = &&_MXDECR1;
	addrs[MXINCR1]	    = &&_MXINCR1;
	addrs[OFFINCR]	    = &&_OFFINCR;
	addrs[PRINT]	    = &&_PRINT;
	addrs[READ]	    = &&_READ;
	addrs[TAKE]	    = &&_TAKE;
	addrs[TERMINATE]    = &&_TERMINATE;
	addrs[TRUEJUMP]	    = &&_TRUEJUMP;
	addrs[VALUE]	    = &&_VALUE;
	addrs[WHILEDECROI2] = &&_WHILEDECROI2;
	addrs[WHILEIM2]	    = &&_WHILEIM2;
	addrs[WHILEIM3]	    = &&_WHILEIM3;
	addrs[WHILEMGM]	    = &&_WHILEMGM;
	addrs[ZERO2IF]	    = &&_ZERO2IF;
	addrs[ZEROM1]	    = &&_ZEROM1;
	addrs[ZERO]	    = &&_ZERO;

	for(auto a : ENUMERATED_ACTIONS){
	    if(!addrs[a]){
		throw std::logic_error(to_string(a) + " not in address table");
	    }
	}

	for(auto& instr : _instructions){
	    instr.jump = addrs.at(instr.action);
	}

#ifdef PROFILER
	for(int i=0; i<_instructions.size(); i++){
	    _instructions.at(i).ndx = i;
	}
#endif

	std::vector<char> characters(30000);
	char* ptr = characters.data();
	auto BEGIN = _instructions.data();
	auto IP = BEGIN;

	// initial JUMP.  The remainder happen via the LOOP macro.
	goto *(IP->jump);

#define LOOP() IP++; goto *(IP->jump)

    _TRUEJUMP:
	if(*ptr){
	    IP += IP->val;
	}
	LOOP();

    _FALSEJUMP:
	if(!(*ptr)){
	    IP += IP->val;
	}
#ifdef PROFILER
	else {
	    current_loop = IP->ndx;
	}
#endif
	LOOP();

    _DECR1MX:
	ptr[0]--;
	ptr += IP->val;
	LOOP();

    _INCR1MX:
	ptr[0]++;
	ptr += IP->val;
	LOOP();

    _MXINCR1:
	ptr += IP->val;
	ptr[0]++;
	LOOP();

    _MXDECR1:
	ptr += IP->val;
	ptr[0]--;
	LOOP();

    _WHILEDECROI2:
	if(ptr[0]){
	    const int o1 = IP[-2].val;
	    const int o2 = IP[-1].val;
	    do {
		ptr[0]--;
		ptr[o1]++;
		ptr[o2]++;
	    } while(ptr[0]);
	}
	LOOP();

    _WHILEMGM:
	if(ptr[0]){
	    const int m1 = IP[-2].val;
	    const int g = IP[-1].val;
	    const int m2 = IP->val;
	    do {
		ptr += m1;
		ptr[g] += ptr[0];
		ptr[0] = 0;
		ptr += m2;
	    } while(ptr[0]);
	}
	LOOP();

    _WHILEIM3:
	if(ptr[0]){
	    const auto a = IP[-6].val;
	    const auto b = IP[-5].val;
	    const auto c = IP[-4].val;
	    const auto d = IP[-3].val;
	    const auto e = IP[-2].val;
	    const auto f = IP[-1].val;
	    do {
		ptr[0] += a;
		ptr += b;
		ptr[0] += c;
		ptr += d;
		ptr[0] += e;
		ptr += f;
	    } while(ptr[0]);
	}
	LOOP();

    _WHILEIM2:
	if(ptr[0]){
	    const auto a = IP[-4].val;
	    const auto b = IP[-3].val;
	    const auto c = IP[-2].val;
	    const auto d = IP[-1].val;
	    do {
		ptr[0] += a;
		ptr += b;
		ptr[0] += c;
		ptr += d;
	    } while(ptr[0]);
	}
	LOOP();

    _OFFINCR:
	ptr[IP[-1].val] += IP->val;
	LOOP();


    _ADVANCE:
	IP += IP->val;
	LOOP();

    _VALUE:
	LOOP();

    _GIVE:
	ptr[IP->val] += (ptr[0] + 256);
	ptr[0] = 0;
	LOOP();

    _TAKE:
	ptr[0] += (ptr[IP->val] + 256);
	ptr[IP->val] = 0;
	LOOP();

    _MOVE:
	ptr += IP->val;
	LOOP();

    _INCR:
	*ptr += IP->val;
	LOOP();

    _MOVEWHILE:
	while(ptr[0]){
	    ptr += IP->val;
	}
	LOOP();

    _ZERO2IF:
	if(ptr[0]){
	    ptr[0] = ptr[1] = 0;
	}
	LOOP();

    _ZEROM1:
	*ptr++ = 0;
	LOOP();

    _M1ZERO:
	*(++ptr) = 0;
	LOOP();

    _ZERO:
	ptr[0] = 0;
	LOOP();


    _PRINT:
#ifndef PROFILER
	std::cout << (*ptr);
#endif
	LOOP();

    _READ:
	std::cin.get(*ptr);
	LOOP();

    _TERMINATE:
	return;

    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbx
leaq 0x38(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x8(%rsp), %rsi
andl $0x0, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x464(%rip), %rcx       # 0x2c4b
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x1, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x559(%rip), %rcx       # 0x2d5f
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x2, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x4d9(%rip), %rcx       # 0x2cfe
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x3, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x479(%rip), %rcx       # 0x2cbd
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x5, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x50c(%rip), %rcx       # 0x2d6f
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x4, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x41c(%rip), %rcx       # 0x2c9e
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x6, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x3f0(%rip), %rcx       # 0x2c91
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x8, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x3bc(%rip), %rcx       # 0x2c7c
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x7, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x493(%rip), %rcx       # 0x2d72
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x9, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x466(%rip), %rcx       # 0x2d64
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xa, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x48d(%rip), %rcx       # 0x2daa
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xb, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x396(%rip), %rcx       # 0x2cd2
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xc, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x306(%rip), %rcx       # 0x2c61
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xd, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x2d3(%rip), %rcx       # 0x2c4d
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xe, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x34a(%rip), %rcx       # 0x2ce3
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0xf, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x474(%rip), %rcx       # 0x2e2c
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x10, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x24e(%rip), %rcx       # 0x2c25
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x11, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x245(%rip), %rcx       # 0x2c3b
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x12, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x36a(%rip), %rcx       # 0x2d7f
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x13, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x3bd(%rip), %rcx       # 0x2df1
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x14, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x2ba(%rip), %rcx       # 0x2d0d
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x15, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x346(%rip), %rcx       # 0x2db8
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x17, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x218(%rip), %rcx       # 0x2ca9
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x18, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x1c6(%rip), %rcx       # 0x2c76
movq %rcx, (%rax)
leaq 0x8(%rsp), %rsi
movl $0x16, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x3250
leaq 0x1fa(%rip), %rcx       # 0x2cc9
movq %rcx, (%rax)
xorl %r12d, %r12d
leaq 0x35f8(%rip), %r13      # 0x60d4
leaq 0x30(%rsp), %r14
leaq 0x2c(%rsp), %r15
cmpq $0x64, %r12
je 0x2b60
movl (%r12,%r13), %eax
movl %eax, 0x2c(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x329e
addq $0x4, %r12
cmpq $0x0, (%rax)
jne 0x2ae6
pushq $0x10
popq %rdi
callq 0x20b0
movq %rax, %r14
movl 0x2c(%rsp), %esi
leaq 0x78(%rsp), %rdi
callq 0x3851
leaq 0x3559(%rip), %rdx      # 0x6082
leaq 0x8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x32ec
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x2250
xorl %ebp, %ebp
movq 0x647f(%rip), %rsi      # 0x8fd0
movq 0x6460(%rip), %rdx      # 0x8fb8
movq %r14, %rdi
callq 0x22b0
movq (%rbx), %r14
movq 0x8(%rbx), %r12
leaq 0x30(%rsp), %r15
cmpq %r12, %r14
je 0x2b89
movq %r15, %rdi
movq %r14, %rsi
callq 0x330c
movq (%rax), %rax
movq %rax, 0x8(%r14)
addq $0x10, %r14
jmp 0x2b6c
leaq 0x60(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movl $0x7530, %esi           # imm = 0x7530
callq 0x3344
movq 0x60(%rsp), %r14
movq (%rbx), %rbx
leaq 0x8(%rbx), %rcx
movq %rbx, %rax
jmpq *(%rcx)
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
jmp 0x2c1d
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2090
jmp 0x2bf7
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x78(%rsp), %rdi
callq 0x2090
testb %bpl, %bpl
jne 0x2c0e
jmp 0x2e5f
movq %rax, %rbx
movq %r14, %rdi
callq 0x2130
jmp 0x2e5f
jmp 0x2c1d
movq %rax, %rbx
jmp 0x2e5f
cmpb $0x0, (%r14)
je 0x2e24
movswq 0x4(%rbx), %rax
shlq $0x4, %rax
addq %rbx, %rax
leaq 0x10(%rax), %rbx
movq %rax, %rcx
addq $0x18, %rcx
movq %rbx, %rax
jmpq *(%rcx)
jmp 0x2c2f
movq 0x6384(%rip), %rdi      # 0x8fd8
movq %r14, %rsi
callq 0x2200
movq %rbx, %rax
jmp 0x2c3b
movsbl (%r14), %esi
movq 0x6354(%rip), %rdi      # 0x8fc0
callq 0x21c0
movq %rbx, %rax
jmp 0x2c3b
movb $0x0, (%r14)
jmp 0x2c96
jmp 0x2c86
movswq 0x4(%rbx), %rax
addq %rax, %r14
cmpb $0x0, (%r14)
jne 0x2c7e
jmp 0x2e24
movb $0x0, 0x1(%r14)
incq %r14
jmp 0x2e24
movb 0x4(%rbx), %al
addb %al, (%r14)
jmp 0x2e24
cmpb $0x0, (%r14)
je 0x2e24
andw $0x0, (%r14)
jmp 0x2e24
movb (%r14), %al
movswq 0x4(%rbx), %rcx
addb %al, (%r14,%rcx)
movb $0x0, (%r14)
jmp 0x2e24
movb 0x4(%rbx), %al
movswq -0xc(%rbx), %rcx
addb %al, (%r14,%rcx)
jmp 0x2e24
movswq 0x4(%rbx), %rax
movb (%r14,%rax), %al
addb %al, (%r14)
movswq 0x4(%rbx), %rax
movb $0x0, (%r14,%rax)
jmp 0x2e24
cmpb $0x0, (%r14)
jne 0x2e24
jmp 0x2c2f
movb (%r14), %r8b
testb %r8b, %r8b
je 0x2e24
movswq -0x4c(%rbx), %rax
movb -0x5c(%rbx), %cl
movb -0x3c(%rbx), %dl
movswq -0x2c(%rbx), %rsi
movb -0x1c(%rbx), %dil
movswq -0xc(%rbx), %r9
leaq (%rax,%rsi), %r10
leaq (%r10,%r9), %r11
addb %cl, %r8b
movb %r8b, (%r14)
addb %dl, (%r14,%rax)
addb %dil, (%r14,%r10)
movb (%r14,%r11), %r8b
addq %rax, %r14
addq %rsi, %r14
addq %r9, %r14
testb %r8b, %r8b
jne 0x2d3a
jmp 0x2e24
decb (%r14)
jmp 0x2d72
movswq 0x4(%rbx), %rax
decb (%r14,%rax)
jmp 0x2db3
incb (%r14)
movswq 0x4(%rbx), %rax
addq %rax, %r14
jmp 0x2e24
movb (%r14), %al
testb %al, %al
je 0x2e24
movswq -0x1c(%rbx), %rcx
movswq -0xc(%rbx), %rdx
decb %al
movb %al, (%r14)
incb (%r14,%rcx)
incb (%r14,%rdx)
movb (%r14), %al
testb %al, %al
jne 0x2d94
jmp 0x2e24
movswq 0x4(%rbx), %rax
incb (%r14,%rax)
addq %rax, %r14
jmp 0x2e24
cmpb $0x0, (%r14)
je 0x2e24
movswq -0x1c(%rbx), %rax
movswq -0xc(%rbx), %rcx
movswq 0x4(%rbx), %rdx
leaq (%rax,%rdx), %rsi
addq %rax, %rcx
movq %r14, %rdi
addq %rax, %r14
movb (%rdi,%rax), %r8b
addb %r8b, (%rdi,%rcx)
movb $0x0, (%rdi,%rax)
addq %rdx, %r14
cmpb $0x0, (%rdi,%rsi)
jne 0x2dd4
jmp 0x2e24
movb (%r14), %dl
testb %dl, %dl
je 0x2e24
movswq -0x2c(%rbx), %rax
movb -0x3c(%rbx), %cl
movb -0x1c(%rbx), %sil
movswq -0xc(%rbx), %rdi
leaq (%rax,%rdi), %r8
addb %cl, %dl
movb %dl, (%r14)
addb %sil, (%r14,%rax)
movb (%r14,%r8), %dl
addq %rax, %r14
addq %rdi, %r14
testb %dl, %dl
jne 0x2e0d
movq %rbx, %rax
jmp 0x2c3b
leaq 0x60(%rsp), %rdi
callq 0x36f6
leaq 0x30(%rsp), %rdi
callq 0x3770
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x36f6
leaq 0x30(%rsp), %rdi
callq 0x3770
movq %rbx, %rdi
callq 0x22c0
nop