aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/asan.c2
-rw-r--r--gcc/builtins.c73
-rw-r--r--gcc/expr.c53
-rw-r--r--gcc/expr.h2
-rw-r--r--gcc/rtl.h17
6 files changed, 107 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d8e374f..b539e13 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,31 @@
+2018-11-27 Martin Liska <mliska@suse.cz>
+
+ * asan.c (asan_emit_stack_protection): Use new enum values
+ instead of int constants.
+ * builtins.c (expand_builtin_memory_copy_args): Replace int
+ type with memop_ret enum type.
+ (expand_builtin_mempcpy_args): Likewise.
+ (expand_builtin_memcpy): Use new enum values
+ instead of int constants. Likewise.
+ (expand_builtin_mempcpy): Likewise.
+ (expand_movstr): Likewise.
+ (expand_builtin_strcpy_args): Likewise.
+ (expand_builtin_stpcpy_1): Likewise.
+ (expand_builtin_strncpy): Likewise.
+ (expand_builtin_memset_args): Likewise.
+ * expr.c (move_by_pieces_d::finish_endp): Rename to ...
+ (move_by_pieces_d::finish_retmode): ... this.
+ (move_by_pieces): Change last argument type to memop_ret.
+ (store_by_pieces): Use new enum values
+ instead of int constants.
+ (emit_block_move_hints): Likewise.
+ (emit_push_insn): Likewise.
+ (store_expr): Likewise.
+ * expr.h (store_by_pieces): Change int to newly added enum
+ type.
+ * rtl.h (enum memop_ret): Define.
+ (move_by_pieces): Use the enum type.
+
2018-11-27 Alan Modra <amodra@gmail.com>
* config/rs6000/aix71.h (ASM_SPEC): Don't select default -maix64
diff --git a/gcc/asan.c b/gcc/asan.c
index b2c4118..45906bf 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1484,7 +1484,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
&& can_store_by_pieces (sz, builtin_memset_read_str, &c,
BITS_PER_UNIT, true))
store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
- BITS_PER_UNIT, true, 0);
+ BITS_PER_UNIT, true, RETURN_BEGIN);
else if (use_after_return_class >= 5
|| !set_storage_via_setmem (shadow_mem,
GEN_INT (sz),
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ebde2db..dcac49d 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -126,10 +126,11 @@ static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, scalar_int_mode);
static rtx expand_builtin_memchr (tree, rtx);
static rtx expand_builtin_memcpy (tree, rtx);
static rtx expand_builtin_memory_copy_args (tree dest, tree src, tree len,
- rtx target, tree exp, int endp);
+ rtx target, tree exp,
+ memop_ret retmode);
static rtx expand_builtin_memmove (tree, rtx);
static rtx expand_builtin_mempcpy (tree, rtx);
-static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, int);
+static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, memop_ret);
static rtx expand_builtin_strcat (tree, rtx);
static rtx expand_builtin_strcpy (tree, rtx);
static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx);
@@ -3751,7 +3752,7 @@ expand_builtin_memcpy (tree exp, rtx target)
check_memop_access (exp, dest, src, len);
return expand_builtin_memory_copy_args (dest, src, len, target, exp,
- /*endp=*/ 0);
+ /*retmode=*/ RETURN_BEGIN);
}
/* Check a call EXP to the memmove built-in for validity.
@@ -3776,10 +3777,7 @@ expand_builtin_memmove (tree exp, rtx)
/* Expand a call EXP to the mempcpy builtin.
Return NULL_RTX if we failed; the caller should emit a normal call,
otherwise try to get the result in TARGET, if convenient (and in
- mode MODE if that's convenient). If ENDP is 0 return the
- destination pointer, if ENDP is 1 return the end pointer ala
- mempcpy, and if ENDP is 2 return the end pointer minus one ala
- stpcpy. */
+ mode MODE if that's convenient). */
static rtx
expand_builtin_mempcpy (tree exp, rtx target)
@@ -3812,20 +3810,17 @@ expand_builtin_mempcpy (tree exp, rtx target)
return NULL_RTX;
return expand_builtin_mempcpy_args (dest, src, len,
- target, exp, /*endp=*/ 1);
+ target, exp, /*retmode=*/ RETURN_END);
}
/* Helper function to do the actual work for expand of memory copy family
functions (memcpy, mempcpy, stpcpy). Expansing should assign LEN bytes
- of memory from SRC to DEST and assign to TARGET if convenient.
- If ENDP is 0 return the
- destination pointer, if ENDP is 1 return the end pointer ala
- mempcpy, and if ENDP is 2 return the end pointer minus one ala
- stpcpy. */
+ of memory from SRC to DEST and assign to TARGET if convenient. Return
+ value is based on RETMODE argument. */
static rtx
expand_builtin_memory_copy_args (tree dest, tree src, tree len,
- rtx target, tree exp, int endp)
+ rtx target, tree exp, memop_ret retmode)
{
const char *src_str;
unsigned int src_align = get_pointer_alignment (src);
@@ -3872,7 +3867,7 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
builtin_memcpy_read_str,
CONST_CAST (char *, src_str),
- dest_align, false, endp);
+ dest_align, false, retmode);
dest_mem = force_operand (XEXP (dest_mem, 0), target);
dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
@@ -3883,9 +3878,10 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
/* Copy word part most expediently. */
enum block_op_methods method = BLOCK_OP_NORMAL;
- if (CALL_EXPR_TAILCALL (exp) && (endp == 0 || target == const0_rtx))
+ if (CALL_EXPR_TAILCALL (exp)
+ && (retmode == RETURN_BEGIN || target == const0_rtx))
method = BLOCK_OP_TAILCALL;
- if (endp == 1 && target != const0_rtx)
+ if (retmode == RETURN_END && target != const0_rtx)
method = BLOCK_OP_NO_LIBCALL_RET;
dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method,
expected_align, expected_size,
@@ -3899,11 +3895,11 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
dest_addr = convert_memory_address (ptr_mode, dest_addr);
}
- if (endp && target != const0_rtx)
+ if (retmode != RETURN_BEGIN && target != const0_rtx)
{
dest_addr = gen_rtx_PLUS (ptr_mode, dest_addr, len_rtx);
/* stpcpy pointer to last byte. */
- if (endp == 2)
+ if (retmode == RETURN_END_MINUS_ONE)
dest_addr = gen_rtx_MINUS (ptr_mode, dest_addr, const1_rtx);
}
@@ -3912,21 +3908,19 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
static rtx
expand_builtin_mempcpy_args (tree dest, tree src, tree len,
- rtx target, tree orig_exp, int endp)
+ rtx target, tree orig_exp, memop_ret retmode)
{
return expand_builtin_memory_copy_args (dest, src, len, target, orig_exp,
- endp);
+ retmode);
}
/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
we failed, the caller should emit a normal call, otherwise try to
- get the result in TARGET, if convenient. If ENDP is 0 return the
- destination pointer, if ENDP is 1 return the end pointer ala
- mempcpy, and if ENDP is 2 return the end pointer minus one ala
- stpcpy. */
+ get the result in TARGET, if convenient.
+ Return value is based on RETMODE argument. */
static rtx
-expand_movstr (tree dest, tree src, rtx target, int endp)
+expand_movstr (tree dest, tree src, rtx target, memop_ret retmode)
{
struct expand_operand ops[3];
rtx dest_mem;
@@ -3937,25 +3931,25 @@ expand_movstr (tree dest, tree src, rtx target, int endp)
dest_mem = get_memory_rtx (dest, NULL);
src_mem = get_memory_rtx (src, NULL);
- if (!endp)
+ if (retmode != RETURN_BEGIN)
{
target = force_reg (Pmode, XEXP (dest_mem, 0));
dest_mem = replace_equiv_address (dest_mem, target);
}
- create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
+ create_output_operand (&ops[0], retmode ? target : NULL_RTX, Pmode);
create_fixed_operand (&ops[1], dest_mem);
create_fixed_operand (&ops[2], src_mem);
if (!maybe_expand_insn (targetm.code_for_movstr, 3, ops))
return NULL_RTX;
- if (endp && target != const0_rtx)
+ if (retmode != RETURN_BEGIN && target != const0_rtx)
{
target = ops[0].value;
/* movstr is supposed to set end to the address of the NUL
terminator. If the caller requested a mempcpy-like return value,
adjust it. */
- if (endp == 1)
+ if (retmode == RETURN_END)
{
rtx tem = plus_constant (GET_MODE (target),
gen_lowpart (GET_MODE (target), target), 1);
@@ -4044,7 +4038,7 @@ expand_builtin_strcpy_args (tree exp, tree dest, tree src, rtx target)
return NULL_RTX;
}
- return expand_movstr (dest, src, target, /*endp=*/0);
+ return expand_movstr (dest, src, target, /*retmode=*/ RETURN_BEGIN);
}
/* Expand a call EXP to the stpcpy builtin.
@@ -4091,14 +4085,16 @@ expand_builtin_stpcpy_1 (tree exp, rtx target, machine_mode mode)
memset (&data, 0, sizeof (c_strlen_data));
if (!c_getstr (src, NULL)
|| !(len = c_strlen (src, 0, &data, 1)))
- return expand_movstr (dst, src, target, /*endp=*/2);
+ return expand_movstr (dst, src, target,
+ /*retmode=*/ RETURN_END_MINUS_ONE);
if (data.decl && !TREE_NO_WARNING (exp))
warn_string_no_nul (EXPR_LOCATION (exp), "stpcpy", src, data.decl);
lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
ret = expand_builtin_mempcpy_args (dst, src, lenp1,
- target, exp, /*endp=*/2);
+ target, exp,
+ /*retmode=*/ RETURN_END_MINUS_ONE);
if (ret)
return ret;
@@ -4132,7 +4128,8 @@ expand_builtin_stpcpy_1 (tree exp, rtx target, machine_mode mode)
}
}
- return expand_movstr (dst, src, target, /*endp=*/2);
+ return expand_movstr (dst, src, target,
+ /*retmode=*/ RETURN_END_MINUS_ONE);
}
}
@@ -4378,7 +4375,8 @@ expand_builtin_strncpy (tree exp, rtx target)
dest_mem = get_memory_rtx (dest, len);
store_by_pieces (dest_mem, tree_to_uhwi (len),
builtin_strncpy_read_str,
- CONST_CAST (char *, p), dest_align, false, 0);
+ CONST_CAST (char *, p), dest_align, false,
+ RETURN_BEGIN);
dest_mem = force_operand (XEXP (dest_mem, 0), target);
dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
@@ -4523,7 +4521,7 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
val_rtx = force_reg (val_mode, val_rtx);
store_by_pieces (dest_mem, tree_to_uhwi (len),
builtin_memset_gen_str, val_rtx, dest_align,
- true, 0);
+ true, RETURN_BEGIN);
}
else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
dest_align, expected_align,
@@ -4546,7 +4544,8 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
builtin_memset_read_str, &c, dest_align,
true))
store_by_pieces (dest_mem, tree_to_uhwi (len),
- builtin_memset_read_str, &c, dest_align, true, 0);
+ builtin_memset_read_str, &c, dest_align, true,
+ RETURN_BEGIN);
else if (!set_storage_via_setmem (dest_mem, len_rtx,
gen_int_mode (c, val_mode),
dest_align, expected_align,
diff --git a/gcc/expr.c b/gcc/expr.c
index ef29ec5..85b7847 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1146,7 +1146,7 @@ class move_by_pieces_d : public op_by_pieces_d
: op_by_pieces_d (to, false, from, true, NULL, NULL, len, align)
{
}
- rtx finish_endp (int);
+ rtx finish_retmode (memop_ret);
};
/* Return true if MODE can be used for a set of copies, given an
@@ -1182,15 +1182,14 @@ move_by_pieces_d::generate (rtx op0, rtx op1,
}
/* Perform the final adjustment at the end of a string to obtain the
- correct return value for the block operation. If ENDP is 1 return
- memory at the end ala mempcpy, and if ENDP is 2 return memory the
- end minus one byte ala stpcpy. */
+ correct return value for the block operation.
+ Return value is based on RETMODE argument. */
rtx
-move_by_pieces_d::finish_endp (int endp)
+move_by_pieces_d::finish_retmode (memop_ret retmode)
{
gcc_assert (!m_reverse);
- if (endp == 2)
+ if (retmode == RETURN_END_MINUS_ONE)
{
m_to.maybe_postinc (-1);
--m_offset;
@@ -1206,13 +1205,11 @@ move_by_pieces_d::finish_endp (int endp)
ALIGN is maximum stack alignment we can assume.
- If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
- mempcpy, and if ENDP is 2 return memory the end minus one byte ala
- stpcpy. */
+ Return value is based on RETMODE argument. */
rtx
move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
- unsigned int align, int endp)
+ unsigned int align, memop_ret retmode)
{
#ifndef PUSH_ROUNDING
if (to == NULL)
@@ -1223,8 +1220,8 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
data.run ();
- if (endp)
- return data.finish_endp (endp);
+ if (retmode)
+ return data.finish_retmode (retmode);
else
return to;
}
@@ -1244,7 +1241,7 @@ class store_by_pieces_d : public op_by_pieces_d
: op_by_pieces_d (to, false, NULL_RTX, true, cfn, cfn_data, len, align)
{
}
- rtx finish_endp (int);
+ rtx finish_retmode (memop_ret);
};
/* Return true if MODE can be used for a set of stores, given an
@@ -1272,15 +1269,14 @@ store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
}
/* Perform the final adjustment at the end of a string to obtain the
- correct return value for the block operation. If ENDP is 1 return
- memory at the end ala mempcpy, and if ENDP is 2 return memory the
- end minus one byte ala stpcpy. */
+ correct return value for the block operation.
+ Return value is based on RETMODE argument. */
rtx
-store_by_pieces_d::finish_endp (int endp)
+store_by_pieces_d::finish_retmode (memop_ret retmode)
{
gcc_assert (!m_reverse);
- if (endp == 2)
+ if (retmode == RETURN_END_MINUS_ONE)
{
m_to.maybe_postinc (-1);
--m_offset;
@@ -1370,18 +1366,17 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
pointer which will be passed as argument in every CONSTFUN call.
ALIGN is maximum alignment we can assume. MEMSETP is true if this is
a memset operation and false if it's a copy of a constant string.
- If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
- mempcpy, and if ENDP is 2 return memory the end minus one byte ala
- stpcpy. */
+ Return value is based on RETMODE argument. */
rtx
store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
rtx (*constfun) (void *, HOST_WIDE_INT, scalar_int_mode),
- void *constfundata, unsigned int align, bool memsetp, int endp)
+ void *constfundata, unsigned int align, bool memsetp,
+ memop_ret retmode)
{
if (len == 0)
{
- gcc_assert (endp != 2);
+ gcc_assert (retmode != RETURN_END_MINUS_ONE);
return to;
}
@@ -1393,8 +1388,8 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
store_by_pieces_d data (to, constfun, constfundata, len, align);
data.run ();
- if (endp)
- return data.finish_endp (endp);
+ if (retmode)
+ return data.finish_retmode (retmode);
else
return to;
}
@@ -1624,7 +1619,7 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
}
if (CONST_INT_P (size) && can_move_by_pieces (INTVAL (size), align))
- move_by_pieces (x, y, INTVAL (size), align, 0);
+ move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
else if (emit_block_move_via_movmem (x, y, size, align,
expected_align, expected_size,
min_size, max_size, probable_max_size))
@@ -4421,7 +4416,8 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
&& where_pad != stack_direction)
anti_adjust_stack (gen_int_mode (extra, Pmode));
- move_by_pieces (NULL, xinner, INTVAL (size) - used, align, 0);
+ move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
+ RETURN_BEGIN);
}
else
#endif /* PUSH_ROUNDING */
@@ -5618,7 +5614,8 @@ store_expr (tree exp, rtx target, int call_param_p,
CONST_CAST (char *,
TREE_STRING_POINTER (str)),
MEM_ALIGN (target), false,
- exp_len > str_copy_len ? 1 : 0);
+ (exp_len > str_copy_len ? RETURN_END :
+ RETURN_BEGIN));
if (exp_len > str_copy_len)
clear_storage (adjust_address (dest_mem, BLKmode, 0),
GEN_INT (exp_len - str_copy_len),
diff --git a/gcc/expr.h b/gcc/expr.h
index 19028f0..6ae343d 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -219,7 +219,7 @@ extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
MEMSETP is true if this is a real memset/bzero, not a copy.
Returns TO + LEN. */
extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT, by_pieces_constfn,
- void *, unsigned int, bool, int);
+ void *, unsigned int, bool, memop_ret);
/* Emit insns to set X from Y. */
extern rtx_insn *emit_move_insn (rtx, rtx);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index dd3ce06..c2aaa9e 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -4046,9 +4046,24 @@ extern void expand_null_return (void);
extern void expand_naked_return (void);
extern void emit_jump (rtx);
+/* Memory operation built-ins differ by return value. Mapping
+ of the enum values is following:
+ - RETURN_BEGIN - return destination, e.g. memcpy
+ - RETURN_END - return destination + n, e.g. mempcpy
+ - RETURN_END_MINUS_ONE - return a pointer to the terminating
+ null byte of the string, e.g. strcpy
+*/
+
+enum memop_ret
+{
+ RETURN_BEGIN,
+ RETURN_END,
+ RETURN_END_MINUS_ONE
+};
+
/* In expr.c */
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
- unsigned int, int);
+ unsigned int, memop_ret);
extern poly_int64 find_args_size_adjust (rtx_insn *);
extern poly_int64 fixup_args_size_notes (rtx_insn *, rtx_insn *, poly_int64);