if (mode != Pmode)
return 0;
- return (GET_CODE (op) == SYMBOL_REF
- || (GET_CODE (op) == REG
- && (REGNO (op) == 27 || WINDOWS_NT)));
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
}
/* Return 1 if OP is a valid Alpha comparison operator. Here we know which
op = XEXP (op, 0);
return (GET_CODE (op) == REG
- && (REGNO (op) == STACK_POINTER_REGNUM
- || op == hard_frame_pointer_rtx
- || (REGNO (op) >= FIRST_VIRTUAL_REGISTER
- && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
+ && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
}
/* Similar, but return 1 if OP is a MEM which is not alignable. */
op = XEXP (op, 0);
return (GET_CODE (op) != REG
- || (REGNO (op) != STACK_POINTER_REGNUM
- && op != hard_frame_pointer_rtx
- && (REGNO (op) < FIRST_VIRTUAL_REGISTER
- || REGNO (op) > LAST_VIRTUAL_REGISTER)));
+ || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
+}
+
+/* Return 1 if OP is either a register or an unaligned memory location. */
+
+int
+reg_or_unaligned_mem_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return register_operand (op, mode) || unaligned_memory_operand (op, mode);
}
/* Return 1 if OP is any memory location. During reload a pseudo matches. */
*pbitnum = GEN_INT ((offset & 3) * 8);
}
-/* Similar, but just get the address. Handle the two reload cases. */
+/* Similar, but just get the address. Handle the two reload cases.
+ Add EXTRA_OFFSET to the address we return. */
rtx
-get_unaligned_address (ref)
+get_unaligned_address (ref, extra_offset)
rtx ref;
+ int extra_offset;
{
rtx base;
HOST_WIDE_INT offset = 0;
if (GET_CODE (base) == PLUS)
offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
- return plus_constant (base, offset);
+ return plus_constant (base, offset + extra_offset);
}
\f
/* Subfunction of the following function. Update the flags of any MEM
if ((HOST_BITS_PER_WIDE_INT != 64
|| c >> 31 == -1 || c >> 31 == 0)
- && c != 0x80000000u)
+ && c != 0x80000000U)
{
HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
HOST_WIDE_INT tmp1 = c - low;
if (c == low || (low == 0 && extra == 0))
return copy_to_suggested_reg (GEN_INT (c), target, mode);
- else if (n >= 2 + (extra != 0))
+ else if (n >= 2 + (extra != 0)
+ /* We can't do this when SImode if HIGH required adjustment.
+ This is because the code relies on an implicit overflow
+ which is invisible to the RTL. We can thus get incorrect
+ code if the two ldah instructions are combined. */
+ && ! (mode == SImode && extra != 0))
{
temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
new |= (HOST_WIDE_INT) 0xff << i;
- if ((temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
+ /* We are only called for SImode and DImode. If this is SImode, ensure that
+ we are sign extended to a full word. */
+
+ if (mode == SImode)
+ new = (new & 0xffffffff) - 2 * (new & 0x80000000);
+
+ if (new != c
+ && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
target, 0, OPTAB_WIDEN);
#endif
target, 0, OPTAB_WIDEN);
/* Now try high-order zero bits. Here we try the shifted-in bits as
- all zero and all ones. */
+ all zero and all ones. Be careful to avoid shifting outside the
+ mode and to avoid shifting outside the host wide int size. */
- if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (c) - 1) > 0)
+ if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
+ - floor_log2 (c) - 1)) > 0)
for (; bits > 0; bits--)
if ((temp = alpha_emit_set_const (subtarget, mode,
c << bits, i)) != 0
i)))
!= 0))
return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
- target, 0, OPTAB_WIDEN);
+ target, 1, OPTAB_WIDEN);
/* Now try high-order 1 bits. We get that with a sign-extension.
- But one bit isn't enough here. */
+ But one bit isn't enough here. Be careful to avoid shifting outside
+ the mode and to avoid shifting outside the host wide int size. */
- if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (~ c) - 2) > 0)
+ if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
+ - floor_log2 (~ c) - 2)) > 0)
for (; bits > 0; bits--)
if ((temp = alpha_emit_set_const (subtarget, mode,
c << bits, i)) != 0
? plus_constant (virtual_incoming_args_rtx, 6 * UNITS_PER_WORD)
: plus_constant (virtual_incoming_args_rtx, - (6 * UNITS_PER_WORD)));
+ addr = force_operand (addr, NULL_RTX);
+
/* Allocate the va_list constructor */
block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
RTX_UNCHANGING_P (block) = 1;
RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
- /* Store the address of the first integer register in the
- __va_base member. */
- emit_move_insn (change_address (block, Pmode, XEXP (block, 0)),
- force_operand (addr, NULL_RTX));
+ /* Store the address of the first integer register in the __base member. */
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+ addr = convert_memory_address (ptr_mode, addr);
+#endif
+
+ emit_move_insn (change_address (block, ptr_mode, XEXP (block, 0)), addr);
/* Store the argsize as the __va_offset member. */
- emit_move_insn (change_address (block, Pmode,
+ emit_move_insn (change_address (block, TYPE_MODE (integer_type_node),
plus_constant (XEXP (block, 0),
- UNITS_PER_WORD)),
- force_operand (argsize, NULL_RTX));
+ POINTER_SIZE/BITS_PER_UNIT)),
+ argsize);
/* Return the address of the va_list constructor, but don't put it in a
register. Doing so would fail when not optimizing and produce worse
FILE *file;
{
#ifdef MS_STAMP
- char *p;
-
- fprintf (file, "\t.verstamp %d %d ", MS_STAMP, LS_STAMP);
- for (p = version_string; *p != ' ' && *p != 0; p++)
- fprintf (file, "%c", *p == '.' ? ' ' : *p);
- fprintf (file, "\n");
+ fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
#endif
}
\f