#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 */
unsigned long long __rthal_generic_ullmul(unsigned int, unsigned int const);
unsigned long long rthal_llmi(unsigned int, unsigned int const);
long long __rthal_generic_llmulshft(const long long op, const unsigned m,
                                    const unsigned s) {
  unsigned oph, opl, tlh, tll, thh, thl;
  unsigned long long th, tl;
  ({
    union {
      unsigned long long _ull;
      struct {
        unsigned _h;
        unsigned _l;
      } _s;
    } _u;
    _u._ull = (op);
    (oph) = _u._s._h;
    (opl) = _u._s._l;
  });
  tl = __rthal_generic_ullmul((opl), (m));
  ({
    union {
      unsigned long long _ull;
      struct {
        unsigned _h;
        unsigned _l;
      } _s;
    } _u;
    _u._ull = (tl);
    (tlh) = _u._s._h;
    (tll) = _u._s._l;
  });
  th = rthal_llmi(oph, m);
  th += tlh;
  ({
    union {
      unsigned long long _ull;
      struct {
        unsigned _h;
        unsigned _l;
      } _s;
    } _u;
    _u._ull = (th);
    (thh) = _u._s._h;
    (thl) = _u._s._l;
  });
  return ({
    unsigned _l = (tll);
    unsigned _m = (thl);
    unsigned _s = (s);
    _l >>= _s;
    _l |= (_m << (32 - _s));
    _m >>= _s;
    _m |= ((thh) << (32 - _s));
    ({
      union {
        unsigned long long _ull;
        struct {
          unsigned _h;
          unsigned _l;
        } _s;
      } _u;
      _u._s._h = (_m);
      _u._s._l = (_l);
      _u._ull;
    });
  });
}


x86 assembly (clang, -O0):
<__rthal_generic_llmulshft>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x3c(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    %eax,-0x44(%rbp)
mov    -0x18(%rbp),%edi
mov    -0xc(%rbp),%esi
call   1030 <__rthal_generic_ullmul@plt>
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x4c(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    %eax,-0x54(%rbp)
mov    -0x14(%rbp),%edi
mov    -0xc(%rbp),%esi
call   1040 <rthal_llmi@plt>
mov    %rax,-0x30(%rbp)
mov    -0x1c(%rbp),%eax
add    -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x60(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x5c(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    %eax,-0x64(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x68(%rbp)
mov    -0x28(%rbp),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x10(%rbp),%eax
mov    %eax,-0x70(%rbp)
mov    -0x70(%rbp),%ecx
mov    -0x68(%rbp),%eax
shr    %cl,%eax
mov    %eax,-0x68(%rbp)
mov    -0x6c(%rbp),%eax
mov    $0x20,%ecx
sub    -0x70(%rbp),%ecx
shl    %cl,%eax
or     -0x68(%rbp),%eax
mov    %eax,-0x68(%rbp)
mov    -0x70(%rbp),%ecx
mov    -0x6c(%rbp),%eax
shr    %cl,%eax
mov    %eax,-0x6c(%rbp)
mov    -0x24(%rbp),%eax
mov    $0x20,%ecx
sub    -0x70(%rbp),%ecx
shl    %cl,%eax
or     -0x6c(%rbp),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x6c(%rbp),%eax
mov    %eax,-0x80(%rbp)
mov    -0x68(%rbp),%eax
mov    %eax,-0x7c(%rbp)
mov    -0x80(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    -0x88(%rbp),%rax
mov    %rax,-0x78(%rbp)
mov    -0x78(%rbp),%rax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__rthal_generic_llmulshft>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %edx,%r14d
mov    %esi,%r15d
mov    %rdi,%r12
shr    $0x20,%rdi
call   1030 <__rthal_generic_ullmul@plt>
mov    %rax,%rbx
mov    %rax,%rbp
shr    $0x20,%rbp
mov    %r12d,%edi
mov    %r15d,%esi
call   1040 <rthal_llmi@plt>
mov    %ebx,%edx
add    %rax,%rdx
mov    %rdx,%rax
shr    $0x20,%rax
mov    %r14d,%ecx
shrd   %cl,%eax,%ebp
shrd   %cl,%edx,%eax
shl    $0x20,%rbp
or     %rbp,%rax
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%union.anon = type { i64 }
%union.anon.0 = type { i64 }
%union.anon.2 = type { i64 }
%union.anon.4 = type { i64 }
%struct.anon = type { i32, i32 }
%struct.anon.1 = type { i32, i32 }
%struct.anon.3 = type { i32, i32 }
%struct.anon.5 = type { i32, i32 }
define i64 @__rthal_generic_llmulshft(i64 %0, i32 %1, i32 %2) {
%4 = alloca i64
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i64
%14 = alloca i64
%15 = alloca %union.anon
%16 = alloca i32
%17 = alloca %union.anon.0
%18 = alloca i32
%19 = alloca %union.anon.2
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i64
%25 = alloca %union.anon.4
%26 = alloca i64
store i64 %0, i64* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%27 = load i64, i64* %4
%28 = bitcast %union.anon* %15 to i64*
store i64 %27, i64* %28
%29 = bitcast %union.anon* %15 to %struct.anon*
%30 = getelementptr inbounds %struct.anon, %struct.anon* %29, i32 0, i32 0
%31 = load i32, i32* %30
store i32 %31, i32* %7
%32 = bitcast %union.anon* %15 to %struct.anon*
%33 = getelementptr inbounds %struct.anon, %struct.anon* %32, i32 0, i32 1
%34 = load i32, i32* %33
store i32 %34, i32* %8
store i32 %34, i32* %16
%35 = load i32, i32* %16
%36 = load i32, i32* %8
%37 = load i32, i32* %5
%38 = call i64 @__rthal_generic_ullmul(i32 %36, i32 %37)
store i64 %38, i64* %14
%39 = load i64, i64* %14
%40 = bitcast %union.anon.0* %17 to i64*
store i64 %39, i64* %40
%41 = bitcast %union.anon.0* %17 to %struct.anon.1*
%42 = getelementptr inbounds %struct.anon.1, %struct.anon.1* %41, i32 0, i32 0
%43 = load i32, i32* %42
store i32 %43, i32* %9
%44 = bitcast %union.anon.0* %17 to %struct.anon.1*
%45 = getelementptr inbounds %struct.anon.1, %struct.anon.1* %44, i32 0, i32 1
%46 = load i32, i32* %45
store i32 %46, i32* %10
store i32 %46, i32* %18
%47 = load i32, i32* %18
%48 = load i32, i32* %7
%49 = load i32, i32* %5
%50 = call i64 @rthal_llmi(i32 %48, i32 %49)
store i64 %50, i64* %13
%51 = load i32, i32* %9
%52 = zext i32 %51 to i64
%53 = load i64, i64* %13
%54 = add i64 %53, %52
store i64 %54, i64* %13
%55 = load i64, i64* %13
%56 = bitcast %union.anon.2* %19 to i64*
store i64 %55, i64* %56
%57 = bitcast %union.anon.2* %19 to %struct.anon.3*
%58 = getelementptr inbounds %struct.anon.3, %struct.anon.3* %57, i32 0, i32 0
%59 = load i32, i32* %58
store i32 %59, i32* %11
%60 = bitcast %union.anon.2* %19 to %struct.anon.3*
%61 = getelementptr inbounds %struct.anon.3, %struct.anon.3* %60, i32 0, i32 1
%62 = load i32, i32* %61
store i32 %62, i32* %12
store i32 %62, i32* %20
%63 = load i32, i32* %20
%64 = load i32, i32* %10
store i32 %64, i32* %21
%65 = load i32, i32* %12
store i32 %65, i32* %22
%66 = load i32, i32* %6
store i32 %66, i32* %23
%67 = load i32, i32* %23
%68 = load i32, i32* %21
%69 = lshr i32 %68, %67
store i32 %69, i32* %21
%70 = load i32, i32* %22
%71 = load i32, i32* %23
%72 = sub i32 32, %71
%73 = shl i32 %70, %72
%74 = load i32, i32* %21
%75 = or i32 %74, %73
store i32 %75, i32* %21
%76 = load i32, i32* %23
%77 = load i32, i32* %22
%78 = lshr i32 %77, %76
store i32 %78, i32* %22
%79 = load i32, i32* %11
%80 = load i32, i32* %23
%81 = sub i32 32, %80
%82 = shl i32 %79, %81
%83 = load i32, i32* %22
%84 = or i32 %83, %82
store i32 %84, i32* %22
%85 = load i32, i32* %22
%86 = bitcast %union.anon.4* %25 to %struct.anon.5*
%87 = getelementptr inbounds %struct.anon.5, %struct.anon.5* %86, i32 0, i32 0
store i32 %85, i32* %87
%88 = load i32, i32* %21
%89 = bitcast %union.anon.4* %25 to %struct.anon.5*
%90 = getelementptr inbounds %struct.anon.5, %struct.anon.5* %89, i32 0, i32 1
store i32 %88, i32* %90
%91 = bitcast %union.anon.4* %25 to i64*
%92 = load i64, i64* %91
store i64 %92, i64* %26
%93 = load i64, i64* %26
store i64 %93, i64* %24
%94 = load i64, i64* %24
ret i64 %94
}

LLVM IR (-O2):
define i64 @__rthal_generic_llmulshft(i64 %0, i32 %1, i32 %2) {
%4 = trunc i64 %0 to i32
%5 = lshr i64 %0, 32
%6 = trunc i64 %5 to i32
%7 = tail call i64 @__rthal_generic_ullmul(i32 %6, i32 %1)
%8 = lshr i64 %7, 32
%9 = trunc i64 %8 to i32
%10 = tail call i64 @rthal_llmi(i32 %4, i32 %1)
%11 = and i64 %7, 4294967295
%12 = add i64 %10, %11
%13 = trunc i64 %12 to i32
%14 = lshr i64 %12, 32
%15 = trunc i64 %14 to i32
%16 = lshr i32 %9, %2
%17 = sub i32 32, %2
%18 = shl i32 %15, %17
%19 = or i32 %18, %16
%20 = lshr i32 %15, %2
%21 = shl i32 %13, %17
%22 = or i32 %20, %21
%23 = zext i32 %19 to i64
%24 = shl nuw i64 %23, 32
%25 = zext i32 %22 to i64
%26 = or i64 %24, %25
ret i64 %26
}