From 6f7b6869f3d90e3b22a687ba09809580fa9f508a Mon Sep 17 00:00:00 2001 From: Matt Thomas Date: Fri, 6 Apr 2007 16:36:48 +0000 Subject: 2007-04-06 Matt Thomas * 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. --- gas/config/tc-vax.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'gas/config/tc-vax.c') diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 47b4fca..93cacd6 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; +} -- cgit v1.1