This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: I386 strlen "fix" (giveup)
- To: Jan Hubicka <hubicka at atrey dot karlin dot mff dot cuni dot cz>
- Subject: Re: I386 strlen "fix" (giveup)
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 7 Mar 2000 18:22:25 -0800
- Cc: egcs-patches at egcs dot cygnus dot com
- References: <20000306213905.A11541@atrey.karlin.mff.cuni.cz>
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 ----