+ else if (len == 16
+ && ((TYPE_CODE (type) == TYPE_CODE_FLT
+ && (gdbarch_long_double_format (gdbarch)
+ == floatformats_ibm_long_double))
+ || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
+ && tdep->soft_float)))
+ {
+ /* Soft-float IBM long double or _Decimal128 passed in
+ four consecutive registers, or on the stack. The
+ registers are not necessarily odd/even pairs. */
+ if (greg > 7)
+ {
+ greg = 11;
+ argoffset = align_up (argoffset, 8);
+ if (write_pass)
+ write_memory (sp + argoffset, val, len);
+ argoffset += 16;
+ }
+ else
+ {
+ if (write_pass)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 0,
+ val + 0);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 1,
+ val + 4);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 2,
+ val + 8);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 3,
+ val + 12);
+ }
+ greg += 4;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && len <= 8
+ && !tdep->soft_float)
+ {
+ /* 32-bit and 64-bit decimal floats go in f1 .. f8. They can
+ end up in memory. */
+
+ if (freg <= 8)
+ {
+ 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;
+
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg, p);
+ }
+
+ freg++;
+ }
+ else
+ {
+ argoffset = align_up (argoffset, len);
+
+ if (write_pass)
+ /* Write value in the stack's parameter save area. */
+ write_memory (sp + argoffset, val, len);
+
+ argoffset += len;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && len == 16
+ && !tdep->soft_float)
+ {
+ /* 128-bit decimal floats go in f2 .. f7, always in even/odd
+ pairs. They can end up in memory, using two doublewords. */
+
+ if (freg <= 6)
+ {
+ /* Make sure freg is even. */
+ freg += freg & 1;
+
+ if (write_pass)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg, val);
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg + 1, val + 8);
+ }
+ }
+ else
+ {
+ argoffset = align_up (argoffset, 8);
+
+ if (write_pass)
+ write_memory (sp + argoffset, val, 16);
+
+ argoffset += 16;
+ }
+
+ /* If a 128-bit decimal float goes to the stack because only f7
+ and f8 are free (thus there's no even/odd register pair
+ available), these registers should be marked as occupied.
+ Hence we increase freg even when writing to memory. */
+ freg += 2;
+ }