DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
recursively.
+ If the result can be stored at TARGET, and ALT_RTL is non-NULL,
+ then *ALT_RTL is set to TARGET (before legitimziation).
If INNER_REFERENCE_P is true, we are expanding an inner reference.
In this case, we don't adjust a returned MEM rtx that wouldn't be
return NULL_RTX;
}
+/* A helper function for expand_expr_real_2 to be used with a
+ misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP
+ is nonzero, with alignment ALIGN in bits.
+ Store the value at TARGET if possible (if TARGET is nonzero).
+ Regardless of TARGET, we return the rtx for where the value is placed.
+ If the result can be stored at TARGET, and ALT_RTL is non-NULL,
+ then *ALT_RTL is set to TARGET (before legitimziation). */
+
+static rtx
+expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
+ unsigned int align, rtx target, rtx *alt_rtl)
+{
+ enum insn_code icode;
+
+ if ((icode = optab_handler (movmisalign_optab, mode))
+ != CODE_FOR_nothing)
+ {
+ class expand_operand ops[2];
+
+ /* We've already validated the memory, and we're creating a
+ new pseudo destination. The predicates really can't fail,
+ nor can the generator. */
+ create_output_operand (&ops[0], NULL_RTX, mode);
+ create_fixed_operand (&ops[1], temp);
+ expand_insn (icode, 2, ops);
+ temp = ops[0].value;
+ }
+ else if (targetm.slow_unaligned_access (mode, align))
+ temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
+ 0, unsignedp, target,
+ mode, mode, false, alt_rtl);
+ return temp;
+}
+
rtx
expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
enum expand_modifier modifier)
&& !inner_reference_p
&& mode != BLKmode
&& MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
- {
- enum insn_code icode;
-
- if ((icode = optab_handler (movmisalign_optab, mode))
- != CODE_FOR_nothing)
- {
- class expand_operand ops[2];
-
- /* We've already validated the memory, and we're creating a
- new pseudo destination. The predicates really can't fail,
- nor can the generator. */
- create_output_operand (&ops[0], NULL_RTX, mode);
- create_fixed_operand (&ops[1], temp);
- expand_insn (icode, 2, ops);
- temp = ops[0].value;
- }
- else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp)))
- temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
- 0, unsignedp, NULL_RTX,
- mode, mode, false, NULL);
- }
+ temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
+ MEM_ALIGN (temp), NULL_RTX, NULL);
return temp;
}
&& modifier != EXPAND_MEMORY
&& mode != BLKmode
&& align < GET_MODE_ALIGNMENT (mode))
- {
- enum insn_code icode;
-
- if ((icode = optab_handler (movmisalign_optab, mode))
- != CODE_FOR_nothing)
- {
- class expand_operand ops[2];
-
- /* We've already validated the memory, and we're creating a
- new pseudo destination. The predicates really can't fail,
- nor can the generator. */
- create_output_operand (&ops[0], NULL_RTX, mode);
- create_fixed_operand (&ops[1], temp);
- expand_insn (icode, 2, ops);
- temp = ops[0].value;
- }
- else if (targetm.slow_unaligned_access (mode, align))
- temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
- 0, unsignedp, NULL_RTX,
- mode, mode, false, NULL);
- }
+ temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
+ align, NULL_RTX, NULL);
return temp;
}
machine_mode address_mode;
tree base = TREE_OPERAND (exp, 0);
gimple *def_stmt;
- enum insn_code icode;
unsigned align;
/* Handle expansion of non-aliased memory with non-BLKmode. That
might end up in a register. */
return expand_expr (exp, target, tmode, modifier);
}
address_mode = targetm.addr_space.address_mode (as);
- base = TREE_OPERAND (exp, 0);
if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
{
tree mask = gimple_assign_rhs2 (def_stmt);
&& !inner_reference_p
&& mode != BLKmode
&& align < GET_MODE_ALIGNMENT (mode))
- {
- if ((icode = optab_handler (movmisalign_optab, mode))
- != CODE_FOR_nothing)
- {
- class expand_operand ops[2];
-
- /* We've already validated the memory, and we're creating a
- new pseudo destination. The predicates really can't fail,
- nor can the generator. */
- create_output_operand (&ops[0], NULL_RTX, mode);
- create_fixed_operand (&ops[1], temp);
- expand_insn (icode, 2, ops);
- temp = ops[0].value;
- }
- else if (targetm.slow_unaligned_access (mode, align))
- temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
- 0, TYPE_UNSIGNED (TREE_TYPE (exp)),
- (modifier == EXPAND_STACK_PARM
- ? NULL_RTX : target),
- mode, mode, false, alt_rtl);
- }
+ temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
+ modifier == EXPAND_STACK_PARM
+ ? NULL_RTX : target, alt_rtl);
if (reverse
&& modifier != EXPAND_MEMORY
&& modifier != EXPAND_WRITE)
machine_mode mode1;
poly_int64 bitsize, bitpos, bytepos;
tree offset;
- int unsignedp, reversep, volatilep = 0;
+ int reversep, volatilep = 0;
tree tem
= get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
&unsignedp, &reversep, &volatilep);
- rtx orig_op0;
/* ??? We should work harder and deal with non-zero offsets. */
if (!offset
&& known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
{
/* See the normal_inner_ref case for the rationale. */
- orig_op0
+ rtx orig_op0
= expand_expr_real (tem,
(TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
&& (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))