Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1203)

Unified Diff: binutils/gas/config/tc-arm.c

Issue 3018030: [binutils] Bump binutils to 2.20.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « binutils/gas/config/obj-coff.c ('k') | binutils/gas/config/tc-ppc.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: binutils/gas/config/tc-arm.c
diff --git a/binutils/gas/config/tc-arm.c b/binutils/gas/config/tc-arm.c
index 5f67171da32cf9bbb546b6b3014bd65350c9b0bf..69b0f92756cf7b9ffc0ef7dc13fc5d63968b4713 100644
--- a/binutils/gas/config/tc-arm.c
+++ b/binutils/gas/config/tc-arm.c
@@ -2486,7 +2486,9 @@ make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
frag->tc_frag_data.first_map = symbolP;
}
if (frag->tc_frag_data.last_map != NULL)
- know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
+ {
+ know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
+ }
frag->tc_frag_data.last_map = symbolP;
}
@@ -19039,6 +19041,8 @@ md_pcrel_from_section (fixS * fixP, segT seg)
case BFD_RELOC_THUMB_PCREL_BRANCH23:
if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (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;
@@ -19048,6 +19052,8 @@ md_pcrel_from_section (fixS * fixP, segT seg)
zero. */
case BFD_RELOC_THUMB_PCREL_BLX:
if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (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;
@@ -19057,6 +19063,8 @@ md_pcrel_from_section (fixS * fixP, segT seg)
loader expects the relocation not to take this into account. */
case BFD_RELOC_ARM_PCREL_BLX:
if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (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;
@@ -19064,6 +19072,8 @@ md_pcrel_from_section (fixS * fixP, segT seg)
case BFD_RELOC_ARM_PCREL_CALL:
if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (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;
@@ -19381,6 +19391,31 @@ arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
return FALSE;
}
+/* Encode Thumb2 unconditional branches and calls. The encoding
+ for the 2 are identical for the immediate values. */
+
+static void
+encode_thumb2_b_bl_offset (char * buf, offsetT value)
+{
+#define T2I1I2MASK ((1 << 13) | (1 << 11))
+ offsetT newval;
+ offsetT newval2;
+ addressT S, I1, I2, lo, hi;
+
+ S = (value >> 24) & 0x01;
+ I1 = (value >> 23) & 0x01;
+ I2 = (value >> 22) & 0x01;
+ hi = (value >> 12) & 0x3ff;
+ lo = (value >> 1) & 0x7ff;
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+ newval |= (S << 10) | hi;
+ newval2 &= ~T2I1I2MASK;
+ newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+}
+
void
md_apply_fix (fixS * fixP,
valueT * valP,
@@ -20073,10 +20108,6 @@ md_apply_fix (fixS * fixP,
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"));
-
if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
/* For a BLX instruction, make sure that the relocation is rounded up
to a word boundary. This follows the semantics of the instruction
@@ -20084,6 +20115,24 @@ md_apply_fix (fixS * fixP,
1 of the base address. */
value = (value + 1) & ~ 1;
+ if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
+ {
+ if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
+ }
+ else if ((value & ~0x1ffffff)
+ && ((value & ~0x1ffffff) != ~0x1ffffff))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Thumb2 branch out of range"));
+ }
+ }
+
+ if (fixP->fx_done || !seg->use_rela_p)
+ encode_thumb2_b_bl_offset (buf, value);
+
if (fixP->fx_done || !seg->use_rela_p)
{
offsetT newval2;
@@ -20104,24 +20153,7 @@ md_apply_fix (fixS * fixP,
if (fixP->fx_done || !seg->use_rela_p)
{
- offsetT newval2;
- addressT S, I1, I2, lo, hi;
-
- S = (value & 0x01000000) >> 24;
- I1 = (value & 0x00800000) >> 23;
- I2 = (value & 0x00400000) >> 22;
- hi = (value & 0x003ff000) >> 12;
- lo = (value & 0x00000ffe) >> 1;
-
- I1 = !(I1 ^ S);
- I2 = !(I2 ^ S);
-
- newval = md_chars_to_number (buf, THUMB_SIZE);
- newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
- newval |= (S << 10) | hi;
- newval2 |= (I1 << 13) | (I2 << 11) | lo;
- md_number_to_chars (buf, newval, THUMB_SIZE);
- md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ encode_thumb2_b_bl_offset (buf, value);
}
break;
« no previous file with comments | « binutils/gas/config/obj-coff.c ('k') | binutils/gas/config/tc-ppc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698