diff mbox series

[092/nnn] poly_int: PUSH_ROUNDING

Message ID 87r2ttepfk.fsf@linaro.org
State New
Headers show
Series [092/nnn] poly_int: PUSH_ROUNDING | expand

Commit Message

Richard Sandiford Oct. 23, 2017, 5:37 p.m. UTC
PUSH_ROUNDING is difficult to convert to a hook since there is still
a lot of conditional code based on it.  It isn't clear that a direct
conversion with checks for null hooks is the right thing to do.

Rather than untangle that, this patch converts all implementations
that do something to out-of-line functions that have the same
interface as a hook would have.  This should at least help towards
any future hook conversion.


2017-10-23  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* config/cr16/cr16-protos.h (cr16_push_rounding): Declare.
	* config/cr16/cr16.h (PUSH_ROUNDING): Move implementation to...
	* config/cr16/cr16.c (cr16_push_rounding): ...this new function.
	* config/h8300/h8300-protos.h (h8300_push_rounding): Declare.
	* config/h8300/h8300.h (PUSH_ROUNDING): Move implementation to...
	* config/h8300/h8300.c (h8300_push_rounding): ...this new function.
	* config/i386/i386-protos.h (ix86_push_rounding): Declare.
	* config/i386/i386.h (PUSH_ROUNDING): Move implementation to...
	* config/i386/i386.c (ix86_push_rounding): ...this new function.
	* config/m32c/m32c-protos.h (m32c_push_rounding): Take and return
	a poly_int64.
	* config/m32c/m32c.c (m32c_push_rounding): Likewise.
	* config/m68k/m68k-protos.h (m68k_push_rounding): Declare.
	* config/m68k/m68k.h (PUSH_ROUNDING): Move implementation to...
	* config/m68k/m68k.c (m68k_push_rounding): ...this new function.
	* config/pdp11/pdp11-protos.h (pdp11_push_rounding): Declare.
	* config/pdp11/pdp11.h (PUSH_ROUNDING): Move implementation to...
	* config/pdp11/pdp11.c (pdp11_push_rounding): ...this new function.
	* config/stormy16/stormy16-protos.h (xstormy16_push_rounding): Declare.
	* config/stormy16/stormy16.h (PUSH_ROUNDING): Move implementation to...
	* config/stormy16/stormy16.c (xstormy16_push_rounding): ...this new
	function.
	* expr.c (emit_move_resolve_push): Treat the input and result
	of PUSH_ROUNDING as a poly_int64.
	(emit_move_complex_push, emit_single_push_insn_1): Likewise.
	(emit_push_insn): Likewise.
	* lra-eliminations.c (mark_not_eliminable): Likewise.
	* recog.c (push_operand): Likewise.
	* reload1.c (elimination_effects): Likewise.
	* rtlanal.c (nonzero_bits1): Likewise.
	* calls.c (store_one_arg): Likewise.  Require the padding to be
	known at compile time.

Comments

Jeff Law Nov. 28, 2017, 4:14 p.m. UTC | #1
On 10/23/2017 11:37 AM, Richard Sandiford wrote:
> PUSH_ROUNDING is difficult to convert to a hook since there is still
> a lot of conditional code based on it.  It isn't clear that a direct
> conversion with checks for null hooks is the right thing to do.
> 
> Rather than untangle that, this patch converts all implementations
> that do something to out-of-line functions that have the same
> interface as a hook would have.  This should at least help towards
> any future hook conversion.
> 
> 
> 2017-10-23  Richard Sandiford  <richard.sandiford@linaro.org>
> 	    Alan Hayward  <alan.hayward@arm.com>
> 	    David Sherwood  <david.sherwood@arm.com>
> 
> gcc/
> 	* config/cr16/cr16-protos.h (cr16_push_rounding): Declare.
> 	* config/cr16/cr16.h (PUSH_ROUNDING): Move implementation to...
> 	* config/cr16/cr16.c (cr16_push_rounding): ...this new function.
> 	* config/h8300/h8300-protos.h (h8300_push_rounding): Declare.
> 	* config/h8300/h8300.h (PUSH_ROUNDING): Move implementation to...
> 	* config/h8300/h8300.c (h8300_push_rounding): ...this new function.
> 	* config/i386/i386-protos.h (ix86_push_rounding): Declare.
> 	* config/i386/i386.h (PUSH_ROUNDING): Move implementation to...
> 	* config/i386/i386.c (ix86_push_rounding): ...this new function.
> 	* config/m32c/m32c-protos.h (m32c_push_rounding): Take and return
> 	a poly_int64.
> 	* config/m32c/m32c.c (m32c_push_rounding): Likewise.
> 	* config/m68k/m68k-protos.h (m68k_push_rounding): Declare.
> 	* config/m68k/m68k.h (PUSH_ROUNDING): Move implementation to...
> 	* config/m68k/m68k.c (m68k_push_rounding): ...this new function.
> 	* config/pdp11/pdp11-protos.h (pdp11_push_rounding): Declare.
> 	* config/pdp11/pdp11.h (PUSH_ROUNDING): Move implementation to...
> 	* config/pdp11/pdp11.c (pdp11_push_rounding): ...this new function.
> 	* config/stormy16/stormy16-protos.h (xstormy16_push_rounding): Declare.
> 	* config/stormy16/stormy16.h (PUSH_ROUNDING): Move implementation to...
> 	* config/stormy16/stormy16.c (xstormy16_push_rounding): ...this new
> 	function.
> 	* expr.c (emit_move_resolve_push): Treat the input and result
> 	of PUSH_ROUNDING as a poly_int64.
> 	(emit_move_complex_push, emit_single_push_insn_1): Likewise.
> 	(emit_push_insn): Likewise.
> 	* lra-eliminations.c (mark_not_eliminable): Likewise.
> 	* recog.c (push_operand): Likewise.
> 	* reload1.c (elimination_effects): Likewise.
> 	* rtlanal.c (nonzero_bits1): Likewise.
> 	* calls.c (store_one_arg): Likewise.  Require the padding to be
> 	known at compile time.
OK.

I so wish PUSH_ROUNDING wasn't needed and that folks could at least keep
their processors consistent (I'm looking at the coldfire designers :(.
For a tale of woe, see BZ68467.

Jeff
Richard Sandiford Nov. 28, 2017, 6 p.m. UTC | #2
Jeff Law <law@redhat.com> writes:
> On 10/23/2017 11:37 AM, Richard Sandiford wrote:
>> PUSH_ROUNDING is difficult to convert to a hook since there is still
>> a lot of conditional code based on it.  It isn't clear that a direct
>> conversion with checks for null hooks is the right thing to do.
>> 
>> Rather than untangle that, this patch converts all implementations
>> that do something to out-of-line functions that have the same
>> interface as a hook would have.  This should at least help towards
>> any future hook conversion.
>> 
>> 
>> 2017-10-23  Richard Sandiford  <richard.sandiford@linaro.org>
>> 	    Alan Hayward  <alan.hayward@arm.com>
>> 	    David Sherwood  <david.sherwood@arm.com>
>> 
>> gcc/
>> 	* config/cr16/cr16-protos.h (cr16_push_rounding): Declare.
>> 	* config/cr16/cr16.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/cr16/cr16.c (cr16_push_rounding): ...this new function.
>> 	* config/h8300/h8300-protos.h (h8300_push_rounding): Declare.
>> 	* config/h8300/h8300.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/h8300/h8300.c (h8300_push_rounding): ...this new function.
>> 	* config/i386/i386-protos.h (ix86_push_rounding): Declare.
>> 	* config/i386/i386.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/i386/i386.c (ix86_push_rounding): ...this new function.
>> 	* config/m32c/m32c-protos.h (m32c_push_rounding): Take and return
>> 	a poly_int64.
>> 	* config/m32c/m32c.c (m32c_push_rounding): Likewise.
>> 	* config/m68k/m68k-protos.h (m68k_push_rounding): Declare.
>> 	* config/m68k/m68k.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/m68k/m68k.c (m68k_push_rounding): ...this new function.
>> 	* config/pdp11/pdp11-protos.h (pdp11_push_rounding): Declare.
>> 	* config/pdp11/pdp11.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/pdp11/pdp11.c (pdp11_push_rounding): ...this new function.
>> 	* config/stormy16/stormy16-protos.h (xstormy16_push_rounding): Declare.
>> 	* config/stormy16/stormy16.h (PUSH_ROUNDING): Move implementation to...
>> 	* config/stormy16/stormy16.c (xstormy16_push_rounding): ...this new
>> 	function.
>> 	* expr.c (emit_move_resolve_push): Treat the input and result
>> 	of PUSH_ROUNDING as a poly_int64.
>> 	(emit_move_complex_push, emit_single_push_insn_1): Likewise.
>> 	(emit_push_insn): Likewise.
>> 	* lra-eliminations.c (mark_not_eliminable): Likewise.
>> 	* recog.c (push_operand): Likewise.
>> 	* reload1.c (elimination_effects): Likewise.
>> 	* rtlanal.c (nonzero_bits1): Likewise.
>> 	* calls.c (store_one_arg): Likewise.  Require the padding to be
>> 	known at compile time.
> OK.
>
> I so wish PUSH_ROUNDING wasn't needed and that folks could at least keep
> their processors consistent (I'm looking at the coldfire designers :(.
> For a tale of woe, see BZ68467.

Ouch.  Is this also fallout from having different code for libcalls
and normal calls?  That always seemed like an accident waiting to
happen, but I don't remember seeing cases where it caused actual ABI
breakage before.

Thanks as ever for the reviews :-)

Richard
Jeff Law Nov. 28, 2017, 6:06 p.m. UTC | #3
On 11/28/2017 11:00 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:

>>
>> I so wish PUSH_ROUNDING wasn't needed and that folks could at least keep
>> their processors consistent (I'm looking at the coldfire designers :(.
>> For a tale of woe, see BZ68467.
> 
> Ouch.  Is this also fallout from having different code for libcalls
> and normal calls?  That always seemed like an accident waiting to
> happen, but I don't remember seeing cases where it caused actual ABI
> breakage before.
Yup.  Essentially the caller uses a libcall interface where promotions
are not occurring, but there's no way to describe that at the source
level to the implementation of the libcall and the implementation thus
expects the usual argument promotions.  At least that's how it looked
when I started poking a bit.  At that point, I had to stop as I couldn't
justify the time to dig further for an m68k issue...


> 
> Thanks as ever for the reviews :-)
You're welcome.  Still lots to do, but at least some progress whittling
it down.

jeff
diff mbox series

Patch

Index: gcc/config/cr16/cr16-protos.h
===================================================================
--- gcc/config/cr16/cr16-protos.h	2017-09-04 11:49:42.896500726 +0100
+++ gcc/config/cr16/cr16-protos.h	2017-10-23 17:25:38.230865460 +0100
@@ -94,5 +94,6 @@  extern const char *cr16_emit_logical_di
 /* Handling the "interrupt" attribute.  */
 extern int cr16_interrupt_function_p (void);
 extern bool cr16_is_data_model (enum data_model_type);
+extern poly_int64 cr16_push_rounding (poly_int64);
 
 #endif /* Not GCC_CR16_PROTOS_H.  */ 
Index: gcc/config/cr16/cr16.h
===================================================================
--- gcc/config/cr16/cr16.h	2017-10-23 11:41:22.824941066 +0100
+++ gcc/config/cr16/cr16.h	2017-10-23 17:25:38.231865424 +0100
@@ -383,7 +383,7 @@  #define ACCUMULATE_OUTGOING_ARGS 0
 
 #define PUSH_ARGS 1
 
-#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
+#define PUSH_ROUNDING(BYTES) cr16_push_rounding (BYTES)
 
 #ifndef CUMULATIVE_ARGS
 struct cumulative_args
Index: gcc/config/cr16/cr16.c
===================================================================
--- gcc/config/cr16/cr16.c	2017-10-23 17:19:01.400170158 +0100
+++ gcc/config/cr16/cr16.c	2017-10-23 17:25:38.231865424 +0100
@@ -2215,6 +2215,14 @@  cr16_emit_logical_di (rtx *operands, enu
   return "";
 }
 
+/* Implement PUSH_ROUNDING.  */
+
+poly_int64
+cr16_push_rounding (poly_int64 bytes)
+{
+  return (bytes + 1) & ~1;
+}
+
 /* Initialize 'targetm' variable which contains pointers to functions 
    and data relating to the target machine.  */
 
Index: gcc/config/h8300/h8300-protos.h
===================================================================
--- gcc/config/h8300/h8300-protos.h	2017-09-12 14:29:25.231530806 +0100
+++ gcc/config/h8300/h8300-protos.h	2017-10-23 17:25:38.231865424 +0100
@@ -112,5 +112,6 @@  extern bool            h8sx_mergeable_me
 extern bool            h8sx_emit_movmd (rtx, rtx, rtx, HOST_WIDE_INT);
 extern void            h8300_swap_into_er6 (rtx);
 extern void            h8300_swap_out_of_er6 (rtx);
+extern poly_int64      h8300_push_rounding (poly_int64);
 
 #endif /* ! GCC_H8300_PROTOS_H */
Index: gcc/config/h8300/h8300.h
===================================================================
--- gcc/config/h8300/h8300.h	2017-10-23 11:41:22.920697531 +0100
+++ gcc/config/h8300/h8300.h	2017-10-23 17:25:38.232865388 +0100
@@ -359,18 +359,7 @@  #define FRAME_GROWS_DOWNWARD 1
 
 #define STARTING_FRAME_OFFSET 0
 
-/* If we generate an insn to push BYTES bytes,
-   this says how many the stack pointer really advances by.
-
-   On the H8/300, @-sp really pushes a byte if you ask it to - but that's
-   dangerous, so we claim that it always pushes a word, then we catch
-   the mov.b rx,@-sp and turn it into a mov.w rx,@-sp on output.
-
-   On the H8/300H, we simplify TARGET_QUICKCALL by setting this to 4
-   and doing a similar thing.  */
-
-#define PUSH_ROUNDING(BYTES) \
-  (((BYTES) + PARM_BOUNDARY / 8 - 1) & -PARM_BOUNDARY / 8)
+#define PUSH_ROUNDING(BYTES) h8300_push_rounding (BYTES)
 
 /* Offset of first parameter from the argument pointer register value.  */
 /* Is equal to the size of the saved fp + pc, even if an fp isn't
Index: gcc/config/h8300/h8300.c
===================================================================
--- gcc/config/h8300/h8300.c	2017-10-23 17:11:40.151767139 +0100
+++ gcc/config/h8300/h8300.c	2017-10-23 17:25:38.232865388 +0100
@@ -6044,6 +6044,21 @@  h8300_trampoline_init (rtx m_tramp, tree
       emit_move_insn (mem, tem);
     }
 }
+
+/* Implement PUSH_ROUNDING.
+
+   On the H8/300, @-sp really pushes a byte if you ask it to - but that's
+   dangerous, so we claim that it always pushes a word, then we catch
+   the mov.b rx,@-sp and turn it into a mov.w rx,@-sp on output.
+
+   On the H8/300H, we simplify TARGET_QUICKCALL by setting this to 4
+   and doing a similar thing.  */
+
+poly_int64
+h8300_push_rounding (poly_int64 bytes)
+{
+  return ((bytes + PARM_BOUNDARY / 8 - 1) & (-PARM_BOUNDARY / 8));
+}
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
Index: gcc/config/i386/i386-protos.h
===================================================================
--- gcc/config/i386/i386-protos.h	2017-10-23 11:41:22.909090687 +0100
+++ gcc/config/i386/i386-protos.h	2017-10-23 17:25:38.232865388 +0100
@@ -328,6 +328,8 @@  extern void ix86_core2i7_init_hooks (voi
 
 extern int ix86_atom_sched_reorder (FILE *, int, rtx_insn **, int *, int);
 
+extern poly_int64 ix86_push_rounding (poly_int64);
+
 #ifdef RTX_CODE
 /* Target data for multipass lookahead scheduling.
    Currently used for Core 2/i7 tuning.  */
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	2017-10-23 11:41:22.852023702 +0100
+++ gcc/config/i386/i386.h	2017-10-23 17:25:38.237865208 +0100
@@ -1525,15 +1525,7 @@  #define FRAME_GROWS_DOWNWARD 1
    of the first local allocated.  */
 #define STARTING_FRAME_OFFSET 0
 
-/* If we generate an insn to push BYTES bytes, this says how many the stack
-   pointer really advances by.  On 386, we have pushw instruction that
-   decrements by exactly 2 no matter what the position was, there is no pushb.
-
-   But as CIE data alignment factor on this arch is -4 for 32bit targets
-   and -8 for 64bit targets, we need to make sure all stack pointer adjustments
-   are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
-
-#define PUSH_ROUNDING(BYTES) ROUND_UP ((BYTES), UNITS_PER_WORD)
+#define PUSH_ROUNDING(BYTES) ix86_push_rounding (BYTES)
 
 /* If defined, the maximum amount of space required for outgoing arguments
    will be computed and placed into the variable `crtl->outgoing_args_size'.
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2017-10-23 17:22:32.719227954 +0100
+++ gcc/config/i386/i386.c	2017-10-23 17:25:38.237865208 +0100
@@ -49022,6 +49022,19 @@  ix86_excess_precision (enum excess_preci
   return FLT_EVAL_METHOD_UNPREDICTABLE;
 }
 
+/* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
+   decrements by exactly 2 no matter what the position was, there is no pushb.
+
+   But as CIE data alignment factor on this arch is -4 for 32bit targets
+   and -8 for 64bit targets, we need to make sure all stack pointer adjustments
+   are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
+
+poly_int64
+ix86_push_rounding (poly_int64 bytes)
+{
+  return ROUND_UP (bytes, UNITS_PER_WORD);
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
Index: gcc/config/m32c/m32c-protos.h
===================================================================
--- gcc/config/m32c/m32c-protos.h	2017-09-15 13:56:20.271148742 +0100
+++ gcc/config/m32c/m32c-protos.h	2017-10-23 17:25:38.237865208 +0100
@@ -29,7 +29,7 @@  void m32c_init_expanders (void);
 int  m32c_initial_elimination_offset (int, int);
 void m32c_output_reg_pop (FILE *, int);
 void m32c_output_reg_push (FILE *, int);
-unsigned int  m32c_push_rounding (int);
+poly_int64 m32c_push_rounding (poly_int64);
 void m32c_register_pragmas (void);
 void m32c_note_pragma_address (const char *, unsigned);
 int  m32c_regno_ok_for_base_p (int);
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	2017-10-23 17:11:40.159782457 +0100
+++ gcc/config/m32c/m32c.c	2017-10-23 17:25:38.238865172 +0100
@@ -1290,8 +1290,8 @@  m32c_initial_elimination_offset (int fro
 
 /* Implements PUSH_ROUNDING.  The R8C and M16C have byte stacks, the
    M32C has word stacks.  */
-unsigned int
-m32c_push_rounding (int n)
+poly_int64
+m32c_push_rounding (poly_int64 n)
 {
   if (TARGET_R8C || TARGET_M16C)
     return n;
Index: gcc/config/m68k/m68k-protos.h
===================================================================
--- gcc/config/m68k/m68k-protos.h	2017-09-04 11:49:42.908500725 +0100
+++ gcc/config/m68k/m68k-protos.h	2017-10-23 17:25:38.238865172 +0100
@@ -99,3 +99,4 @@  extern void init_68881_table (void);
 extern rtx m68k_legitimize_call_address (rtx);
 extern rtx m68k_legitimize_sibcall_address (rtx);
 extern int m68k_hard_regno_rename_ok(unsigned int, unsigned int);
+extern poly_int64 m68k_push_rounding (poly_int64);
Index: gcc/config/m68k/m68k.h
===================================================================
--- gcc/config/m68k/m68k.h	2017-10-23 11:41:23.045471107 +0100
+++ gcc/config/m68k/m68k.h	2017-10-23 17:25:38.239865136 +0100
@@ -469,9 +469,7 @@  #define STACK_GROWS_DOWNWARD 1
 #define FRAME_GROWS_DOWNWARD 1
 #define STARTING_FRAME_OFFSET 0
 
-/* On the 680x0, sp@- in a byte insn really pushes a word.
-   On the ColdFire, sp@- in a byte insn pushes just a byte.  */
-#define PUSH_ROUNDING(BYTES) (TARGET_COLDFIRE ? BYTES : ((BYTES) + 1) & ~1)
+#define PUSH_ROUNDING(BYTES) m68k_push_rounding (BYTES)
 
 #define FIRST_PARM_OFFSET(FNDECL) 8
 
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	2017-10-23 17:19:01.404170211 +0100
+++ gcc/config/m68k/m68k.c	2017-10-23 17:25:38.238865172 +0100
@@ -6612,4 +6612,15 @@  m68k_excess_precision (enum excess_preci
   return FLT_EVAL_METHOD_UNPREDICTABLE;
 }
 
+/* Implement PUSH_ROUNDING.  On the 680x0, sp@- in a byte insn really pushes
+   a word.  On the ColdFire, sp@- in a byte insn pushes just a byte.  */
+
+poly_int64
+m68k_push_rounding (poly_int64 bytes)
+{
+  if (TARGET_COLDFIRE)
+    return bytes;
+  return (bytes + 1) & ~1;
+}
+
 #include "gt-m68k.h"
Index: gcc/config/pdp11/pdp11-protos.h
===================================================================
--- gcc/config/pdp11/pdp11-protos.h	2017-09-15 13:56:20.277148839 +0100
+++ gcc/config/pdp11/pdp11-protos.h	2017-10-23 17:25:38.239865136 +0100
@@ -44,3 +44,4 @@  extern void pdp11_asm_output_var (FILE *
 extern void pdp11_expand_prologue (void);
 extern void pdp11_expand_epilogue (void);
 extern int pdp11_branch_cost (void);
+extern poly_int64 pdp11_push_rounding (poly_int64);
Index: gcc/config/pdp11/pdp11.h
===================================================================
--- gcc/config/pdp11/pdp11.h	2017-10-23 11:41:23.044503870 +0100
+++ gcc/config/pdp11/pdp11.h	2017-10-23 17:25:38.239865136 +0100
@@ -263,10 +263,7 @@  #define FRAME_GROWS_DOWNWARD 1
    of the first local allocated.  */
 #define STARTING_FRAME_OFFSET 0
 
-/* If we generate an insn to push BYTES bytes,
-   this says how many the stack pointer really advances by.
-   On the pdp11, the stack is on an even boundary */
-#define PUSH_ROUNDING(BYTES) ((BYTES + 1) & ~1)
+#define PUSH_ROUNDING(BYTES) pdp11_push_rounding (BYTES)
 
 /* current_first_parm_offset stores the # of registers pushed on the 
    stack */
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	2017-10-23 17:11:40.168799690 +0100
+++ gcc/config/pdp11/pdp11.c	2017-10-23 17:25:38.239865136 +0100
@@ -1977,4 +1977,13 @@  pdp11_modes_tieable_p (machine_mode, mac
   return false;
 }
 
+/* Implement PUSH_ROUNDING.  On the pdp11, the stack is on an even
+   boundary.  */
+
+poly_int64
+pdp11_push_rounding (poly_int64 bytes)
+{
+  return (bytes + 1) & ~1;
+}
+
 struct gcc_target targetm = TARGET_INITIALIZER;
Index: gcc/config/stormy16/stormy16-protos.h
===================================================================
--- gcc/config/stormy16/stormy16-protos.h	2017-02-23 19:54:23.000000000 +0000
+++ gcc/config/stormy16/stormy16-protos.h	2017-10-23 17:25:38.239865136 +0100
@@ -28,6 +28,7 @@  extern int direct_return (void);
 extern int xstormy16_interrupt_function_p (void);
 extern int xstormy16_epilogue_uses (int);
 extern void xstormy16_function_profiler (void);
+extern poly_int64 xstormy16_push_rounding (poly_int64);
 
 #if defined (TREE_CODE)
 extern void xstormy16_asm_output_aligned_common (FILE *, tree, const char *,
Index: gcc/config/stormy16/stormy16.h
===================================================================
--- gcc/config/stormy16/stormy16.h	2017-10-23 11:41:22.789153296 +0100
+++ gcc/config/stormy16/stormy16.h	2017-10-23 17:25:38.240865100 +0100
@@ -257,7 +257,7 @@  #define INITIAL_ELIMINATION_OFFSET(FROM,
 
 /* Passing Function Arguments on the Stack.  */
 
-#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
+#define PUSH_ROUNDING(BYTES) xstormy16_push_rounding (BYTES)
 
 
 /* Function Arguments in Registers.  */
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	2017-10-23 17:11:40.184830325 +0100
+++ gcc/config/stormy16/stormy16.c	2017-10-23 17:25:38.240865100 +0100
@@ -2635,6 +2635,14 @@  xstormy16_modes_tieable_p (machine_mode
 {
   return mode1 != BImode && mode2 != BImode;
 }
+
+/* Implement PUSH_ROUNDING.  */
+
+poly_int64
+xstormy16_push_rounding (poly_int64 bytes)
+{
+  return (bytes + 1) & ~1;
+}
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	2017-10-23 17:25:37.064907370 +0100
+++ gcc/expr.c	2017-10-23 17:25:38.241865064 +0100
@@ -3344,10 +3344,9 @@  emit_move_via_integer (machine_mode mode
 emit_move_resolve_push (machine_mode mode, rtx x)
 {
   enum rtx_code code = GET_CODE (XEXP (x, 0));
-  HOST_WIDE_INT adjust;
   rtx temp;
 
-  adjust = GET_MODE_SIZE (mode);
+  poly_int64 adjust = GET_MODE_SIZE (mode);
 #ifdef PUSH_ROUNDING
   adjust = PUSH_ROUNDING (adjust);
 #endif
@@ -3356,14 +3355,12 @@  emit_move_resolve_push (machine_mode mod
   else if (code == PRE_MODIFY || code == POST_MODIFY)
     {
       rtx expr = XEXP (XEXP (x, 0), 1);
-      HOST_WIDE_INT val;
 
       gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
-      gcc_assert (CONST_INT_P (XEXP (expr, 1)));
-      val = INTVAL (XEXP (expr, 1));
+      poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
       if (GET_CODE (expr) == MINUS)
 	val = -val;
-      gcc_assert (adjust == val || adjust == -val);
+      gcc_assert (must_eq (adjust, val) || must_eq (adjust, -val));
       adjust = val;
     }
 
@@ -3405,11 +3402,11 @@  emit_move_complex_push (machine_mode mod
   bool imag_first;
 
 #ifdef PUSH_ROUNDING
-  unsigned int submodesize = GET_MODE_SIZE (submode);
+  poly_int64 submodesize = GET_MODE_SIZE (submode);
 
   /* In case we output to the stack, but the size is smaller than the
      machine can push exactly, we need to use move instructions.  */
-  if (PUSH_ROUNDING (submodesize) != submodesize)
+  if (may_ne (PUSH_ROUNDING (submodesize), submodesize))
     {
       x = emit_move_resolve_push (mode, x);
       return emit_move_insn (x, y);
@@ -4117,7 +4114,7 @@  fixup_args_size_notes (rtx_insn *prev, r
 emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
 {
   rtx dest_addr;
-  unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
+  poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
   rtx dest;
   enum insn_code icode;
 
@@ -4133,7 +4130,7 @@  emit_single_push_insn_1 (machine_mode mo
       if (maybe_expand_insn (icode, 1, ops))
 	return;
     }
-  if (GET_MODE_SIZE (mode) == rounded_size)
+  if (must_eq (GET_MODE_SIZE (mode), rounded_size))
     dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
   /* If we are to pad downward, adjust the stack pointer first and
      then store X into the stack location using an offset.  This is
@@ -4353,9 +4350,9 @@  emit_push_insn (rtx x, machine_mode mode
 	     and such small pushes do rounding that causes trouble.  */
 	  && ((!targetm.slow_unaligned_access (word_mode, align))
 	      || align >= BIGGEST_ALIGNMENT
-	      || (PUSH_ROUNDING (align / BITS_PER_UNIT)
-		  == (align / BITS_PER_UNIT)))
-	  && (HOST_WIDE_INT) PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
+	      || must_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
+			  align / BITS_PER_UNIT))
+	  && must_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
 	{
 	  /* Push padding now if padding above and stack grows down,
 	     or if padding below and stack grows up.
Index: gcc/lra-eliminations.c
===================================================================
--- gcc/lra-eliminations.c	2017-10-23 17:11:40.393228585 +0100
+++ gcc/lra-eliminations.c	2017-10-23 17:25:38.241865064 +0100
@@ -748,7 +748,7 @@  mark_not_eliminable (rtx x, machine_mode
 		  && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
 		  && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset))))
 	{
-	  int size = GET_MODE_SIZE (mem_mode);
+	  poly_int64 size = GET_MODE_SIZE (mem_mode);
 	  
 #ifdef PUSH_ROUNDING
 	  /* If more bytes than MEM_MODE are pushed, account for
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2017-10-23 17:18:57.860160878 +0100
+++ gcc/recog.c	2017-10-23 17:25:38.242865029 +0100
@@ -1258,33 +1258,35 @@  nonmemory_operand (rtx op, machine_mode
 int
 push_operand (rtx op, machine_mode mode)
 {
-  unsigned int rounded_size = GET_MODE_SIZE (mode);
-
-#ifdef PUSH_ROUNDING
-  rounded_size = PUSH_ROUNDING (rounded_size);
-#endif
-
   if (!MEM_P (op))
     return 0;
 
   if (mode != VOIDmode && GET_MODE (op) != mode)
     return 0;
 
+  poly_int64 rounded_size = GET_MODE_SIZE (mode);
+
+#ifdef PUSH_ROUNDING
+  rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
+#endif
+
   op = XEXP (op, 0);
 
-  if (rounded_size == GET_MODE_SIZE (mode))
+  if (must_eq (rounded_size, GET_MODE_SIZE (mode)))
     {
       if (GET_CODE (op) != STACK_PUSH_CODE)
 	return 0;
     }
   else
     {
+      poly_int64 offset;
       if (GET_CODE (op) != PRE_MODIFY
 	  || GET_CODE (XEXP (op, 1)) != PLUS
 	  || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
-	  || !CONST_INT_P (XEXP (XEXP (op, 1), 1))
-	  || INTVAL (XEXP (XEXP (op, 1), 1))
-	     != ((STACK_GROWS_DOWNWARD ? -1 : 1) * (int) rounded_size))
+	  || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
+	  || (STACK_GROWS_DOWNWARD
+	      ? may_ne (offset, -rounded_size)
+	      : may_ne (offset, rounded_size)))
 	return 0;
     }
 
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2017-10-23 17:18:57.861160790 +0100
+++ gcc/reload1.c	2017-10-23 17:25:38.242865029 +0100
@@ -2996,7 +2996,7 @@  elimination_effects (rtx x, machine_mode
       for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
 	if (ep->to_rtx == XEXP (x, 0))
 	  {
-	    int size = GET_MODE_SIZE (mem_mode);
+	    poly_int64 size = GET_MODE_SIZE (mem_mode);
 
 	    /* If more bytes than MEM_MODE are pushed, account for them.  */
 #ifdef PUSH_ROUNDING
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2017-10-23 17:25:32.610067499 +0100
+++ gcc/rtlanal.c	2017-10-23 17:25:38.243864993 +0100
@@ -4518,8 +4518,10 @@  nonzero_bits1 (const_rtx x, scalar_int_m
 	     stack to be momentarily aligned only to that amount,
 	     so we pick the least alignment.  */
 	  if (x == stack_pointer_rtx && PUSH_ARGS)
-	    alignment = MIN ((unsigned HOST_WIDE_INT) PUSH_ROUNDING (1),
-			     alignment);
+	    {
+	      poly_uint64 rounded_1 = PUSH_ROUNDING (poly_int64 (1));
+	      alignment = MIN (known_alignment (rounded_1), alignment);
+	    }
 #endif
 
 	  nonzero &= ~(alignment - 1);
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	2017-10-23 17:19:01.395170091 +0100
+++ gcc/calls.c	2017-10-23 17:25:38.230865460 +0100
@@ -5449,7 +5449,6 @@  store_one_arg (struct arg_data *arg, rtx
     ;
   else if (arg->mode != BLKmode)
     {
-      int size;
       unsigned int parm_align;
 
       /* Argument is a scalar, not entirely passed in registers.
@@ -5462,7 +5461,7 @@  store_one_arg (struct arg_data *arg, rtx
 	 Note that in C the default argument promotions
 	 will prevent such mismatches.  */
 
-      size = GET_MODE_SIZE (arg->mode);
+      poly_int64 size = GET_MODE_SIZE (arg->mode);
       /* Compute how much space the push instruction will push.
 	 On many machines, pushing a byte will advance the stack
 	 pointer by a halfword.  */
@@ -5475,9 +5474,10 @@  store_one_arg (struct arg_data *arg, rtx
 	 round up to a multiple of the alignment for arguments.  */
       if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
 	  != PAD_NONE)
-	used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
-		 / (PARM_BOUNDARY / BITS_PER_UNIT))
-		* (PARM_BOUNDARY / BITS_PER_UNIT));
+	/* At the moment we don't (need to) support ABIs for which the
+	   padding isn't known at compile time.  In principle it should
+	   be easy to add though.  */
+	used = force_align_up (size, PARM_BOUNDARY / BITS_PER_UNIT);
 
       /* Compute the alignment of the pushed argument.  */
       parm_align = arg->locate.boundary;