diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2002-03-08 22:38:00 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2002-03-08 22:38:00 +0000 |
commit | 41daaf0ebfe2da33b369d47c8239ac69b63a874d (patch) | |
tree | 30b464cb200db0c74a98ce013c3425952fdac8df | |
parent | e23483d273c930173a1bff9eb0734a93c293ce92 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 88 |
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); |