pt (x->types[i]);
fprintf (stdout, "\n");
if (x->types[i]
- & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX))
+ & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM))
fprintf (stdout, "%s\n", x->regs[i]->reg_name);
if (x->types[i] & Imm)
pe (x->imms[i]);
{ Acc, "Acc" },
{ JumpAbsolute, "Jump Absolute" },
{ RegMMX, "rMMX" },
+ { RegXMM, "rXMM" },
{ EsSeg, "es" },
{ 0, "" }
};
&& (strncmp (mnemonic, "fsub", 4) !=0)
&& (strncmp (mnemonic, "fdiv", 4) !=0))
{
- const reg_entry *temp_reg;
- expressionS *temp_disp;
- expressionS *temp_imm;
+ const reg_entry *temp_reg = NULL;
+ expressionS *temp_disp = NULL;
+ expressionS *temp_imm = NULL;
unsigned int temp_type;
- int xchg1, xchg2;
+ int xchg1 = 0;
+ int xchg2 = 0;
if (i.operands == 2)
{
continue;
}
/* Any other register is bad */
- if (i.types[op] & (Reg | RegMMX | Control | Debug | Test
- | FloatReg | FloatAcc | SReg2 | SReg3))
+ if (i.types[op] & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test
+ | FloatReg | FloatAcc))
{
as_bad (_("`%%%s' not allowed with `%s%c'"),
i.regs[op]->reg_name,
}
}
- if (i.tm.base_opcode == AMD_3DNOW_OPCODE)
+ if (i.tm.opcode_modifier & ImmExt)
{
- /* These AMD specific instructions have an opcode suffix which
- is coded in the same place as an 8-bit immediate field
- would be. Here we fake an 8-bit immediate operand from the
- opcode suffix stored in tm.extension_opcode. */
+ /* These AMD 3DNow! and Intel Katmai New Instructions have an
+ opcode suffix which is coded in the same place as an 8-bit
+ immediate field would be. Here we fake an 8-bit immediate
+ operand from the opcode suffix stored in tm.extension_opcode. */
expressionS *exp;
{
unsigned int source, dest;
source = ((i.types[0]
- & (Reg
- | SReg2
- | SReg3
- | Control
- | Debug
- | Test
- | RegMMX))
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
? 0 : 1);
dest = source + 1;
- /* Certain instructions expect the destination to be
- in the i.rm.reg field. This is by far the
- exceptional case. For these instructions, if the
- source operand is a register, we must reverse the
- i.rm.reg and i.rm.regmem fields. We accomplish
- this by pretending that the two register operands
- were given in the reverse order. */
- if (i.tm.opcode_modifier & ReverseRegRegmem)
- {
- const reg_entry *tmp = i.regs[source];
- i.regs[source] = i.regs[dest];
- i.regs[dest] = tmp;
- }
-
i.rm.mode = 3;
- /* We must be careful to make sure that all
- segment/control/test/debug/MMX registers go into
- the i.rm.reg field (despite whether they are
- source or destination operands). */
- if (i.regs[dest]->reg_type
- & (SReg2 | SReg3 | Control | Debug | Test | RegMMX))
+ /* One of the register operands will be encoded in the
+ i.tm.reg field, the other in the combined i.tm.mode
+ and i.tm.regmem fields. If no form of this
+ instruction supports a memory destination operand,
+ then we assume the source operand may sometimes be
+ a memory operand and so we need to store the
+ 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;
{
unsigned int op =
((i.types[0]
- & (Reg | SReg2 | SReg3 | Control | Debug
- | Test | RegMMX))
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
? 0
: ((i.types[1]
- & (Reg | SReg2 | SReg3 | Control | Debug
- | Test | RegMMX))
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
? 1
: 2));
/* If there is an extension opcode to put here, the
&& GOT_symbol == i.imms[n]->X_add_symbol
&& (i.imms[n]->X_op == O_symbol
|| (i.imms[n]->X_op == O_add
- && (i.imms[n]->X_op_symbol->sy_value.X_op
+ && ((symbol_get_value_expression
+ (i.imms[n]->X_op_symbol)->X_op)
== O_subtract))))
{
r_type = BFD_RELOC_386_GOTPC;
if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
{
- as_bad (_ ("only 1 or 2 immediate operands are allowed"));
+ as_bad (_("Only 1 or 2 immediate operands are allowed"));
return 0;
}
save_input_line_pointer = input_line_pointer;
input_line_pointer = imm_start;
+
+#ifndef LEX_AT
+ {
+ /*
+ * We can have operands of the form
+ * <symbol>@GOTOFF+<nnn>
+ * Take the easy way out here and copy everything
+ * into a temporary buffer...
+ */
+ register char *cp;
+
+ cp = strchr (input_line_pointer, '@');
+ if (cp != NULL)
+ {
+ char *tmpbuf;
+ int len = 0;
+ int first;
+
+ /* GOT relocations are not supported in 16 bit mode */
+ if (flag_16bit_code)
+ as_bad (_("GOT relocations not supported in 16 bit mode"));
+
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+
+ if (strncmp (cp + 1, "PLT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
+ len = 3;
+ }
+ else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
+ len = 6;
+ }
+ else if (strncmp (cp + 1, "GOT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
+ len = 3;
+ }
+ else
+ as_bad (_("Bad reloc specifier in expression"));
+
+ /* Replace the relocation token with ' ', so that errors like
+ foo@GOTOFF1 will be detected. */
+ first = cp - input_line_pointer;
+ tmpbuf = (char *) alloca (strlen(input_line_pointer));
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ strcpy (tmpbuf + first + 1, cp + 1 + len);
+ input_line_pointer = tmpbuf;
+ }
+ }
+#endif
+
exp_seg = expression (exp);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer)
+ as_bad (_("Ignoring junk `%s' after expression"), input_line_pointer);
+
input_line_pointer = save_input_line_pointer;
if (exp->X_op == O_absent)
{
/* missing or bad expr becomes absolute 0 */
- as_bad (_ ("missing or invalid immediate expression `%s' taken as 0"),
+ as_bad (_("Missing or invalid immediate expression `%s' taken as 0"),
imm_start);
- exp->X_op = O_constant;
- exp->X_add_number = 0;
- exp->X_add_symbol = (symbolS *) 0;
- exp->X_op_symbol = (symbolS *) 0;
- i.types[this_operand] |= Imm;
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ i.types[this_operand] |= Imm;
}
else if (exp->X_op == O_constant)
{
i.types[this_operand] |=
- smallest_imm_type ((long) exp->X_add_number);
+ smallest_imm_type ((long) exp->X_add_number);
/* If a suffix is given, this operand may be shortended. */
switch (i.suffix)
#endif
)
{
- seg_unimplemented:
- as_bad (_ ("Unimplemented segment type %d in operand"), exp_seg);
- return 0;
+ as_bad (_("Unimplemented segment type %d in operand"), exp_seg);
+ return 0;
}
#endif
else
suffix, or the default for the section. We exclude
Imm8S here so that `push $foo' and other instructions
with an Imm8S form will use Imm16 or Imm32. */
- i.types[this_operand] |= (Imm8 | Imm16 | Imm32);
+ i.types[this_operand] |= (Imm8 | Imm16 | Imm32);
}
return 1;
-
}
static int i386_scale PARAMS ((char *));
i.log2_scale_factor = 0;
#endif
}
+ return 1;
}
static int i386_displacement PARAMS ((char *, char *));
cp = strchr (input_line_pointer, '@');
if (cp != NULL)
{
- char *tmpbuf;
-
- if (GOT_symbol == NULL)
- GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+ char *tmpbuf;
+ int len = 0;
+ int first;
- tmpbuf = (char *) alloca ((cp - input_line_pointer) + 20);
-
- if (strncmp (cp + 1, "PLT", 3) == 0)
- {
- i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
- *cp = '\0';
- strcpy (tmpbuf, input_line_pointer);
- strcat (tmpbuf, cp + 1 + 3);
- *cp = '@';
- }
- else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
- {
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
- *cp = '\0';
- strcpy (tmpbuf, input_line_pointer);
- strcat (tmpbuf, cp + 1 + 6);
- *cp = '@';
- }
- else if (strncmp (cp + 1, "GOT", 3) == 0)
- {
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
- *cp = '\0';
- strcpy (tmpbuf, input_line_pointer);
- strcat (tmpbuf, cp + 1 + 3);
- *cp = '@';
- }
- else
- as_bad (_("Bad reloc specifier `%s' in expression"), cp + 1);
+ /* GOT relocations are not supported in 16 bit mode */
+ if (flag_16bit_code)
+ as_bad (_("GOT relocations not supported in 16 bit mode"));
- /* GOT relocations are not supported in 16 bit mode */
- if (flag_16bit_code)
- as_bad (_("GOT relocations not supported in 16 bit mode"));
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
- input_line_pointer = tmpbuf;
- }
+ if (strncmp (cp + 1, "PLT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
+ len = 3;
+ }
+ else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
+ len = 6;
+ }
+ else if (strncmp (cp + 1, "GOT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
+ len = 3;
+ }
+ else
+ as_bad (_("Bad reloc specifier in expression"));
+
+ /* Replace the relocation token with ' ', so that errors like
+ foo@GOTOFF1 will be detected. */
+ first = cp - input_line_pointer;
+ tmpbuf = (char *) alloca (strlen(input_line_pointer));
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ strcpy (tmpbuf + first + 1, cp + 1 + len);
+ input_line_pointer = tmpbuf;
+ }
}
#endif
{
if (S_IS_LOCAL(exp->X_add_symbol)
&& S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
- section_symbol(exp->X_add_symbol->bsym->section);
+ section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
assert (exp->X_op == O_symbol);
exp->X_op = O_subtract;
exp->X_op_symbol = GOT_symbol;
}
#endif
+ SKIP_WHITESPACE ();
if (*input_line_pointer)
as_bad (_("Ignoring junk `%s' after expression"),
input_line_pointer);
char *temp_string = (char *) malloc (strlen (op_string) + 1);
char *end_of_operand_string;
char *tc;
- char *temp_disp, *temp_disp2;
+ char *temp_disp;
temp_string[0] = '\0';
tc = end_of_operand_string = strchr (op_string, '[');
if (is_space_char (*temp_string))
++temp_string;
if (*temp_string == REGISTER_PREFIX
- || allow_naked_reg && i386_is_reg (temp_string))
+ || (allow_naked_reg && i386_is_reg (temp_string)))
++op_string;
}
if (*op_string == REGISTER_PREFIX
- || allow_naked_reg && i386_is_reg (op_string))
+ || (allow_naked_reg && i386_is_reg (op_string)))
{
const reg_entry *temp_reg;
char *end_op;
int got_a_float;
{
char *op_string = operand_string;
- char *end_of_operand_string;
int operand_modifier = i386_operand_modifier (&op_string, got_a_float);
if (is_space_char (*op_string))
i.mem_operands++;
break;
- case SHORT:
-
case FLAT:
case OFFSET_FLAT:
return 0;
break;
+ case SHORT:
+
case NONE_FOUND:
/* Should be register or immediate */
if (is_digit_char (*op_string)
char *end_of_operand_string;
register char *base_string;
int found_base_index_form;
- int operand_modifier;
/* Start and end of displacement string expression (if found). */
- char *displacement_string_start;
- char *displacement_string_end;
+ char *displacement_string_start = NULL;
+ char *displacement_string_end = NULL;
do_memory_reference:
++base_string;
if (*base_string == REGISTER_PREFIX
- || allow_naked_reg && i386_is_reg (base_string))
+ || (allow_naked_reg && i386_is_reg (base_string)))
{
char *end_op;
#else
void
md_convert_frag (abfd, sec, fragP)
- bfd *abfd;
- segT sec;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ segT sec ATTRIBUTE_UNUSED;
register fragS *fragP;
#endif
{
/* Address we want to reach in file space. */
target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
#ifdef BFD_ASSEMBLER /* not needed otherwise? */
- target_address += fragP->fr_symbol->sy_frag->fr_address;
+ target_address += symbol_get_frag (fragP->fr_symbol)->fr_address;
#endif
/* Address opcode resides at in file space. */
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
- fragS *frag;
- symbolS *to_symbol;
+ fragS *frag ATTRIBUTE_UNUSED;
+ symbolS *to_symbol ATTRIBUTE_UNUSED;
{
long offset;
register char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
valueT value = *valp;
- if (fixP->fx_r_type == BFD_RELOC_32 && fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_32_PCREL;
-
#if defined (BFD_ASSEMBLER) && !defined (TE_Mach)
+ if (fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_8_PCREL;
+ break;
+ }
+ }
+
/*
* This is a hack. There should be a better way to
* handle this.
*/
- if (fixP->fx_r_type == BFD_RELOC_32_PCREL && fixP->fx_addsy)
+ if ((fixP->fx_r_type == BFD_RELOC_32_PCREL
+ || fixP->fx_r_type == BFD_RELOC_16_PCREL
+ || fixP->fx_r_type == BFD_RELOC_8_PCREL)
+ && fixP->fx_addsy)
{
#ifndef OBJ_AOUT
if (OUTPUT_FLAVOR == bfd_target_elf_flavour
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
if (OUTPUT_FLAVOR == bfd_target_elf_flavour
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg
- || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+ || symbol_section_p (fixP->fx_addsy))
&& ! S_IS_EXTERNAL (fixP->fx_addsy)
&& ! S_IS_WEAK (fixP->fx_addsy)
&& S_IS_DEFINED (fixP->fx_addsy)
default:
break;
}
-#endif
-
-#endif
+#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
+ *valp = value;
+#endif /* defined (BFD_ASSEMBLER) && !defined (TE_Mach) */
md_number_to_chars (p, value, fixP->fx_size);
return 1;
int
md_parse_option (c, arg)
int c;
- char *arg;
+ char *arg ATTRIBUTE_UNUSED;
{
switch (c)
{
/* Round up a section size to the appropriate boundary. */
valueT
md_section_align (segment, size)
- segT segment;
+ segT segment ATTRIBUTE_UNUSED;
valueT size;
{
#ifdef OBJ_AOUT
static void
s_bss (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
register int temp;
}
}
-#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
-#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
-
arelent *
tc_gen_reloc (section, fixp)
- asection *section;
+ asection *section ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *rel;
code = fixp->fx_r_type;
break;
default:
- switch (F (fixp->fx_size, fixp->fx_pcrel))
+ if (fixp->fx_pcrel)
{
- MAP (1, 0, BFD_RELOC_8);
- MAP (2, 0, BFD_RELOC_16);
- MAP (4, 0, BFD_RELOC_32);
- MAP (1, 1, BFD_RELOC_8_PCREL);
- MAP (2, 1, BFD_RELOC_16_PCREL);
- MAP (4, 1, BFD_RELOC_32_PCREL);
- default:
- if (fixp->fx_pcrel)
- as_bad (_("Can not do %d byte pc-relative relocation"),
- fixp->fx_size);
- else
- as_bad (_("Can not do %d byte relocation"), fixp->fx_size);
- code = BFD_RELOC_32;
- break;
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad (_("Can not do %d byte pc-relative relocation"),
+ fixp->fx_size);
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case 1: code = BFD_RELOC_8_PCREL; break;
+ case 2: code = BFD_RELOC_16_PCREL; break;
+ case 4: code = BFD_RELOC_32_PCREL; break;
+ }
+ }
+ else
+ {
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad (_("Can not do %d byte relocation"), fixp->fx_size);
+ code = BFD_RELOC_32;
+ break;
+ case 1: code = BFD_RELOC_8; break;
+ case 2: code = BFD_RELOC_16; break;
+ case 4: code = BFD_RELOC_32; break;
+ }
}
break;
}
-#undef MAP
-#undef F
if (code == BFD_RELOC_32
&& GOT_symbol
code = BFD_RELOC_386_GOTPC;
rel = (arelent *) xmalloc (sizeof (arelent));
- rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
/* HACK: Since i386 ELF uses Rel instead of Rela, encode the
#endif /* I386COFF */
-#endif /* BFD_ASSEMBLER? */
+#endif /* ! BFD_ASSEMBLER */
\f
/* end of tc-i386.c */