/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
Contributed by Carnegie Mellon University, 1993.
Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
Modified by Ken Raeburn for gas-2.x and ECOFF support.
#ifdef OBJ_EVAX
#include "vms.h"
+#include "vms/egps.h"
#endif
#include "dwarf2dbg.h"
#define MAX_INSN_FIXUPS 2
#define MAX_INSN_ARGS 5
+/* Used since new relocation types are introduced in this
+ file (DUMMY_RELOC_LITUSE_*) */
+typedef int extended_bfd_reloc_code_real_type;
+
struct alpha_fixup
{
expressionS exp;
- bfd_reloc_code_real_type reloc;
+ /* bfd_reloc_code_real_type reloc; */
+ extended_bfd_reloc_code_real_type reloc;
#ifdef OBJ_EVAX
- symbolS *xtrasym, *procsym;
+ /* The symbol of the item in the linkage section. */
+ symbolS *xtrasym;
+
+ /* The symbol of the procedure descriptor. */
+ symbolS *procsym;
#endif
};
#undef AXP_REG_GP
#define AXP_REG_GP AXP_REG_PV
-static struct hash_control *alpha_evax_proc_hash;
-
#endif /* OBJ_EVAX */
/* The cpu for which we are generating code. */
and the section happens to not be on an eight byte boundary, it
will align both the symbol and the .quad to an eight byte boundary. */
static symbolS *alpha_insn_label;
-#ifdef OBJ_ELF
+#if defined(OBJ_ELF) || defined (OBJ_EVAX)
static symbolS *alpha_prologue_label;
#endif
int handler_data;
};
+/* Linked list of .linkage fixups. */
struct alpha_linkage_fixups *alpha_linkage_fixup_root;
static struct alpha_linkage_fixups *alpha_linkage_fixup_tail;
+/* Current procedure descriptor. */
static struct alpha_evax_procs *alpha_evax_proc;
+static struct alpha_evax_procs alpha_evax_proc_data;
static int alpha_flag_hash_long_names = 0; /* -+ */
static int alpha_flag_show_after_trunc = 0; /* -H */
const char *name; /* String to lookup. */
size_t length; /* Size of the string. */
operatorT op; /* Which operator to use. */
- bfd_reloc_code_real_type reloc; /* Relocation before frob. */
+ extended_bfd_reloc_code_real_type reloc;
unsigned int require_seq : 1; /* Require a sequence number. */
unsigned int allow_seq : 1; /* Allow a sequence number. */
}
{
fixS *master; /* The literal reloc. */
#ifdef OBJ_EVAX
- struct symbol *sym;
- struct symbol *psym;
+ struct symbol *sym; /* Linkage section item symbol. */
+ struct symbol *psym; /* Pdesc symbol. */
#endif
fixS *slaves; /* Head of linked list of lituses. */
segT segment; /* Segment relocs are in or undefined_section. */
static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
-static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
+static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type);
static void emit_insn (struct alpha_insn *);
static void assemble_tokens (const char *, const expressionS *, int, int);
#ifdef OBJ_EVAX
static char *s_alpha_section_name (void);
-static symbolS *add_to_link_pool (symbolS *, symbolS *, offsetT);
+static symbolS *add_to_link_pool (symbolS *, offsetT);
#endif
\f
static struct alpha_reloc_tag *
size_t len = strlen (buffer);
const char *errmsg;
- info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
+ info = (struct alpha_reloc_tag *)
+ xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
info->segment = now_seg;
info->sequence = sequence;
strcpy (info->string, buffer);
errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
if (errmsg)
- as_fatal (errmsg);
+ as_fatal ("%s", errmsg);
#ifdef OBJ_EVAX
info->sym = 0;
info->psym = 0;
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
- assert (insn.nfixups == 1);
+ gas_assert (insn.nfixups == 1);
insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
insn.sequence = emit_lituse = next_sequence_num--;
#endif /* OBJ_ECOFF */
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
- assert (insn.nfixups == 1);
+ gas_assert (insn.nfixups == 1);
insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
insn.sequence = emit_lituse = next_sequence_num--;
#endif /* OBJ_ELF */
if (exp->X_add_symbol == alpha_evax_proc->symbol)
{
+ /* Linkage-relative expression. */
+ set_tok_reg (newtok[0], targreg);
+
if (range_signed_16 (addend))
{
- set_tok_reg (newtok[0], targreg);
set_tok_const (newtok[1], addend);
- set_tok_preg (newtok[2], basereg);
- assemble_tokens_to_insn ("lda", newtok, 3, &insn);
addend = 0;
}
else
{
- set_tok_reg (newtok[0], targreg);
set_tok_const (newtok[1], 0);
- set_tok_preg (newtok[2], basereg);
- assemble_tokens_to_insn ("lda", newtok, 3, &insn);
}
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
}
else
{
if ((symlen > 4 &&
strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
{
+ /* Access to an item whose address is stored in the linkage
+ section. Just read the address. */
set_tok_reg (newtok[0], targreg);
newtok[1] = *exp;
if (alpha_flag_replace && targreg == 26)
{
+ /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */
char *ensymname;
symbolS *ensym;
- volatile asymbol *dummy;
+ /* Build the entry name as 'NAME..en'. */
ptr1 = strstr (symname, "..") + 2;
if (ptr1 > ptr2)
ptr1 = symname;
- ensymname = (char *) xmalloc (ptr2 - ptr1 + 5);
+ ensymname = (char *) alloca (ptr2 - ptr1 + 5);
memcpy (ensymname, ptr1, ptr2 - ptr1);
memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
- assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
ensym = symbol_find_or_make (ensymname);
ensym->sy_used = 1;
/* ??? Force bsym to be instantiated now, as it will be
too late to do so in tc_gen_reloc. */
- dummy = symbol_get_bfdsym (exp->X_add_symbol);
+ symbol_get_bfdsym (exp->X_add_symbol);
}
else if (alpha_flag_replace && targreg == 27)
{
+ /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'. */
char *psymname;
symbolS *psym;
+ /* Extract NAME. */
ptr1 = strstr (symname, "..") + 2;
if (ptr1 > ptr2)
ptr1 = symname;
- psymname = (char *) xmalloc (ptr2 - ptr1 + 1);
+ psymname = (char *) alloca (ptr2 - ptr1 + 1);
memcpy (psymname, ptr1, ptr2 - ptr1);
psymname [ptr2 - ptr1] = 0;
- assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
+
+ gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
psym = symbol_find_or_make (psymname);
psym->sy_used = 1;
insn.nfixups++;
}
- emit_insn(&insn);
+ emit_insn (&insn);
return 0;
}
else
{
+ /* Not in the linkage section. Put the value into the linkage
+ section. */
symbolS *linkexp;
if (!range_signed_32 (addend))
addend = sign_extend_32 (addend);
- linkexp = add_to_link_pool (alpha_evax_proc->symbol,
- exp->X_add_symbol, 0);
+ linkexp = add_to_link_pool (exp->X_add_symbol, 0);
set_tok_reg (newtok[0], targreg);
set_tok_sym (newtok[1], linkexp, 0);
set_tok_preg (newtok[2], basereg);
/* For 64-bit addends, just put it in the literal pool. */
#ifdef OBJ_EVAX
/* Emit "ldq targreg, lit(basereg)". */
- litexp = add_to_link_pool (alpha_evax_proc->symbol,
- section_symbol (absolute_section), addend);
+ litexp = add_to_link_pool (section_symbol (absolute_section), addend);
set_tok_reg (newtok[0], targreg);
set_tok_sym (newtok[1], litexp, 0);
set_tok_preg (newtok[2], alpha_gp_register);
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
- assert (insn.nfixups == 1);
+ gas_assert (insn.nfixups == 1);
#ifdef OBJ_ECOFF
insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
#endif
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
}
else
{
- reloc_howto_type *reloc_howto
- = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
- assert (reloc_howto);
+ reloc_howto_type *reloc_howto =
+ bfd_reloc_type_lookup (stdoutput,
+ (bfd_reloc_code_real_type) fixup->reloc);
+ gas_assert (reloc_howto);
size = bfd_get_reloc_size (reloc_howto);
break;
#endif
default:
- assert (size >= 1 && size <= 4);
+ gas_assert (size >= 1 && size <= 4);
}
pcrel = reloc_howto->pc_relative;
}
fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
- &fixup->exp, pcrel, fixup->reloc);
+ &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc);
/* Turn off complaints that the addend is too large for some fixups,
and copy in the sequence number for the explicit relocations. */
insn = (*operand->insert) (insn, val, &errmsg);
if (errmsg)
- as_warn (errmsg);
+ as_warn ("%s", errmsg);
}
else
insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
const expressionS *tok,
int ntok,
struct alpha_insn *insn,
- bfd_reloc_code_real_type reloc)
+ extended_bfd_reloc_code_real_type reloc)
{
const struct alpha_operand *reloc_operand = NULL;
const expressionS *reloc_exp = NULL;
case O_constant:
image = insert_operand (image, operand, t->X_add_number, NULL, 0);
- assert (reloc_operand == NULL);
+ gas_assert (reloc_operand == NULL);
reloc_operand = operand;
reloc_exp = t;
break;
if (reloc == BFD_RELOC_UNUSED)
reloc = operand->default_reloc;
- assert (reloc_operand == NULL);
+ gas_assert (reloc_operand == NULL);
reloc_operand = operand;
reloc_exp = t;
}
else if (reloc < BFD_RELOC_UNUSED && reloc > 0)
{
reloc_howto_type *reloc_howto
- = bfd_reloc_type_lookup (stdoutput, reloc);
+ = bfd_reloc_type_lookup (stdoutput,
+ (bfd_reloc_code_real_type) reloc);
if (reloc_operand == NULL
|| reloc_howto->bitsize != reloc_operand->bits)
{
basereg = tok[2].X_add_number;
lituse = load_expression (tok[0].X_add_number, &tok[1],
- &basereg, &newtok[1], opname);
+ &basereg, &newtok[1], (const char *) opname);
if (basereg == alpha_gp_register &&
(symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0))
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
as_bad (_("macro requires $at register while noat in effect"));
lituse = load_expression (AXP_REG_AT, &tok[1],
- &basereg, &newtok[1], opname);
+ &basereg, &newtok[1], (const char *) opname);
}
else
{
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
if (lituse)
{
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
&& tok[tokidx].X_add_symbol
&& alpha_linkage_symbol)
{
+ /* Create a BOH reloc for 'jsr $27,NAME'. */
const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
int symlen = strlen (symname);
char *ensymname;
- ensymname = (char *) xmalloc (symlen + 5);
+ /* Build the entry name as 'NAME..en'. */
+ ensymname = (char *) alloca (symlen + 5);
memcpy (ensymname, symname, symlen);
memcpy (ensymname + symlen, "..en", 5);
- assert (insn.nfixups < MAX_INSN_FIXUPS);
+ gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
if (insn.nfixups > 0)
{
memmove (&insn.fixups[1], &insn.fixups[0],
/* Implement the ldgp macro. */
static void
-emit_ldgp (const expressionS *tok,
+emit_ldgp (const expressionS *tok ATTRIBUTE_UNUSED,
int ntok ATTRIBUTE_UNUSED,
const void * unused ATTRIBUTE_UNUSED)
{
insn.sequence = next_sequence_num--;
emit_insn (&insn);
-#else /* OBJ_ECOFF || OBJ_ELF */
- /* Avoid warning. */
- tok = NULL;
-#endif
+#endif /* OBJ_ECOFF || OBJ_ELF */
}
/* The macro table. */
const struct alpha_opcode *opcode;
const struct alpha_macro *macro;
int cpumatch = 1;
- bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
+ extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
#ifdef RELOC_OP_P
/* If a user-specified relocation is present, this is not a macro. */
\f
#ifdef OBJ_EVAX
-/* Add symbol+addend to link pool.
- Return offset from basesym to entry in link pool.
+/* Add sym+addend to link pool.
+ Return offset from curent procedure value (pv) to entry in link pool.
Add new fixup only if offset isn't 16bit. */
static symbolS *
-add_to_link_pool (symbolS *basesym,
- symbolS *sym,
- offsetT addend)
+add_to_link_pool (symbolS *sym, offsetT addend)
{
+ symbolS *basesym;
segT current_section = now_seg;
int current_subsec = now_subseg;
- valueT offset;
char *p;
segment_info_type *seginfo = seg_info (alpha_link_section);
fixS *fixp;
symbolS *linksym, *expsym;
expressionS e;
- offset = 0; /* ??? DBR */
+ basesym = alpha_evax_proc->symbol;
/* @@ This assumes all entries in a given section will be of the same
size... Probably correct, but unwise to rely on. */
fixp != (fixS *) NULL;
fixp = fixp->fx_next)
{
- if (fixp->tc_fix_data.info
- && fixp->tc_fix_data.info->sym
- && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
- offset += 8;
-
if (fixp->fx_addsy == sym
&& fixp->fx_offset == (valueT)addend
&& fixp->tc_fix_data.info
return fixp->tc_fix_data.info->sym;
}
- /* Not found in 16bit signed range. */
-
+ /* Not found, add a new entry. */
subseg_set (alpha_link_section, 0);
linksym = symbol_new
(FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
p = frag_more (8);
memset (p, 0, 8);
+ /* Create the basesym - linksym expression (offset of the added entry). */
e.X_op = O_subtract;
e.X_add_symbol = linksym;
e.X_op_symbol = basesym;
expsym = make_expr_symbol (&e);
fixp = fix_new
- (frag_now, p-frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
+ (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--);
fixp->tc_fix_data.info->sym = expsym;
subseg_set (current_section, current_subsec);
- seginfo->literal_pool_size += 8;
return expsym;
}
#endif /* OBJ_EVAX */
sec = subseg_new (sec_name, 0);
S_SET_SEGMENT (sec_symbol, sec);
symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM;
- bfd_vms_set_section_flags (stdoutput, sec,
- EGPS_S_V_OVR | EGPS_S_V_GBL | EGPS_S_V_NOMOD);
+ bfd_vms_set_section_flags (stdoutput, sec, 0,
+ EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD);
record_alignment (sec, log_align);
/* Reuse stab_string_size to store the size of the section. */
if (S_GET_VALUE (symbolP))
{
if (S_GET_VALUE (symbolP) != (valueT) size)
- as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
S_GET_NAME (symbolP),
(long) S_GET_VALUE (symbolP),
(long) size);
static void
s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
{
- int temp;
-
- temp = get_absolute_expression ();
+ get_absolute_expression ();
subseg_new (".rdata", 0);
demand_empty_rest_of_line ();
alpha_insn_label = NULL;
static void
s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
{
- int temp;
-
- temp = get_absolute_expression ();
+ get_absolute_expression ();
subseg_new (".sdata", 0);
demand_empty_rest_of_line ();
alpha_insn_label = NULL;
sym = symbol_find_or_make (name);
symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
- cur_frame_data = calloc (1, sizeof (*cur_frame_data));
+ cur_frame_data = (struct alpha_elf_frame_data *)
+ calloc (1, sizeof (*cur_frame_data));
cur_frame_data->func_sym = sym;
/* Provide sensible defaults. */
if (sym && cur_frame_data)
{
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
- expressionS *exp = xmalloc (sizeof (expressionS));
+ expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS));
obj->size = exp;
exp->X_op = O_subtract;
discard_rest_of_line ();
len = input_line_pointer - start;
- first_file_directive = xmalloc (len + 1);
+ first_file_directive = (char *) xmalloc (len + 1);
memcpy (first_file_directive, start, len);
first_file_directive[len] = '\0';
ecoff_directive_val,
};
- assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
+ gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
if (ECOFF_DEBUGGING)
(*fns[which]) (0);
return name;
}
+/* Put clear/set flags in one flagword. The LSBs are flags to be set,
+ the MSBs are the flags to be cleared. */
+
+#define EGPS__V_NO_SHIFT 16
+#define EGPS__V_MASK 0xffff
+
+/* Parse one VMS section flag. */
+
static flagword
s_alpha_section_word (char *str, size_t len)
{
if (len == 3)
{
if (strncmp (str, "PIC", 3) == 0)
- flag = EGPS_S_V_PIC;
+ flag = EGPS__V_PIC;
else if (strncmp (str, "LIB", 3) == 0)
- flag = EGPS_S_V_LIB;
+ flag = EGPS__V_LIB;
else if (strncmp (str, "OVR", 3) == 0)
- flag = EGPS_S_V_OVR;
+ flag = EGPS__V_OVR;
else if (strncmp (str, "REL", 3) == 0)
- flag = EGPS_S_V_REL;
+ flag = EGPS__V_REL;
else if (strncmp (str, "GBL", 3) == 0)
- flag = EGPS_S_V_GBL;
+ flag = EGPS__V_GBL;
else if (strncmp (str, "SHR", 3) == 0)
- flag = EGPS_S_V_SHR;
+ flag = EGPS__V_SHR;
else if (strncmp (str, "EXE", 3) == 0)
- flag = EGPS_S_V_EXE;
+ flag = EGPS__V_EXE;
else if (strncmp (str, "WRT", 3) == 0)
- flag = EGPS_S_V_WRT;
+ flag = EGPS__V_WRT;
else if (strncmp (str, "VEC", 3) == 0)
- flag = EGPS_S_V_VEC;
+ flag = EGPS__V_VEC;
else if (strncmp (str, "MOD", 3) == 0)
{
- flag = no ? EGPS_S_V_NOMOD : EGPS_S_V_NOMOD << EGPS_S_V_NO_SHIFT;
+ flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT;
no = 0;
}
else if (strncmp (str, "COM", 3) == 0)
- flag = EGPS_S_V_COM;
+ flag = EGPS__V_COM;
}
if (flag == 0)
}
if (no)
- return flag << EGPS_S_V_NO_SHIFT;
+ return flag << EGPS__V_NO_SHIFT;
else
return flag;
}
static void
s_alpha_section (int secid)
{
- int temp;
char *name, *beg;
segT sec;
flagword vms_flags = 0;
symbol = symbol_find_or_make (name);
S_SET_SEGMENT (symbol, sec);
symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM;
- bfd_vms_set_section_flags (stdoutput, sec, vms_flags);
+ bfd_vms_set_section_flags
+ (stdoutput, sec,
+ (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK,
+ vms_flags & EGPS__V_MASK);
}
else
{
- temp = get_absolute_expression ();
+ get_absolute_expression ();
subseg_new (section_name[secid], 0);
}
symbolS *symbol;
expressionS symexpr;
- alpha_evax_proc
- = (struct alpha_evax_procs *) xmalloc (sizeof (struct alpha_evax_procs));
+ if (alpha_evax_proc != NULL)
+ as_bad (_("previous .ent not closed by a .end"));
+
+ alpha_evax_proc = &alpha_evax_proc_data;
alpha_evax_proc->pdsckind = 0;
alpha_evax_proc->framereg = -1;
symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
alpha_evax_proc->symbol = symbol;
- (void) hash_insert
- (alpha_evax_proc_hash,
- symbol_get_bfdsym (alpha_evax_proc->symbol)->name, (PTR)alpha_evax_proc);
-
demand_empty_rest_of_line ();
}
alpha_evax_proc->rsa_offset = get_absolute_expression ();
}
+/* Parse .prologue. */
+
static void
s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
{
- int arg;
-
- arg = get_absolute_expression ();
+ get_absolute_expression ();
demand_empty_rest_of_line ();
alpha_prologue_label = symbol_new
(FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
}
+/* Parse .pdesc <entry_name>.
+ Insert a procedure descriptor. */
+
static void
s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
{
register char *p;
expressionS exp;
symbolS *entry_sym;
- fixS *fixp;
- segment_info_type *seginfo = seg_info (alpha_link_section);
const char *entry_sym_name;
- char *sym_name;
- int len;
+ const char *pdesc_sym_name;
+ fixS *fixp;
+ size_t len;
if (now_seg != alpha_link_section)
{
as_bad (_(".pdesc directive not in link (.link) section"));
- demand_empty_rest_of_line ();
return;
}
expression (&exp);
if (exp.X_op != O_symbol)
{
- as_warn (_(".pdesc directive has no entry symbol"));
- demand_empty_rest_of_line ();
+ as_bad (_(".pdesc directive has no entry symbol"));
return;
}
entry_sym = make_expr_symbol (&exp);
- entry_sym_name = symbol_get_bfdsym (entry_sym)->name;
+ entry_sym_name = S_GET_NAME (entry_sym);
+ /* Strip "..en". */
len = strlen (entry_sym_name);
- sym_name = (char *) xmalloc (len - 4 + 1);
- strncpy (sym_name, entry_sym_name, len - 4);
- sym_name [len - 4] = 0;
-
- alpha_evax_proc = (struct alpha_evax_procs *)
- hash_find (alpha_evax_proc_hash, sym_name);
-
- if (!alpha_evax_proc || !S_IS_DEFINED (alpha_evax_proc->symbol))
+ if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0)
{
- as_fatal (_(".pdesc has no matching .ent"));
- demand_empty_rest_of_line ();
+ as_bad (_(".pdesc has a bad entry symbol"));
return;
}
+ len -= 4;
+ pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol);
- *symbol_get_obj (alpha_evax_proc->symbol) =
- (valueT) seginfo->literal_pool_size;
+ if (!alpha_evax_proc
+ || !S_IS_DEFINED (alpha_evax_proc->symbol)
+ || strlen (pdesc_sym_name) != len
+ || memcmp (entry_sym_name, pdesc_sym_name, len) != 0)
+ {
+ as_fatal (_(".pdesc doesn't match with last .ent"));
+ return;
+ }
- alpha_evax_proc->symbol->sy_obj = (valueT)seginfo->literal_pool_size;
+ /* Define pdesc symbol. */
+ symbol_set_value_now (alpha_evax_proc->symbol);
/* Save bfd symbol of proc entry in function symbol. */
((struct evax_private_udata_struct *)
p = frag_more (16);
fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
fixp->fx_done = 1;
- seginfo->literal_pool_size += 16;
*p = alpha_evax_proc->pdsckind
| ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
/* Signature offset. */
md_number_to_chars (p + 6, (valueT) 0, 2);
- fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
+ fix_new_exp (frag_now, p - frag_now->fr_literal + 8,
+ 8, &exp, 0, BFD_RELOC_64);
if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
return;
- /* Add dummy fix to make add_to_link_pool work. */
- p = frag_more (6);
- fixp = fix_new (frag_now, p - frag_now->fr_literal, 6, 0, 0, 0, 0);
- fixp->fx_done = 1;
- seginfo->literal_pool_size += 6;
-
/* pdesc+16: Size. */
+ p = frag_more (6);
md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
-
md_number_to_chars (p + 4, (valueT) 0, 2);
/* Entry length. */
if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
return;
- /* Add dummy fix to make add_to_link_pool work. */
- p = frag_more (8);
- fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
- fixp->fx_done = 1;
- seginfo->literal_pool_size += 8;
-
/* pdesc+24: register masks. */
-
+ p = frag_more (8);
md_number_to_chars (p, alpha_evax_proc->imask, 4);
md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
if (alpha_evax_proc->handler_data)
{
- /* Add dummy fix to make add_to_link_pool work. */
p = frag_more (8);
- fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
- fixp->fx_done = 1;
- seginfo->literal_pool_size += 8;
md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
}
}
{
char *p;
expressionS exp;
- segment_info_type *seginfo = seg_info (alpha_link_section);
if (now_seg != alpha_link_section)
{
frag_align (3, 0, 0);
p = frag_more (8);
- seginfo->literal_pool_size += 8;
fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
}
+/* Parse .linkage <symbol>.
+ Create a linkage pair relocation. */
+
static void
s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
{
demand_empty_rest_of_line ();
}
+/* Parse .code_address <symbol>.
+ Create a code address relocation. */
+
static void
s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
{
c = get_symbol_end ();
*input_line_pointer = c;
demand_empty_rest_of_line ();
- alpha_evax_proc = 0;
+ alpha_evax_proc = NULL;
}
static void
temp = get_absolute_expression ();
}
/* *symbol_get_obj (symbolP) = (signed char) temp; */
+ (void) symbolP;
as_warn (_("unhandled: .proc %s,%d"), name, temp);
demand_empty_rest_of_line ();
}
if (align != 0)
{
alpha_auto_align_on = 1;
- alpha_align (align, pfill, alpha_insn_label, 1);
+ alpha_align (align, pfill, NULL, 1);
}
else
{
alpha_auto_align_on = 0;
}
+ alpha_insn_label = NULL;
demand_empty_rest_of_line ();
}
alpha_target_name = p->name, alpha_target = p->flags;
goto found;
}
- as_warn ("Unknown CPU identifier `%s'", name);
+ as_warn (_("Unknown CPU identifier `%s'"), name);
found:
*input_line_pointer = ch;
static void
select_gp_value (void)
{
- assert (alpha_gp_value == 0);
+ gas_assert (alpha_gp_value == 0);
/* Get minus-one in whatever width... */
alpha_gp_value = 0;
if (letter == 's')
return SHF_ALPHA_GPREL;
- *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
+ *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string");
return -1;
}
expressionS e;
e.X_op = O_max;
- assert (e.X_op == O_max);
+ gas_assert (e.X_op == O_max);
}
/* Create the opcode hash table. */
if ((slash = strchr (name, '/')) != NULL)
{
- char *p = xmalloc (strlen (name));
+ char *p = (char *) xmalloc (strlen (name));
memcpy (p, name, slash - name);
strcpy (p + (slash - name), slash + 1);
#ifdef OBJ_EVAX
create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
- alpha_evax_proc_hash = hash_new ();
#endif
#ifdef OBJ_ELF
#ifdef OBJ_ECOFF
case BFD_RELOC_GPREL32:
- assert (fixP->fx_subsy == alpha_gp_symbol);
+ gas_assert (fixP->fx_subsy == alpha_gp_symbol);
fixP->fx_subsy = 0;
/* FIXME: inherited this obliviousness of `value' -- why? */
md_number_to_chars (fixpos, -alpha_gp_value, 4);
as_fatal (_("unhandled relocation type %s"),
bfd_get_reloc_code_name (fixP->fx_r_type));
- assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
+ gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
operand = &alpha_operands[-(int) fixP->fx_r_type];
/* The rest of these fixups only exist internally during symbol
{
arelent *reloc;
- reloc = xmalloc (sizeof (* reloc));
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ reloc = (arelent *) xmalloc (sizeof (* reloc));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
/* Make sure none of our internal relocations make it this far.
They'd better have been fully resolved by this point. */
- assert ((int) fixp->fx_r_type > 0);
+ gas_assert ((int) fixp->fx_r_type > 0);
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == NULL)
as_fatal (_("internal error? cannot generate `%s' relocation"),
bfd_get_reloc_code_name (fixp->fx_r_type));
- assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
+ gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
+
+ reloc->addend = fixp->fx_offset;
#ifdef OBJ_ECOFF
+ /* Fake out bfd_perform_relocation. sigh. */
+ /* ??? Better would be to use the special_function hook. */
if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
- /* Fake out bfd_perform_relocation. sigh. */
reloc->addend = -alpha_gp_value;
- else
-#endif
- {
- reloc->addend = fixp->fx_offset;
-#ifdef OBJ_ELF
- /* Ohhh, this is ugly. The problem is that if this is a local global
- symbol, the relocation will entirely be performed at link time, not
- at assembly time. bfd_perform_reloc doesn't know about this sort
- of thing, and as a result we need to fake it out here. */
- if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
- || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
- || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
- && !S_IS_COMMON (fixp->fx_addsy))
- reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
#endif
- }
#ifdef OBJ_EVAX
switch (fixp->fx_r_type)
int pname_len;
case BFD_RELOC_ALPHA_LINKAGE:
+ /* Copy the linkage index. */
reloc->addend = fixp->fx_addnumber;
break;
if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
{
symbolS *sym;
- char *my_pname = xstrdup (pname);
+ char *my_pname = (char *) alloca (pname_len - 4 + 1);
+
+ memcpy (my_pname, pname, pname_len - 4);
my_pname [pname_len - 4] = 0;
sym = symbol_find (my_pname);
if (sym == NULL)
abort ();
+
while (symbol_equated_reloc_p (sym))
{
symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;