aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/tc-i386.c149
2 files changed, 84 insertions, 76 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8caa123..87a2cd4 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,14 @@
+Thu Mar 26 23:07:18 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Swap template arguments to
+ CONSISTENT_REGISTER_MATCH macro in reverse direction test.
+ This macro is currently symmetric, so passing them the wrong
+ way didn't cause any problem, but may if the macro is changed
+ in the future.
+ After copying template to i.tm, use i.tm. rather than t-> to
+ access fields, and make t a const*
+ Move i.tm.operand_types[] swap to immediately after the copy.
+
start-sanitize-sky
Thu Mar 26 13:29:59 1998 Doug Evans <devans@canuck.cygnus.com>
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ea57da8..427d2c6 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -834,8 +834,8 @@ void
md_assemble (line)
char *line;
{
- /* Holds template once we've found it. */
- template *t;
+ /* Points to template once we've found it. */
+ const template *t;
/* Count the size of the instruction generated. */
int insn_size = 0;
@@ -853,7 +853,7 @@ md_assemble (line)
memset (im_expressions, '\0', sizeof (im_expressions));
save_stack_p = save_stack; /* reset stack pointer */
- /* Fist parse an opcode & call i386_operand for the operands.
+ /* First parse an opcode & call i386_operand for the operands.
We assume that the scrubber has arranged it so that line[0] is the valid
start of a (possibly prefixed) opcode. */
{
@@ -1132,8 +1132,8 @@ md_assemble (line)
if (!MATCH (overlap0, i.types[0]) ||
!MATCH (overlap1, i.types[1]) ||
!CONSISTENT_REGISTER_MATCH (overlap0, overlap1,
- t->operand_types[0],
- t->operand_types[1]))
+ t->operand_types[1],
+ t->operand_types[0]))
{
/* does not match either direction */
continue;
@@ -1168,18 +1168,23 @@ md_assemble (line)
/* Copy the template we found (we may change it!). */
i.tm = *t;
- t = &i.tm; /* alter new copy of template */
+
+ if (found_reverse_match)
+ {
+ i.tm.operand_types[0] = t->operand_types[1];
+ i.tm.operand_types[1] = t->operand_types[0];
+ }
/* If the matched instruction specifies an explicit opcode suffix,
use it - and make sure none has already been specified. */
- if (t->opcode_modifier & (Data16|Data32))
+ if (i.tm.opcode_modifier & (Data16|Data32))
{
if (i.suffix)
{
as_bad ("extraneous opcode suffix given");
return;
}
- if (t->opcode_modifier & Data16)
+ if (i.tm.opcode_modifier & Data16)
i.suffix = WORD_OPCODE_SUFFIX;
else
i.suffix = DWORD_OPCODE_SUFFIX;
@@ -1276,19 +1281,11 @@ md_assemble (line)
if (overlap0 & Imm1)
i.imm_operands = 0; /* kludge for shift insns */
- if (found_reverse_match)
- {
- unsigned int save;
- save = t->operand_types[0];
- t->operand_types[0] = t->operand_types[1];
- t->operand_types[1] = save;
- }
-
/* Finalize opcode. First, we change the opcode based on the operand
size given by i.suffix: we never have to change things for byte insns,
or when no opcode suffix is need to size the operands. */
- if (!i.suffix && (t->opcode_modifier & W))
+ if (!i.suffix && (i.tm.opcode_modifier & W))
{
as_bad ("no opcode suffix given and no register operands; can't size instruction");
return;
@@ -1297,15 +1294,15 @@ md_assemble (line)
if (i.suffix && i.suffix != BYTE_OPCODE_SUFFIX)
{
/* Select between byte and word/dword operations. */
- if (t->opcode_modifier & W)
- t->base_opcode |= W;
+ if (i.tm.opcode_modifier & W)
+ i.tm.base_opcode |= W;
/* Now select between word & dword operations via the
operand size prefix. */
if ((i.suffix == WORD_OPCODE_SUFFIX) ^ flag_16bit_code)
{
if (i.prefixes == MAX_PREFIXES)
{
- as_bad ("%d prefixes given and 'w' opcode suffix gives too many prefixes",
+ as_bad ("%d prefixes given and data size prefix gives too many prefixes",
MAX_PREFIXES);
return;
}
@@ -1332,12 +1329,12 @@ md_assemble (line)
if (found_reverse_match)
{
- t->base_opcode |= found_reverse_match;
+ i.tm.base_opcode |= found_reverse_match;
}
/* The imul $imm, %reg instruction is converted into
imul $imm, %reg, %reg. */
- if (t->opcode_modifier & imulKludge)
+ if (i.tm.opcode_modifier & imulKludge)
{
/* Pretend we saw the 3 operand case. */
i.regs[2] = i.regs[1];
@@ -1345,7 +1342,7 @@ md_assemble (line)
}
/* The clr %reg instruction is converted into xor %reg, %reg. */
- if (t->opcode_modifier & iclrKludge)
+ if (i.tm.opcode_modifier & iclrKludge)
{
i.regs[1] = i.regs[0];
i.reg_operands = 2;
@@ -1356,7 +1353,7 @@ md_assemble (line)
instructions, if the source operand is a register, we must reverse
the i.rm.reg and i.rm.regmem fields. We accomplish this by faking
that the two register operands were given in the reverse order. */
- if ((t->opcode_modifier & ReverseRegRegmem) && i.reg_operands == 2)
+ if ((i.tm.opcode_modifier & ReverseRegRegmem) && i.reg_operands == 2)
{
unsigned int first_reg_operand = (i.types[0] & Reg) ? 0 : 1;
unsigned int second_reg_operand = first_reg_operand + 1;
@@ -1365,40 +1362,40 @@ md_assemble (line)
i.regs[second_reg_operand] = tmp;
}
- if (t->opcode_modifier & ShortForm)
+ if (i.tm.opcode_modifier & ShortForm)
{
/* 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. */
- t->base_opcode |= i.regs[op]->reg_num;
+ i.tm.base_opcode |= i.regs[op]->reg_num;
}
- else if (t->opcode_modifier & ShortFormW)
+ else if (i.tm.opcode_modifier & ShortFormW)
{
/* Short form with 0x8 width bit. Register is always dest. operand */
- t->base_opcode |= i.regs[1]->reg_num;
+ i.tm.base_opcode |= i.regs[1]->reg_num;
if (i.suffix == WORD_OPCODE_SUFFIX ||
i.suffix == DWORD_OPCODE_SUFFIX)
- t->base_opcode |= 0x8;
+ i.tm.base_opcode |= 0x8;
}
- else if (t->opcode_modifier & Seg2ShortForm)
+ else if (i.tm.opcode_modifier & Seg2ShortForm)
{
- if (t->base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1)
+ if (i.tm.base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1)
{
as_bad ("you can't 'pop cs' on the 386.");
return;
}
- t->base_opcode |= (i.regs[0]->reg_num << 3);
+ i.tm.base_opcode |= (i.regs[0]->reg_num << 3);
}
- else if (t->opcode_modifier & Seg3ShortForm)
+ else if (i.tm.opcode_modifier & Seg3ShortForm)
{
/* 'push %fs' is 0x0fa0; 'pop %fs' is 0x0fa1.
'push %gs' is 0x0fa8; 'pop %fs' is 0x0fa9.
So, only if i.regs[0]->reg_num == 5 (%gs) do we need
to change the opcode. */
if (i.regs[0]->reg_num == 5)
- t->base_opcode |= 0x08;
+ i.tm.base_opcode |= 0x08;
}
- else if ((t->base_opcode & ~DW) == MOV_AX_DISP32)
+ else if ((i.tm.base_opcode & ~DW) == MOV_AX_DISP32)
{
/* This is a special non-modrm instruction
that addresses memory with a 32-bit displacement mode anyway,
@@ -1406,12 +1403,12 @@ md_assemble (line)
uses_mem_addrmode = 1;
default_seg = &ds;
}
- else if (t->opcode_modifier & Modrm)
+ else if (i.tm.opcode_modifier & Modrm)
{
- /* The opcode is completed (modulo t->extension_opcode which must
- be put into the modrm byte.
- Now, we make the modrm & index base bytes based on all the info
- we've collected. */
+ /* The opcode is completed (modulo i.tm.extension_opcode which
+ must be put into the modrm byte).
+ Now, we make the modrm & index base bytes based on all the
+ info we've collected. */
/* i.reg_operands MUST be the number of real register operands;
implicit registers do not count. */
@@ -1564,10 +1561,10 @@ md_assemble (line)
}
/* Fill in i.rm.reg or i.rm.regmem field with register
- operand (if any) based on
- t->extension_opcode. Again, we must be careful to
- make sure that segment/control/debug/test/MMX
- registers are coded into the i.rm.reg field. */
+ operand (if any) based on i.tm.extension_opcode.
+ Again, we must be careful to make sure that
+ segment/control/debug/test/MMX registers are coded
+ into the i.rm.reg field. */
if (i.reg_operands)
{
unsigned int op =
@@ -1582,7 +1579,7 @@ md_assemble (line)
: 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)
+ if (i.tm.extension_opcode != None)
i.rm.regmem = i.regs[op]->reg_num;
else
i.rm.reg = i.regs[op]->reg_num;
@@ -1595,8 +1592,8 @@ md_assemble (line)
}
/* Fill in i.rm.reg field with extension opcode (if any). */
- if (t->extension_opcode != None)
- i.rm.reg = t->extension_opcode;
+ if (i.tm.extension_opcode != None)
+ i.rm.reg = i.tm.extension_opcode;
}
if (i.rm.mode != 3)
@@ -1637,9 +1634,9 @@ md_assemble (line)
}
/* Handle conversion of 'int $3' --> special int3 insn. */
- if (t->base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3)
+ if (i.tm.base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3)
{
- t->base_opcode = INT3_OPCODE;
+ i.tm.base_opcode = INT3_OPCODE;
i.imm_operands = 0;
}
@@ -1648,7 +1645,7 @@ md_assemble (line)
register char *p;
/* Output jumps. */
- if (t->opcode_modifier & Jump)
+ if (i.tm.opcode_modifier & Jump)
{
unsigned long n = i.disps[0]->X_add_number;
@@ -1658,7 +1655,7 @@ md_assemble (line)
{
p = frag_more (2);
insn_size += 2;
- p[0] = t->base_opcode;
+ p[0] = i.tm.base_opcode;
p[1] = n;
}
else
@@ -1675,7 +1672,7 @@ md_assemble (line)
return;
}
- if (t->base_opcode == JUMP_PC_RELATIVE)
+ if (i.tm.base_opcode == JUMP_PC_RELATIVE)
{ /* pace */
/* unconditional jump */
p = frag_more (1 + jmp_size);
@@ -1689,7 +1686,7 @@ md_assemble (line)
p = frag_more (2 + jmp_size);
insn_size += 2 + jmp_size;
p[0] = TWO_BYTE_OPCODE_ESCAPE;
- p[1] = t->base_opcode + 0x10;
+ p[1] = i.tm.base_opcode + 0x10;
md_number_to_chars (&p[2], (valueT) n, jmp_size);
}
}
@@ -1708,7 +1705,7 @@ md_assemble (line)
frag_grow (7);
p = frag_more (1);
insn_size += 1;
- p[0] = t->base_opcode;
+ p[0] = i.tm.base_opcode;
frag_var (rs_machine_dependent,
6, /* 2 opcode/prefix + 4 displacement */
1,
@@ -1719,9 +1716,9 @@ md_assemble (line)
(offsetT) n, p);
}
}
- else if (t->opcode_modifier & (JumpByte | JumpDword))
+ else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
{
- int size = (t->opcode_modifier & JumpByte) ? 1 : 4;
+ int size = (i.tm.opcode_modifier & JumpByte) ? 1 : 4;
unsigned long n = i.disps[0]->X_add_number;
unsigned char *q;
@@ -1748,8 +1745,8 @@ md_assemble (line)
want to emit WORD_PREFIX_OPCODE, but I am keeping
the old behaviour for safety. */
- if (IS_JUMP_ON_CX_ZERO (t->base_opcode)
- || IS_LOOP_ECX_TIMES (t->base_opcode))
+ if (IS_JUMP_ON_CX_ZERO (i.tm.base_opcode)
+ || IS_LOOP_ECX_TIMES (i.tm.base_opcode))
FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
else
FRAG_APPEND_1_CHAR (WORD_PREFIX_OPCODE);
@@ -1764,9 +1761,9 @@ md_assemble (line)
insn_size += 1;
}
- if (fits_in_unsigned_byte (t->base_opcode))
+ if (fits_in_unsigned_byte (i.tm.base_opcode))
{
- FRAG_APPEND_1_CHAR (t->base_opcode);
+ FRAG_APPEND_1_CHAR (i.tm.base_opcode);
insn_size += 1;
}
else
@@ -1774,8 +1771,8 @@ md_assemble (line)
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++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = i.tm.base_opcode & 0xff;
}
p = frag_more (size);
@@ -1796,7 +1793,7 @@ md_assemble (line)
}
}
- else if (t->opcode_modifier & JumpInterSegment)
+ else if (i.tm.opcode_modifier & JumpInterSegment)
{
if (flag_16bit_code)
{
@@ -1806,7 +1803,7 @@ md_assemble (line)
p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */
insn_size += 1 + 2 + 4;
- p[0] = t->base_opcode;
+ p[0] = i.tm.base_opcode;
if (i.imms[1]->X_op == O_constant)
md_number_to_chars (p + 1, (valueT) i.imms[1]->X_add_number, 4);
else
@@ -1830,39 +1827,39 @@ md_assemble (line)
}
/* Now the opcode; be careful about word order here! */
- if (fits_in_unsigned_byte (t->base_opcode))
+ if (fits_in_unsigned_byte (i.tm.base_opcode))
{
- FRAG_APPEND_1_CHAR (t->base_opcode);
+ FRAG_APPEND_1_CHAR (i.tm.base_opcode);
insn_size += 1;
}
- else if (fits_in_unsigned_word (t->base_opcode))
+ else if (fits_in_unsigned_word (i.tm.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;
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = i.tm.base_opcode & 0xff;
}
else
{ /* opcode is either 3 or 4 bytes */
- if (t->base_opcode & 0xff000000)
+ if (i.tm.base_opcode & 0xff000000)
{
p = frag_more (4);
insn_size += 4;
- *p++ = (t->base_opcode >> 24) & 0xff;
+ *p++ = (i.tm.base_opcode >> 24) & 0xff;
}
else
{
p = frag_more (3);
insn_size += 3;
}
- *p++ = (t->base_opcode >> 16) & 0xff;
- *p++ = (t->base_opcode >> 8) & 0xff;
- *p = (t->base_opcode) & 0xff;
+ *p++ = (i.tm.base_opcode >> 16) & 0xff;
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = (i.tm.base_opcode) & 0xff;
}
/* Now the modrm byte and base index byte (if present). */
- if (t->opcode_modifier & Modrm)
+ if (i.tm.opcode_modifier & Modrm)
{
p = frag_more (1);
insn_size += 1;
@@ -2193,7 +2190,7 @@ i386_operand (operand_string)
i.mem_operands++;
/* Determine type of memory operand from opcode_suffix;
- no opcode suffix implies general memory references. */
+ no opcode suffix implies general memory references. */
switch (i.suffix)
{
case BYTE_OPCODE_SUFFIX: