diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeb15c44913..b9f0d3632fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-07-23 Steve Ellcey + + * gcc/explow.c (convert_memory_address): Fix conversion of CONSTs. + Fix permutation of conversion and plus/mult. + * gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is + ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined. + (expand_builtin_strncpy) Ditto. + (expand_builtin_memset) Ditto. + 2002-07-23 Gabriel Dos Reis Fix PR/7363: diff --git a/gcc/builtins.c b/gcc/builtins.c index 457067649c0..1c8e8a8ea4d 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1981,7 +1981,12 @@ expand_builtin_memcpy (arglist, target, mode) store_by_pieces (dest_mem, INTVAL (len_rtx), builtin_memcpy_read_str, (PTR) src_str, dest_align); - return force_operand (XEXP (dest_mem, 0), NULL_RTX); + dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_mem) != ptr_mode) + dest_mem = convert_memory_address (ptr_mode, dest_mem); +#endif + return dest_mem; } src_mem = get_memory_rtx (src); @@ -1991,7 +1996,13 @@ expand_builtin_memcpy (arglist, target, mode) dest_addr = emit_block_move (dest_mem, src_mem, len_rtx); if (dest_addr == 0) - dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); + { + dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_addr) != ptr_mode) + dest_addr = convert_memory_address (ptr_mode, dest_addr); +#endif + } return dest_addr; } @@ -2107,7 +2118,12 @@ expand_builtin_strncpy (arglist, target, mode) store_by_pieces (dest_mem, tree_low_cst (len, 1), builtin_strncpy_read_str, (PTR) p, dest_align); - return force_operand (XEXP (dest_mem, 0), NULL_RTX); + dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_mem) != ptr_mode) + dest_mem = convert_memory_address (ptr_mode, dest_mem); +#endif + return dest_mem; } /* OK transform into builtin memcpy. */ @@ -2232,7 +2248,12 @@ expand_builtin_memset (exp, target, mode) store_by_pieces (dest_mem, tree_low_cst (len, 1), builtin_memset_gen_str, (PTR)val_rtx, dest_align); - return force_operand (XEXP (dest_mem, 0), NULL_RTX); + dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_mem) != ptr_mode) + dest_mem = convert_memory_address (ptr_mode, dest_mem); +#endif + return dest_mem; } if (target_char_cast (val, &c)) @@ -2251,7 +2272,12 @@ expand_builtin_memset (exp, target, mode) store_by_pieces (dest_mem, tree_low_cst (len, 1), builtin_memset_read_str, (PTR) &c, dest_align); - return force_operand (XEXP (dest_mem, 0), NULL_RTX); + dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_mem) != ptr_mode) + dest_mem = convert_memory_address (ptr_mode, dest_mem); +#endif + return dest_mem; } len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); @@ -2261,7 +2287,13 @@ expand_builtin_memset (exp, target, mode) dest_addr = clear_storage (dest_mem, len_rtx); if (dest_addr == 0) - dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); + { + dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (dest_addr) != ptr_mode) + dest_addr = convert_memory_address (ptr_mode, dest_addr); +#endif + } return dest_addr; } diff --git a/gcc/explow.c b/gcc/explow.c index 13a7b82be5b..3cda4104672 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -353,6 +353,7 @@ convert_memory_address (to_mode, x) { enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode; rtx temp; + enum rtx_code code; /* Here we handle some special cases. If none of them apply, fall through to the default case. */ @@ -360,7 +361,18 @@ convert_memory_address (to_mode, x) { case CONST_INT: case CONST_DOUBLE: - return x; + if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)) + code = TRUNCATE; + else if (POINTERS_EXTEND_UNSIGNED < 0) + break; + else if (POINTERS_EXTEND_UNSIGNED > 0) + code = ZERO_EXTEND; + else + code = SIGN_EXTEND; + temp = simplify_unary_operation (code, to_mode, x, from_mode); + if (temp) + return temp; + break; case SUBREG: if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x))) @@ -389,17 +401,17 @@ convert_memory_address (to_mode, x) case PLUS: case MULT: - /* For addition the second operand is a small constant, we can safely - permute the conversion and addition operation. We can always safely - permute them if we are making the address narrower. In addition, - always permute the operations if this is a constant. */ - if ((GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) - || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT - && (INTVAL (XEXP (x, 1)) + 20000 < 40000 - || CONSTANT_P (XEXP (x, 0)))))) + /* For addition we can safely permute the conversion and addition + operation if one operand is a constant and converting the constant + does not change it. We can always safely permute them if we are + making the address narrower. */ + if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) + || (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == CONST_INT + && XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1)))) return gen_rtx_fmt_ee (GET_CODE (x), to_mode, convert_memory_address (to_mode, XEXP (x, 0)), - convert_memory_address (to_mode, XEXP (x, 1))); + XEXP (x, 1)); break; default: