#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ sys_free_virtual_addr(int *, void *, int);
scalar_t__ sys_malloc_virtual_addr(int *, int, int);
int /*<<< orphan*/ usleep(int);
void TCC_VPU_HW_Reset(void) {
  int membase;
  unsigned int mask_SWRESET, mask_SOFTRESET;
  typedef struct _tVPU_SWRESET {
    unsigned int VPU_SWRESET[18];
  } tVPU_SWRESET;
  typedef struct _tVPU_SOFTRESET {
    unsigned int VPU_SOFTRESET[2];
  } tVPU_SOFTRESET;
  volatile tVPU_SWRESET *regAddr_SWRESET =
      (volatile tVPU_SWRESET *)sys_malloc_virtual_addr(&membase, 0xF0400000,
                                                       sizeof(tVPU_SWRESET));
  volatile tVPU_SOFTRESET *regAddr_SOFTRESET =
      (volatile tVPU_SOFTRESET *)sys_malloc_virtual_addr(
          &membase, 0xF0702000, sizeof(tVPU_SOFTRESET));
  mask_SWRESET = (1 << 6);
  mask_SOFTRESET = (1 << 2);
  (regAddr_SWRESET->VPU_SWRESET[17]) |= mask_SWRESET;
  (regAddr_SOFTRESET->VPU_SOFTRESET[1]) |= mask_SOFTRESET;
  usleep(1000);
  (regAddr_SWRESET->VPU_SWRESET[17]) &= (~mask_SWRESET);
  (regAddr_SOFTRESET->VPU_SOFTRESET[1]) &= (~mask_SOFTRESET);
  usleep(10 * 1000);
  sys_free_virtual_addr(&membase, (void *)regAddr_SWRESET,
                        sizeof(tVPU_SWRESET));
  sys_free_virtual_addr(&membase, (void *)regAddr_SOFTRESET,
                        sizeof(tVPU_SOFTRESET));
}


x86 assembly (clang, -O0):
<TCC_VPU_HW_Reset>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
lea    -0x4(%rbp),%rdi
mov    $0xf0400000,%esi
mov    $0x48,%edx
call   1030 <sys_malloc_virtual_addr@plt>
mov    %rax,-0x18(%rbp)
lea    -0x4(%rbp),%rdi
mov    $0xf0702000,%esi
mov    $0x8,%edx
call   1030 <sys_malloc_virtual_addr@plt>
mov    %rax,-0x20(%rbp)
movl   $0x40,-0x8(%rbp)
movl   $0x4,-0xc(%rbp)
mov    -0x8(%rbp),%edx
mov    -0x18(%rbp),%rax
mov    0x44(%rax),%ecx
or     %edx,%ecx
mov    %ecx,0x44(%rax)
mov    -0xc(%rbp),%edx
mov    -0x20(%rbp),%rax
mov    0x4(%rax),%ecx
or     %edx,%ecx
mov    %ecx,0x4(%rax)
mov    $0x3e8,%edi
call   1050 <usleep@plt>
mov    -0x8(%rbp),%edx
xor    $0xffffffff,%edx
mov    -0x18(%rbp),%rax
mov    0x44(%rax),%ecx
and    %edx,%ecx
mov    %ecx,0x44(%rax)
mov    -0xc(%rbp),%edx
xor    $0xffffffff,%edx
mov    -0x20(%rbp),%rax
mov    0x4(%rax),%ecx
and    %edx,%ecx
mov    %ecx,0x4(%rax)
mov    $0x2710,%edi
call   1050 <usleep@plt>
mov    -0x18(%rbp),%rsi
lea    -0x4(%rbp),%rdi
mov    $0x48,%edx
call   1040 <sys_free_virtual_addr@plt>
mov    -0x20(%rbp),%rsi
lea    -0x4(%rbp),%rdi
mov    $0x8,%edx
call   1040 <sys_free_virtual_addr@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<TCC_VPU_HW_Reset>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
lea    0xc(%rsp),%r14
mov    %r14,%rdi
mov    $0xf0400000,%esi
mov    $0x48,%edx
call   1030 <sys_malloc_virtual_addr@plt>
mov    %rax,%r15
mov    %r14,%rdi
mov    $0xf0702000,%esi
mov    $0x8,%edx
call   1030 <sys_malloc_virtual_addr@plt>
orl    $0x40,0x44(%r15)
mov    %rax,%rbx
orl    $0x4,0x4(%rax)
mov    $0x3e8,%edi
call   1050 <usleep@plt>
andl   $0xffffffbf,0x44(%r15)
andl   $0xfffffffb,0x4(%rbx)
mov    $0x2710,%edi
call   1050 <usleep@plt>
mov    %r14,%rdi
mov    %r15,%rsi
mov    $0x48,%edx
call   1040 <sys_free_virtual_addr@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x8,%edx
call   1040 <sys_free_virtual_addr@plt>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct._tVPU_SWRESET = type { [18 x i32] }
%struct._tVPU_SOFTRESET = type { [2 x i32] }
define void @TCC_VPU_HW_Reset() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca %struct._tVPU_SWRESET*
%5 = alloca %struct._tVPU_SOFTRESET*
%6 = call i64 @sys_malloc_virtual_addr(i32* %1, i32 -264241152, i32 72)
%7 = inttoptr i64 %6 to %struct._tVPU_SWRESET*
store %struct._tVPU_SWRESET* %7, %struct._tVPU_SWRESET** %4
%8 = call i64 @sys_malloc_virtual_addr(i32* %1, i32 -261087232, i32 8)
%9 = inttoptr i64 %8 to %struct._tVPU_SOFTRESET*
store %struct._tVPU_SOFTRESET* %9, %struct._tVPU_SOFTRESET** %5
store i32 64, i32* %2
store i32 4, i32* %3
%10 = load i32, i32* %2
%11 = load %struct._tVPU_SWRESET*, %struct._tVPU_SWRESET** %4
%12 = getelementptr inbounds %struct._tVPU_SWRESET, %struct._tVPU_SWRESET* %11, i32 0, i32 0
%13 = getelementptr inbounds [18 x i32], [18 x i32]* %12, i64 0, i64 17
%14 = load volatile i32, i32* %13
%15 = or i32 %14, %10
store volatile i32 %15, i32* %13
%16 = load i32, i32* %3
%17 = load %struct._tVPU_SOFTRESET*, %struct._tVPU_SOFTRESET** %5
%18 = getelementptr inbounds %struct._tVPU_SOFTRESET, %struct._tVPU_SOFTRESET* %17, i32 0, i32 0
%19 = getelementptr inbounds [2 x i32], [2 x i32]* %18, i64 0, i64 1
%20 = load volatile i32, i32* %19
%21 = or i32 %20, %16
store volatile i32 %21, i32* %19
%22 = call i32 @usleep(i32 1000)
%23 = load i32, i32* %2
%24 = xor i32 %23, -1
%25 = load %struct._tVPU_SWRESET*, %struct._tVPU_SWRESET** %4
%26 = getelementptr inbounds %struct._tVPU_SWRESET, %struct._tVPU_SWRESET* %25, i32 0, i32 0
%27 = getelementptr inbounds [18 x i32], [18 x i32]* %26, i64 0, i64 17
%28 = load volatile i32, i32* %27
%29 = and i32 %28, %24
store volatile i32 %29, i32* %27
%30 = load i32, i32* %3
%31 = xor i32 %30, -1
%32 = load %struct._tVPU_SOFTRESET*, %struct._tVPU_SOFTRESET** %5
%33 = getelementptr inbounds %struct._tVPU_SOFTRESET, %struct._tVPU_SOFTRESET* %32, i32 0, i32 0
%34 = getelementptr inbounds [2 x i32], [2 x i32]* %33, i64 0, i64 1
%35 = load volatile i32, i32* %34
%36 = and i32 %35, %31
store volatile i32 %36, i32* %34
%37 = call i32 @usleep(i32 10000)
%38 = load %struct._tVPU_SWRESET*, %struct._tVPU_SWRESET** %4
%39 = bitcast %struct._tVPU_SWRESET* %38 to i8*
%40 = call i32 @sys_free_virtual_addr(i32* %1, i8* %39, i32 72)
%41 = load %struct._tVPU_SOFTRESET*, %struct._tVPU_SOFTRESET** %5
%42 = bitcast %struct._tVPU_SOFTRESET* %41 to i8*
%43 = call i32 @sys_free_virtual_addr(i32* %1, i8* %42, i32 8)
ret void
}

LLVM IR (-O2):
%struct._tVPU_SWRESET = type { [18 x i32] }
%struct._tVPU_SOFTRESET = type { [2 x i32] }
define void @TCC_VPU_HW_Reset() {
%1 = alloca i32
%2 = bitcast i32* %1 to i8*
%3 = call i64 @sys_malloc_virtual_addr(i32* %1, i32 -264241152, i32 72)
%4 = inttoptr i64 %3 to %struct._tVPU_SWRESET*
%5 = call i64 @sys_malloc_virtual_addr(i32* %1, i32 -261087232, i32 8)
%6 = inttoptr i64 %5 to %struct._tVPU_SOFTRESET*
%7 = getelementptr inbounds %struct._tVPU_SWRESET, %struct._tVPU_SWRESET* %4, i64 0, i32 0, i64 17
%8 = load volatile i32, i32* %7
%9 = or i32 %8, 64
store volatile i32 %9, i32* %7
%10 = getelementptr inbounds %struct._tVPU_SOFTRESET, %struct._tVPU_SOFTRESET* %6, i64 0, i32 0, i64 1
%11 = load volatile i32, i32* %10
%12 = or i32 %11, 4
store volatile i32 %12, i32* %10
%13 = call i32 @usleep(i32 1000)
%14 = load volatile i32, i32* %7
%15 = and i32 %14, -65
store volatile i32 %15, i32* %7
%16 = load volatile i32, i32* %10
%17 = and i32 %16, -5
store volatile i32 %17, i32* %10
%18 = call i32 @usleep(i32 10000)
%19 = inttoptr i64 %3 to i8*
%20 = call i32 @sys_free_virtual_addr(i32* %1, i8* %19, i32 72)
%21 = inttoptr i64 %5 to i8*
%22 = call i32 @sys_free_virtual_addr(i32* %1, i8* %21, i32 8)
ret void
}