blob: e87ba45546b811a1da21fbeb3276e97a9c01e365 [file] [log] [blame]
%default {"result":"","special":"","rem":""}
/*
* 32-bit binary div/rem operation. Handles special case of op0=minint and
* op1=-1.
*/
/* div/rem vAA, vBB, vCC */
movzbl 2(rPC), %eax # eax <- BB
movzbl 3(rPC), %ecx # ecx <- CC
GET_VREG %eax, %eax # eax <- vBB
GET_VREG %ecx, %ecx # ecx <- vCC
mov rIBASE, LOCAL0(%esp)
testl %ecx, %ecx
je common_errDivideByZero
movl %eax, %edx
orl %ecx, %edx
testl $$0xFFFFFF00, %edx # If both arguments are less
# than 8-bit and +ve
jz .L${opcode}_8 # Do 8-bit divide
testl $$0xFFFF0000, %edx # If both arguments are less
# than 16-bit and +ve
jz .L${opcode}_16 # Do 16-bit divide
cmpl $$-1, %ecx
jne .L${opcode}_32
cmpl $$0x80000000, %eax
jne .L${opcode}_32
movl $special, $result
jmp .L${opcode}_finish
.L${opcode}_32:
cltd
idivl %ecx
jmp .L${opcode}_finish
.L${opcode}_8:
div %cl # 8-bit divide otherwise.
# Remainder in %ah, quotient in %al
.if $rem
movl %eax, %edx
shr $$8, %edx
.else
andl $$0x000000FF, %eax
.endif
jmp .L${opcode}_finish
.L${opcode}_16:
xorl %edx, %edx # Clear %edx before divide
div %cx
.L${opcode}_finish:
SET_VREG $result, rINST
mov LOCAL0(%esp), rIBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2