summaryrefslogtreecommitdiff
path: root/vm/mterp/x86/bindiv2addr.S
blob: efa76b5b97f51cd35ef328fea70fe806c86bcefe (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
%default {"result":"","special":""}
    /*
     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
     * op1=-1.
     */
    /* div/rem/2addr vA, vB */
    movzx    rINST_HI,%ecx          # eax<- BA
    sarl     $$4,%ecx               # ecx<- B
    GET_VREG(%ecx,%ecx)             # eax<- vBB
    movzbl   rINST_HI,rINST_FULL    # rINST_FULL<- BA
    andb     $$0xf,rINST_LO         # rINST_FULL<- A
    GET_VREG(%eax,rINST_FULL)       # eax<- vBB
    SPILL(rPC)
    cmpl     $$0,%ecx
    je       common_errDivideByZero
    cmpl     $$-1,%ecx
    jne      .L${opcode}_continue_div2addr
    cmpl     $$0x80000000,%eax
    jne      .L${opcode}_continue_div2addr
    movl     $special,$result
    jmp      .L${opcode}_finish_div2addr

%break
.L${opcode}_continue_div2addr:
    cltd
    idivl   %ecx
.L${opcode}_finish_div2addr:
    SET_VREG($result,rINST_FULL)
    UNSPILL(rPC)
    FETCH_INST_WORD(1)
    ADVANCE_PC(1)
    GOTO_NEXT