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

Matt Thomas matt@3am-software.com
Fri Apr 6 16:40:00 GMT 2007


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



More information about the Binutils mailing list