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]

SPU relocs for PPU syms


This offers another way for SPU executables to access PPU symbols.
The _EAR_ symbol method proved inadequate to handle new spu-gcc
features currently being developed, because it only allows one
location in the SPU executable to be initialised to a given PPU symbol
value.  So this extends the assembler, linker, and embedspu with some
new relocations.

".long foo@ppu" in assembly now generates an R_SPU_PPU32 reloc against
foo, which is emitted by the linker and converted by embedspu to an
R_PPC_ADDR32 (or R_PPC64_ADDR32) against foo in PPU land.  (foo can
also be used as a normal SPU symbol without clashing.)

".quad foo@ppu" similarly generates an R_SPU_PPU64 reloc, which is
converted to an R_PPC_ADDR32 in the low word or an R_PPC64_ADDR64.

You can also use foo+/-constant@ppu or foo@ppu+/-constant.

include/elf/
	* spu.h (R_SPU_PPU32, R_SPU_PPU64): Define.
bfd/
	* reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.
	* elf-bfd.h (struct elf_backend_data): Change return type of
	elf_backend_relocate_section to int.
	* elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and
	R_SPU_PPU64.
	(spu_elf_bfd_to_reloc_type): Convert new relocs.
	(spu_elf_count_relocs): New function.
	(elf_backend_count_relocs): Define.
	(spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and
	R_SPU_PPU64 relocs.
	* elflink.c (elf_link_input_bfd): Emit relocs if relocate_section
	returns 2.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
gas/
	* config/tc-spu.c (md_pseudo_table): Add int, long, quad.  Call
	spu_cons for word.
	(md_assemble): Tidy use of insn.flag.
	(get_imm): Likewise.  Handle uppercase input too.
	(spu_cons): New function.
	* config/tc-spu.h (tc_fix_adjustable): Don't adjust SPU_PPU relocs.
	(TC_FORCE_RELOCATION): Don't resolve them either.
binutils/
	* embedspu.sh (find_prog): Prefer prog in same dir as embedspu
	over one found on the users path.
	(main): Generate .reloc for each R_SPU_PPU* reloc.

Index: include/elf/spu.h
===================================================================
RCS file: /cvs/src/src/include/elf/spu.h,v
retrieving revision 1.1
diff -u -p -r1.1 spu.h
--- include/elf/spu.h	25 Oct 2006 06:49:18 -0000	1.1
+++ include/elf/spu.h	8 May 2007 01:34:17 -0000
@@ -39,6 +39,8 @@ START_RELOC_NUMBERS (elf_spu_reloc_type)
      RELOC_NUMBER (R_SPU_ADDR10I,	11)
      RELOC_NUMBER (R_SPU_ADDR16I,	12)
      RELOC_NUMBER (R_SPU_REL32,		13)
+     RELOC_NUMBER (R_SPU_PPU32,		14)
+     RELOC_NUMBER (R_SPU_PPU64,		15)
 END_RELOC_NUMBERS (R_SPU_max)
 
 /* Program header extensions */
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.231
diff -u -p -r1.231 elf-bfd.h
--- bfd/elf-bfd.h	17 Apr 2007 20:09:51 -0000	1.231
+++ bfd/elf-bfd.h	8 May 2007 01:33:43 -0000
@@ -792,8 +792,11 @@ struct elf_backend_data
      STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
      going to be the section symbol corresponding to the output
      section, which means that the addend must be adjusted
-     accordingly.  */
-  bfd_boolean (*elf_backend_relocate_section)
+     accordingly.
+
+     Returns FALSE on error, TRUE on success, 2 if successful and
+     relocations should be written for this section.  */
+  int (*elf_backend_relocate_section)
     (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
      asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
      Elf_Internal_Sym *local_syms, asection **local_sections);
Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.15
diff -u -p -r1.15 elf32-spu.c
--- bfd/elf32-spu.c	8 May 2007 02:29:27 -0000	1.15
+++ bfd/elf32-spu.c	8 May 2007 02:38:09 -0000
@@ -78,6 +78,12 @@ static reloc_howto_type elf_howto_table[
   HOWTO (R_SPU_REL32,   0, 2, 32, TRUE,  0, complain_overflow_dont,
 	 bfd_elf_generic_reloc, "SPU_REL32",
 	 FALSE, 0, 0xffffffff, TRUE),
+  HOWTO (R_SPU_PPU32,   0, 2, 32, FALSE,  0, complain_overflow_dont,
+	 bfd_elf_generic_reloc, "SPU_PPU32",
+	 FALSE, 0, 0xffffffff, FALSE),
+  HOWTO (R_SPU_PPU64,   0, 4, 64, FALSE,  0, complain_overflow_dont,
+	 bfd_elf_generic_reloc, "SPU_PPU64",
+	 FALSE, 0, -1, FALSE),
 };
 
 static struct bfd_elf_special_section const spu_elf_special_sections[] = {
@@ -120,6 +126,10 @@ spu_elf_bfd_to_reloc_type (bfd_reloc_cod
       return R_SPU_ADDR32;
     case BFD_RELOC_32_PCREL:
       return R_SPU_REL32;
+    case BFD_RELOC_SPU_PPU32:
+      return R_SPU_PPU32;
+    case BFD_RELOC_SPU_PPU64:
+      return R_SPU_PPU64;
     }
 }
 
@@ -2627,6 +2637,26 @@ spu_elf_final_link (bfd *output_bfd, str
   return bfd_elf_final_link (output_bfd, info);
 }
 
+/* Called when not normally emitting relocs, ie. !info->relocatable
+   and !info->emitrelocations.  Returns a count of special relocs
+   that need to be emitted.  */
+
+static unsigned int
+spu_elf_count_relocs (asection *sec, Elf_Internal_Rela *relocs)
+{
+  unsigned int count = 0;
+  Elf_Internal_Rela *relend = relocs + sec->reloc_count;
+
+  for (; relocs < relend; relocs++)
+    {
+      int r_type = ELF32_R_TYPE (relocs->r_info);
+      if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+	++count;
+    }
+
+  return count;
+}
+
 /* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD.  */
 
 static bfd_boolean
@@ -2644,6 +2674,7 @@ spu_elf_relocate_section (bfd *output_bf
   Elf_Internal_Rela *rel, *relend;
   struct spu_link_hash_table *htab;
   bfd_boolean ret = TRUE;
+  bfd_boolean emit_these_relocs = FALSE;
 
   htab = spu_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -2669,10 +2700,15 @@ spu_elf_relocate_section (bfd *output_bf
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
+      if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+	{
+	  emit_these_relocs = TRUE;
+	  continue;
+	}
+
       howto = elf_howto_table + r_type;
       unresolved_reloc = FALSE;
       warned = FALSE;
-
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -2796,6 +2832,31 @@ spu_elf_relocate_section (bfd *output_bf
 	}
     }
 
+  if (ret
+      && emit_these_relocs
+      && !info->relocatable
+      && !info->emitrelocations)
+    {
+      Elf_Internal_Rela *wrel;
+      Elf_Internal_Shdr *rel_hdr;
+
+      wrel = rel = relocs;
+      relend = relocs + input_section->reloc_count;
+      for (; rel < relend; rel++)
+	{
+	  int r_type;
+
+	  r_type = ELF32_R_TYPE (rel->r_info);
+	  if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+	    *wrel++ = *rel;
+	}
+      input_section->reloc_count = wrel - relocs;
+      /* Backflips for _bfd_elf_link_output_relocs.  */
+      rel_hdr = &elf_section_data (input_section)->rel_hdr;
+      rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
+      ret = 2;
+    }
+
   return ret;
 }
 
@@ -3059,6 +3120,7 @@ spu_elf_modify_program_headers (bfd *abf
 #define bfd_elf32_bfd_reloc_type_lookup		spu_elf_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup	spu_elf_reloc_name_lookup
 #define elf_info_to_howto			spu_elf_info_to_howto
+#define elf_backend_count_relocs		spu_elf_count_relocs
 #define elf_backend_relocate_section		spu_elf_relocate_section
 #define elf_backend_symbol_processing		spu_elf_backend_symbol_processing
 #define elf_backend_link_output_symbol_hook	spu_elf_output_symbol_hook
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.261
diff -u -p -r1.261 elflink.c
--- bfd/elflink.c	7 May 2007 14:47:28 -0000	1.261
+++ bfd/elflink.c	8 May 2007 01:33:56 -0000
@@ -8198,7 +8198,7 @@ _bfd_elf_check_kept_section (asection *s
 static bfd_boolean
 elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
 {
-  bfd_boolean (*relocate_section)
+  int (*relocate_section)
     (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
      Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
   bfd *output_bfd;
@@ -8212,7 +8212,6 @@ elf_link_input_bfd (struct elf_final_lin
   asection **ppsection;
   asection *o;
   const struct elf_backend_data *bed;
-  bfd_boolean emit_relocs;
   struct elf_link_hash_entry **sym_hashes;
 
   output_bfd = finfo->output_bfd;
@@ -8225,9 +8224,6 @@ elf_link_input_bfd (struct elf_final_lin
   if ((input_bfd->flags & DYNAMIC) != 0)
     return TRUE;
 
-  emit_relocs = (finfo->info->relocatable
-		 || finfo->info->emitrelocations);
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   if (elf_bad_symtab (input_bfd))
     {
@@ -8443,6 +8439,7 @@ elf_link_input_bfd (struct elf_final_lin
 	  Elf_Internal_Rela *internal_relocs;
 	  bfd_vma r_type_mask;
 	  int r_sym_shift;
+	  int ret;
 
 	  /* Get the swapped relocs.  */
 	  internal_relocs
@@ -8580,14 +8577,17 @@ elf_link_input_bfd (struct elf_final_lin
 	     corresponding to the output section, which will require
 	     the addend to be adjusted.  */
 
-	  if (! (*relocate_section) (output_bfd, finfo->info,
+	  ret = (*relocate_section) (output_bfd, finfo->info,
 				     input_bfd, o, contents,
 				     internal_relocs,
 				     isymbuf,
-				     finfo->sections))
+				     finfo->sections);
+	  if (!ret)
 	    return FALSE;
 
-	  if (emit_relocs)
+	  if (ret == 2
+	      || finfo->info->relocatable
+	      || finfo->info->emitrelocations)
 	    {
 	      Elf_Internal_Rela *irela;
 	      Elf_Internal_Rela *irelaend;
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.165
diff -u -p -r1.165 reloc.c
--- bfd/reloc.c	26 Apr 2007 14:46:58 -0000	1.165
+++ bfd/reloc.c	8 May 2007 01:33:59 -0000
@@ -1972,6 +1972,10 @@ ENUMX
   BFD_RELOC_SPU_LO16
 ENUMX
   BFD_RELOC_SPU_HI16
+ENUMX
+  BFD_RELOC_SPU_PPU32
+ENUMX
+  BFD_RELOC_SPU_PPU64
 ENUMDOC
   SPU Relocations.
 
Index: binutils/embedspu.sh
===================================================================
RCS file: /cvs/src/src/binutils/embedspu.sh,v
retrieving revision 1.5
diff -u -p -r1.5 embedspu.sh
--- binutils/embedspu.sh	27 Mar 2007 02:10:58 -0000	1.5
+++ binutils/embedspu.sh	10 May 2007 02:59:02 -0000
@@ -38,12 +38,12 @@ mydir=`dirname "$0"`
 find_prog ()
 {
   prog=`echo $1 | sed "$program_transform_name"`
-  which $prog > /dev/null 2> /dev/null && return 0
   prog="$mydir/$prog"
   test -x "$prog" && return 0
   prog="$mydir/$1"
   test -x "$prog" && return 0
   prog=`echo $1 | sed "$program_transform_name"`
+  which $prog > /dev/null 2> /dev/null && return 0
   return 1
 }
 
@@ -95,7 +95,7 @@ main ()
     CC="$prog"
   fi
 
-  # Find readelf.  Any old readelf should do.  We only want to read syms.
+  # Find readelf.  Any old readelf should do.
   find_prog readelf
   if test $? -ne 0; then
     if which readelf > /dev/null 2> /dev/null; then
@@ -119,8 +119,13 @@ main ()
   toe=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *\.toe *[PROGN]*BITS *\([0-9a-f]*\).*,\1 \2,p'`
   toe_addr=`echo $toe | sed -n -e 's,.* ,,p'`
   toe=`echo $toe | sed -n -e 's, .*,,p'`
+  # For loaded sections, pick off section number, address, and file offset
   sections=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *[^ ]* *PROGBITS *\([0-9a-f]*\) *\([0-9a-f]*\).*,\1 \2 \3,p'`
   sections=`echo ${sections}`
+  # For relocation sections, pick off file offset and info (points to
+  # section where relocs apply)
+  relas=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *[0-9]*\] *[^ ]* *RELA *[0-9a-f]* *0*\([0-9a-f][0-9a-f]*\) .*\([0-9a-f][0-9a-f]*\) *[0-9a-f][0-9a-f]*$,\1 \2,p'`
+  relas=`echo ${relas}`
 
   # Build embedded SPU image.
   # 1. The whole SPU ELF file is written to .rodata.speelf
@@ -135,8 +140,10 @@ main ()
   #    write the address of the corresponding PowerPC symbol in a table
   #    built in .data.spetoe.  For _EAE_ symbols not in .toe, create
   #    .reloc commands to relocate their location directly.
-  # 3. Write a struct spe_program_handle to .data.
-  # 4. Write a table of _SPUEAR_ symbols.
+  # 3. Look for R_SPU_PPU32 and R_SPU_PPU64 relocations in the SPU ELF image
+  #    and create .reloc commands for them.
+  # 4. Write a struct spe_program_handle to .data.
+  # 5. Write a table of _SPUEAR_ symbols.
   ${CC} ${FLAGS} -x assembler-with-cpp -nostartfiles -nostdlib \
 	-Wa,-mbig -Wl,-r -Wl,-x -o ${OUTFILE} - <<EOF
  .section .rodata.speelf,"a",@progbits
@@ -179,6 +186,35 @@ $7 != "'${toe}'" && ! $7 in sec_off { \
 	print "#error Section not found for " $8; \
 } \
 '`
+`test -z "${relas}" || ${READELF} -r -W ${INFILE} | awk \
+'BEGIN { \
+	split ("'"${sections}"'", s, " "); \
+	for (i = 1; i in s; i += 3) { \
+	    sec_off[s[i]] = strtonum ("0x" s[i+2]) - strtonum ("0x" s[i+1]); \
+	} \
+	split ("'"${relas}"'", s, " "); \
+	for (i = 1; i in s; i += 2) { \
+	    rela[s[i]] = strtonum (s[i+1]); \
+	} \
+} \
+/^Relocation section/ { \
+	sec = substr($6, 3); \
+} \
+$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 "#else"; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + (substr($3, 10) == "64" ? 4 : 0)", R_PPC_ADDR32, " $5 "+0x" $7; \
+	print "#endif"; \
+} \
+$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 "#else"; \
+	print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " $6 "+0x" $8; \
+	print "#endif"; \
+} \
+'`
 
  .section .data,"aw",@progbits
  .globl ${SYMBOL}
Index: gas/config/tc-spu.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.c,v
retrieving revision 1.4
diff -u -p -r1.4 tc-spu.c
--- gas/config/tc-spu.c	23 Mar 2007 00:42:26 -0000	1.4
+++ gas/config/tc-spu.c	8 May 2007 01:34:05 -0000
@@ -51,9 +51,9 @@ struct spu_insn
 static const char *get_imm (const char *param, struct spu_insn *insn, int arg);
 static const char *get_reg (const char *param, struct spu_insn *insn, int arg,
 			    int accept_expr);
-
 static int calcop (struct spu_opcode *format, const char *param,
 		   struct spu_insn *insn);
+static void spu_cons (int);
 
 extern char *myname;
 static struct hash_control *op_hash = NULL;
@@ -82,14 +82,17 @@ const char FLT_CHARS[] = "dDfF";
 const pseudo_typeS md_pseudo_table[] =
 {
   {"align", s_align_ptwo, 4},
+  {"bss", s_lcomm_bytes, 1},
   {"def", s_set, 0},
   {"dfloat", float_cons, 'd'},
   {"ffloat", float_cons, 'f'},
   {"global", s_globl, 0},
   {"half", cons, 2},
-  {"bss", s_lcomm_bytes, 1},
+  {"int", spu_cons, 4},
+  {"long", spu_cons, 4},
+  {"quad", spu_cons, 8},
   {"string", stringer, 1},
-  {"word", cons, 4},
+  {"word", spu_cons, 4},
   /* Force set to be treated as an instruction.  */
   {"set", NULL, 0},
   {".set", s_set, 0},
@@ -351,13 +354,14 @@ md_assemble (char *op)
         fixS *fixP;
         bfd_reloc_code_real_type reloc = arg_encode[insn.reloc_arg[i]].reloc;
 	int pcrel = 0;
+
         if (reloc == BFD_RELOC_SPU_PCREL9a
 	    || reloc == BFD_RELOC_SPU_PCREL9b
             || reloc == BFD_RELOC_SPU_PCREL16)
 	  pcrel = 1;
-	if (insn.flag[i] & 1)
+	if (insn.flag[i] == 1)
 	  reloc = BFD_RELOC_SPU_HI16;
-	else if (insn.flag[i] & 2)
+	else if (insn.flag[i] == 2)
 	  reloc = BFD_RELOC_SPU_LO16;
 	fixP = fix_new_exp (frag_now,
 			    thisfrag - frag_now->fr_literal,
@@ -585,30 +589,30 @@ get_imm (const char *param, struct spu_i
   int low = 0, high = 0;
   int reloc_i = insn->reloc_arg[0] >= 0 ? 1 : 0;
 
-  if (strncmp (param, "%lo(", 4) == 0)
+  if (strncasecmp (param, "%lo(", 4) == 0)
     {
       param += 3;
       low = 1;
       as_warn (_("Using old style, %%lo(expr), please change to PPC style, expr@l."));
     }
-  else if (strncmp (param, "%hi(", 4) == 0)
+  else if (strncasecmp (param, "%hi(", 4) == 0)
     {
       param += 3;
       high = 1;
       as_warn (_("Using old style, %%hi(expr), please change to PPC style, expr@h."));
     }
-  else if (strncmp (param, "%pic(", 5) == 0)
+  else if (strncasecmp (param, "%pic(", 5) == 0)
     {
       /* Currently we expect %pic(expr) == expr, so do nothing here.
-       * i.e. for code loaded at address 0 $toc will be 0.  */
+	 i.e. for code loaded at address 0 $toc will be 0.  */
       param += 4;
     }
       
   if (*param == '$')
     {
       /* Symbols can start with $, but if this symbol matches a register
-       * name, it's probably a mistake.   The only way to avoid this
-       * warning is to rename the symbol.  */
+	 name, it's probably a mistake.  The only way to avoid this
+	 warning is to rename the symbol.  */
       struct spu_insn tmp_insn;
       const char *np = get_reg (param, &tmp_insn, arg, 0);
 
@@ -623,7 +627,7 @@ get_imm (const char *param, struct spu_i
   input_line_pointer = save_ptr;
 
   /* Similar to ppc_elf_suffix in tc-ppc.c.  We have so few cases to
-   * handle we do it inlined here. */
+     handle we do it inlined here. */
   if (param[0] == '@' && !ISALNUM (param[2]) && param[2] != '@')
     {
       if (param[1] == 'h' || param[1] == 'H')
@@ -638,10 +642,10 @@ get_imm (const char *param, struct spu_i
 	}
     }
 
-  val = insn->exp[reloc_i].X_add_number;
-
   if (insn->exp[reloc_i].X_op == O_constant)
     {
+      val = insn->exp[reloc_i].X_add_number;
+
       if (emulate_apuasm)
 	{
 	  /* Convert the value to a format we expect. */ 
@@ -691,9 +695,9 @@ get_imm (const char *param, struct spu_i
     {
       insn->reloc_arg[reloc_i] = arg;
       if (high)
-	insn->flag[reloc_i] |= 1;
-      if (low)
-	insn->flag[reloc_i] |= 2;
+	insn->flag[reloc_i] = 1;
+      else if (low)
+	insn->flag[reloc_i] = 2;
     }
 
   return param;
@@ -802,6 +806,52 @@ md_create_long_jump (char *ptr,
 }
 #endif
 
+/* Support @ppu on symbols referenced in .int/.long/.word/.quad.  */
+static void
+spu_cons (int nbytes)
+{
+  expressionS exp;
+
+  if (is_it_end_of_statement ())
+    {
+      demand_empty_rest_of_line ();
+      return;
+    }
+
+  do
+    {
+      expression (&exp);
+      if (exp.X_op == O_symbol
+	  && strncasecmp (input_line_pointer, "@ppu", 4) == 0)
+	{
+	  char *p = frag_more (nbytes);
+	  enum bfd_reloc_code_real reloc;
+
+	  /* Check for identifier@suffix+constant.  */
+	  input_line_pointer += 4;
+	  if (*input_line_pointer == '-' || *input_line_pointer == '+')
+	    {
+	      expressionS new_exp;
+
+	      expression (&new_exp);
+	      if (new_exp.X_op == O_constant)
+		exp.X_add_number += new_exp.X_add_number;
+	    }
+
+	  reloc = nbytes == 4 ? BFD_RELOC_SPU_PPU32 : BFD_RELOC_SPU_PPU64;
+	  fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes,
+		       &exp, 0, reloc);
+	}
+      else
+	emit_expr (&exp, nbytes);
+    }
+  while (*input_line_pointer++ == ',');
+
+  /* Put terminator back into stream.  */
+  input_line_pointer--;
+  demand_empty_rest_of_line ();
+}
+
 int
 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
 			       segT segment_type ATTRIBUTE_UNUSED)
Index: gas/config/tc-spu.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.h,v
retrieving revision 1.3
diff -u -p -r1.3 tc-spu.h
--- gas/config/tc-spu.h	23 Mar 2007 00:42:26 -0000	1.3
+++ gas/config/tc-spu.h	11 May 2007 01:47:29 -0000
@@ -61,8 +61,12 @@ struct tc_fix_info {
     }						\
   while (0)
 
-/* Don't reduce function symbols to section symbols.  */
-#define tc_fix_adjustable(FIXP) (!S_IS_FUNCTION ((FIXP)->fx_addsy))
+/* Don't reduce function symbols to section symbols, and don't adjust
+   references to PPU symbols.  */
+#define tc_fix_adjustable(FIXP) \
+  (!(S_IS_FUNCTION ((FIXP)->fx_addsy)			\
+     || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32	\
+     || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64))
 
 /* Keep relocs on calls.  Branches to function symbols are tail or
    sibling calls.  */
@@ -73,6 +77,8 @@ struct tc_fix_info {
 	|| (FIXP)->tc_fix_data.insn_tag == M_BRA)	\
        && (FIXP)->fx_addsy != NULL			\
        && S_IS_FUNCTION ((FIXP)->fx_addsy))		\
+   || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32		\
+   || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64		\
    || generic_force_reloc (FIXP))
 
 /* Values passed to md_apply_fix don't include symbol values.  */

-- 
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]