* arm-dis.c: Split up the comments describing the format codes, so

that the ARM and 16-bit Thumb opcode tables each have comments
	preceding them that describe all the codes, and only the codes,
	valid in those tables.  (32-bit Thumb table is already like this.)
	Reorder the lists in all three comments to match the order in
	which the codes are implemented.
	Remove all forward declarations of static functions.  Convert all
	function definitions to ISO C format.
	(print_insn_arm, print_insn_thumb16, print_insn_thumb32):
	Return nothing.
	(print_insn_thumb16): Remove unused case 'I'.
	(print_insn): Update for changed calling convention of subroutines.
This commit is contained in:
Zack Weinberg 2005-06-07 22:16:52 +00:00
parent 1ae72221f9
commit 4a5329c63a
2 changed files with 119 additions and 140 deletions

View File

@ -1,3 +1,18 @@
2005-06-07 Zack Weinberg <zack@codesourcery.com>
* arm-dis.c: Split up the comments describing the format codes, so
that the ARM and 16-bit Thumb opcode tables each have comments
preceding them that describe all the codes, and only the codes,
valid in those tables. (32-bit Thumb table is already like this.)
Reorder the lists in all three comments to match the order in
which the codes are implemented.
Remove all forward declarations of static functions. Convert all
function definitions to ISO C format.
(print_insn_arm, print_insn_thumb16, print_insn_thumb32):
Return nothing.
(print_insn_thumb16): Remove unused case 'I'.
(print_insn): Update for changed calling convention of subroutines.
2005-05-25 Jan Beulich <jbeulich@novell.com>
* i386-dis.c (OP_E): In Intel mode, display 32-bit displacements in

View File

@ -49,66 +49,57 @@
#define WORD_ADDRESS(pc) ((pc) & ~0x3)
/* Format of the disassembler control string :
/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
ordered: they must be searched linearly from the top to obtain a correct
match. */
/* print_insn_arm recognizes the following format control codes:
%% %
%a print address for ldr/str instruction
%s print address for ldr/str halfword/signextend instruction
%b print branch destination
%c print condition code (always bits 28-31)
%m print register mask for ldm/stm instruction
%o print operand2 (immediate or register + shift)
%p print 'p' iff bits 12-15 are 15
%t print 't' iff bit 21 set and bit 24 clear
%A print address for ldc/stc/ldf/stf instruction
%B print arm BLX(1) destination
%I print cirrus signed shift immediate: bits 0..3|4..6
%C print the PSR sub type.
%F print the COUNT field of a LFM/SFM instruction.
%P print floating point precision in arithmetic insn
%Q print floating point precision in ldf/stf insn
%R print floating point rounding mode
%<bitfield>r print as an ARM register
%<bitfield>d print the bitfield in decimal
%<bitfield>W print the bitfield plus one in decimal
%<bitfield>x print the bitfield in hex
%<bitfield>X print the bitfield as 1 hex digit without leading "0x"
%<bitfield>W print the bitfield plus one in decimal
%<bitfield>r print as an ARM register
%<bitfield>f print a floating point constant if >7 else a
floating point register
%<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
%<bitfield>g print as an iWMMXt 64-bit register
%<bitfield>G print as an iWMMXt general purpose or control register
%<code>y print a single precision VFP reg.
Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
%<code>z print a double precision VFP reg
Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
%c print condition code (always bits 28-31)
%P print floating point precision in arithmetic insn
%Q print floating point precision in ldf/stf insn
%R print floating point rounding mode
%<bitnum>'c print specified char iff bit is one
%<bitnum>`c print specified char iff bit is zero
%<bitnum>?ab print a if bit is one else print b
%p print 'p' iff bits 12-15 are 15
%t print 't' iff bit 21 set and bit 24 clear
%o print operand2 (immediate or register + shift)
%a print address for ldr/str instruction
%s print address for ldr/str halfword/signextend instruction
%b print branch destination
%B print arm BLX(1) destination
%A print address for ldc/stc/ldf/stf instruction
%m print register mask for ldm/stm instruction
%C print the PSR sub type.
%F print the COUNT field of a LFM/SFM instruction.
%E print the LSB and WIDTH fields of a BFI or BFC instruction.
%V print the 16-bit immediate field of a MOVT or MOVW instruction.
IWMMXT specific format options:
%<bitfield>g print as an iWMMXt 64-bit register
%<bitfield>G print as an iWMMXt general purpose or control register
%<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
%Z print the Immediate of a WSHUFH instruction.
%L print as an iWMMXt N/M width field.
%l like 'A' except use byte offsets for 'B' & 'H' versions
Thumb specific format options:
%D print Thumb register (bits 0..2 as high number if bit 7 set)
%S print Thumb register (bits 3..5 as high number if bit 6 set)
%<bitfield>I print bitfield as a signed decimal
(top bit of range being the sign bit)
%M print Thumb register mask
%N print Thumb register mask (with LR)
%O print Thumb register mask (with PC)
%I print cirrus signed shift immediate: bits 0..3|4..6
%<bitfield>B print Thumb branch destination (signed displacement)
%<bitfield>W print (bitfield * 4) as a decimal
%<bitfield>H print (bitfield * 2) as a decimal
%<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
%<bitfield>c print bitfield as a condition code
%e print arm SMI operand (bits 0..7,8..19).
%s print Thumb right-shift immediate (6..10; 0 == 32). */
/* Note: There is a partial ordering in this table - it must be searched from
the top to obtain a correct match. */
%L print as an iWMMXt N/M width field.
%Z print the Immediate of a WSHUFH instruction.
%l like 'A' except use byte offsets for 'B' & 'H' versions.
%e print arm SMI operand (bits 0..7,8..19).
%E print the LSB and WIDTH fields of a BFI or BFC instruction.
%V print the 16-bit immediate field of a MOVT or MOVW instruction. */
static const struct arm_opcode arm_opcodes[] =
{
@ -632,6 +623,27 @@ static const struct arm_opcode arm_opcodes[] =
{0, 0x00000000, 0x00000000, 0}
};
/* print_insn_thumb16 recognizes the following format control codes:
%S print Thumb register (bits 3..5 as high number if bit 6 set)
%D print Thumb register (bits 0..2 as high number if bit 7 set)
%<bitfield>I print bitfield as a signed decimal
(top bit of range being the sign bit)
%N print Thumb register mask (with LR)
%O print Thumb register mask (with PC)
%M print Thumb register mask
%b print CZB's 6-bit unsigned branch destination
%s print Thumb right-shift immediate (6..10; 0 == 32).
%<bitfield>r print bitfield as an ARM register
%<bitfield>d print bitfield as a decimal
%<bitfield>H print (bitfield * 2) as a decimal
%<bitfield>W print (bitfield * 4) as a decimal
%<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
%<bitfield>B print Thumb branch destination (signed displacement)
%<bitfield>c print bitfield as a condition code
%<bitnum>'c print specified char iff bit is one
%<bitnum>?ab print a if bit is one else print b. */
static const struct thumb_opcode thumb_opcodes[] =
{
/* Thumb instructions. */
@ -761,17 +773,9 @@ static const struct thumb_opcode thumb_opcodes[] =
We adopt the convention that hw1 is the high 16 bits of .value and
.mask, hw2 the low 16 bits.
%-escapes defined for these instructions:
print_insn_thumb32 recognizes the following format control codes:
%% %
%<bitfield>d print bitfield in decimal
%<bitfield>W print bitfield*4 in decimal
%<bitfield>r print bitfield as an ARM register
%<bitfield>c print bitfield as a condition code
%<bitnum>'c print "c" iff bit is one
%<bitnum>`c print "c" iff bit is zero
%<bitnum>?ab print "a" if bit is one, else "b"
%I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
%M print a modified 12-bit immediate (same location)
@ -786,11 +790,20 @@ static const struct thumb_opcode thumb_opcodes[] =
%E print the lsb and width fields of a bfc/bfi instruction
%F print the lsb and width fields of a sbfx/ubfx instruction
%B print an unconditional branch offset
%b print a conditional branch offset
%B print an unconditional branch offset
%s print the shift field of an SSAT instruction
%R print the rotation field of an SXT instruction
%<bitfield>d print bitfield in decimal
%<bitfield>W print bitfield*4 in decimal
%<bitfield>r print bitfield as an ARM register
%<bitfield>c print bitfield as a condition code
%<bitnum>'c print "c" iff bit is one
%<bitnum>`c print "c" iff bit is zero
%<bitnum>?ab print "a" if bit is one, else "b"
With one exception at the bottom (done because BL and BLX(1) need
to come dead last), this table was machine-sorted first in
decreasing order of number of bits set in the mask, then in
@ -1062,39 +1075,15 @@ static char * arm_fp_const[] =
static char * arm_shift[] =
{"lsl", "lsr", "asr", "ror"};
/* Forward declarations. */
static void arm_decode_shift
PARAMS ((long, fprintf_ftype, void *));
static int print_insn_arm
PARAMS ((bfd_vma, struct disassemble_info *, long));
static int print_insn_thumb16
PARAMS ((bfd_vma, struct disassemble_info *, long));
static int print_insn_thumb32
PARAMS ((bfd_vma, struct disassemble_info *, long));
static void parse_disassembler_options
PARAMS ((char *));
static int print_insn
PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
static int set_iwmmxt_regnames
PARAMS ((void));
int get_arm_regname_num_options
PARAMS ((void));
int set_arm_regname_option
PARAMS ((int));
int get_arm_regnames
PARAMS ((int, const char **, const char **, const char ***));
/* Functions. */
int
get_arm_regname_num_options ()
get_arm_regname_num_options (void)
{
return NUM_ARM_REGNAMES;
}
int
set_arm_regname_option (option)
int option;
set_arm_regname_option (int option)
{
int old = regname_selected;
regname_selected = option;
@ -1102,11 +1091,8 @@ set_arm_regname_option (option)
}
int
get_arm_regnames (option, setname, setdescription, register_names)
int option;
const char **setname;
const char **setdescription;
const char ***register_names;
get_arm_regnames (int option, const char **setname, const char **setdescription,
const char ***register_names)
{
*setname = regnames[option].name;
*setdescription = regnames[option].description;
@ -1115,10 +1101,7 @@ get_arm_regnames (option, setname, setdescription, register_names)
}
static void
arm_decode_shift (given, func, stream)
long given;
fprintf_ftype func;
void * stream;
arm_decode_shift (long given, fprintf_ftype func, void *stream)
{
func (stream, "%s", arm_regnames[given & 0xf]);
@ -1149,7 +1132,7 @@ arm_decode_shift (given, func, stream)
}
static int
set_iwmmxt_regnames ()
set_iwmmxt_regnames (void)
{
const char * setname;
const char * setdesc;
@ -1165,15 +1148,11 @@ set_iwmmxt_regnames ()
return iwmmxt_regnames;
}
/* Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (always 4 on ARM). */
static int
print_insn_arm (pc, info, given)
bfd_vma pc;
struct disassemble_info *info;
long given;
/* Print one ARM instruction from PC on INFO->STREAM. */
static void
print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
{
const struct arm_opcode *insn;
void *stream = info->stream;
@ -1911,20 +1890,16 @@ print_insn_arm (pc, info, given)
else
func (stream, "%c", *c);
}
return 4;
return;
}
}
abort ();
}
/* Print one instruction from PC on INFO->STREAM.
Return the size of the instruction. */
/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
static int
print_insn_thumb16 (pc, info, given)
bfd_vma pc;
struct disassemble_info *info;
long given;
static void
print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
{
const struct thumb_opcode *insn;
void *stream = info->stream;
@ -2093,11 +2068,6 @@ print_insn_thumb16 (pc, info, given)
func (stream, "0x%04x", reg);
break;
case 'I':
reg = ((reg ^ (1 << bitend)) - (1 << bitend));
func (stream, "%d", reg);
break;
case 'B':
reg = ((reg ^ (1 << bitend)) - (1 << bitend));
(*info->print_address_func)
@ -2145,18 +2115,17 @@ print_insn_thumb16 (pc, info, given)
abort ();
}
}
return 2;
return;
}
/* No match. */
abort ();
}
static int
print_insn_thumb32 (pc, info, given)
bfd_vma pc;
struct disassemble_info *info;
long given;
/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
static void
print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
{
const struct arm_opcode *insn;
void *stream = info->stream;
@ -2554,7 +2523,7 @@ print_insn_thumb32 (pc, info, given)
abort ();
}
}
return 4;
return;
}
/* No match. */
@ -2581,8 +2550,7 @@ arm_symbol_is_valid (asymbol * sym,
/* Parse an individual disassembler option. */
void
parse_arm_disassembler_option (option)
char * option;
parse_arm_disassembler_option (char *option)
{
if (option == NULL)
return;
@ -2619,8 +2587,7 @@ parse_arm_disassembler_option (option)
or commas. (Whitespace separators supported for backwards compatibility). */
static void
parse_disassembler_options (options)
char * options;
parse_disassembler_options (char *options)
{
if (options == NULL)
return;
@ -2642,16 +2609,14 @@ parse_disassembler_options (options)
the relevant number of data bytes exist. */
static int
print_insn (pc, info, little)
bfd_vma pc;
struct disassemble_info * info;
bfd_boolean little;
print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
{
unsigned char b[4];
long given;
int status;
int is_thumb;
int (*printer) (bfd_vma, struct disassemble_info *, long);
int size;
void (*printer) (bfd_vma, struct disassemble_info *, long);
if (info->disassembler_options)
{
@ -2697,6 +2662,7 @@ print_insn (pc, info, little)
is four bytes long and is either ordered 0123 or 3210. */
printer = print_insn_arm;
info->bytes_per_chunk = 4;
size = 4;
status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
if (little)
@ -2710,8 +2676,10 @@ print_insn (pc, info, little)
instruction lengths. Fortunately, the bits that determine
the length of the current instruction are always to be found
in the first two bytes. */
printer = print_insn_thumb16;
info->bytes_per_chunk = 2;
size = 2;
status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
if (!status)
{
@ -2733,9 +2701,8 @@ print_insn (pc, info, little)
given = (b[1]) | (b[0] << 8) | (given << 16);
printer = print_insn_thumb32;
size = 4;
}
else
printer = print_insn_thumb16;
}
}
@ -2752,27 +2719,24 @@ print_insn (pc, info, little)
addresses, since the addend is not currently pc-relative. */
pc = 0;
return printer (pc, info, given);
printer (pc, info, given);
return size;
}
int
print_insn_big_arm (pc, info)
bfd_vma pc;
struct disassemble_info * info;
print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
{
return print_insn (pc, info, FALSE);
}
int
print_insn_little_arm (pc, info)
bfd_vma pc;
struct disassemble_info * info;
print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
{
return print_insn (pc, info, TRUE);
}
void
print_arm_disassembler_options (FILE * stream)
print_arm_disassembler_options (FILE *stream)
{
int i;