* config/tc-i386.c: Add INFER_ADDR_PREFIX code. Fix 16 bit mode nop.

This commit is contained in:
Alan Modra
1999-08-03 05:47:26 +00:00
parent a0b3c4fd32
commit c3332e24e8
2 changed files with 440 additions and 399 deletions

View File

@ -1,3 +1,12 @@
1999-08-03 Etienne Lorrain <etienne.lorrain@ibm.net>
* config/tc-i386.c (f16_3): New. Fixes 16 bit 3 byte nop.
1999-08-03 Alan Modra <alan@spri.levels.unisa.edu.au>
* config/tc-i386.c (i386_operand): Add INFER_ADDR_PREFIX code, but
don't enable it by default. White space changes.
1999-07-30 Jakub Jelinek <jj@ultra.linux.cz> 1999-07-30 Jakub Jelinek <jj@ultra.linux.cz>
* config/tc-sparc.c (md_longopts): Add --no-undeclared-regs option. * config/tc-sparc.c (md_longopts): Add --no-undeclared-regs option.

View File

@ -40,6 +40,10 @@
#define REGISTER_WARNINGS 1 #define REGISTER_WARNINGS 1
#endif #endif
#ifndef INFER_ADDR_PREFIX
#define INFER_ADDR_PREFIX 0
#endif
#ifndef SCALE1_WHEN_NO_INDEX #ifndef SCALE1_WHEN_NO_INDEX
/* Specifying a scale factor besides 1 when there is no index is /* Specifying a scale factor besides 1 when there is no index is
futile. eg. `mov (%ebx,2),%al' does exactly the same as futile. eg. `mov (%ebx,2),%al' does exactly the same as
@ -343,6 +347,8 @@ i386_align_code (fragP, count)
static const char f32_15[] = static const char f32_15[] =
{0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */ {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
static const char f16_3[] =
{0x8d,0x74,0x00}; /* lea 0(%esi),%esi */
static const char f16_4[] = static const char f16_4[] =
{0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
static const char f16_5[] = static const char f16_5[] =
@ -362,7 +368,7 @@ i386_align_code (fragP, count)
f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15 f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
}; };
static const char *const f16_patt[] = { static const char *const f16_patt[] = {
f32_1, f32_2, f32_3, f16_4, f16_5, f16_6, f16_7, f16_8, f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8,
f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15 f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15
}; };
@ -3241,71 +3247,71 @@ i386_intel_operand (operand_string, got_a_float)
case SHORT: case SHORT:
case NONE_FOUND: case NONE_FOUND:
/* Should be register or immediate */ /* Should be register or immediate */
if (is_digit_char (*op_string) if (is_digit_char (*op_string)
&& strchr (op_string, '[') == 0) && strchr (op_string, '[') == 0)
{ {
if (!i386_immediate (op_string)) if (!i386_immediate (op_string))
return 0; return 0;
} }
else if (*op_string == REGISTER_PREFIX else if (*op_string == REGISTER_PREFIX
|| (allow_naked_reg || (allow_naked_reg
&& i386_is_reg (op_string))) && i386_is_reg (op_string)))
{ {
register const reg_entry * r; register const reg_entry * r;
char *end_op; char *end_op;
r = parse_register (op_string, &end_op); r = parse_register (op_string, &end_op);
if (r == NULL) if (r == NULL)
return 0; return 0;
/* Check for a segment override by searching for ':' after a /* Check for a segment override by searching for ':' after a
segment register. */ segment register. */
op_string = end_op; op_string = end_op;
if (is_space_char (*op_string)) if (is_space_char (*op_string))
++op_string; ++op_string;
if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3))) if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
{ {
switch (r->reg_num) switch (r->reg_num)
{ {
case 0: case 0:
i.seg[i.mem_operands] = &es; i.seg[i.mem_operands] = &es;
break; break;
case 1: case 1:
i.seg[i.mem_operands] = &cs; i.seg[i.mem_operands] = &cs;
break; break;
case 2: case 2:
i.seg[i.mem_operands] = &ss; i.seg[i.mem_operands] = &ss;
break; break;
case 3: case 3:
i.seg[i.mem_operands] = &ds; i.seg[i.mem_operands] = &ds;
break; break;
case 4: case 4:
i.seg[i.mem_operands] = &fs; i.seg[i.mem_operands] = &fs;
break; break;
case 5: case 5:
i.seg[i.mem_operands] = &gs; i.seg[i.mem_operands] = &gs;
break; break;
} }
} }
i.types[this_operand] |= r->reg_type & ~BaseIndex; i.types[this_operand] |= r->reg_type & ~BaseIndex;
i.regs[this_operand] = r; i.regs[this_operand] = r;
i.reg_operands++; i.reg_operands++;
} }
else else
{ {
if (!i386_intel_memory_operand (op_string)) if (!i386_intel_memory_operand (op_string))
return 0; return 0;
i.mem_operands++; i.mem_operands++;
} }
break; break;
} /* end switch */ } /* end switch */
/* Special case for (%dx) while doing input/output op. */ /* Special case for (%dx) while doing input/output op. */
if (i.base_reg if (i.base_reg
&& i.base_reg->reg_type == (Reg16 | InOutPortReg) && i.base_reg->reg_type == (Reg16 | InOutPortReg)
@ -3313,42 +3319,42 @@ i386_intel_operand (operand_string, got_a_float)
&& i.log2_scale_factor == 0 && i.log2_scale_factor == 0
&& i.seg[i.mem_operands] == 0 && i.seg[i.mem_operands] == 0
&& (i.types[this_operand] & Disp) == 0) && (i.types[this_operand] & Disp) == 0)
{ {
i.types[this_operand] = InOutPortReg; i.types[this_operand] = InOutPortReg;
return 1; return 1;
} }
/* Make sure the memory operand we've been dealt is valid. */ /* Make sure the memory operand we've been dealt is valid. */
if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0)) if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
{ {
if ((i.base_reg if ((i.base_reg
&& ((i.base_reg->reg_type & (Reg16|BaseIndex)) && ((i.base_reg->reg_type & (Reg16|BaseIndex))
!= (Reg16|BaseIndex))) != (Reg16|BaseIndex)))
|| (i.index_reg || (i.index_reg
&& (((i.index_reg->reg_type & (Reg16|BaseIndex)) && (((i.index_reg->reg_type & (Reg16|BaseIndex))
!= (Reg16|BaseIndex)) != (Reg16|BaseIndex))
|| ! (i.base_reg || ! (i.base_reg
&& i.base_reg->reg_num < 6 && i.base_reg->reg_num < 6
&& i.index_reg->reg_num >= 6 && i.index_reg->reg_num >= 6
&& i.log2_scale_factor == 0)))) && i.log2_scale_factor == 0))))
{
as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "16");
return 0;
}
}
else
{ {
if ((i.base_reg as_bad (_("`%s' is not a valid %s bit base/index expression"),
&& (i.base_reg->reg_type & Reg32) == 0) operand_string, "16");
|| (i.index_reg return 0;
&& ((i.index_reg->reg_type & (Reg32|BaseIndex))
!= (Reg32|BaseIndex))))
{
as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "32");
return 0;
}
} }
}
else
{
if ((i.base_reg
&& (i.base_reg->reg_type & Reg32) == 0)
|| (i.index_reg
&& ((i.index_reg->reg_type & (Reg32|BaseIndex))
!= (Reg32|BaseIndex))))
{
as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "32");
return 0;
}
}
return 1; return 1;
} }
@ -3361,335 +3367,361 @@ static int
i386_operand (operand_string) i386_operand (operand_string)
char *operand_string; char *operand_string;
{ {
char *op_string = operand_string; char *op_string = operand_string;
if (is_space_char (*op_string)) if (is_space_char (*op_string))
++op_string; ++op_string;
/* We check for an absolute prefix (differentiating, /* We check for an absolute prefix (differentiating,
for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
if (*op_string == ABSOLUTE_PREFIX) if (*op_string == ABSOLUTE_PREFIX)
{ {
++op_string; ++op_string;
if (is_space_char (*op_string)) if (is_space_char (*op_string))
++op_string; ++op_string;
i.types[this_operand] |= JumpAbsolute; i.types[this_operand] |= JumpAbsolute;
} }
/* Check if operand is a register. */ /* Check if operand is a register. */
if (*op_string == REGISTER_PREFIX if (*op_string == REGISTER_PREFIX
|| (allow_naked_reg && i386_is_reg (op_string))) || (allow_naked_reg && i386_is_reg (op_string)))
{ {
register const reg_entry *r; register const reg_entry *r;
char *end_op; char *end_op;
r = parse_register (op_string, &end_op); r = parse_register (op_string, &end_op);
if (r == NULL) if (r == NULL)
return 0; return 0;
/* Check for a segment override by searching for ':' after a /* Check for a segment override by searching for ':' after a
segment register. */ segment register. */
op_string = end_op; op_string = end_op;
if (is_space_char (*op_string)) if (is_space_char (*op_string))
++op_string; ++op_string;
if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3))) if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
{ {
switch (r->reg_num) switch (r->reg_num)
{ {
case 0: case 0:
i.seg[i.mem_operands] = &es; i.seg[i.mem_operands] = &es;
break; break;
case 1: case 1:
i.seg[i.mem_operands] = &cs; i.seg[i.mem_operands] = &cs;
break; break;
case 2: case 2:
i.seg[i.mem_operands] = &ss; i.seg[i.mem_operands] = &ss;
break; break;
case 3: case 3:
i.seg[i.mem_operands] = &ds; i.seg[i.mem_operands] = &ds;
break; break;
case 4: case 4:
i.seg[i.mem_operands] = &fs; i.seg[i.mem_operands] = &fs;
break; break;
case 5: case 5:
i.seg[i.mem_operands] = &gs; i.seg[i.mem_operands] = &gs;
break; break;
} }
/* Skip the ':' and whitespace. */ /* Skip the ':' and whitespace. */
++op_string;
if (is_space_char (*op_string))
++op_string;
/* Pretend given string starts here. */
operand_string = op_string;
if (!is_digit_char (*op_string)
&& !is_identifier_char (*op_string)
&& *op_string != '('
&& *op_string != ABSOLUTE_PREFIX)
{
as_bad (_("bad memory operand `%s'"), op_string);
return 0;
}
/* Handle case of %es:*foo. */
if (*op_string == ABSOLUTE_PREFIX)
{
++op_string; ++op_string;
if (is_space_char (*op_string)) if (is_space_char (*op_string))
++op_string; ++op_string;
i.types[this_operand] |= JumpAbsolute;
}
goto do_memory_reference;
}
if (*op_string)
{
as_bad (_("Junk `%s' after register"), op_string);
return 0;
}
i.types[this_operand] |= r->reg_type & ~BaseIndex;
i.regs[this_operand] = r;
i.reg_operands++;
}
else if (*op_string == IMMEDIATE_PREFIX)
{ /* ... or an immediate */
++op_string;
if (i.types[this_operand] & JumpAbsolute)
{
as_bad (_("Immediate operand illegal with absolute jump"));
return 0;
}
if (!i386_immediate (op_string))
return 0;
}
else if (is_digit_char (*op_string)
|| is_identifier_char (*op_string)
|| *op_string == '(' )
{
/* This is a memory reference of some sort. */
char *end_of_operand_string;
register char *base_string;
int found_base_index_form;
/* Pretend given string starts here. */ /* Start and end of displacement string expression (if found). */
operand_string = op_string; char *displacement_string_start = NULL;
if (!is_digit_char (*op_string) char *displacement_string_end = NULL;
&& !is_identifier_char (*op_string)
&& *op_string != '('
&& *op_string != ABSOLUTE_PREFIX)
{
as_bad (_("bad memory operand `%s'"), op_string);
return 0;
}
/* Handle case of %es:*foo. */
if (*op_string == ABSOLUTE_PREFIX)
{
++op_string;
if (is_space_char (*op_string))
++op_string;
i.types[this_operand] |= JumpAbsolute;
}
goto do_memory_reference;
}
if (*op_string)
{
as_bad (_("Junk `%s' after register"), op_string);
return 0;
}
i.types[this_operand] |= r->reg_type & ~BaseIndex;
i.regs[this_operand] = r;
i.reg_operands++;
}
else if (*op_string == IMMEDIATE_PREFIX)
{ /* ... or an immediate */
++op_string;
if (i.types[this_operand] & JumpAbsolute)
{
as_bad (_("Immediate operand illegal with absolute jump"));
return 0;
}
if (!i386_immediate (op_string))
return 0;
}
else if (is_digit_char (*op_string)
|| is_identifier_char (*op_string)
|| *op_string == '(' )
{
/* This is a memory reference of some sort. */
char *end_of_operand_string;
register char *base_string;
int found_base_index_form;
/* Start and end of displacement string expression (if found). */ do_memory_reference:
char *displacement_string_start = NULL;
char *displacement_string_end = NULL;
do_memory_reference: if ((i.mem_operands == 1
&& (current_templates->start->opcode_modifier & IsString) == 0)
|| i.mem_operands == 2)
{
as_bad (_("too many memory references for `%s'"),
current_templates->start->name);
return 0;
}
if ((i.mem_operands == 1 /* Check for base index form. We detect the base index form by
&& (current_templates->start->opcode_modifier & IsString) == 0) looking for an ')' at the end of the operand, searching
|| i.mem_operands == 2) for the '(' matching it, and finding a REGISTER_PREFIX or ','
{ after the '('. */
as_bad (_("too many memory references for `%s'"), found_base_index_form = 0;
current_templates->start->name); end_of_operand_string = op_string + strlen (op_string);
return 0;
}
/* Check for base index form. We detect the base index form by --end_of_operand_string;
looking for an ')' at the end of the operand, searching if (is_space_char (*end_of_operand_string))
for the '(' matching it, and finding a REGISTER_PREFIX or ',' --end_of_operand_string;
after the '('. */
found_base_index_form = 0;
end_of_operand_string = op_string + strlen (op_string);
--end_of_operand_string; base_string = end_of_operand_string;
if (is_space_char (*end_of_operand_string))
--end_of_operand_string;
base_string = end_of_operand_string; if (*base_string == ')')
{
unsigned int parens_balanced = 1;
/* We've already checked that the number of left & right ()'s are
equal, so this loop will not be infinite. */
do
{
base_string--;
if (*base_string == ')')
parens_balanced++;
if (*base_string == '(')
parens_balanced--;
}
while (parens_balanced);
if (*base_string == ')') /* If there is a displacement set-up for it to be parsed later. */
{ displacement_string_start = op_string;
unsigned int parens_balanced = 1; displacement_string_end = base_string;
/* We've already checked that the number of left & right ()'s are
equal, so this loop will not be infinite. */
do
{
base_string--;
if (*base_string == ')')
parens_balanced++;
if (*base_string == '(')
parens_balanced--;
}
while (parens_balanced);
/* If there is a displacement set-up for it to be parsed later. */ /* Skip past '(' and whitespace. */
displacement_string_start = op_string; ++base_string;
displacement_string_end = base_string; if (is_space_char (*base_string))
++base_string;
/* Skip past '(' and whitespace. */ if (*base_string == REGISTER_PREFIX
|| (allow_naked_reg && i386_is_reg (base_string))
|| *base_string == ',')
found_base_index_form = 1;
}
/* If we can't parse a base index register expression, we've found
a pure displacement expression. We set up displacement_string_start
and displacement_string_end for the code below. */
if (!found_base_index_form)
{
displacement_string_start = op_string;
displacement_string_end = end_of_operand_string + 1;
}
else
{
i.types[this_operand] |= BaseIndex;
/* Find base register (if any). */
if (*base_string != ',')
{
char *end_op;
/* Trim off the closing ')' so that parse_register won't
see it. */
END_STRING_AND_SAVE (end_of_operand_string);
i.base_reg = parse_register (base_string, &end_op);
RESTORE_END_STRING (end_of_operand_string);
if (i.base_reg == NULL)
return 0;
base_string = end_op;
if (is_space_char (*base_string))
++base_string;
}
/* There may be an index reg or scale factor here. */
if (*base_string == ',')
{
++base_string; ++base_string;
if (is_space_char (*base_string)) if (is_space_char (*base_string))
++base_string; ++base_string;
if (*base_string == REGISTER_PREFIX if (*base_string == REGISTER_PREFIX
|| (allow_naked_reg && i386_is_reg (base_string)) || (allow_naked_reg && i386_is_reg (base_string)))
|| *base_string == ',')
found_base_index_form = 1;
}
/* If we can't parse a base index register expression, we've found
a pure displacement expression. We set up displacement_string_start
and displacement_string_end for the code below. */
if (!found_base_index_form)
{
displacement_string_start = op_string;
displacement_string_end = end_of_operand_string + 1;
}
else
{
i.types[this_operand] |= BaseIndex;
/* Find base register (if any). */
if (*base_string != ',')
{ {
char *end_op; char *end_op;
/* Trim off the closing ')' so that parse_register won't END_STRING_AND_SAVE (end_of_operand_string);
see it. */ i.index_reg = parse_register (base_string, &end_op);
END_STRING_AND_SAVE (end_of_operand_string); RESTORE_END_STRING (end_of_operand_string);
i.base_reg = parse_register (base_string, &end_op);
RESTORE_END_STRING (end_of_operand_string);
if (i.base_reg == NULL) if (i.index_reg == NULL)
return 0; return 0;
base_string = end_op; base_string = end_op;
if (is_space_char (*base_string)) if (is_space_char (*base_string))
++base_string; ++base_string;
} if (*base_string == ',')
{
/* There may be an index reg or scale factor here. */
if (*base_string == ',')
{
++base_string;
if (is_space_char (*base_string))
++base_string; ++base_string;
if (is_space_char (*base_string))
if (*base_string == REGISTER_PREFIX ++base_string;
|| (allow_naked_reg && i386_is_reg (base_string))) }
{ else if (*base_string != ')' )
char *end_op; {
as_bad (_("expecting `,' or `)' after index register in `%s'"),
END_STRING_AND_SAVE (end_of_operand_string); operand_string);
i.index_reg = parse_register (base_string, &end_op); return 0;
RESTORE_END_STRING (end_of_operand_string); }
if (i.index_reg == NULL)
return 0;
base_string = end_op;
if (is_space_char (*base_string))
++base_string;
if (*base_string == ',')
{
++base_string;
if (is_space_char (*base_string))
++base_string;
}
else if (*base_string != ')' )
{
as_bad (_("expecting `,' or `)' after index register in `%s'"),
operand_string);
return 0;
}
}
/* Check for scale factor. */
if (isdigit ((unsigned char) *base_string))
{
if (!i386_scale (base_string))
return 0;
++base_string;
if (is_space_char (*base_string))
++base_string;
if (*base_string != ')')
{
as_bad (_("expecting `)' after scale factor in `%s'"),
operand_string);
return 0;
}
}
else if (!i.index_reg)
{
as_bad (_("expecting index register or scale factor after `,'; got '%c'"),
*base_string);
return 0;
}
} }
else if (*base_string != ')')
/* Check for scale factor. */
if (isdigit ((unsigned char) *base_string))
{ {
as_bad (_("expecting `,' or `)' after base register in `%s'"), if (!i386_scale (base_string))
operand_string); return 0;
return 0;
}
}
/* If there's an expression beginning the operand, parse it, ++base_string;
assuming displacement_string_start and if (is_space_char (*base_string))
displacement_string_end are meaningful. */ ++base_string;
if (displacement_string_start != displacement_string_end) if (*base_string != ')')
{ {
if (!i386_displacement (displacement_string_start, as_bad (_("expecting `)' after scale factor in `%s'"),
displacement_string_end)) operand_string);
return 0; return 0;
} }
}
else if (!i.index_reg)
{
as_bad (_("expecting index register or scale factor after `,'; got '%c'"),
*base_string);
return 0;
}
}
else if (*base_string != ')')
{
as_bad (_("expecting `,' or `)' after base register in `%s'"),
operand_string);
return 0;
}
}
/* Special case for (%dx) while doing input/output op. */ /* If there's an expression beginning the operand, parse it,
if (i.base_reg assuming displacement_string_start and
&& i.base_reg->reg_type == (Reg16 | InOutPortReg) displacement_string_end are meaningful. */
&& i.index_reg == 0 if (displacement_string_start != displacement_string_end)
&& i.log2_scale_factor == 0 {
&& i.seg[i.mem_operands] == 0 if (!i386_displacement (displacement_string_start,
&& (i.types[this_operand] & Disp) == 0) displacement_string_end))
{ return 0;
i.types[this_operand] = InOutPortReg; }
return 1;
} /* Special case for (%dx) while doing input/output op. */
/* Make sure the memory operand we've been dealt is valid. */ if (i.base_reg
if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0)) && i.base_reg->reg_type == (Reg16 | InOutPortReg)
{ && i.index_reg == 0
if ((i.base_reg && i.log2_scale_factor == 0
&& ((i.base_reg->reg_type & (Reg16|BaseIndex)) && i.seg[i.mem_operands] == 0
!= (Reg16|BaseIndex))) && (i.types[this_operand] & Disp) == 0)
|| (i.index_reg {
&& (((i.index_reg->reg_type & (Reg16|BaseIndex)) i.types[this_operand] = InOutPortReg;
!= (Reg16|BaseIndex)) return 1;
|| ! (i.base_reg }
&& i.base_reg->reg_num < 6 /* Make sure the memory operand we've been dealt is valid. */
&& i.index_reg->reg_num >= 6 if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
&& i.log2_scale_factor == 0)))) {
#if INFER_ADDR_PREFIX
try16:
#endif
if ((i.base_reg
&& ((i.base_reg->reg_type & (Reg16|BaseIndex))
!= (Reg16|BaseIndex)))
|| (i.index_reg
&& (((i.index_reg->reg_type & (Reg16|BaseIndex))
!= (Reg16|BaseIndex))
|| ! (i.base_reg
&& i.base_reg->reg_num < 6
&& i.index_reg->reg_num >= 6
&& i.log2_scale_factor == 0))))
{
#if INFER_ADDR_PREFIX
if (i.prefix[ADDR_PREFIX] == 0)
{ {
as_bad (_("`%s' is not a valid %s bit base/index expression"), i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
operand_string, "16"); goto try32;
return 0;
} }
} else
else #endif
{
if ((i.base_reg
&& (i.base_reg->reg_type & Reg32) == 0)
|| (i.index_reg
&& ((i.index_reg->reg_type & (Reg32|BaseIndex))
!= (Reg32|BaseIndex))))
{ {
as_bad (_("`%s' is not a valid %s bit base/index expression"), as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "32"); operand_string, "16");
return 0; return 0;
} }
} }
i.mem_operands++; }
} else
else {
{ /* it's not a memory operand; argh! */ #if INFER_ADDR_PREFIX
as_bad (_("invalid char %s beginning operand %d `%s'"), try32:
output_invalid (*op_string), #endif
this_operand + 1, if ((i.base_reg
op_string); && (i.base_reg->reg_type & Reg32) == 0)
return 0; || (i.index_reg
} && ((i.index_reg->reg_type & (Reg32|BaseIndex))
return 1; /* normal return */ != (Reg32|BaseIndex))))
{
#if INFER_ADDR_PREFIX
if (i.prefix[ADDR_PREFIX] == 0)
{
i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
goto try16;
}
else
#endif
{
as_bad (_("`%s' is not a valid %s bit base/index expression"),
operand_string, "32");
return 0;
}
}
}
i.mem_operands++;
}
else
{ /* it's not a memory operand; argh! */
as_bad (_("invalid char %s beginning operand %d `%s'"),
output_invalid (*op_string),
this_operand + 1,
op_string);
return 0;
}
return 1; /* normal return */
} }
/* /*