public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [COMMITTED PATCH] gdb: LoongArch: Implement the push_dummy_call gdbarch method
@ 2022-07-07  9:15 Tiezhu Yang
  2022-07-15 17:27 ` Tom Tromey
  0 siblings, 1 reply; 3+ messages in thread
From: Tiezhu Yang @ 2022-07-07  9:15 UTC (permalink / raw)
  To: gdb-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 21483 bytes --]

According to "Procedure Calling Convention" in "LoongArch ELF ABI
specification" [1], implement the push_dummy_call gdbarch method
as clear as possible.

[1] https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_procedure_calling_convention

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 gdb/loongarch-tdep.c | 596 +++++++++++++++++++++++++++++++++++++++++++
 gdb/loongarch-tdep.h |   2 +
 2 files changed, 598 insertions(+)

diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index 76480ce6c94..3add71b2a09 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -452,6 +452,599 @@ static const struct frame_unwind loongarch_frame_unwind = {
   /*.prev_arch	   =*/nullptr,
 };
 
+static void
+pass_in_gar (struct regcache *regcache, unsigned int gar, const gdb_byte *val)
+{
+  unsigned int regnum = LOONGARCH_ARG_REGNUM - gar + LOONGARCH_A0_REGNUM;
+  regcache->cooked_write (regnum, val);
+}
+
+static void
+pass_in_far (struct regcache *regcache, unsigned int far, const gdb_byte *val)
+{
+  unsigned int regnum = LOONGARCH_ARG_REGNUM - far + LOONGARCH_BADV_REGNUM + 1;
+  regcache->cooked_write (regnum, val);
+}
+
+static __attribute__((aligned(16))) gdb_byte buf[1024] = { 0 };
+static gdb_byte *addr = buf;
+
+static void
+pass_on_stack (struct regcache *regcache, const gdb_byte *val, size_t len, int align)
+{
+  align = align_up (align, 8);
+  if (align > 16)
+    align = 16;
+
+  CORE_ADDR align_addr = (CORE_ADDR) addr;
+  align_addr = align_up (align_addr, align);
+  addr = (gdb_byte *) align_addr;
+  memcpy (addr, val, len);
+  addr += len;
+}
+
+static unsigned int fixed_point_members = 0;
+static unsigned int floating_point_members = 0;
+static bool first_member_is_fixed_point = false;
+
+static void
+compute_struct_member (struct type *type)
+{
+  for (int i = 0; i < type->num_fields (); i++)
+    {
+      struct type *field_type = check_typedef (type->field (i).type ());
+
+      if (field_type->code () == TYPE_CODE_INT
+	  || field_type->code () == TYPE_CODE_BOOL
+	  || field_type->code () == TYPE_CODE_CHAR
+	  || field_type->code () == TYPE_CODE_RANGE
+	  || field_type->code () == TYPE_CODE_ENUM
+	  || field_type->code () == TYPE_CODE_PTR)
+      {
+	fixed_point_members++;
+
+	if (floating_point_members == 0)
+	  first_member_is_fixed_point = true;
+      }
+      else if (field_type->code () == TYPE_CODE_FLT)
+	floating_point_members++;
+      else if (field_type->code () == TYPE_CODE_STRUCT)
+	compute_struct_member (field_type);
+      else if (field_type->code () == TYPE_CODE_COMPLEX)
+	floating_point_members += 2;
+    }
+}
+
+/* Implement the push_dummy_call gdbarch method.  */
+
+static CORE_ADDR
+loongarch_push_dummy_call (struct gdbarch *gdbarch,
+			   struct value *function,
+			   struct regcache *regcache,
+			   CORE_ADDR bp_addr,
+			   int nargs,
+			   struct value **args,
+			   CORE_ADDR sp,
+			   function_call_return_method return_method,
+			   CORE_ADDR struct_addr)
+{
+  int regsize = register_size (gdbarch, 0);
+  unsigned int gar = LOONGARCH_ARG_REGNUM;
+  unsigned int far = LOONGARCH_ARG_REGNUM;
+
+  if (return_method != return_method_normal)
+    pass_in_gar (regcache, gar--, (gdb_byte *) &struct_addr);
+
+  addr = buf;
+  for (int i = 0; i < nargs; i++)
+    {
+      struct value *arg = args[i];
+      const gdb_byte *val = value_contents (arg).data ();
+      struct type *type = check_typedef (value_type (arg));
+      size_t len = TYPE_LENGTH (type);
+      int align = type_align (type);
+      enum type_code code = type->code ();
+
+      switch (code)
+	{
+	case TYPE_CODE_INT:
+	case TYPE_CODE_BOOL:
+	case TYPE_CODE_CHAR:
+	case TYPE_CODE_RANGE:
+	case TYPE_CODE_ENUM:
+	case TYPE_CODE_PTR:
+	  {
+	    /* integer or pointer type is passed in GAR.
+	     * If no GAR is available, it’s passed on the stack.
+	     * When passed in registers or on the stack,
+	     * the unsigned integer scalars are zero-extended to GRLEN bits,
+	     * and the signed integer scalars are sign-extended.  */
+	  if (type->is_unsigned ())
+	    {
+              ULONGEST data = extract_unsigned_integer (val, len, BFD_ENDIAN_LITTLE);
+	      if (gar > 0)
+		pass_in_gar (regcache, gar--, (gdb_byte *) &data);
+	      else
+		pass_on_stack (regcache, (gdb_byte *) &data, len, align);
+            }
+	  else
+	    {
+	      LONGEST data = extract_signed_integer (val, len, BFD_ENDIAN_LITTLE);
+	      if (gar > 0)
+		pass_in_gar (regcache, gar--, (gdb_byte *) &data);
+	      else
+		pass_on_stack (regcache, (gdb_byte *) &data, len, align);
+            }
+	  }
+	  break;
+	case TYPE_CODE_FLT:
+	  if (len == 2 * regsize)
+	    {
+	      /* long double type is passed in a pair of GAR,
+	       * with the low-order GRLEN bits in the lower-numbered register
+	       * and the high-order GRLEN bits in the higher-numbered register.
+	       * If exactly one register is available,
+	       * the low-order GRLEN bits are passed in the register
+	       * and the high-order GRLEN bits are passed on the stack.
+	       * If no GAR is available, it’s passed on the stack.  */
+	      if (gar >= 2)
+		{
+		  pass_in_gar (regcache, gar--, val);
+		  pass_in_gar (regcache, gar--, val + regsize);
+		}
+	      else if (gar == 1)
+		{
+		  pass_in_gar (regcache, gar--, val);
+		  pass_on_stack (regcache, val + regsize, len - regsize, align);
+		}
+	      else
+		{
+		  pass_on_stack (regcache, val, len, align);
+		}
+	    }
+	  else
+	    {
+	      /* The other floating-point type is passed in FAR.
+	       * If no FAR is available, it’s passed in GAR.
+	       * If no GAR is available, it’s passed on the stack.  */
+	      if (far > 0)
+		  pass_in_far (regcache, far--, val);
+	      else if (gar > 0)
+		  pass_in_gar (regcache, gar--, val);
+	      else
+		  pass_on_stack (regcache, val, len, align);
+	    }
+	  break;
+	case TYPE_CODE_STRUCT:
+	  {
+	    fixed_point_members = 0;
+	    floating_point_members = 0;
+	    first_member_is_fixed_point = false;
+	    compute_struct_member (type);
+
+	    if (len > 0 && len <= regsize)
+	      {
+		/* The structure has only fixed-point members.  */
+		if (fixed_point_members > 0 && floating_point_members == 0)
+		  {
+		    /* If there is an available GAR,
+		     * the structure is passed through the GAR by value passing;
+		     * If no GAR is available, it’s passed on the stack.  */
+		    if (gar > 0)
+		      pass_in_gar (regcache, gar--, val);
+		    else
+		      pass_on_stack (regcache, val, len, align);
+		  }
+		/* The structure has only floating-point members.  */
+		else if (fixed_point_members == 0 && floating_point_members > 0)
+		  {
+		    /* One floating-point member.
+		     * The argument is passed in a FAR.
+		     * If no FAR is available, the value is passed in a GAR.
+		     * if no GAR is available, the value is passed on the stack.  */
+		    if (floating_point_members == 1)
+		      {
+			if (far > 0)
+			  pass_in_far (regcache, far--, val);
+			else if (gar > 0)
+			  pass_in_gar (regcache, gar--, val);
+			else
+			  pass_on_stack (regcache, val, len, align);
+		      }
+		    /* Two floating-point members.
+		     * The argument is passed in a pair of available FAR,
+		     * with the low-order float member bits in the lower-numbered FAR
+		     * and the high-order float member bits in the higher-numbered FAR.
+		     * If the number of available FAR is less than 2, it’s passed in a GAR,
+		     * and passed on the stack if no GAR is available.  */
+		    else if (floating_point_members == 2)
+		      {
+			if (far >= 2)
+			  {
+			    pass_in_far (regcache, far--, val);
+			    pass_in_far (regcache, far--, val + align);
+			  }
+			else if (gar > 0)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			  }
+			else
+			  {
+			    pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		  }
+		/* The structure has both fixed-point and floating-point members.  */
+		else if (fixed_point_members > 0 && floating_point_members > 0)
+		  {
+		    /* One float member and multiple fixed-point members.
+		     * If there are available GAR, the structure is passed in a GAR,
+		     * and passed on the stack if no GAR is available.  */
+		    if (floating_point_members == 1 && fixed_point_members > 1)
+		      {
+			if (gar > 0)
+			  pass_in_gar (regcache, gar--, val);
+			else
+			  pass_on_stack (regcache, val, len, align);
+		      }
+		    /* One float member and only one fixed-point member.
+		     * If one FAR and one GAR are available,
+		     * the floating-point member of the structure is passed in the FAR,
+		     * and the fixed-point member of the structure is passed in the GAR.
+		     * If no floating-point register but one GAR is available, it’s passed in GAR;
+		     * If no GAR is available, it’s passed on the stack.  */
+		    else if (floating_point_members == 1 && fixed_point_members == 1)
+		      {
+			if (far > 0 && gar > 0)
+			  {
+			    if (first_member_is_fixed_point == false)
+			      {
+				pass_in_far (regcache, far--, val);
+				pass_in_gar (regcache, gar--, val + align);
+			      }
+			    else
+			      {
+				pass_in_gar (regcache, gar--, val);
+				pass_in_far (regcache, far--, val + align);
+			      }
+			  }
+			else
+			  {
+			    if (gar > 0)
+			      pass_in_gar (regcache, gar--, val);
+			    else
+			      pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		  }
+	      }
+	    else if (len > regsize && len <= 2 * regsize)
+	      {
+		/* Only fixed-point members.  */
+		if (fixed_point_members > 0 && floating_point_members == 0)
+		  {
+		    /* The argument is passed in a pair of available GAR,
+		     * with the low-order bits in the lower-numbered GAR
+		     * and the high-order bits in the higher-numbered GAR.
+		     * If only one GAR is available,
+		     * the low-order bits are in the GAR
+		     * and the high-order bits are on the stack,
+		     * and passed on the stack if no GAR is available.  */
+		    if (gar >= 2)
+		      {
+			pass_in_gar (regcache, gar--, val);
+			pass_in_gar (regcache, gar--, val + regsize);
+		      }
+		    else if (gar == 1)
+		      {
+			pass_in_gar (regcache, gar--, val);
+			pass_on_stack (regcache, val + regsize, len - regsize, align);
+		      }
+		    else
+		      {
+			pass_on_stack (regcache, val, len, align);
+		      }
+		  }
+		/* Only floating-point members.  */
+		else if (fixed_point_members == 0 && floating_point_members > 0)
+		  {
+		    /* The structure has one long double member
+		     * or one double member and two adjacent float members
+		     * or 3-4 float members.
+		     * The argument is passed in a pair of available GAR,
+		     * with the low-order bits in the lower-numbered GAR
+		     * and the high-order bits in the higher-numbered GAR.
+		     * If only one GAR is available,
+		     * the low-order bits are in the GAR
+		     * and the high-order bits are on the stack,
+		     * and passed on the stack if no GAR is available.  */
+		    if ((len == 16 && floating_point_members == 1)
+			 || (len == 16 && floating_point_members == 3)
+			 || (len == 12 && floating_point_members == 3)
+			 || (len == 16 && floating_point_members == 4))
+		      {
+			if (gar >= 2)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_in_gar (regcache, gar--, val + regsize);
+			  }
+			else if (gar == 1)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_on_stack (regcache, val + regsize, len - regsize, align);
+			  }
+			else
+			  {
+			    pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		    /* The structure with two double members
+		     * is passed in a pair of available FAR,
+		     * with the low-order bits in the lower-numbered FAR
+		     * and the high-order bits in the higher-numbered FAR.
+		     * If no a pair of available FAR,
+		     * it’s passed in a pair of available GAR,
+		     * with the low-order bits in the lower-numbered GAR
+		     * and the high-order bits in the higher-numbered GAR.
+		     * If only one GAR is available,
+		     * the low-order bits are in the GAR
+		     * and the high-order bits are on stack,
+		     * and passed on the stack if no GAR is available.
+		     * A structure with one double member and one float member is same.  */
+		    else if ((len == 16 && floating_point_members == 2)
+			     || (len == 12 && floating_point_members == 2))
+		      {
+			if (far >= 2)
+			  {
+			    pass_in_far (regcache, far--, val);
+			    pass_in_far (regcache, far--, val + regsize);
+			  }
+			else if (gar >= 2)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_in_gar (regcache, gar--, val + regsize);
+			  }
+			else if (gar == 1)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_on_stack (regcache, val + regsize, len - regsize, align);
+			  }
+			else
+			  {
+			    pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		  }
+		/* Both fixed-point and floating-point members.  */
+		else if (fixed_point_members > 0 && floating_point_members > 0)
+		  {
+		    /* The structure has one floating-point member and only one fixed-point member.  */
+		    if (floating_point_members == 1 && fixed_point_members == 1)
+		      {
+			/* If one FAR and one GAR are available,
+			 * the floating-point member of the structure is passed in the FAR,
+			 * and the fixed-point member of the structure is passed in the GAR;
+			 * If no floating-point registers but two GARs are available,
+			 * it’s passed in the two GARs;
+			 * If only one GAR is available,
+			 * the low-order bits are in the GAR
+			 * and the high-order bits are on the stack;
+			 * And it’s passed on the stack if no GAR is available.  */
+			if (far > 0 && gar > 0)
+			  {
+			    if (first_member_is_fixed_point == false)
+			      {
+				pass_in_far (regcache, far--, val);
+				pass_in_gar (regcache, gar--, val + regsize);
+			      }
+			    else
+			      {
+				pass_in_gar (regcache, gar--, val);
+				pass_in_far (regcache, far--, val + regsize);
+			      }
+			  }
+			else if (far == 0 && gar >= 2)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_in_gar (regcache, gar--, val + regsize);
+			  }
+			else if (far == 0 && gar == 1)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_on_stack (regcache, val + regsize, len - regsize, align);
+			  }
+			else if (far == 0 && gar == 0)
+			  {
+			    pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		    else
+		      {
+			/* The argument is passed in a pair of available GAR,
+			 * with the low-order bits in the lower-numbered GAR
+			 * and the high-order bits in the higher-numbered GAR.
+			 * If only one GAR is available,
+			 * the low-order bits are in the GAR
+			 * and the high-order bits are on the stack,
+			 * and passed on the stack if no GAR is available.  */
+			if (gar >= 2)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_in_gar (regcache, gar--, val + regsize);
+			  }
+			else if (gar == 1)
+			  {
+			    pass_in_gar (regcache, gar--, val);
+			    pass_on_stack (regcache, val + regsize, len - regsize, align);
+			  }
+			else
+			  {
+			    pass_on_stack (regcache, val, len, align);
+			  }
+		      }
+		  }
+	      }
+	    else if (len > 2 * regsize)
+	      {
+	        /* It’s passed by reference and are replaced in the argument list with the address.
+		 * If there is an available GAR, the reference is passed in the GAR,
+		 * and passed on the stack if no GAR is available.  */
+		sp = align_down (sp - len, 16);
+		write_memory (sp, val, len);
+
+		if (gar > 0)
+		  pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
+		else
+		  pass_on_stack (regcache, (const gdb_byte*) &sp, len, regsize);
+	      }
+	  }
+	  break;
+	case TYPE_CODE_UNION:
+	  /* Union is passed in GAR or stack.  */
+	  if (len > 0 && len <= regsize)
+	    {
+	      /* The argument is passed in a GAR,
+	       * or on the stack by value if no GAR is available.  */
+	      if (gar > 0)
+		pass_in_gar (regcache, gar--, val);
+	      else
+		pass_on_stack (regcache, val, len, align);
+	    }
+	  else if (len > regsize && len <= 2 * regsize)
+	    {
+	      /* The argument is passed in a pair of available GAR,
+	       * with the low-order bits in the lower-numbered GAR
+	       * and the high-order bits in the higher-numbered GAR.
+	       * If only one GAR is available,
+	       * the low-order bits are in the GAR
+	       * and the high-order bits are on the stack.
+	       * The arguments are passed on the stack when no GAR is available.  */
+	      if (gar >= 2)
+		{
+		  pass_in_gar (regcache, gar--, val);
+		  pass_in_gar (regcache, gar--, val + regsize);
+		}
+	      else if (gar == 1)
+		{
+		  pass_in_gar (regcache, gar--, val);
+		  pass_on_stack (regcache, val + regsize, len - regsize, align);
+		}
+	      else
+		{
+		  pass_on_stack (regcache, val, len, align);
+		}
+	    }
+	  else if (len > 2 * regsize)
+	    {
+	      /* It’s passed by reference and are replaced in the argument list with the address.
+	       * If there is an available GAR, the reference is passed in the GAR,
+	       * and passed on the stack if no GAR is available.  */
+	      sp = align_down (sp - len, 16);
+	      write_memory (sp, val, len);
+
+	      if (gar > 0)
+		pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
+	      else
+		pass_on_stack (regcache, (const gdb_byte*) &sp, len, regsize);
+	    }
+	  break;
+	case TYPE_CODE_COMPLEX:
+	  {
+	    struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+	    size_t target_len = TYPE_LENGTH (target_type);
+
+	    if (target_len < regsize)
+	      {
+		/* The complex with two float members
+		 * is passed in a pair of available FAR,
+		 * with the low-order float member bits in the lower-numbered FAR
+		 * and the high-order float member bits in the higher-numbered FAR.
+		 * If the number of available FAR is less than 2, it’s passed in a GAR,
+		 * and passed on the stack if no GAR is available.  */
+		if (far >= 2)
+		  {
+		    pass_in_far (regcache, far--, val);
+		    pass_in_far (regcache, far--, val + align);
+		  }
+		else if (gar > 0)
+		  {
+		    pass_in_gar (regcache, gar--, val);
+		  }
+		else
+		  {
+		    pass_on_stack (regcache, val, len, align);
+		  }
+	      }
+	    else if (target_len == regsize)
+	      {
+		/* The complex with two double members
+		 * is passed in a pair of available FAR,
+		 * with the low-order bits in the lower-numbered FAR
+		 * and the high-order bits in the higher-numbered FAR.
+		 * If no a pair of available FAR,
+		 * it’s passed in a pair of available GAR,
+		 * with the low-order bits in the lower-numbered GAR
+		 * and the high-order bits in the higher-numbered GAR.
+		 * If only one GAR is available,
+		 * the low-order bits are in the GAR
+		 * and the high-order bits are on stack,
+		 * and passed on the stack if no GAR is available.  */
+		{
+		  if (far >= 2)
+		    {
+		      pass_in_far (regcache, far--, val);
+		      pass_in_far (regcache, far--, val + align);
+		    }
+		  else if (gar >= 2)
+		    {
+		      pass_in_gar (regcache, gar--, val);
+		      pass_in_gar (regcache, gar--, val + align);
+		    }
+		  else if (gar == 1)
+		    {
+		      pass_in_gar (regcache, gar--, val);
+		      pass_on_stack (regcache, val + align, len - align, align);
+		    }
+		  else
+		    {
+		      pass_on_stack (regcache, val, len, align);
+		    }
+		}
+	      }
+	    else if (target_len == 2 * regsize)
+	      {
+		/* The complex with two long double members
+		 * is passed by reference and are replaced in the argument list with the address.
+	         * If there is an available GAR, the reference is passed in the GAR,
+	         * and passed on the stack if no GAR is available.  */
+		sp = align_down (sp - len, 16);
+		write_memory (sp, val, len);
+
+		if (gar > 0)
+		  pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
+		else
+		  pass_on_stack (regcache, (const gdb_byte*) &sp, regsize, regsize);
+	      }
+	  }
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  if (addr > buf)
+    {
+      sp -= addr - buf;
+      sp = align_down (sp, 16);
+      write_memory (sp, buf, addr - buf);
+    }
+
+  regcache_cooked_write_unsigned (regcache, LOONGARCH_RA_REGNUM, bp_addr);
+  regcache_cooked_write_unsigned (regcache, LOONGARCH_SP_REGNUM, sp);
+
+  return sp;
+}
+
 /* Implement the return_value gdbarch method.  */
 
 static enum return_value_convention
@@ -644,6 +1237,9 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Finalise the target description registers.  */
   tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
+  /* Functions handling dummy frames.  */
+  set_gdbarch_push_dummy_call (gdbarch, loongarch_push_dummy_call);
+
   /* Return value info  */
   set_gdbarch_return_value (gdbarch, loongarch_return_value);
 
diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h
index acf0191fd65..672bc2b80de 100644
--- a/gdb/loongarch-tdep.h
+++ b/gdb/loongarch-tdep.h
@@ -39,6 +39,8 @@ enum
   LOONGARCH_PC_REGNUM = 33,		/* Program Counter.  */
   LOONGARCH_BADV_REGNUM = 34,		/* Bad Vaddr for Addressing Exception.  */
   LOONGARCH_LINUX_NUM_GREGSET = 45,	/* 32 GPR, ORIG_A0, PC, BADV, RESERVED 10.  */
+  LOONGARCH_ARG_REGNUM = 8,            /* r4-r11: general-purpose argument registers.
+					  f0-f7: floating-point argument registers.  */
 };
 
 /* Register set definitions.  */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [COMMITTED PATCH] gdb: LoongArch: Implement the push_dummy_call gdbarch method
  2022-07-07  9:15 [COMMITTED PATCH] gdb: LoongArch: Implement the push_dummy_call gdbarch method Tiezhu Yang
@ 2022-07-15 17:27 ` Tom Tromey
  2022-07-16 11:58   ` Tiezhu Yang
  0 siblings, 1 reply; 3+ messages in thread
From: Tom Tromey @ 2022-07-15 17:27 UTC (permalink / raw)
  To: Tiezhu Yang; +Cc: gdb-patches

>>>>> Tiezhu Yang <yangtiezhu@loongson.cn> writes:

> +static void
> +pass_in_gar (struct regcache *regcache, unsigned int gar, const gdb_byte *val)

In gdb, functions generally should have an introductory comment
explaining their purpose.

> +static __attribute__((aligned(16))) gdb_byte buf[1024] = { 0 };
> +static gdb_byte *addr = buf;

I don't understand why a global is needed here, or why the attribute is
needed.  But anyway, the attribute isn't really portable, and since this
is tdep code (not specific to some host where you could maybe get away
with assuming the compiler), it can't be used.

> +static unsigned int fixed_point_members = 0;
> +static unsigned int floating_point_members = 0;
> +static bool first_member_is_fixed_point = false;

Please don't use globals for this kind of thing.
You can make a new object or you can pass pointers to locals.

> +	    /* integer or pointer type is passed in GAR.
> +	     * If no GAR is available, it€s passed on the stack.
> +	     * When passed in registers or on the stack,
> +	     * the unsigned integer scalars are zero-extended to GRLEN bits,
> +	     * and the signed integer scalars are sign-extended.  */

In the gdb style, subsequent comment lines don't have the "*".

thanks,
Tom

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [COMMITTED PATCH] gdb: LoongArch: Implement the push_dummy_call gdbarch method
  2022-07-15 17:27 ` Tom Tromey
@ 2022-07-16 11:58   ` Tiezhu Yang
  0 siblings, 0 replies; 3+ messages in thread
From: Tiezhu Yang @ 2022-07-16 11:58 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches



On 07/16/2022 01:27 AM, Tom Tromey wrote:
>>>>>> Tiezhu Yang <yangtiezhu@loongson.cn> writes:
>
>> +static void
>> +pass_in_gar (struct regcache *regcache, unsigned int gar, const gdb_byte *val)
>
> In gdb, functions generally should have an introductory comment
> explaining their purpose.
>
>> +static __attribute__((aligned(16))) gdb_byte buf[1024] = { 0 };
>> +static gdb_byte *addr = buf;
>
> I don't understand why a global is needed here, or why the attribute is
> needed.  But anyway, the attribute isn't really portable, and since this
> is tdep code (not specific to some host where you could maybe get away
> with assuming the compiler), it can't be used.
>
>> +static unsigned int fixed_point_members = 0;
>> +static unsigned int floating_point_members = 0;
>> +static bool first_member_is_fixed_point = false;
>
> Please don't use globals for this kind of thing.
> You can make a new object or you can pass pointers to locals.
>
>> +	    /* integer or pointer type is passed in GAR.
>> +	     * If no GAR is available, it€s passed on the stack.
>> +	     * When passed in registers or on the stack,
>> +	     * the unsigned integer scalars are zero-extended to GRLEN bits,
>> +	     * and the signed integer scalars are sign-extended.  */
>
> In the gdb style, subsequent comment lines don't have the "*".
>
> thanks,
> Tom
>

Hi Tom,

Thank you very much.

I modify the related code as you suggested, please review the patch.

https://sourceware.org/pipermail/gdb-patches/2022-July/190814.html

Thanks,
Tiezhu


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-07-16 11:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-07  9:15 [COMMITTED PATCH] gdb: LoongArch: Implement the push_dummy_call gdbarch method Tiezhu Yang
2022-07-15 17:27 ` Tom Tromey
2022-07-16 11:58   ` Tiezhu Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).