Fix local branches for bl and blx.
authorRamana Radhakrishnan <ramana.r@gmail.com>
Tue, 5 May 2009 11:41:32 +0000 (11:41 +0000)
committerRamana Radhakrishnan <ramana.r@gmail.com>
Tue, 5 May 2009 11:41:32 +0000 (11:41 +0000)
gas/ChangeLog
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/bl-local-v4t.d [new file with mode: 0644]
gas/testsuite/gas/arm/bl-local-v4t.s [new file with mode: 0644]
gas/testsuite/gas/arm/blx-local-thumb.l [new file with mode: 0644]
gas/testsuite/gas/arm/blx-local.d
gas/testsuite/gas/arm/blx-local.l [new file with mode: 0644]
gas/testsuite/gas/arm/blx-local.s

index e9358094ea827946909ff5be2989c54ae6ce7046..1674d78b02c3a9e5bc58030dbb986143fd7a5876 100644 (file)
@@ -1,3 +1,25 @@
+2009-05-05 Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+
+       * config\tc-arm.h: Fix typo in comment.
+       (ARM_IS_FUNC): New macro.
+       (MD_APPLY_SYM_VALUE): Define.
+
+       * config\tc-arm.c (do_blx): Retain BFD_RELOC_ARM_PCREL_BLX for
+       all versions of EABI.
+       (relax_branch): Do not relax for branches to ARM functions.
+       (md_pcrel_from_section): Set up base correctly for
+       BFD_RELOC_THUMB_PCREL_BLX, BFD_RELOC_THUMB_PCREL_CALL,
+       BFD_RELOC_THUMB_PCREL_BRANCH23, BFD_RELOC_ARM_PCREL_BLX
+       BFD_RELOC_ARM_PCREL_CALL.
+       (md_apply_fix): Flip bl to blx where possible.
+       Flip blx to bl where possible.
+       (arm_force_relocation): Force relocations for
+       BFD_RELOC_ARM_PCREL_JUMP, BFD_RELOC_ARM_PCREL_JUMP,
+       BFD_RELOC_ARM_PCREL_BLX, BFD_RELOC_THUMB_PCREL_BLX,
+       BFD_RELOC_THUMB_PCREL_BRANCH20, BFD_RELOC_THUMB_PCREL_BRANCH23,
+       BFD_RELOC_THUMB_PCREL_BRANCH25.
+       (arm_apply_sym_value): New function.
+       
 2009-05-04  Tristan Gingold  <gingold@adacore.com>
 
        * config/tc-alpha.c: Also declare alpha_prologue_label for OBJ_EVAX.
index 21de2b33296046c06875268835e6fced96d0031b..06253c9efee256cf907a0a9ec57f7ff22662b557 100644 (file)
@@ -6735,7 +6735,7 @@ encode_branch (int default_reloc)
     {
       constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
                  _("the only suffix valid here is '(plt)'"));
-      inst.reloc.type  = BFD_RELOC_ARM_PLT32;
+      inst.reloc.type  = BFD_RELOC_ARM_PLT32;
     }
   else
     {
@@ -6794,15 +6794,12 @@ do_blx (void)
   else
     {
       /* Arg is an address; this instruction cannot be executed
-        conditionally, and the opcode must be adjusted.  */
+        conditionally, and the opcode must be adjusted.
+        We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
+        where we generate out a BFD_RELOC_ARM_PCREL_CALL instead.  */
       constraint (inst.cond != COND_ALWAYS, BAD_COND);
       inst.instruction = 0xfa000000;
-#ifdef OBJ_ELF
-      if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
-       encode_branch (BFD_RELOC_ARM_PCREL_CALL);
-      else
-#endif
-       encode_branch (BFD_RELOC_ARM_PCREL_BLX);
+      encode_branch (BFD_RELOC_ARM_PCREL_BLX);
     }
 }
 
@@ -17461,6 +17458,12 @@ relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
       || sec != S_GET_SEGMENT (fragp->fr_symbol))
     return 4;
 
+#ifdef OBJ_ELF
+  if (S_IS_DEFINED (fragp->fr_symbol)
+      && ARM_IS_FUNC (fragp->fr_symbol))
+      return 4;
+#endif
+
   val = relaxed_symbol_addr (fragp, stretch);
   addr = fragp->fr_address + fragp->fr_fix + 4;
   val -= addr;
@@ -18185,6 +18188,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
              )))
     base = 0;
 
+
   switch (fixP->fx_r_type)
     {
       /* PC relative addressing on the Thumb is slightly odd as the
@@ -18206,21 +18210,43 @@ md_pcrel_from_section (fixS * fixP, segT seg)
     case BFD_RELOC_THUMB_PCREL_BRANCH9:
     case BFD_RELOC_THUMB_PCREL_BRANCH12:
     case BFD_RELOC_THUMB_PCREL_BRANCH20:
-    case BFD_RELOC_THUMB_PCREL_BRANCH23:
     case BFD_RELOC_THUMB_PCREL_BRANCH25:
       return base + 4;
 
+    case BFD_RELOC_THUMB_PCREL_BRANCH23:
+       if (fixP->fx_addsy
+         && ARM_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       base = fixP->fx_where + fixP->fx_frag->fr_address;
+       return base + 4;
+
       /* BLX is like branches above, but forces the low two bits of PC to
         zero.  */
-    case BFD_RELOC_THUMB_PCREL_BLX:
+     case BFD_RELOC_THUMB_PCREL_BLX:
+       if (fixP->fx_addsy
+         && THUMB_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       base = fixP->fx_where + fixP->fx_frag->fr_address;
       return (base + 4) & ~3;
 
       /* ARM mode branches are offset by +8.  However, the Windows CE
         loader expects the relocation not to take this into account.  */
+    case BFD_RELOC_ARM_PCREL_BLX:
+       if (fixP->fx_addsy
+         && ARM_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       base = fixP->fx_where + fixP->fx_frag->fr_address;
+       return base + 8;
+
+      case BFD_RELOC_ARM_PCREL_CALL:
+       if (fixP->fx_addsy
+         && THUMB_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       base = fixP->fx_where + fixP->fx_frag->fr_address;
+       return base + 8;
+
     case BFD_RELOC_ARM_PCREL_BRANCH:
-    case BFD_RELOC_ARM_PCREL_CALL:
     case BFD_RELOC_ARM_PCREL_JUMP:
-    case BFD_RELOC_ARM_PCREL_BLX:
     case BFD_RELOC_ARM_PLT32:
 #ifdef TE_WINCE
       /* When handling fixups immediately, because we have already
@@ -18239,6 +18265,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
       return base + 8;
 #endif
 
+
       /* ARM mode loads relative to PC are also offset by +8.  Unlike
         branches, the Windows CE loader *does* expect the relocation
         to take this into account.  */
@@ -18982,14 +19009,41 @@ md_apply_fix (fixS *  fixP,
 
 #ifdef OBJ_ELF
     case BFD_RELOC_ARM_PCREL_CALL:
-      newval = md_chars_to_number (buf, INSN_SIZE);
-      if ((newval & 0xf0000000) == 0xf0000000)
-       temp = 1;
+
+      if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
+         && fixP->fx_addsy
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && THUMB_IS_FUNC (fixP->fx_addsy))
+       /* Flip the bl to blx. This is a simple flip
+          bit here because we generate PCREL_CALL for
+          unconditional bls.  */
+       {
+         newval = md_chars_to_number (buf, INSN_SIZE);
+         newval = newval | 0x10000000;
+         md_number_to_chars (buf, newval, INSN_SIZE);
+         temp = 1;
+         fixP->fx_done = 1;
+       }
       else
        temp = 3;
       goto arm_branch_common;
 
     case BFD_RELOC_ARM_PCREL_JUMP:
+      if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
+         && fixP->fx_addsy
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && THUMB_IS_FUNC (fixP->fx_addsy))
+       {
+         /* This would map to a bl<cond>, b<cond>,
+            b<always> to a Thumb function. We
+            need to force a relocation for this particular
+            case.  */
+         newval = md_chars_to_number (buf, INSN_SIZE);
+         fixP->fx_done = 0;
+       }
+
     case BFD_RELOC_ARM_PLT32:
 #endif
     case BFD_RELOC_ARM_PCREL_BRANCH:
@@ -18997,7 +19051,30 @@ md_apply_fix (fixS *   fixP,
       goto arm_branch_common;
 
     case BFD_RELOC_ARM_PCREL_BLX:
+
       temp = 1;
+      if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
+         && fixP->fx_addsy
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && ARM_IS_FUNC (fixP->fx_addsy))
+       {
+         /* Flip the blx to a bl and warn.  */
+         const char *name = S_GET_NAME (fixP->fx_addsy);
+         newval = 0xeb000000;
+         as_warn_where (fixP->fx_file, fixP->fx_line,
+                        _("blx to '%s' an ARM ISA state function changed to bl"),
+                         name);
+         md_number_to_chars (buf, newval, INSN_SIZE);
+         temp = 3;
+         fixP->fx_done = 1;
+       }
+
+#ifdef OBJ_ELF
+       if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
+         fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
+#endif
+
     arm_branch_common:
       /* We are going to store value (shifted right by two) in the
         instruction, in a 24 bit, signed field.  Bits 26 through 32 either
@@ -19084,6 +19161,16 @@ md_apply_fix (fixS *   fixP,
       break;
 
     case BFD_RELOC_THUMB_PCREL_BRANCH20:
+      if (fixP->fx_addsy
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && S_IS_DEFINED (fixP->fx_addsy)
+         && ARM_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       {
+         /* Force a relocation for a branch 20 bits wide.  */
+         fixP->fx_done = 0;
+       }
       if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("conditional branch out of range"));
@@ -19109,7 +19196,57 @@ md_apply_fix (fixS *   fixP,
       break;
 
     case BFD_RELOC_THUMB_PCREL_BLX:
+
+      /* If there is a blx from a thumb state function to
+        another thumb function flip this to a bl and warn
+        about it.  */
+
+      if (fixP->fx_addsy
+         && S_IS_DEFINED (fixP->fx_addsy)
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && THUMB_IS_FUNC (fixP->fx_addsy))
+       {
+         const char *name = S_GET_NAME (fixP->fx_addsy);
+         as_warn_where (fixP->fx_file, fixP->fx_line,
+                        _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
+                        name);
+         newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+         newval = newval | 0x1000;
+         md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
+         fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+         fixP->fx_done = 1;
+       }
+
+
+      goto thumb_bl_common;
+
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
+
+      /* A bl from Thumb state ISA to an internal ARM state function
+        is converted to a blx.  */
+      if (fixP->fx_addsy
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && !S_IS_EXTERNAL (fixP->fx_addsy)
+         && S_IS_DEFINED (fixP->fx_addsy)
+         && ARM_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
+       {
+         newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+         newval = newval & ~0x1000;
+         md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
+         fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
+         fixP->fx_done = 1;
+       }
+
+    thumb_bl_common:
+
+#ifdef OBJ_ELF
+       if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4 &&
+          fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
+        fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+#endif
+
       if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("branch out of range"));
@@ -19962,6 +20099,7 @@ arm_validate_fix (fixS * fixP)
 }
 #endif
 
+
 int
 arm_force_relocation (struct fix * fixp)
 {
@@ -19970,6 +20108,34 @@ arm_force_relocation (struct fix * fixp)
     return 1;
 #endif
 
+  /* In case we have a call or a branch to a function in ARM ISA mode from
+     a thumb function or vice-versa force the relocation. These relocations
+     are cleared off for some cores that might have blx and simple transformations
+     are possible.  */
+
+#ifdef OBJ_ELF
+  switch (fixp->fx_r_type)
+    {
+    case BFD_RELOC_ARM_PCREL_JUMP:
+    case BFD_RELOC_ARM_PCREL_CALL:
+    case BFD_RELOC_THUMB_PCREL_BLX:
+      if (THUMB_IS_FUNC (fixp->fx_addsy))
+       return 1;
+      break;
+
+    case BFD_RELOC_ARM_PCREL_BLX:
+    case BFD_RELOC_THUMB_PCREL_BRANCH25:
+    case BFD_RELOC_THUMB_PCREL_BRANCH20:
+    case BFD_RELOC_THUMB_PCREL_BRANCH23:
+      if (ARM_IS_FUNC (fixp->fx_addsy))
+       return 1;
+      break;
+
+    default:
+      break;
+    }
+#endif
+
   /* Resolve these relocations even if the symbol is extern or weak.  */
   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
@@ -20450,7 +20616,7 @@ md_begin (void)
              -mthumb-interwork          Code supports ARM/Thumb interworking
 
              -m[no-]warn-deprecated     Warn about deprecated features
-             
+
       For now we will also provide support for:
 
              -mapcs-32                  32-bit Program counter
@@ -21608,4 +21774,39 @@ arm_convert_symbolic_attribute (const char *name)
 
   return -1;
 }
+
+
+/* Apply sym value for relocations only in the case that
+   they are for local symbols and you have the respective
+   architectural feature for blx and simple switches.  */
+int
+arm_apply_sym_value (struct fix * fixP)
+{
+  if (fixP->fx_addsy
+      && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
+      && !S_IS_EXTERNAL (fixP->fx_addsy))
+    {
+      switch (fixP->fx_r_type)
+       {
+       case BFD_RELOC_ARM_PCREL_BLX:
+       case BFD_RELOC_THUMB_PCREL_BRANCH23:
+         if (ARM_IS_FUNC (fixP->fx_addsy))
+           return 1;
+         break;
+
+       case BFD_RELOC_ARM_PCREL_CALL:
+       case BFD_RELOC_THUMB_PCREL_BLX:
+         if (THUMB_IS_FUNC (fixP->fx_addsy))
+             return 1;
+         break;
+
+       default:
+         break;
+       }
+
+    }
+  return 0;
+}
 #endif /* OBJ_ELF */
+
+
index c6f6fd8c7f04f23da103f95592f9204b3987ec00..13bc86ab7993adfe9bd32f29b66814a528159dfc 100644 (file)
@@ -126,15 +126,24 @@ bfd_boolean arm_is_eabi (void);
 #ifdef OBJ_ELF
 
 /* For ELF objects THUMB_IS_FUNC is inferred from
-   ARM_IS_TUMB and the function type.  */
+   ARM_IS_THUMB and the function type.  */
 #define THUMB_IS_FUNC(s) \
   ((arm_is_eabi () \
     && (ARM_IS_THUMB (s)) \
     && (symbol_get_bfdsym (s)->flags & BSF_FUNCTION)) \
    || (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC))
 
+#define ARM_IS_FUNC(s) \
+  ((arm_is_eabi () \
+    && !(ARM_IS_THUMB (s)) \
+    /* && !(THUMB_FLAG_FUNC & ARM_GET_FLAG (s)) \ */ \
+    && (symbol_get_bfdsym (s)->flags & BSF_FUNCTION)))
+
+
 #else
 #define THUMB_IS_FUNC(s)       (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
+#define ARM_IS_FUNC(s)          (!THUMB_IS_FUNC (s) \
+                                && (symbol_get_bfdsym (s)->flags & BSF_FUNCTION))
 #endif
 
 #define ARM_SET_THUMB(s,t)      ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB)     : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
@@ -247,12 +256,17 @@ struct arm_segment_info_type
 
 # define EXTERN_FORCE_RELOC                    1
 # define tc_fix_adjustable(FIX)                arm_fix_adjustable (FIX)
+#endif
+
+#ifdef OBJ_ELF
 /* Values passed to md_apply_fix don't include the symbol value.  */
-# define MD_APPLY_SYM_VALUE(FIX)               0
+# define MD_APPLY_SYM_VALUE(FIX)               arm_apply_sym_value (FIX)
 #endif
 
 #ifdef OBJ_COFF
 # define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL)  arm_validate_fix (FIX)
+/* Values passed to md_apply_fix don't include the symbol value.  */
+# define MD_APPLY_SYM_VALUE(FIX)               0
 #endif
 
 #define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section(F,S)
@@ -290,4 +304,5 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
 #ifdef OBJ_ELF
 #define CONVERT_SYMBOLIC_ATTRIBUTE(name) arm_convert_symbolic_attribute (name)
 extern int arm_convert_symbolic_attribute (const char *);
+extern int arm_apply_sym_value (struct fix *);
 #endif
index e7a526c744c87f15bc5d84bcfbe8ecc6f9e8f449..b25a40ac4e19caf0f3efe2d373bde101e1b993e7 100644 (file)
@@ -1,3 +1,15 @@
+2009-05-05  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+
+       * gas\arm\bl-local-v4t.d: New file.
+       * gas\arm\bl-local-v4t.s: New file.
+       * gas\arm\blx-local.s: Update for branches and calls to local
+         functions.
+       * gas\arm\blx-local.d: Likewise.
+       * gas\arm\blx-local.l: New file.
+       * gas\arm\blx-local-thumb.l: New file.
+       * gas\arm\blx-local-thumb.s: New file.
+       * gas\arm\blx-local-thumb.d: New file.
+
 2009-05-01  Nathan Sidwell  <nathan@codesourcery.com>
            Daniel Jacobowitz  <dan@codesourcery.com>
 
diff --git a/gas/testsuite/gas/arm/bl-local-v4t.d b/gas/testsuite/gas/arm/bl-local-v4t.d
new file mode 100644 (file)
index 0000000..b5af7fd
--- /dev/null
@@ -0,0 +1,19 @@
+#name: bl local instructions for v4t.
+#objdump: -drw --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#as:
+# stderr: blx-local-thumb.l
+
+.*: +file format .*arm.*
+Disassembly of section .text:
+0+00 <[^>]*> f7ff fffe         bl      00+18 <[^>]*>   0: R_ARM_THM_CALL       foo2
+0+1c <[^>]*> d004              beq.n   00+28 <[^>]*>
+0+1e <[^>]*> e003              b.n     00+28 <[^>]*>
+0+20 <[^>]*> f000 f808         bl      00+34 <[^>]*>
+0+24 <[^>]*> f000 f802         bl      00+2c <[^>]*>
+0+28 <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+2a <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+2c <[^>]*> 46c0              nop                     \(mov r8, r8\)
+       ...
+0+30 <[^>]*> e1a00000  nop                     \(mov r0,r0\)
+0+34 <[^>]*> e1a00000  nop                     \(mov r0,r0\)
\ No newline at end of file
diff --git a/gas/testsuite/gas/arm/bl-local-v4t.s b/gas/testsuite/gas/arm/bl-local-v4t.s
new file mode 100644 (file)
index 0000000..4935344
--- /dev/null
@@ -0,0 +1,25 @@
+        .text
+       .arch armv4t
+       .syntax unified
+       .thumb
+one:
+       bl      foo2  @ bl foo2 with reloc.
+       beq     foo   @ beq foo with reloc.
+       b       foo   @ branch foo with reloc.
+       bl      fooundefarm
+       bl      fooundefthumb
+       .thumb
+        .type foo, %function
+        .thumb_func
+foo:
+        nop
+       nop
+fooundefthumb:
+       nop
+        .type foo2, %function
+       .arm
+       .align  2
+foo2:
+        nop
+fooundefarm:
+       nop
diff --git a/gas/testsuite/gas/arm/blx-local-thumb.l b/gas/testsuite/gas/arm/blx-local-thumb.l
new file mode 100644 (file)
index 0000000..588674c
--- /dev/null
@@ -0,0 +1,2 @@
+[^;]*: Assembler messages:
+[^;]*:6: Warning: blx to Thumb func 'foo' from Thumb ISA state changed to bl
\ No newline at end of file
index e187536b363035d5076c102ae4ed91083b6b8a2d..4b7d53a85f19801406cb678f75e2cf0c4320cb91 100644 (file)
@@ -1,15 +1,29 @@
 #name: Local BLX instructions
-#objdump: -dr --prefix-addresses --show-raw-insn
+#objdump: -drw --prefix-addresses --show-raw-insn
 #skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
 #as:
-
-# Test assembler resolution of blx instructions.
-
+# stderr: blx-local.l
+# Test assembler resolution of blx and bl instructions in ARM mode.
 .*: +file format .*arm.*
 
 Disassembly of section .text:
-
-0+00 <[^>]*> fa000000  blx     00+8 <foo>
-0+04 <[^>]*> fbffffff  blx     00+a <foo2>
-0+08 <[^>]*> 46c0              nop                     \(mov r8, r8\)
-0+0a <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+00 <[^>]*> fa000006  blx     00000020 <foo>
+0+04 <[^>]*> eb000007  bl      00000028 <foo2>
+0+08 <[^>]*> fa000004  blx     00000020 <foo>
+0+0c <[^>]*> eb000005  bl      00000028 <foo2>
+0+10 <[^>]*> fa00000b  blx     00000044 <fooundefarm>
+0+14 <[^>]*> eb00000a  bl      00000044 <fooundefarm>
+0+18 <[^>]*> fa000001  blx     00000024 <fooundefthumb>
+0+1c <[^>]*> eb000000  bl      00000024 <fooundefthumb>
+0+20 <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+22 <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+24 <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+26 <[^>]*> 46c0              nop                     \(mov r8, r8\)
+0+28 <[^>]*> 0bfffffd  bleq    00000024 <fooundefthumb>
+0+2c <[^>]*> 0afffffc  beq     00000024 <fooundefthumb>
+0+30 <[^>]*> eafffffb  b       00000024 <fooundefthumb>
+0+34 <[^>]*> 0bfffffe  bleq    00000020 <foo>  34: R_ARM_JUMP24        foo
+0+58 <[^>]*> 0afffffe  beq     00000020 <foo>  38: R_ARM_JUMP24        foo
+0+5c <[^>]*> eafffffe  b       00000020 <foo>  3c: R_ARM_JUMP24        foo
+0+60 <[^>]*> e1a00000  nop                     \(mov r0,r0\)
+0+64 <[^>]*> e1a00000  nop                     \(mov r0,r0\)
diff --git a/gas/testsuite/gas/arm/blx-local.l b/gas/testsuite/gas/arm/blx-local.l
new file mode 100644 (file)
index 0000000..fcca464
--- /dev/null
@@ -0,0 +1,3 @@
+[^;]*: Assembler messages:
+[^;]*:9: Warning: blx to 'foo2' an ARM ISA state function changed to bl
+
index c85a562d90f80c1f16dfae4a8e41d61bcea6851d..ed587c9e4c5864d29a6dd259e374a16cbce857a1 100644 (file)
@@ -1,16 +1,38 @@
-        .text
-       .arch armv5t
-        .arm
-one:
-        blx     foo
-        blx     foo2
+# objdump: -fdrw --prefix-addresses --show-raw-insn
+# not-target: *-*-*aout* *-*-pe
 
-        .thumb
-        .type foo, %function
-        .thumb_func
+  .text
+  .arch armv5t
+  .arm
+one:
+        blx    foo
+       blx     foo2
+       bl      foo
+       bl      foo2
+       blx     fooundefarm
+       bl      fooundefarm
+       blx     fooundefthumb
+       bl      fooundefthumb
+       
+       .thumb
+       .type foo, %function
+       .thumb_func
 foo:
-        nop
+       nop
+       nop
+fooundefthumb:
+       nop
+
+       .align 2
         .type foo2, %function
-        .thumb_func
+       .arm
 foo2:
-        nop
+       bleq  fooundefthumb @no relocs
+       beq   fooundefthumb @no relocs
+       b     fooundefthumb @no relocs
+       bleq  foo  @ R_ARM_PCREL_JUMP
+       beq   foo  @ R_ARM_PCREL_JUMP
+       b     foo  @ R_ARM_PCREL_JUMP
+       nop
+fooundefarm:
+       nop