mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
(md_create_short_jump, md_create_long_jump,
md_number_to_chars, md_section_align): Adjusted for new interface.
This commit is contained in:
@ -34,7 +34,7 @@
|
|||||||
/* 'md_assemble ()' gathers together information and puts it into a
|
/* 'md_assemble ()' gathers together information and puts it into a
|
||||||
i386_insn. */
|
i386_insn. */
|
||||||
|
|
||||||
typedef struct
|
struct _i386_insn
|
||||||
{
|
{
|
||||||
/* TM holds the template for the insn were currently assembling. */
|
/* TM holds the template for the insn were currently assembling. */
|
||||||
template tm;
|
template tm;
|
||||||
@ -85,9 +85,9 @@ typedef struct
|
|||||||
|
|
||||||
modrm_byte rm;
|
modrm_byte rm;
|
||||||
base_index_byte bi;
|
base_index_byte bi;
|
||||||
}
|
};
|
||||||
|
|
||||||
i386_insn;
|
typedef struct _i386_insn i386_insn;
|
||||||
|
|
||||||
/* This array holds the chars that always start a comment. If the
|
/* This array holds the chars that always start a comment. If the
|
||||||
pre-processor is disabled, these aren't very useful */
|
pre-processor is disabled, these aren't very useful */
|
||||||
@ -135,8 +135,7 @@ static char digit_chars[256];
|
|||||||
/* put here all non-digit non-letter charcters that may occur in an operand */
|
/* put here all non-digit non-letter charcters that may occur in an operand */
|
||||||
static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:";
|
static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:";
|
||||||
|
|
||||||
static char *ordinal_names[] =
|
static char *ordinal_names[] = {"first", "second", "third"}; /* for printfs */
|
||||||
{"first", "second", "third"}; /* for printfs */
|
|
||||||
|
|
||||||
/* md_assemble() always leaves the strings it's passed unaltered. To
|
/* md_assemble() always leaves the strings it's passed unaltered. To
|
||||||
effect this we maintain a stack of saved characters that we've smashed
|
effect this we maintain a stack of saved characters that we've smashed
|
||||||
@ -158,12 +157,11 @@ static reg_entry *ebp, *esp;
|
|||||||
|
|
||||||
static int this_operand; /* current operand we are working on */
|
static int this_operand; /* current operand we are working on */
|
||||||
|
|
||||||
/*
|
/* Interface to relax_segment.
|
||||||
Interface to relax_segment.
|
There are 2 relax states for 386 jump insns: one for conditional &
|
||||||
There are 2 relax states for 386 jump insns: one for conditional & one
|
one for unconditional jumps. This is because the these two types
|
||||||
for unconditional jumps. This is because the these two types of jumps
|
of jumps add different sizes to frags when we're figuring out what
|
||||||
add different sizes to frags when we're figuring out what sort of jump
|
sort of jump to choose to reach a given label. */
|
||||||
to choose to reach a given label. */
|
|
||||||
|
|
||||||
/* types */
|
/* types */
|
||||||
#define COND_JUMP 1 /* conditional jump */
|
#define COND_JUMP 1 /* conditional jump */
|
||||||
@ -174,6 +172,14 @@ static int this_operand; /* current operand we are working on */
|
|||||||
#define DWORD 2
|
#define DWORD 2
|
||||||
#define UNKNOWN_SIZE 3
|
#define UNKNOWN_SIZE 3
|
||||||
|
|
||||||
|
#ifndef INLINE
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define INLINE __inline__
|
||||||
|
#else
|
||||||
|
#define INLINE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size))
|
#define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size))
|
||||||
#define SIZE_FROM_RELAX_STATE(s) \
|
#define SIZE_FROM_RELAX_STATE(s) \
|
||||||
( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) )
|
( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) )
|
||||||
@ -191,23 +197,23 @@ const relax_typeS md_relax_table[] =
|
|||||||
{1, 1, 0, 0},
|
{1, 1, 0, 0},
|
||||||
{1, 1, 0, 0},
|
{1, 1, 0, 0},
|
||||||
|
|
||||||
/* For now we don't use word displacement jumps: they may be
|
/* For now we don't use word displacement jumps; they may be
|
||||||
untrustworthy. */
|
untrustworthy. */
|
||||||
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
|
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
|
||||||
/* word conditionals add 3 bytes to frag:
|
/* word conditionals add 3 bytes to frag:
|
||||||
2 opcode prefix; 1 displacement bytes */
|
2 opcode prefix; 1 displacement bytes */
|
||||||
{32767 + 2, -32768 + 2, 3, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
|
{32767 + 2, -32768 + 2, 3, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
|
||||||
/* dword conditionals adds 4 bytes to frag:
|
/* dword conditionals adds 4 bytes to frag:
|
||||||
1 opcode prefix; 3 displacement bytes */
|
1 opcode prefix; 3 displacement bytes */
|
||||||
{0, 0, 4, 0},
|
{0, 0, 4, 0},
|
||||||
{1, 1, 0, 0},
|
{1, 1, 0, 0},
|
||||||
|
|
||||||
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
|
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
|
||||||
/* word jmp adds 2 bytes to frag:
|
/* word jmp adds 2 bytes to frag:
|
||||||
1 opcode prefix; 1 displacement bytes */
|
1 opcode prefix; 1 displacement bytes */
|
||||||
{32767 + 2, -32768 + 2, 2, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
|
{32767 + 2, -32768 + 2, 2, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
|
||||||
/* dword jmp adds 3 bytes to frag:
|
/* dword jmp adds 3 bytes to frag:
|
||||||
0 opcode prefix; 3 displacement bytes */
|
0 opcode prefix; 3 displacement bytes */
|
||||||
{0, 0, 3, 0},
|
{0, 0, 3, 0},
|
||||||
{1, 1, 0, 0},
|
{1, 1, 0, 0},
|
||||||
|
|
||||||
@ -220,18 +226,16 @@ static reg_entry *parse_register PARAMS ((char *reg_string));
|
|||||||
static void s_bss PARAMS ((void));
|
static void s_bss PARAMS ((void));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned long
|
static INLINE unsigned long
|
||||||
mode_from_disp_size (t)
|
mode_from_disp_size (t)
|
||||||
unsigned long t;
|
unsigned long t;
|
||||||
{
|
{
|
||||||
return ((t & (Disp8))
|
return (t & Disp8) ? 1 : (t & Disp32) ? 2 : 0;
|
||||||
? 1
|
}
|
||||||
: ((t & (Disp32)) ? 2 : 0));
|
|
||||||
} /* mode_from_disp_size() */
|
|
||||||
|
|
||||||
/* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */
|
/* convert opcode suffix ('b' 'w' 'l' typically) into type specifier */
|
||||||
|
|
||||||
static unsigned long
|
static INLINE unsigned long
|
||||||
opcode_suffix_to_type (s)
|
opcode_suffix_to_type (s)
|
||||||
unsigned long s;
|
unsigned long s;
|
||||||
{
|
{
|
||||||
@ -240,32 +244,32 @@ opcode_suffix_to_type (s)
|
|||||||
? Word : DWord));
|
? Word : DWord));
|
||||||
} /* opcode_suffix_to_type() */
|
} /* opcode_suffix_to_type() */
|
||||||
|
|
||||||
static int
|
static INLINE int
|
||||||
fits_in_signed_byte (num)
|
fits_in_signed_byte (num)
|
||||||
long num;
|
long num;
|
||||||
{
|
{
|
||||||
return ((num >= -128) && (num <= 127));
|
return (num >= -128) && (num <= 127);
|
||||||
} /* fits_in_signed_byte() */
|
} /* fits_in_signed_byte() */
|
||||||
|
|
||||||
static int
|
static INLINE int
|
||||||
fits_in_unsigned_byte (num)
|
fits_in_unsigned_byte (num)
|
||||||
long num;
|
long num;
|
||||||
{
|
{
|
||||||
return ((num & 0xff) == num);
|
return (num & 0xff) == num;
|
||||||
} /* fits_in_unsigned_byte() */
|
} /* fits_in_unsigned_byte() */
|
||||||
|
|
||||||
static int
|
static INLINE int
|
||||||
fits_in_unsigned_word (num)
|
fits_in_unsigned_word (num)
|
||||||
long num;
|
long num;
|
||||||
{
|
{
|
||||||
return ((num & 0xffff) == num);
|
return (num & 0xffff) == num;
|
||||||
} /* fits_in_unsigned_word() */
|
} /* fits_in_unsigned_word() */
|
||||||
|
|
||||||
static int
|
static INLINE int
|
||||||
fits_in_signed_word (num)
|
fits_in_signed_word (num)
|
||||||
long num;
|
long num;
|
||||||
{
|
{
|
||||||
return ((-32768 <= num) && (num <= 32767));
|
return (-32768 <= num) && (num <= 32767);
|
||||||
} /* fits_in_signed_word() */
|
} /* fits_in_signed_word() */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -274,13 +278,13 @@ smallest_imm_type (num)
|
|||||||
{
|
{
|
||||||
return ((num == 1)
|
return ((num == 1)
|
||||||
? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
|
? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
|
||||||
: (fits_in_signed_byte (num)
|
: fits_in_signed_byte (num)
|
||||||
? (Imm8S | Imm8 | Imm16 | Imm32)
|
? (Imm8S | Imm8 | Imm16 | Imm32)
|
||||||
: (fits_in_unsigned_byte (num)
|
: fits_in_unsigned_byte (num)
|
||||||
? (Imm8 | Imm16 | Imm32)
|
? (Imm8 | Imm16 | Imm32)
|
||||||
: ((fits_in_signed_word (num) || fits_in_unsigned_word (num))
|
: (fits_in_signed_word (num) || fits_in_unsigned_word (num))
|
||||||
? (Imm16 | Imm32)
|
? (Imm16 | Imm32)
|
||||||
: (Imm32)))));
|
: (Imm32));
|
||||||
} /* smallest_imm_type() */
|
} /* smallest_imm_type() */
|
||||||
|
|
||||||
/* Ignore certain directives generated by gcc. This probably should
|
/* Ignore certain directives generated by gcc. This probably should
|
||||||
@ -297,7 +301,7 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
#ifndef I386COFF
|
#ifndef I386COFF
|
||||||
{"bss", s_bss, 0},
|
{"bss", s_bss, 0},
|
||||||
#endif
|
#endif
|
||||||
#if !defined (TE_LINUX) && !defined (TE_386BSD)
|
#ifndef OBJ_AOUT
|
||||||
{"align", s_align_bytes, 0},
|
{"align", s_align_bytes, 0},
|
||||||
#else
|
#else
|
||||||
{"align", s_align_ptwo, 0},
|
{"align", s_align_ptwo, 0},
|
||||||
@ -364,7 +368,8 @@ md_begin ()
|
|||||||
if (hash_err && *hash_err)
|
if (hash_err && *hash_err)
|
||||||
{
|
{
|
||||||
hash_error:
|
hash_error:
|
||||||
as_fatal ("Internal Error: Can't hash %s: %s", prev_name, hash_err);
|
as_fatal ("Internal Error: Can't hash %s: %s", prev_name,
|
||||||
|
hash_err);
|
||||||
}
|
}
|
||||||
prev_name = optab->name;
|
prev_name = optab->name;
|
||||||
core_optab = (templates *) xmalloc (sizeof (templates));
|
core_optab = (templates *) xmalloc (sizeof (templates));
|
||||||
@ -629,7 +634,7 @@ reloc (size, pcrel)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the guts of the machine-dependent assembler. LINE points to a
|
/* This is the guts of the machine-dependent assembler. LINE points to a
|
||||||
machine dependent instruction. This funciton is supposed to emit
|
machine dependent instruction. This function is supposed to emit
|
||||||
the frags/bytes it assembles to. */
|
the frags/bytes it assembles to. */
|
||||||
void
|
void
|
||||||
md_assemble (line)
|
md_assemble (line)
|
||||||
@ -1611,7 +1616,7 @@ i386_operand (operand_string)
|
|||||||
char *displacement_string_end = NULL;
|
char *displacement_string_end = NULL;
|
||||||
|
|
||||||
/* We check for an absolute prefix (differentiating,
|
/* We check for an absolute prefix (differentiating,
|
||||||
for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
|
for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
|
||||||
if (*op_string == ABSOLUTE_PREFIX)
|
if (*op_string == ABSOLUTE_PREFIX)
|
||||||
{
|
{
|
||||||
op_string++;
|
op_string++;
|
||||||
@ -1628,7 +1633,7 @@ i386_operand (operand_string)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Check for segment override, rather than segment register by
|
/* Check for segment override, rather than segment register by
|
||||||
searching for ':' after %<x>s where <x> = s, c, d, e, f, g. */
|
searching for ':' after %<x>s where <x> = s, c, d, e, f, g. */
|
||||||
if ((r->reg_type & (SReg2 | SReg3)) && op_string[3] == ':')
|
if ((r->reg_type & (SReg2 | SReg3)) && op_string[3] == ':')
|
||||||
{
|
{
|
||||||
switch (r->reg_num)
|
switch (r->reg_num)
|
||||||
@ -2156,7 +2161,7 @@ const int md_reloc_size = 8; /* Size of relocation record */
|
|||||||
void
|
void
|
||||||
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||||
char *ptr;
|
char *ptr;
|
||||||
long from_addr, to_addr;
|
valueT from_addr, to_addr;
|
||||||
fragS *frag;
|
fragS *frag;
|
||||||
symbolS *to_symbol;
|
symbolS *to_symbol;
|
||||||
{
|
{
|
||||||
@ -2170,7 +2175,7 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
|||||||
void
|
void
|
||||||
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||||
char *ptr;
|
char *ptr;
|
||||||
long from_addr, to_addr;
|
valueT from_addr, to_addr;
|
||||||
fragS *frag;
|
fragS *frag;
|
||||||
symbolS *to_symbol;
|
symbolS *to_symbol;
|
||||||
{
|
{
|
||||||
@ -2204,7 +2209,7 @@ md_parse_option (argP, cntP, vecP)
|
|||||||
void /* Knows about order of bytes in address. */
|
void /* Knows about order of bytes in address. */
|
||||||
md_number_to_chars (con, value, nbytes)
|
md_number_to_chars (con, value, nbytes)
|
||||||
char con[]; /* Return 'nbytes' of chars here. */
|
char con[]; /* Return 'nbytes' of chars here. */
|
||||||
long value; /* The value of the bits. */
|
valueT value; /* The value of the bits. */
|
||||||
int nbytes; /* Number of bytes in the output. */
|
int nbytes; /* Number of bytes in the output. */
|
||||||
{
|
{
|
||||||
register char *p = con;
|
register char *p = con;
|
||||||
@ -2303,8 +2308,7 @@ md_chars_to_number (con, nbytes)
|
|||||||
|
|
||||||
/* Turn the string pointed to by litP into a floating point constant of type
|
/* Turn the string pointed to by litP into a floating point constant of type
|
||||||
type, and emit the appropriate bytes. The number of LITTLENUMS emitted
|
type, and emit the appropriate bytes. The number of LITTLENUMS emitted
|
||||||
is stored in *sizeP . An error message is returned, or NULL on OK.
|
is stored in *sizeP . An error message is returned, or NULL on OK. */
|
||||||
*/
|
|
||||||
char *
|
char *
|
||||||
md_atof (type, litP, sizeP)
|
md_atof (type, litP, sizeP)
|
||||||
char type;
|
char type;
|
||||||
@ -2342,8 +2346,8 @@ md_atof (type, litP, sizeP)
|
|||||||
input_line_pointer = t;
|
input_line_pointer = t;
|
||||||
|
|
||||||
*sizeP = prec * sizeof (LITTLENUM_TYPE);
|
*sizeP = prec * sizeof (LITTLENUM_TYPE);
|
||||||
/* this loops outputs the LITTLENUMs in REVERSE order; in accord with
|
/* This loops outputs the LITTLENUMs in REVERSE order; in accord with
|
||||||
the bigendian 386 */
|
the bigendian 386. */
|
||||||
for (wordP = words + prec - 1; prec--;)
|
for (wordP = words + prec - 1; prec--;)
|
||||||
{
|
{
|
||||||
md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
|
md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
|
||||||
@ -2367,7 +2371,8 @@ output_invalid (c)
|
|||||||
|
|
||||||
static reg_entry *
|
static reg_entry *
|
||||||
parse_register (reg_string)
|
parse_register (reg_string)
|
||||||
char *reg_string; /* reg_string starts *before* REGISTER_PREFIX */
|
/* reg_string starts *before* REGISTER_PREFIX */
|
||||||
|
char *reg_string;
|
||||||
{
|
{
|
||||||
register char *s = reg_string;
|
register char *s = reg_string;
|
||||||
register char *p;
|
register char *p;
|
||||||
@ -2407,10 +2412,10 @@ md_operand (expressionP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Round up a section size to the appropriate boundary. */
|
/* Round up a section size to the appropriate boundary. */
|
||||||
long
|
valueT
|
||||||
md_section_align (segment, size)
|
md_section_align (segment, size)
|
||||||
segT segment;
|
segT segment;
|
||||||
long size;
|
valueT size;
|
||||||
{
|
{
|
||||||
return size; /* Byte alignment is fine */
|
return size; /* Byte alignment is fine */
|
||||||
}
|
}
|
||||||
@ -2467,6 +2472,8 @@ tc_gen_reloc (section, fixp)
|
|||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
#undef MAP
|
||||||
|
#undef F
|
||||||
|
|
||||||
reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
|
reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
|
||||||
assert (reloc != 0);
|
assert (reloc != 0);
|
||||||
@ -2497,8 +2504,7 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
|
|||||||
* Out: GNU LD relocation length code: 0, 1, or 2.
|
* Out: GNU LD relocation length code: 0, 1, or 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned char nbytes_r_length[] =
|
static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
|
||||||
{42, 0, 1, 42, 2};
|
|
||||||
long r_symbolnum;
|
long r_symbolnum;
|
||||||
|
|
||||||
know (fixP->fx_addsy != NULL);
|
know (fixP->fx_addsy != NULL);
|
||||||
|
Reference in New Issue
Block a user