This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to allow strlen expander to fail
Hi
This patch adds the strlen libcall and necesary code to emit_builtin_strlen
to emit libcall when strlen expander fails.
This avoids problems with expr expanded twice.
Together with the strlensi patch it ought to make gcc to deal sanely
with strlen on i386.
Honza
Sat Aug 5 18:10:24 CET 2000 Jan Hubicka <jh@suse.cz>
* optabs.c (init_optabs): Add strlen_libfunc.
* expr.h (enum libfunc_index): Add LTI_strlen
(strlen_libfunc): Nef macro.
* builtins.c (expand_builtin_strlen): Use libcall when
strlen expander failed.
*** optabs.c.old Sun Mar 5 17:21:52 2000
--- optabs.c Sun Mar 5 17:22:08 2000
*************** init_optabs ()
*** 4664,4669 ****
--- 4664,4670 ----
bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
memset_libfunc = init_one_libfunc ("memset");
bzero_libfunc = init_one_libfunc ("bzero");
+ strlen_libfunc = init_one_libfunc ("strlen");
throw_libfunc = init_one_libfunc ("__throw");
rethrow_libfunc = init_one_libfunc ("__rethrow");
*** expr.h.old Sun Mar 5 17:20:59 2000
--- expr.h Sun Mar 5 17:21:36 2000
*************** enum libfunc_index
*** 483,488 ****
--- 483,489 ----
LTI_bcmp,
LTI_memset,
LTI_bzero,
+ LTI_strlen,
LTI_throw,
LTI_rethrow,
*************** extern rtx libfunc_table[LTI_MAX];
*** 616,621 ****
--- 617,623 ----
#define bcmp_libfunc (libfunc_table[LTI_bcmp])
#define memset_libfunc (libfunc_table[LTI_memset])
#define bzero_libfunc (libfunc_table[LTI_bzero])
+ #define strlen_libfunc (libfunc_table[LTI_strlen])
#define throw_libfunc (libfunc_table[LTI_throw])
#define rethrow_libfunc (libfunc_table[LTI_rethrow])
*** builtins.c.old Sun Mar 5 16:25:22 2000
--- builtins.c Sun Mar 5 17:56:32 2000
*************** expand_builtin_strlen (exp, target, mode
*** 1299,1304 ****
--- 1299,1305 ----
return 0;
else
{
+ rtx pat;
tree src = TREE_VALUE (arglist);
tree len = c_strlen (src);
*************** expand_builtin_strlen (exp, target, mode
*** 1342,1354 ****
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)
--- 1343,1349 ----
if (! (*insn_data[(int)icode].operand[0].predicate) (result, insn_mode))
result = gen_reg_rtx (insn_mode);
! src_rtx = get_memory_rtx (src);
/* Check the string is readable and has an end. */
if (current_function_check_memory_usage)
*************** expand_builtin_strlen (exp, target, mode
*** 1362,1370 ****
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)
--- 1357,1371 ----
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,
! gen_rtx_MEM (BLKmode, src_rtx),
! char_rtx, GEN_INT (align));
! if (pat)
! emit_insn (pat);
! else
! emit_library_call_value (strlen_libfunc, result, 0,
! value_mode, 1,
! XEXP (src_rtx, 0), Pmode);
/* Return the value in the proper mode for this function. */
if (GET_MODE (result) == value_mode)