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>
|
||||
|
||||
* config/tc-i386.c (process_operands): Check vexvvvv instead
|
||||
|
|
|
@ -19536,6 +19536,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,
|
||||
|
@ -20228,10 +20253,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
|
||||
|
@ -20239,17 +20260,25 @@ md_apply_fix (fixS * fixP,
|
|||
1 of the base address. */
|
||||
value = (value + 1) & ~ 1;
|
||||
|
||||
if (fixP->fx_done || !seg->use_rela_p)
|
||||
{
|
||||
offsetT newval2;
|
||||
|
||||
newval = md_chars_to_number (buf, THUMB_SIZE);
|
||||
newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
|
||||
newval |= (value & 0x7fffff) >> 12;
|
||||
newval2 |= (value & 0xfff) >> 1;
|
||||
md_number_to_chars (buf, newval, THUMB_SIZE);
|
||||
md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
|
||||
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);
|
||||
|
||||
break;
|
||||
|
||||
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
||||
|
@ -20258,26 +20287,8 @@ md_apply_fix (fixS * fixP,
|
|||
_("branch out of range"));
|
||||
|
||||
if (fixP->fx_done || !seg->use_rela_p)
|
||||
{
|
||||
offsetT newval2;
|
||||
addressT S, I1, I2, lo, hi;
|
||||
encode_thumb2_b_bl_offset (buf, value);
|
||||
|
||||
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;
|
||||
|
||||
case BFD_RELOC_8:
|
||||
|
|
Loading…
Reference in New Issue