2007-04-06 Matt Thomas <matt@netbsd.org>

* config/tc-vax.c (vax_cons): Added to support %pcrel{8,16,32}(exp)
	to emit pcrel relocations by DWARF2 in non-code sections.  Borrowed
	heavily from tc-sparc.c.  (vax_cons_fix_new): Likewise.
This commit is contained in:
Matt Thomas 2007-04-06 16:36:48 +00:00
parent da6bcfca95
commit 6f7b6869f3
3 changed files with 153 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2007-04-06 Matt Thomas <matt@netbsd.org>
* config/tc-vax.c (vax_cons): Added to support %pcrel{8,16,32}(exp)
to emit pcrel relocations by DWARF2 in non-code sections. Borrowed
heavily from tc-sparc.c. (vax_cons_fix_new): Likewise.
2007-04-04 Kazu Hirata <kazu@codesourcery.com>
* config/tc-m68k.c (HAVE_LONG_BRANCH): Add fido_a.

View File

@ -3265,3 +3265,143 @@ md_begin (void)
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;
}

View File

@ -47,6 +47,13 @@
#define md_operand(x)
#ifdef OBJ_ELF
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) vax_cons (EXP, NBYTES)
#define TC_CONS_FIX_NEW vax_cons_fix_new
void vax_cons (expressionS *, int);
void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *);
#endif
extern const struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table