0

For a simple test case for my compiler project, I'm trying to divide 88 by 11, but when I call idivq my program throws a Floating Point Exception. Here is the relevant section of generated code where the exception occurs:

# push 88
movq $88,%r10

# push 11
movq $11,%r13

# \
movq  %r10,%rax
idivq %r13

I have looked up examples of how to use div, and I thought I was following the same format, so I don't understand why I am getting an exception.

nrz
  • 10,435
  • 4
  • 39
  • 71
Otto45
  • 555
  • 2
  • 6
  • 20
  • Possible duplicate of http://stackoverflow.com/questions/10343155/x86-assembly-handling-the-idiv-instruction – Leeor Nov 16 '13 at 22:19
  • Your idivq divides rdx:rax by r13. Not setting rdx can easily cause the #DE trap. How that produces a "floating point exception" is hard to guess. – Hans Passant Nov 16 '13 at 22:19

1 Answers1

4

idiv concatenates rdx and rax before performing the division (that is, it is actually 128-bit division). If you want to do single-word division, put a zero in rdx. What you're getting is not an FP exception, but an integer overflow exception: there's something left over in rdx which is making the quotient too big to fit in the destination register.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Alright, that makes sense from the documents I read. Thank you – Otto45 Nov 16 '13 at 22:57
  • 1
    `idiv` is signed division, so zeroing `rdx` is only correct if the dividend is positive. In general, `rax` needs to be sign extended into `rdx` (with say, `movq %rax,%rdx/sarq $63, %rdx`). – gsg Nov 17 '13 at 11:09
  • 1
    @gsg: actually there's [`CQO`](http://siyobik.info.gf/main/reference/instruction/CWD%2FCDQ%2FCQO) for just this purpose. – Igor Skochinsky Nov 18 '13 at 12:09
  • @IgorSkochinsky yes, although compilers seem to prefer `movq/sarq` – gsg Nov 18 '13 at 12:28
  • 1
    Might be worth it to submit a "missed optimization" bug report then :) – Igor Skochinsky Nov 18 '13 at 12:33