// File: /workspace/github_c_makefile_star2_O3/wjmelements[P]evm/tst/evm.c
// Function: test_delegateCall
void test_delegateCall() {
    evmInit();

    // 5f365b818111156042577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01813560f81c8153803560f81c825390600101906002565b365ff3
#define PROGRAM_REVERSE \
        PUSH0, CALLDATASIZE, \
        JUMPDEST, \
        DUP2, DUP2, GT, ISZERO, PUSH1, 66, JUMPI, \
        PUSH32, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ADD, \
        DUP2, CALLDATALOAD, PUSH1, 248, SHR, DUP2, MSTORE8, \
        DUP1, CALLDATALOAD, PUSH1, 248, SHR, DUP3, MSTORE8, \
        SWAP1, PUSH1, 1, ADD, SWAP1, \
        PUSH1, 2, JUMP, \
        JUMPDEST, \
        CALLDATASIZE, PUSH0, RETURN
    op_t reverseBytes[] = {
        PROGRAM_REVERSE
    };

    op_t createReverseBytes[] = {
        PUSH1, 70, DUP1, PUSH1, 9, RETURNDATASIZE, CODECOPY, RETURNDATASIZE, RETURN,
        PROGRAM_REVERSE
    };
#undef PROGRAM_REVERSE
    address_t from = AddressFromHex42("0x4a6f6B9fF1fc974096f9063a45Fd12bD5B928AD1");
    uint64_t gas = 0x10ad0;
    val_t value;
    value[0] = value[1] = value[2] = 0;
    data_t input;
    input.size = sizeof(createReverseBytes);
    input.content = createReverseBytes;
    result_t result = txCreate(from, gas, value, input);
    assert(UPPER(UPPER(result.status)) == 0);
    assert(LOWER(UPPER(result.status)) == 0x80d9b122);
    assert(UPPER(LOWER(result.status)) == 0xdc3a16fdc41f96cf);
    assert(LOWER(LOWER(result.status)) == 0x010ffe7e38d227c3);
    assert(result.returnData.size == sizeof(reverseBytes));
    assert(memcmp(result.returnData.content, reverseBytes, sizeof(reverseBytes)) == 0);
    assert(result.gasRemaining == 0);

#define PROGRAM_PROXY \
        CALLDATASIZE, RETURNDATASIZE, RETURNDATASIZE, CALLDATACOPY, \
        RETURNDATASIZE, \
        RETURNDATASIZE, RETURNDATASIZE, CALLDATASIZE, RETURNDATASIZE, PUSH20, ACCOUNT0, GAS, DELEGATECALL, \
        RETURNDATASIZE, DUP3, DUP1, RETURNDATACOPY, \
        SWAP1, RETURNDATASIZE, SWAP2, PUSH1, 43, JUMPI, REVERT, \
        JUMPDEST, RETURN
    op_t delegateCaller[] = {
        PROGRAM_PROXY
    };

    op_t createDelegateCaller[] = {
        PUSH1, 45,
        DUP1, PUSH1, 9, RETURNDATASIZE, CODECOPY, RETURNDATASIZE, RETURN,
        PROGRAM_PROXY
    };
#undef PROGRAM_PROXY

    gas = 0xf5b0;
    input.content = createDelegateCaller;
    input.size = sizeof(createDelegateCaller);

    result_t secondCreateResult = txCreate(from, gas, value, input);
    assert(UPPER(UPPER(secondCreateResult.status)) == 0);
    assert(LOWER(UPPER(secondCreateResult.status)) == 0x47784b21);
    assert(UPPER(LOWER(secondCreateResult.status)) == 0x780d1e1d5efcd005);
    assert(LOWER(LOWER(secondCreateResult.status)) == 0xc5fe542813b6d71e);
    assert(secondCreateResult.returnData.size == sizeof(delegateCaller));
    assert(memcmp(secondCreateResult.returnData.content, delegateCaller, sizeof(delegateCaller)) == 0);
    assert(secondCreateResult.gasRemaining == 0);

    address_t proxy = AddressFromUint256(&secondCreateResult.status);
    gas = 0x6fe8;
    input.content = createReverseBytes;
    input.size = sizeof(createReverseBytes);

    result_t reverseProxy = txCall(from, gas, proxy, value, input, NULL);
    assert(UPPER(UPPER(reverseProxy.status)) == 0);
    assert(LOWER(UPPER(reverseProxy.status)) == 0);
    assert(UPPER(LOWER(reverseProxy.status)) == 0);
    assert(LOWER(LOWER(reverseProxy.status)) == 1);
    assert(reverseProxy.returnData.size == input.size);
    for (size_t i = 0; i < input.size; i++) {
        assert(reverseProxy.returnData.content[i] == input.content[input.size - i - 1]);
    }
    assert(reverseProxy.gasRemaining == 16);

    evmFinalize();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
xorl %eax, %eax
callq 0xca4d
leaq 0xd5ce(%rip), %rsi      # 0x18770
leaq 0x130(%rsp), %rax
movl $0x9, %ecx
movq %rax, %rdi
rep  movsq (%rsi), %es:(%rdi)
movl $0xf35f365b, 0x4b(%rax) # imm = 0xF35F365B
movl $0x5b560260, 0x48(%rax) # imm = 0x5B560260
movq $-0x2, %r14
leaq 0x30(%rsp), %r15
leaq 0x8e9a(%rip), %r12      # 0x14070
movq 0x12e1b(%rip), %r13     # 0x1dff8
leaq 0xbef9(%rip), %rbx      # 0x170dd
movzbl 0x4(%r14,%r12), %ecx
leal -0x30(%rcx), %ebp
cmpb $0xa, %bpl
jb 0xb20b
leal -0x61(%rcx), %eax
cmpb $0x5, %al
ja 0xb1ff
addb $-0x57, %cl
jmp 0xb209
leal -0x41(%rcx), %eax
cmpb $0x5, %al
ja 0xb249
addb $-0x37, %cl
movl %ecx, %ebp
movzbl 0x5(%r14,%r12), %ecx
leal -0x30(%rcx), %eax
cmpb $0xa, %al
jb 0xb230
leal -0x61(%rcx), %eax
cmpb $0x5, %al
ja 0xb224
addb $-0x57, %cl
jmp 0xb22e
leal -0x41(%rcx), %eax
cmpb $0x5, %al
ja 0xb25e
addb $-0x37, %cl
movl %ecx, %eax
shlb $0x4, %bpl
addb %al, %bpl
movb %bpl, (%r15)
addq $0x2, %r14
incq %r15
cmpq $0x26, %r14
jb 0xb1e4
jmp 0xb272
movq (%r13), %rdi
movq %rbx, %rsi
movl %ecx, %edx
xorl %eax, %eax
callq 0x30a0
movb $-0x1, %bpl
jmp 0xb20b
movq (%r13), %rdi
movq %rbx, %rsi
movl %ecx, %edx
xorl %eax, %eax
callq 0x30a0
movb $-0x1, %al
jmp 0xb230
leaq 0x44(%rsp), %rdx
movl $0x0, 0x8(%rdx)
movq $0x0, (%rdx)
movl 0x40(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x30(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0xf0(%rsp), %rbx
leaq 0x130(%rsp), %r8
movl $0x10ad0, %esi          # imm = 0x10AD0
movl $0x4f, %ecx
movq %rbx, %rdi
callq 0xd683
cmpq $0x0, 0x10(%rbx)
jne 0xb540
movl $0x80d9b122, %eax       # imm = 0x80D9B122
cmpq %rax, 0x108(%rsp)
jne 0xb55f
movabsq $-0x23c5e9023be06931, %rax # imm = 0xDC3A16FDC41F96CF
cmpq %rax, 0x110(%rsp)
jne 0xb57e
movabsq $0x10ffe7e38d227c3, %rax # imm = 0x10FFE7E38D227C3
cmpq %rax, 0x118(%rsp)
jne 0xb59d
cmpq $0x46, 0xf0(%rsp)
jne 0xb5bc
movq 0xf8(%rsp), %rdi
leaq 0xd3fc(%rip), %rsi      # 0x18720
movl $0x46, %edx
callq 0x30d0
testl %eax, %eax
jne 0xb5db
cmpq $0x0, 0x120(%rsp)
jne 0xb5fa
movaps 0xd4c4(%rip), %xmm0     # 0x18810
leaq 0x180(%rsp), %r8
movaps %xmm0, 0x20(%r8)
movaps 0xd4a0(%rip), %xmm0     # 0x18800
movaps %xmm0, 0x10(%r8)
movaps 0xd484(%rip), %xmm0     # 0x187f0
movaps %xmm0, (%r8)
movabsq $-0xca402a8d49f6ec3, %rax # imm = 0xF35BFD572B60913D
movq %rax, 0x2e(%r8)
movl 0x40(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x30(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0xb0(%rsp), %rbx
leaq 0x44(%rsp), %rdx
movl $0xf5b0, %esi           # imm = 0xF5B0
movl $0x36, %ecx
movq %rbx, %rdi
callq 0xd683
cmpq $0x0, 0x10(%rbx)
jne 0xb619
cmpq $0x47784b21, 0xc8(%rsp) # imm = 0x47784B21
jne 0xb638
movabsq $0x780d1e1d5efcd005, %rax # imm = 0x780D1E1D5EFCD005
cmpq %rax, 0xd0(%rsp)
jne 0xb657
movabsq $-0x3a01abd7ec4928e2, %rax # imm = 0xC5FE542813B6D71E
cmpq %rax, 0xd8(%rsp)
jne 0xb676
cmpq $0x2d, 0xb0(%rsp)
jne 0xb695
movq 0xb8(%rsp), %rdi
leaq 0xd3a7(%rip), %rsi      # 0x187c0
movl $0x2d, %edx
callq 0x30d0
testl %eax, %eax
jne 0xb6b4
cmpq $0x0, 0xe0(%rsp)
jne 0xb6d3
movaps 0x8c1f(%rip), %xmm0     # 0x14060
movaps %xmm0, 0x50(%rsp)
movl $0x1ed7b613, 0x60(%rsp) # imm = 0x1ED7B613
movl 0x60(%rsp), %eax
movl %eax, 0x28(%rsp)
movaps 0x50(%rsp), %xmm0
movups %xmm0, 0x18(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x30(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0x70(%rsp), %rbx
leaq 0x44(%rsp), %rdx
leaq 0x130(%rsp), %r8
movl $0x6fe8, %esi           # imm = 0x6FE8
movl $0x4f, %ecx
movq %rbx, %rdi
xorl %r9d, %r9d
callq 0xd126
cmpq $0x0, 0x10(%rbx)
jne 0xb6f2
cmpq $0x0, 0x88(%rsp)
jne 0xb711
cmpq $0x0, 0x90(%rsp)
jne 0xb730
cmpq $0x1, 0x98(%rsp)
jne 0xb74f
cmpq $0x4f, 0x70(%rsp)
jne 0xb76e
movl $0x4f, %eax
movq 0x78(%rsp), %rcx
movb (%rcx), %dl
cmpb 0x12f(%rsp,%rax), %dl
jne 0xb521
incq %rcx
decq %rax
jne 0xb4e6
cmpq $0x10, 0xa0(%rsp)
jne 0xb78d
xorl %eax, %eax
callq 0xcd49
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbb4d(%rip), %rdi      # 0x17075
leaq 0x8b8d(%rip), %rsi      # 0x140bc
leaq 0xb94d(%rip), %rcx      # 0x16e83
movl $0x722, %edx            # imm = 0x722
callq 0x3040
leaq 0x8b54(%rip), %rdi      # 0x1409b
leaq 0x8b6e(%rip), %rsi      # 0x140bc
leaq 0xb92e(%rip), %rcx      # 0x16e83
movl $0x6ef, %edx            # imm = 0x6EF
callq 0x3040
leaq 0x8b71(%rip), %rdi      # 0x140d7
leaq 0x8b4f(%rip), %rsi      # 0x140bc
leaq 0xb90f(%rip), %rcx      # 0x16e83
movl $0x6f0, %edx            # imm = 0x6F0
callq 0x3040
leaq 0x8b7c(%rip), %rdi      # 0x14101
leaq 0x8b30(%rip), %rsi      # 0x140bc
leaq 0xb8f0(%rip), %rcx      # 0x16e83
movl $0x6f1, %edx            # imm = 0x6F1
callq 0x3040
leaq 0x8b8f(%rip), %rdi      # 0x14133
leaq 0x8b11(%rip), %rsi      # 0x140bc
leaq 0xb8d1(%rip), %rcx      # 0x16e83
movl $0x6f2, %edx            # imm = 0x6F2
callq 0x3040
leaq 0xb8d9(%rip), %rdi      # 0x16e9c
leaq 0x8af2(%rip), %rsi      # 0x140bc
leaq 0xb8b2(%rip), %rcx      # 0x16e83
movl $0x6f3, %edx            # imm = 0x6F3
callq 0x3040
leaq 0xb8e9(%rip), %rdi      # 0x16ecb
leaq 0x8ad3(%rip), %rsi      # 0x140bc
leaq 0xb893(%rip), %rcx      # 0x16e83
movl $0x6f4, %edx            # imm = 0x6F4
callq 0x3040
leaq 0x8b80(%rip), %rdi      # 0x14181
leaq 0x8ab4(%rip), %rsi      # 0x140bc
leaq 0xb874(%rip), %rcx      # 0x16e83
movl $0x6f5, %edx            # imm = 0x6F5
callq 0x3040
leaq 0x94e4(%rip), %rdi      # 0x14b04
leaq 0x8a95(%rip), %rsi      # 0x140bc
leaq 0xb855(%rip), %rcx      # 0x16e83
movl $0x70e, %edx            # imm = 0x70E
callq 0x3040
leaq 0x94f2(%rip), %rdi      # 0x14b31
leaq 0x8a76(%rip), %rsi      # 0x140bc
leaq 0xb836(%rip), %rcx      # 0x16e83
movl $0x70f, %edx            # imm = 0x70F
callq 0x3040
leaq 0x9509(%rip), %rdi      # 0x14b67
leaq 0x8a57(%rip), %rsi      # 0x140bc
leaq 0xb817(%rip), %rcx      # 0x16e83
movl $0x710, %edx            # imm = 0x710
callq 0x3040
leaq 0x9528(%rip), %rdi      # 0x14ba5
leaq 0x8a38(%rip), %rsi      # 0x140bc
leaq 0xb7f8(%rip), %rcx      # 0x16e83
movl $0x711, %edx            # imm = 0x711
callq 0x3040
leaq 0xb87a(%rip), %rdi      # 0x16f16
leaq 0x8a19(%rip), %rsi      # 0x140bc
leaq 0xb7d9(%rip), %rcx      # 0x16e83
movl $0x712, %edx            # imm = 0x712
callq 0x3040
leaq 0xb898(%rip), %rdi      # 0x16f53
leaq 0x89fa(%rip), %rsi      # 0x140bc
leaq 0xb7ba(%rip), %rcx      # 0x16e83
movl $0x713, %edx            # imm = 0x713
callq 0x3040
leaq 0x9509(%rip), %rdi      # 0x14be3
leaq 0x89db(%rip), %rsi      # 0x140bc
leaq 0xb79b(%rip), %rcx      # 0x16e83
movl $0x714, %edx            # imm = 0x714
callq 0x3040
leaq 0xb8b5(%rip), %rdi      # 0x16fae
leaq 0x89bc(%rip), %rsi      # 0x140bc
leaq 0xb77c(%rip), %rcx      # 0x16e83
movl $0x71c, %edx            # imm = 0x71C
callq 0x3040
leaq 0xb8bd(%rip), %rdi      # 0x16fd5
leaq 0x899d(%rip), %rsi      # 0x140bc
leaq 0xb75d(%rip), %rcx      # 0x16e83
movl $0x71d, %edx            # imm = 0x71D
callq 0x3040
leaq 0xb8c5(%rip), %rdi      # 0x16ffc
leaq 0x897e(%rip), %rsi      # 0x140bc
leaq 0xb73e(%rip), %rcx      # 0x16e83
movl $0x71e, %edx            # imm = 0x71E
callq 0x3040
leaq 0xb8cd(%rip), %rdi      # 0x17023
leaq 0x895f(%rip), %rsi      # 0x140bc
leaq 0xb71f(%rip), %rcx      # 0x16e83
movl $0x71f, %edx            # imm = 0x71F
callq 0x3040
leaq 0xb8d5(%rip), %rdi      # 0x1704a
leaq 0x8940(%rip), %rsi      # 0x140bc
leaq 0xb700(%rip), %rcx      # 0x16e83
movl $0x720, %edx            # imm = 0x720
callq 0x3040
leaq 0xb929(%rip), %rdi      # 0x170bd
leaq 0x8921(%rip), %rsi      # 0x140bc
leaq 0xb6e1(%rip), %rcx      # 0x16e83
movl $0x724, %edx            # imm = 0x724
callq 0x3040