This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: I386 strlen "fix" (giveup)


On Mon, Mar 06, 2000 at 09:39:05PM +0100, Jan Hubicka wrote:
> This patch fixes and disables the problematic piece of code in i386.md
> Maybe someone else will be able to add the necesary functionality.

I believe this will do the job. 

I'm still not quite able to bootstrap, but the entire diff between a
working and non-working compiler is

@@ -1494,7 +1494,7 @@ gendecl:
        cmpb    $48, %al
        je      .L72
        movsbl  (%ebx),%eax
-       subl    $12, %esp
+       addl    $4, %esp
        pushl   %eax
        call    type_from_format
        addl    $4, %esp

which is suggestive of stack alignment rather than strlen. 


r~


	* builtins.c (expand_builtin_strlen): Be prepared for strlensi
	to fail.

	* i386.md (strlensi): Initialize eoschar and align before use.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.c,v
retrieving revision 1.33
diff -c -p -d -r1.33 builtins.c
*** builtins.c	2000/03/06 18:03:54	1.33
--- builtins.c	2000/03/08 02:11:25
*************** expand_builtin_strlen (exp, target, mode
*** 1334,1346 ****
      return 0;
    else
      {
        tree src = TREE_VALUE (arglist);
        tree len = c_strlen (src);
  
        int align
  	= get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
  
!       rtx result, src_rtx, char_rtx;
        enum machine_mode insn_mode = value_mode, char_mode;
        enum insn_code icode = CODE_FOR_nothing;
  
--- 1334,1347 ----
      return 0;
    else
      {
+       rtx pat;
        tree src = TREE_VALUE (arglist);
        tree len = c_strlen (src);
  
        int align
  	= get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
  
!       rtx result, src_rtx, src_mem, char_rtx;
        enum machine_mode insn_mode = value_mode, char_mode;
        enum insn_code icode = CODE_FOR_nothing;
  
*************** expand_builtin_strlen (exp, target, mode
*** 1365,1370 ****
--- 1366,1373 ----
        if (insn_mode == VOIDmode)
  	return 0;
  
+       start_sequence ();
+ 
        /* Make a place to write the result of the instruction.  */
        result = target;
        if (! (result != 0
*************** expand_builtin_strlen (exp, target, mode
*** 1377,1388 ****
  
        if (! (*insn_data[(int)icode].operand[0].predicate) (result, insn_mode))
  	result = gen_reg_rtx (insn_mode);
-       src_rtx = memory_address (BLKmode,
- 				expand_expr (src, NULL_RTX, ptr_mode,
- 					     EXPAND_NORMAL));
  
!       if (! (*insn_data[(int)icode].operand[1].predicate) (src_rtx, Pmode))
! 	src_rtx = copy_to_mode_reg (Pmode, src_rtx);
  
        /* Check the string is readable and has an end.  */
        if (current_function_check_memory_usage)
--- 1380,1388 ----
  
        if (! (*insn_data[(int)icode].operand[0].predicate) (result, insn_mode))
  	result = gen_reg_rtx (insn_mode);
  
!       src_mem = get_memory_rtx (src);
!       src_rtx = XEXP (src_mem, 0);
  
        /* Check the string is readable and has an end.  */
        if (current_function_check_memory_usage)
*************** expand_builtin_strlen (exp, target, mode
*** 1396,1415 ****
        if (! (*insn_data[(int)icode].operand[2].predicate) (char_rtx, char_mode))
  	char_rtx = copy_to_mode_reg (char_mode, char_rtx);
  
!       emit_insn (GEN_FCN (icode) (result,
! 				  gen_rtx_MEM (BLKmode, src_rtx),
! 				  char_rtx, GEN_INT (align)));
  
        /* Return the value in the proper mode for this function.  */
        if (GET_MODE (result) == value_mode)
! 	return result;
        else if (target != 0)
! 	{
! 	  convert_move (target, result, 0);
! 	  return target;
! 	}
        else
! 	return convert_to_mode (value_mode, result, 0);
      }
  }
  
--- 1396,1422 ----
        if (! (*insn_data[(int)icode].operand[2].predicate) (char_rtx, char_mode))
  	char_rtx = copy_to_mode_reg (char_mode, char_rtx);
  
!       pat = GEN_FCN (icode) (result, src_mem, char_rtx, GEN_INT (align));
!       if (! pat)
! 	{
! 	  end_sequence ();
! 	  return 0;
! 	}
!       emit_insn (pat);
  
        /* Return the value in the proper mode for this function.  */
        if (GET_MODE (result) == value_mode)
! 	target = result;
        else if (target != 0)
! 	convert_move (target, result, 0);
        else
! 	target = convert_to_mode (value_mode, result, 0);
! 
!       pat = gen_sequence ();
!       end_sequence ();
!       emit_insn (pat);
! 
!       return target;
      }
  }
  
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.140
diff -c -p -d -r1.140 i386.md
*** i386.md	2000/03/01 11:15:52	1.140
--- i386.md	2000/03/08 02:11:26
***************
*** 8591,8597 ****
    ""
    "
  {
!   rtx out, addr, eoschar, align, scratch1, scratch2, scratch3;
  
    /* The generic case of strlen expander is long.  Avoid it's
       expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
--- 8591,8599 ----
    ""
    "
  {
!   rtx out, addr, scratch1, scratch2, scratch3;
!   rtx eoschar = operands[2];
!   rtx align = operands[3];
  
    /* The generic case of strlen expander is long.  Avoid it's
       expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
***************
*** 8603,8610 ****
  
    out = operands[0];
    addr = force_reg (Pmode, XEXP (operands[1], 0));
-   eoschar = operands[2];
-   align = operands[3];
    scratch1 = gen_reg_rtx (SImode);
  
    if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
--- 8605,8610 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]