Jan Hubicka <hubicka@freesoft.cz>
authorJan Hubicka <hubicka@freesoft.cz>
Sat, 2 Oct 1999 17:54:05 +0000 (19:54 +0200)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 2 Oct 1999 17:54:05 +0000 (10:54 -0700)
        * i386.md (ffs expander): Emit Pentium friendly code for
        TARGET_PENTIUM.

From-SVN: r29769

gcc/ChangeLog
gcc/config/i386/i386.md

index 62642b4..985c4c9 100644 (file)
@@ -1,3 +1,8 @@
+Sat Oct  2 10:53:22 1999  Jan Hubicka  <hubicka@freesoft.cz>
+
+       * i386.md (ffs expander): Emit Pentium friendly code for
+       TARGET_PENTIUM.
+
 Sat Oct  2 02:48:21 1999  Mark P. Mitchell  <mark@codesourcery.com>
 
        * tree.c (build): Don't look at TREE_SIDE_EFFECTS or TREE_RAISES 
index b2adc39..a8281cc 100644 (file)
                                const0_rtx),
                    tmp,
                    out)));
+      emit_insn (gen_addsi3 (out, out, const1_rtx));
+      emit_move_insn (operands[0], out);
+    }
+
+  /* Pentium bsf instruction is extremly slow.  Following code is recommended by
+     the Intel Optimizing Manual as resonable replacement:
+           TEST    EAX,EAX
+          JZ      SHORT BS2
+          XOR     ECX,ECX
+          MOV     DWORD PTR [TEMP+4],ECX
+          SUB     ECX,EAX
+          AND     EAX,ECX
+          MOV     DWORD PTR [TEMP],EAX
+          FILD    QWORD PTR [TEMP]
+          FSTP    QWORD PTR [TEMP]
+          WAIT    ; WAIT only needed for compatibility with
+                  ; earlier processors
+          MOV     ECX, DWORD PTR [TEMP+4]
+          SHR     ECX,20
+          SUB     ECX,3FFH
+          TEST    EAX,EAX       ; clear zero flag
+       BS2:
+     Following piece of code expand ffs to similar beast.
+       */
+
+  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
+    {
+      rtx label = gen_label_rtx ();
+      rtx lo, hi;
+      rtx mem = assign_386_stack_local (DImode, 0);
+      rtx fptmp = gen_reg_rtx (DFmode);
+      split_di (&mem, 1, &lo, &hi);
+
+      emit_move_insn (out, const0_rtx);
+
+      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
+
+      emit_move_insn (hi, out);
+      emit_insn (gen_subsi3 (out, out, in));
+      emit_insn (gen_andsi3 (out, out, in));
+      emit_move_insn (lo, out);
+      emit_insn (gen_floatdidf2 (fptmp,mem));
+      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
+      emit_move_insn (out, hi);
+      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
+      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3fe)));
+
+      emit_label (label);
+      LABEL_NUSES (label) = 1;
+
+      emit_move_insn (operands[0], out);
     }
   else
     {
                              const0_rtx)));
       emit_insn (gen_negsi2 (tmp, tmp));
       emit_insn (gen_iorsi3 (out, out, tmp));
+      emit_insn (gen_addsi3 (out, out, const1_rtx));
+      emit_move_insn (operands[0], out);
     }
-  emit_insn (gen_addsi3 (out, out, const1_rtx));
-
-  emit_move_insn (operands[0], out);
   DONE;  
 }")