// File: 7shi[P]8086run/v1/main.cpp
// Function: shift(Operand*, int, unsigned char*)
inline void shift(Operand *opr, int c, uint8_t *p) {
    int val, m = opr->w ? 0x8000 : 0x80;
    switch ((p[1] >> 3) & 7) {
        case 0: // rol
            val = opr->u();
            for (int i = 0; i < c; ++i)
                val = (val << 1) | (CF = val & m);
            OF = CF ^ bool(val & m);
            *opr = val;
            break;
        case 1: // ror
            val = opr->u();
            for (int i = 0; i < c; ++i)
                val = (val >> 1) | ((CF = val & 1) ? m : 0);
            OF = CF ^ bool(val & (m >> 1));
            *opr = val;
            break;
        case 2: // rcl
            val = opr->u();
            for (int i = 0; i < c; ++i) {
                val = (val << 1) | CF;
                CF = val & (m << 1);
            }
            OF = CF ^ bool(val & m);
            *opr = val;
            break;
        case 3: // rcr
            val = opr->u();
            for (int i = 0; i < c; ++i) {
                bool f1 = val & 1, f2 = val & m;
                val = (val >> 1) | (CF ? m : 0);
                OF = CF ^ f2;
                CF = f1;
            }
            *opr = val;
            break;
        case 4: // shl/sal
            if (c > 0) {
                val = opr->u();
                for (int i = 0; i < c; ++i) {
                    val <<= 1;
                }
                *opr = opr->setf(val);
                CF = val & (m << 1);
                OF = CF != bool(val & m);
            }
            break;
        case 5: // shr
            if (c > 0) {
                val = opr->u();
                for (int i = 1; i < c; ++i) {
                    val >>= 1;
                }
                *opr = opr->setf(val >> 1);
                CF = val & 1;
                OF = val & m;
            }
            break;
        case 7: // sar
            if (c > 0) {
                val = **opr;
                for (int i = 1; i < c; ++i) {
                    val >>= 1;
                }
                *opr = opr->setf(val >> 1);
                CF = val & 1;
                OF = false;
            }
            break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movb 0x4(%rax), %al
testb $0x1, %al
movl $0x8000, %ecx           # imm = 0x8000
movl $0x80, %eax
cmovnel %ecx, %eax
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
shrl $0x3, %eax
andl $0x7, %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0x7, %eax
ja 0x7262
movq -0x48(%rbp), %rax
leaq 0x1730(%rip), %rcx      # 0x8594
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x6eba
movl -0x1c(%rbp), %eax
shll %eax
movl -0x1c(%rbp), %ecx
andl -0x20(%rbp), %ecx
cmpl $0x0, %ecx
setne %cl
movb %cl, %dl
andb $0x1, %dl
movb %dl, 0x124384(%rip)     # 0x12b228
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x6e80
movb 0x124368(%rip), %al     # 0x12b228
andb $0x1, %al
movzbl %al, %eax
movl -0x1c(%rbp), %ecx
andl -0x20(%rbp), %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x124339(%rip)     # 0x12b220
movl -0x1c(%rbp), %esi
movq -0x8(%rbp), %rdi
callq 0x6490
jmp 0x7262
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x6f5d
movl -0x1c(%rbp), %eax
sarl %eax
movl %eax, -0x4c(%rbp)
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
movb %al, %cl
andb $0x1, %cl
movb %cl, 0x1242f6(%rip)     # 0x12b228
testb $0x1, %al
jne 0x6f38
jmp 0x6f40
movl -0x20(%rbp), %eax
movl %eax, -0x50(%rbp)
jmp 0x6f47
xorl %eax, %eax
movl %eax, -0x50(%rbp)
jmp 0x6f47
movl -0x4c(%rbp), %eax
movl -0x50(%rbp), %ecx
orl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x6f0b
movb 0x1242c5(%rip), %al     # 0x12b228
andb $0x1, %al
movzbl %al, %eax
movl -0x1c(%rbp), %ecx
movl -0x20(%rbp), %edx
sarl %edx
andl %edx, %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x124292(%rip)     # 0x12b220
movl -0x1c(%rbp), %esi
movq -0x8(%rbp), %rdi
callq 0x6490
jmp 0x7262
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x6ff3
movl -0x1c(%rbp), %eax
shll %eax
movb 0x124263(%rip), %cl     # 0x12b228
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movl -0x20(%rbp), %ecx
shll %ecx
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x124240(%rip)     # 0x12b228
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6fb2
movb 0x12422f(%rip), %al     # 0x12b228
andb $0x1, %al
movzbl %al, %eax
movl -0x1c(%rbp), %ecx
andl -0x20(%rbp), %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x124200(%rip)     # 0x12b220
movl -0x1c(%rbp), %esi
movq -0x8(%rbp), %rdi
callq 0x6490
jmp 0x7262
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x70da
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x31(%rbp)
movl -0x1c(%rbp), %eax
andl -0x20(%rbp), %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x32(%rbp)
movl -0x1c(%rbp), %eax
sarl %eax
movl %eax, -0x54(%rbp)
testb $0x1, 0x1241a7(%rip)    # 0x12b228
je 0x708b
movl -0x20(%rbp), %eax
movl %eax, -0x58(%rbp)
jmp 0x7092
xorl %eax, %eax
movl %eax, -0x58(%rbp)
jmp 0x7092
movl -0x54(%rbp), %eax
movl -0x58(%rbp), %ecx
orl %ecx, %eax
movl %eax, -0x1c(%rbp)
movb 0x124185(%rip), %al     # 0x12b228
andb $0x1, %al
movzbl %al, %eax
movb -0x32(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x12415f(%rip)     # 0x12b220
movb -0x31(%rbp), %al
andb $0x1, %al
movb %al, 0x12415c(%rip)     # 0x12b228
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x7044
movl -0x1c(%rbp), %esi
movq -0x8(%rbp), %rdi
callq 0x6490
jmp 0x7262
cmpl $0x0, -0xc(%rbp)
jle 0x717c
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x7123
movl -0x1c(%rbp), %eax
shll %eax
movl %eax, -0x1c(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x7108
movq -0x8(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6450
movl %eax, %esi
movq -0x8(%rbp), %rdi
callq 0x6490
movl -0x1c(%rbp), %eax
movl -0x20(%rbp), %ecx
shll %ecx
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x1240d6(%rip)     # 0x12b228
movb 0x1240d0(%rip), %al     # 0x12b228
andb $0x1, %al
movzbl %al, %eax
movl -0x1c(%rbp), %ecx
andl -0x20(%rbp), %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
setne %al
andb $0x1, %al
movb %al, 0x1240a4(%rip)     # 0x12b220
jmp 0x7262
cmpl $0x0, -0xc(%rbp)
jle 0x71f6
movq -0x8(%rbp), %rdi
callq 0x72e0
movl %eax, -0x1c(%rbp)
movl $0x1, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x71b5
movl -0x1c(%rbp), %eax
sarl %eax
movl %eax, -0x1c(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x719a
movq -0x8(%rbp), %rdi
movl -0x1c(%rbp), %esi
sarl %esi
callq 0x6450
movl %eax, %esi
movq -0x8(%rbp), %rdi
callq 0x6490
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x124046(%rip)     # 0x12b228
movl -0x1c(%rbp), %eax
andl -0x20(%rbp), %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x12402a(%rip)     # 0x12b220
jmp 0x7262
cmpl $0x0, -0xc(%rbp)
jle 0x7260
movq -0x8(%rbp), %rdi
callq 0x63a0
movl %eax, -0x1c(%rbp)
movl $0x1, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x722c
movl -0x1c(%rbp), %eax
sarl %eax
movl %eax, -0x1c(%rbp)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x7211
movq -0x8(%rbp), %rdi
movl -0x1c(%rbp), %esi
sarl %esi
callq 0x6450
movl %eax, %esi
movq -0x8(%rbp), %rdi
callq 0x6490
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x123fcf(%rip)     # 0x12b228
movb $0x0, 0x123fc0(%rip)    # 0x12b220
jmp 0x7262
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)