diff options
Diffstat (limited to 'vm/mterp/x86/bindivLit16.S')
-rw-r--r-- | vm/mterp/x86/bindivLit16.S | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/vm/mterp/x86/bindivLit16.S b/vm/mterp/x86/bindivLit16.S new file mode 100644 index 0000000..c935367 --- /dev/null +++ b/vm/mterp/x86/bindivLit16.S @@ -0,0 +1,34 @@ +%default {"result":"","special":""} + /* + * 32-bit binary div/rem operation. Handles special case of op0=minint and + * op1=-1. + */ + /* div/rem/lit16 vA, vB, #+CCCC */ + /* Need A in rINST, ssssCCCC in ecx, vB in eax */ + movzbl rINSTbl,%eax # eax<- 000000BA + SPILL(rIBASE) + sarl $$4,%eax # eax<- B + GET_VREG_R %eax %eax # eax<- vB + movswl 2(rPC),%ecx # ecx<- ssssCCCC + andb $$0xf,rINSTbl # rINST<- A + cmpl $$0,%ecx + je common_errDivideByZero + cmpl $$-1,%ecx + jne .L${opcode}_continue_div + cmpl $$0x80000000,%eax + jne .L${opcode}_continue_div + movl $special,$result + SET_VREG $result rINST + UNSPILL(rIBASE) + FETCH_INST_OPCODE 2 %ecx + ADVANCE_PC 2 + GOTO_NEXT_R %ecx + +.L${opcode}_continue_div: + cltd + idivl %ecx + SET_VREG $result rINST + UNSPILL(rIBASE) + FETCH_INST_OPCODE 2 %ecx + ADVANCE_PC 2 + GOTO_NEXT_R %ecx |