From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31832 invoked by alias); 13 Sep 2013 21:55:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 31817 invoked by uid 89); 13 Sep 2013 21:55:51 -0000 Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.222.213) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Sep 2013 21:55:51 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_50,KHOP_THREADED,MSGID_MULTIPLE_AT autolearn=no version=3.3.2 X-HELO: mailhost.u-strasbg.fr Received: from mailhost.u-strasbg.fr (localhost [127.0.0.1]) by antispam (Postfix) with ESMTP id A784EC0C9B; Fri, 13 Sep 2013 23:55:44 +0200 (CEST) Received: from mailhost.u-strasbg.fr (localhost [127.0.0.1]) by antivirus (Postfix) with ESMTP id 948AAC0BFB; Fri, 13 Sep 2013 23:55:44 +0200 (CEST) Received: from md13.u-strasbg.fr (md13.u-strasbg.fr [130.79.200.248]) by mr3.u-strasbg.fr (Postfix) with ESMTP id 6BC0DC0E56; Fri, 13 Sep 2013 23:55:42 +0200 (CEST) Received: from ms11.u-strasbg.fr (ms11.u-strasbg.fr [130.79.204.111]) by md13.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id r8DLtfjT006854 ; Fri, 13 Sep 2013 23:55:42 +0200 (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from E6510Muller (lec67-4-82-230-53-140.fbx.proxad.net [82.230.53.140]) (Authenticated sender: mullerp) by ms11.u-strasbg.fr (Postfix) with ESMTPSA id 3C5901FD90; Fri, 13 Sep 2013 23:55:40 +0200 (CEST) From: "Pierre Muller" To: "'Joel Brobecker'" Cc: References: <000301cea9b9$4b298820$e17c9860$@muller@ics-cnrs.unistra.fr> <20130904220309.GA3226@adacore.com> In-Reply-To: <20130904220309.GA3226@adacore.com> Subject: RE: [RFC] Improve windows amd64 call command Date: Fri, 13 Sep 2013 21:55:00 -0000 Message-ID: <002901ceb0cb$fc390cd0$f4ab2670$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-SW-Source: 2013-09/txt/msg00410.txt.bz2 I tried to merge the two patches and I will send a new RFA in the other thread. Pierre Muller > -----Message d'origine----- > De=A0: gdb-patches-owner@sourceware.org [mailto:gdb-patches- > owner@sourceware.org] De la part de Joel Brobecker > Envoy=E9=A0: jeudi 5 septembre 2013 00:03 > =C0=A0: Pierre Muller > Cc=A0: gdb-patches@sourceware.org > Objet=A0: Re: [RFC] Improve windows amd64 call command >=20 > > mingw64 GDB does a poor job when it comes to > > handling call command. > > > > This is because it uses the SYS V ABI, > > while windows OS uses a separate ABI called Microsoft x64 calling > convention > > in >=20 > Hi Pierre. I think you patch is the same as the first one I initially > proposed, and got rejected by Mark saying that we should really have our > own separate code for Windows as the two ABIs are really completely > different. Since then, I've re-implemented the calling convention > following that advice. The patch is posted at: > http://www.sourceware.org/ml/gdb-patches/2013-01/msg00332.html >=20 > I cannot believe it was 8 months ago! I was waiting on Mark's input, > and then meant to just go ahead and finish it up, and since then, > life has taken over. >=20 > Can you try my patch and see if it works as well for you? (assuming > it still applies - otherwise, I will rebase for you tomorrow). > If not, we could work together to finalize it and get it in for > everyone to enjoy. >=20 > > > > http://en.wikipedia.org/wiki/X86_calling_conventions#x86- > 64_calling_conventi > > ons > > > > This patch removes all failures in gdb.base/call*.exp > > when using x86_6'-w64-mingw32-gcc version 4.7.3, > > but some of those results might be GCC version dependent... > > It would also be nice to know what happens if a Microsoft compiler > > is used... > > > > The only regression I found in gdb.base is in varargs.exp: > > < 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) > > < FAIL: gdb.base/varargs.exp: print find_max_long_double_real(4, ldc1, > ldc2, > > ldc3, ldc4) > > --- > > > FAIL: gdb.base/varargs.exp: print > find_max_double(5,1.0,17.0,2.0,3.0,4.0) > > It's isn't a true regression, as there is only one failure instead of > three, > > but the one failure seemed to pass without the change... > > I didn't investigate that yet. > > > > The overall change for gdb.base testsuite runs is 253 failures instead of > > 327 > > without the patch. > > > > Comments welcome, > > > > > > Pierre Muller > > GDB pascal language maintainer > > > > 2013-09-03 Pierre Muller > > > > * i386-tdep.h (struct gdbarch_tdep): Add new fields, > > neede to handle amd64 windows specfic calling conventions. > > * amd64-tdep.c (amd64_dummy_call_fp_regs): New array. > > (amd64_return_value): Add debug infrun information. > > (amd64_push_arguments): handle new fields of gdbarch_tdep > > structure. > > (amd64_push_dummy_call): Likewise. > > (amd64_init_abi): Initialize added fields. > > * amd64-windows-tdep.c (amd64_windows_dummy_call_fp_regs): New > > array. > > (amd64_windows_classify): Try to comply with Windows ABI. > > (amd64_windows_return_value): Do not use $xmm0 return register > > for "long double" return type. > > (amd64_windows_init_abi): Initialize new fields of gdbarch_tdep. > > > > > > Index: src/gdb/i386-tdep.h > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > RCS file: /cvs/src/src/gdb/i386-tdep.h,v > > retrieving revision 1.82 > > diff -u -p -r1.82 i386-tdep.h > > --- src/gdb/i386-tdep.h 1 Jan 2013 06:32:45 -0000 1.82 > > +++ src/gdb/i386-tdep.h 4 Sep 2013 21:21:34 -0000 > > @@ -80,6 +80,10 @@ struct gdbarch_tdep > > are passed through the stack on x86. */ > > int call_dummy_num_integer_regs; > > int *call_dummy_integer_regs; > > + /* Used on amd64 only. The floating point registers used to pass > > + reals when making function calls. */ > > + int call_dummy_num_fp_regs; > > + int *call_dummy_fp_regs; > > > > /* Used on amd64 only. Classify TYPE according to calling conventions, > > and store the result in CLASS. */ > > @@ -104,6 +108,14 @@ struct gdbarch_tdep > > above). */ > > int integer_param_regs_saved_in_caller_frame; > > > > + /* Used on amd64 only. > > + > > + If non-zero, integer and floating point registers are coupled: > > + Either ECX or XMM0 are used as first register argument, > > + but second will be EDX or XMM1, never ECX nor XMM0, this > > + coupled behavior is used in Microsoft x64 ABI. */ > > + int integer_and_fp_regs_coupled; > > + > > /* Floating-point registers. */ > > struct regset *fpregset; > > size_t sizeof_fpregset; > > Index: src/gdb/amd64-tdep.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > RCS file: /cvs/src/src/gdb/amd64-tdep.c,v > > retrieving revision 1.117 > > diff -u -p -r1.117 amd64-tdep.c > > --- src/gdb/amd64-tdep.c 1 Jan 2013 06:32:37 -0000 1.117 > > +++ src/gdb/amd64-tdep.c 4 Sep 2013 21:21:36 -0000 > > @@ -103,6 +103,16 @@ static int amd64_dummy_call_integer_regs > > 9 /* %r9 */ > > }; > > > > +/* The registers used to pass floating point arguments in function call. > > */ > > +static int amd64_dummy_call_fp_regs[] =3D > > +{ > > + /* %xmm0 ... %xmm7 */ > > + AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM, > > + AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3, > > + AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5, > > + AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7, > > +}; > > + > > /* DWARF Register Number Mapping as defined in the System V psABI, > > section 3.6. */ > > > > @@ -650,6 +660,8 @@ amd64_return_value (struct gdbarch *gdba > > read_memory (addr, readbuf, TYPE_LENGTH (type)); > > } > > > > + if (debug_infrun) > > + printf_filtered (_("Return value as memory address in RAX\n")); > > return RETURN_VALUE_ABI_RETURNS_ADDRESS; > > } > > > > @@ -674,6 +686,8 @@ amd64_return_value (struct gdbarch *gdba > > regcache_raw_write_unsigned (regcache, AMD64_FTAG_REGNUM, 0xfff); > > } > > > > + if (debug_infrun) > > + printf_filtered (_("Complex X87 return value in ST0/ST1\n")); > > return RETURN_VALUE_REGISTER_CONVENTION; > > } > > > > @@ -739,6 +753,9 @@ amd64_return_value (struct gdbarch *gdba > > if (writebuf) > > regcache_raw_write_part (regcache, regnum, offset, min (len, 8), > > writebuf + i * 8); > > + if (debug_infrun) > > + printf_filtered (_("Return value in register %s\n"), > > + gdbarch_register_name (gdbarch, regnum)); > > } > > > > return RETURN_VALUE_REGISTER_CONVENTION; > > @@ -753,15 +770,10 @@ amd64_push_arguments (struct regcache *r > > struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > > int *integer_regs =3D tdep->call_dummy_integer_regs; > > int num_integer_regs =3D tdep->call_dummy_num_integer_regs; > > + int *sse_regs =3D tdep->call_dummy_fp_regs; > > + int num_sse_regs =3D tdep->call_dummy_num_fp_regs; > > + int regs_coupled =3D tdep->integer_and_fp_regs_coupled; > > > > - static int sse_regnum[] =3D > > - { > > - /* %xmm0 ... %xmm7 */ > > - AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM, > > - AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3, > > - AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5, > > - AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7, > > - }; > > struct value **stack_args =3D alloca (nargs * sizeof (struct value *= )); > > /* An array that mirrors the stack_args array. For all arguments > > that are passed by MEMORY, if that argument's address also needs > > @@ -769,8 +781,10 @@ amd64_push_arguments (struct regcache *r > > that register number (or a negative value otherwise). */ > > int *arg_addr_regno =3D alloca (nargs * sizeof (int)); > > int num_stack_args =3D 0; > > - int num_elements =3D 0; > > - int element =3D 0; > > + int total_64bit_elements =3D 0; > > + int stack_64bit_elements =3D 0; > > + int indirect_element =3D 0; > > + int addr_element =3D 0; > > int integer_reg =3D 0; > > int sse_reg =3D 0; > > int i; > > @@ -798,19 +812,27 @@ amd64_push_arguments (struct regcache *r > > for (j =3D 0; j < 2; j++) > > { > > if (class[j] =3D=3D AMD64_INTEGER) > > - needed_integer_regs++; > > + { > > + needed_integer_regs++; > > + if (regs_coupled) > > + needed_sse_regs++; > > + } > > else if (class[j] =3D=3D AMD64_SSE) > > - needed_sse_regs++; > > + { > > + needed_sse_regs++; > > + if (regs_coupled) > > + needed_integer_regs++; > > + } > > } > > > > /* Check whether enough registers are available, and if the > > argument should be passed in registers at all. */ > > if (integer_reg + needed_integer_regs > num_integer_regs > > - || sse_reg + needed_sse_regs > ARRAY_SIZE (sse_regnum) > > + || sse_reg + needed_sse_regs > num_sse_regs > > || (needed_integer_regs =3D=3D 0 && needed_sse_regs =3D=3D 0)) > > { > > /* The argument will be passed on the stack. */ > > - num_elements +=3D ((len + 7) / 8); > > + total_64bit_elements +=3D ((len + 7) / 8); > > stack_args[num_stack_args] =3D args[i]; > > /* If this is an AMD64_MEMORY argument whose address must also > > be passed in one of the integer registers, reserve that > > @@ -818,11 +840,29 @@ amd64_push_arguments (struct regcache *r > > we can store the argument address as soon as we know it. */ > > if (class[0] =3D=3D AMD64_MEMORY > > && tdep->memory_args_by_pointer > > - && integer_reg < tdep->call_dummy_num_integer_regs) > > - arg_addr_regno[num_stack_args] =3D > > - tdep->call_dummy_integer_regs[integer_reg++]; > > + && integer_reg < num_integer_regs) > > + { > > + arg_addr_regno[num_stack_args] =3D > > + tdep->call_dummy_integer_regs[integer_reg++]; > > + if (debug_infrun) > > + printf_filtered (_("Arg. %d (len=3D%d on stack)," > > + " addr. in register %s\n"), > > + i, len, gdbarch_register_name (gdbarch, > > + arg_addr_regno[num_stack_args])); > > + if (regs_coupled) > > + sse_reg++; > > + } > > else > > - arg_addr_regno[num_stack_args] =3D -1; > > + { > > + arg_addr_regno[num_stack_args] =3D -1; > > + if (tdep->memory_args_by_pointer > > + && len !=3D 1 && len !=3D 2 && len !=3D 4 && len !=3D 8) > > + total_64bit_elements +=3D 1; > > + stack_64bit_elements +=3D 1; > > + if (debug_infrun) > > + printf_filtered (_("Arg. %d (len=3D%d on stack)\n"), > > + i, len); > > + } > > num_stack_args++; > > } > > else > > @@ -842,15 +882,28 @@ amd64_push_arguments (struct regcache *r > > { > > case AMD64_INTEGER: > > regnum =3D integer_regs[integer_reg++]; > > + if (debug_infrun) > > + printf_filtered (_("Arg. %d in register %s\n"), > > + i, gdbarch_register_name (gdbarch, regnum)); > > + if (regs_coupled) > > + sse_reg++; > > break; > > > > case AMD64_SSE: > > - regnum =3D sse_regnum[sse_reg++]; > > + regnum =3D sse_regs[sse_reg++]; > > + if (debug_infrun) > > + printf_filtered (_("Arg. %d in register %s\n"), > > + i, gdbarch_register_name (gdbarch, regnum)); > > + if (regs_coupled) > > + integer_reg++; > > break; > > > > case AMD64_SSEUP: > > gdb_assert (sse_reg > 0); > > - regnum =3D sse_regnum[sse_reg - 1]; > > + if (debug_infrun) > > + printf_filtered (_("Arg. %d in register %s at offset > > 8\n"), > > + i, gdbarch_register_name (gdbarch, regnum)); > > + regnum =3D sse_regs[sse_reg - 1]; > > offset =3D 8; > > break; > > > > @@ -867,7 +920,7 @@ amd64_push_arguments (struct regcache *r > > } > > > > /* Allocate space for the arguments on the stack. */ > > - sp -=3D num_elements * 8; > > + sp -=3D total_64bit_elements * 8; > > > > /* The psABI says that "The end of the input argument area shall be > > aligned on a 16 byte boundary." */ > > @@ -878,9 +931,20 @@ amd64_push_arguments (struct regcache *r > > { > > struct type *type =3D value_type (stack_args[i]); > > const gdb_byte *valbuf =3D value_contents (stack_args[i]); > > - CORE_ADDR arg_addr =3D sp + element * 8; > > + int len =3D TYPE_LENGTH (type); > > + CORE_ADDR arg_addr; > > + int indirect =3D (arg_addr_regno[i] > 0) > > + || (tdep->memory_args_by_pointer > > + && len !=3D 1 && len !=3D 2 && len !=3D 4 && len !=3D 8); > > + if (indirect) > > + arg_addr =3D sp + (stack_64bit_elements + indirect_element) * 8; > > + else > > + arg_addr =3D sp + addr_element * 8; > > > > - write_memory (arg_addr, valbuf, TYPE_LENGTH (type)); > > + write_memory (arg_addr, valbuf, len); > > + if (debug_infrun) > > + printf_unfiltered (_("Stack arg. %d (len=3D%d) at addr. %s\n"), > > + i, len, paddress (gdbarch, arg_addr)); > > if (arg_addr_regno[i] >=3D 0) > > { > > /* We also need to store the address of that argument in > > @@ -890,8 +954,34 @@ amd64_push_arguments (struct regcache *r > > > > store_unsigned_integer (buf, 8, byte_order, arg_addr); > > regcache_cooked_write (regcache, arg_addr_regno[i], buf); > > + if (debug_infrun) > > + printf_unfiltered (_("Stack arg. %d addr. stored in reg. %s\n"), > > + i, gdbarch_register_name (gdbarch, > > + arg_addr_regno[i])); > > } > > - element +=3D ((TYPE_LENGTH (type) + 7) / 8); > > + else if (indirect) > > + { > > + /* We also need to store the address of that argument in > > + the given register. */ > > + gdb_byte buf[8]; > > + enum bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); > > + CORE_ADDR arg_addrp =3D sp + addr_element * 8; > > + > > + store_unsigned_integer (buf, 8, byte_order, arg_addr); > > + write_memory (arg_addrp, buf, 8); > > + > > + if (debug_infrun) > > + printf_unfiltered (_("Stack arg. %d addr. stored at addr. > > %s\n"), > > + i, paddress (gdbarch, arg_addrp)); > > + } > > + if (indirect) > > + { > > + indirect_element +=3D ((len + 7) / 8); > > + if (arg_addr_regno[i] < 0) > > + addr_element +=3D 1; > > + } > > + else > > + addr_element +=3D ((len + 7) / 8); > > } > > > > /* The psABI says that "For calls that may call functions that use > > @@ -899,7 +989,7 @@ amd64_push_arguments (struct regcache *r > > containing ellipsis (...) in the declaration) %al is used as > > hidden argument to specify the number of SSE registers used. */ > > regcache_raw_write_unsigned (regcache, AMD64_RAX_REGNUM, sse_reg); > > - return sp; > > + return sp; > > } > > > > static CORE_ADDR > > @@ -913,7 +1003,11 @@ amd64_push_dummy_call (struct gdbarch *g > > gdb_byte buf[8]; > > > > /* Pass arguments. */ > > + if (debug_infrun) > > + printf_unfiltered (_("Start sp=3D%s\n"), paddress (gdbarch, sp)); > > sp =3D amd64_push_arguments (regcache, nargs, args, sp, struct_retur= n); > > + if (debug_infrun) > > + printf_unfiltered (_("sp after push args=3D%s\n"), paddress (gdbar= ch, > > sp)); > > > > /* Pass "hidden" argument". */ > > if (struct_return) > > @@ -929,19 +1023,33 @@ amd64_push_dummy_call (struct gdbarch *g > > /* Reserve some memory on the stack for the integer-parameter > registers, > > if required by the ABI. */ > > if (tdep->integer_param_regs_saved_in_caller_frame) > > - sp -=3D tdep->call_dummy_num_integer_regs * 8; > > + { > > + sp -=3D tdep->call_dummy_num_integer_regs * 8; > > + if (debug_infrun) > > + printf_unfiltered (_("sp after integer reg. saved area=3D%s\n"), > > + paddress (gdbarch, sp)); > > + > > + } > > > > /* Store return address. */ > > sp -=3D 8; > > store_unsigned_integer (buf, 8, byte_order, bp_addr); > > write_memory (sp, buf, 8); > > + if (debug_infrun) > > + printf_unfiltered (_("Return addr. %s stored at %s\n"), > > + paddress (gdbarch, bp_addr), paddress (gdbarch, sp)); > > + > > > > /* Finally, update the stack pointer... */ > > store_unsigned_integer (buf, 8, byte_order, sp); > > regcache_cooked_write (regcache, AMD64_RSP_REGNUM, buf); > > + if (debug_infrun) > > + printf_unfiltered (_("Setting RSP to %s\n"), paddress (gdbarch, sp)); > > > > /* ...and fake a frame pointer. */ > > regcache_cooked_write (regcache, AMD64_RBP_REGNUM, buf); > > + if (debug_infrun) > > + printf_unfiltered (_("Setting RBP to %s\n"), paddress (gdbarch, sp)); > > > > return sp + 16; > > } > > @@ -2924,7 +3032,11 @@ amd64_init_abi (struct gdbarch_info info > > tdep->call_dummy_num_integer_regs =3D > > ARRAY_SIZE (amd64_dummy_call_integer_regs); > > tdep->call_dummy_integer_regs =3D amd64_dummy_call_integer_regs; > > + tdep->call_dummy_num_fp_regs =3D > > + ARRAY_SIZE (amd64_dummy_call_fp_regs); > > + tdep->call_dummy_fp_regs =3D amd64_dummy_call_fp_regs; > > tdep->classify =3D amd64_classify; > > + tdep->integer_and_fp_regs_coupled =3D 0; > > > > set_gdbarch_convert_register_p (gdbarch, i387_convert_register_p); > > set_gdbarch_register_to_value (gdbarch, i387_register_to_value); > > Index: src/gdb/amd64-windows-tdep.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > RCS file: /cvs/src/src/gdb/amd64-windows-tdep.c,v > > retrieving revision 1.17 > > diff -u -p -r1.17 amd64-windows-tdep.c > > --- src/gdb/amd64-windows-tdep.c 2 Sep 2013 09:28:02 -0000 1.17 > > +++ src/gdb/amd64-windows-tdep.c 4 Sep 2013 21:21:36 -0000 > > @@ -31,6 +31,7 @@ > > #include "coff/i386.h" > > #include "coff/pe.h" > > #include "libcoff.h" > > +#include "buildsym.h" > > > > /* The registers used to pass integer arguments during a function call. > */ > > static int amd64_windows_dummy_call_integer_regs[] =3D > > @@ -41,6 +42,14 @@ static int amd64_windows_dummy_call_inte > > 9 /* %r9 */ > > }; > > > > +/* The registers used to pass floating point arguments in function call. > > */ > > +static int amd64_windows_dummy_call_fp_regs[] =3D > > +{ > > + /* %xmm0 ... %xmm7 */ > > + AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM, > > + AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3, > > +}; > > + > > /* Implement the "classify" method in the gdbarch_tdep structure > > for amd64-windows. */ > > > > @@ -64,13 +73,45 @@ amd64_windows_classify (struct type *typ > > || TYPE_LENGTH (type) =3D=3D 4 > > || TYPE_LENGTH (type) =3D=3D 8) > > { > > - class[0] =3D AMD64_INTEGER; > > - class[1] =3D AMD64_NO_CLASS; > > + if (TYPE_NFIELDS (type) =3D=3D 1) > > + { > > + struct type *subtype =3D check_typedef ( > > + TYPE_FIELD_TYPE (type, 0)); > > + > > + amd64_windows_classify (subtype, class); > > + } > > + else > > + { > > + class[0] =3D AMD64_INTEGER; > > + class[1] =3D AMD64_NO_CLASS; > > + } > > } > > else > > class[0] =3D class[1] =3D AMD64_MEMORY; > > break; > > > > + /* Pass all complex types in memory. */ > > + case TYPE_CODE_COMPLEX: > > + if (TYPE_LENGTH (type) =3D=3D 8) > > + { > > + class[0] =3D AMD64_INTEGER; > > + class[1] =3D AMD64_NO_CLASS; > > + } > > + else > > + class[0] =3D class[1] =3D AMD64_MEMORY; > > + break; > > + > > + case TYPE_CODE_FLT: > > + /* For "long double" type, > > + GNU C compiler still uses x87 coprocessor. > > + Parameters are passed by memory address. */ > > + if ((TYPE_CODE (type) =3D=3D TYPE_CODE_FLT) > > + && (processing_gcc_compilation !=3D 0) > > + && ((TYPE_LENGTH(type) =3D=3D 12) || (TYPE_LENGTH(type) =3D=3D 16= ))) > > + { > > + class[0] =3D class[1] =3D AMD64_MEMORY; > > + break; > > + } > > default: > > /* For all the other types, the conventions are the same as > > with the System V ABI. */ > > @@ -94,6 +135,11 @@ amd64_windows_return_value (struct gdbar > > { > > case TYPE_CODE_FLT: > > case TYPE_CODE_DECFLOAT: > > + /* GNU C compiler still uses coprocessor by default. */ > > + if ((TYPE_CODE (type) =3D=3D TYPE_CODE_FLT) > > + && (processing_gcc_compilation !=3D 0) > > + && ((len =3D=3D 12) || (len =3D=3D 16))) > > + break; > > /* __m128, __m128i, __m128d, floats, and doubles are returned > > via XMM0. */ > > if (len =3D=3D 4 || len =3D=3D 8 || len =3D=3D 16) > > @@ -979,9 +1025,13 @@ amd64_windows_init_abi (struct gdbarch_i > > tdep->call_dummy_num_integer_regs =3D > > ARRAY_SIZE (amd64_windows_dummy_call_integer_regs); > > tdep->call_dummy_integer_regs =3D amd64_windows_dummy_call_integer_regs; > > + tdep->call_dummy_num_fp_regs =3D > > + ARRAY_SIZE (amd64_windows_dummy_call_fp_regs); > > + tdep->call_dummy_fp_regs =3D amd64_windows_dummy_call_fp_regs; > > tdep->classify =3D amd64_windows_classify; > > tdep->memory_args_by_pointer =3D 1; > > tdep->integer_param_regs_saved_in_caller_frame =3D 1; > > + tdep->integer_and_fp_regs_coupled =3D 1; > > set_gdbarch_return_value (gdbarch, amd64_windows_return_value); > > set_gdbarch_skip_main_prologue (gdbarch, amd64_skip_main_prologue); > > set_gdbarch_skip_trampoline_code (gdbarch, >=20 > -- > Joel