-void
-push_parameters (return_type, struct_conv, nargs, args)
- struct type *return_type;
- int struct_conv;
- int nargs;
- value *args;
-{
- int parm_num;
- unsigned int p_words = 0;
- CORE_ADDR left_parm_addr;
-
- /* Start out by creating a space for the return value (if need be). We
- only need to do this if the return value is a struct or union. If we
- do make a space for a struct or union return value, then we must also
- arrange for the base address of that space to go into r12, which is the
- standard place to pass the address of the return value area to the
- callee. Note that only structs and unions are returned in this fashion.
- Ints, enums, pointers, and floats are returned into r2. Doubles are
- returned into the register pair {r2,r3}. Note also that the space
- reserved for a struct or union return value only has to be word aligned
- (not double-word) but it is double-word aligned here anyway (just in
- case that becomes important someday). */
-
- switch (TYPE_CODE (return_type))
- {
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- {
- int return_bytes = ((TYPE_LENGTH (return_type) + 7) / 8) * 8;
- CORE_ADDR rv_addr;
-
- rv_addr = read_register (SP_REGNUM) - return_bytes;
-
- write_register (SP_REGNUM, rv_addr); /* push space onto the stack */
- write_register (SRA_REGNUM, rv_addr);/* set return value register */
- }
- }
-
- /* Here we make a pre-pass on the whole parameter list to figure out exactly
- how many words worth of stuff we are going to pass. */
-
- for (p_words = 0, parm_num = 0; parm_num < nargs; parm_num++)
- p_words += pushed_size (p_words, value_arg_coerce (args[parm_num]));
-
- /* Now, check to see if we have to round up the number of parameter words
- to get up to the next 8-bytes boundary. This may be necessary because
- of the software convention to always keep the stack aligned on an 8-byte
- boundary. */
-
- if (p_words & 1)
- p_words++; /* round to 8-byte boundary */
-
- /* Now figure out the absolute address of the leftmost parameter, and update
- the stack pointer to point at that address. */
-
- left_parm_addr = read_register (SP_REGNUM) - (p_words * 4);
- write_register (SP_REGNUM, left_parm_addr);
-
- /* Now we can go through all of the parameters (in left-to-right order)
- and write them to their parameter stack slots. Note that we are not
- really "pushing" the parameter values. The stack space for these values
- was already allocated above. Now we are just filling it up. */
-
- for (p_words = 0, parm_num = 0; parm_num < nargs; parm_num++)
- p_words +=
- store_parm (p_words, left_parm_addr, value_arg_coerce (args[parm_num]));
-
- /* Now that we are all done storing the parameter values into the stack, we
- must go back and load up the parameter registers with the values from the
- corresponding stack slots. Note that in the two cases of (a) gaps in the
- parameter word sequence causes by (otherwise) misaligned doubles, and (b)
- slots correcponding to structs or unions, the work we do here in loading
- some parameter registers may be unnecessary, but who cares? */
-
- for (p_words = 0; p_words < 8; p_words++)
- {
- write_register (FIRST_PARM_REGNUM + p_words,
- read_memory_integer (left_parm_addr + (p_words * 4), 4));
- }
-}