long fref(data, maxl, rcp)
char *data;
long maxl;
struct res *rcp;
{
  char *skipsp(), *getline(), *lp;
  char *outp(), *outs(), *outl(), *outc();
  char *datap = data;
  int iconid;
  if ((lp = skipsp(getline())) == 0)
    fatal("no type specified");
  checktype(lp);
  datap = outc(datap, lp[0], &maxl);
  datap = outc(datap, lp[1], &maxl);
  datap = outc(datap, lp[2], &maxl);
  datap = outc(datap, lp[3], &maxl);
  if ((lp = getline()) == 0 || sscanf(lp, "%d", &iconid) != 1)
    fatal("bad icon id");
  datap = outs(datap, iconid, &maxl);
  datap = outc(datap, (char)0, &maxl);
  return (datap - data);
}


x86 assembly (clang, -O0):
<fref>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    $0x0,%al
call   1060 <getline@plt>
mov    %rax,%rdi
mov    $0x0,%al
call   1070 <skipsp@plt>
mov    %rax,-0x20(%rbp)
cmp    $0x0,%rax
jne    11b9 <fref+0x49>
lea    0xe4e(%rip),%rdi
mov    $0x0,%al
call   1090 <fatal@plt>
mov    -0x20(%rbp),%rdi
mov    $0x0,%al
call   1040 <checktype@plt>
mov    -0x28(%rbp),%rdi
mov    -0x20(%rbp),%rax
movsbl (%rax),%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1050 <outc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x20(%rbp),%rax
movsbl 0x1(%rax),%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1050 <outc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x20(%rbp),%rax
movsbl 0x2(%rax),%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1050 <outc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x20(%rbp),%rax
movsbl 0x3(%rax),%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1050 <outc@plt>
mov    %rax,-0x28(%rbp)
mov    $0x0,%al
call   1060 <getline@plt>
mov    %rax,-0x20(%rbp)
cmp    $0x0,%rax
je     1263 <fref+0xf3>
mov    -0x20(%rbp),%rdi
lea    0xdc3(%rip),%rsi
lea    -0x2c(%rbp),%rdx
mov    $0x0,%al
call   1030 <sscanf@plt>
cmp    $0x1,%eax
je     1271 <fref+0x101>
lea    0xdab(%rip),%rdi
mov    $0x0,%al
call   1090 <fatal@plt>
mov    -0x28(%rbp),%rdi
mov    -0x2c(%rbp),%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1080 <outs@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
xor    %esi,%esi
lea    -0x10(%rbp),%rdx
mov    $0x0,%al
call   1050 <outc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fref>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%r14
mov    %rsi,0x8(%rsp)
xor    %eax,%eax
call   1060 <getline@plt>
mov    %rax,%rdi
xor    %eax,%eax
call   1070 <skipsp@plt>
mov    %rax,%rbx
test   %rax,%rax
jne    11a8 <fref+0x38>
lea    0xe5f(%rip),%rdi
xor    %eax,%eax
call   1090 <fatal@plt>
mov    %rbx,%rdi
xor    %eax,%eax
call   1040 <checktype@plt>
movsbl (%rbx),%esi
lea    0x8(%rsp),%r15
mov    %r14,%rdi
mov    %r15,%rdx
xor    %eax,%eax
call   1050 <outc@plt>
movsbl 0x1(%rbx),%esi
mov    %rax,%rdi
mov    %r15,%rdx
xor    %eax,%eax
call   1050 <outc@plt>
movsbl 0x2(%rbx),%esi
mov    %rax,%rdi
mov    %r15,%rdx
xor    %eax,%eax
call   1050 <outc@plt>
movsbl 0x3(%rbx),%esi
mov    %rax,%rdi
mov    %r15,%rdx
xor    %eax,%eax
call   1050 <outc@plt>
mov    %rax,%r15
xor    %eax,%eax
call   1060 <getline@plt>
test   %rax,%rax
je     1224 <fref+0xb4>
lea    0xe02(%rip),%rsi
lea    0x4(%rsp),%rdx
mov    %rax,%rdi
xor    %eax,%eax
call   1030 <sscanf@plt>
cmp    $0x1,%eax
je     1232 <fref+0xc2>
lea    0xdea(%rip),%rdi
xor    %eax,%eax
call   1090 <fatal@plt>
mov    0x4(%rsp),%esi
lea    0x8(%rsp),%rbx
mov    %r15,%rdi
mov    %rbx,%rdx
xor    %eax,%eax
call   1080 <outs@plt>
mov    %rax,%rdi
xor    %esi,%esi
mov    %rbx,%rdx
xor    %eax,%eax
call   1050 <outc@plt>
sub    %r14,%rax
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.res = type opaque
@.str = [18 x i8] c"no type specified\00"
@.str.1 = [3 x i8] c"%d\00"
@.str.2 = [12 x i8] c"bad icon id\00"
define i64 @fref(i8* %0, i64 %1, %struct.res* %2) {
%4 = alloca i8*
%5 = alloca i64
%6 = alloca %struct.res*
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i32
store i8* %0, i8** %4
store i64 %1, i64* %5
store %struct.res* %2, %struct.res** %6
%10 = load i8*, i8** %4
store i8* %10, i8** %8
%11 = call i8* (...) @getline()
%12 = call i8* (i8*, ...) bitcast (i8* (...)* @skipsp to i8* (i8*, ...)*)(i8* %11)
store i8* %12, i8** %7
%13 = icmp eq i8* %12, null
br i1 %13, label %14, label %16
14: ; preds = %3
%15 = call i32 (i8*, ...) bitcast (i32 (...)* @fatal to i32 (i8*, ...)*)(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0))
br label %16
16: ; preds = %14, %3
%17 = load i8*, i8** %7
%18 = call i32 (i8*, ...) bitcast (i32 (...)* @checktype to i32 (i8*, ...)*)(i8* %17)
%19 = load i8*, i8** %8
%20 = load i8*, i8** %7
%21 = getelementptr inbounds i8, i8* %20, i64 0
%22 = load i8, i8* %21
%23 = sext i8 %22 to i32
%24 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %19, i32 %23, i64* %5)
store i8* %24, i8** %8
%25 = load i8*, i8** %8
%26 = load i8*, i8** %7
%27 = getelementptr inbounds i8, i8* %26, i64 1
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %25, i32 %29, i64* %5)
store i8* %30, i8** %8
%31 = load i8*, i8** %8
%32 = load i8*, i8** %7
%33 = getelementptr inbounds i8, i8* %32, i64 2
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %31, i32 %35, i64* %5)
store i8* %36, i8** %8
%37 = load i8*, i8** %8
%38 = load i8*, i8** %7
%39 = getelementptr inbounds i8, i8* %38, i64 3
%40 = load i8, i8* %39
%41 = sext i8 %40 to i32
%42 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %37, i32 %41, i64* %5)
store i8* %42, i8** %8
%43 = call i8* (...) @getline()
store i8* %43, i8** %7
%44 = icmp eq i8* %43, null
br i1 %44, label %49, label %45
45: ; preds = %16
%46 = load i8*, i8** %7
%47 = call i32 (i8*, i8*, ...) @sscanf(i8* %46, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i32* %9)
%48 = icmp ne i32 %47, 1
br i1 %48, label %49, label %51
49: ; preds = %45, %16
%50 = call i32 (i8*, ...) bitcast (i32 (...)* @fatal to i32 (i8*, ...)*)(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.2, i64 0, i64 0))
br label %51
51: ; preds = %49, %45
%52 = load i8*, i8** %8
%53 = load i32, i32* %9
%54 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outs to i8* (i8*, i32, i64*, ...)*)(i8* %52, i32 %53, i64* %5)
store i8* %54, i8** %8
%55 = load i8*, i8** %8
%56 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %55, i32 0, i64* %5)
store i8* %56, i8** %8
%57 = load i8*, i8** %8
%58 = load i8*, i8** %4
%59 = ptrtoint i8* %57 to i64
%60 = ptrtoint i8* %58 to i64
%61 = sub i64 %59, %60
ret i64 %61
}

LLVM IR (-O2):
%struct.res = type opaque
@.str = [18 x i8] c"no type specified\00"
@.str.1 = [3 x i8] c"%d\00"
@.str.2 = [12 x i8] c"bad icon id\00"
define i64 @fref(i8* %0, i64 %1, %struct.res* nocapture readnone %2) {
%4 = alloca i64
%5 = alloca i32
store i64 %1, i64* %4
%6 = bitcast i32* %5 to i8*
%7 = tail call i8* (...) @getline()
%8 = tail call i8* (i8*, ...) bitcast (i8* (...)* @skipsp to i8* (i8*, ...)*)(i8* %7)
%9 = icmp eq i8* %8, null
br i1 %9, label %10, label %12
10: ; preds = %3
%11 = tail call i32 (i8*, ...) bitcast (i32 (...)* @fatal to i32 (i8*, ...)*)(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0))
br label %12
12: ; preds = %10, %3
%13 = tail call i32 (i8*, ...) bitcast (i32 (...)* @checktype to i32 (i8*, ...)*)(i8* %8)
%14 = load i8, i8* %8
%15 = sext i8 %14 to i32
%16 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %0, i32 %15, i64* %4)
%17 = getelementptr inbounds i8, i8* %8, i64 1
%18 = load i8, i8* %17
%19 = sext i8 %18 to i32
%20 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %16, i32 %19, i64* %4)
%21 = getelementptr inbounds i8, i8* %8, i64 2
%22 = load i8, i8* %21
%23 = sext i8 %22 to i32
%24 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %20, i32 %23, i64* %4)
%25 = getelementptr inbounds i8, i8* %8, i64 3
%26 = load i8, i8* %25
%27 = sext i8 %26 to i32
%28 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %24, i32 %27, i64* %4)
%29 = call i8* (...) @getline()
%30 = icmp eq i8* %29, null
br i1 %30, label %34, label %31
31: ; preds = %12
%32 = call i32 (i8*, i8*, ...) @sscanf(i8* %29, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i32* %5)
%33 = icmp eq i32 %32, 1
br i1 %33, label %36, label %34
34: ; preds = %31, %12
%35 = call i32 (i8*, ...) bitcast (i32 (...)* @fatal to i32 (i8*, ...)*)(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.2, i64 0, i64 0))
br label %36
36: ; preds = %34, %31
%37 = load i32, i32* %5
%38 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outs to i8* (i8*, i32, i64*, ...)*)(i8* %28, i32 %37, i64* %4)
%39 = call i8* (i8*, i32, i64*, ...) bitcast (i8* (...)* @outc to i8* (i8*, i32, i64*, ...)*)(i8* %38, i32 0, i64* %4)
%40 = ptrtoint i8* %39 to i64
%41 = ptrtoint i8* %0 to i64
%42 = sub i64 %40, %41
ret i64 %42
}