const char *urg_strerror(const int errno) {
  const char *errorStr[] = {
      "Unknown",
      "Not Implemented.",
      "Send fail.",
      "Receive fail.",
      "SCIP1.1 protocol is not supported. Please update URG firmware.",
      "SS fail.",
      "Adjust baudrate fail.",
      "Invalid parameters.",
      "Urg invalid response.",
      "Serial connection fail.",
      "Serial receive fail.",
      "Response mismatch.",
      "No Response.",
      "UTM-30LX is not supported GD_INTENSITY. Please use MD_INTENSITY",
      "dummy.",
  };
  int n = sizeof(errorStr) / sizeof(errorStr[0]);
  if ((-errno >= n) || (errno > 0)) {
    return errorStr[0];
  }
  return errorStr[-errno];
}


x86 assembly (clang, -O0):
<urg_strerror>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %edi,-0xc(%rbp)
lea    -0x90(%rbp),%rdi
lea    0x2c74(%rip),%rsi
mov    $0x78,%edx
call   1030 <memcpy@plt>
movl   $0xf,-0x94(%rbp)
xor    %eax,%eax
sub    -0xc(%rbp),%eax
cmp    -0x94(%rbp),%eax
jge    115b <urg_strerror+0x4b>
cmpl   $0x0,-0xc(%rbp)
jle    116b <urg_strerror+0x5b>
mov    -0x90(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    117e <urg_strerror+0x6e>
xor    %eax,%eax
sub    -0xc(%rbp),%eax
cltq
mov    -0x90(%rbp,%rax,8),%rax
ff
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<urg_strerror>:
lea    -0x1(%rdi),%eax
neg    %edi
cmp    $0xfffffff1,%eax
movslq %edi,%rax
lea    0x2cbe(%rip),%rcx
lea    (%rcx,%rax,8),%rax
cmovb  %rcx,%rax
mov    (%rax),%rax
ret

LLVM IR (-O0):
@.str = [8 x i8] c"Unknown\00"
@.str.1 = [17 x i8] c"Not Implemented.\00"
@.str.2 = [11 x i8] c"Send fail.\00"
@.str.3 = [14 x i8] c"Receive fail.\00"
@.str.4 = [63 x i8] c"SCIP1.1 protocol is not supported. Please update URG firmware.\00"
@.str.5 = [9 x i8] c"SS fail.\00"
@.str.6 = [22 x i8] c"Adjust baudrate fail.\00"
@.str.7 = [20 x i8] c"Invalid parameters.\00"
@.str.8 = [22 x i8] c"Urg invalid response.\00"
@.str.9 = [24 x i8] c"Serial connection fail.\00"
@.str.10 = [21 x i8] c"Serial receive fail.\00"
@.str.11 = [19 x i8] c"Response mismatch.\00"
@.str.12 = [13 x i8] c"No Response.\00"
@.str.13 = [64 x i8] c"UTM-30LX is not supported GD_INTENSITY. Please use MD_INTENSITY\00"
@.str.14 = [7 x i8] c"dummy.\00"
@__const.urg_strerror.errorStr = [15 x i8*] [i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([63 x i8], [63 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str.13, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.14, i32 0, i32 0)]
define i8* @urg_strerror(i32 %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca [15 x i8*]
%5 = alloca i32
store i32 %0, i32* %3
%6 = bitcast [15 x i8*]* %4 to i8*
store i32 15, i32* %5
%7 = load i32, i32* %3
%8 = sub nsw i32 0, %7
%9 = load i32, i32* %5
%10 = icmp sge i32 %8, %9
br i1 %10, label %14, label %11
11: ; preds = %1
%12 = load i32, i32* %3
%13 = icmp sgt i32 %12, 0
br i1 %13, label %14, label %17
14: ; preds = %11, %1
%15 = getelementptr inbounds [15 x i8*], [15 x i8*]* %4, i64 0, i64 0
%16 = load i8*, i8** %15
store i8* %16, i8** %2
br label %23
17: ; preds = %11
%18 = load i32, i32* %3
%19 = sub nsw i32 0, %18
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds [15 x i8*], [15 x i8*]* %4, i64 0, i64 %20
%22 = load i8*, i8** %21
store i8* %22, i8** %2
br label %23
23: ; preds = %17, %14
%24 = load i8*, i8** %2
ret i8* %24
}

LLVM IR (-O2):
@.str = [8 x i8] c"Unknown\00"
@.str.1 = [17 x i8] c"Not Implemented.\00"
@.str.2 = [11 x i8] c"Send fail.\00"
@.str.3 = [14 x i8] c"Receive fail.\00"
@.str.4 = [63 x i8] c"SCIP1.1 protocol is not supported. Please update URG firmware.\00"
@.str.5 = [9 x i8] c"SS fail.\00"
@.str.6 = [22 x i8] c"Adjust baudrate fail.\00"
@.str.7 = [20 x i8] c"Invalid parameters.\00"
@.str.8 = [22 x i8] c"Urg invalid response.\00"
@.str.9 = [24 x i8] c"Serial connection fail.\00"
@.str.10 = [21 x i8] c"Serial receive fail.\00"
@.str.11 = [19 x i8] c"Response mismatch.\00"
@.str.12 = [13 x i8] c"No Response.\00"
@.str.13 = [64 x i8] c"UTM-30LX is not supported GD_INTENSITY. Please use MD_INTENSITY\00"
@.str.14 = [7 x i8] c"dummy.\00"
@__const.urg_strerror.errorStr = [15 x i8*] [i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([63 x i8], [63 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str.13, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.14, i32 0, i32 0)]
define i8* @urg_strerror(i32 %0) {
%2 = add i32 %0, -1
%3 = icmp ult i32 %2, -15
%4 = sub nsw i32 0, %0
%5 = sext i32 %4 to i64
%6 = getelementptr inbounds [15 x i8*], [15 x i8*]* @__const.urg_strerror.errorStr, i64 0, i64 %5
%7 = select i1 %3, i8** getelementptr inbounds ([15 x i8*], [15 x i8*]* @__const.urg_strerror.errorStr, i64 0, i64 0), i8** %6
%8 = load i8*, i8** %7
ret i8* %8
}