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