// File: /workspace/github_c_makefile_star2_O3/Nico01[P]obj2asm/odisasm.c
// Function: mod_reg
int mod_reg( byte, text, class )
    uchar   byte;
    char            *text;
    int             class;
{
    char            *opcode;
    int             dir;
    int             size;
    int             reg_size;
    int             size_needed;
    int             type;
    int             method;
    int             group;
    dword   mod_reg;
    uchar   mod;
    uchar   r_m;
    uchar   reg;
    int             additional;
    char            mem_text[50];
    char            reg_text[50];
    char            third_text[50];
    char            operands[80];
    int             ref_mode;

    if ( get_checkc( &mod_reg ) ) {
        return( 0 );
    }

    mod = (uchar)(((int)mod_reg & 0xC0) >> 6);
    reg = (uchar)(((int)mod_reg & 0x38) >> 3);
    r_m = (uchar)(((int)mod_reg & 0x07) >> 0);

    dir         = modrm_class[class].dir;
    size        = modrm_class[class].size;
    method      = modrm_class[class].method;
    group       = modrm_class[class].group;
    size_needed = modrm_class[class].size_needed;
    type        = modrm_class[class].type;

    ref_mode = 0;

    if ( group == 6 ) {
        if ( mod == 3 ) {
            if ( reg == 0 || reg == 1 || reg == 2 || reg == 3 ) {
                addr_large = FALSE;         /* 286 only instructions */
                size_large = FALSE;
            }
        }
        type = WORD_PTR;
        size_needed = TRUE;
    }

    reg_size = size;                /* 386 Segments effect register names */
    if ( reg_size == 1 && size_large ) {
        reg_size = 2;
    }
    if ( type == UNKNOWN ) {
        type = reg_size_to_type( reg_size );
    }

    if ( group == 0 ) {
        opcode = text;
    } else {
        opcode = op_grp[group-1][reg];
    }
    if ( strlen(opcode) == 0 ) {
        return( 0 );
    }

    if ( class == 26 ) {
        reg_size = 1;
    }

    if ( byte == 0x62 || byte == 0x63 ) {
        if ( byte == 0x63 ) {
            type = WORD_PTR;
        }
        size_needed = TRUE;     /* LAR, LSL, BOUND, ARPL need size */
    }
    if ( byte == 0xC4 || byte == 0xC5
           || byte == 0xB2 || byte == 0xB4 || byte == 0xB5 ) {
        size_needed = TRUE;
    }

    if ( group == 3 ) {         /* Group 3 has a test instruction which    */
        if ( reg == 0 ) {       /* needs an immediate value (byte or word) */
            method = 5 + size;  /* the rest of group 3 needs nothing       */
            dir = 0;
            size_needed = TRUE;
        } else {
            method = 0;
            if ( reg == 2 || reg == 3 ) {
                size_needed = FALSE;
            } else {
                size_needed = TRUE;
            }
        }
    }

    if ( group == 5 ) {                 /* Group 5 has call far and jump far */
        if ( reg == 3 || reg == 5 ) {   /* instructions which are dwords     */
                                        /* the rest of group 5 is words      */
            if ( size_large ) {
                type = FWORD_PTR;
            } else {
                type = DWORD_PTR;
            }
            size_needed = TRUE;
        } else {
            if ( reg == 0 || reg == 1 ) {
                size_needed = TRUE;
            }
        }
    }

    if ( group == 7 ) {                 /* Group 7 has mostly FWORD sized    */
        if ( reg == 4 || reg == 6 ) {   /* EAs, but these two are WORD sized */
            type = WORD_PTR;
        }
    }

    if ( dir == 0 && mod == 3 && (class == 0 || class == 1) ) {
        /*
        ** Ambiguous!   eg. OBJ 20F8 = and al,bh => MASM 22C7
        ** This is because MASM prefers the first operand to be
        ** a register and the other operand to be a mem/reg.
        */
        return(0);
    }

    mem_text[0] = '\0';
    additional = do_mod_rm( mem_text, mod, r_m, type, size_needed, ref_mode );
    if ( additional == -1 ) {
        return( 0 );
    }

    switch( method ) {
        case 0:         /* No additional information (one operand only) */
            break;
        case 1:         /* Other operand is a register */
                        /* LES,LDS,BOUND,LSS,LFS,LGS, ARPL instructions */
                        /* revert to Word */
            if ( byte == 0xC4 || byte == 0xC5 || byte == 0x62 || byte == 0x63
                   || byte == 0xB2 || byte == 0xB4 || byte == 0xB5 ) {
                reg_size = 1;
            }

            strcpy( reg_text, regs[reg_size][reg] );
            break;
        case 2:         /* Other operand is a segment register */
            if ( reg > 5 ) {    /* 0=ES,1=CS,2=SS,3=DS,4=FS,5=GS */
                return( 0 );
            }
            strcpy( reg_text, sregs[reg] );
            break;
        case 3:         /* Other operand is 1 */
            strcpy( reg_text, "1" );
            break;
        case 4:         /* Other operand is register CL */
            strcpy( reg_text, "cl" );
            break;
        case 5:         /* Immediate byte value */
            if ( byte_immed(reg_text, additional,FALSE) ) {
                return( 0 );
            }
            additional++;
            break;
        case 6:         /* Immediate word value (could be fixupp) */
            if ( word_immed(reg_text, additional) ) {
                return( 0 );
            }
            if ( size_large ) {
                additional += 4;
            } else {
                additional += 2;
            }
            break;
        case 7:         /* Immediate signed byte value */
            if ( byte_immed(reg_text,additional,TRUE) ) {
                return( 0 );
            }
            additional++;
            break;
        case 8:         /* IMUL (3 operands [reg,mem,immed word]) */
            strcpy( reg_text, regs[reg_size][reg] );
            if ( word_immed(third_text, additional) ) {
                return(0);
            }
            additional += 2;
            break;
        case 9:         /* IMUL (3 operands [reg,mem,immed signed byte]) */
            strcpy( reg_text, regs[reg_size][reg] );
            if ( byte_immed(third_text, additional,TRUE) ) {
                return(0);
            }
            additional += 1;
            break;
        case 10:        /* Control Register (CR0...) */
            strcpy( reg_text, cr_regs[reg] );
            break;
        case 11:        /* Debug Register (DR0...) */
            strcpy( reg_text, dr_regs[reg] );
            break;
        case 12:
            strcpy( reg_text, tr_regs[reg] );
            break;
        case 13:
            strcpy( reg_text, regs[reg_size][reg] );
            strcpy( third_text, "cl" );
            break;
    }

    if ( dir & 0x01 ) {
        sprintf( operands, dir_fmt[dir], reg_text, mem_text, third_text );
    } else {
        sprintf( operands, dir_fmt[dir], mem_text, reg_text, third_text );
    }

    adjust_assumes();
    instr_opcode( opcode );
    instr_operand( operands );

    return( 2+additional );
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movl %edx, %r14d
movq %rsi, %r12
movl %edi, %ebx
leaq 0x68(%rsp), %rdi
callq 0x9787
xorl %r8d, %r8d
testl %eax, %eax
je 0xb2d2
movl %r8d, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %ebx, 0x1c(%rsp)
movb 0x68(%rsp), %bl
movl %ebx, %r10d
shrb $0x6, %r10b
movb %bl, 0xf(%rsp)
shrb $0x3, %bl
andb $0x7, %bl
movslq %r14d, %rax
leaq (%rax,%rax,2), %rax
leaq 0xe3b7(%rip), %rcx      # 0x196b0
movl (%rcx,%rax,8), %edi
movl 0x4(%rcx,%rax,8), %ebp
movl 0x8(%rcx,%rax,8), %r11d
movslq 0xc(%rcx,%rax,8), %r15
cmpq $0x6, %r15
jne 0xb331
cmpb $0x3, %r10b
sete %al
cmpb $0x4, %bl
setb %cl
testb %cl, %al
je 0xb390
xorl %eax, %eax
movl %eax, 0x11b5f(%rip)     # 0x1ce88
movl %eax, 0x11b55(%rip)     # 0x1ce84
jmp 0xb39a
movq %r12, 0x10(%rsp)
leaq (%rcx,%rax,8), %rax
movl 0x10(%rax), %r13d
cmpl $0x0, 0x11b3f(%rip)     # 0x1ce84
movl 0x14(%rax), %eax
movl $0x2, %r12d
cmovel %ebp, %r12d
cmpl $0x1, %ebp
cmovnel %ebp, %r12d
testl %eax, %eax
jne 0xb384
movl %edi, 0x8(%rsp)
movl %r12d, %edi
movb %r10b, 0x1b(%rsp)
movq %r11, 0x60(%rsp)
callq 0xf65a
movq 0x60(%rsp), %r11
movb 0x1b(%rsp), %r10b
xorl %r8d, %r8d
movl 0x8(%rsp), %edi
testl %r15d, %r15d
movq 0x10(%rsp), %rcx
jne 0xb3b8
jmp 0xb3d1
cmpl $0x0, 0x11aed(%rip)     # 0x1ce84
setne %al
testb $0x1, %al
movl $0x2, %r12d
cmovel %ebp, %r12d
cmpl $0x1, %ebp
cmovnel %ebp, %r12d
movl $0x1, %r13d
movl $0x4, %eax
movq %r15, %rcx
shlq $0x6, %rcx
leaq 0xe00a(%rip), %rdx      # 0x193d0
addq %rcx, %rdx
movzbl %bl, %ecx
movq -0x40(%rdx,%rcx,8), %rcx
movq %rcx, 0x10(%rsp)
cmpb $0x0, (%rcx)
je 0xb2bd
cmpl $0x1a, %r14d
movl $0x1, %ecx
cmovel %ecx, %r12d
movl 0x1c(%rsp), %r9d
movl %r9d, %edx
andb $-0x2, %dl
cmpb $0x63, %r9b
movl $0x4, %esi
cmovel %esi, %eax
cmpb $-0x4c, %dl
cmovel %ecx, %r13d
cmpb $-0x4e, %r9b
cmovel %ecx, %r13d
cmpb $-0x3c, %dl
cmovel %ecx, %r13d
cmpb $0x62, %dl
cmovel %ecx, %r13d
cmpl $0x5, %r15d
je 0xb446
cmpl $0x3, %r15d
jne 0xb486
testb %bl, %bl
je 0xb46a
movb 0xf(%rsp), %cl
andb $0x30, %cl
xorl %r13d, %r13d
cmpb $0x10, %cl
setne %r13b
xorl %r11d, %r11d
jmp 0xb486
cmpb $0x5, %bl
je 0xb453
movzbl %bl, %ecx
cmpl $0x3, %ecx
jne 0xb47a
cmpl $0x1, 0x11a2a(%rip)     # 0x1ce84
movl $0x6, %eax
sbbl $0x0, %eax
movl $0x1, %r13d
jmp 0xb486
addl $0x5, %ebp
movl $0x1, %r13d
xorl %edi, %edi
movl %ebp, %r11d
jmp 0xb486
cmpb $0x2, %bl
movl $0x1, %ecx
cmovbl %ecx, %r13d
cmpl $0x1, %r14d
ja 0xb49a
testl %edi, %edi
jne 0xb49a
cmpb $0x3, %r10b
je 0xb2bd
movq %r11, %rbp
movl %edi, 0x8(%rsp)
movb 0xf(%rsp), %cl
movl %ecx, %edx
andb $0x7, %dl
andb $0x28, %cl
cmpb $0x20, %cl
movl $0x4, %ecx
cmovnel %eax, %ecx
cmpl $0x7, %r15d
cmovnel %eax, %ecx
leaq 0xb0(%rsp), %rdi
movb $0x0, (%rdi)
movzbl %r10b, %esi
movzbl %dl, %edx
movl %r13d, %r8d
callq 0xaf5e
cmpl $-0x1, %eax
je 0xb53d
movl %eax, %r14d
decl %ebp
cmpl $0xc, %ebp
ja 0xb67f
leaq 0x7b61(%rip), %rax      # 0x13054
movslq (%rax,%rbp,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movzbl 0x1c(%rsp), %eax
leal -0xb2(%rax), %ecx
cmpl $0x13, %ecx
ja 0xb516
movl $0xc000d, %edx          # imm = 0xC000D
btl %ecx, %edx
jb 0xb51e
addl $-0x62, %eax
cmpl $0x2, %eax
jae 0xb524
movl $0x1, %r12d
movslq %r12d, %rax
shlq $0x6, %rax
leaq 0xdbde(%rip), %rcx      # 0x19110
addq %rax, %rcx
movzbl %bl, %eax
jmp 0xb671
xorl %r8d, %r8d
jmp 0xb2bd
movzbl %bl, %eax
leaq 0xdda1(%rip), %rcx      # 0x192f0
jmp 0xb671
leaq 0x20(%rsp), %rdi
movl %r14d, %esi
xorl %edx, %edx
callq 0xb145
xorl %r8d, %r8d
testl %eax, %eax
jne 0xb2bd
jmp 0xb740
movslq %r12d, %rax
shlq $0x6, %rax
leaq 0xdb8f(%rip), %rcx      # 0x19110
addq %rax, %rcx
movzbl %bl, %eax
movq (%rcx,%rax,8), %rsi
leaq 0x20(%rsp), %rdi
callq 0x9070
movw $0x6c63, 0x70(%rsp)     # imm = 0x6C63
movb $0x0, 0x72(%rsp)
jmp 0xb67f
movzbl %bl, %eax
leaq 0xdcc0(%rip), %rcx      # 0x19270
jmp 0xb671
movw $0x31, 0x20(%rsp)
jmp 0xb67f
movb $0x0, 0x22(%rsp)
movw $0x6c63, 0x20(%rsp)     # imm = 0x6C63
jmp 0xb67f
movslq %r12d, %rax
shlq $0x6, %rax
leaq 0xdb30(%rip), %rcx      # 0x19110
addq %rax, %rcx
movzbl %bl, %eax
movq (%rcx,%rax,8), %rsi
leaq 0x20(%rsp), %rdi
callq 0x9070
leaq 0x70(%rsp), %rdi
movl %r14d, %esi
callq 0xb1c8
testl %eax, %eax
movl $0x0, %r8d
jne 0xb2bd
jmp 0xb748
cmpb $0x5, %bl
movl $0x0, %r8d
ja 0xb2bd
movzbl %bl, %eax
leaq 0xdbe3(%rip), %rcx      # 0x19210
jmp 0xb671
leaq 0x20(%rsp), %rdi
movl %r14d, %esi
callq 0xb1c8
testl %eax, %eax
movl $0x0, %r8d
jne 0xb2bd
cmpl $0x0, 0x11833(%rip)     # 0x1ce84
je 0xb748
addl $0x4, %r14d
jmp 0xb67f
leaq 0x20(%rsp), %rdi
jmp 0xb725
movzbl %bl, %eax
leaq 0xdc3f(%rip), %rcx      # 0x192b0
movq (%rcx,%rax,8), %rsi
leaq 0x20(%rsp), %rdi
callq 0x9070
movq 0x10(%rsp), %rbx
movl 0x8(%rsp), %ebp
movslq %ebp, %rax
leaq 0xdfee(%rip), %rcx      # 0x19680
movq (%rcx,%rax,8), %rsi
leaq 0xf0(%rsp), %rdi
testb $0x1, %bpl
jne 0xb6b3
leaq 0xb0(%rsp), %rdx
leaq 0x20(%rsp), %rcx
jmp 0xb6c0
leaq 0x20(%rsp), %rdx
leaq 0xb0(%rsp), %rcx
leaq 0x70(%rsp), %r8
xorl %eax, %eax
callq 0x91b0
callq 0xf955
movq %rbx, %rdi
callq 0x97c1
leaq 0x11888(%rip), %rax     # 0x1cf68
cmpl $0x3, (%rax)
jne 0xb6f2
leaq 0xf0(%rsp), %rdi
callq 0xca45
addl $0x2, %r14d
movl %r14d, %r8d
jmp 0xb2bd
movslq %r12d, %rax
shlq $0x6, %rax
leaq 0xda04(%rip), %rcx      # 0x19110
addq %rax, %rcx
movzbl %bl, %eax
movq (%rcx,%rax,8), %rsi
leaq 0x20(%rsp), %rdi
callq 0x9070
leaq 0x70(%rsp), %rdi
movl %r14d, %esi
movl $0x1, %edx
callq 0xb145
testl %eax, %eax
movl $0x0, %r8d
jne 0xb2bd
incl %r14d
jmp 0xb67f
addl $0x2, %r14d
jmp 0xb67f