// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %rbx
subq $0x1c0, %rsp            # imm = 0x1C0
xorl %eax, %eax
callq 0xaa8d
leaq 0xc385(%rip), %rsi      # 0x15710
pushq $0x4f
popq %rbx
leaq 0x130(%rsp), %r14
movq %rbx, %rcx
movq %r14, %rdi
rep  movsb (%rsi), %es:(%rdi)
leaq 0x38(%rsp), %r15
movq %r15, %rdi
callq 0x332c
leaq 0x4c(%rsp), %rdx
andl $0x0, 0x8(%rdx)
andq $0x0, (%rdx)
movl 0x10(%r15), %eax
movl %eax, 0x10(%rsp)
movups (%r15), %xmm0
movups %xmm0, (%rsp)
leaq 0xd8(%rsp), %r15
movl $0x10ad0, %esi          # imm = 0x10AD0
movq %r15, %rdi
movq %rbx, %rcx
movq %r14, %r8
callq 0xb68f
cmpq $0x0, 0x10(%r15)
jne 0x965b
movl $0x80d9b122, %eax       # imm = 0x80D9B122
cmpq %rax, 0xf0(%rsp)
jne 0x967a
movabsq $-0x23c5e9023be06931, %rax # imm = 0xDC3A16FDC41F96CF
cmpq %rax, 0xf8(%rsp)
jne 0x9699
movabsq $0x10ffe7e38d227c3, %rax # imm = 0x10FFE7E38D227C3
cmpq %rax, 0x100(%rsp)
jne 0x96b8
cmpq $0x46, 0xd8(%rsp)
jne 0x96d7
movq 0xe0(%rsp), %rdi
leaq 0xc271(%rip), %rsi      # 0x156c0
pushq $0x46
popq %rdx
callq 0x30d0
testl %eax, %eax
jne 0x96f6
cmpq $0x0, 0x108(%rsp)
jne 0x9715
movaps 0xc33b(%rip), %xmm0     # 0x157b0
leaq 0x180(%rsp), %r8
movaps %xmm0, 0x20(%r8)
movaps 0xc317(%rip), %xmm0     # 0x157a0
movaps %xmm0, 0x10(%r8)
movaps 0xc2fb(%rip), %xmm0     # 0x15790
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 0x58(%rsp), %rbx
leaq 0x4c(%rsp), %rdx
pushq $0x36
popq %rcx
movl $0xf5b0, %esi           # imm = 0xF5B0
movq %rbx, %rdi
callq 0xb68f
cmpq $0x0, 0x10(%rbx)
jne 0x9734
cmpq $0x47784b21, 0x70(%rsp) # imm = 0x47784B21
jne 0x9753
movabsq $0x780d1e1d5efcd005, %rax # imm = 0x780D1E1D5EFCD005
cmpq %rax, 0x78(%rsp)
jne 0x9772
movabsq $-0x3a01abd7ec4928e2, %rax # imm = 0xC5FE542813B6D71E
cmpq %rax, 0x80(%rsp)
jne 0x9791
cmpq $0x2d, 0x58(%rsp)
jne 0x97b0
movq 0x60(%rsp), %rdi
leaq 0xc22f(%rip), %rsi      # 0x15760
pushq $0x2d
popq %rdx
callq 0x30d0
testl %eax, %eax
jne 0x97cf
cmpq $0x0, 0x88(%rsp)
jne 0x97ee
leaq 0x68(%rsp), %rsi
leaq 0x118(%rsp), %rbx
movq %rbx, %rdi
callq 0x5fbc
movl 0x10(%rbx), %eax
movl %eax, 0x28(%rsp)
movups (%rbx), %xmm0
movups %xmm0, 0x18(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x10(%rsp)
movups 0x38(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0x98(%rsp), %r14
leaq 0x4c(%rsp), %rdx
pushq $0x4f
popq %rbx
leaq 0x130(%rsp), %r8
movl $0x6fe8, %esi           # imm = 0x6FE8
movq %r14, %rdi
movq %rbx, %rcx
xorl %r9d, %r9d
callq 0xb135
cmpq $0x0, 0x10(%r14)
jne 0x980d
cmpq $0x0, 0xb0(%rsp)
jne 0x982c
cmpq $0x0, 0xb8(%rsp)
jne 0x984b
cmpq $0x1, 0xc0(%rsp)
jne 0x986a
cmpq $0x4f, 0x98(%rsp)
jne 0x9889
movq 0xa0(%rsp), %rax
movq %rbx, %rcx
subq $0x1, %rcx
jb 0x9638
movb (%rax), %dl
incq %rax
cmpb 0x12f(%rsp,%rbx), %dl
movq %rcx, %rbx
je 0x9602
leaq 0xa9e9(%rip), %rdi      # 0x14009
leaq 0x7a29(%rip), %rsi      # 0x11050
leaq 0xa7e9(%rip), %rcx      # 0x13e17
movl $0x722, %edx            # imm = 0x722
callq 0x3040
cmpq $0x10, 0xc8(%rsp)
jne 0x98a8
xorl %eax, %eax
callq 0xada8
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbx
popq %r14
popq %r15
retq
leaq 0x79cd(%rip), %rdi      # 0x1102f
leaq 0x79e7(%rip), %rsi      # 0x11050
leaq 0xa7a7(%rip), %rcx      # 0x13e17
movl $0x6ef, %edx            # imm = 0x6EF
callq 0x3040
leaq 0x79ea(%rip), %rdi      # 0x1106b
leaq 0x79c8(%rip), %rsi      # 0x11050
leaq 0xa788(%rip), %rcx      # 0x13e17
movl $0x6f0, %edx            # imm = 0x6F0
callq 0x3040
leaq 0x79f5(%rip), %rdi      # 0x11095
leaq 0x79a9(%rip), %rsi      # 0x11050
leaq 0xa769(%rip), %rcx      # 0x13e17
movl $0x6f1, %edx            # imm = 0x6F1
callq 0x3040
leaq 0x7a08(%rip), %rdi      # 0x110c7
leaq 0x798a(%rip), %rsi      # 0x11050
leaq 0xa74a(%rip), %rcx      # 0x13e17
movl $0x6f2, %edx            # imm = 0x6F2
callq 0x3040
leaq 0xa752(%rip), %rdi      # 0x13e30
leaq 0x796b(%rip), %rsi      # 0x11050
leaq 0xa72b(%rip), %rcx      # 0x13e17
movl $0x6f3, %edx            # imm = 0x6F3
callq 0x3040
leaq 0xa762(%rip), %rdi      # 0x13e5f
leaq 0x794c(%rip), %rsi      # 0x11050
leaq 0xa70c(%rip), %rcx      # 0x13e17
movl $0x6f4, %edx            # imm = 0x6F4
callq 0x3040
leaq 0x79f9(%rip), %rdi      # 0x11115
leaq 0x792d(%rip), %rsi      # 0x11050
leaq 0xa6ed(%rip), %rcx      # 0x13e17
movl $0x6f5, %edx            # imm = 0x6F5
callq 0x3040
leaq 0x835d(%rip), %rdi      # 0x11a98
leaq 0x790e(%rip), %rsi      # 0x11050
leaq 0xa6ce(%rip), %rcx      # 0x13e17
movl $0x70e, %edx            # imm = 0x70E
callq 0x3040
leaq 0x836b(%rip), %rdi      # 0x11ac5
leaq 0x78ef(%rip), %rsi      # 0x11050
leaq 0xa6af(%rip), %rcx      # 0x13e17
movl $0x70f, %edx            # imm = 0x70F
callq 0x3040
leaq 0x8382(%rip), %rdi      # 0x11afb
leaq 0x78d0(%rip), %rsi      # 0x11050
leaq 0xa690(%rip), %rcx      # 0x13e17
movl $0x710, %edx            # imm = 0x710
callq 0x3040
leaq 0x83a1(%rip), %rdi      # 0x11b39
leaq 0x78b1(%rip), %rsi      # 0x11050
leaq 0xa671(%rip), %rcx      # 0x13e17
movl $0x711, %edx            # imm = 0x711
callq 0x3040
leaq 0xa6f3(%rip), %rdi      # 0x13eaa
leaq 0x7892(%rip), %rsi      # 0x11050
leaq 0xa652(%rip), %rcx      # 0x13e17
movl $0x712, %edx            # imm = 0x712
callq 0x3040
leaq 0xa711(%rip), %rdi      # 0x13ee7
leaq 0x7873(%rip), %rsi      # 0x11050
leaq 0xa633(%rip), %rcx      # 0x13e17
movl $0x713, %edx            # imm = 0x713
callq 0x3040
leaq 0x8382(%rip), %rdi      # 0x11b77
leaq 0x7854(%rip), %rsi      # 0x11050
leaq 0xa614(%rip), %rcx      # 0x13e17
movl $0x714, %edx            # imm = 0x714
callq 0x3040
leaq 0xa72e(%rip), %rdi      # 0x13f42
leaq 0x7835(%rip), %rsi      # 0x11050
leaq 0xa5f5(%rip), %rcx      # 0x13e17
movl $0x71c, %edx            # imm = 0x71C
callq 0x3040
leaq 0xa736(%rip), %rdi      # 0x13f69
leaq 0x7816(%rip), %rsi      # 0x11050
leaq 0xa5d6(%rip), %rcx      # 0x13e17
movl $0x71d, %edx            # imm = 0x71D
callq 0x3040
leaq 0xa73e(%rip), %rdi      # 0x13f90
leaq 0x77f7(%rip), %rsi      # 0x11050
leaq 0xa5b7(%rip), %rcx      # 0x13e17
movl $0x71e, %edx            # imm = 0x71E
callq 0x3040
leaq 0xa746(%rip), %rdi      # 0x13fb7
leaq 0x77d8(%rip), %rsi      # 0x11050
leaq 0xa598(%rip), %rcx      # 0x13e17
movl $0x71f, %edx            # imm = 0x71F
callq 0x3040
leaq 0xa74e(%rip), %rdi      # 0x13fde
leaq 0x77b9(%rip), %rsi      # 0x11050
leaq 0xa579(%rip), %rcx      # 0x13e17
movl $0x720, %edx            # imm = 0x720
callq 0x3040
leaq 0xa7a2(%rip), %rdi      # 0x14051
leaq 0x779a(%rip), %rsi      # 0x11050
leaq 0xa55a(%rip), %rcx      # 0x13e17
movl $0x724, %edx            # imm = 0x724
callq 0x3040