gdb: mips: Fix the handling of complex type of function return value

$ objdump -d outputs/gdb.base/varargs/varargs
00000001200012e8 <find_max_float_real>:
...
   1200013b8:   c7c10000        lwc1    $f1,0(s8)
   1200013bc:   c7c00004        lwc1    $f0,4(s8)
   1200013c0:   46000886        mov.s   $f2,$f1
   1200013c4:   46000046        mov.s   $f1,$f0
   1200013c8:   46001006        mov.s   $f0,$f2
   1200013cc:   46000886        mov.s   $f2,$f1
   1200013d0:   03c0e825        move    sp,s8
   1200013d4:   dfbe0038        ld      s8,56(sp)
   1200013d8:   67bd0080        daddiu  sp,sp,128
   1200013dc:   03e00008        jr      ra
   1200013e0:   00000000        nop

From the above disassembly, we can see that when the return value of the
function is a complex type and len <= 2 * MIPS64_REGSIZE, the return value
will be passed through $f0 and $f2, so fix the corresponding processing
in mips_n32n64_return_value().

$ make check RUNTESTFLAGS='GDB=../gdb gdb.base/varargs.exp --outdir=test'

Before applying the patch:
 FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3, fc4)
 FAIL: gdb.base/varargs.exp: print find_max_double_real(4, dc1, dc2, dc3, dc4)

 # of expected passes            9
 # of unexpected failures        2

After applying the patch:
 # of expected passes            11

This also fixes:
 FAIL: gdb.base/callfuncs.exp: call inferior func with struct - returns float _Complex

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Co-Authored-By: Maciej W. Rozycki <macro@orcam.me.uk>
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 9394589..4bdbf0f 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -5217,30 +5217,44 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function,
      that all composite results be handled by conversion to implicit first
      parameters.  The MIPS/SGI Fortran implementation has always made a
      specific exception to return COMPLEX results in the floating point
-     registers.]  */
+     registers.]
+
+     From MIPSpro Assembly Language Programmer's Guide, Document Number:
+     007-2418-004
+
+              Software
+     Register Name(from
+     Name     fgregdef.h) Use and Linkage
+     -----------------------------------------------------------------
+     $f0, $f2 fv0, fv1    Hold results of floating-point type function
+                          ($f0) and complex type function ($f0 has the
+                          real part, $f2 has the imaginary part.)  */
 
   if (TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
     return RETURN_VALUE_STRUCT_CONVENTION;
-  else if (type->code () == TYPE_CODE_FLT
-	   && TYPE_LENGTH (type) == 16
+  else if ((type->code () == TYPE_CODE_COMPLEX
+	    || (type->code () == TYPE_CODE_FLT && TYPE_LENGTH (type) == 16))
 	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
-      /* A 128-bit floating-point value fills both $f0 and $f2.  The
-	 two registers are used in the same as memory order, so the
-	 eight bytes with the lower memory address are in $f0.  */
+      /* A complex value of up to 128 bits in width as well as a 128-bit
+	 floating-point value goes in both $f0 and $f2.  A single complex
+	 value is held in the lower halves only of the respective registers.
+	 The two registers are used in the same as memory order, so the
+	 bytes with the lower memory address are in $f0.  */
       if (mips_debug)
 	gdb_printf (gdb_stderr, "Return float in $f0 and $f2\n");
       mips_xfer_register (gdbarch, regcache,
 			  (gdbarch_num_regs (gdbarch)
 			   + mips_regnum (gdbarch)->fp0),
-			  8, gdbarch_byte_order (gdbarch),
+			  TYPE_LENGTH (type) / 2, gdbarch_byte_order (gdbarch),
 			  readbuf, writebuf, 0);
       mips_xfer_register (gdbarch, regcache,
 			  (gdbarch_num_regs (gdbarch)
 			   + mips_regnum (gdbarch)->fp0 + 2),
-			  8, gdbarch_byte_order (gdbarch),
-			  readbuf ? readbuf + 8 : readbuf,
-			  writebuf ? writebuf + 8 : writebuf, 0);
+			  TYPE_LENGTH (type) / 2, gdbarch_byte_order (gdbarch),
+			  readbuf ? readbuf + TYPE_LENGTH (type) / 2 : readbuf,
+			  (writebuf
+			   ? writebuf + TYPE_LENGTH (type) / 2 : writebuf), 0);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (type->code () == TYPE_CODE_FLT