// File: /workspace/github_c_makefile_star2_O1/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 0xca7b
leaq 0xd592(%rip), %rsi      # 0x18750
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 0x38(%rsp), %r15
leaq 0x8e5e(%rip), %r12      # 0x14050
movq 0x12dff(%rip), %r13     # 0x1dff8
leaq 0xbebd(%rip), %rbx      # 0x170bd
movzbl 0x4(%r14,%r12), %ecx
leal -0x30(%rcx), %ebp
cmpb $0xa, %bpl
jb 0xb227
leal -0x61(%rcx), %eax
cmpb $0x5, %al
ja 0xb21b
addb $-0x57, %cl
jmp 0xb225
leal -0x41(%rcx), %eax
cmpb $0x5, %al
ja 0xb265
addb $-0x37, %cl
movl %ecx, %ebp
movzbl 0x5(%r14,%r12), %ecx
leal -0x30(%rcx), %eax
cmpb $0xa, %al
jb 0xb24c
leal -0x61(%rcx), %eax
cmpb $0x5, %al
ja 0xb240
addb $-0x57, %cl
jmp 0xb24a
leal -0x41(%rcx), %eax
cmpb $0x5, %al
ja 0xb27a
addb $-0x37, %cl
movl %ecx, %eax
shlb $0x4, %bpl
addb %al, %bpl
movb %bpl, (%r15)
addq $0x2, %r14
incq %r15
cmpq $0x26, %r14
jb 0xb200
jmp 0xb28e
movq (%r13), %rdi
movq %rbx, %rsi
movl %ecx, %edx
xorl %eax, %eax
callq 0x30a0
movb $-0x1, %bpl
jmp 0xb227
movq (%r13), %rdi
movq %rbx, %rsi
movl %ecx, %edx
xorl %eax, %eax
callq 0x30a0
movb $-0x1, %al
jmp 0xb24c
leaq 0x64(%rsp), %rdx
movl $0x0, 0x8(%rdx)
movq $0x0, (%rdx)
movl 0x48(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x38(%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 0xd845
cmpq $0x0, 0x10(%rbx)
jne 0xb575
movl $0x80d9b122, %eax       # imm = 0x80D9B122
cmpq %rax, 0x108(%rsp)
jne 0xb594
movabsq $-0x23c5e9023be06931, %rax # imm = 0xDC3A16FDC41F96CF
cmpq %rax, 0x110(%rsp)
jne 0xb5b3
movabsq $0x10ffe7e38d227c3, %rax # imm = 0x10FFE7E38D227C3
cmpq %rax, 0x118(%rsp)
jne 0xb5d2
cmpq $0x46, 0xf0(%rsp)
jne 0xb5f1
movq 0xf8(%rsp), %rdi
leaq 0xd3c0(%rip), %rsi      # 0x18700
movl $0x46, %edx
callq 0x30d0
testl %eax, %eax
jne 0xb610
cmpq $0x0, 0x120(%rsp)
jne 0xb62f
movaps 0xd488(%rip), %xmm0     # 0x187f0
leaq 0x180(%rsp), %r8
movaps %xmm0, 0x20(%r8)
movaps 0xd464(%rip), %xmm0     # 0x187e0
movaps %xmm0, 0x10(%r8)
movaps 0xd448(%rip), %xmm0     # 0x187d0
movaps %xmm0, (%r8)
movabsq $-0xca402a8d49f6ec3, %rax # imm = 0xF35BFD572B60913D
movq %rax, 0x2e(%r8)
movl 0x48(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x38(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0x70(%rsp), %rbx
leaq 0x64(%rsp), %rdx
movl $0xf5b0, %esi           # imm = 0xF5B0
movl $0x36, %ecx
movq %rbx, %rdi
callq 0xd845
cmpq $0x0, 0x10(%rbx)
jne 0xb64e
cmpq $0x47784b21, 0x88(%rsp) # imm = 0x47784B21
jne 0xb66d
movabsq $0x780d1e1d5efcd005, %rax # imm = 0x780D1E1D5EFCD005
cmpq %rax, 0x90(%rsp)
jne 0xb68c
movabsq $-0x3a01abd7ec4928e2, %rax # imm = 0xC5FE542813B6D71E
cmpq %rax, 0x98(%rsp)
jne 0xb6ab
cmpq $0x2d, 0x70(%rsp)
jne 0xb6ca
movq 0x78(%rsp), %rdi
leaq 0xd374(%rip), %rsi      # 0x187a0
movl $0x2d, %edx
callq 0x30d0
testl %eax, %eax
jne 0xb6e9
cmpq $0x0, 0xa0(%rsp)
jne 0xb708
movl 0x88(%rsp), %eax
bswapl %eax
movl %eax, 0x50(%rsp)
movq 0x90(%rsp), %rax
bswapq %rax
movq %rax, 0x54(%rsp)
movq 0x98(%rsp), %rax
bswapq %rax
movq %rax, 0x5c(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0x28(%rsp)
movups 0x50(%rsp), %xmm0
movups %xmm0, 0x18(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x38(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0xb0(%rsp), %rbx
leaq 0x64(%rsp), %rdx
leaq 0x130(%rsp), %r8
movl $0x6fe8, %esi           # imm = 0x6FE8
movl $0x4f, %ecx
movq %rbx, %rdi
xorl %r9d, %r9d
callq 0xd30c
cmpq $0x0, 0x10(%rbx)
jne 0xb727
cmpq $0x0, 0xc8(%rsp)
jne 0xb746
cmpq $0x0, 0xd0(%rsp)
jne 0xb765
cmpq $0x1, 0xd8(%rsp)
jne 0xb784
cmpq $0x4f, 0xb0(%rsp)
jne 0xb7a3
movl $0x4f, %eax
movq 0xb8(%rsp), %rcx
movb (%rcx), %dl
cmpb 0x12f(%rsp,%rax), %dl
jne 0xb556
incq %rcx
decq %rax
jne 0xb51b
cmpq $0x10, 0xe0(%rsp)
jne 0xb7c2
xorl %eax, %eax
callq 0xcf29
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbaf8(%rip), %rdi      # 0x17055
leaq 0x8b38(%rip), %rsi      # 0x1409c
leaq 0xb8f8(%rip), %rcx      # 0x16e63
movl $0x722, %edx            # imm = 0x722
callq 0x3040
leaq 0x8aff(%rip), %rdi      # 0x1407b
leaq 0x8b19(%rip), %rsi      # 0x1409c
leaq 0xb8d9(%rip), %rcx      # 0x16e63
movl $0x6ef, %edx            # imm = 0x6EF
callq 0x3040
leaq 0x8b1c(%rip), %rdi      # 0x140b7
leaq 0x8afa(%rip), %rsi      # 0x1409c
leaq 0xb8ba(%rip), %rcx      # 0x16e63
movl $0x6f0, %edx            # imm = 0x6F0
callq 0x3040
leaq 0x8b27(%rip), %rdi      # 0x140e1
leaq 0x8adb(%rip), %rsi      # 0x1409c
leaq 0xb89b(%rip), %rcx      # 0x16e63
movl $0x6f1, %edx            # imm = 0x6F1
callq 0x3040
leaq 0x8b3a(%rip), %rdi      # 0x14113
leaq 0x8abc(%rip), %rsi      # 0x1409c
leaq 0xb87c(%rip), %rcx      # 0x16e63
movl $0x6f2, %edx            # imm = 0x6F2
callq 0x3040
leaq 0xb884(%rip), %rdi      # 0x16e7c
leaq 0x8a9d(%rip), %rsi      # 0x1409c
leaq 0xb85d(%rip), %rcx      # 0x16e63
movl $0x6f3, %edx            # imm = 0x6F3
callq 0x3040
leaq 0xb894(%rip), %rdi      # 0x16eab
leaq 0x8a7e(%rip), %rsi      # 0x1409c
leaq 0xb83e(%rip), %rcx      # 0x16e63
movl $0x6f4, %edx            # imm = 0x6F4
callq 0x3040
leaq 0x8b2b(%rip), %rdi      # 0x14161
leaq 0x8a5f(%rip), %rsi      # 0x1409c
leaq 0xb81f(%rip), %rcx      # 0x16e63
movl $0x6f5, %edx            # imm = 0x6F5
callq 0x3040
leaq 0x948f(%rip), %rdi      # 0x14ae4
leaq 0x8a40(%rip), %rsi      # 0x1409c
leaq 0xb800(%rip), %rcx      # 0x16e63
movl $0x70e, %edx            # imm = 0x70E
callq 0x3040
leaq 0x949d(%rip), %rdi      # 0x14b11
leaq 0x8a21(%rip), %rsi      # 0x1409c
leaq 0xb7e1(%rip), %rcx      # 0x16e63
movl $0x70f, %edx            # imm = 0x70F
callq 0x3040
leaq 0x94b4(%rip), %rdi      # 0x14b47
leaq 0x8a02(%rip), %rsi      # 0x1409c
leaq 0xb7c2(%rip), %rcx      # 0x16e63
movl $0x710, %edx            # imm = 0x710
callq 0x3040
leaq 0x94d3(%rip), %rdi      # 0x14b85
leaq 0x89e3(%rip), %rsi      # 0x1409c
leaq 0xb7a3(%rip), %rcx      # 0x16e63
movl $0x711, %edx            # imm = 0x711
callq 0x3040
leaq 0xb825(%rip), %rdi      # 0x16ef6
leaq 0x89c4(%rip), %rsi      # 0x1409c
leaq 0xb784(%rip), %rcx      # 0x16e63
movl $0x712, %edx            # imm = 0x712
callq 0x3040
leaq 0xb843(%rip), %rdi      # 0x16f33
leaq 0x89a5(%rip), %rsi      # 0x1409c
leaq 0xb765(%rip), %rcx      # 0x16e63
movl $0x713, %edx            # imm = 0x713
callq 0x3040
leaq 0x94b4(%rip), %rdi      # 0x14bc3
leaq 0x8986(%rip), %rsi      # 0x1409c
leaq 0xb746(%rip), %rcx      # 0x16e63
movl $0x714, %edx            # imm = 0x714
callq 0x3040
leaq 0xb860(%rip), %rdi      # 0x16f8e
leaq 0x8967(%rip), %rsi      # 0x1409c
leaq 0xb727(%rip), %rcx      # 0x16e63
movl $0x71c, %edx            # imm = 0x71C
callq 0x3040
leaq 0xb868(%rip), %rdi      # 0x16fb5
leaq 0x8948(%rip), %rsi      # 0x1409c
leaq 0xb708(%rip), %rcx      # 0x16e63
movl $0x71d, %edx            # imm = 0x71D
callq 0x3040
leaq 0xb870(%rip), %rdi      # 0x16fdc
leaq 0x8929(%rip), %rsi      # 0x1409c
leaq 0xb6e9(%rip), %rcx      # 0x16e63
movl $0x71e, %edx            # imm = 0x71E
callq 0x3040
leaq 0xb878(%rip), %rdi      # 0x17003
leaq 0x890a(%rip), %rsi      # 0x1409c
leaq 0xb6ca(%rip), %rcx      # 0x16e63
movl $0x71f, %edx            # imm = 0x71F
callq 0x3040
leaq 0xb880(%rip), %rdi      # 0x1702a
leaq 0x88eb(%rip), %rsi      # 0x1409c
leaq 0xb6ab(%rip), %rcx      # 0x16e63
movl $0x720, %edx            # imm = 0x720
callq 0x3040
leaq 0xb8d4(%rip), %rdi      # 0x1709d
leaq 0x88cc(%rip), %rsi      # 0x1409c
leaq 0xb68c(%rip), %rcx      # 0x16e63
movl $0x724, %edx            # imm = 0x724
callq 0x3040