2010-01-13 Chao-ying Fu <fu@mips.com>

* elfxx-mips.c (JR_TO_B_P): New define to transform JR to B.
	It is true for all CPUs.
	(jal_reloc_p): New function.
	(mips_elf_calculate_relocation): Rename require_jalxp to
	cross_mode_jump_p.
	Update comment for CROSS_MODE_JUMP_P.
	Set up cross_mode_jump_p based on the mode change.
	(mips_elf_perform_relocation): Rename require_jalx to cross_mode_jump_p.
	Update comment for CROSS_MODE_JUMP_P.
	Test cross_mode_jump_p and jal_reloc_p to turn jal to jalx.
	Use !cross_mode_jump_p to guard conversion.
	Convert "jr t9" to "b", if possible.
	(_bfd_mips_elf_relocate_section): Rename require_jalx to
	cross_mode_jump_p.
	Pass &cross_mode_jump_p to call mips_elf_calculate_relocation.
	Pass cross_mode_jump_p to call mips_elf_perform_relocation.
This commit is contained in:
Chao-ying Fu 2010-01-13 22:30:53 +00:00
parent 4427219284
commit 38a7df635c
2 changed files with 60 additions and 19 deletions

View File

@ -1,3 +1,22 @@
2010-01-13 Chao-ying Fu <fu@mips.com>
* elfxx-mips.c (JR_TO_B_P): New define to transform JR to B.
It is true for all CPUs.
(jal_reloc_p): New function.
(mips_elf_calculate_relocation): Rename require_jalxp to
cross_mode_jump_p.
Update comment for CROSS_MODE_JUMP_P.
Set up cross_mode_jump_p based on the mode change.
(mips_elf_perform_relocation): Rename require_jalx to cross_mode_jump_p.
Update comment for CROSS_MODE_JUMP_P.
Test cross_mode_jump_p and jal_reloc_p to turn jal to jalx.
Use !cross_mode_jump_p to guard conversion.
Convert "jr t9" to "b", if possible.
(_bfd_mips_elf_relocate_section): Rename require_jalx to
cross_mode_jump_p.
Pass &cross_mode_jump_p to call mips_elf_calculate_relocation.
Pass cross_mode_jump_p to call mips_elf_perform_relocation.
2010-01-13 Nick Clifton <nickc@redhat.com>
* cpu-m32c.c (m32c_scan): New function. Ensures that a scan for

View File

@ -680,6 +680,11 @@ static bfd *reldyn_sorting_bfd;
all CPUs. */
#define JALR_TO_BAL_P(abfd) 1
/* True if ABFD is for CPUs that are faster if JR is converted to B.
This should be safe for all architectures. We enable this predicate for
all CPUs. */
#define JR_TO_B_P(abfd) 1
/* True if ABFD is a PIC object. */
#define PIC_OBJECT_P(abfd) \
((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
@ -1871,6 +1876,12 @@ mips16_call_reloc_p (int r_type)
return r_type == R_MIPS16_26 || r_type == R_MIPS16_CALL16;
}
static inline bfd_boolean
jal_reloc_p (int r_type)
{
return r_type == R_MIPS_26 || r_type == R_MIPS16_26;
}
void
_bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type,
bfd_boolean jal_shuffle, bfd_byte *data)
@ -4771,8 +4782,8 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
RELOCATION; RELOCATION->R_ADDEND is ignored.
The result of the relocation calculation is stored in VALUEP.
REQUIRE_JALXP indicates whether or not the opcode used with this
relocation must be JALX.
On exit, set *CROSS_MODE_JUMP_P to true if the relocation field
is a MIPS16 jump to non-MIPS16 code, or vice versa.
This function returns bfd_reloc_continue if the caller need take no
further action regarding this relocation, bfd_reloc_notsupported if
@ -4787,7 +4798,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
bfd_vma addend, reloc_howto_type *howto,
Elf_Internal_Sym *local_syms,
asection **local_sections, bfd_vma *valuep,
const char **namep, bfd_boolean *require_jalxp,
const char **namep,
bfd_boolean *cross_mode_jump_p,
bfd_boolean save_addend)
{
/* The eventual value we will return. */
@ -5076,10 +5088,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+ h->la25_stub->offset);
/* Calls from 16-bit code to 32-bit code and vice versa require the
special jalx instruction. */
*require_jalxp = (!info->relocatable
&& (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p)
|| ((r_type == R_MIPS_26) && target_is_16_bit_code_p)));
mode change. */
*cross_mode_jump_p = !info->relocatable
&& ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
|| ((r_type == R_MIPS_26 || r_type == R_MIPS_JALR)
&& target_is_16_bit_code_p));
local_p = mips_elf_local_relocation_p (input_bfd, relocation,
local_sections, TRUE);
@ -5533,9 +5546,9 @@ mips_elf_obtain_contents (reloc_howto_type *howto,
/* It has been determined that the result of the RELOCATION is the
VALUE. Use HOWTO to place VALUE into the output file at the
appropriate position. The SECTION is the section to which the
relocation applies. If REQUIRE_JALX is TRUE, then the opcode used
for the relocation must be either JAL or JALX, and it is
unconditionally converted to JALX.
relocation applies.
CROSS_MODE_JUMP_P is true if the relocation field
is a MIPS16 jump to non-MIPS16 code, or vice versa.
Returns FALSE if anything goes wrong. */
@ -5545,7 +5558,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
const Elf_Internal_Rela *relocation,
bfd_vma value, bfd *input_bfd,
asection *input_section, bfd_byte *contents,
bfd_boolean require_jalx)
bfd_boolean cross_mode_jump_p)
{
bfd_vma x;
bfd_byte *location;
@ -5566,7 +5579,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
x |= (value & howto->dst_mask);
/* If required, turn JAL into JALX. */
if (require_jalx)
if (cross_mode_jump_p && jal_reloc_p (r_type))
{
bfd_boolean ok;
bfd_vma opcode = x >> 26;
@ -5600,15 +5613,19 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
}
/* Try converting JAL and JALR to BAL, if the target is in range. */
/* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
range. */
if (!info->relocatable
&& !require_jalx
&& !cross_mode_jump_p
&& ((JAL_TO_BAL_P (input_bfd)
&& r_type == R_MIPS_26
&& (x >> 26) == 0x3) /* jal addr */
|| (JALR_TO_BAL_P (input_bfd)
&& r_type == R_MIPS_JALR
&& x == 0x0320f809))) /* jalr t9 */
&& x == 0x0320f809) /* jalr t9 */
|| (JR_TO_B_P (input_bfd)
&& r_type == R_MIPS_JALR
&& x == 0x03200008))) /* jr t9 */
{
bfd_vma addr;
bfd_vma dest;
@ -5624,7 +5641,12 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
dest = value;
off = dest - addr;
if (off <= 0x1ffff && off >= -0x20000)
x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
{
if (x == 0x03200008) /* jr t9 */
x = 0x10000000 | (((bfd_vma) off >> 2) & 0xffff); /* b addr */
else
x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
}
}
/* Put the value into the output. */
@ -8886,7 +8908,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
const char *name;
bfd_vma value = 0;
reloc_howto_type *howto;
bfd_boolean require_jalx;
bfd_boolean cross_mode_jump_p;
/* TRUE if the relocation is a RELA relocation, rather than a
REL relocation. */
bfd_boolean rela_relocation_p = TRUE;
@ -9086,7 +9108,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
input_section, info, rel,
addend, howto, local_syms,
local_sections, &value,
&name, &require_jalx,
&name, &cross_mode_jump_p,
use_saved_addend_p))
{
case bfd_reloc_continue:
@ -9198,7 +9220,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* Actually perform the relocation. */
if (! mips_elf_perform_relocation (info, howto, rel, value,
input_bfd, input_section,
contents, require_jalx))
contents, cross_mode_jump_p))
return FALSE;
}