/* tc-vax.c - vax-specific -
Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1998, 2000, 2001, 2002,
- 2003, 2004, 2005
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
into host byte order.
con is the buffer to convert,
nbytes is the length of the given buffer. */
-long
+static long
md_chars_to_number (unsigned char con[], int nbytes)
{
long retval;
|| S_IS_WEAK (fragP->fr_symbol)
|| S_IS_EXTERNAL (fragP->fr_symbol)))
{
- if (p[0] & 0x10)
- {
- if (flag_want_pic)
- as_fatal ("PIC reference to %s is indirect.\n",
- S_GET_NAME (fragP->fr_symbol));
- }
+ /* Indirect references cannot go through the GOT or PLT,
+ let's hope they'll become local in the final link. */
+ if ((ELF_ST_VISIBILITY (S_GET_OTHER (fragP->fr_symbol))
+ != STV_DEFAULT)
+ || (p[0] & 0x10))
+ reloc_type = BFD_RELOC_32_PCREL;
+ else if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS
+ || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG
+ || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB
+ || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP
+ || S_IS_FUNCTION (fragP->fr_symbol))
+ reloc_type = BFD_RELOC_32_PLT_PCREL;
else
- {
- if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS
- || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG
- || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB
- || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP
- || S_IS_FUNCTION (fragP->fr_symbol))
- reloc_type = BFD_RELOC_32_PLT_PCREL;
- else
- reloc_type = BFD_RELOC_32_GOT_PCREL;
- }
+ reloc_type = BFD_RELOC_32_GOT_PCREL;
}
#endif
switch (RELAX_STATE (fragP->fr_subtype))
{"jbcs", {"rlvbb?", 0x800000e3}},
{"jbsc", {"rlvbb?", 0x800000e4}},
{"jbcc", {"rlvbb?", 0x800000e5}},
+ {"jbssi", {"rlvbb?", 0x800000e6}},
+ {"jbcci", {"rlvbb?", 0x800000e7}},
{"jlbs", {"rlb?", 0x800000e8}},
{"jlbc", {"rlb?", 0x800000e9}},
op_hash = hash_new ();
for (vP = votstrs; *vP->vot_name && !retval; vP++)
- retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+ retval = hash_insert (op_hash, vP->vot_name, (void *) &vP->vot_detail);
if (synthetic_too)
for (vP = synthetic_votstrs; *vP->vot_name && !retval; vP++)
- retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+ retval = hash_insert (op_hash, vP->vot_name, (void *) &vP->vot_detail);
#ifndef CONST_TABLE
vip_op_defaults (immediate, indirect, displen);
get the types wrong below, we lose at compile time rather than at
lint or run time. */
char access_mode; /* vop_access. */
- char width; /* vop_width. */
access_mode = vopP->vop_access;
- width = vopP->vop_width;
/* None of our code bugs (yet), no user text errors, no warnings
even. */
err = wrn = 0;
We declare arrays non-local in case some of our tiny-minded machines
default to small stacks. Also, helps with some debuggers. */
-#include <stdio.h>
-
char answer[100]; /* Human types into here. */
char *p; /* */
char *myerr;
#endif
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
- assert (reloc->howto != 0);
+ gas_assert (reloc->howto != 0);
return reloc;
}
if (need_pass_2 || goofed)
return;
+ dwarf2_emit_insn (0);
/* Emit op-code. */
/* Remember where it is, in case we want to modify the op-code later. */
opcode_low_byteP = frag_more (v.vit_opcode_nbytes);
if (flag_want_pic && operandP->vop_mode == 8
&& this_add_symbol != NULL)
{
- as_warn (_("Symbol used as immediate operand in PIC mode."));
+ as_warn (_("Symbol %s used as immediate operand in PIC mode."),
+ S_GET_NAME (this_add_symbol));
}
#endif
p[0] = (operandP->vop_mode << 4) | 0xF;
min (sizeof (valueT),
(size_t) nbytes));
if ((size_t) nbytes > sizeof (valueT))
- memset (p + 5, '\0', nbytes - sizeof (valueT));
+ memset (p + 1 + sizeof (valueT),
+ '\0', nbytes - sizeof (valueT));
}
else
{
fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1];
}
}
+
+static char *vax_cons_special_reloc;
+
+void
+vax_cons (expressionS *exp, int size)
+{
+ char *save;
+
+ SKIP_WHITESPACE ();
+ vax_cons_special_reloc = NULL;
+ save = input_line_pointer;
+ if (input_line_pointer[0] == '%')
+ {
+ if (strncmp (input_line_pointer + 1, "pcrel", 5) == 0)
+ {
+ input_line_pointer += 6;
+ vax_cons_special_reloc = "pcrel";
+ }
+ if (vax_cons_special_reloc)
+ {
+ int bad = 0;
+
+ switch (size)
+ {
+ case 1:
+ if (*input_line_pointer != '8')
+ bad = 1;
+ input_line_pointer--;
+ break;
+ case 2:
+ if (input_line_pointer[0] != '1' || input_line_pointer[1] != '6')
+ bad = 1;
+ break;
+ case 4:
+ if (input_line_pointer[0] != '3' || input_line_pointer[1] != '2')
+ bad = 1;
+ break;
+ default:
+ bad = 1;
+ break;
+ }
+
+ if (bad)
+ {
+ as_bad (_("Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"),
+ vax_cons_special_reloc, size * 8, size);
+ }
+ else
+ {
+ input_line_pointer += 2;
+ if (*input_line_pointer != '(')
+ {
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ vax_cons_special_reloc, size * 8);
+ bad = 1;
+ }
+ }
+
+ if (bad)
+ {
+ input_line_pointer = save;
+ vax_cons_special_reloc = NULL;
+ }
+ else
+ {
+ int c;
+ char *end = ++input_line_pointer;
+ int npar = 0;
+
+ while (! is_end_of_line[(c = *end)])
+ {
+ if (c == '(')
+ npar++;
+ else if (c == ')')
+ {
+ if (!npar)
+ break;
+ npar--;
+ }
+ end++;
+ }
+
+ if (c != ')')
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ vax_cons_special_reloc, size * 8);
+ else
+ {
+ *end = '\0';
+ expression (exp);
+ *end = c;
+ if (input_line_pointer != end)
+ {
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ vax_cons_special_reloc, size * 8);
+ }
+ else
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (! is_end_of_line[c] && c != ',')
+ as_bad (_("Illegal operands: garbage after %%r_%s%d()"),
+ vax_cons_special_reloc, size * 8);
+ }
+ }
+ }
+ }
+ }
+ if (vax_cons_special_reloc == NULL)
+ expression (exp);
+}
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+ reloc for a cons. */
+
+void
+vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp)
+{
+ bfd_reloc_code_real_type r;
+
+ r = (nbytes == 1 ? BFD_RELOC_8 :
+ (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
+
+ if (vax_cons_special_reloc)
+ {
+ if (*vax_cons_special_reloc == 'p')
+ {
+ switch (nbytes)
+ {
+ case 1: r = BFD_RELOC_8_PCREL; break;
+ case 2: r = BFD_RELOC_16_PCREL; break;
+ case 4: r = BFD_RELOC_32_PCREL; break;
+ default: abort ();
+ }
+ }
+ }
+
+ fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+ vax_cons_special_reloc = NULL;
+}
+
+char *
+md_atof (int type, char * litP, int * sizeP)
+{
+ return vax_md_atof (type, litP, sizeP);
+}