PATCH: handle user-defined alignment on SPU

trevor_smigiel@playstation.sony.com trevor_smigiel@playstation.sony.com
Thu Dec 7 03:51:00 GMT 2006


The following test case will fail, with or without this patch.

  extern void exit (int);
  extern void abort (void);
  int a = 1;
  int b __attribute__ ((__aligned__(4))) = 2;
  int main()
  {
     a = 3;
     if (b != 2)
       abort ();
     exit (0);
  }

Can you adjust your patch to make it work?  Perhaps special
data sections for data with less than 16-byte alignment.

The SPU backend assumes all objects are aligned to 16 bytes, which means
that they are also all padded to 16 bytes.  It does this so it can use
single instruction loads and stores to access scalar objects.

Trevor

* Ben Elliston <bje@au1.ibm.com> [2006-12-06 02:53]:
> This patch corrects the behaviour of user-defined alignment on
> variables that have a desired alignment less than 16.  Tested on
> spu-unknown-elf with no regressions.
> 
> Okay for the trunk?
> 
> 2006-12-06  Ulrich Weigand  <uweigand@de.ibm.com>
> 
> 	* config/spu/spu.c (TARGET_ENCODE_SECTION_INFO): Define.
> 	(spu_encode_section_info): New.
> 	* config/spu/spu.h (ALIGNED_SYMBOL_REF_P): Adjust.
> 	(SYMBOL_FLAG_ALIGN1): New.
> 
> Index: spu.h
> ===================================================================
> --- spu.h	(revision 119574)
> +++ spu.h	(working copy)
> @@ -86,6 +86,7 @@ extern int target_flags;
>  /* symbol_ref's of functions are not aligned to 16 byte boundary. */
>  #define ALIGNED_SYMBOL_REF_P(X) \
>  	(GET_CODE (X) == SYMBOL_REF \
> +          && (SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1) == 0 \
>  	  && (! SYMBOL_REF_FUNCTION_P (X) \
>  	      || align_functions >= 16))
>  
> @@ -372,6 +373,9 @@ warn_main = 0;								\
>  #define FUNCTION_VALUE_REGNO_P(N) ((N) >= (FIRST_RETURN_REGNUM) && (N) <= (LAST_RETURN_REGNUM))
>  
>  
> +/* Machine-specific symbol_ref flags.  */
> +#define SYMBOL_FLAG_ALIGN1	(SYMBOL_FLAG_MACH_DEP << 0)
> +
>  /* Aggregate Return */
>  
>  #define DEFAULT_PCC_STRUCT_RETURN 0
> Index: spu.c
> ===================================================================
> --- spu.c	(revision 119574)
> +++ spu.c	(working copy)
> @@ -128,6 +128,7 @@ static unsigned char spu_rtx_costs (rtx 
>  static unsigned char spu_function_ok_for_sibcall (tree decl, tree exp);
>  static void spu_init_libfuncs (void);
>  static bool spu_return_in_memory (tree type, tree fntype);
> +static void spu_encode_section_info(tree, rtx, int);
>  
>  extern const char *reg_names[];
>  rtx spu_compare_op0, spu_compare_op1;
> @@ -230,6 +231,9 @@ const struct attribute_spec spu_attribut
>  #undef TARGET_RETURN_IN_MEMORY
>  #define TARGET_RETURN_IN_MEMORY spu_return_in_memory
>  
> +#undef  TARGET_ENCODE_SECTION_INFO
> +#define TARGET_ENCODE_SECTION_INFO spu_encode_section_info
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>  
>  /* Sometimes certain combinations of command options do not make sense
> @@ -2990,6 +2994,20 @@ aligned_mem_p (rtx mem)
>    return 0;
>  }
>  
> +/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
> +   into its SYMBOL_REF_FLAGS.  */
> +static void
> +spu_encode_section_info (tree decl, rtx rtl, int first)
> +{
> +  default_encode_section_info (decl, rtl, first);
> +
> +  /* If a variable has a forced alignment to < 16 bytes, mark it with
> +     SYMBOL_FLAG_ALIGN1.  */
> +  if (TREE_CODE (decl) == VAR_DECL
> +      && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 128)
> +    SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
> +}
> +
>  /* Return TRUE if we are certain the mem refers to a complete object
>     which is both 16-byte aligned and padded to a 16-byte boundary.  This
>     would make it safe to store with a single instruction. 



More information about the Gcc-patches mailing list