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]

Fixes for spu @ppu expressions


".long foo@ppu" is supposed to always refer to the ppu symbol foo,
even if foo is also used as an spu symbol.  Unfortunately, if foo was
a local defined symbol, its value was substitued in the generic gas
expression code and spu gas never saw it as a symbol.  Fixed by
spu_cons asking for deferred expression evaluation.  

This patch also add support for ".long @ppu" and ".long 0@ppu"),
which, like _EAR_ with a NULL suffix, resolve to the address of the
embedded spu image.

binutils/
	* embedspu.sh: Handle R_SPU_PPU* relocs with no symbol.
gas/
	* config/tc-spu.c (spu_cons): Use deferred_expression.  Handle
	number@ppu.
	(tc_gen_reloc): Abort if neither addsy or subsy is set.
	(md_apply_fix): Don't attempt to resolve SPU_PPU relocs.
	* config/tc-spu.h (md_operand): Handle @ppu without sym.

Index: binutils/embedspu.sh
===================================================================
RCS file: /cvs/src/src/binutils/embedspu.sh,v
retrieving revision 1.7
diff -u -p -r1.7 embedspu.sh
--- binutils/embedspu.sh	29 May 2007 13:10:10 -0000	1.7
+++ binutils/embedspu.sh	4 Jun 2007 08:02:09 -0000
@@ -198,17 +198,17 @@ $7 != "'${toe}'" && ! $7 in sec_off { \
 } \
 $3 ~ /R_SPU_PPU/ { \
 	print "#ifdef _LP64"; \
-	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" substr($3, 10) ", " $5 "+0x" $7; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" substr($3, 10) ", " ($5 != "" ? $5 "+0x" $7 : "__speelf__ + 0x" $4); \
 	print "#else"; \
-	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + (substr($3, 10) == "64" ? 4 : 0)", R_PPC_ADDR32, " $5 "+0x" $7; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + (substr($3, 10) == "64" ? 4 : 0)", R_PPC_ADDR32, " ($5 != "" ? $5 "+0x" $7 : "__speelf__ + 0x" $4); \
 	print "#endif"; \
 	if (!donedef) { print "#define HAS_RELOCS 1"; donedef = 1; }; \
 } \
 $3 ~ /unrecognized:/ { \
 	print "#ifdef _LP64"; \
-	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" ($4 == "f" ? "64" : "32") ", " $6 "+0x" $8; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" ($4 == "f" ? "64" : "32") ", " ($6 != "" ? $6 "+0x" $8 : "__speelf__ + 0x" $5); \
 	print "#else"; \
-	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " $6 "+0x" $8; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " ($6 != "" ? $6 "+0x" $8 : "__speelf__ + 0x" $5); \
 	print "#endif"; \
 	if (!donedef) { print "#define HAS_RELOCS 1"; donedef = 1; }; \
 } \
Index: gas/config/tc-spu.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.c,v
retrieving revision 1.5
diff -u -p -r1.5 tc-spu.c
--- gas/config/tc-spu.c	11 May 2007 03:10:11 -0000	1.5
+++ gas/config/tc-spu.c	4 Jun 2007 23:59:31 -0000
@@ -820,8 +820,9 @@ spu_cons (int nbytes)
 
   do
     {
-      expression (&exp);
-      if (exp.X_op == O_symbol
+      deferred_expression (&exp);
+      if ((exp.X_op == O_symbol
+	   || exp.X_op == O_constant)
 	  && strncasecmp (input_line_pointer, "@ppu", 4) == 0)
 	{
 	  char *p = frag_more (nbytes);
@@ -873,6 +874,8 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UN
     *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   else if (fixp->fx_subsy)
     *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
+  else
+    abort ();
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   if (reloc->howto == (reloc_howto_type *) NULL)
@@ -987,6 +990,10 @@ md_apply_fix (fixS *fixP, valueT *valP, 
 
   fixP->fx_addnumber = val;
 
+  if (fixP->fx_r_type == BFD_RELOC_SPU_PPU32
+      || fixP->fx_r_type == BFD_RELOC_SPU_PPU64)
+    return;
+
   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
     {
       fixP->fx_done = 1;
Index: gas/config/tc-spu.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.h,v
retrieving revision 1.5
diff -u -p -r1.5 tc-spu.h
--- gas/config/tc-spu.h	29 May 2007 02:10:09 -0000	1.5
+++ gas/config/tc-spu.h	4 Jun 2007 23:59:31 -0000
@@ -85,8 +85,18 @@ struct tc_fix_info {
 /* We don't need to do anything special for undefined symbols.  */
 #define md_undefined_symbol(s) 0
 
-/* We have no special operand handling.  */
-#define md_operand(e)
+extern symbolS *section_symbol (asection *);
+#define md_operand(e) \
+  do {								\
+    if (strncasecmp (input_line_pointer, "@ppu", 4) == 0)	\
+      {								\
+	e->X_op = O_symbol;					\
+	if (abs_section_sym == NULL)				\
+	  abs_section_sym = section_symbol (absolute_section);	\
+	e->X_add_symbol = abs_section_sym;			\
+	e->X_add_number = 0;					\
+      }								\
+  } while (0)
 
 /* Fill in rs_align_code fragments.  */
 extern void spu_handle_align PARAMS ((fragS *));

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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