aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2000-02-24 08:18:20 +0000
committerAlan Modra <amodra@gmail.com>2000-02-24 08:18:20 +0000
commit520dc8e893f461f2357cddb68f82fa109c82cb94 (patch)
tree2f59c2a00a522d3091344873cf27e440d80f8b0e /gas/config/tc-i386.c
parente56ac5c3a397926b0569e691a16b2c58dafc11c8 (diff)
downloadgdb-520dc8e893f461f2357cddb68f82fa109c82cb94.zip
gdb-520dc8e893f461f2357cddb68f82fa109c82cb94.tar.gz
gdb-520dc8e893f461f2357cddb68f82fa109c82cb94.tar.bz2
config/tc-i386.c (struct _i386_insn): Combine disps, imms, regs into
a union. Use throughout file. Delete TC_RELOC macro.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c248
1 files changed, 97 insertions, 151 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index d762d5f..7d8a0e7 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -32,10 +32,6 @@
#include "subsegs.h"
#include "opcode/i386.h"
-#ifndef TC_RELOC
-#define TC_RELOC(X,Y) (Y)
-#endif
-
#ifndef REGISTER_WARNINGS
#define REGISTER_WARNINGS 1
#endif
@@ -74,6 +70,13 @@ static bfd_reloc_code_real_type reloc
/* 'md_assemble ()' gathers together information and puts it into a
i386_insn. */
+union i386_op
+ {
+ expressionS *disps;
+ expressionS *imms;
+ const reg_entry *regs;
+ };
+
struct _i386_insn
{
/* TM holds the template for the insn were currently assembling. */
@@ -83,8 +86,6 @@ struct _i386_insn
(e.g. 'l' for 'movl') */
char suffix;
- /* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */
-
/* OPERANDS gives the number of given operands. */
unsigned int operands;
@@ -94,12 +95,12 @@ struct _i386_insn
unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
/* TYPES [i] is the type (see above #defines) which tells us how to
- search through DISPS [i] & IMMS [i] & REGS [i] for the required
- operand. */
+ use OP[i] for the corresponding operand. */
unsigned int types[MAX_OPERANDS];
- /* Displacements (if given) for each operand. */
- expressionS *disps[MAX_OPERANDS];
+ /* Displacement expression, immediate expression, or register for each
+ operand. */
+ union i386_op op[MAX_OPERANDS];
/* Relocation type for operand */
#ifdef BFD_ASSEMBLER
@@ -108,12 +109,6 @@ struct _i386_insn
int disp_reloc[MAX_OPERANDS];
#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
the base index byte below. */
const reg_entry *base_reg;
@@ -761,11 +756,11 @@ pi (line, x)
fprintf (stdout, "\n");
if (x->types[i]
& (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)
- pe (x->imms[i]);
+ pe (x->op[i].imms);
if (x->types[i] & Disp)
- pe (x->disps[i]);
+ pe (x->op[i].disps);
}
}
@@ -1271,15 +1266,13 @@ md_assemble (line)
int suffix_check;
/* 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, "bound") != 0)
&& (strncmp (mnemonic, "fsub", 4) !=0)
&& (strncmp (mnemonic, "fdiv", 4) !=0))
{
- const reg_entry *temp_reg = NULL;
- expressionS *temp_disp = NULL;
- expressionS *temp_imm = NULL;
+ union i386_op temp_op;
unsigned int temp_type;
int xchg1 = 0;
int xchg2 = 0;
@@ -1294,56 +1287,12 @@ md_assemble (line)
xchg1 = 0;
xchg2 = 2;
}
-
- if (i.operands > 1)
- {
- temp_type = i.types[xchg2];
- if (temp_type & Imm)
- temp_imm = i.imms[xchg2];
- 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;
- }
+ temp_type = i.types[xchg2];
+ i.types[xchg2] = i.types[xchg1];
+ i.types[xchg1] = temp_type;
+ temp_op = i.op[xchg2];
+ i.op[xchg2] = i.op[xchg1];
+ i.op[xchg1] = temp_op;
}
overlap0 = 0;
overlap1 = 0;
@@ -1556,7 +1505,7 @@ md_assemble (line)
|| i.tm.base_opcode == 0xfbf))
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
/* Check that the template allows eight bit regs
This kills insns such as `orb $1,%edx', which
@@ -1568,8 +1517,8 @@ md_assemble (line)
#if REGISTER_WARNINGS
if ((i.tm.operand_types[op] & InOutPortReg) == 0)
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
- (i.regs[op] - (i.types[op] & Reg16 ? 8 : 16))->reg_name,
- i.regs[op]->reg_name,
+ (i.op[op].regs - (i.types[op] & Reg16 ? 8 : 16))->reg_name,
+ i.op[op].regs->reg_name,
i.suffix);
#endif
continue;
@@ -1581,7 +1530,7 @@ md_assemble (line)
| FloatReg | FloatAcc))
{
as_bad (_("`%%%s' not allowed with `%s%c'"),
- i.regs[op]->reg_name,
+ i.op[op].regs->reg_name,
i.tm.name,
i.suffix);
return;
@@ -1598,7 +1547,7 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
{
as_bad (_("`%%%s' not allowed with `%s%c'"),
- i.regs[op]->reg_name,
+ i.op[op].regs->reg_name,
i.tm.name,
i.suffix);
return;
@@ -1609,8 +1558,8 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg32|Acc)) != 0)
{
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
- (i.regs[op] + 8)->reg_name,
- i.regs[op]->reg_name,
+ (i.op[op].regs + 8)->reg_name,
+ i.op[op].regs->reg_name,
i.suffix);
}
#endif
@@ -1625,7 +1574,7 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
{
as_bad (_("`%%%s' not allowed with `%s%c'"),
- i.regs[op]->reg_name,
+ i.op[op].regs->reg_name,
i.tm.name,
i.suffix);
return;
@@ -1636,8 +1585,8 @@ md_assemble (line)
&& (i.tm.operand_types[op] & (Reg16|Acc)) != 0)
{
as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
- (i.regs[op] - 8)->reg_name,
- i.regs[op]->reg_name,
+ (i.op[op].regs - 8)->reg_name,
+ i.op[op].regs->reg_name,
i.suffix);
}
#endif
@@ -1724,7 +1673,7 @@ md_assemble (line)
{
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))
return;
}
@@ -1771,10 +1720,10 @@ md_assemble (line)
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++];
- i.imms[i.operands] = exp;
+ i.op[i.operands].imms = exp;
i.types[i.operands++] = Imm8;
exp->X_op = O_constant;
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;
/* 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;
}
@@ -1811,7 +1762,7 @@ md_assemble (line)
/* The register or float register operand is in operand 0 or 1. */
unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
/* 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)
{
/* Warn about some common errors, but press on regardless.
@@ -1820,14 +1771,14 @@ md_assemble (line)
{
/* reversed arguments on faddp, fsubp, etc. */
as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
- i.regs[1]->reg_name,
- i.regs[0]->reg_name);
+ i.op[1].regs->reg_name,
+ i.op[0].regs->reg_name);
}
else
{
/* extraneous `l' suffix on fp insn */
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. */
if ((i.tm.operand_types[dest] & AnyMem) == 0)
{
- i.rm.reg = i.regs[dest]->reg_num;
- i.rm.regmem = i.regs[source]->reg_num;
+ i.rm.reg = i.op[dest].regs->reg_num;
+ i.rm.regmem = i.op[source].regs->reg_num;
}
else
{
- i.rm.reg = i.regs[source]->reg_num;
- i.rm.regmem = i.regs[dest]->reg_num;
+ i.rm.reg = i.op[source].regs->reg_num;
+ i.rm.regmem = i.op[dest].regs->reg_num;
}
}
else
@@ -1989,8 +1940,9 @@ md_assemble (line)
holds the correct displacement size. */
expressionS *exp;
+ assert (i.op[op].disps == 0);
exp = &disp_expressions[i.disp_operands++];
- i.disps[op] = exp;
+ i.op[op].disps = exp;
exp->X_op = O_constant;
exp->X_add_number = 0;
exp->X_add_symbol = (symbolS *) 0;
@@ -2020,9 +1972,9 @@ md_assemble (line)
/* If there is an extension opcode to put here, the
register number must be put into the regmem field. */
if (i.tm.extension_opcode != None)
- i.rm.regmem = i.regs[op]->reg_num;
+ i.rm.regmem = i.op[op].regs->reg_num;
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
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))
{
- 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'"));
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)
{
@@ -2076,20 +2028,20 @@ md_assemble (line)
}
/* 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.imm_operands = 0;
}
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
the absolute address given by the constant. Since ix86 jumps and
calls are pc relative, we need to generate a reloc. */
- i.disps[0]->X_add_symbol = &abs_symbol;
- i.disps[0]->X_op = O_symbol;
+ i.op[0].disps->X_add_symbol = &abs_symbol;
+ i.op[0].disps->X_op = O_symbol;
}
/* We are ready to output the insn. */
@@ -2141,8 +2093,8 @@ md_assemble (line)
((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,
- i.disps[0]->X_add_number,
+ i.op[0].disps->X_add_symbol,
+ i.op[0].disps->X_add_number,
p);
}
else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
@@ -2199,7 +2151,7 @@ md_assemble (line)
*p++ = i.tm.base_opcode & 0xff;
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)
{
@@ -2231,9 +2183,9 @@ md_assemble (line)
if (prefix)
*p++ = DATA_PREFIX_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))
{
@@ -2244,11 +2196,11 @@ md_assemble (line)
}
else
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
- i.imms[1], 0, reloc (size, 0, i.disp_reloc[0]));
- if (i.imms[0]->X_op != O_constant)
+ i.op[1].imms, 0, reloc (size, 0, i.disp_reloc[0]));
+ if (i.op[0].imms->X_op != O_constant)
as_bad (_("can't handle non absolute segment in `%s'"),
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
{
@@ -2334,12 +2286,12 @@ md_assemble (line)
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;
- 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))
{
@@ -2361,21 +2313,18 @@ md_assemble (line)
p = frag_more (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
- { /* must be Disp16 */
- insn_size += 2;
- p = frag_more (2);
- fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
- i.disps[n], 0,
- TC_RELOC (i.disp_reloc[n], BFD_RELOC_16));
+ {
+ int size = 4;
+
+ if (i.types[n] & Disp16)
+ size = 2;
+
+ 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++)
{
- 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;
- 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))
{
@@ -2417,41 +2366,39 @@ md_assemble (line)
else
{ /* not absolute_section */
/* Need a 32-bit fixup (don't support 8bit
- non-absolute ims). Try to support other
+ non-absolute imms). Try to support other
sizes ... */
#ifdef BFD_ASSEMBLER
enum bfd_reloc_code_real reloc_type;
#else
int reloc_type;
#endif
- int size;
- int pcrel = 0;
+ int size = 4;
- if (i.types[n] & (Imm8 | Imm8S))
- size = 1;
- else if (i.types[n] & Imm16)
+ if (i.types[n] & Imm16)
size = 2;
- else
- size = 4;
+ else if (i.types[n] & (Imm8 | Imm8S))
+ size = 1;
+
insn_size += size;
p = frag_more (size);
reloc_type = reloc (size, 0, i.disp_reloc[0]);
#ifdef BFD_ASSEMBLER
if (reloc_type == BFD_RELOC_32
&& GOT_symbol
- && GOT_symbol == i.imms[n]->X_add_symbol
- && (i.imms[n]->X_op == O_symbol
- || (i.imms[n]->X_op == O_add
+ && GOT_symbol == i.op[n].imms->X_add_symbol
+ && (i.op[n].imms->X_op == O_symbol
+ || (i.op[n].imms->X_op == O_add
&& ((symbol_get_value_expression
- (i.imms[n]->X_op_symbol)->X_op)
+ (i.op[n].imms->X_op_symbol)->X_op)
== O_subtract))))
{
reloc_type = BFD_RELOC_386_GOTPC;
- i.imms[n]->X_add_number += 3;
+ i.op[n].imms->X_add_number += 3;
}
#endif
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++];
- i.imms[this_operand] = exp;
+ i.op[this_operand].imms = exp;
if (is_space_char (*imm_start))
++imm_start;
@@ -2678,8 +2625,7 @@ i386_displacement (disp_start, disp_end)
i.types[this_operand] |= bigdisp;
exp = &disp_expressions[i.disp_operands];
- i.disps[this_operand] = exp;
- i.disp_reloc[this_operand] = NO_RELOC;
+ i.op[this_operand].disps = exp;
i.disp_operands++;
save_input_line_pointer = input_line_pointer;
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.regs[this_operand] = r;
+ i.op[this_operand].regs = r;
i.reg_operands++;
}
else if (*op_string == REGISTER_PREFIX)
@@ -3415,7 +3361,7 @@ i386_operand (operand_string)
return 0;
}
i.types[this_operand] |= r->reg_type & ~BaseIndex;
- i.regs[this_operand] = r;
+ i.op[this_operand].regs = r;
i.reg_operands++;
}
else if (*op_string == REGISTER_PREFIX)