aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index da8304a..96cab62 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5829,6 +5829,8 @@ safe_from_p (rtx x, tree exp, int top_p)
}
break;
+ case MISALIGNED_INDIRECT_REF:
+ case ALIGN_INDIRECT_REF:
case INDIRECT_REF:
if (MEM_P (x)
&& alias_sets_conflict_p (MEM_ALIAS_SET (x),
@@ -6745,11 +6747,17 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return target;
}
+ case MISALIGNED_INDIRECT_REF:
+ case ALIGN_INDIRECT_REF:
case INDIRECT_REF:
{
tree exp1 = TREE_OPERAND (exp, 0);
tree orig;
+ if (code == MISALIGNED_INDIRECT_REF
+ && !targetm.vectorize.misaligned_mem_ok (mode))
+ abort ();
+
if (modifier != EXPAND_WRITE)
{
tree t;
@@ -6761,6 +6769,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
+
+ if (code == ALIGN_INDIRECT_REF)
+ {
+ int align = TYPE_ALIGN_UNIT (type);
+ op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
+ op0 = memory_address (mode, op0);
+ }
+
temp = gen_rtx_MEM (mode, op0);
orig = REF_ORIGINAL (exp);
@@ -8203,6 +8219,24 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return expand_expr_real (TREE_OPERAND (exp, 0), original_target, tmode,
modifier, alt_rtl);
+ case REALIGN_LOAD_EXPR:
+ {
+ tree oprnd0 = TREE_OPERAND (exp, 0);
+ tree oprnd1 = TREE_OPERAND (exp, 1);
+ tree oprnd2 = TREE_OPERAND (exp, 2);
+ rtx op2;
+
+ this_optab = optab_for_tree_code (code, type);
+ expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, 0);
+ op2 = expand_expr (oprnd2, NULL_RTX, VOIDmode, 0);
+ temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
+ target, unsignedp);
+ if (temp == 0)
+ abort ();
+ return temp;
+ }
+
+
default:
return lang_hooks.expand_expr (exp, original_target, tmode,
modifier, alt_rtl);