summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-10 15:32:32 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-10 15:32:32 +0000
commitf955ca518bf9bfa53aabe55c11a67c6c5a2a3581 (patch)
tree0aa9473b8b3617587ecfad9b6ad9269f5bee34ac /gcc/expr.c
parenta05c309c67d515619f68423d67debbf61f61a31f (diff)
downloadgcc-f955ca518bf9bfa53aabe55c11a67c6c5a2a3581.tar.gz
* expr.c (store_field): Remove TYPE parameter. Remove block of code
dealing with BLKmode in registers. Reimplement this support using pseudo-registers and bit-field techniques. (store_constructor_field): Remove TYPE parameter and adjust calls to store_field. (expand_assignment): Adjust calls to store_field. Add comment. (store_expr): Add comment. (store_constructor): Adjust calls to store_constructor_field. (expand_expr_real_2): Adjust call to store_field. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193391 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c124
1 files changed, 41 insertions, 83 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 1e41625b2ed..cbf3a4038e8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -137,12 +137,11 @@ static rtx compress_float_constant (rtx, rtx);
static rtx get_subtarget (rtx);
static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode,
- tree, tree, int, alias_set_type);
+ tree, int, alias_set_type);
static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
- enum machine_mode,
- tree, tree, alias_set_type, bool);
+ enum machine_mode, tree, alias_set_type, bool);
static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
@@ -4772,15 +4771,14 @@ expand_assignment (tree to, tree from, bool nontemporal)
else if (bitpos + bitsize <= mode_bitsize / 2)
result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
bitregion_start, bitregion_end,
- mode1, from, TREE_TYPE (tem),
+ mode1, from,
get_alias_set (to), nontemporal);
else if (bitpos >= mode_bitsize / 2)
result = store_field (XEXP (to_rtx, 1), bitsize,
bitpos - mode_bitsize / 2,
bitregion_start, bitregion_end,
mode1, from,
- TREE_TYPE (tem), get_alias_set (to),
- nontemporal);
+ get_alias_set (to), nontemporal);
else if (bitpos == 0 && bitsize == mode_bitsize)
{
rtx from_rtx;
@@ -4801,8 +4799,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
result = store_field (temp, bitsize, bitpos,
bitregion_start, bitregion_end,
mode1, from,
- TREE_TYPE (tem), get_alias_set (to),
- nontemporal);
+ get_alias_set (to), nontemporal);
emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
}
@@ -4834,8 +4831,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
result = store_field (to_rtx, bitsize, bitpos,
bitregion_start, bitregion_end,
mode1, from,
- TREE_TYPE (tem), get_alias_set (to),
- nontemporal);
+ get_alias_set (to), nontemporal);
}
if (misalignp)
@@ -4896,6 +4892,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
int_size_in_bytes (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
{
+ /* Handle calls that return BLKmode values in registers. */
if (REG_P (value))
copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
else
@@ -5246,6 +5243,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
{
if (GET_MODE (target) == BLKmode)
{
+ /* Handle calls that return BLKmode values in registers. */
if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
else
@@ -5680,7 +5678,6 @@ all_zeros_p (const_tree exp)
/* Helper function for store_constructor.
TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
- TYPE is the type of the CONSTRUCTOR, not the element type.
CLEARED is as for store_constructor.
ALIAS_SET is the alias set to use for any stores.
@@ -5692,8 +5689,7 @@ all_zeros_p (const_tree exp)
static void
store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
HOST_WIDE_INT bitpos, enum machine_mode mode,
- tree exp, tree type, int cleared,
- alias_set_type alias_set)
+ tree exp, int cleared, alias_set_type alias_set)
{
if (TREE_CODE (exp) == CONSTRUCTOR
/* We can only call store_constructor recursively if the size and
@@ -5725,8 +5721,7 @@ store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
}
else
- store_field (target, bitsize, bitpos, 0, 0, mode, exp, type, alias_set,
- false);
+ store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false);
}
/* Store the value of constructor EXP into the rtx TARGET.
@@ -5897,7 +5892,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
}
store_constructor_field (to_rtx, bitsize, bitpos, mode,
- value, type, cleared,
+ value, cleared,
get_alias_set (TREE_TYPE (field)));
}
break;
@@ -6052,7 +6047,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
}
store_constructor_field
- (target, bitsize, bitpos, mode, value, type, cleared,
+ (target, bitsize, bitpos, mode, value, cleared,
get_alias_set (elttype));
}
}
@@ -6156,7 +6151,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
MEM_KEEP_ALIAS_SET_P (target) = 1;
}
store_constructor_field (target, bitsize, bitpos, mode, value,
- type, cleared, get_alias_set (elttype));
+ cleared, get_alias_set (elttype));
}
}
break;
@@ -6276,9 +6271,8 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
? TYPE_MODE (TREE_TYPE (value))
: eltmode;
bitpos = eltpos * elt_size;
- store_constructor_field (target, bitsize, bitpos,
- value_mode, value, type,
- cleared, alias);
+ store_constructor_field (target, bitsize, bitpos, value_mode,
+ value, cleared, alias);
}
}
@@ -6307,8 +6301,6 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
Always return const0_rtx unless we have something particular to
return.
- TYPE is the type of the underlying object,
-
ALIAS_SET is the alias set for the destination. This value will
(in general) be different from that for TARGET, since TARGET is a
reference to the containing structure.
@@ -6319,7 +6311,7 @@ static rtx
store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
unsigned HOST_WIDE_INT bitregion_start,
unsigned HOST_WIDE_INT bitregion_end,
- enum machine_mode mode, tree exp, tree type,
+ enum machine_mode mode, tree exp,
alias_set_type alias_set, bool nontemporal)
{
if (TREE_CODE (exp) == ERROR_MARK)
@@ -6330,38 +6322,6 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
if (bitsize == 0)
return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
- /* If we are storing into an unaligned field of an aligned union that is
- in a register, we may have the mode of TARGET being an integer mode but
- MODE == BLKmode. In that case, get an aligned object whose size and
- alignment are the same as TARGET and store TARGET into it (we can avoid
- the store if the field being stored is the entire width of TARGET). Then
- call ourselves recursively to store the field into a BLKmode version of
- that object. Finally, load from the object into TARGET. This is not
- very efficient in general, but should only be slightly more expensive
- than the otherwise-required unaligned accesses. Perhaps this can be
- cleaned up later. It's tempting to make OBJECT readonly, but it's set
- twice, once with emit_move_insn and once via store_field. */
-
- if (mode == BLKmode
- && (REG_P (target) || GET_CODE (target) == SUBREG)
- && TREE_CODE (exp) != CALL_EXPR)
- {
- rtx object = assign_temp (type, 1, 1);
- rtx blk_object = adjust_address (object, BLKmode, 0);
-
- if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
- emit_move_insn (object, target);
-
- store_field (blk_object, bitsize, bitpos,
- bitregion_start, bitregion_end,
- mode, exp, type, MEM_ALIAS_SET (blk_object), nontemporal);
-
- emit_move_insn (target, object);
-
- /* We want to return the BLKmode version of the data. */
- return blk_object;
- }
-
if (GET_CODE (target) == CONCAT)
{
/* We're storing into a struct containing a single __complex. */
@@ -6472,35 +6432,34 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
The Irix 6 ABI has examples of this. */
if (GET_CODE (temp) == PARALLEL)
{
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
rtx temp_target;
-
- /* We are not supposed to have a true bitfield in this case. */
- gcc_assert (bitsize == GET_MODE_BITSIZE (mode));
-
- /* If we don't store at bit 0, we need an intermediate pseudo
- since emit_group_store only stores at bit 0. */
- if (bitpos != 0)
- temp_target = gen_reg_rtx (mode);
- else
- temp_target = target;
-
- emit_group_store (temp_target, temp, TREE_TYPE (exp),
- int_size_in_bytes (TREE_TYPE (exp)));
-
- if (temp_target == target)
- return const0_rtx;
-
+ if (mode == BLKmode)
+ mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
+ temp_target = gen_reg_rtx (mode);
+ emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
temp = temp_target;
}
-
- /* Handle calls that return BLKmode values in registers. */
- else if (mode == BLKmode
- && REG_P (temp)
- && TREE_CODE (exp) == CALL_EXPR)
+ else if (mode == BLKmode)
{
- rtx temp_target = gen_reg_rtx (GET_MODE (temp));
- copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
- temp = temp_target;
+ /* Handle calls that return BLKmode values in registers. */
+ if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
+ {
+ rtx temp_target = gen_reg_rtx (GET_MODE (temp));
+ copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
+ temp = temp_target;
+ }
+ else
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+ rtx temp_target;
+ mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
+ temp_target = gen_reg_rtx (mode);
+ temp_target
+ = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
+ false, temp_target, mode, mode);
+ temp = temp_target;
+ }
}
/* Store the value in the bitfield. */
@@ -8059,8 +8018,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
(treeop0))
* BITS_PER_UNIT),
(HOST_WIDE_INT) GET_MODE_BITSIZE (mode)),
- 0, 0, 0, TYPE_MODE (valtype), treeop0,
- type, 0, false);
+ 0, 0, 0, TYPE_MODE (valtype), treeop0, 0, false);
}
/* Return the entire union. */