diff options
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -3643,7 +3643,8 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size, xinner = x; - if (mode == BLKmode) + if (mode == BLKmode + || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode))) { /* Copy a block into the stack, entirely or partially. */ @@ -3655,6 +3656,20 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size, offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT); used = partial - offset; + if (mode != BLKmode) + { + /* A value is to be stored in an insufficiently aligned + stack slot; copy via a suitably aligned slot if + necessary. */ + size = GEN_INT (GET_MODE_SIZE (mode)); + if (!MEM_P (xinner)) + { + temp = assign_temp (type, 0, 1, 1); + emit_move_insn (temp, xinner); + xinner = temp; + } + } + gcc_assert (size); /* USED is now the # of bytes we need not copy to the stack |