void swo_init(unsigned int cpu_speed, unsigned int swo_speed,
              unsigned int port_mask) {
  (*((volatile unsigned *)0xE000EDFC)) |= (1 << 24);
  (*((volatile unsigned *)0xE0000FB0)) = 0xC5ACCE55;
  (*((volatile unsigned *)0xE00400F0)) = 0x00000002;
  unsigned int prescaler = (cpu_speed / swo_speed) - 1;
  (*((volatile unsigned *)0xE0040010)) = prescaler;
  (*((volatile unsigned *)0xE0000E40)) = 0x00000000;
  (*((volatile unsigned *)0xE0001000)) |= 0x400003FE;
  (*((volatile unsigned *)0xE0000E80)) = 0x0001001F;
  (*((volatile unsigned *)0xE0040304)) = 0x00000100;
  (*((volatile unsigned *)0xE0000E00)) = port_mask;
}


x86 assembly (clang, -O0):
<swo_init>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    $0xe000edfc,%eax
mov    (%rax),%ecx
or     $0x1000000,%ecx
mov    $0xe000edfc,%eax
mov    %ecx,(%rax)
mov    $0xe0000fb0,%eax
movl   $0xc5acce55,(%rax)
mov    $0xe00400f0,%eax
movl   $0x2,(%rax)
mov    -0x4(%rbp),%eax
xor    %edx,%edx
divl   -0x8(%rbp)
sub    $0x1,%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%ecx
mov    $0xe0040010,%eax
mov    %ecx,(%rax)
mov    $0xe0000e40,%eax
movl   $0x0,(%rax)
mov    $0xe0001000,%eax
mov    (%rax),%ecx
or     $0x400003fe,%ecx
mov    $0xe0001000,%eax
mov    %ecx,(%rax)
mov    $0xe0000e80,%eax
movl   $0x1001f,(%rax)
mov    $0xe0040304,%eax
movl   $0x100,(%rax)
mov    -0xc(%rbp),%ecx
mov    $0xe0000e00,%eax
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<swo_init>:
mov    $0xe0001000,%ecx
orl    $0x1000000,0xddfc(%rcx)
mov    %edx,%r8d
mov    %edi,%eax
movl   $0xc5acce55,-0x50(%rcx)
movl   $0x2,0x3f0f0(%rcx)
xor    %edx,%edx
div    %esi
add    $0xffffffff,%eax
mov    %eax,0x3f010(%rcx)
movl   $0x0,-0x1c0(%rcx)
orl    $0x400003fe,(%rcx)
movl   $0x1001f,-0x180(%rcx)
movl   $0x100,0x3f304(%rcx)
mov    %r8d,-0x200(%rcx)
ret

LLVM IR (-O0):
define void @swo_init(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%8 = load volatile i32, i32* inttoptr (i64 3758157308 to i32*)
%9 = or i32 %8, 16777216
store volatile i32 %9, i32* inttoptr (i64 3758157308 to i32*)
store volatile i32 -978530731, i32* inttoptr (i64 3758100400 to i32*)
store volatile i32 2, i32* inttoptr (i64 3758358768 to i32*)
%10 = load i32, i32* %4
%11 = load i32, i32* %5
%12 = udiv i32 %10, %11
%13 = sub i32 %12, 1
store i32 %13, i32* %7
%14 = load i32, i32* %7
store volatile i32 %14, i32* inttoptr (i64 3758358544 to i32*)
store volatile i32 0, i32* inttoptr (i64 3758100032 to i32*)
%15 = load volatile i32, i32* inttoptr (i64 3758100480 to i32*)
%16 = or i32 %15, 1073742846
store volatile i32 %16, i32* inttoptr (i64 3758100480 to i32*)
store volatile i32 65567, i32* inttoptr (i64 3758100096 to i32*)
store volatile i32 256, i32* inttoptr (i64 3758359300 to i32*)
%17 = load i32, i32* %6
store volatile i32 %17, i32* inttoptr (i64 3758099968 to i32*)
ret void
}

LLVM IR (-O2):
define void @swo_init(i32 %0, i32 %1, i32 %2) {
%4 = load volatile i32, i32* inttoptr (i64 3758157308 to i32*)
%5 = or i32 %4, 16777216
store volatile i32 %5, i32* inttoptr (i64 3758157308 to i32*)
store volatile i32 -978530731, i32* inttoptr (i64 3758100400 to i32*)
store volatile i32 2, i32* inttoptr (i64 3758358768 to i32*)
%6 = udiv i32 %0, %1
%7 = add i32 %6, -1
store volatile i32 %7, i32* inttoptr (i64 3758358544 to i32*)
store volatile i32 0, i32* inttoptr (i64 3758100032 to i32*)
%8 = load volatile i32, i32* inttoptr (i64 3758100480 to i32*)
%9 = or i32 %8, 1073742846
store volatile i32 %9, i32* inttoptr (i64 3758100480 to i32*)
store volatile i32 65567, i32* inttoptr (i64 3758100096 to i32*)
store volatile i32 256, i32* inttoptr (i64 3758359300 to i32*)
store volatile i32 %2, i32* inttoptr (i64 3758099968 to i32*)
ret void
}