void half(void *pval, char type) {
  switch (type) {
  case 'i': {
    *((int *)pval) /= 2;
    break;
  }
  case 'l': {
    *((long *)pval) /= 2;
    break;
  }
  case 'f': {
    *((float *)pval) /= 2;
    break;
  }
  case 'd': {
    *((double *)pval) /= 2;
    break;
  }
  }
}


x86 assembly (clang, -O0):
<half>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
movsbl -0x9(%rbp),%eax
add    $0xffffff9c,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x8,%eax
ja     11b0 <half+0xb0>
mov    -0x18(%rbp),%rax
lea    0xedd(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    (%rax),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
jmp    11b0 <half+0xb0>
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    (%rax),%rax
mov    $0x2,%ecx
cqto
idiv   %rcx
mov    %rax,%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
jmp    11b0 <half+0xb0>
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
movss  0xe7d(%rip),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,(%rax)
jmp    11b0 <half+0xb0>
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xe58(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<half>:
add    $0xffffff9c,%esi
cmp    $0x8,%esi
ja     1128 <half+0x28>
lea    0xefd(%rip),%rax
movslq (%rax,%rsi,4),%rcx
add    %rax,%rcx
jmp    *%rcx
movsd  (%rdi),%xmm0
mulsd  0xedc(%rip),%xmm0
movsd  %xmm0,(%rdi)
ret
movss  (%rdi),%xmm0
mulss  0xed3(%rip),%xmm0
movss  %xmm0,(%rdi)
ret
mov    (%rdi),%eax
mov    %eax,%ecx
shr    $0x1f,%ecx
add    %eax,%ecx
sar    %ecx
mov    %ecx,(%rdi)
ret
mov    (%rdi),%rax
mov    %rax,%rcx
shr    $0x3f,%rcx
add    %rax,%rcx
sar    %rcx
mov    %rcx,(%rdi)
ret

LLVM IR (-O0):
define void @half(i8* %0, i8 signext %1) {
%3 = alloca i8*
%4 = alloca i8
store i8* %0, i8** %3
store i8 %1, i8* %4
%5 = load i8, i8* %4
%6 = sext i8 %5 to i32
switch i32 %6, label %27 [
i32 105, label %7
i32 108, label %12
i32 102, label %17
i32 100, label %22
]
7: ; preds = %2
%8 = load i8*, i8** %3
%9 = bitcast i8* %8 to i32*
%10 = load i32, i32* %9
%11 = sdiv i32 %10, 2
store i32 %11, i32* %9
br label %27
12: ; preds = %2
%13 = load i8*, i8** %3
%14 = bitcast i8* %13 to i64*
%15 = load i64, i64* %14
%16 = sdiv i64 %15, 2
store i64 %16, i64* %14
br label %27
17: ; preds = %2
%18 = load i8*, i8** %3
%19 = bitcast i8* %18 to float*
%20 = load float, float* %19
%21 = fdiv float %20, 2.000000e+00
store float %21, float* %19
br label %27
22: ; preds = %2
%23 = load i8*, i8** %3
%24 = bitcast i8* %23 to double*
%25 = load double, double* %24
%26 = fdiv double %25, 2.000000e+00
store double %26, double* %24
br label %27
27: ; preds = %2, %22, %17, %12, %7
ret void
}

LLVM IR (-O2):
define void @half(i8* nocapture %0, i8 signext %1) {
%3 = sext i8 %1 to i32
switch i32 %3, label %20 [
i32 105, label %4
i32 108, label %8
i32 102, label %12
i32 100, label %16
]
4: ; preds = %2
%5 = bitcast i8* %0 to i32*
%6 = load i32, i32* %5
%7 = sdiv i32 %6, 2
store i32 %7, i32* %5
br label %20
8: ; preds = %2
%9 = bitcast i8* %0 to i64*
%10 = load i64, i64* %9
%11 = sdiv i64 %10, 2
store i64 %11, i64* %9
br label %20
12: ; preds = %2
%13 = bitcast i8* %0 to float*
%14 = load float, float* %13
%15 = fmul float %14, 5.000000e-01
store float %15, float* %13
br label %20
16: ; preds = %2
%17 = bitcast i8* %0 to double*
%18 = load double, double* %17
%19 = fmul double %18, 5.000000e-01
store double %19, double* %17
br label %20
20: ; preds = %2, %16, %12, %8, %4
ret void
}