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

/* Variables and functions */
int tlv_get_length(int /*<<< orphan*/ const *);
int tlv_get_type(int /*<<< orphan*/ const *);
bool ecmg_validate_param(const uint8_t *p_tlv_n) {
  static const uint16_t pi_ecmg_params_minlength[] = {0, 4, 1, 2, 2, 2, 2, 2, 2,
                                                      2, 1, 1, 2, 0, 2, 2, 2, 1,
                                                      2, 2, 0, 0, 2, 2, 0, 2};
  uint16_t i_type = tlv_get_type(p_tlv_n);
  uint16_t i_length = tlv_get_length(p_tlv_n);
  if (i_type <= 0x19) {
    if (i_length < pi_ecmg_params_minlength[i_type])
      return false;
  } else if (i_type == 0x7000) {
    if (i_length < 2)
      return false;
  }
  return true;
}


x86 assembly (clang, -O0):
<ecmg_validate_param>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <tlv_get_type@plt>
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <tlv_get_length@plt>
mov    %eax,-0x18(%rbp)
cmpl   $0x19,-0x14(%rbp)
jg     1176 <ecmg_validate_param+0x56>
mov    -0x18(%rbp),%eax
movslq -0x14(%rbp),%rdx
lea    0xea4(%rip),%rcx
cmp    (%rcx,%rdx,4),%eax
jge    1171 <ecmg_validate_param+0x51>
movl   $0x0,-0x4(%rbp)
jmp    11aa <ecmg_validate_param+0x8a>
jmp    11a3 <ecmg_validate_param+0x83>
cmpl   $0x7000,-0x14(%rbp)
jne    119e <ecmg_validate_param+0x7e>
cmpl   $0x2,-0x18(%rbp)
jge    1199 <ecmg_validate_param+0x79>
movl   $0x0,-0x4(%rbp)
jmp    11aa <ecmg_validate_param+0x8a>
jmp    119e <ecmg_validate_param+0x7e>
jmp    11a3 <ecmg_validate_param+0x83>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ecmg_validate_param>:
push   %rbp
push   %rbx
push   %rax
mov    %rdi,%rbx
call   1030 <tlv_get_type@plt>
mov    %eax,%ebp
mov    %rbx,%rdi
call   1040 <tlv_get_length@plt>
cmp    $0x19,%ebp
jg     114d <ecmg_validate_param+0x2d>
movslq %ebp,%rdx
lea    0xebc(%rip),%rsi
xor    %ecx,%ecx
cmp    (%rsi,%rdx,4),%eax
jge    115c <ecmg_validate_param+0x3c>
jmp    1161 <ecmg_validate_param+0x41>
cmp    $0x7000,%ebp
jne    115c <ecmg_validate_param+0x3c>
xor    %ecx,%ecx
cmp    $0x2,%eax
jl     1161 <ecmg_validate_param+0x41>
mov    $0x1,%ecx
mov    %ecx,%eax
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@ecmg_validate_param.pi_ecmg_params_minlength = internal constant [26 x i32] [i32 0, i32 4, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1, i32 2, i32 0, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 0, i32 0, i32 2, i32 2, i32 0, i32 2]
define i32 @ecmg_validate_param(i32* %0) {
%2 = alloca i32
%3 = alloca i32*
%4 = alloca i32
%5 = alloca i32
store i32* %0, i32** %3
%6 = load i32*, i32** %3
%7 = call i32 @tlv_get_type(i32* %6)
store i32 %7, i32* %4
%8 = load i32*, i32** %3
%9 = call i32 @tlv_get_length(i32* %8)
store i32 %9, i32* %5
%10 = load i32, i32* %4
%11 = icmp sle i32 %10, 25
br i1 %11, label %12, label %21
12: ; preds = %1
%13 = load i32, i32* %5
%14 = load i32, i32* %4
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds [26 x i32], [26 x i32]* @ecmg_validate_param.pi_ecmg_params_minlength, i64 0, i64 %15
%17 = load i32, i32* %16
%18 = icmp slt i32 %13, %17
br i1 %18, label %19, label %20
19: ; preds = %12
store i32 0, i32* %2
br label %31
20: ; preds = %12
br label %30
21: ; preds = %1
%22 = load i32, i32* %4
%23 = icmp eq i32 %22, 28672
br i1 %23, label %24, label %29
24: ; preds = %21
%25 = load i32, i32* %5
%26 = icmp slt i32 %25, 2
br i1 %26, label %27, label %28
27: ; preds = %24
store i32 0, i32* %2
br label %31
28: ; preds = %24
br label %29
29: ; preds = %28, %21
br label %30
30: ; preds = %29, %20
store i32 1, i32* %2
br label %31
31: ; preds = %30, %27, %19
%32 = load i32, i32* %2
ret i32 %32
}

LLVM IR (-O2):
@ecmg_validate_param.pi_ecmg_params_minlength = internal unnamed_addr constant [26 x i32] [i32 0, i32 4, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1, i32 2, i32 0, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 0, i32 0, i32 2, i32 2, i32 0, i32 2]
define i32 @ecmg_validate_param(i32* %0) {
%2 = tail call i32 @tlv_get_type(i32* %0)
%3 = tail call i32 @tlv_get_length(i32* %0)
%4 = icmp slt i32 %2, 26
br i1 %4, label %5, label %10
5: ; preds = %1
%6 = sext i32 %2 to i64
%7 = getelementptr inbounds [26 x i32], [26 x i32]* @ecmg_validate_param.pi_ecmg_params_minlength, i64 0, i64 %6
%8 = load i32, i32* %7
%9 = icmp slt i32 %3, %8
br i1 %9, label %15, label %14
10: ; preds = %1
%11 = icmp eq i32 %2, 28672
%12 = icmp slt i32 %3, 2
%13 = select i1 %11, i1 %12, i1 false
br i1 %13, label %15, label %14
14: ; preds = %10, %5
br label %15
15: ; preds = %10, %5, %14
%16 = phi i32 [ 1, %14 ], [ 0, %5 ], [ 0, %10 ]
ret i32 %16
}