gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 23 Sep 2012 10:41:24 +0000 (10:41 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sun, 23 Sep 2012 10:41:24 +0000 (10:41 +0000)
2012-09-23  Richard Sandiford  <rdsandiford@googlemail.com>
    Maciej W. Rozycki  <macro@codesourcery.com>

* config/tc-mips.h (mips_record_label): Delete.
(mips_add_dot_label): Declare.
(tc_new_dot_label): Use it.
* config/tc-mips.c (mips_assembling_insn): New variable.
(md_assemble): Call mips_mark_labels.  Set mips_assembling_insn
while the main part of the function is executing.
(mips_compressed_mark_label): New function, split out from...
(mips_compressed_mark_labels): ...here.
(append_insn): Don't call mips_mark_labels here.
(mips_record_label): Make local.
(mips_add_dot_label): New function.

gas/testsuite/
* gas/mips/dot-1.s, gas/mips/dot-1.d, gas/mips/micromips@dot-1.d,
gas/mips/mips16@dot-1.d: New test.
* gas/mips/mips.exp: Run it.

gas/ChangeLog
gas/config/tc-mips.c
gas/config/tc-mips.h
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/dot-1.d [new file with mode: 0644]
gas/testsuite/gas/mips/dot-1.s [new file with mode: 0644]
gas/testsuite/gas/mips/micromips@dot-1.d [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/mips16@dot-1.d [new file with mode: 0644]

index 8bbf1775a317e1ae7423a8a197eb1074858923dd..c3abe80acdc304d93ec7d6768962e5be7cdaefb9 100644 (file)
@@ -1,3 +1,18 @@
+2012-09-23  Richard Sandiford  <rdsandiford@googlemail.com>
+           Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * config/tc-mips.h (mips_record_label): Delete.
+       (mips_add_dot_label): Declare.
+       (tc_new_dot_label): Use it.
+       * config/tc-mips.c (mips_assembling_insn): New variable.
+       (md_assemble): Call mips_mark_labels.  Set mips_assembling_insn
+       while the main part of the function is executing.
+       (mips_compressed_mark_label): New function, split out from...
+       (mips_compressed_mark_labels): ...here.
+       (append_insn): Don't call mips_mark_labels here.
+       (mips_record_label): Make local.
+       (mips_add_dot_label): New function.
+
 2012-09-23  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config/tc-mips.c (SEXT_16BIT): New macro.
index 35bea8b9fc64fbfeb14d945e603cd97cf8be20ca..e71e35297ee0ddafa116f070c261d8b7e73a5ce8 100644 (file)
@@ -1574,6 +1574,11 @@ static bfd_reloc_code_real_type offset_reloc[3]
 
 static unsigned int forced_insn_length;
 
+/* True if we are assembling an instruction.  All dot symbols defined during
+   this time should be treated as code labels.  */
+
+static bfd_boolean mips_assembling_insn;
+
 #ifdef OBJ_ELF
 /* The pdr segment for per procedure frame/regmask info.  Not used for
    ECOFF debugging.  */
@@ -2592,6 +2597,9 @@ md_assemble (char *str)
   offset_reloc[1] = BFD_RELOC_UNUSED;
   offset_reloc[2] = BFD_RELOC_UNUSED;
 
+  mips_mark_labels ();
+  mips_assembling_insn = TRUE;
+
   if (mips_opts.mips16)
     mips16_ip (str, &insn);
   else
@@ -2602,12 +2610,8 @@ md_assemble (char *str)
     }
 
   if (insn_error)
-    {
-      as_bad ("%s `%s'", insn_error, str);
-      return;
-    }
-
-  if (insn.insn_mo->pinfo == INSN_MACRO)
+    as_bad ("%s `%s'", insn_error, str);
+  else if (insn.insn_mo->pinfo == INSN_MACRO)
     {
       macro_start ();
       if (mips_opts.mips16)
@@ -2625,6 +2629,8 @@ md_assemble (char *str)
       else
        append_insn (&insn, NULL, unused_reloc, FALSE);
     }
+
+  mips_assembling_insn = FALSE;
 }
 
 /* Convenience functions for abstracting away the differences between
@@ -2832,7 +2838,7 @@ s_is_linkonce (symbolS *sym, segT from_seg)
   return linkonce;
 }
 
-/* Mark instruction labels in MIPS16/microMIPS mode.  This permits the
+/* Mark MIPS16 or microMIPS instruction label LABEL.  This permits the
    linker to handle them specially, such as generating jalx instructions
    when needed.  We also make them odd for the duration of the assembly,
    in order to generate the right sort of code.  We will make them even
@@ -2841,36 +2847,39 @@ s_is_linkonce (symbolS *sym, segT from_seg)
    to make them odd again.  */
 
 static void
-mips_compressed_mark_labels (void)
+mips_compressed_mark_label (symbolS *label)
 {
-  segment_info_type *si = seg_info (now_seg);
-  struct insn_label_list *l;
-
   gas_assert (HAVE_CODE_COMPRESSION);
 
-  for (l = si->label_list; l != NULL; l = l->next)
-   {
-      symbolS *label = l->label;
-
 #if defined(OBJ_ELF) || defined(OBJ_MAYBE_ELF)
-      if (IS_ELF)
-       {
-         if (mips_opts.mips16)
-           S_SET_OTHER (label, ELF_ST_SET_MIPS16 (S_GET_OTHER (label)));
-         else
-           S_SET_OTHER (label, ELF_ST_SET_MICROMIPS (S_GET_OTHER (label)));
-       }
-#endif
-      if ((S_GET_VALUE (label) & 1) == 0
-       /* Don't adjust the address if the label is global or weak, or
-          in a link-once section, since we'll be emitting symbol reloc
-          references to it which will be patched up by the linker, and
-          the final value of the symbol may or may not be MIPS16/microMIPS.  */
-         && ! S_IS_WEAK (label)
-         && ! S_IS_EXTERNAL (label)
-         && ! s_is_linkonce (label, now_seg))
-       S_SET_VALUE (label, S_GET_VALUE (label) | 1);
+  if (IS_ELF)
+    {
+      if (mips_opts.mips16)
+       S_SET_OTHER (label, ELF_ST_SET_MIPS16 (S_GET_OTHER (label)));
+      else
+       S_SET_OTHER (label, ELF_ST_SET_MICROMIPS (S_GET_OTHER (label)));
     }
+#endif
+  if ((S_GET_VALUE (label) & 1) == 0
+      /* Don't adjust the address if the label is global or weak, or
+        in a link-once section, since we'll be emitting symbol reloc
+        references to it which will be patched up by the linker, and
+        the final value of the symbol may or may not be MIPS16/microMIPS.  */
+      && !S_IS_WEAK (label)
+      && !S_IS_EXTERNAL (label)
+      && !s_is_linkonce (label, now_seg))
+    S_SET_VALUE (label, S_GET_VALUE (label) | 1);
+}
+
+/* Mark preceding MIPS16 or microMIPS instruction labels.  */
+
+static void
+mips_compressed_mark_labels (void)
+{
+  struct insn_label_list *l;
+
+  for (l = seg_info (now_seg)->label_list; l != NULL; l = l->next)
+    mips_compressed_mark_label (l->label);
 }
 
 /* End the current frag.  Make it a variant frag and record the
@@ -4031,8 +4040,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
     fix_loongson2f (ip);
 
-  mips_mark_labels ();
-
   file_ase_mips16 |= mips_opts.mips16;
   file_ase_micromips |= mips_opts.micromips;
 
@@ -18405,7 +18412,7 @@ mips_frob_file_after_relocs (void)
    move it.  This also bumps the value of the symbol by 1 in compressed
    code.  */
 
-void
+static void
 mips_record_label (symbolS *sym)
 {
   segment_info_type *si = seg_info (now_seg);
@@ -18435,6 +18442,17 @@ mips_define_label (symbolS *sym)
   dwarf2_emit_label (sym);
 #endif
 }
+
+/* This function is called by tc_new_dot_label whenever a new dot symbol
+   is defined.  */
+
+void
+mips_add_dot_label (symbolS *sym)
+{
+  mips_record_label (sym);
+  if (mips_assembling_insn && HAVE_CODE_COMPRESSION)
+    mips_compressed_mark_label (sym);
+}
 \f
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 
index 364ebd853e11608398de5d5ac7872927e0733c21..dc4c0a47869d42174253df9aaa79cdd9b0922078 100644 (file)
@@ -113,8 +113,8 @@ extern int mips_parse_long_option (const char *);
 #define tc_frob_label(sym) mips_define_label (sym)
 extern void mips_define_label (symbolS *);
 
-#define tc_new_dot_label(sym) mips_record_label (sym)
-extern void mips_record_label (symbolS *);
+#define tc_new_dot_label(sym) mips_add_dot_label (sym)
+extern void mips_add_dot_label (symbolS *);
 
 #define tc_frob_file_before_adjust() mips_frob_file_before_adjust ()
 extern void mips_frob_file_before_adjust (void);
index 47baaff4022e6d5ae17337833a904b7c3dafa030..fe5da58cadb4f6473d28859ce1012479c98bca91 100644 (file)
@@ -1,3 +1,9 @@
+2012-09-23  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * gas/mips/dot-1.s, gas/mips/dot-1.d, gas/mips/micromips@dot-1.d,
+       gas/mips/mips16@dot-1.d: New test.
+       * gas/mips/mips.exp: Run it.
+
 2012-09-20  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gas/i386/i386.exp: Run x86-64-arch-2-1 and x86-64-arch-2-2.
diff --git a/gas/testsuite/gas/mips/dot-1.d b/gas/testsuite/gas/mips/dot-1.d
new file mode 100644 (file)
index 0000000..ace625c
--- /dev/null
@@ -0,0 +1,20 @@
+#objdump: -dr --show-raw-insn
+#as: -32
+#name: MIPS dot-1
+#source: dot-1.s
+
+.*file format.*
+
+Disassembly .*
+
+0+0 <foo>:
+.*:    24840000        addiu   a0,a0,0
+       \.\.\.
+.*:    2484000c        addiu   a0,a0,12
+.*:    24840008        addiu   a0,a0,8
+.*:    24840014        addiu   a0,a0,20
+.*:    24840000        addiu   a0,a0,0
+.*:    24840010        addiu   a0,a0,16
+.*:    24840018        addiu   a0,a0,24
+.*:    24840024        addiu   a0,a0,36
+#pass
diff --git a/gas/testsuite/gas/mips/dot-1.s b/gas/testsuite/gas/mips/dot-1.s
new file mode 100644 (file)
index 0000000..78e05bf
--- /dev/null
@@ -0,0 +1,18 @@
+       .ent    foo
+foo:
+       addiu   $4,.-foo
+       nop
+.L1:
+       nop
+       addiu   $4,.L2 - .
+       addiu   $4,. - .L1
+       addiu   $4,. - foo
+.L2:
+       addiu   $4,%lo(.L2 - .)
+       addiu   $4,%lo(.L3 - .)
+       addiu   $4,%lo(. - .L1)
+       addiu   $4,%lo(. - foo)
+       nop
+.L3:
+       nop
+       .end    foo
diff --git a/gas/testsuite/gas/mips/micromips@dot-1.d b/gas/testsuite/gas/mips/micromips@dot-1.d
new file mode 100644 (file)
index 0000000..d66c408
--- /dev/null
@@ -0,0 +1,21 @@
+#objdump: -dr --show-raw-insn
+#as: -32
+#name: MIPS dot-1
+#source: dot-1.s
+
+.*file format.*
+
+Disassembly .*
+
+0+0 <foo>:
+.*:    4c80            addiu   a0,a0,0
+.*:    0c00            nop
+.*:    0c00            nop
+.*:    3084 0008       addiu   a0,a0,8
+.*:    4c8c            addiu   a0,a0,6
+.*:    6e46            addiu   a0,a0,12
+.*:    3084 0000       addiu   a0,a0,0
+.*:    3084 000e       addiu   a0,a0,14
+.*:    3084 0012       addiu   a0,a0,18
+.*:    3084 001a       addiu   a0,a0,26
+#pass
index 1cc4b6fb28c5ecd1484b593a7dc55f112e211cb7..762755e2c938a8d0e33a6c881980e2a21555fbcd 100644 (file)
@@ -478,7 +478,8 @@ if { [istarget mips*-*-vxworks*] } {
     if { $no_micromips } {
        mips_arch_destroy micromips
     }
-    
+
+    run_dump_test_arches "dot-1"       [mips_arch_list_matching mips1]
     run_dump_test_arches "abs"         [mips_arch_list_matching mips1]
     run_dump_test_arches "add"         [mips_arch_list_matching mips1]
     run_dump_test_arches "and"         [mips_arch_list_matching mips1]
diff --git a/gas/testsuite/gas/mips/mips16@dot-1.d b/gas/testsuite/gas/mips/mips16@dot-1.d
new file mode 100644 (file)
index 0000000..55d1282
--- /dev/null
@@ -0,0 +1,21 @@
+#objdump: -dr --show-raw-insn
+#as: -32
+#name: MIPS dot-1
+#source: dot-1.s
+
+.*file format.*
+
+Disassembly .*
+
+0+0 <foo>:
+.*:    4c00            addiu   a0,0
+.*:    6500            nop
+.*:    6500            nop
+.*:    4c06            addiu   a0,6
+.*:    4c04            addiu   a0,4
+.*:    4c0a            addiu   a0,10
+.*:    4c00            addiu   a0,0
+.*:    f000 4c0e       addiu   a0,14
+.*:    f000 4c0e       addiu   a0,14
+.*:    f000 4c16       addiu   a0,22
+#pass