1%default {"result":"","special":"","rem":""}
2/*
3 * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4 * op1=-1.
5 */
6    /* div/rem vAA, vBB, vCC */
7    movzbl  2(rPC), %eax                    # eax <- BB
8    movzbl  3(rPC), %ecx                    # ecx <- CC
9    GET_VREG %eax, %eax                     # eax <- vBB
10    GET_VREG %ecx, %ecx                     # ecx <- vCC
11    mov     rIBASE, LOCAL0(%esp)
12    testl   %ecx, %ecx
13    je      common_errDivideByZero
14    movl    %eax, %edx
15    orl     %ecx, %edx
16    testl   $$0xFFFFFF00, %edx              # If both arguments are less
17                                            #   than 8-bit and +ve
18    jz      .L${opcode}_8                   # Do 8-bit divide
19    testl   $$0xFFFF0000, %edx              # If both arguments are less
20                                            #   than 16-bit and +ve
21    jz      .L${opcode}_16                  # Do 16-bit divide
22    cmpl    $$-1, %ecx
23    jne     .L${opcode}_32
24    cmpl    $$0x80000000, %eax
25    jne     .L${opcode}_32
26    movl    $special, $result
27    jmp     .L${opcode}_finish
28.L${opcode}_32:
29    cltd
30    idivl   %ecx
31    jmp     .L${opcode}_finish
32.L${opcode}_8:
33    div     %cl                             # 8-bit divide otherwise.
34                                            # Remainder in %ah, quotient in %al
35    .if $rem
36    movl    %eax, %edx
37    shr     $$8, %edx
38    .else
39    andl    $$0x000000FF, %eax
40    .endif
41    jmp     .L${opcode}_finish
42.L${opcode}_16:
43    xorl    %edx, %edx                      # Clear %edx before divide
44    div     %cx
45.L${opcode}_finish:
46    SET_VREG $result, rINST
47    mov     LOCAL0(%esp), rIBASE
48    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
49