forked from Imagelibrary/binutils-gdb
Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org)
* config/tc-i386.c: (md_begin): Do not zero static arrays. Don't call strchr for each character to see if it is a special char, instead add a second loop over special_chars. Set alignment of text, data and bss sections to 4. (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be used again. (reloc): Don't return 8 and 16 bit non-PC relative relocations on ELF, since the ELF object format does not have these type of relocations. Change the abort into as as_bad and return BFD_RELOC_NONE to silence compiler warnings. (md_assemble): Keep track of the instruction size. Allow white space between the $ and the constant for compatibility with older gases and other assemblers. (i386_operand): Skip spaces between $ and expression. (tc_gen_reloc): Don't allow anything but 32 bit relocations on ELF. Convert abort into an as_bad and assert into as_fatal.
This commit is contained in:
@@ -1,3 +1,22 @@
|
||||
Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org)
|
||||
|
||||
* config/tc-i386.c: (md_begin): Do not zero static arrays. Don't
|
||||
call strchr for each character to see if it is a special char,
|
||||
instead add a second loop over special_chars. Set alignment
|
||||
of text, data and bss sections to 4.
|
||||
(pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be
|
||||
used again.
|
||||
(reloc): Don't return 8 and 16 bit non-PC relative relocations on
|
||||
ELF, since the ELF object format does not have these type of
|
||||
relocations. Change the abort into as as_bad and return
|
||||
BFD_RELOC_NONE to silence compiler warnings.
|
||||
(md_assemble): Keep track of the instruction size. Allow white
|
||||
space between the $ and the constant for compatibility with older
|
||||
gases and other assemblers.
|
||||
(i386_operand): Skip spaces between $ and expression.
|
||||
(tc_gen_reloc): Don't allow anything but 32 bit relocations on
|
||||
ELF. Convert abort into an as_bad and assert into as_fatal.
|
||||
|
||||
Wed Oct 13 16:50:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
|
||||
|
||||
* config/obj-coffbfd.c (fixup_segment) [DIFF_EXPR_OK]: If
|
||||
|
||||
@@ -106,7 +106,7 @@ const char comment_chars[] = "#";
|
||||
/* Also note that comments started like this one will always work if
|
||||
'/' isn't otherwise defined. */
|
||||
#if defined (TE_I386AIX) || defined (OBJ_ELF)
|
||||
const char line_comment_chars[];
|
||||
const char line_comment_chars[] = "";
|
||||
#else
|
||||
const char line_comment_chars[] = "/";
|
||||
#endif
|
||||
@@ -184,7 +184,8 @@ static int this_operand; /* current operand we are working on */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size))
|
||||
#define ENCODE_RELAX_STATE(type,size) \
|
||||
((relax_substateT)((type<<2) | (size)))
|
||||
#define SIZE_FROM_RELAX_STATE(s) \
|
||||
( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) )
|
||||
|
||||
@@ -227,7 +228,7 @@ static char *output_invalid PARAMS ((int c));
|
||||
static int i386_operand PARAMS ((char *operand_string));
|
||||
static reg_entry *parse_register PARAMS ((char *reg_string));
|
||||
#ifndef I386COFF
|
||||
static void s_bss PARAMS ((void));
|
||||
static void s_bss PARAMS ((int));
|
||||
#endif
|
||||
|
||||
static INLINE unsigned long
|
||||
@@ -237,6 +238,8 @@ mode_from_disp_size (t)
|
||||
return (t & Disp8) ? 1 : (t & Disp32) ? 2 : 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Not used. */
|
||||
/* convert opcode suffix ('b' 'w' 'l' typically) into type specifier */
|
||||
|
||||
static INLINE unsigned long
|
||||
@@ -247,6 +250,7 @@ opcode_suffix_to_type (s)
|
||||
? Byte : (s == WORD_OPCODE_SUFFIX
|
||||
? Word : DWord));
|
||||
} /* opcode_suffix_to_type() */
|
||||
#endif
|
||||
|
||||
static INLINE int
|
||||
fits_in_signed_byte (num)
|
||||
@@ -291,15 +295,6 @@ smallest_imm_type (num)
|
||||
: (Imm32));
|
||||
} /* smallest_imm_type() */
|
||||
|
||||
/* Ignore certain directives generated by gcc. This probably should
|
||||
not be here. */
|
||||
void
|
||||
dummy ()
|
||||
{
|
||||
while (*input_line_pointer && *input_line_pointer != '\n')
|
||||
input_line_pointer++;
|
||||
}
|
||||
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
#ifndef I386COFF
|
||||
@@ -339,7 +334,7 @@ static struct hash_control *prefix_hash = (struct hash_control *) 0;
|
||||
void
|
||||
md_begin ()
|
||||
{
|
||||
char *hash_err;
|
||||
const char *hash_err;
|
||||
|
||||
obstack_begin (&o, 4096);
|
||||
|
||||
@@ -372,7 +367,7 @@ md_begin ()
|
||||
core_optab->end = (template *) obstack_next_free (&o);
|
||||
core_optab->start = (template *) obstack_finish (&o);
|
||||
hash_err = hash_insert (op_hash, prev_name, (char *) core_optab);
|
||||
if (hash_err && *hash_err)
|
||||
if (hash_err)
|
||||
{
|
||||
hash_error:
|
||||
as_fatal ("Internal Error: Can't hash %s: %s", prev_name,
|
||||
@@ -392,8 +387,8 @@ md_begin ()
|
||||
|
||||
for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++)
|
||||
{
|
||||
hash_err = hash_insert (reg_hash, regtab->reg_name, regtab);
|
||||
if (hash_err && *hash_err)
|
||||
hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
|
||||
if (hash_err)
|
||||
goto hash_error;
|
||||
}
|
||||
}
|
||||
@@ -409,21 +404,17 @@ md_begin ()
|
||||
for (prefixtab = i386_prefixtab;
|
||||
prefixtab < i386_prefixtab_end; prefixtab++)
|
||||
{
|
||||
hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab);
|
||||
if (hash_err && *hash_err)
|
||||
hash_err = hash_insert (prefix_hash, prefixtab->prefix_name,
|
||||
(PTR) prefixtab);
|
||||
if (hash_err)
|
||||
goto hash_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in lexical tables: opcode_chars, operand_chars, space_chars */
|
||||
{
|
||||
register unsigned int c;
|
||||
|
||||
memset (opcode_chars, '\0', sizeof (opcode_chars));
|
||||
memset (operand_chars, '\0', sizeof (operand_chars));
|
||||
memset (space_chars, '\0', sizeof (space_chars));
|
||||
memset (identifier_chars, '\0', sizeof (identifier_chars));
|
||||
memset (digit_chars, '\0', sizeof (digit_chars));
|
||||
register int c;
|
||||
register char *p;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
@@ -448,8 +439,6 @@ md_begin ()
|
||||
|
||||
if (isupper (c) || islower (c) || isdigit (c))
|
||||
operand_chars[c] = c;
|
||||
else if (c && strchr (operand_special_chars, c))
|
||||
operand_chars[c] = c;
|
||||
|
||||
if (isdigit (c) || c == '-')
|
||||
digit_chars[c] = c;
|
||||
@@ -460,7 +449,16 @@ md_begin ()
|
||||
if (c == ' ' || c == '\t')
|
||||
space_chars[c] = c;
|
||||
}
|
||||
|
||||
for (p = operand_special_chars; *p != '\0'; p++)
|
||||
operand_chars[(unsigned char) *p] = *p;
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
record_alignment (text_section, 2);
|
||||
record_alignment (data_section, 2);
|
||||
record_alignment (bss_section, 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -472,7 +470,11 @@ md_end ()
|
||||
#ifdef DEBUG386
|
||||
|
||||
/* debugging routines for md_assemble */
|
||||
/* static void pi (), pte (), pt (), pe (), ps (); */
|
||||
static void pi PARAMS ((char *, i386_insn *));
|
||||
static void pte PARAMS ((template *));
|
||||
static void pt PARAMS ((unsigned int));
|
||||
static void pe PARAMS ((expressionS *));
|
||||
static void ps PARAMS ((symbolS *));
|
||||
|
||||
static void
|
||||
pi (line, x)
|
||||
@@ -625,18 +627,25 @@ reloc (size, pcrel)
|
||||
if (pcrel)
|
||||
switch (size)
|
||||
{
|
||||
#ifndef OBJ_ELF
|
||||
case 1: return BFD_RELOC_8_PCREL;
|
||||
case 2: return BFD_RELOC_16_PCREL;
|
||||
#endif
|
||||
case 4: return BFD_RELOC_32_PCREL;
|
||||
}
|
||||
else
|
||||
switch (size)
|
||||
{
|
||||
#ifndef OBJ_ELF
|
||||
case 1: return BFD_RELOC_8;
|
||||
case 2: return BFD_RELOC_16;
|
||||
#endif
|
||||
case 4: return BFD_RELOC_32;
|
||||
}
|
||||
abort ();
|
||||
|
||||
as_bad ("Can not do %d byte %srelocation", size,
|
||||
pcrel ? "pc-relative" : "");
|
||||
return BFD_RELOC_NONE;
|
||||
}
|
||||
#else
|
||||
#define reloc(SIZE,PCREL) 0
|
||||
@@ -651,9 +660,12 @@ void
|
||||
md_assemble (line)
|
||||
char *line;
|
||||
{
|
||||
/* Holds temlate once we've found it. */
|
||||
/* Holds template once we've found it. */
|
||||
register template *t;
|
||||
|
||||
/* Count the size of the instruction generated. */
|
||||
int insn_size = 0;
|
||||
|
||||
/* Possible templates for current insn */
|
||||
templates *current_templates = (templates *) 0;
|
||||
|
||||
@@ -806,7 +818,7 @@ md_assemble (line)
|
||||
else
|
||||
break; /* we are done */
|
||||
}
|
||||
else if (!is_operand_char (*l))
|
||||
else if (!is_operand_char (*l) && !is_space_char (*l))
|
||||
{
|
||||
as_bad ("invalid character %s in %s operand",
|
||||
output_invalid (*l),
|
||||
@@ -987,13 +999,13 @@ md_assemble (line)
|
||||
/* We take i.suffix from the LAST register operand specified. This
|
||||
assumes that the last register operands is the destination register
|
||||
operand. */
|
||||
int o;
|
||||
for (o = 0; o < MAX_OPERANDS; o++)
|
||||
if (i.types[o] & Reg)
|
||||
int op;
|
||||
for (op = 0; op < MAX_OPERANDS; op++)
|
||||
if (i.types[op] & Reg)
|
||||
{
|
||||
i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX :
|
||||
(i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX :
|
||||
DWORD_OPCODE_SUFFIX;
|
||||
i.suffix = ((i.types[op] == Reg8) ? BYTE_OPCODE_SUFFIX :
|
||||
(i.types[op] == Reg16) ? WORD_OPCODE_SUFFIX :
|
||||
DWORD_OPCODE_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,9 +1125,9 @@ md_assemble (line)
|
||||
if (t->opcode_modifier & ShortForm)
|
||||
{
|
||||
/* The register or float register operand is in operand 0 or 1. */
|
||||
unsigned int o = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
|
||||
unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
|
||||
/* Register goes in low 3 bits of opcode. */
|
||||
t->base_opcode |= i.regs[o]->reg_num;
|
||||
t->base_opcode |= i.regs[op]->reg_num;
|
||||
}
|
||||
else if (t->opcode_modifier & ShortFormW)
|
||||
{
|
||||
@@ -1178,7 +1190,7 @@ md_assemble (line)
|
||||
if (i.mem_operands)
|
||||
{
|
||||
unsigned int fake_zero_displacement = 0;
|
||||
unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
|
||||
unsigned int op = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
|
||||
|
||||
/* Encode memory operand into modrm byte and base index
|
||||
byte. */
|
||||
@@ -1188,25 +1200,25 @@ md_assemble (line)
|
||||
/* <disp>(%esp) becomes two byte modrm with no index
|
||||
register. */
|
||||
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
||||
i.rm.mode = mode_from_disp_size (i.types[o]);
|
||||
i.rm.mode = mode_from_disp_size (i.types[op]);
|
||||
i.bi.base = ESP_REG_NUM;
|
||||
i.bi.index = NO_INDEX_REGISTER;
|
||||
i.bi.scale = 0; /* Must be zero! */
|
||||
}
|
||||
else if (i.base_reg == ebp && !i.index_reg)
|
||||
{
|
||||
if (!(i.types[o] & Disp))
|
||||
if (!(i.types[op] & Disp))
|
||||
{
|
||||
/* Must fake a zero byte displacement. There is
|
||||
no direct way to code '(%ebp)' directly. */
|
||||
fake_zero_displacement = 1;
|
||||
/* fake_zero_displacement code does not set this. */
|
||||
i.types[o] |= Disp8;
|
||||
i.types[op] |= Disp8;
|
||||
}
|
||||
i.rm.mode = mode_from_disp_size (i.types[o]);
|
||||
i.rm.mode = mode_from_disp_size (i.types[op]);
|
||||
i.rm.regmem = EBP_REG_NUM;
|
||||
}
|
||||
else if (!i.base_reg && (i.types[o] & BaseIndex))
|
||||
else if (!i.base_reg && (i.types[op] & BaseIndex))
|
||||
{
|
||||
/* There are three cases here.
|
||||
Case 1: '<32bit disp>(,1)' -- indirect absolute.
|
||||
@@ -1217,8 +1229,8 @@ md_assemble (line)
|
||||
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
||||
i.rm.mode = 0; /* 32bit mode */
|
||||
i.bi.base = NO_BASE_REGISTER;
|
||||
i.types[o] &= ~Disp;
|
||||
i.types[o] |= Disp32; /* Must be 32bit! */
|
||||
i.types[op] &= ~Disp;
|
||||
i.types[op] |= Disp32; /* Must be 32bit! */
|
||||
if (i.index_reg)
|
||||
{ /* case 2 or case 3 */
|
||||
i.bi.index = i.index_reg->reg_num;
|
||||
@@ -1237,14 +1249,14 @@ md_assemble (line)
|
||||
/* Operand is just <32bit disp> */
|
||||
i.rm.regmem = EBP_REG_NUM;
|
||||
i.rm.mode = 0;
|
||||
i.types[o] &= ~Disp;
|
||||
i.types[o] |= Disp32;
|
||||
i.types[op] &= ~Disp;
|
||||
i.types[op] |= Disp32;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's not a special case; rev'em up. */
|
||||
i.rm.regmem = i.base_reg->reg_num;
|
||||
i.rm.mode = mode_from_disp_size (i.types[o]);
|
||||
i.rm.mode = mode_from_disp_size (i.types[op]);
|
||||
if (i.index_reg)
|
||||
{
|
||||
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
||||
@@ -1254,17 +1266,17 @@ md_assemble (line)
|
||||
if (i.base_reg == ebp && i.disp_operands == 0)
|
||||
{ /* pace */
|
||||
fake_zero_displacement = 1;
|
||||
i.types[o] |= Disp8;
|
||||
i.rm.mode = mode_from_disp_size (i.types[o]);
|
||||
i.types[op] |= Disp8;
|
||||
i.rm.mode = mode_from_disp_size (i.types[op]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fake_zero_displacement)
|
||||
{
|
||||
/* Fakes a zero displacement assuming that i.types[o]
|
||||
/* Fakes a zero displacement assuming that i.types[op]
|
||||
holds the correct displacement size. */
|
||||
exp = &disp_expressions[i.disp_operands++];
|
||||
i.disps[o] = exp;
|
||||
i.disps[op] = exp;
|
||||
exp->X_op = O_constant;
|
||||
exp->X_add_number = 0;
|
||||
exp->X_add_symbol = (symbolS *) 0;
|
||||
@@ -1308,15 +1320,15 @@ md_assemble (line)
|
||||
registers are coded into the i.rm.reg field. */
|
||||
if (i.reg_operands)
|
||||
{
|
||||
unsigned int o =
|
||||
unsigned int op =
|
||||
(i.types[0] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 0 :
|
||||
(i.types[1] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 1 : 2;
|
||||
/* If there is an extension opcode to put here, the
|
||||
register number must be put into the regmem field. */
|
||||
if (t->extension_opcode != None)
|
||||
i.rm.regmem = i.regs[o]->reg_num;
|
||||
i.rm.regmem = i.regs[op]->reg_num;
|
||||
else
|
||||
i.rm.reg = i.regs[o]->reg_num;
|
||||
i.rm.reg = i.regs[op]->reg_num;
|
||||
|
||||
/* Now, if no memory operand has set i.rm.mode = 0, 1, 2
|
||||
we must set it to 3 to indicate this is a register
|
||||
@@ -1347,13 +1359,14 @@ md_assemble (line)
|
||||
/* Output jumps. */
|
||||
if (t->opcode_modifier & Jump)
|
||||
{
|
||||
int n = i.disps[0]->X_add_number;
|
||||
unsigned long n = i.disps[0]->X_add_number;
|
||||
|
||||
if (i.disps[0]->X_op == O_constant)
|
||||
{
|
||||
if (fits_in_signed_byte (n))
|
||||
{
|
||||
p = frag_more (2);
|
||||
insn_size += 2;
|
||||
p[0] = t->base_opcode;
|
||||
p[1] = n;
|
||||
}
|
||||
@@ -1361,9 +1374,10 @@ md_assemble (line)
|
||||
else if (fits_in_signed_word (n))
|
||||
{
|
||||
p = frag_more (4);
|
||||
insn_size += 4;
|
||||
p[0] = WORD_PREFIX_OPCODE;
|
||||
p[1] = t->base_opcode;
|
||||
md_number_to_chars (&p[2], n, 2);
|
||||
md_number_to_chars (&p[2], (valueT) n, 2);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
@@ -1372,16 +1386,18 @@ md_assemble (line)
|
||||
{ /* pace */
|
||||
/* unconditional jump */
|
||||
p = frag_more (5);
|
||||
insn_size += 5;
|
||||
p[0] = (char) 0xe9;
|
||||
md_number_to_chars (&p[1], n, 4);
|
||||
md_number_to_chars (&p[1], (valueT) n, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* conditional jump */
|
||||
p = frag_more (6);
|
||||
insn_size += 6;
|
||||
p[0] = TWO_BYTE_OPCODE_ESCAPE;
|
||||
p[1] = t->base_opcode + 0x10;
|
||||
md_number_to_chars (&p[2], n, 4);
|
||||
md_number_to_chars (&p[2], (valueT) n, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1396,6 +1412,7 @@ md_assemble (line)
|
||||
frag_new (0);
|
||||
}
|
||||
p = frag_more (1);
|
||||
insn_size += 1;
|
||||
p[0] = t->base_opcode;
|
||||
frag_var (rs_machine_dependent,
|
||||
6, /* 2 opcode/prefix + 4 displacement */
|
||||
@@ -1404,33 +1421,36 @@ md_assemble (line)
|
||||
? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE)
|
||||
: ENCODE_RELAX_STATE (COND_JUMP, BYTE)),
|
||||
i.disps[0]->X_add_symbol,
|
||||
n, p);
|
||||
(long) n, p);
|
||||
}
|
||||
}
|
||||
else if (t->opcode_modifier & (JumpByte | JumpDword))
|
||||
{
|
||||
int size = (t->opcode_modifier & JumpByte) ? 1 : 4;
|
||||
int n = i.disps[0]->X_add_number;
|
||||
unsigned long n = i.disps[0]->X_add_number;
|
||||
|
||||
if (fits_in_unsigned_byte (t->base_opcode))
|
||||
{
|
||||
FRAG_APPEND_1_CHAR (t->base_opcode);
|
||||
insn_size += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = frag_more (2); /* opcode can be at most two bytes */
|
||||
insn_size += 2;
|
||||
/* put out high byte first: can't use md_number_to_chars! */
|
||||
*p++ = (t->base_opcode >> 8) & 0xff;
|
||||
*p = t->base_opcode & 0xff;
|
||||
}
|
||||
|
||||
p = frag_more (size);
|
||||
insn_size += size;
|
||||
if (i.disps[0]->X_op == O_constant)
|
||||
{
|
||||
md_number_to_chars (p, n, size);
|
||||
md_number_to_chars (p, (valueT) n, size);
|
||||
if (size == 1 && !fits_in_signed_byte (n))
|
||||
{
|
||||
as_bad ("loop/jecx only takes byte displacement; %d shortened to %d",
|
||||
as_bad ("loop/jecx only takes byte displacement; %lu shortened to %d",
|
||||
n, *p);
|
||||
}
|
||||
}
|
||||
@@ -1443,15 +1463,16 @@ md_assemble (line)
|
||||
else if (t->opcode_modifier & JumpInterSegment)
|
||||
{
|
||||
p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */
|
||||
insn_size += 1 + 2 + 4;
|
||||
p[0] = t->base_opcode;
|
||||
if (i.imms[1]->X_op == O_constant)
|
||||
md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4);
|
||||
md_number_to_chars (p + 1, (valueT) i.imms[1]->X_add_number, 4);
|
||||
else
|
||||
fix_new_exp (frag_now, p + 1 - frag_now->fr_literal, 4,
|
||||
i.imms[1], 0, BFD_RELOC_32);
|
||||
if (i.imms[0]->X_op != O_constant)
|
||||
as_bad ("can't handle non absolute segment in long call/jmp");
|
||||
md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2);
|
||||
md_number_to_chars (p + 5, (valueT) i.imms[0]->X_add_number, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1462,17 +1483,20 @@ md_assemble (line)
|
||||
for (q = i.prefix; q < i.prefix + i.prefixes; q++)
|
||||
{
|
||||
p = frag_more (1);
|
||||
md_number_to_chars (p, (unsigned int) *q, 1);
|
||||
insn_size += 1;
|
||||
md_number_to_chars (p, (valueT) *q, 1);
|
||||
}
|
||||
|
||||
/* Now the opcode; be careful about word order here! */
|
||||
if (fits_in_unsigned_byte (t->base_opcode))
|
||||
{
|
||||
FRAG_APPEND_1_CHAR (t->base_opcode);
|
||||
insn_size += 1;
|
||||
}
|
||||
else if (fits_in_unsigned_word (t->base_opcode))
|
||||
{
|
||||
p = frag_more (2);
|
||||
insn_size += 2;
|
||||
/* put out high byte first: can't use md_number_to_chars! */
|
||||
*p++ = (t->base_opcode >> 8) & 0xff;
|
||||
*p = t->base_opcode & 0xff;
|
||||
@@ -1482,10 +1506,14 @@ md_assemble (line)
|
||||
if (t->base_opcode & 0xff000000)
|
||||
{
|
||||
p = frag_more (4);
|
||||
insn_size += 4;
|
||||
*p++ = (t->base_opcode >> 24) & 0xff;
|
||||
}
|
||||
else
|
||||
p = frag_more (3);
|
||||
{
|
||||
p = frag_more (3);
|
||||
insn_size += 3;
|
||||
}
|
||||
*p++ = (t->base_opcode >> 16) & 0xff;
|
||||
*p++ = (t->base_opcode >> 8) & 0xff;
|
||||
*p = (t->base_opcode) & 0xff;
|
||||
@@ -1495,15 +1523,24 @@ md_assemble (line)
|
||||
if (t->opcode_modifier & Modrm)
|
||||
{
|
||||
p = frag_more (1);
|
||||
insn_size += 1;
|
||||
/* md_number_to_chars (p, i.rm, 1); */
|
||||
md_number_to_chars (p, (i.rm.regmem << 0 | i.rm.reg << 3 | i.rm.mode << 6), 1);
|
||||
md_number_to_chars (p,
|
||||
(valueT) (i.rm.regmem << 0
|
||||
| i.rm.reg << 3
|
||||
| i.rm.mode << 6),
|
||||
1);
|
||||
/* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode)
|
||||
==> need second modrm byte. */
|
||||
if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3)
|
||||
{
|
||||
p = frag_more (1);
|
||||
insn_size += 1;
|
||||
/* md_number_to_chars (p, i.bi, 1); */
|
||||
md_number_to_chars (p, (i.bi.base << 0 | i.bi.index << 3 | i.bi.scale << 6), 1);
|
||||
md_number_to_chars (p, (valueT) (i.bi.base << 0
|
||||
| i.bi.index << 3
|
||||
| i.bi.scale << 6),
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,23 +1557,33 @@ md_assemble (line)
|
||||
if (i.types[n] & (Disp8 | Abs8))
|
||||
{
|
||||
p = frag_more (1);
|
||||
md_number_to_chars (p, i.disps[n]->X_add_number, 1);
|
||||
insn_size += 1;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.disps[n]->X_add_number,
|
||||
1);
|
||||
}
|
||||
else if (i.types[n] & (Disp16 | Abs16))
|
||||
{
|
||||
p = frag_more (2);
|
||||
md_number_to_chars (p, i.disps[n]->X_add_number, 2);
|
||||
insn_size += 2;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.disps[n]->X_add_number,
|
||||
2);
|
||||
}
|
||||
else
|
||||
{ /* Disp32|Abs32 */
|
||||
p = frag_more (4);
|
||||
md_number_to_chars (p, i.disps[n]->X_add_number, 4);
|
||||
insn_size += 4;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.disps[n]->X_add_number,
|
||||
4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* not absolute_section */
|
||||
/* need a 32-bit fixup (don't support 8bit non-absolute disps) */
|
||||
p = frag_more (4);
|
||||
insn_size += 4;
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
|
||||
i.disps[n], 0, BFD_RELOC_32);
|
||||
}
|
||||
@@ -1558,17 +1605,26 @@ md_assemble (line)
|
||||
if (i.types[n] & (Imm8 | Imm8S))
|
||||
{
|
||||
p = frag_more (1);
|
||||
md_number_to_chars (p, i.imms[n]->X_add_number, 1);
|
||||
insn_size += 1;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.imms[n]->X_add_number,
|
||||
1);
|
||||
}
|
||||
else if (i.types[n] & Imm16)
|
||||
{
|
||||
p = frag_more (2);
|
||||
md_number_to_chars (p, i.imms[n]->X_add_number, 2);
|
||||
insn_size += 2;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.imms[n]->X_add_number,
|
||||
2);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = frag_more (4);
|
||||
md_number_to_chars (p, i.imms[n]->X_add_number, 4);
|
||||
insn_size += 4;
|
||||
md_number_to_chars (p,
|
||||
(valueT) i.imms[n]->X_add_number,
|
||||
4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1583,6 +1639,7 @@ md_assemble (line)
|
||||
else
|
||||
size = 4;
|
||||
p = frag_more (size);
|
||||
insn_size += size;
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
|
||||
i.imms[n], 0, reloc (size, 0));
|
||||
}
|
||||
@@ -1696,6 +1753,7 @@ i386_operand (operand_string)
|
||||
i.imms[this_operand] = exp;
|
||||
save_input_line_pointer = input_line_pointer;
|
||||
input_line_pointer = ++op_string; /* must advance op_string! */
|
||||
SKIP_WHITESPACE ();
|
||||
exp_seg = expression (exp);
|
||||
input_line_pointer = save_input_line_pointer;
|
||||
|
||||
@@ -1712,7 +1770,8 @@ i386_operand (operand_string)
|
||||
}
|
||||
else if (exp->X_op == O_constant)
|
||||
{
|
||||
i.types[this_operand] |= smallest_imm_type (exp->X_add_number);
|
||||
i.types[this_operand] |=
|
||||
smallest_imm_type ((unsigned long) exp->X_add_number);
|
||||
}
|
||||
#ifdef OBJ_AOUT
|
||||
else if (exp_seg != text_section
|
||||
@@ -2152,7 +2211,7 @@ md_convert_frag (abfd, sec, fragP)
|
||||
}
|
||||
/* now put displacement after opcode */
|
||||
md_number_to_chars ((char *) where_to_put_displacement,
|
||||
displacement_from_opcode_start - extension,
|
||||
(valueT) (displacement_from_opcode_start - extension),
|
||||
SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
|
||||
fragP->fr_fix += extension;
|
||||
}
|
||||
@@ -2172,8 +2231,8 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||
long offset;
|
||||
|
||||
offset = to_addr - (from_addr + 2);
|
||||
md_number_to_chars (ptr, (long) 0xeb, 1); /* opcode for byte-disp jump */
|
||||
md_number_to_chars (ptr + 1, offset, 1);
|
||||
md_number_to_chars (ptr, (valueT) 0xeb, 1); /* opcode for byte-disp jump */
|
||||
md_number_to_chars (ptr + 1, (valueT) offset, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2188,16 +2247,16 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||
if (flagseen['m'])
|
||||
{
|
||||
offset = to_addr - S_GET_VALUE (to_symbol);
|
||||
md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */
|
||||
md_number_to_chars (ptr + 1, offset, 4);
|
||||
md_number_to_chars (ptr, (valueT) 0xe9, 1);/* opcode for long jmp */
|
||||
md_number_to_chars (ptr + 1, (valueT) offset, 4);
|
||||
fix_new (frag, (ptr + 1) - frag->fr_literal, 4,
|
||||
to_symbol, (offsetT) 0, 0, BFD_RELOC_32);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = to_addr - (from_addr + 5);
|
||||
md_number_to_chars (ptr, (long) 0xe9, 1);
|
||||
md_number_to_chars (ptr + 1, offset, 4);
|
||||
md_number_to_chars (ptr, (valueT) 0xe9, 1);
|
||||
md_number_to_chars (ptr + 1, (valueT) offset, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2294,6 +2353,8 @@ md_apply_fix (fixP, val)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* This is never used. */
|
||||
long /* Knows about the byte order in a word. */
|
||||
md_chars_to_number (con, nbytes)
|
||||
unsigned char con[]; /* Low order byte 1st. */
|
||||
@@ -2307,7 +2368,7 @@ md_chars_to_number (con, nbytes)
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
#define MAX_LITTLENUMS 6
|
||||
@@ -2356,7 +2417,7 @@ md_atof (type, litP, sizeP)
|
||||
the bigendian 386. */
|
||||
for (wordP = words + prec - 1; prec--;)
|
||||
{
|
||||
md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
|
||||
md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
|
||||
litP += sizeof (LITTLENUM_TYPE);
|
||||
}
|
||||
return 0;
|
||||
@@ -2439,16 +2500,13 @@ md_pcrel_from (fixP)
|
||||
#ifndef I386COFF
|
||||
|
||||
static void
|
||||
s_bss ()
|
||||
s_bss (ignore)
|
||||
int ignore;
|
||||
{
|
||||
register int temp;
|
||||
|
||||
temp = get_absolute_expression ();
|
||||
#ifdef BFD_ASSEMBLER
|
||||
subseg_set (bss_section, (subsegT) temp);
|
||||
#else
|
||||
subseg_new (bss_section, (subsegT) temp);
|
||||
#endif
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
@@ -2462,38 +2520,52 @@ tc_gen_reloc (section, fixp)
|
||||
asection *section;
|
||||
fixS *fixp;
|
||||
{
|
||||
arelent *reloc;
|
||||
arelent *rel;
|
||||
bfd_reloc_code_real_type code;
|
||||
|
||||
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
|
||||
switch (F (fixp->fx_size, fixp->fx_pcrel))
|
||||
{
|
||||
#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
|
||||
#ifndef OBJ_ELF
|
||||
MAP (1, 0, BFD_RELOC_8);
|
||||
MAP (2, 0, BFD_RELOC_16);
|
||||
#endif
|
||||
MAP (4, 0, BFD_RELOC_32);
|
||||
#ifndef OBJ_ELF
|
||||
MAP (1, 1, BFD_RELOC_8_PCREL);
|
||||
MAP (2, 1, BFD_RELOC_16_PCREL);
|
||||
#endif
|
||||
MAP (4, 1, BFD_RELOC_32_PCREL);
|
||||
default:
|
||||
abort ();
|
||||
as_bad ("Can not do %d byte %srelocation", fixp->fx_size,
|
||||
fixp->fx_pcrel ? "pc-relative" : "");
|
||||
}
|
||||
#undef MAP
|
||||
#undef F
|
||||
|
||||
reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
|
||||
assert (reloc != 0);
|
||||
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
|
||||
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
||||
rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
|
||||
assert (rel != 0);
|
||||
rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
|
||||
rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
||||
if (fixp->fx_pcrel)
|
||||
reloc->addend = fixp->fx_addnumber;
|
||||
rel->addend = fixp->fx_addnumber;
|
||||
else
|
||||
reloc->addend = 0;
|
||||
rel->addend = 0;
|
||||
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
|
||||
assert (reloc->howto != 0);
|
||||
rel->howto = bfd_reloc_type_lookup (stdoutput, code);
|
||||
if (!rel->howto)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
return reloc;
|
||||
name = S_GET_NAME (fixp->fx_addsy);
|
||||
if (name == NULL)
|
||||
name = "<unknown>";
|
||||
as_fatal ("Cannot find relocation type for symbol %s, code %d",
|
||||
name, (int) code);
|
||||
}
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
#else /* ! BFD_ASSEMBLER */
|
||||
@@ -2516,7 +2588,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
|
||||
know (fixP->fx_addsy != NULL);
|
||||
|
||||
md_number_to_chars (where,
|
||||
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
|
||||
(valueT) (fixP->fx_frag->fr_address
|
||||
+ fixP->fx_where - segment_address_in_file),
|
||||
4);
|
||||
|
||||
r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
|
||||
|
||||
Reference in New Issue
Block a user