Endianess attributes

2008-11-13 Thread Paul Chavent

Hi.

I wonder why there aren't any endianess attributes ?

For example we could write this :
int x __attribute__ ((endianess (lil))) = 0;

Is it a silly suggestion ?
No one need it ?
Is it a bad design need ?

Could someone give me some information ?

Thanks.

Paul CHAVENT


Endianess attribute

2009-07-02 Thread Paul Chavent

Hi.

I already have posted about the endianess attribute 
(http://gcc.gnu.org/ml/gcc/2008-11/threads.html#00146).

For some year, i really need this feature on c projects.

Today i would like to go inside the internals of gcc, and i would like to 
implement this feature as an exercise.

You already prevent me that it would be a hard task (aliasing, etc.), but i 
would like to begin with basic specs.


The spec could be :

- add an attribute (this description could change to be compatible with 
existing ones (diabdata for example))

  __attribute__ ((endian("big")))
  __attribute__ ((endian("lil")))

- this attribute only apply to ints

- this attribute only apply to variables declaration

- a pointer to this variable don't inherit the attribute (this behavior could 
change later, i don't know...)

- the test case is

  uint32_t x __attribute__ ((endian("big")));
  uint32_t * ptr_x = x;

  x = 0xDEADBEEF

  if(plf_is_little)
{
  assert((*ptr_x == 0xEFBEADDE));
}
  else if(plf_is_big)
{
  assert((*ptr_x == 0xDEADBEEF));
}




My first work is the patch below.

So my questions to the mailing list are :

- is it a good starting point ?

- how can i get the endianess of the target ?


Thank for your help and suggestion.


8<

diff -abBruN gcc-4.4.0.orig/gcc/c-common.c gcc-4.4.0.mod/gcc/c-common.c
--- gcc-4.4.0.orig/gcc/c-common.c   2009-03-30 19:42:27.0 +0200
+++ gcc-4.4.0.mod/gcc/c-common.c2009-07-02 11:10:28.0 +0200
@@ -522,6 +522,7 @@
 static bool check_case_bounds (tree, tree, tree *, tree *);

 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
+static tree handle_endian_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
 static tree handle_common_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
@@ -761,6 +762,8 @@
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
   { "packed", 0, 0, false, false, false,
  handle_packed_attribute },
+  { "endian", 1, 1, false, false, false,
+ handle_endian_attribute },
   { "nocommon",   0, 0, true,  false, false,
  handle_nocommon_attribute },
   { "common", 0, 0, true,  false, false,
@@ -5155,6 +5158,58 @@
   return NULL_TREE;
 }

+/* Handle an "endian" attribute; arguments as in
+   struct attribute_spec.handler.
+   IDENTIFIER_POINTER (name) gives "endian"
+   TREE_CODE (arg) should be a STRING_CST
+*/
+
+static tree
+handle_endian_attribute (tree *node, tree name, tree args,
+int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  tree arg = TREE_VALUE (args);
+
+  if (TREE_CODE (arg) != STRING_CST)
+{
+  error ("argument of %qE attribute should be a string\n", name);
+}
+  else if (TREE_CODE (*node) != FIELD_DECL &&
+   TREE_CODE (*node) != VAR_DECL  &&
+   TREE_CODE (*node) != TYPE_DECL)
+{
+  error ("%qE only support FIELD_DECL, VAR_DECL and TYPE_DECL\n", name);
+}
+  else
+{
+  if (!strcmp (TREE_STRING_POINTER (arg), "little"))
+{
+  if(TARGET_BIG_ENDIAN)
+{
+  DECL_SWAP(*node) = 1;
+  debug_tree(*node);
+}
+}
+  else if (!strcmp (TREE_STRING_POINTER (arg), "big"))
+{
+  if(TARGET_LITTLE_ENDIAN)
+{
+  DECL_SWAP(*node) = 1;
+  debug_tree(*node);
+}
+}
+  else
+{
+  error ("argument of %qE attribute should be 'little' or 'big'\n", 
name);
+  *no_add_attrs = true;
+}
+}
+
+  *no_add_attrs = true;
+
+  return NULL_TREE;
+}
+
 /* Handle a "nocommon" attribute; arguments as in
struct attribute_spec.handler.  */

diff -abBruN gcc-4.4.0.orig/gcc/tree.h gcc-4.4.0.mod/gcc/tree.h
--- gcc-4.4.0.orig/gcc/tree.h   2009-03-23 17:29:33.0 +0100
+++ gcc-4.4.0.mod/gcc/tree.h2009-07-02 11:10:28.0 +0200
@@ -2721,13 +2721,15 @@
   /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
  In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR.  */
   unsigned decl_flag_3 : 1;
+  /* In FIELD_DECL, VAR_DECL and TYPE_DECL this is DECL_SWAP.  */
+  unsigned decl_flag_4 : 1;
   /* Logically, these two would go in a theoretical base shared by var and
  parm decl. */
   unsigned gimple_reg_flag : 1;
   /* In a DECL with pointer type, set if no TBAA should be done.  */
   unsigned no_tbaa_flag : 1;
   /* Padding so that 'align' can be on a 32-bit boundary.  */
-  unsigned decl_common_unused : 2;
+  unsigned decl_common_unused : 1;

   unsigned int align : 24;
   /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
@@ -2854,6 +2856,10 @@
 #define DECL_NONADDRESSABLE_P(NODE) \