summaryrefslogtreecommitdiff
path: root/ia32/PrintAsm.ml
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2011-08-27 07:15:26 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2011-08-27 07:15:26 +0000
commite8bd77565422ab8e6d2fdd4ec7d5e7e4916ff2bd (patch)
tree18b2a9efc754ba386781896dee70971a7f8f1806 /ia32/PrintAsm.ml
parentca0117ca268873766ac4fda3771295842b17fcd6 (diff)
Watch out for min_int / -1
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1727 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'ia32/PrintAsm.ml')
-rw-r--r--ia32/PrintAsm.ml12
1 files changed, 11 insertions, 1 deletions
diff --git a/ia32/PrintAsm.ml b/ia32/PrintAsm.ml
index e1f0911..ec3db77 100644
--- a/ia32/PrintAsm.ml
+++ b/ia32/PrintAsm.ml
@@ -559,8 +559,18 @@ let print_instruction oc = function
fprintf oc " xorl %%edx, %%edx\n";
fprintf oc " divl %a\n" ireg r1
| Pidiv(r1) ->
+ let lbl1 = new_label() in
+ let lbl2 = new_label() in
+ fprintf oc " cmpl $-1, %a\n" ireg r1;
+ fprintf oc " je %a\n" label lbl1;
fprintf oc " cltd\n";
- fprintf oc " idivl %a\n" ireg r1
+ fprintf oc " idivl %a\n" ireg r1;
+ fprintf oc " jmp %a\n" label lbl2;
+ (* Division by -1 can cause an overflow trap if dividend = min_int.
+ Force x div (-1) = -x and x mod (-1) = 0. *)
+ fprintf oc "%a: negl %a\n" label lbl1 ireg EAX;
+ fprintf oc " xorl %a, %a\n" ireg EDX ireg EDX;
+ fprintf oc "%a:\n" label lbl2
| Pand_rr(rd, r1) ->
fprintf oc " andl %a, %a\n" ireg r1 ireg rd
| Pand_ri(rd, n) ->