aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana.r@gmail.com>2009-05-05 11:41:32 +0000
committerRamana Radhakrishnan <ramana.r@gmail.com>2009-05-05 11:41:32 +0000
commit267bf99505c8522ff9e10ec56c195deb533da338 (patch)
treeadbf93eacd361f3d3d7308525148afbfbfb88d6b
parent84f1b567bb140a51db3dd7032e34707ffe7974d2 (diff)
downloadfsf-binutils-gdb-267bf99505c8522ff9e10ec56c195deb533da338.zip
fsf-binutils-gdb-267bf99505c8522ff9e10ec56c195deb533da338.tar.gz
fsf-binutils-gdb-267bf99505c8522ff9e10ec56c195deb533da338.tar.bz2
Fix local branches for bl and blx.
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/tc-arm.c233
-rw-r--r--gas/config/tc-arm.h19
-rw-r--r--gas/testsuite/ChangeLog12
-rw-r--r--gas/testsuite/gas/arm/bl-local-v4t.d19
-rw-r--r--gas/testsuite/gas/arm/bl-local-v4t.s25
-rw-r--r--gas/testsuite/gas/arm/blx-local-thumb.l2
-rw-r--r--gas/testsuite/gas/arm/blx-local.d32
-rw-r--r--gas/testsuite/gas/arm/blx-local.l3
-rw-r--r--gas/testsuite/gas/arm/blx-local.s46
10 files changed, 374 insertions, 39 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index e935809..1674d78 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 21de2b3..06253c9 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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 */
+
+
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index c6f6fd8..13bc86a 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index e7a526c..b25a40a 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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
index 0000000..b5af7fd
--- /dev/null
+++ b/gas/testsuite/gas/arm/bl-local-v4t.d
@@ -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
index 0000000..4935344
--- /dev/null
+++ b/gas/testsuite/gas/arm/bl-local-v4t.s
@@ -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
index 0000000..588674c
--- /dev/null
+++ b/gas/testsuite/gas/arm/blx-local-thumb.l
@@ -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
diff --git a/gas/testsuite/gas/arm/blx-local.d b/gas/testsuite/gas/arm/blx-local.d
index e187536..4b7d53a 100644
--- a/gas/testsuite/gas/arm/blx-local.d
+++ b/gas/testsuite/gas/arm/blx-local.d
@@ -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
index 0000000..fcca464
--- /dev/null
+++ b/gas/testsuite/gas/arm/blx-local.l
@@ -0,0 +1,3 @@
+[^;]*: Assembler messages:
+[^;]*:9: Warning: blx to 'foo2' an ARM ISA state function changed to bl
+
diff --git a/gas/testsuite/gas/arm/blx-local.s b/gas/testsuite/gas/arm/blx-local.s
index c85a562..ed587c9 100644
--- a/gas/testsuite/gas/arm/blx-local.s
+++ b/gas/testsuite/gas/arm/blx-local.s
@@ -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