// File: Infinidat[P]slimfastq/recs.cpp
// Function: numberwang(unsigned char const*, int, unsigned long long&, unsigned char)
static UCHAR numberwang(const UCHAR* p, int len, UINT64 &num, UCHAR pctype)
{
    // return type
    //  hex if deci & prev == hex
    //  hex if hex
    //  deci if deci
    //  str else
    int i = 0;
    bool has_z = p[i] == '0';
    rarely_if (has_z)
        if ( p[++i] == '0')     // can't recreate two preceding zeros
            return ST_STR;

    UCHAR caps  = 0; // 0=? 1=lower 2=caps

    num = 0;
    while (pctype != 2) {       // prev weren't hex
        if (i >= len)
            return has_z ? ST_DGT_Z : ST_DGT ;

        if (isdigit(p[i])) {
            UINT64 tnum = (num<<3) + (num<<1) + (p[i++]) - '0';
            if (tnum < num) return ST_STR;  // too big
            num = tnum;
            continue;
        }
        // Here: not a deci

        if ((p[i]|0x20) < 'a' or
            (p[i]|0x20) > 'f')
            return ST_STR;

        // reset and try as hex
        caps = 1 + (p[i] < 'a');
        i = has_z;
        num = 0;
        break;
    }

    if (len > 16)
        return ST_STR;

    for (; i < len; i ++) {
       int nibel;
       if (isdigit (p[i]))
           nibel = (p[i]) - '0';

       else if (p[i] >= 'a' and p[i] <= 'f') {
           if (caps == 2)
               return ST_STR;   // can't combine upper and lower
           caps = 1;
           nibel = 10 + (p[i] - 'a');
       }
       else if (p[i] >= 'A' and p[i] <= 'F') {
           if (caps == 1)
               return ST_STR;   // can't combine upper and lower
           caps = 2;
           nibel = 10 + (p[i] - 'A');
       }
       else
           return ST_STR;

       num = (num<<4) + nibel;
    }

    // Here: it's an hexa
    return
        caps == 2 ?
        has_z ? ST_HGTC_Z : ST_HGTC :
        has_z ? ST_HGT_Z  : ST_HGT ;
}

// Assembly:
subq $0x48, %rsp
movb %cl, %al
movq %rdi, 0x38(%rsp)
movl %esi, 0x34(%rsp)
movq %rdx, 0x28(%rsp)
movb %al, 0x27(%rsp)
movl $0x0, 0x20(%rsp)
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x30, %eax
sete %al
andb $0x1, %al
movb %al, 0x1f(%rsp)
testb $0x1, 0x1f(%rsp)
je 0xb6e9
movq 0x38(%rsp), %rax
movl 0x20(%rsp), %ecx
addl $0x1, %ecx
movl %ecx, 0x20(%rsp)
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x30, %eax
jne 0xb6e7
movb $0x2, 0x47(%rsp)
jmp 0xb99d
jmp 0xb6e9
movb $0x0, 0x1e(%rsp)
movq 0x28(%rsp), %rax
movq $0x0, (%rax)
movzbl 0x27(%rsp), %eax
cmpl $0x2, %eax
je 0xb81d
movl 0x20(%rsp), %eax
cmpl 0x34(%rsp), %eax
jl 0xb72c
movb 0x1f(%rsp), %dl
xorl %eax, %eax
movl $0xb, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movb %al, 0x47(%rsp)
jmp 0xb99d
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x2250
cmpl $0x0, %eax
je 0xb7ae
movq 0x28(%rsp), %rax
movq (%rax), %rax
shlq $0x3, %rax
movq 0x28(%rsp), %rcx
movq (%rcx), %rcx
shlq %rcx
addq %rcx, %rax
movq 0x38(%rsp), %rcx
movl 0x20(%rsp), %edx
movl %edx, %esi
addl $0x1, %esi
movl %esi, 0x20(%rsp)
movslq %edx, %rdx
movzbl (%rcx,%rdx), %ecx
addq %rcx, %rax
subq $0x30, %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movq 0x28(%rsp), %rcx
cmpq (%rcx), %rax
jae 0xb79c
movb $0x2, 0x47(%rsp)
jmp 0xb99d
movq 0x10(%rsp), %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
jmp 0xb6fa
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
orl $0x20, %eax
cmpl $0x61, %eax
jl 0xb7da
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
orl $0x20, %eax
cmpl $0x66, %eax
jle 0xb7e4
movb $0x2, 0x47(%rsp)
jmp 0xb99d
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x61, %eax
setl %al
andb $0x1, %al
movzbl %al, %eax
addl $0x1, %eax
movb %al, 0x1e(%rsp)
movb 0x1f(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20(%rsp)
movq 0x28(%rsp), %rax
movq $0x0, (%rax)
cmpl $0x10, 0x34(%rsp)
jle 0xb82e
movb $0x2, 0x47(%rsp)
jmp 0xb99d
jmp 0xb830
movl 0x20(%rsp), %eax
cmpl 0x34(%rsp), %eax
jge 0xb959
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x2250
cmpl $0x0, %eax
je 0xb870
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
subl $0x30, %eax
movl %eax, 0xc(%rsp)
jmp 0xb92d
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x61, %eax
jl 0xb8c9
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x66, %eax
jg 0xb8c9
movzbl 0x1e(%rsp), %eax
cmpl $0x2, %eax
jne 0xb8aa
movb $0x2, 0x47(%rsp)
jmp 0xb99d
movb $0x1, 0x1e(%rsp)
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
subl $0x61, %eax
addl $0xa, %eax
movl %eax, 0xc(%rsp)
jmp 0xb92b
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x41, %eax
jl 0xb922
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x46, %eax
jg 0xb922
movzbl 0x1e(%rsp), %eax
cmpl $0x1, %eax
jne 0xb903
movb $0x2, 0x47(%rsp)
jmp 0xb99d
movb $0x2, 0x1e(%rsp)
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movzbl (%rax,%rcx), %eax
subl $0x41, %eax
addl $0xa, %eax
movl %eax, 0xc(%rsp)
jmp 0xb929
movb $0x2, 0x47(%rsp)
jmp 0xb99d
jmp 0xb92b
jmp 0xb92d
movq 0x28(%rsp), %rax
movq (%rax), %rcx
shlq $0x4, %rcx
movslq 0xc(%rsp), %rax
addq %rax, %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0xb830
movzbl 0x1e(%rsp), %eax
cmpl $0x2, %eax
jne 0xb97d
movb 0x1f(%rsp), %dl
movl $0x7, %eax
movl $0x9, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, 0x8(%rsp)
jmp 0xb995
movb 0x1f(%rsp), %dl
movl $0x3, %eax
movl $0x5, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
movb %al, 0x47(%rsp)
movb 0x47(%rsp), %al
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)