// File: akshayrajput[P]ARMV8_Simulator/./instructions.cpp
// Function: DecodeBitMask(int, int, int, int)
static uint64_t DecodeBitMask(int N, int imms, int immr, int size){
        int len, levels, S, R, diff, esize;

        uint64_t welem = 0;

        /* Finding the highest set bit in N:imms */
        if(N){
                len = 6;
        }
        else{
                imms = ~imms;
                for(int i=5; i>=0; i--){
                        if(imms & (1<<i)){
                                len = i;
                                break;
                        }
                }
                imms = ~imms;
        }
        if(len < 1){
                cout << "Invalid Instruction found" << endl;
        }

        /* caluclating levels value */
        levels = 0;
        for(int i=0; i<len; i++){
                levels = levels << 1;
                levels = (levels | 1) ;
        }

        if((levels & imms) == levels){
                cout << "Invalid Instruction found" << endl;
        }
        S = levels & imms;
        R = levels & immr;
        diff = S - R;
        esize = (1 << len);
        for(int i=0; i<(S+1); i++){
                welem = welem << 1;
                welem = (welem | 1) ;
        }

        for(int i=0; i<R; i++){
                uint64_t lbit = welem & 1;
                welem = welem >> 1;
                if(size == 32){
                        welem = welem & 0xffffffff7fffffff;
                        welem = (welem | (int)((lbit) << 31));
                }
                else{
                        welem = welem & 0x7fffffffffffffff;
                        welem = (welem |(uint64_t) ((lbit) << 63));
                }
        }
        return welem;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl %edx, -0xc(%rbp)
movl %ecx, -0x10(%rbp)
movq $0x0, -0x30(%rbp)
cmpl $0x0, -0x4(%rbp)
je 0x266b
movl $0x6, -0x14(%rbp)
jmp 0x26b5
movl -0x8(%rbp), %eax
xorl $-0x1, %eax
movl %eax, -0x8(%rbp)
movl $0x5, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x26ac
movl -0x8(%rbp), %eax
movl -0x34(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x269f
movl -0x34(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x26ac
jmp 0x26a1
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x267b
movl -0x8(%rbp), %eax
xorl $-0x1, %eax
movl %eax, -0x8(%rbp)
cmpl $0x1, -0x14(%rbp)
jge 0x26dd
movq 0xb916(%rip), %rdi      # 0xdfd8
leaq 0x9a5b(%rip), %rsi      # 0xc124
callq 0x10a0
movq %rax, %rdi
movq 0xb8e8(%rip), %rsi      # 0xdfc0
callq 0x10c0
movl $0x0, -0x18(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x270f
movl -0x18(%rbp), %eax
shll %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
orl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x26eb
movl -0x18(%rbp), %eax
andl -0x8(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x273c
movq 0xb8b7(%rip), %rdi      # 0xdfd8
leaq 0x99fc(%rip), %rsi      # 0xc124
callq 0x10a0
movq %rax, %rdi
movq 0xb889(%rip), %rsi      # 0xdfc0
callq 0x10c0
movl -0x18(%rbp), %eax
andl -0x8(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
andl -0xc(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
subl -0x20(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x14(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x28(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jge 0x279a
movq -0x30(%rbp), %rax
shlq %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
orq $0x1, %rax
movq %rax, -0x30(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x276b
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x2825
movq -0x30(%rbp), %rax
andq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
shrq %rax
movq %rax, -0x30(%rbp)
cmpl $0x20, -0x10(%rbp)
jne 0x27f0
movabsq $-0x80000001, %rax      # imm = 0xFFFFFFFF7FFFFFFF
andq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x48(%rbp), %rcx
shlq $0x1f, %rcx
movslq %ecx, %rcx
orq %rcx, %rax
movq %rax, -0x30(%rbp)
jmp 0x2815
movabsq $0x7fffffffffffffff, %rax # imm = 0x7FFFFFFFFFFFFFFF
andq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x48(%rbp), %rcx
shlq $0x3f, %rcx
orq %rcx, %rax
movq %rax, -0x30(%rbp)
jmp 0x2817
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x27a1
movq -0x30(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nop