X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fexplow.c;h=719421f6cd6e70a25b69e262918cb68f043f56ff;hb=5bf4303e2b3e213e573bf72d7b7b05ad78e9b8bb;hp=b2763e3abf0349952b155208eea9cd6183d04c03;hpb=dea049dca0cc1d48b7d2c5d5b227a03f6972d556;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/explow.c b/gcc/explow.c index b2763e3abf0..719421f6cd6 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -56,28 +56,16 @@ trunc_int_for_mode (c, mode) if (mode == BImode) return c & 1 ? STORE_FLAG_VALUE : 0; - /* We clear out all bits that don't belong in MODE, unless they and our - sign bit are all one. So we get either a reasonable negative - value or a reasonable unsigned value. */ + /* Sign-extend for the requested mode. */ - if (width < HOST_BITS_PER_WIDE_INT - && ((c & ((HOST_WIDE_INT) (-1) << (width - 1))) - != ((HOST_WIDE_INT) (-1) << (width - 1)))) - c &= ((HOST_WIDE_INT) 1 << width) - 1; - - /* If this would be an entire word for the target, but is not for - the host, then sign-extend on the host so that the number will look - the same way on the host that it would on the target. - - For example, when building a 64 bit alpha hosted 32 bit sparc - targeted compiler, then we want the 32 bit unsigned value -1 to be - represented as a 64 bit value -1, and not as 0x00000000ffffffff. - The later confuses the sparc backend. */ - - if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT - && BITS_PER_WORD == width - && (c & ((HOST_WIDE_INT) 1 << (width - 1)))) - c |= ((HOST_WIDE_INT) (-1) << width); + if (width < HOST_BITS_PER_WIDE_INT) + { + HOST_WIDE_INT sign = 1; + sign <<= width - 1; + c &= (sign << 1) - 1; + c ^= sign; + c -= sign; + } return c; } @@ -129,15 +117,10 @@ plus_constant_wide (x, c) if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))) { - /* Any rtl we create here must go in a saveable obstack, since - we might have been called from within combine. */ - push_obstacks_nochange (); - rtl_in_saveable_obstack (); tem = force_const_mem (GET_MODE (x), plus_constant (get_pool_constant (XEXP (x, 0)), c)); - pop_obstacks (); if (memory_address_p (GET_MODE (tem), XEXP (tem, 0))) return tem; } @@ -391,6 +374,11 @@ convert_memory_address (to_mode, x) case CONST_DOUBLE: return x; + case SUBREG: + if (GET_MODE (SUBREG_REG (x)) == to_mode) + return SUBREG_REG (x); + break; + case LABEL_REF: temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0)); LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x); @@ -400,6 +388,7 @@ convert_memory_address (to_mode, x) temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0)); SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x); CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x); + STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x); return temp; case CONST: @@ -1298,15 +1287,10 @@ allocate_dynamic_stack_space (size, target, known_align) #endif if (MUST_ALIGN) - { - if (GET_CODE (size) == CONST_INT) - size = GEN_INT (INTVAL (size) - + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1)); - else - size = expand_binop (Pmode, add_optab, size, - GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1), - NULL_RTX, 1, OPTAB_LIB_WIDEN); - } + size + = force_operand (plus_constant (size, + BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1), + NULL_RTX); #ifdef SETJMP_VIA_SAVE_AREA /* If setjmp restores regs from a save area in the stack frame, @@ -1329,12 +1313,12 @@ allocate_dynamic_stack_space (size, target, known_align) #if !defined(PREFERRED_STACK_BOUNDARY) || !defined(MUST_ALIGN) || (PREFERRED_STACK_BOUNDARY != BIGGEST_ALIGNMENT) /* If anyone creates a target with these characteristics, let them know that our optimization cannot work correctly in such a case. */ - abort(); + abort (); #endif if (GET_CODE (size) == CONST_INT) { - int new = INTVAL (size) / align * align; + HOST_WIDE_INT new = INTVAL (size) / align * align; if (INTVAL (size) != new) setjmpless_size = GEN_INT (new); @@ -1399,9 +1383,10 @@ allocate_dynamic_stack_space (size, target, known_align) if (flag_stack_check && ! STACK_CHECK_BUILTIN) probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size); - /* Don't use a TARGET that isn't a pseudo. */ + /* Don't use a TARGET that isn't a pseudo or is the wrong mode. */ if (target == 0 || GET_CODE (target) != REG - || REGNO (target) < FIRST_PSEUDO_REGISTER) + || REGNO (target) < FIRST_PSEUDO_REGISTER + || GET_MODE (target) != Pmode) target = gen_reg_rtx (Pmode); mark_reg_pointer (target, known_align); @@ -1426,7 +1411,6 @@ allocate_dynamic_stack_space (size, target, known_align) if (mode == VOIDmode) mode = Pmode; - size = convert_modes (mode, ptr_mode, size, 1); pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate; if (pred && ! ((*pred) (size, mode))) size = copy_to_mode_reg (mode, size); @@ -1439,7 +1423,6 @@ allocate_dynamic_stack_space (size, target, known_align) #ifndef STACK_GROWS_DOWNWARD emit_move_insn (target, virtual_stack_dynamic_rtx); #endif - size = convert_modes (Pmode, ptr_mode, size, 1); /* Check stack bounds if necessary. */ if (current_function_limit_stack) @@ -1478,6 +1461,7 @@ allocate_dynamic_stack_space (size, target, known_align) REG_NOTES (note_target)); } #endif /* SETJMP_VIA_SAVE_AREA */ + #ifdef STACK_GROWS_DOWNWARD emit_move_insn (target, virtual_stack_dynamic_rtx); #endif @@ -1562,12 +1546,20 @@ probe_stack_range (first, size) /* First see if the front end has set up a function for us to call to check the stack. */ if (stack_check_libfunc != 0) - emit_library_call (stack_check_libfunc, 0, VOIDmode, 1, - memory_address (QImode, - gen_rtx (STACK_GROW_OP, Pmode, - stack_pointer_rtx, - plus_constant (size, first))), - ptr_mode); + { + rtx addr = memory_address (QImode, + gen_rtx (STACK_GROW_OP, Pmode, + stack_pointer_rtx, + plus_constant (size, first))); + +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (addr) != ptr_mode) + addr = convert_memory_address (ptr_mode, addr); +#endif + + emit_library_call (stack_check_libfunc, 0, VOIDmode, 1, addr, + ptr_mode); + } /* Next see if we have an insn to check the stack. Use it if so. */ #ifdef HAVE_check_stack