Tidy jump handling code and comments.

This commit is contained in:
Alan Modra
1999-09-13 03:44:49 +00:00
parent a20a10a650
commit a217f122fa

View File

@ -236,8 +236,8 @@ static char stackop_size = '\0'; /* Used in 16 bit gcc mode to add an l
/* 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 for unconditional jumps. This is because the these two types one for unconditional jumps. This is because these two types of
of jumps add different sizes to frags when we're figuring out what jumps add different sizes to frags when we're figuring out what
sort of jump to choose to reach a given label. */ sort of jump to choose to reach a given label. */
/* types */ /* types */
@ -2092,23 +2092,33 @@ md_assemble (line)
/* Output jumps. */ /* Output jumps. */
if (i.tm.opcode_modifier & Jump) if (i.tm.opcode_modifier & Jump)
{ {
long n = (long) i.disps[0]->X_add_number; int size;
int prefix = (i.prefix[DATA_PREFIX] != 0); int code16;
int code16 = 0; int prefix;
if (prefix) code16 = 0;
{
i.prefixes -= 1;
code16 = CODE16;
}
if (flag_16bit_code) if (flag_16bit_code)
code16 ^= CODE16; code16 = CODE16;
if (!intel_syntax && (i.prefixes != 0)) prefix = 0;
if (i.prefix[DATA_PREFIX])
{
prefix = 1;
i.prefixes -= 1;
code16 ^= CODE16;
}
size = 4;
if (code16)
size = 2;
if (i.prefixes != 0 && !intel_syntax)
as_warn (_("skipping prefixes on this instruction")); as_warn (_("skipping prefixes on this instruction"));
if (i.disps[0]->X_op == O_constant) if (i.disps[0]->X_op == O_constant)
{ {
long n = (long) i.disps[0]->X_add_number;
if (fits_in_signed_byte (n)) if (fits_in_signed_byte (n))
{ {
insn_size += 2; insn_size += 2;
@ -2122,7 +2132,6 @@ md_assemble (line)
because text segments are limited to 64K anyway; because text segments are limited to 64K anyway;
Use 32-bit jumps for 32-bit code, because they're faster, Use 32-bit jumps for 32-bit code, because they're faster,
and a 16-bit jump will clear the top 16 bits of %eip. */ and a 16-bit jump will clear the top 16 bits of %eip. */
int jmp_size = code16 ? 2 : 4;
if (code16 && !fits_in_signed_word (n)) if (code16 && !fits_in_signed_word (n))
{ {
as_bad (_("16-bit jump out of range")); as_bad (_("16-bit jump out of range"));
@ -2132,56 +2141,60 @@ md_assemble (line)
if (i.tm.base_opcode == JUMP_PC_RELATIVE) if (i.tm.base_opcode == JUMP_PC_RELATIVE)
{ /* pace */ { /* pace */
/* unconditional jump */ /* unconditional jump */
insn_size += prefix + 1 + jmp_size; insn_size += prefix + 1 + size;
p = frag_more (prefix + 1 + jmp_size); p = frag_more (prefix + 1 + size);
if (prefix) if (prefix)
*p++ = DATA_PREFIX_OPCODE; *p++ = DATA_PREFIX_OPCODE;
*p++ = (char) 0xe9; *p++ = (char) 0xe9;
md_number_to_chars (p, (valueT) n, jmp_size); md_number_to_chars (p, (valueT) n, size);
} }
else else
{ {
/* conditional jump */ /* conditional jump */
insn_size += prefix + 2 + jmp_size; insn_size += prefix + 2 + size;
p = frag_more (prefix + 2 + jmp_size); p = frag_more (prefix + 2 + size);
if (prefix) if (prefix)
*p++ = DATA_PREFIX_OPCODE; *p++ = DATA_PREFIX_OPCODE;
*p++ = TWO_BYTE_OPCODE_ESCAPE; *p++ = TWO_BYTE_OPCODE_ESCAPE;
*p++ = i.tm.base_opcode + 0x10; *p++ = i.tm.base_opcode + 0x10;
md_number_to_chars (p, (valueT) n, jmp_size); md_number_to_chars (p, (valueT) n, size);
} }
} }
} }
else else
{ {
int size = code16 ? 2 : 4; /* It's a symbol; End frag & setup for relax.
Make sure there is enough room in this frag for the largest
/* It's a symbol; end frag & setup for relax. instruction we may generate in md_convert_frag. This is 2
Make sure there are more than 6 chars left in the current frag; bytes for the opcode and room for the prefix and largest
if not we'll have to start a new one. */ displacement. */
frag_grow (prefix + 1 + 2 + size); frag_grow (prefix + 2 + size);
insn_size += 1 + prefix; insn_size += prefix + 1;
p = frag_more (1 + prefix); /* Prefix and 1 opcode byte go in fr_fix. */
p = frag_more (prefix + 1);
if (prefix) if (prefix)
*p++ = DATA_PREFIX_OPCODE; *p++ = DATA_PREFIX_OPCODE;
*p = i.tm.base_opcode; *p = i.tm.base_opcode;
/* 1 possible extra opcode + displacement go in fr_var */
frag_var (rs_machine_dependent, frag_var (rs_machine_dependent,
prefix + 2 + size, /* 2 opcode/prefix + displacement */ 1 + size,
1, 1,
((unsigned char) *p == JUMP_PC_RELATIVE ((unsigned char) *p == JUMP_PC_RELATIVE
? ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL) | code16 ? ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL) | code16
: ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16), : ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16),
i.disps[0]->X_add_symbol, i.disps[0]->X_add_symbol,
(offsetT) n, p); i.disps[0]->X_add_number,
p);
} }
} }
else if (i.tm.opcode_modifier & (JumpByte | JumpDword)) else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
{ {
int size = (i.tm.opcode_modifier & JumpByte) ? 1 : 4; int size;
long n = (long) i.disps[0]->X_add_number;
if (size == 1) /* then this is a loop or jecxz type instruction */ if (i.tm.opcode_modifier & JumpByte)
{ {
/* This is a loop or jecxz type instruction. */
size = 1;
if (i.prefix[ADDR_PREFIX]) if (i.prefix[ADDR_PREFIX])
{ {
insn_size += 1; insn_size += 1;
@ -2191,23 +2204,26 @@ md_assemble (line)
} }
else else
{ {
int code16 = 0; int code16;
code16 = 0;
if (flag_16bit_code)
code16 = CODE16;
if (i.prefix[DATA_PREFIX]) if (i.prefix[DATA_PREFIX])
{ {
insn_size += 1; insn_size += 1;
FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE); FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
i.prefixes -= 1; i.prefixes -= 1;
code16 = CODE16; code16 ^= CODE16;
} }
if (flag_16bit_code)
code16 ^= CODE16;
size = 4;
if (code16) if (code16)
size = 2; size = 2;
} }
if (!intel_syntax && (i.prefixes != 0)) if (i.prefixes != 0 && !intel_syntax)
as_warn (_("skipping prefixes on this instruction")); as_warn (_("skipping prefixes on this instruction"));
if (fits_in_unsigned_byte (i.tm.base_opcode)) if (fits_in_unsigned_byte (i.tm.base_opcode))
@ -2217,7 +2233,8 @@ md_assemble (line)
} }
else else
{ {
insn_size += 2 + size; /* opcode can be at most two bytes */ /* opcode can be at most two bytes */
insn_size += 2 + size;
p = frag_more (2 + size); p = frag_more (2 + size);
*p++ = (i.tm.base_opcode >> 8) & 0xff; *p++ = (i.tm.base_opcode >> 8) & 0xff;
} }
@ -2225,6 +2242,8 @@ md_assemble (line)
if (i.disps[0]->X_op == O_constant) if (i.disps[0]->X_op == O_constant)
{ {
long n = (long) i.disps[0]->X_add_number;
if (size == 1 && !fits_in_signed_byte (n)) if (size == 1 && !fits_in_signed_byte (n))
{ {
as_bad (_("`%s' only takes byte displacement; %ld shortened to %d"), as_bad (_("`%s' only takes byte displacement; %ld shortened to %d"),
@ -2248,16 +2267,20 @@ md_assemble (line)
{ {
int size; int size;
int reloc_type; int reloc_type;
int prefix = i.prefix[DATA_PREFIX] != 0; int prefix;
int code16 = 0; int code16;
if (prefix) code16 = 0;
{
code16 = CODE16;
i.prefixes -= 1;
}
if (flag_16bit_code) if (flag_16bit_code)
code16 ^= CODE16; code16 = CODE16;
prefix = 0;
if (i.prefix[DATA_PREFIX])
{
prefix = 1;
i.prefixes -= 1;
code16 ^= CODE16;
}
size = 4; size = 4;
reloc_type = BFD_RELOC_32; reloc_type = BFD_RELOC_32;
@ -2267,7 +2290,7 @@ md_assemble (line)
reloc_type = BFD_RELOC_16; reloc_type = BFD_RELOC_16;
} }
if (!intel_syntax && (i.prefixes != 0)) if (i.prefixes != 0 && !intel_syntax)
as_warn (_("skipping prefixes on this instruction")); as_warn (_("skipping prefixes on this instruction"));
insn_size += prefix + 1 + 2 + size; /* 1 opcode; 2 segment; offset */ insn_size += prefix + 1 + 2 + size; /* 1 opcode; 2 segment; offset */
@ -4235,7 +4258,6 @@ i386_target_format ()
#endif /* OBJ_MAYBE_ELF */ #endif /* OBJ_MAYBE_ELF */
#endif /* BFD_ASSEMBLER */ #endif /* BFD_ASSEMBLER */
/* ARGSUSED */
symbolS * symbolS *
md_undefined_symbol (name) md_undefined_symbol (name)
char *name; char *name;