Fix Thumb2 bl range options.
2009-12-21 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Richard Earnshaw <richard.earnshaw@arm.com> * config/tc-arm.c (encode_thumb2_b_bl_offset): New. Refactored from md_apply_fix. (md_apply_fix): Fixup range checks for Thumb2 version of unconditional calls. Call encode_thumb2_b_bl_offset for unconditional branches / function calls.
This commit is contained in:
parent
1a7bd2debe
commit
4a42ebbc0e
|
@ -1,3 +1,12 @@
|
||||||
|
2009-12-21 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||||
|
Richard Earnshaw <richard.earnshaw@arm.com>
|
||||||
|
|
||||||
|
* config/tc-arm.c (encode_thumb2_b_bl_offset): New. Refactored
|
||||||
|
from md_apply_fix.
|
||||||
|
(md_apply_fix): Fixup range checks for Thumb2 version
|
||||||
|
of unconditional calls. Call encode_thumb2_b_bl_offset for
|
||||||
|
unconditional branches / function calls.
|
||||||
|
|
||||||
2009-12-19 H.J. Lu <hongjiu.lu@intel.com>
|
2009-12-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* config/tc-i386.c (process_operands): Check vexvvvv instead
|
* config/tc-i386.c (process_operands): Check vexvvvv instead
|
||||||
|
|
|
@ -19536,6 +19536,31 @@ arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
|
||||||
return FALSE;
|
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
|
void
|
||||||
md_apply_fix (fixS * fixP,
|
md_apply_fix (fixS * fixP,
|
||||||
valueT * valP,
|
valueT * valP,
|
||||||
|
@ -20228,10 +20253,6 @@ md_apply_fix (fixS * fixP,
|
||||||
fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
|
fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
|
||||||
#endif
|
#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)
|
if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
|
||||||
/* For a BLX instruction, make sure that the relocation is rounded up
|
/* For a BLX instruction, make sure that the relocation is rounded up
|
||||||
to a word boundary. This follows the semantics of the instruction
|
to a word boundary. This follows the semantics of the instruction
|
||||||
|
@ -20239,17 +20260,25 @@ md_apply_fix (fixS * fixP,
|
||||||
1 of the base address. */
|
1 of the base address. */
|
||||||
value = (value + 1) & ~ 1;
|
value = (value + 1) & ~ 1;
|
||||||
|
|
||||||
if (fixP->fx_done || !seg->use_rela_p)
|
|
||||||
{
|
|
||||||
offsetT newval2;
|
|
||||||
|
|
||||||
newval = md_chars_to_number (buf, THUMB_SIZE);
|
if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
|
||||||
newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
|
{
|
||||||
newval |= (value & 0x7fffff) >> 12;
|
if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)))
|
||||||
newval2 |= (value & 0xfff) >> 1;
|
{
|
||||||
md_number_to_chars (buf, newval, THUMB_SIZE);
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
|
_("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);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
||||||
|
@ -20258,26 +20287,8 @@ md_apply_fix (fixS * fixP,
|
||||||
_("branch out of range"));
|
_("branch out of range"));
|
||||||
|
|
||||||
if (fixP->fx_done || !seg->use_rela_p)
|
if (fixP->fx_done || !seg->use_rela_p)
|
||||||
{
|
encode_thumb2_b_bl_offset (buf, value);
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_8:
|
case BFD_RELOC_8:
|
||||||
|
|
Loading…
Reference in New Issue