config/tc-i386.c (struct _i386_insn): Combine disps, imms, regs into

a union.  Use throughout file.  Delete TC_RELOC macro.
This commit is contained in:
Alan Modra
2000-02-24 08:18:20 +00:00
parent e56ac5c3a3
commit 520dc8e893
3 changed files with 110 additions and 156 deletions

View File

@ -1,5 +1,18 @@
2000-02-24 Alan Modra <alan@spri.levels.unisa.edu.au> 2000-02-24 Alan Modra <alan@spri.levels.unisa.edu.au>
* config/tc-i386.c (union i386_op): New.
(struct _i386_insn): Delete disps[], imms[], regs[]. Add op[].
Throughout file replace occurences of disps[n], imms[n], regs[n]
with equivalent op[n].disps, op[n].imms, op[n].regs. Simplify
intel mode operand swapping. Add assert in regKludge and
fake_zero_displacement code. Test i.types[n] when outputting
displacements and immediates. Combine output of Disp16 with
Disp32.
* config/tc-i386.h (TC_RELOC): Delete.
* config/tc-i386.c (TC_RELOC): Delete. Replace usage of TC_RELOC
with equivalent call to reloc.
* as.h (flag_m68k_mri): Move declaration after target include, and * as.h (flag_m68k_mri): Move declaration after target include, and
only declare when TC_M68K defined. Define as zero otherwise. only declare when TC_M68K defined. Define as zero otherwise.
(LABELS_WITHOUT_COLONS, NO_PSEUDO_DOT): If undefined, define as 0. (LABELS_WITHOUT_COLONS, NO_PSEUDO_DOT): If undefined, define as 0.

View File

@ -32,10 +32,6 @@
#include "subsegs.h" #include "subsegs.h"
#include "opcode/i386.h" #include "opcode/i386.h"
#ifndef TC_RELOC
#define TC_RELOC(X,Y) (Y)
#endif
#ifndef REGISTER_WARNINGS #ifndef REGISTER_WARNINGS
#define REGISTER_WARNINGS 1 #define REGISTER_WARNINGS 1
#endif #endif
@ -74,6 +70,13 @@ static bfd_reloc_code_real_type reloc
/* 'md_assemble ()' gathers together information and puts it into a /* 'md_assemble ()' gathers together information and puts it into a
i386_insn. */ i386_insn. */
union i386_op
{
expressionS *disps;
expressionS *imms;
const reg_entry *regs;
};
struct _i386_insn struct _i386_insn
{ {
/* TM holds the template for the insn were currently assembling. */ /* TM holds the template for the insn were currently assembling. */
@ -83,8 +86,6 @@ struct _i386_insn
(e.g. 'l' for 'movl') */ (e.g. 'l' for 'movl') */
char suffix; char suffix;
/* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */
/* OPERANDS gives the number of given operands. */ /* OPERANDS gives the number of given operands. */
unsigned int operands; unsigned int operands;
@ -94,12 +95,12 @@ struct _i386_insn
unsigned int reg_operands, disp_operands, mem_operands, imm_operands; unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
/* TYPES [i] is the type (see above #defines) which tells us how to /* TYPES [i] is the type (see above #defines) which tells us how to
search through DISPS [i] & IMMS [i] & REGS [i] for the required use OP[i] for the corresponding operand. */
operand. */
unsigned int types[MAX_OPERANDS]; unsigned int types[MAX_OPERANDS];
/* Displacements (if given) for each operand. */ /* Displacement expression, immediate expression, or register for each
expressionS *disps[MAX_OPERANDS]; operand. */
union i386_op op[MAX_OPERANDS];
/* Relocation type for operand */ /* Relocation type for operand */
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
@ -108,12 +109,6 @@ struct _i386_insn
int disp_reloc[MAX_OPERANDS]; int disp_reloc[MAX_OPERANDS];
#endif #endif
/* Immediate operands (if given) for each operand. */
expressionS *imms[MAX_OPERANDS];
/* Register operands (if given) for each operand. */
const reg_entry *regs[MAX_OPERANDS];
/* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
the base index byte below. */ the base index byte below. */
const reg_entry *base_reg; const reg_entry *base_reg;
@ -761,11 +756,11 @@ pi (line, x)
fprintf (stdout, "\n"); fprintf (stdout, "\n");
if (x->types[i] if (x->types[i]
& (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM)) & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM))
fprintf (stdout, "%s\n", x->regs[i]->reg_name); fprintf (stdout, "%s\n", x->op[i].regs->reg_name);
if (x->types[i] & Imm) if (x->types[i] & Imm)
pe (x->imms[i]); pe (x->op[i].imms);
if (x->types[i] & Disp) if (x->types[i] & Disp)
pe (x->disps[i]); pe (x->op[i].disps);
} }
} }
@ -1271,15 +1266,13 @@ md_assemble (line)
int suffix_check; int suffix_check;
/* All intel opcodes have reversed operands except for BOUND and ENTER */ /* All intel opcodes have reversed operands except for BOUND and ENTER */
if (intel_syntax if (intel_syntax && i.operands > 1
&& (strcmp (mnemonic, "enter") != 0) && (strcmp (mnemonic, "enter") != 0)
&& (strcmp (mnemonic, "bound") != 0) && (strcmp (mnemonic, "bound") != 0)
&& (strncmp (mnemonic, "fsub", 4) !=0) && (strncmp (mnemonic, "fsub", 4) !=0)
&& (strncmp (mnemonic, "fdiv", 4) !=0)) && (strncmp (mnemonic, "fdiv", 4) !=0))
{ {
const reg_entry *temp_reg = NULL; union i386_op temp_op;
expressionS *temp_disp = NULL;
expressionS *temp_imm = NULL;
unsigned int temp_type; unsigned int temp_type;
int xchg1 = 0; int xchg1 = 0;
int xchg2 = 0; int xchg2 = 0;
@ -1294,56 +1287,12 @@ md_assemble (line)
xchg1 = 0; xchg1 = 0;
xchg2 = 2; xchg2 = 2;
} }
temp_type = i.types[xchg2];
if (i.operands > 1) i.types[xchg2] = i.types[xchg1];
{ i.types[xchg1] = temp_type;
temp_type = i.types[xchg2]; temp_op = i.op[xchg2];
if (temp_type & Imm) i.op[xchg2] = i.op[xchg1];
temp_imm = i.imms[xchg2]; i.op[xchg1] = temp_op;
else if (temp_type & Disp)
temp_disp = i.disps[xchg2];
else
temp_reg = i.regs[xchg2];
i.types[xchg2] = i.types[xchg1];
if (i.types[xchg2] & Imm)
{
i.imms[xchg2] = i.imms[xchg1];
i.imms[xchg1] = NULL;
}
else if (i.types[xchg2] & Disp)
{
i.disps[xchg2] = i.disps[xchg1];
i.disps[xchg1] = NULL;
}
else
{
i.regs[xchg2] = i.regs[xchg1];
i.regs[xchg1] = NULL;
}
if (temp_type & Imm)
{
i.imms[xchg1] = temp_imm;
if (! (i.types[xchg1] & Imm))
i.imms[xchg2] = NULL;
}
else if (temp_type & Disp)
{
i.disps[xchg1] = temp_disp;
if (! (i.types[xchg1] & Disp))
i.disps[xchg2] = NULL;
}
else
{
i.regs[xchg1] = temp_reg;
if (i.types[xchg1] & (Imm | Disp))
i.regs[xchg2] = NULL;
}
i.types[xchg1] = temp_type;
}
} }
overlap0 = 0; overlap0 = 0;
overlap1 = 0; overlap1 = 0;
@ -1556,7 +1505,7 @@ md_assemble (line)
|| i.tm.base_opcode == 0xfbf)) || i.tm.base_opcode == 0xfbf))
continue; continue;
if ((i.types[op] & WordReg) && i.regs[op]->reg_num < 4 if ((i.types[op] & WordReg) && i.op[op].regs->reg_num < 4
#if 0 #if 0
/* Check that the template allows eight bit regs /* Check that the template allows eight bit regs
This kills insns such as `orb $1,%edx', which This kills insns such as `orb $1,%edx', which
@ -1568,8 +1517,8 @@ md_assemble (line)
#if REGISTER_WARNINGS #if REGISTER_WARNINGS
if ((i.tm.operand_types[op] & InOutPortReg) == 0) if ((i.tm.operand_types[op] & InOutPortReg) == 0)
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"), as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
(i.regs[op] - (i.types[op] & Reg16 ? 8 : 16))->reg_name, (i.op[op].regs - (i.types[op] & Reg16 ? 8 : 16))->reg_name,
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.suffix); i.suffix);
#endif #endif
continue; continue;
@ -1581,7 +1530,7 @@ md_assemble (line)
| FloatReg | FloatAcc)) | FloatReg | FloatAcc))
{ {
as_bad (_("`%%%s' not allowed with `%s%c'"), as_bad (_("`%%%s' not allowed with `%s%c'"),
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.tm.name, i.tm.name,
i.suffix); i.suffix);
return; return;
@ -1598,7 +1547,7 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0) && (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
{ {
as_bad (_("`%%%s' not allowed with `%s%c'"), as_bad (_("`%%%s' not allowed with `%s%c'"),
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.tm.name, i.tm.name,
i.suffix); i.suffix);
return; return;
@ -1609,8 +1558,8 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg32|Acc)) != 0) && (i.tm.operand_types[op] & (Reg32|Acc)) != 0)
{ {
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"), as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
(i.regs[op] + 8)->reg_name, (i.op[op].regs + 8)->reg_name,
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.suffix); i.suffix);
} }
#endif #endif
@ -1625,7 +1574,7 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0) && (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
{ {
as_bad (_("`%%%s' not allowed with `%s%c'"), as_bad (_("`%%%s' not allowed with `%s%c'"),
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.tm.name, i.tm.name,
i.suffix); i.suffix);
return; return;
@ -1636,8 +1585,8 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Acc)) != 0) && (i.tm.operand_types[op] & (Reg16|Acc)) != 0)
{ {
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"), as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
(i.regs[op] - 8)->reg_name, (i.op[op].regs - 8)->reg_name,
i.regs[op]->reg_name, i.op[op].regs->reg_name,
i.suffix); i.suffix);
} }
#endif #endif
@ -1724,7 +1673,7 @@ md_assemble (line)
{ {
unsigned int prefix = DATA_PREFIX_OPCODE; unsigned int prefix = DATA_PREFIX_OPCODE;
if ((i.regs[1]->reg_type & Reg16) != 0) if ((i.op[1].regs->reg_type & Reg16) != 0)
if (!add_prefix (prefix)) if (!add_prefix (prefix))
return; return;
} }
@ -1771,10 +1720,10 @@ md_assemble (line)
expressionS *exp; expressionS *exp;
assert(i.imm_operands == 0 && i.operands <= 2); assert(i.imm_operands == 0 && i.operands <= 2 && 2 < MAX_OPERANDS);
exp = &im_expressions[i.imm_operands++]; exp = &im_expressions[i.imm_operands++];
i.imms[i.operands] = exp; i.op[i.operands].imms = exp;
i.types[i.operands++] = Imm8; i.types[i.operands++] = Imm8;
exp->X_op = O_constant; exp->X_op = O_constant;
exp->X_add_number = i.tm.extension_opcode; exp->X_add_number = i.tm.extension_opcode;
@ -1802,7 +1751,9 @@ md_assemble (line)
{ {
unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1; unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
/* Pretend we saw the extra register operand. */ /* Pretend we saw the extra register operand. */
i.regs[first_reg_op+1] = i.regs[first_reg_op]; assert (i.op[first_reg_op+1].regs == 0);
i.op[first_reg_op+1].regs = i.op[first_reg_op].regs;
i.types[first_reg_op+1] = i.types[first_reg_op];
i.reg_operands = 2; i.reg_operands = 2;
} }
@ -1811,7 +1762,7 @@ md_assemble (line)
/* The register or float register operand is in operand 0 or 1. */ /* The register or float register operand is in operand 0 or 1. */
unsigned int op = (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. */ /* Register goes in low 3 bits of opcode. */
i.tm.base_opcode |= i.regs[op]->reg_num; i.tm.base_opcode |= i.op[op].regs->reg_num;
if ((i.tm.opcode_modifier & Ugh) != 0) if ((i.tm.opcode_modifier & Ugh) != 0)
{ {
/* Warn about some common errors, but press on regardless. /* Warn about some common errors, but press on regardless.
@ -1820,14 +1771,14 @@ md_assemble (line)
{ {
/* reversed arguments on faddp, fsubp, etc. */ /* reversed arguments on faddp, fsubp, etc. */
as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name, as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
i.regs[1]->reg_name, i.op[1].regs->reg_name,
i.regs[0]->reg_name); i.op[0].regs->reg_name);
} }
else else
{ {
/* extraneous `l' suffix on fp insn */ /* extraneous `l' suffix on fp insn */
as_warn (_("translating to `%s %%%s'"), i.tm.name, as_warn (_("translating to `%s %%%s'"), i.tm.name,
i.regs[0]->reg_name); i.op[0].regs->reg_name);
} }
} }
} }
@ -1860,13 +1811,13 @@ md_assemble (line)
destination in the i.rm.reg field. */ destination in the i.rm.reg field. */
if ((i.tm.operand_types[dest] & AnyMem) == 0) if ((i.tm.operand_types[dest] & AnyMem) == 0)
{ {
i.rm.reg = i.regs[dest]->reg_num; i.rm.reg = i.op[dest].regs->reg_num;
i.rm.regmem = i.regs[source]->reg_num; i.rm.regmem = i.op[source].regs->reg_num;
} }
else else
{ {
i.rm.reg = i.regs[source]->reg_num; i.rm.reg = i.op[source].regs->reg_num;
i.rm.regmem = i.regs[dest]->reg_num; i.rm.regmem = i.op[dest].regs->reg_num;
} }
} }
else else
@ -1989,8 +1940,9 @@ md_assemble (line)
holds the correct displacement size. */ holds the correct displacement size. */
expressionS *exp; expressionS *exp;
assert (i.op[op].disps == 0);
exp = &disp_expressions[i.disp_operands++]; exp = &disp_expressions[i.disp_operands++];
i.disps[op] = exp; i.op[op].disps = exp;
exp->X_op = O_constant; exp->X_op = O_constant;
exp->X_add_number = 0; exp->X_add_number = 0;
exp->X_add_symbol = (symbolS *) 0; exp->X_add_symbol = (symbolS *) 0;
@ -2020,9 +1972,9 @@ md_assemble (line)
/* If there is an extension opcode to put here, the /* If there is an extension opcode to put here, the
register number must be put into the regmem field. */ register number must be put into the regmem field. */
if (i.tm.extension_opcode != None) if (i.tm.extension_opcode != None)
i.rm.regmem = i.regs[op]->reg_num; i.rm.regmem = i.op[op].regs->reg_num;
else else
i.rm.reg = i.regs[op]->reg_num; i.rm.reg = i.op[op].regs->reg_num;
/* Now, if no memory operand has set i.rm.mode = 0, 1, 2 /* 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 we must set it to 3 to indicate this is a register
@ -2038,12 +1990,12 @@ md_assemble (line)
} }
else if (i.tm.opcode_modifier & (Seg2ShortForm | Seg3ShortForm)) else if (i.tm.opcode_modifier & (Seg2ShortForm | Seg3ShortForm))
{ {
if (i.tm.base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1) if (i.tm.base_opcode == POP_SEG_SHORT && i.op[0].regs->reg_num == 1)
{ {
as_bad (_("you can't `pop %%cs'")); as_bad (_("you can't `pop %%cs'"));
return; return;
} }
i.tm.base_opcode |= (i.regs[0]->reg_num << 3); i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
} }
else if ((i.tm.base_opcode & ~(D|W)) == MOV_AX_DISP32) else if ((i.tm.base_opcode & ~(D|W)) == MOV_AX_DISP32)
{ {
@ -2076,20 +2028,20 @@ md_assemble (line)
} }
/* Handle conversion of 'int $3' --> special int3 insn. */ /* Handle conversion of 'int $3' --> special int3 insn. */
if (i.tm.base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3) if (i.tm.base_opcode == INT_OPCODE && i.op[0].imms->X_add_number == 3)
{ {
i.tm.base_opcode = INT3_OPCODE; i.tm.base_opcode = INT3_OPCODE;
i.imm_operands = 0; i.imm_operands = 0;
} }
if ((i.tm.opcode_modifier & (Jump | JumpByte | JumpDword)) if ((i.tm.opcode_modifier & (Jump | JumpByte | JumpDword))
&& i.disps[0]->X_op == O_constant) && i.op[0].disps->X_op == O_constant)
{ {
/* Convert "jmp constant" (and "call constant") to a jump (call) to /* Convert "jmp constant" (and "call constant") to a jump (call) to
the absolute address given by the constant. Since ix86 jumps and the absolute address given by the constant. Since ix86 jumps and
calls are pc relative, we need to generate a reloc. */ calls are pc relative, we need to generate a reloc. */
i.disps[0]->X_add_symbol = &abs_symbol; i.op[0].disps->X_add_symbol = &abs_symbol;
i.disps[0]->X_op = O_symbol; i.op[0].disps->X_op = O_symbol;
} }
/* We are ready to output the insn. */ /* We are ready to output the insn. */
@ -2141,8 +2093,8 @@ md_assemble (line)
((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.op[0].disps->X_add_symbol,
i.disps[0]->X_add_number, i.op[0].disps->X_add_number,
p); p);
} }
else if (i.tm.opcode_modifier & (JumpByte | JumpDword)) else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
@ -2199,7 +2151,7 @@ md_assemble (line)
*p++ = i.tm.base_opcode & 0xff; *p++ = i.tm.base_opcode & 0xff;
fix_new_exp (frag_now, p - frag_now->fr_literal, size, fix_new_exp (frag_now, p - frag_now->fr_literal, size,
i.disps[0], 1, reloc (size, 1, i.disp_reloc[0])); i.op[0].disps, 1, reloc (size, 1, i.disp_reloc[0]));
} }
else if (i.tm.opcode_modifier & JumpInterSegment) else if (i.tm.opcode_modifier & JumpInterSegment)
{ {
@ -2231,9 +2183,9 @@ md_assemble (line)
if (prefix) if (prefix)
*p++ = DATA_PREFIX_OPCODE; *p++ = DATA_PREFIX_OPCODE;
*p++ = i.tm.base_opcode; *p++ = i.tm.base_opcode;
if (i.imms[1]->X_op == O_constant) if (i.op[1].imms->X_op == O_constant)
{ {
long n = (long) i.imms[1]->X_add_number; long n = (long) i.op[1].imms->X_add_number;
if (size == 2 && !fits_in_unsigned_word (n)) if (size == 2 && !fits_in_unsigned_word (n))
{ {
@ -2244,11 +2196,11 @@ md_assemble (line)
} }
else else
fix_new_exp (frag_now, p - frag_now->fr_literal, size, fix_new_exp (frag_now, p - frag_now->fr_literal, size,
i.imms[1], 0, reloc (size, 0, i.disp_reloc[0])); i.op[1].imms, 0, reloc (size, 0, i.disp_reloc[0]));
if (i.imms[0]->X_op != O_constant) if (i.op[0].imms->X_op != O_constant)
as_bad (_("can't handle non absolute segment in `%s'"), as_bad (_("can't handle non absolute segment in `%s'"),
i.tm.name); i.tm.name);
md_number_to_chars (p + size, (valueT) i.imms[0]->X_add_number, 2); md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
} }
else else
{ {
@ -2334,12 +2286,12 @@ md_assemble (line)
for (n = 0; n < i.operands; n++) for (n = 0; n < i.operands; n++)
{ {
if (i.disps[n]) if (i.types[n] & Disp)
{ {
if (i.disps[n]->X_op == O_constant) if (i.op[n].disps->X_op == O_constant)
{ {
int size = 4; int size = 4;
long val = (long) i.disps[n]->X_add_number; long val = (long) i.op[n].disps->X_add_number;
if (i.types[n] & (Disp8 | Disp16)) if (i.types[n] & (Disp8 | Disp16))
{ {
@ -2361,21 +2313,18 @@ md_assemble (line)
p = frag_more (size); p = frag_more (size);
md_number_to_chars (p, (valueT) val, size); md_number_to_chars (p, (valueT) val, size);
} }
else if (i.types[n] & Disp32)
{
insn_size += 4;
p = frag_more (4);
fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
i.disps[n], 0,
TC_RELOC (i.disp_reloc[n], BFD_RELOC_32));
}
else else
{ /* must be Disp16 */ {
insn_size += 2; int size = 4;
p = frag_more (2);
fix_new_exp (frag_now, p - frag_now->fr_literal, 2, if (i.types[n] & Disp16)
i.disps[n], 0, size = 2;
TC_RELOC (i.disp_reloc[n], BFD_RELOC_16));
insn_size += size;
p = frag_more (size);
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
i.op[n].disps, 0,
reloc (size, 0, i.disp_reloc[n]));
} }
} }
} }
@ -2388,12 +2337,12 @@ md_assemble (line)
for (n = 0; n < i.operands; n++) for (n = 0; n < i.operands; n++)
{ {
if (i.imms[n]) if (i.types[n] & Imm)
{ {
if (i.imms[n]->X_op == O_constant) if (i.op[n].imms->X_op == O_constant)
{ {
int size = 4; int size = 4;
long val = (long) i.imms[n]->X_add_number; long val = (long) i.op[n].imms->X_add_number;
if (i.types[n] & (Imm8 | Imm8S | Imm16)) if (i.types[n] & (Imm8 | Imm8S | Imm16))
{ {
@ -2417,41 +2366,39 @@ md_assemble (line)
else else
{ /* not absolute_section */ { /* not absolute_section */
/* Need a 32-bit fixup (don't support 8bit /* Need a 32-bit fixup (don't support 8bit
non-absolute ims). Try to support other non-absolute imms). Try to support other
sizes ... */ sizes ... */
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
enum bfd_reloc_code_real reloc_type; enum bfd_reloc_code_real reloc_type;
#else #else
int reloc_type; int reloc_type;
#endif #endif
int size; int size = 4;
int pcrel = 0;
if (i.types[n] & (Imm8 | Imm8S)) if (i.types[n] & Imm16)
size = 1;
else if (i.types[n] & Imm16)
size = 2; size = 2;
else else if (i.types[n] & (Imm8 | Imm8S))
size = 4; size = 1;
insn_size += size; insn_size += size;
p = frag_more (size); p = frag_more (size);
reloc_type = reloc (size, 0, i.disp_reloc[0]); reloc_type = reloc (size, 0, i.disp_reloc[0]);
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
if (reloc_type == BFD_RELOC_32 if (reloc_type == BFD_RELOC_32
&& GOT_symbol && GOT_symbol
&& GOT_symbol == i.imms[n]->X_add_symbol && GOT_symbol == i.op[n].imms->X_add_symbol
&& (i.imms[n]->X_op == O_symbol && (i.op[n].imms->X_op == O_symbol
|| (i.imms[n]->X_op == O_add || (i.op[n].imms->X_op == O_add
&& ((symbol_get_value_expression && ((symbol_get_value_expression
(i.imms[n]->X_op_symbol)->X_op) (i.op[n].imms->X_op_symbol)->X_op)
== O_subtract)))) == O_subtract))))
{ {
reloc_type = BFD_RELOC_386_GOTPC; reloc_type = BFD_RELOC_386_GOTPC;
i.imms[n]->X_add_number += 3; i.op[n].imms->X_add_number += 3;
} }
#endif #endif
fix_new_exp (frag_now, p - frag_now->fr_literal, size, fix_new_exp (frag_now, p - frag_now->fr_literal, size,
i.imms[n], pcrel, reloc_type); i.op[n].imms, 0, reloc_type);
} }
} }
} }
@ -2484,7 +2431,7 @@ i386_immediate (imm_start)
} }
exp = &im_expressions[i.imm_operands++]; exp = &im_expressions[i.imm_operands++];
i.imms[this_operand] = exp; i.op[this_operand].imms = exp;
if (is_space_char (*imm_start)) if (is_space_char (*imm_start))
++imm_start; ++imm_start;
@ -2678,8 +2625,7 @@ i386_displacement (disp_start, disp_end)
i.types[this_operand] |= bigdisp; i.types[this_operand] |= bigdisp;
exp = &disp_expressions[i.disp_operands]; exp = &disp_expressions[i.disp_operands];
i.disps[this_operand] = exp; i.op[this_operand].disps = exp;
i.disp_reloc[this_operand] = NO_RELOC;
i.disp_operands++; i.disp_operands++;
save_input_line_pointer = input_line_pointer; save_input_line_pointer = input_line_pointer;
input_line_pointer = disp_start; input_line_pointer = disp_start;
@ -3312,7 +3258,7 @@ i386_intel_operand (operand_string, got_a_float)
} }
i.types[this_operand] |= r->reg_type & ~BaseIndex; i.types[this_operand] |= r->reg_type & ~BaseIndex;
i.regs[this_operand] = r; i.op[this_operand].regs = r;
i.reg_operands++; i.reg_operands++;
} }
else if (*op_string == REGISTER_PREFIX) else if (*op_string == REGISTER_PREFIX)
@ -3415,7 +3361,7 @@ i386_operand (operand_string)
return 0; return 0;
} }
i.types[this_operand] |= r->reg_type & ~BaseIndex; i.types[this_operand] |= r->reg_type & ~BaseIndex;
i.regs[this_operand] = r; i.op[this_operand].regs = r;
i.reg_operands++; i.reg_operands++;
} }
else if (*op_string == REGISTER_PREFIX) else if (*op_string == REGISTER_PREFIX)

View File

@ -38,11 +38,6 @@ struct fix;
type. The idea is that if the original type is already some kind of PIC type. The idea is that if the original type is already some kind of PIC
relocation, we leave it alone, otherwise we give it the desired type */ relocation, we leave it alone, otherwise we give it the desired type */
#define TC_RELOC(X,Y) (((X) != BFD_RELOC_386_PLT32 && \
(X) != BFD_RELOC_386_GOTOFF && \
(X) != BFD_RELOC_386_GOT32 && \
(X) != BFD_RELOC_386_GOTPC) ? Y : X)
#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X) #define tc_fix_adjustable(X) tc_i386_fix_adjustable(X)
extern int tc_i386_fix_adjustable PARAMS ((struct fix *)); extern int tc_i386_fix_adjustable PARAMS ((struct fix *));