/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
#endif
#ifndef TARGET_PROFILE_KERNEL
#define TARGET_PROFILE_KERNEL 0
-#define SET_PROFILE_KERNEL(N)
-#else
-#define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
#endif
/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
field = TREE_CHAIN (field);
if (! field)
break;
+ /* A packed field does not contribute any extra alignment. */
+ if (DECL_PACKED (field))
+ return align;
type = TREE_TYPE (field);
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
return orig_x;
}
+ if (TARGET_MACHO
+ && GET_CODE (orig_x) == LO_SUM
+ && GET_CODE (XEXP (x, 1)) == CONST)
+ {
+ y = XEXP (XEXP (x, 1), 0);
+ if (GET_CODE (y) == UNSPEC
+ && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
+ return XVECEXP (y, 0, 0);
+ }
+
return orig_x;
}
return;
}
- /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
- in the secondary_reload phase, which evidently overwrites the CONST_INT
- with a register. */
- if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
- && mode == Pmode)
- {
- rtx add_op0 = XEXP (XEXP (source, 0), 0);
- rtx add_op1 = XEXP (XEXP (source, 0), 1);
-
- if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
- {
- rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
-
- if (TARGET_DEBUG_ADDR)
- {
- fprintf (stderr, "\nrs6000_emit_move: bad source\n");
- debug_rtx (source);
- }
-
- rs6000_emit_move (tmp, add_op0, Pmode);
- emit_insn (gen_rtx_SET (VOIDmode, dest,
- gen_rtx_PLUS (Pmode, tmp, add_op1)));
- return;
- }
- }
-
if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
&& !gpc_reg_operand (operands[1], mode))
operands[1] = force_reg (mode, operands[1]);
{ MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
{ MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
{ MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
+ { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
+ { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
+ { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
+ { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
int i;
int j = -1;
bool used_update = false;
+ rtx restore_basereg = NULL_RTX;
if (MEM_P (src) && INT_REGNO_P (reg))
{
}
else if (! rs6000_offsettable_memref_p (src))
{
- rtx basereg;
- basereg = gen_rtx_REG (Pmode, reg);
- emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
- src = replace_equiv_address (src, basereg);
+ if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
+ {
+ rtx basereg = XEXP (XEXP (src, 0), 0);
+ if (TARGET_UPDATE)
+ {
+ rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, ndst,
+ gen_rtx_MEM (reg_mode, XEXP (src, 0))));
+ used_update = true;
+ }
+ else
+ emit_insn (gen_rtx_SET (VOIDmode, basereg,
+ XEXP (XEXP (src, 0), 1)));
+ src = replace_equiv_address (src, basereg);
+ }
+ else
+ {
+ rtx basereg = gen_rtx_REG (Pmode, reg);
+ emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
+ src = replace_equiv_address (src, basereg);
+ }
}
breg = XEXP (src, 0);
&& REGNO (breg) < REGNO (dst) + nregs)
j = REGNO (breg) - REGNO (dst);
}
-
- if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
+ else if (MEM_P (dst) && INT_REGNO_P (reg))
{
rtx breg;
emit_insn (gen_add3_insn (breg, breg, delta_rtx));
dst = replace_equiv_address (dst, breg);
}
- else
+ else if (!rs6000_offsettable_memref_p (dst)
+ && GET_CODE (XEXP (dst, 0)) != LO_SUM)
+ {
+ if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
+ {
+ rtx basereg = XEXP (XEXP (dst, 0), 0);
+ if (TARGET_UPDATE)
+ {
+ rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
+ emit_insn (gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
+ used_update = true;
+ }
+ else
+ emit_insn (gen_rtx_SET (VOIDmode, basereg,
+ XEXP (XEXP (dst, 0), 1)));
+ dst = replace_equiv_address (dst, basereg);
+ }
+ else
+ {
+ rtx basereg = XEXP (XEXP (dst, 0), 0);
+ rtx offsetreg = XEXP (XEXP (dst, 0), 1);
+ emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
+ restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
+ dst = replace_equiv_address (dst, basereg);
+ }
+ }
+ else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
gcc_assert (rs6000_offsettable_memref_p (dst));
}
simplify_gen_subreg (reg_mode, src, mode,
j * reg_mode_size)));
}
+ if (restore_basereg != NULL_RTX)
+ emit_insn (restore_basereg);
}
}
do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
SImode, NULL_RTX, NULL_RTX,
- no_toc_save_needed);
+ no_toc_save_needed, -1);
mem = gen_frame_mem (Pmode,
gen_rtx_PLUS (Pmode, stack_top,