diff options
author | Matt Thomas <matt@3am-software.com> | 2007-04-06 16:36:48 +0000 |
---|---|---|
committer | Matt Thomas <matt@3am-software.com> | 2007-04-06 16:36:48 +0000 |
commit | 6f7b6869f3d90e3b22a687ba09809580fa9f508a (patch) | |
tree | bde6447638ced7c61225c32b482f0684c3edefc2 /gas | |
parent | da6bcfca9535fb9680fd738207da6c58e0e898bc (diff) | |
download | ppe42-binutils-6f7b6869f3d90e3b22a687ba09809580fa9f508a.tar.gz ppe42-binutils-6f7b6869f3d90e3b22a687ba09809580fa9f508a.zip |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-vax.c | 140 | ||||
-rw-r--r-- | gas/config/tc-vax.h | 7 |
3 files changed, 153 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 96abc6fadc..4c2e52c30a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 47b4fcaea2..93cacd6e69 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -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; +} diff --git a/gas/config/tc-vax.h b/gas/config/tc-vax.h index 715d54a812..4f16e5837d 100644 --- a/gas/config/tc-vax.h +++ b/gas/config/tc-vax.h @@ -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 |