+ /* Now write each of the args at the proper offset down the stack. */
+ for (i = 0; i < nargs; i++)
+ write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
+
+ /* If a structure has to be returned, set up register 28 to hold its
+ address */
+ if (struct_return)
+ write_register (28, struct_addr);
+
+ /* For the PA64 we must pass a pointer to the outgoing argument list.
+ The ABI mandates that the pointer should point to the first byte of
+ storage beyond the register flushback area.
+
+ However, the call dummy expects the outgoing argument pointer to
+ be passed in register %r4. */
+ write_register (4, orig_sp + REG_PARM_STACK_SPACE);
+
+ /* ?!? This needs further work. We need to set up the global data
+ pointer for this procedure. This assumes the same global pointer
+ for every procedure. The call dummy expects the dp value to
+ be passed in register %r6. */
+ write_register (6, read_register (27));
+
+ /* The stack will have 64 bytes of additional space for a frame marker. */
+ return sp + 64;
+}
+
+#else
+
+/* This function pushes a stack frame with arguments as part of the
+ inferior function calling mechanism.
+
+ This is the version of the function for the 32-bit PA machines, in
+ which later arguments appear at lower addresses. (The stack always
+ grows towards higher addresses.)
+
+ We simply allocate the appropriate amount of stack space and put
+ arguments into their proper slots. The call dummy code will copy
+ arguments into registers as needed by the ABI. */
+
+CORE_ADDR
+hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr *args;
+ CORE_ADDR sp;
+ int struct_return;
+ CORE_ADDR struct_addr;
+{
+ /* array of arguments' offsets */
+ int *offset = (int *) alloca (nargs * sizeof (int));
+
+ /* array of arguments' lengths: real lengths in bytes, not aligned to
+ word size */
+ int *lengths = (int *) alloca (nargs * sizeof (int));
+
+ /* The number of stack bytes occupied by the current argument. */
+ int bytes_reserved;
+
+ /* The total number of bytes reserved for the arguments. */
+ int cum_bytes_reserved = 0;
+
+ /* Similarly, but aligned. */
+ int cum_bytes_aligned = 0;
+ int i;
+
+ /* Iterate over each argument provided by the user. */
+ for (i = 0; i < nargs; i++)
+ {
+ lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[i]));
+
+ /* Align the size of the argument to the word size for this
+ target. */
+ bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
+
+ offset[i] = cum_bytes_reserved + lengths[i];
+
+ /* If the argument is a double word argument, then it needs to be
+ double word aligned. */