unsigned short DSP_Division(unsigned int numer, unsigned int denom) {
  unsigned short i;
  denom <<= 15;
  for (i = 16; i > 0; i--) {
    if (numer > denom) {
      numer -= denom;
      numer <<= 1;
      numer++;
    } else
      numer <<= 1;
  }
  return (unsigned short)numer;
}


x86 assembly (clang, -O0):
<DSP_Division>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    -0x8(%rbp),%eax
shl    $0xf,%eax
mov    %eax,-0x8(%rbp)
movw   $0x10,-0xa(%rbp)
movzwl -0xa(%rbp),%eax
cmp    $0x0,%eax
jle    1173 <DSP_Division+0x73>
mov    -0x4(%rbp),%eax
cmp    -0x8(%rbp),%eax
jbe    1154 <DSP_Division+0x54>
mov    -0x8(%rbp),%ecx
mov    -0x4(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    115d <DSP_Division+0x5d>
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    1162 <DSP_Division+0x62>
mov    -0xa(%rbp),%ax
add    $0xffff,%ax
mov    %ax,-0xa(%rbp)
jmp    1119 <DSP_Division+0x19>
mov    -0x4(%rbp),%eax
movzwl %ax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<DSP_Division>:
shl    $0xf,%esi
lea    (%rdi,%rdi,1),%eax
sub    %esi,%edi
lea    0x1(%rdi,%rdi,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%eax
sub    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%ecx
cmovbe %eax,%ecx
lea    (%rcx,%rcx,1),%edx
cmp    %esi,%ecx
lea    0x1(%rcx,%rcx,1),%eax
cmovbe %edx,%eax
ret

LLVM IR (-O0):
define zeroext i16 @DSP_Division(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i16
store i32 %0, i32* %3
store i32 %1, i32* %4
%6 = load i32, i32* %4
%7 = shl i32 %6, 15
store i32 %7, i32* %4
store i16 16, i16* %5
br label %8
8: ; preds = %28, %2
%9 = load i16, i16* %5
%10 = zext i16 %9 to i32
%11 = icmp sgt i32 %10, 0
br i1 %11, label %12, label %31
12: ; preds = %8
%13 = load i32, i32* %3
%14 = load i32, i32* %4
%15 = icmp ugt i32 %13, %14
br i1 %15, label %16, label %24
16: ; preds = %12
%17 = load i32, i32* %4
%18 = load i32, i32* %3
%19 = sub i32 %18, %17
store i32 %19, i32* %3
%20 = load i32, i32* %3
%21 = shl i32 %20, 1
store i32 %21, i32* %3
%22 = load i32, i32* %3
%23 = add i32 %22, 1
store i32 %23, i32* %3
br label %27
24: ; preds = %12
%25 = load i32, i32* %3
%26 = shl i32 %25, 1
store i32 %26, i32* %3
br label %27
27: ; preds = %24, %16
br label %28
28: ; preds = %27
%29 = load i16, i16* %5
%30 = add i16 %29, -1
store i16 %30, i16* %5
br label %8
31: ; preds = %8
%32 = load i32, i32* %3
%33 = trunc i32 %32 to i16
ret i16 %33
}

LLVM IR (-O2):
define zeroext i16 @DSP_Division(i32 %0, i32 %1) {
%3 = shl i32 %1, 15
%4 = icmp ult i32 %3, %0
%5 = sub i32 %0, %3
%6 = shl i32 %5, 1
%7 = or i32 %6, 1
%8 = shl i32 %0, 1
%9 = select i1 %4, i32 %7, i32 %8
%10 = icmp ugt i32 %9, %3
%11 = sub i32 %9, %3
%12 = shl i32 %11, 1
%13 = or i32 %12, 1
%14 = shl i32 %9, 1
%15 = select i1 %10, i32 %13, i32 %14
%16 = icmp ugt i32 %15, %3
%17 = sub i32 %15, %3
%18 = shl i32 %17, 1
%19 = or i32 %18, 1
%20 = shl i32 %15, 1
%21 = select i1 %16, i32 %19, i32 %20
%22 = icmp ugt i32 %21, %3
%23 = sub i32 %21, %3
%24 = shl i32 %23, 1
%25 = or i32 %24, 1
%26 = shl i32 %21, 1
%27 = select i1 %22, i32 %25, i32 %26
%28 = icmp ugt i32 %27, %3
%29 = sub i32 %27, %3
%30 = shl i32 %29, 1
%31 = or i32 %30, 1
%32 = shl i32 %27, 1
%33 = select i1 %28, i32 %31, i32 %32
%34 = icmp ugt i32 %33, %3
%35 = sub i32 %33, %3
%36 = shl i32 %35, 1
%37 = or i32 %36, 1
%38 = shl i32 %33, 1
%39 = select i1 %34, i32 %37, i32 %38
%40 = icmp ugt i32 %39, %3
%41 = sub i32 %39, %3
%42 = shl i32 %41, 1
%43 = or i32 %42, 1
%44 = shl i32 %39, 1
%45 = select i1 %40, i32 %43, i32 %44
%46 = icmp ugt i32 %45, %3
%47 = sub i32 %45, %3
%48 = shl i32 %47, 1
%49 = or i32 %48, 1
%50 = shl i32 %45, 1
%51 = select i1 %46, i32 %49, i32 %50
%52 = icmp ugt i32 %51, %3
%53 = sub i32 %51, %3
%54 = shl i32 %53, 1
%55 = or i32 %54, 1
%56 = shl i32 %51, 1
%57 = select i1 %52, i32 %55, i32 %56
%58 = icmp ugt i32 %57, %3
%59 = sub i32 %57, %3
%60 = shl i32 %59, 1
%61 = or i32 %60, 1
%62 = shl i32 %57, 1
%63 = select i1 %58, i32 %61, i32 %62
%64 = icmp ugt i32 %63, %3
%65 = sub i32 %63, %3
%66 = shl i32 %65, 1
%67 = or i32 %66, 1
%68 = shl i32 %63, 1
%69 = select i1 %64, i32 %67, i32 %68
%70 = icmp ugt i32 %69, %3
%71 = sub i32 %69, %3
%72 = shl i32 %71, 1
%73 = or i32 %72, 1
%74 = shl i32 %69, 1
%75 = select i1 %70, i32 %73, i32 %74
%76 = icmp ugt i32 %75, %3
%77 = sub i32 %75, %3
%78 = shl i32 %77, 1
%79 = or i32 %78, 1
%80 = shl i32 %75, 1
%81 = select i1 %76, i32 %79, i32 %80
%82 = icmp ugt i32 %81, %3
%83 = sub i32 %81, %3
%84 = shl i32 %83, 1
%85 = or i32 %84, 1
%86 = shl i32 %81, 1
%87 = select i1 %82, i32 %85, i32 %86
%88 = icmp ugt i32 %87, %3
%89 = sub i32 %87, %3
%90 = shl i32 %89, 1
%91 = or i32 %90, 1
%92 = shl i32 %87, 1
%93 = select i1 %88, i32 %91, i32 %92
%94 = icmp ugt i32 %93, %3
%95 = shl i32 %93, 1
%96 = or i32 %95, 1
%97 = shl i32 %93, 1
%98 = select i1 %94, i32 %96, i32 %97
%99 = trunc i32 %98 to i16
ret i16 %99
}