Commits

Anonymous committed 5c38325

emit_alpha: on gratte un cycle sur le Lswitch a 3 cas.
emit_sparc: bug dans le transfert reg flottant -> regs entiers non alignes.
emit_i386: faire pop apres l'appel d'une fonction C retournant un flottant;
optimisation cmpl $0 -> testl
proc_i386: plus de contraintes sur div et mod.

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@175f963ae5c-01c2-4b8c-9fe0-0dff7051ff02

Comments (0)

Files changed (4)

asmcomp/emit_alpha.mlp

         begin match Array.length jumptbl with
           3 ->
             (* Should eliminate the branches that just fall through *)
-            `	subq	{emit_reg i.arg.(0)}, 1, $25\n`;
-            `	blt	$25, {emit_label jumptbl.(0)}\n`;
-            `	beq	$25, {emit_label jumptbl.(1)}\n`;
+            `	beq	{emit_reg i.arg.(0)}, {emit_label jumptbl.(0)}\n`;
+            `	blbs	{emit_reg i.arg.(0)}, {emit_label jumptbl.(1)}\n`;
             `	br	{emit_label jumptbl.(2)}\n`
         | 4 ->
             `	beq	{emit_reg i.arg.(0)}, {emit_label jumptbl.(0)}\n`;

asmcomp/emit_i386.mlp

   | Iunsigned Cle -> "be"  | Iunsigned Cgt -> "a"
   | Iunsigned Clt -> "b"  | Iunsigned Cge -> "ae"
     
+(* Output a comparison with a constant *)
+
+let output_comparison arg n =
+  match arg.loc with
+    Reg r when n = 0 -> `	testl	{emit_reg arg}, {emit_reg arg}\n`
+  | _                -> `	cmpl	${emit_int n}, {emit_reg arg}\n`
+
 (* Output the assembly code for an instruction *)
 
 (* Name of current function *)
           record_frame i.live
         end else begin
           `	call	{emit_symbol s}\n`
-        end
+        end;
+        if Array.length i.res > 0 & i.res.(0).typ = Float then
+          `	fstpl	{emit_shift i.res.(0)}\n`
     | Lop(Istackoffset n) ->
         if n >= 0
         then `	subl	${emit_int n}, %esp\n`
           `	cmpl	_young_start, %eax\n`;
           let lbl_cont = record_frame_label i.live in
           `	jae	{emit_label lbl_cont}\n`;
-          `	movl	${emit_int n}, %eax\n`;
           `	call	_caml_call_gc\n`;
+          `	.word	{emit_int n}\n`;
           `{emit_label lbl_cont}:	leal	4(%eax), {emit_reg i.res.(0)}\n`
         end else begin
           begin match n with
         `	set{emit_string b}	%al\n`;
         `	movzbl	%al, {emit_reg i.res.(0)}\n`
     | Lop(Iintop_imm(Icomp cmp, n)) ->
-        `	cmpl	${emit_int n}, {emit_reg i.arg.(0)}\n`;
+        output_comparison i.arg.(0) n;
         let b = name_for_cond_branch cmp in
         `	set{emit_string b}	%al\n`;
         `	movzbl	%al, {emit_reg i.res.(0)}\n`
     | Lcondbranch(tst, lbl) ->
         begin match tst with
           Itruetest ->
-            `	cmpl	$0, {emit_reg i.arg.(0)}\n`;
+            output_comparison i.arg.(0) 0;
             `	jne	{emit_label lbl}\n`
         | Ifalsetest ->
-            `	cmpl	$0, {emit_reg i.arg.(0)}\n`;
+            output_comparison i.arg.(0) 0;
             `	je	{emit_label lbl}\n`
         | Iinttest cmp ->
             `	cmpl	{emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
             let b = name_for_cond_branch cmp in
             `	j{emit_string b}	{emit_label lbl}\n`
         | Iinttest_imm(cmp, n) ->
-            `	cmpl	${emit_int n}, {emit_reg i.arg.(0)}\n`;
+            output_comparison i.arg.(0) n;
             let b = name_for_cond_branch cmp in
             `	j{emit_string b}	{emit_label lbl}\n`
         | Ifloattest cmp ->

asmcomp/emit_sparc.mlp

                 `	ldd	[%sp + 96], {emit_reg dst}\n`
               else begin
                 `	ld	[%sp + 96], {emit_reg dst}\n`;
-                `	ld	[%sp + 96], {emit_reg(next_in_pair dst)}\n`
+                `	ld	[%sp + 100], {emit_reg(next_in_pair dst)}\n`
               end;
               `	add	%sp, 8, %sp\n`
           | {loc = Reg rs; typ = (Int | Addr)}, {loc = Stack sd} ->

asmcomp/proc_i386.ml

     (* For shifts with variable shift count, second arg must be in ecx *)
   | Iintop(Ilsl|Ilsr|Iasr) ->
       ([|res.(0); phys_reg 2|], res)
-    (* For div and mod, first arg must be in eax, result is in eax or edx *)
+    (* For div and mod, first arg must be in eax, edx is clobbered,
+       and result is in eax or edx respectively.
+       Keep it simple, just force second argument in ecx. *)
   | Iintop(Idiv) ->
-      ([|phys_reg 0; arg.(1)|], [|phys_reg 0|])
+      ([|phys_reg 0; phys_reg 2|], [|phys_reg 0|])
   | Iintop(Imod) ->
-      ([|phys_reg 0; arg.(1)|], [|phys_reg 3|])
+      ([|phys_reg 0; phys_reg 2|], [|phys_reg 3|])
     (* For storing a byte, the argument must be in eax...edx.
        For storing a halfword, any reg is ok.
        Keep it simple, just force it to be in edx in both cases. *)