+ CORE_ADDR func_addr = find_function_addr (function, NULL);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct type *ftype;
+ int opencl_abi = 0;
+ ULONGEST back_chain;
+ /* See for-loop comment below. */
+ int write_pass;
+ /* Size of the by-reference parameter copy region, the final value is
+ computed in the for-loop below. */
+ LONGEST refparam_size = 0;
+ /* Size of the general parameter region, the final value is computed
+ in the for-loop below. */
+ LONGEST gparam_size = 0;
+ /* Kevin writes ... I don't mind seeing tdep->wordsize used in the
+ calls to align_up(), align_down(), etc. because this makes it
+ easier to reuse this code (in a copy/paste sense) in the future,
+ but it is a 64-bit ABI and asserting that the wordsize is 8 bytes
+ at some point makes it easier to verify that this function is
+ correct without having to do a non-local analysis to figure out
+ the possible values of tdep->wordsize. */
+ gdb_assert (tdep->wordsize == 8);
+
+ /* This function exists to support a calling convention that
+ requires floating-point registers. It shouldn't be used on
+ processors that lack them. */
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+ /* By this stage in the proceedings, SP has been decremented by "red
+ zone size" + "struct return size". Fetch the stack-pointer from
+ before this and use that as the BACK_CHAIN. */
+ regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch),
+ &back_chain);
+
+ ftype = check_typedef (value_type (function));
+ if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
+ ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
+ if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
+ && TYPE_CALLING_CONVENTION (ftype) == DW_CC_GDB_IBM_OpenCL)
+ opencl_abi = 1;
+
+ /* Go through the argument list twice.
+
+ Pass 1: Compute the function call's stack space and register
+ requirements.
+
+ Pass 2: Replay the same computation but this time also write the
+ values out to the target. */
+
+ for (write_pass = 0; write_pass < 2; write_pass++)
+ {
+ int argno;
+ /* Next available floating point register for float and double
+ arguments. */
+ int freg = 1;
+ /* Next available general register for non-vector (but possibly
+ float) arguments. */
+ int greg = 3;
+ /* Next available vector register for vector arguments. */
+ int vreg = 2;
+ /* The address, at which the next general purpose parameter
+ (integer, struct, float, vector, ...) should be saved. */
+ CORE_ADDR gparam;
+ /* The address, at which the next by-reference parameter
+ (non-Altivec vector, variably-sized type) should be saved. */
+ CORE_ADDR refparam;
+
+ if (!write_pass)
+ {
+ /* During the first pass, GPARAM and REFPARAM are more like
+ offsets (start address zero) than addresses. That way
+ they accumulate the total stack space each region
+ requires. */
+ gparam = 0;
+ refparam = 0;
+ }
+ else
+ {
+ /* Decrement the stack pointer making space for the Altivec
+ and general on-stack parameters. Set refparam and gparam
+ to their corresponding regions. */
+ refparam = align_down (sp - refparam_size, 16);
+ gparam = align_down (refparam - gparam_size, 16);
+ /* Add in space for the TOC, link editor double word,
+ compiler double word, LR save area, CR save area. */
+ sp = align_down (gparam - 48, 16);
+ }
+
+ /* If the function is returning a `struct', then there is an
+ extra hidden parameter (which will be passed in r3)
+ containing the address of that struct.. In that case we
+ should advance one word and start from r4 register to copy
+ parameters. This also consumes one on-stack parameter slot. */
+ if (struct_return)
+ {
+ if (write_pass)
+ regcache_cooked_write_signed (regcache,
+ tdep->ppc_gp0_regnum + greg,
+ struct_addr);
+ greg++;
+ gparam = align_up (gparam + tdep->wordsize, tdep->wordsize);
+ }
+
+ for (argno = 0; argno < nargs; argno++)
+ {
+ struct value *arg = args[argno];
+ struct type *type = check_typedef (value_type (arg));
+ const bfd_byte *val = value_contents (arg);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
+ {
+ /* Floats and Doubles go in f1 .. f13. They also
+ consume a left aligned GREG,, and can end up in
+ memory. */
+ if (write_pass)
+ {
+ gdb_byte regval[MAX_REGISTER_SIZE];
+ const gdb_byte *p;
+
+ /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
+
+ "Single precision floating point values are mapped to
+ the first word in a single doubleword."
+
+ And version 1.9 says:
+
+ "Single precision floating point values are mapped to
+ the second word in a single doubleword."
+
+ GDB then writes single precision floating point values
+ at both words in a doubleword, to support both ABIs. */
+ if (TYPE_LENGTH (type) == 4)
+ {
+ memcpy (regval, val, 4);
+ memcpy (regval + 4, val, 4);
+ p = regval;
+ }
+ else
+ p = val;
+
+ /* Write value in the stack's parameter save area. */
+ write_memory (gparam, p, 8);
+
+ if (freg <= 13)
+ {
+ struct type *regtype
+ = register_type (gdbarch, tdep->ppc_fp0_regnum);
+
+ convert_typed_floating (val, type, regval, regtype);
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg,
+ regval);
+ }
+ if (greg <= 10)
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg,
+ regval);
+ }
+
+ freg++;
+ greg++;
+ /* Always consume parameter stack space. */
+ gparam = align_up (gparam + 8, tdep->wordsize);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) == 16
+ && (gdbarch_long_double_format (gdbarch)
+ == floatformats_ibm_long_double))
+ {
+ /* IBM long double stored in two doublewords of the
+ parameter save area and corresponding registers. */
+ if (write_pass)
+ {
+ if (!tdep->soft_float && freg <= 13)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg,
+ val);
+ if (freg <= 12)
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg + 1,
+ val + 8);
+ }
+ if (greg <= 10)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg,
+ val);
+ if (greg <= 9)
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 1,
+ val + 8);
+ }
+ write_memory (gparam, val, TYPE_LENGTH (type));
+ }
+ freg += 2;
+ greg += 2;
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
+ && TYPE_LENGTH (type) <= 8)
+ {
+ /* 32-bit and 64-bit decimal floats go in f1 .. f13. They can
+ end up in memory. */
+ if (write_pass)
+ {
+ gdb_byte regval[MAX_REGISTER_SIZE];
+ const gdb_byte *p;
+
+ /* 32-bit decimal floats are right aligned in the
+ doubleword. */
+ if (TYPE_LENGTH (type) == 4)
+ {
+ memcpy (regval + 4, val, 4);
+ p = regval;
+ }
+ else
+ p = val;
+
+ /* Write value in the stack's parameter save area. */
+ write_memory (gparam, p, 8);
+
+ if (freg <= 13)
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg, p);
+ }
+
+ freg++;
+ greg++;
+ /* Always consume parameter stack space. */
+ gparam = align_up (gparam + 8, tdep->wordsize);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT &&
+ TYPE_LENGTH (type) == 16)
+ {
+ /* 128-bit decimal floats go in f2 .. f12, always in even/odd
+ pairs. They can end up in memory, using two doublewords. */
+ if (write_pass)
+ {
+ if (freg <= 12)
+ {
+ /* Make sure freg is even. */
+ freg += freg & 1;
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg, val);
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg + 1, val + 8);
+ }
+
+ write_memory (gparam, val, TYPE_LENGTH (type));
+ }
+
+ freg += 2;
+ greg += 2;
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
+ else if (TYPE_LENGTH (type) < 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type)
+ && opencl_abi)
+ {
+ /* OpenCL vectors shorter than 16 bytes are passed as if
+ a series of independent scalars. */
+ struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+ int i, nelt = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
+
+ for (i = 0; i < nelt; i++)
+ {
+ const gdb_byte *elval = val + i * TYPE_LENGTH (eltype);
+
+ if (TYPE_CODE (eltype) == TYPE_CODE_FLT)
+ {
+ if (write_pass)
+ {
+ gdb_byte regval[MAX_REGISTER_SIZE];
+ const gdb_byte *p;
+
+ if (TYPE_LENGTH (eltype) == 4)
+ {
+ memcpy (regval, elval, 4);
+ memcpy (regval + 4, elval, 4);
+ p = regval;
+ }
+ else
+ p = elval;
+
+ write_memory (gparam, p, 8);
+
+ if (freg <= 13)
+ {
+ int regnum = tdep->ppc_fp0_regnum + freg;
+ struct type *regtype
+ = register_type (gdbarch, regnum);
+
+ convert_typed_floating (elval, eltype,
+ regval, regtype);
+ regcache_cooked_write (regcache, regnum, regval);
+ }
+
+ if (greg <= 10)
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg,
+ regval);
+ }
+
+ freg++;
+ greg++;
+ gparam = align_up (gparam + 8, tdep->wordsize);
+ }
+ else
+ {
+ if (write_pass)
+ {
+ ULONGEST word = unpack_long (eltype, elval);
+ if (greg <= 10)
+ regcache_cooked_write_unsigned
+ (regcache, tdep->ppc_gp0_regnum + greg, word);
+
+ write_memory_unsigned_integer
+ (gparam, tdep->wordsize, byte_order, word);
+ }
+
+ greg++;
+ gparam = align_up (gparam + TYPE_LENGTH (eltype),
+ tdep->wordsize);
+ }
+ }
+ }
+ else if (TYPE_LENGTH (type) >= 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type)
+ && opencl_abi)
+ {
+ /* OpenCL vectors 16 bytes or longer are passed as if
+ a series of AltiVec vectors. */
+ int i;
+
+ for (i = 0; i < TYPE_LENGTH (type) / 16; i++)
+ {
+ const gdb_byte *elval = val + i * 16;
+
+ gparam = align_up (gparam, 16);
+ greg += greg & 1;
+
+ if (write_pass)
+ {
+ if (vreg <= 13)
+ regcache_cooked_write (regcache,
+ tdep->ppc_vr0_regnum + vreg,
+ elval);
+
+ write_memory (gparam, elval, 16);
+ }
+
+ greg += 2;
+ vreg++;
+ gparam += 16;
+ }
+ }
+ else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
+ {
+ /* In the Altivec ABI, vectors go in the vector registers
+ v2 .. v13, as well as the parameter area -- always at
+ 16-byte aligned addresses. */
+
+ gparam = align_up (gparam, 16);
+ greg += greg & 1;
+
+ if (write_pass)
+ {
+ if (vreg <= 13)
+ regcache_cooked_write (regcache,
+ tdep->ppc_vr0_regnum + vreg, val);
+
+ write_memory (gparam, val, TYPE_LENGTH (type));
+ }
+
+ greg += 2;
+ vreg++;
+ gparam += 16;
+ }
+ else if (TYPE_LENGTH (type) >= 16 && TYPE_VECTOR (type)
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ /* Non-Altivec vectors are passed by reference. */
+
+ /* Copy value onto the stack ... */
+ refparam = align_up (refparam, 16);
+ if (write_pass)
+ write_memory (refparam, val, TYPE_LENGTH (type));
+
+ /* ... and pass a pointer to the copy as parameter. */
+ if (write_pass)
+ {
+ if (greg <= 10)
+ regcache_cooked_write_unsigned (regcache,
+ tdep->ppc_gp0_regnum +
+ greg, refparam);
+ write_memory_unsigned_integer (gparam, tdep->wordsize,
+ byte_order, refparam);
+ }
+ greg++;
+ gparam = align_up (gparam + tdep->wordsize, tdep->wordsize);
+ refparam = align_up (refparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
+ else if ((TYPE_CODE (type) == TYPE_CODE_INT
+ || TYPE_CODE (type) == TYPE_CODE_ENUM
+ || TYPE_CODE (type) == TYPE_CODE_BOOL
+ || TYPE_CODE (type) == TYPE_CODE_CHAR
+ || TYPE_CODE (type) == TYPE_CODE_PTR
+ || TYPE_CODE (type) == TYPE_CODE_REF)
+ && TYPE_LENGTH (type) <= 8)
+ {
+ /* Scalars and Pointers get sign[un]extended and go in
+ gpr3 .. gpr10. They can also end up in memory. */
+ if (write_pass)
+ {
+ /* Sign extend the value, then store it unsigned. */
+ ULONGEST word = unpack_long (type, val);
+ /* Convert any function code addresses into
+ descriptors. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ || TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ struct type *target_type;
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (target_type) == TYPE_CODE_FUNC
+ || TYPE_CODE (target_type) == TYPE_CODE_METHOD)
+ {
+ CORE_ADDR desc = word;
+ convert_code_addr_to_desc_addr (word, &desc);
+ word = desc;
+ }
+ }
+ if (greg <= 10)
+ regcache_cooked_write_unsigned (regcache,
+ tdep->ppc_gp0_regnum +
+ greg, word);
+ write_memory_unsigned_integer (gparam, tdep->wordsize,
+ byte_order, word);
+ }
+ greg++;
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
+ else
+ {
+ int byte;
+ for (byte = 0; byte < TYPE_LENGTH (type);
+ byte += tdep->wordsize)
+ {
+ if (write_pass && greg <= 10)
+ {
+ gdb_byte regval[MAX_REGISTER_SIZE];
+ int len = TYPE_LENGTH (type) - byte;
+ if (len > tdep->wordsize)
+ len = tdep->wordsize;
+ memset (regval, 0, sizeof regval);
+ /* The ABI (version 1.9) specifies that values
+ smaller than one doubleword are right-aligned
+ and those larger are left-aligned. GCC
+ versions before 3.4 implemented this
+ incorrectly; see
+ <http://gcc.gnu.org/gcc-3.4/powerpc-abi.html>. */
+ if (byte == 0)
+ memcpy (regval + tdep->wordsize - len,
+ val + byte, len);
+ else
+ memcpy (regval, val + byte, len);
+ regcache_cooked_write (regcache, greg, regval);
+ }
+ greg++;
+ }
+ if (write_pass)
+ {
+ /* WARNING: cagney/2003-09-21: Strictly speaking, this
+ isn't necessary, unfortunately, GCC appears to get
+ "struct convention" parameter passing wrong putting
+ odd sized structures in memory instead of in a
+ register. Work around this by always writing the
+ value to memory. Fortunately, doing this
+ simplifies the code. */
+ int len = TYPE_LENGTH (type);
+ if (len < tdep->wordsize)
+ write_memory (gparam + tdep->wordsize - len, val, len);
+ else
+ write_memory (gparam, val, len);
+ }
+ if (freg <= 13
+ && TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1
+ && TYPE_LENGTH (type) <= 16)
+ {
+ /* The ABI (version 1.9) specifies that structs
+ containing a single floating-point value, at any
+ level of nesting of single-member structs, are
+ passed in floating-point registers. */
+ while (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1)
+ type = check_typedef (TYPE_FIELD_TYPE (type, 0));
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (TYPE_LENGTH (type) <= 8)
+ {
+ if (write_pass)
+ {
+ gdb_byte regval[MAX_REGISTER_SIZE];
+ struct type *regtype
+ = register_type (gdbarch,
+ tdep->ppc_fp0_regnum);
+ convert_typed_floating (val, type, regval,
+ regtype);
+ regcache_cooked_write (regcache,
+ (tdep->ppc_fp0_regnum
+ + freg),
+ regval);
+ }
+ freg++;
+ }
+ else if (TYPE_LENGTH (type) == 16
+ && (gdbarch_long_double_format (gdbarch)
+ == floatformats_ibm_long_double))
+ {
+ if (write_pass)
+ {
+ regcache_cooked_write (regcache,
+ (tdep->ppc_fp0_regnum
+ + freg),
+ val);
+ if (freg <= 12)
+ regcache_cooked_write (regcache,
+ (tdep->ppc_fp0_regnum
+ + freg + 1),
+ val + 8);
+ }
+ freg += 2;
+ }
+ }
+ }
+ /* Always consume parameter stack space. */
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
+ }
+
+ if (!write_pass)
+ {
+ /* Save the true region sizes ready for the second pass. */
+ refparam_size = refparam;
+ /* Make certain that the general parameter save area is at
+ least the minimum 8 registers (or doublewords) in size. */
+ if (greg < 8)
+ gparam_size = 8 * tdep->wordsize;
+ else
+ gparam_size = gparam;
+ }
+ }
+
+ /* Update %sp. */
+ regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);
+
+ /* Write the backchain (it occupies WORDSIZED bytes). */
+ write_memory_signed_integer (sp, tdep->wordsize, byte_order, back_chain);
+
+ /* Point the inferior function call's return address at the dummy's
+ breakpoint. */
+ regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
+
+ /* Use the func_addr to find the descriptor, and use that to find
+ the TOC. If we're calling via a function pointer, the pointer
+ itself identifies the descriptor. */
+ {
+ struct type *ftype = check_typedef (value_type (function));
+ CORE_ADDR desc_addr = value_as_address (function);
+
+ if (TYPE_CODE (ftype) == TYPE_CODE_PTR
+ || convert_code_addr_to_desc_addr (func_addr, &desc_addr))
+ {
+ /* The TOC is the second double word in the descriptor. */
+ CORE_ADDR toc =
+ read_memory_unsigned_integer (desc_addr + tdep->wordsize,
+ tdep->wordsize, byte_order);
+ regcache_cooked_write_unsigned (regcache,
+ tdep->ppc_gp0_regnum + 2, toc);
+ }
+ }
+
+ return sp;