This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commited] [vax] gas: add %pcrel{8,16,32}(exp)


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.

Index: config/tc-vax.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-vax.c,v
retrieving revision 1.33
diff -u -r1.33 tc-vax.c
--- config/tc-vax.c 7 Jun 2006 11:27:58 -0000 1.33
+++ config/tc-vax.c 6 Apr 2007 16:36:12 -0000
@@ -3265,3 +3265,143 @@
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;
+}
Index: config/tc-vax.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-vax.h,v
retrieving revision 1.10
diff -u -r1.10 tc-vax.h
--- config/tc-vax.h 18 Mar 2006 11:23:38 -0000 1.10
+++ config/tc-vax.h 6 Apr 2007 16:36:12 -0000
@@ -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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]