aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2002-03-08 22:38:00 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2002-03-08 22:38:00 +0000
commit41daaf0ebfe2da33b369d47c8239ac69b63a874d (patch)
tree30b464cb200db0c74a98ce013c3425952fdac8df
parente23483d273c930173a1bff9eb0734a93c293ce92 (diff)
downloadgcc-41daaf0ebfe2da33b369d47c8239ac69b63a874d.zip
gcc-41daaf0ebfe2da33b369d47c8239ac69b63a874d.tar.gz
gcc-41daaf0ebfe2da33b369d47c8239ac69b63a874d.tar.bz2
rs6000.c (rs6000_va_arg): Fix alignment for vectors.
2002-03-08 Aldy Hernandez <aldyh@redhat.com> * config/rs6000/rs6000.c (rs6000_va_arg): Fix alignment for vectors. From-SVN: r50463
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c88
2 files changed, 59 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9078f5b..024914a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2002-03-08 Aldy Hernandez <aldyh@redhat.com>
+ * config/rs6000/rs6000.c (rs6000_va_arg): Fix alignment for
+ vectors.
+
+2002-03-08 Aldy Hernandez <aldyh@redhat.com>
+
* config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.
Fri Mar 8 21:27:49 CET 2002 Jan Hubicka <jh@suse.cz>
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 89caf5c..0a86921 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3192,50 +3192,62 @@ rs6000_va_arg (valist, type)
lab_over = gen_label_rtx ();
addr_rtx = gen_reg_rtx (Pmode);
- emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
- GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
- lab_false);
-
- /* Long long is aligned in the registers. */
- if (n_reg > 1)
+ /* Vectors never go in registers. */
+ if (TREE_CODE (type) != VECTOR_TYPE)
{
- u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
- build_int_2 (n_reg - 1, 0));
- u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
- u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
- TREE_SIDE_EFFECTS (u) = 1;
- expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
+ TREE_THIS_VOLATILE (reg) = 1;
+ emit_cmp_and_jump_insns
+ (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
+ GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
+ lab_false);
- if (sav_ofs)
- t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
- else
- t = sav;
+ /* Long long is aligned in the registers. */
+ if (n_reg > 1)
+ {
+ u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
+ build_int_2 (n_reg - 1, 0));
+ u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
+ u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
+ TREE_SIDE_EFFECTS (u) = 1;
+ expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
- u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, build_int_2 (n_reg, 0));
- TREE_SIDE_EFFECTS (u) = 1;
+ if (sav_ofs)
+ t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
+ else
+ t = sav;
- u = build1 (CONVERT_EXPR, integer_type_node, u);
- TREE_SIDE_EFFECTS (u) = 1;
+ u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
+ build_int_2 (n_reg, 0));
+ TREE_SIDE_EFFECTS (u) = 1;
- u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
- TREE_SIDE_EFFECTS (u) = 1;
+ u = build1 (CONVERT_EXPR, integer_type_node, u);
+ TREE_SIDE_EFFECTS (u) = 1;
- t = build (PLUS_EXPR, ptr_type_node, t, u);
- TREE_SIDE_EFFECTS (t) = 1;
+ u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
+ TREE_SIDE_EFFECTS (u) = 1;
- r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
- if (r != addr_rtx)
- emit_move_insn (addr_rtx, r);
+ t = build (PLUS_EXPR, ptr_type_node, t, u);
+ TREE_SIDE_EFFECTS (t) = 1;
+
+ r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
+ if (r != addr_rtx)
+ emit_move_insn (addr_rtx, r);
+
+ emit_jump_insn (gen_jump (lab_over));
+ emit_barrier ();
+ }
- emit_jump_insn (gen_jump (lab_over));
- emit_barrier ();
emit_label (lab_false);
/* ... otherwise out of the overflow area. */
- /* Make sure we don't find reg 7 for the next int arg. */
- if (n_reg > 1)
+ /* Make sure we don't find reg 7 for the next int arg.
+
+ All AltiVec vectors go in the overflow area. So in the AltiVec
+ case we need to get the vectors from the overflow area, but
+ remember where the GPRs and FPRs are. */
+ if (n_reg > 1 && TREE_CODE (type) != VECTOR_TYPE)
{
t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
TREE_SIDE_EFFECTS (t) = 1;
@@ -3247,8 +3259,16 @@ rs6000_va_arg (valist, type)
t = ovf;
else
{
- t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (7, 0));
- t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-8, -1));
+ int align;
+
+ /* Vectors are 16 byte aligned. */
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ align = 15;
+ else
+ align = 7;
+
+ t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
}
t = save_expr (t);