#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 */
typedef int uint8_t;

/* Variables and functions */
int /*<<< orphan*/ add_CRC(int *, int, int);
int rt_modbus_force_multiple_outputs(int *, int);
int rt_modbus_force_single_output(int *, int);
int rt_modbus_loopback(int *, int);
int rt_modbus_preset_multiple_registers(int *, int);
int rt_modbus_preset_single_register(int *, int);
int rt_modbus_read_analog_inputs(int *, int);
int rt_modbus_read_exception_status(int *, int);
int rt_modbus_read_input_table(int *, int);
int rt_modbus_read_output_table(int *, int);
int rt_modbus_read_registers(int *, int);
int rt_modbus_read_scratch_pad(int *, int);
int rt_modbus_report_device_type(int *, int);
int rt_modbus_process_request(uint8_t *buf, int n) {
  switch (buf[1]) {
  case (0x01):
    return rt_modbus_read_output_table(buf, n);
  case (0x02):
    return rt_modbus_read_input_table(buf, n);
  case (0x03):
    return rt_modbus_read_registers(buf, n);
  case (0x04):
    return rt_modbus_read_analog_inputs(buf, n);
  case (0x05):
    return rt_modbus_force_single_output(buf, n);
  case (0x06):
    return rt_modbus_preset_single_register(buf, n);
  case (0x07):
    return rt_modbus_read_exception_status(buf, n);
  case (0x08):
    return rt_modbus_loopback(buf, n);
  case (0x0F):
    return rt_modbus_force_multiple_outputs(buf, n);
  case (0x10):
    return rt_modbus_preset_multiple_registers(buf, n);
  case (0x11):
    return rt_modbus_report_device_type(buf, n);
  case (67):
    return rt_modbus_read_scratch_pad(buf, n);
  default:
    if (buf[1] < 80)
      buf[1] += 0x80;
    else
      buf[1] = 0xFF;
    buf[2] = 0x01;
    add_CRC(buf, 5, 0xffff);
    return 5;
  }
  return 0;
}


x86 assembly (clang, -O0):
<rt_modbus_process_request>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x20(%rbp)
sub    $0x42,%eax
ja     12fc <rt_modbus_process_request+0x12c>
mov    -0x20(%rbp),%rax
lea    0xdfd(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1080 <rt_modbus_read_output_table@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   10b0 <rt_modbus_read_input_table@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1060 <rt_modbus_read_registers@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1040 <rt_modbus_read_analog_inputs@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   10e0 <rt_modbus_force_single_output@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <rt_modbus_preset_single_register@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1030 <rt_modbus_read_exception_status@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   10f0 <rt_modbus_loopback@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1050 <rt_modbus_force_multiple_outputs@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   10c0 <rt_modbus_preset_multiple_registers@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1090 <rt_modbus_report_device_type@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   10d0 <rt_modbus_read_scratch_pad@plt>
mov    %eax,-0x4(%rbp)
jmp    134f <rt_modbus_process_request+0x17f>
mov    -0x10(%rbp),%rax
cmpl   $0x50,0x4(%rax)
jge    131f <rt_modbus_process_request+0x14f>
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%ecx
add    $0x80,%ecx
mov    %ecx,0x4(%rax)
jmp    132a <rt_modbus_process_request+0x15a>
mov    -0x10(%rbp),%rax
movl   $0xff,0x4(%rax)
mov    -0x10(%rbp),%rax
movl   $0x1,0x8(%rax)
mov    -0x10(%rbp),%rdi
mov    $0x5,%esi
mov    $0xffff,%edx
call   10a0 <add_CRC@plt>
movl   $0x5,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rt_modbus_process_request>:
push   %rax
mov    0x4(%rdi),%eax
lea    -0x1(%rax),%ecx
cmp    $0x42,%ecx
ja     121c <rt_modbus_process_request+0x4c>
lea    0xe1d(%rip),%rdx
movslq (%rdx,%rcx,4),%rcx
add    %rdx,%rcx
jmp    *%rcx
pop    %rax
jmp    1080 <rt_modbus_read_output_table@plt>
pop    %rax
jmp    10b0 <rt_modbus_read_input_table@plt>
pop    %rax
jmp    1060 <rt_modbus_read_registers@plt>
pop    %rax
jmp    1040 <rt_modbus_read_analog_inputs@plt>
pop    %rax
jmp    10e0 <rt_modbus_force_single_output@plt>
pop    %rax
jmp    1070 <rt_modbus_preset_single_register@plt>
pop    %rax
jmp    1030 <rt_modbus_read_exception_status@plt>
pop    %rax
jmp    10f0 <rt_modbus_loopback@plt>
lea    0x80(%rax),%ecx
cmp    $0x50,%eax
mov    $0xff,%eax
cmovl  %ecx,%eax
mov    %eax,0x4(%rdi)
movl   $0x1,0x8(%rdi)
mov    $0x5,%esi
mov    $0xffff,%edx
call   10a0 <add_CRC@plt>
mov    $0x5,%eax
pop    %rcx
ret
pop    %rax
jmp    1050 <rt_modbus_force_multiple_outputs@plt>
pop    %rax
jmp    10c0 <rt_modbus_preset_multiple_registers@plt>
pop    %rax
jmp    1090 <rt_modbus_report_device_type@plt>
pop    %rax
jmp    10d0 <rt_modbus_read_scratch_pad@plt>

LLVM IR (-O0):
define i32 @rt_modbus_process_request(i32* %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32*
%5 = alloca i32
store i32* %0, i32** %4
store i32 %1, i32* %5
%6 = load i32*, i32** %4
%7 = getelementptr inbounds i32, i32* %6, i64 1
%8 = load i32, i32* %7
switch i32 %8, label %57 [
i32 1, label %9
i32 2, label %13
i32 3, label %17
i32 4, label %21
i32 5, label %25
i32 6, label %29
i32 7, label %33
i32 8, label %37
i32 15, label %41
i32 16, label %45
i32 17, label %49
i32 67, label %53
]
9: ; preds = %2
%10 = load i32*, i32** %4
%11 = load i32, i32* %5
%12 = call i32 @rt_modbus_read_output_table(i32* %10, i32 %11)
store i32 %12, i32* %3
br label %75
13: ; preds = %2
%14 = load i32*, i32** %4
%15 = load i32, i32* %5
%16 = call i32 @rt_modbus_read_input_table(i32* %14, i32 %15)
store i32 %16, i32* %3
br label %75
17: ; preds = %2
%18 = load i32*, i32** %4
%19 = load i32, i32* %5
%20 = call i32 @rt_modbus_read_registers(i32* %18, i32 %19)
store i32 %20, i32* %3
br label %75
21: ; preds = %2
%22 = load i32*, i32** %4
%23 = load i32, i32* %5
%24 = call i32 @rt_modbus_read_analog_inputs(i32* %22, i32 %23)
store i32 %24, i32* %3
br label %75
25: ; preds = %2
%26 = load i32*, i32** %4
%27 = load i32, i32* %5
%28 = call i32 @rt_modbus_force_single_output(i32* %26, i32 %27)
store i32 %28, i32* %3
br label %75
29: ; preds = %2
%30 = load i32*, i32** %4
%31 = load i32, i32* %5
%32 = call i32 @rt_modbus_preset_single_register(i32* %30, i32 %31)
store i32 %32, i32* %3
br label %75
33: ; preds = %2
%34 = load i32*, i32** %4
%35 = load i32, i32* %5
%36 = call i32 @rt_modbus_read_exception_status(i32* %34, i32 %35)
store i32 %36, i32* %3
br label %75
37: ; preds = %2
%38 = load i32*, i32** %4
%39 = load i32, i32* %5
%40 = call i32 @rt_modbus_loopback(i32* %38, i32 %39)
store i32 %40, i32* %3
br label %75
41: ; preds = %2
%42 = load i32*, i32** %4
%43 = load i32, i32* %5
%44 = call i32 @rt_modbus_force_multiple_outputs(i32* %42, i32 %43)
store i32 %44, i32* %3
br label %75
45: ; preds = %2
%46 = load i32*, i32** %4
%47 = load i32, i32* %5
%48 = call i32 @rt_modbus_preset_multiple_registers(i32* %46, i32 %47)
store i32 %48, i32* %3
br label %75
49: ; preds = %2
%50 = load i32*, i32** %4
%51 = load i32, i32* %5
%52 = call i32 @rt_modbus_report_device_type(i32* %50, i32 %51)
store i32 %52, i32* %3
br label %75
53: ; preds = %2
%54 = load i32*, i32** %4
%55 = load i32, i32* %5
%56 = call i32 @rt_modbus_read_scratch_pad(i32* %54, i32 %55)
store i32 %56, i32* %3
br label %75
57: ; preds = %2
%58 = load i32*, i32** %4
%59 = getelementptr inbounds i32, i32* %58, i64 1
%60 = load i32, i32* %59
%61 = icmp slt i32 %60, 80
br i1 %61, label %62, label %67
62: ; preds = %57
%63 = load i32*, i32** %4
%64 = getelementptr inbounds i32, i32* %63, i64 1
%65 = load i32, i32* %64
%66 = add nsw i32 %65, 128
store i32 %66, i32* %64
br label %70
67: ; preds = %57
%68 = load i32*, i32** %4
%69 = getelementptr inbounds i32, i32* %68, i64 1
store i32 255, i32* %69
br label %70
70: ; preds = %67, %62
%71 = load i32*, i32** %4
%72 = getelementptr inbounds i32, i32* %71, i64 2
store i32 1, i32* %72
%73 = load i32*, i32** %4
%74 = call i32 @add_CRC(i32* %73, i32 5, i32 65535)
store i32 5, i32* %3
br label %75
75: ; preds = %70, %53, %49, %45, %41, %37, %33, %29, %25, %21, %17, %13, %9
%76 = load i32, i32* %3
ret i32 %76
}

LLVM IR (-O2):
define i32 @rt_modbus_process_request(i32* %0, i32 %1) {
%3 = getelementptr inbounds i32, i32* %0, i64 1
%4 = load i32, i32* %3
switch i32 %4, label %29 [
i32 1, label %5
i32 2, label %7
i32 3, label %9
i32 4, label %11
i32 5, label %13
i32 6, label %15
i32 7, label %17
i32 8, label %19
i32 15, label %21
i32 16, label %23
i32 17, label %25
i32 67, label %27
]
5: ; preds = %2
%6 = tail call i32 @rt_modbus_read_output_table(i32* %0, i32 %1)
br label %35
7: ; preds = %2
%8 = tail call i32 @rt_modbus_read_input_table(i32* %0, i32 %1)
br label %35
9: ; preds = %2
%10 = tail call i32 @rt_modbus_read_registers(i32* %0, i32 %1)
br label %35
11: ; preds = %2
%12 = tail call i32 @rt_modbus_read_analog_inputs(i32* %0, i32 %1)
br label %35
13: ; preds = %2
%14 = tail call i32 @rt_modbus_force_single_output(i32* %0, i32 %1)
br label %35
15: ; preds = %2
%16 = tail call i32 @rt_modbus_preset_single_register(i32* %0, i32 %1)
br label %35
17: ; preds = %2
%18 = tail call i32 @rt_modbus_read_exception_status(i32* %0, i32 %1)
br label %35
19: ; preds = %2
%20 = tail call i32 @rt_modbus_loopback(i32* %0, i32 %1)
br label %35
21: ; preds = %2
%22 = tail call i32 @rt_modbus_force_multiple_outputs(i32* %0, i32 %1)
br label %35
23: ; preds = %2
%24 = tail call i32 @rt_modbus_preset_multiple_registers(i32* %0, i32 %1)
br label %35
25: ; preds = %2
%26 = tail call i32 @rt_modbus_report_device_type(i32* %0, i32 %1)
br label %35
27: ; preds = %2
%28 = tail call i32 @rt_modbus_read_scratch_pad(i32* %0, i32 %1)
br label %35
29: ; preds = %2
%30 = icmp slt i32 %4, 80
%31 = add nsw i32 %4, 128
%32 = select i1 %30, i32 %31, i32 255
store i32 %32, i32* %3
%33 = getelementptr inbounds i32, i32* %0, i64 2
store i32 1, i32* %33
%34 = tail call i32 @add_CRC(i32* %0, i32 5, i32 65535)
br label %35
35: ; preds = %29, %27, %25, %23, %21, %19, %17, %15, %13, %11, %9, %7, %5
%36 = phi i32 [ 5, %29 ], [ %28, %27 ], [ %26, %25 ], [ %24, %23 ], [ %22, %21 ], [ %20, %19 ], [ %18, %17 ], [ %16, %15 ], [ %14, %13 ], [ %12, %11 ], [ %10, %9 ], [ %8, %7 ], [ %6, %5 ]
ret i32 %36
}