summaryrefslogtreecommitdiff
path: root/ia32/PrintAsm.ml
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2011-08-10 11:29:04 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2011-08-10 11:29:04 +0000
commitfd0f28867db2f183216b27d7030265ae9e887586 (patch)
treee3418d4c8e15ecb8329e35995773e414f200072a /ia32/PrintAsm.ml
parent4caa6402f1f2749b23c68338c98265db88be3c52 (diff)
IA32 PrintAsm.ml: wrong moves generated in print_builtin_memcpy_big
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1706 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'ia32/PrintAsm.ml')
-rw-r--r--ia32/PrintAsm.ml28
1 files changed, 20 insertions, 8 deletions
diff --git a/ia32/PrintAsm.ml b/ia32/PrintAsm.ml
index a6369c4..63658e5 100644
--- a/ia32/PrintAsm.ml
+++ b/ia32/PrintAsm.ml
@@ -306,17 +306,29 @@ let print_builtin_memcpy_small oc sz al src dst =
if need_tmp && tmp = EAX then
fprintf oc " popl %a\n" ireg EAX
+let print_mov2 oc src1 dst1 src2 dst2 =
+ if src1 = dst1 then
+ if src2 = dst2
+ then ()
+ else fprintf oc " movl %a, %a\n" ireg src2 ireg dst2
+ else if src2 = dst2 then
+ fprintf oc " movl %a, %a\n" ireg src1 ireg dst1
+ else if src2 = dst1 then
+ if src1 = dst2 then
+ fprintf oc " xchgl %a, %a\n" ireg src1 ireg src2
+ else begin
+ fprintf oc " movl %a, %a\n" ireg src2 ireg dst2;
+ fprintf oc " movl %a, %a\n" ireg src1 ireg dst1
+ end
+ else begin
+ fprintf oc " movl %a, %a\n" ireg src1 ireg dst1;
+ fprintf oc " movl %a, %a\n" ireg src2 ireg dst2
+ end
+
let print_builtin_memcpy_big oc sz al src dst =
fprintf oc " pushl %a\n" ireg ESI;
fprintf oc " pushl %a\n" ireg EDI;
- begin match src, dst with
- | ESI, EDI -> ()
- | EDI, ESI -> fprintf oc " xchgl %a, %a\n" ireg ESI ireg EDI
- | ESI, _ -> fprintf oc " movl %a, %a\n" ireg dst ireg EDI
- | _, EDI -> fprintf oc " movl %a, %a\n" ireg src ireg ESI
- | _, _ -> fprintf oc " movl %a, %a\n" ireg src ireg ESI;
- fprintf oc " movl %a, %a\n" ireg dst ireg EDI
- end;
+ print_mov2 oc src ESI dst EDI;
fprintf oc " movl $%d, %a\n" (sz / 4) ireg ECX;
fprintf oc " rep movsl\n";
if sz mod 4 >= 2 then fprintf oc " movsw\n";