Fix handling of BLX instruction to conform to Operations definition in the

ARM ARM.
This commit is contained in:
Nick Clifton 2002-05-23 12:48:23 +00:00
parent 2984e11475
commit baf0cc5e96
1 changed files with 23 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/* Instruction printing code for the ARM /* Instruction printing code for the ARM
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc. Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modification by James G. Smith (jsmith@cygnus.co.uk) Modification by James G. Smith (jsmith@cygnus.co.uk)
@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "libcoff.h" #include "libcoff.h"
#include "opintl.h" #include "opintl.h"
/* FIXME: This shouldn't be done here */ /* FIXME: This shouldn't be done here. */
#include "elf-bfd.h" #include "elf-bfd.h"
#include "elf/internal.h" #include "elf/internal.h"
#include "elf/arm.h" #include "elf/arm.h"
@ -99,15 +99,16 @@ int get_arm_regnames (int option, const char **setname,
const char **setdescription, const char **setdescription,
const char ***register_names); const char ***register_names);
/* Functions. */ /* Functions. */
int int
get_arm_regname_num_options (void) get_arm_regname_num_options ()
{ {
return NUM_ARM_REGNAMES; return NUM_ARM_REGNAMES;
} }
int int
set_arm_regname_option (int option) set_arm_regname_option (option)
int option;
{ {
int old = regname_selected; int old = regname_selected;
regname_selected = option; regname_selected = option;
@ -115,9 +116,11 @@ set_arm_regname_option (int option)
} }
int int
get_arm_regnames (int option, const char **setname, get_arm_regnames (option, setname, setdescription, register_names)
const char **setdescription, int option;
const char ***register_names) const char **setname;
const char **setdescription;
const char ***register_names;
{ {
*setname = regnames[option].name; *setname = regnames[option].name;
*setdescription = regnames[option].description; *setdescription = regnames[option].description;
@ -161,6 +164,7 @@ arm_decode_shift (given, func, stream)
/* Print one instruction from PC on INFO->STREAM. /* Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (always 4 on ARM). */ Return the size of the instruction (always 4 on ARM). */
static int static int
print_insn_arm (pc, info, given) print_insn_arm (pc, info, given)
bfd_vma pc; bfd_vma pc;
@ -200,7 +204,7 @@ print_insn_arm (pc, info, given)
if ((given & 0x00800000) == 0) if ((given & 0x00800000) == 0)
offset = - offset; offset = - offset;
/* pre-indexed */ /* Pre-indexed. */
func (stream, ", #%d]", offset); func (stream, ", #%d]", offset);
offset += pc + 8; offset += pc + 8;
@ -217,7 +221,8 @@ print_insn_arm (pc, info, given)
/* Post indexed. */ /* Post indexed. */
func (stream, "], #%d", offset); func (stream, "], #%d", offset);
offset = pc + 8; /* ie ignore the offset. */ /* ie ignore the offset. */
offset = pc + 8;
} }
func (stream, "\t; "); func (stream, "\t; ");
@ -740,6 +745,7 @@ print_insn_arm (pc, info, given)
/* Print one instruction from PC on INFO->STREAM. /* Print one instruction from PC on INFO->STREAM.
Return the size of the instruction. */ Return the size of the instruction. */
static int static int
print_insn_thumb (pc, info, given) print_insn_thumb (pc, info, given)
bfd_vma pc; bfd_vma pc;
@ -765,26 +771,17 @@ print_insn_thumb (pc, info, given)
info->bytes_per_line = 4; info->bytes_per_line = 4;
offset = BDISP23 (given); offset = BDISP23 (given);
offset = offset * 2 + pc + 4;
if ((given & 0x10000000) == 0) if ((given & 0x10000000) == 0)
{ {
func (stream, "blx\t"); func (stream, "blx\t");
offset &= 0xfffffffc;
/* The spec says that bit 1 of the branch's destination
address comes from bit 1 of the instruction's
address and not from the offset in the instruction. */
if (offset & 0x1)
{
/* func (stream, "*malformed!* "); */
offset &= ~ 0x1;
}
offset |= ((pc & 0x2) >> 1);
} }
else else
func (stream, "bl\t"); func (stream, "bl\t");
info->print_address_func (offset * 2 + pc + 4, info); info->print_address_func (offset, info);
return 4; return 4;
} }
else else
@ -988,6 +985,7 @@ print_insn_thumb (pc, info, given)
} }
/* Parse an individual disassembler option. */ /* Parse an individual disassembler option. */
void void
parse_arm_disassembler_option (option) parse_arm_disassembler_option (option)
char * option; char * option;
@ -1022,6 +1020,7 @@ parse_arm_disassembler_option (option)
} }
/* Parse the string of disassembler options, spliting it at whitespaces. */ /* Parse the string of disassembler options, spliting it at whitespaces. */
static void static void
parse_disassembler_options (options) parse_disassembler_options (options)
char * options; char * options;
@ -1050,6 +1049,7 @@ parse_disassembler_options (options)
/* NOTE: There are no checks in these routines that /* NOTE: There are no checks in these routines that
the relevant number of data bytes exist. */ the relevant number of data bytes exist. */
static int static int
print_insn (pc, info, little) print_insn (pc, info, little)
bfd_vma pc; bfd_vma pc;