From: Richard Henderson Date: Wed, 8 Mar 2000 19:21:13 +0000 (-0800) Subject: builtins.c (expand_builtin_strlen): Be prepared for strlensi to fail. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dd05e4fae90b9f885f20217bd5b18ed13030314c;p=gcc.git builtins.c (expand_builtin_strlen): Be prepared for strlensi to fail. * builtins.c (expand_builtin_strlen): Be prepared for strlensi to fail. Don't pre-expand the source operand. From-SVN: r32429 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b36c413815..b3a8130d86c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-03-08 Richard Henderson + + * builtins.c (expand_builtin_strlen): Be prepared for strlensi + to fail. Don't pre-expand the source operand. + + * i386.md (strlensi): Initialize eoschar and align before use. + 2000-03-08 Jason Merrill * expr.c (expand_expr, case ARRAY_REF): Still check for missing diff --git a/gcc/builtins.c b/gcc/builtins.c index a38f3c4b861..c75d2fb44ae 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1334,13 +1334,14 @@ expand_builtin_strlen (exp, target, mode) 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, char_rtx; + rtx result, src_reg, char_rtx, before_strlen; enum machine_mode insn_mode = value_mode, char_mode; enum insn_code icode = CODE_FOR_nothing; @@ -1352,8 +1353,7 @@ expand_builtin_strlen (exp, target, mode) if (align == 0) return 0; - /* Call a function if we can't compute strlen in the right mode. */ - + /* Bail out if we can't compute strlen in the right mode. */ while (insn_mode != VOIDmode) { icode = strlen_optab->handlers[(int) insn_mode].insn_code; @@ -1373,21 +1373,19 @@ expand_builtin_strlen (exp, target, mode) && REGNO (result) >= FIRST_PSEUDO_REGISTER)) result = gen_reg_rtx (insn_mode); - /* Make sure the operands are acceptable to the predicates. */ - - 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)); + /* Make a place to hold the source address. We will not expand + the actual source until we are sure that the expansion will + not fail -- there are trees that cannot be expanded twice. */ + src_reg = gen_reg_rtx (Pmode); - if (! (*insn_data[(int)icode].operand[1].predicate) (src_rtx, Pmode)) - src_rtx = copy_to_mode_reg (Pmode, src_rtx); + /* Mark the beginning of the strlen sequence so we can emit the + source operand later. */ + before_strlen = get_last_insn(); /* Check the string is readable and has an end. */ if (current_function_check_memory_usage) emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2, - src_rtx, Pmode, + src_reg, Pmode, GEN_INT (MEMORY_USE_RO), TYPE_MODE (integer_type_node)); @@ -1396,20 +1394,30 @@ expand_builtin_strlen (exp, target, mode) 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))); + pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg), + char_rtx, GEN_INT (align)); + if (! pat) + return 0; + emit_insn (pat); + + /* Now that we are assured of success, expand the source. */ + start_sequence (); + pat = expand_expr (src, src_reg, ptr_mode, EXPAND_SUM); + if (pat != src_reg) + emit_move_insn (src_reg, pat); + pat = gen_sequence (); + end_sequence (); + emit_insn_after (pat, before_strlen); /* Return the value in the proper mode for this function. */ if (GET_MODE (result) == value_mode) - return result; + target = result; else if (target != 0) - { - convert_move (target, result, 0); - return target; - } + convert_move (target, result, 0); else - return convert_to_mode (value_mode, result, 0); + target = convert_to_mode (value_mode, result, 0); + + return target; } }