summaryrefslogtreecommitdiff
path: root/vm/mterp/x86/OP_DIV_LONG_2ADDR.S
blob: 4722098945f57ee7c05cbcf2dbf9f673054ef0cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
%verify "executed"
%default {"routine":"__divdi3","special":"$0x80000000"}
    /* div/2addr vA, vB */
    movzbl    rINSTbl,%eax
    shrl      $$4,%eax                  # eax<- B
    andb      $$0xf,rINSTbl             # rINST<- A
    SPILL(rIBASE)                       # save rIBASE/%edx
    GET_VREG_WORD rIBASE %eax 0
    GET_VREG_WORD %eax %eax 1
    movl     rIBASE,OUT_ARG2(%esp)
    testl    %eax,%eax
    je       .L${opcode}_check_zero
    cmpl     $$-1,%eax
    je       .L${opcode}_check_neg1
.L${opcode}_notSpecial:
    GET_VREG_WORD rIBASE rINST 0
    GET_VREG_WORD %ecx rINST 1
.L${opcode}_notSpecial1:
    movl     %eax,OUT_ARG3(%esp)
    movl     rIBASE,OUT_ARG0(%esp)
    movl     %ecx,OUT_ARG1(%esp)
    call     $routine
.L${opcode}_finish:
    SET_VREG_WORD rIBASE rINST 1
    UNSPILL(rIBASE)                    # restore rIBASE/%edx
    SET_VREG_WORD %eax rINST 0
    FETCH_INST_OPCODE 1 %ecx
    ADVANCE_PC 1
    GOTO_NEXT_R %ecx

.L${opcode}_check_zero:
    testl   rIBASE,rIBASE
    jne     .L${opcode}_notSpecial
    jmp     common_errDivideByZero
.L${opcode}_check_neg1:
    testl   rIBASE,%eax
    jne     .L${opcode}_notSpecial
    GET_VREG_WORD rIBASE rINST 0
    GET_VREG_WORD %ecx rINST 1
    testl    rIBASE,rIBASE
    jne      .L${opcode}_notSpecial1
    cmpl     $$0x80000000,%ecx
    jne      .L${opcode}_notSpecial1
    /* minint / -1, return minint on div, 0 on rem */
    xorl     %eax,%eax
    movl     $special,rIBASE
    jmp      .L${opcode}_finish