public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][MIPS][Committed] Fix PR/gas 25539 fix_loongson3_llsc: fix when target has multi labels
@ 2020-02-28  9:38 Paul Hua
  2020-03-17  1:42 ` Maciej W. Rozycki
  0 siblings, 1 reply; 3+ messages in thread
From: Paul Hua @ 2020-02-28  9:38 UTC (permalink / raw)
  To: binutils; +Cc: syq

[-- Attachment #1: Type: text/plain, Size: 427 bytes --]

When there is multi-labels on the same insn, the current code
will take care about the last one. it may cause that no sync
is added at the target.

Here we scan all labels with same value of
   S_GET_VALUE(label_list->label)
by label_list->next.

2020-02-28  YunQiang Su  <syq@debian.org>

    PR gas/25539
    * config/tc-mips.c (fix_loongson3_llsc): Compare label value
    to handle multi-labels.
    (has_label_name): New.

[-- Attachment #2: 0001-MIPS-fix_loongson3_llsc-fix-when-target-has-multi-la.patch --]
[-- Type: text/x-patch, Size: 4219 bytes --]

From dec7b24be89fe0496f9442232bcbfcb16e030742 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq@debian.org>
Date: Fri, 28 Feb 2020 15:58:13 +0800
Subject: [PATCH] MIPS/fix_loongson3_llsc: fix when target has multi labels

When there is multi-labels on the same insn, the current code
will take care about the last one. it may cause that no sync
is added at the target.

Here we scan all labels with same value of
   S_GET_VALUE(label_list->label)
by label_list->next.

2020-02-28  YunQiang Su  <syq@debian.org>

    PR gas/25539
    * config/tc-mips.c (fix_loongson3_llsc): Compare label value
    to handle multi-labels.
    (has_label_name): New.
---
 gas/ChangeLog        |  7 +++++++
 gas/config/tc-mips.c | 49 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 601fb5082d..d146fe321e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2020-02-28  YunQiang Su  <syq@debian.org>
+
+	PR gas/25539
+	* config/tc-mips.c (fix_loongson3_llsc): Compare label value
+	to handle multi-labels.
+	(has_label_name): New.
+
 2020-02-26  Matthew Malcomson  <matthew.malcomson@arm.com>
 
 	* config/tc-arm.c (enum pred_instruction_type): Remove
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 6244d8ac09..a00c69b689 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -812,6 +812,9 @@ static int mips_debug = 0;
    fill a branch delay slot.  */
 static struct mips_cl_insn history[1 + MAX_NOPS + MAX_LLSC_RANGE];
 
+/* The maximum number of LABELS detect for the same address.  */
+#define MAX_LABELS_SAME 10
+
 /* Arrays of operands for each instruction.  */
 #define MAX_OPERANDS 6
 struct mips_operand_array
@@ -6901,7 +6904,21 @@ fix_loongson2f (struct mips_cl_insn * ip)
     fix_loongson2f_jump (ip);
 }
 
-/* Fix loongson3 llsc errata: Insert sync before ll/lld. */
+static bfd_boolean
+has_label_name (const char *arr[], size_t len ,const char *s)
+{
+  unsigned long i;
+  for (i = 0; i < len; i++)
+    {
+      if (!arr[i])
+	return FALSE;
+      if (streq (arr[i], s))
+	return TRUE;
+    }
+  return FALSE;
+}
+
+/* Fix loongson3 llsc errata: Insert sync before ll/lld.  */
 
 static void
 fix_loongson3_llsc (struct mips_cl_insn * ip)
@@ -6915,10 +6932,30 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
       && S_IS_LOCAL (seg_info (now_seg)->label_list->label)
       && (strcmp (ip->insn_mo->name, "sync") != 0))
     {
-      const char *label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
-      unsigned long lookback = ARRAY_SIZE (history);
       unsigned long i;
+      valueT label_value;
+      const char *label_names[MAX_LABELS_SAME];
+      const char *label_name;
+
+      label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
+      label_names[0] = label_name;
+      struct insn_label_list *llist = seg_info (now_seg)->label_list;
+      label_value = S_GET_VALUE (llist->label);
 
+      for (i = 1; i < MAX_LABELS_SAME; i++)
+	{
+	  llist = llist->next;
+	  if (!llist)
+	    break;
+	  if (S_GET_VALUE (llist->label) == label_value)
+	    label_names[i] = S_GET_NAME (llist->label);
+	  else
+	    break;
+	}
+      for (; i < MAX_LABELS_SAME; i++)
+	label_names[i] = NULL;
+
+      unsigned long lookback = ARRAY_SIZE (history);
       for (i = 0; i < lookback; i++)
 	{
 	  if (streq (history[i].insn_mo->name, "ll")
@@ -6938,7 +6975,9 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
 
 		  if (delayed_branch_p (&history[j]))
 		    {
-		      if (streq (history[j].target, label_name))
+		      if (has_label_name (label_names,
+					  MAX_LABELS_SAME,
+					  history[j].target))
 			{
 			  add_fixed_insn (&sync_insn);
 			  insert_into_history (0, 1, &sync_insn);
@@ -6952,7 +6991,7 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
     }
   /* If we find a sc, we look forward to look for an branch insn,
      and see whether it jump back and out of ll/sc.  */
-  else if (streq(ip->insn_mo->name, "sc") || streq(ip->insn_mo->name, "scd"))
+  else if (streq (ip->insn_mo->name, "sc") || streq (ip->insn_mo->name, "scd"))
     {
       unsigned long lookback = ARRAY_SIZE (history) - 1;
       unsigned long i;
-- 
2.18.1


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

* Re: [PATCH][MIPS][Committed] Fix PR/gas 25539 fix_loongson3_llsc: fix when target has multi labels
  2020-02-28  9:38 [PATCH][MIPS][Committed] Fix PR/gas 25539 fix_loongson3_llsc: fix when target has multi labels Paul Hua
@ 2020-03-17  1:42 ` Maciej W. Rozycki
  2020-03-17  2:08   ` YunQiang Su
  0 siblings, 1 reply; 3+ messages in thread
From: Maciej W. Rozycki @ 2020-03-17  1:42 UTC (permalink / raw)
  To: Paul Hua; +Cc: binutils, syq

On Fri, 28 Feb 2020, Paul Hua wrote:

> When there is multi-labels on the same insn, the current code
> will take care about the last one. it may cause that no sync
> is added at the target.

 Why do you need to set an arbitrary limit as to the number of labels 
handled (MAX_LABELS_SAME)?  This handles user-supplied input, so we can't 
predict how many there will be at most.  What happens if the limit has 
been exceeded?

 We should avoid setting unnecessary limits, as per our coding standards: 
<https://www.gnu.org/prep/standards/standards.html#Semantics>.

  Maciej

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

* Re: [PATCH][MIPS][Committed] Fix PR/gas 25539 fix_loongson3_llsc: fix when target has multi labels
  2020-03-17  1:42 ` Maciej W. Rozycki
@ 2020-03-17  2:08   ` YunQiang Su
  0 siblings, 0 replies; 3+ messages in thread
From: YunQiang Su @ 2020-03-17  2:08 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Paul Hua, binutils

Maciej W. Rozycki <macro@linux-mips.org> 于2020年3月17日周二 上午9:49写道:
>
> On Fri, 28 Feb 2020, Paul Hua wrote:
>
> > When there is multi-labels on the same insn, the current code
> > will take care about the last one. it may cause that no sync
> > is added at the target.
>
>  Why do you need to set an arbitrary limit as to the number of labels
> handled (MAX_LABELS_SAME)?  This handles user-supplied input, so we can't

Yes. It is a problem. I did it fellow the scheme as MAX_LLSC_RANGE.
Maybe that we should use dynamic allocated memory to hold both of them.

> predict how many there will be at most.  What happens if the limit has
> been exceeded?

If exceeded the workaround won't work, aka no `sync' will be insert in
this case.

>
>  We should avoid setting unnecessary limits, as per our coding standards:
> <https://www.gnu.org/prep/standards/standards.html#Semantics>.
>
>   Maciej

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

end of thread, other threads:[~2020-03-17  2:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-28  9:38 [PATCH][MIPS][Committed] Fix PR/gas 25539 fix_loongson3_llsc: fix when target has multi labels Paul Hua
2020-03-17  1:42 ` Maciej W. Rozycki
2020-03-17  2:08   ` YunQiang Su

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).