This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[Patch] H8/300 : Add target specific option -msort-data for H8/300-ELF target


Hi,

Please find below a patch for H8/300 (ELF) target, which generate
separate sections for variables with different data types. Arrays are
also treated same way. This is done for initialized global variables and
read only (const) data. 

This patch will reduce padding (memory gaps) between variables with
different data types. Since characters will be 1 byte aligned, short
integers will be 2 byte aligned and long integers will be 4 byte aligned
and all will be placed in different sections. This will help in reducing
RAM as well as ROM size. 

All characters will go in .d_char section, short integers in .d_short
section, long integers in .d_long section, read only characters will go
in .rod_char section, read only short integers will go in .rod_short
section and read only long integers will go in .rod_long section. 

The default is not to sort variables as per data type.

No new regressions found.

Custom linker script may need to be modified like following,
.rodata : 
{
 *(.rodata)
 *(.rodata.*)
 *(.rod_char)
 *(.rod_long)
 *(.rod_short)
 _erodata = .;
} > rom

.data : AT (_mdata) { 
_data = .;
*(.data) 
*(.d_char)
*(.d_long)
*(.d_short)
_edata = .; 
} > ram

========================Start Of Patch==================================
ChangeLog
2005-06-14  Anil Paranjpe <anilp1@kpitcummins.com>
	* config/h8300/h8300.c (h8300_select_section): New function.
	* config/h8300/elf.h : Define EXTRA_SECTIONS,
EXTRA_SECTION_FUNCTIONS,
	CHAR_DATA_SECTION_FUNCTION, SHORT_DATA_SECTION_FUNCTION,
LONG_DATA_SECTION_FUNCTION,
	CHAR_RODATA_SECTION_FUNCTION, SHORT_RODATA_SECTION_FUNCTION,
LONG_RODATA_SECTION_FUNCTION,
	TARGET_ASM_SELECT_SECTION, CHAR_DATA_SECTION_ASM_OP,
SHORT_DATA_SECTION_ASM_OP,
	LONG_DATA_SECTION_ASM_OP, CHAR_RODATA_SECTION_ASM_OP,
SHORT_RODATA_SECTION_ASM_OP,
	LONG_RODATA_SECTION_ASM_OP.	
	* config/h8300/h8300.opt (TARGET_SWITCHES): Add "sort-data" to
create separate sections
	for variables with different data types.
	* doc/invoke.texi (H8/300 Options): Document "msort-data"
option.

========================================================================
--- gcc-4.1-20050611/gcc/config/h8300/h8300.c.orig	2005-05-25
09:46:53.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/h8300/h8300.c	2005-06-13
12:07:23.000000000 +0530
@@ -112,6 +112,14 @@ static unsigned int  h8300_bitfield_leng
 static unsigned int  h8300_binary_length          (rtx, const
h8300_length_table *);
 static bool          h8300_short_move_mem_p       (rtx, enum rtx_code);
 static unsigned int  h8300_move_length            (rtx *, const
h8300_length_table *);
+static void h8300_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
+void char_data_section(void);
+void short_data_section(void);
+void long_data_section(void);
+void char_rodata_section(void);
+void short_rodata_section(void);
+void long_rodata_section(void);
+
 
 /* CPU_TYPE, says what cpu we're compiling for.  */
 int cpu_type;
@@ -5712,6 +5725,78 @@ h8300_return_in_memory (tree type, tree 
   return (TYPE_MODE (type) == BLKmode
 	  || GET_MODE_SIZE (TYPE_MODE (type)) > (TARGET_H8300 ? 4 : 8));
 }
+/*
+  This function creates separate sections for variables with different
data types.
+  Arrays are also treated in same way.
+*/
+static void
+h8300_select_section (tree decl, int reloc,
+	 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+{
+  if (TARGET_SORT_DATA)
+  {
+      if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+          TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == QImode) 
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	char_rodata_section ();
+	  else 
+                char_data_section ();
+      }
+      else if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+               TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == HImode) 
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	short_rodata_section ();
+	  else 
+                short_data_section ();
+      }	
+      else if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+	       (TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == SImode ||
+	        TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == DImode) )
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	long_rodata_section ();
+	  else 
+                long_data_section ();
+
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == QImode)
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	char_rodata_section ();
+          else
+	        char_data_section ();
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == HImode)
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	short_rodata_section ();
+          else
+	        short_data_section ();
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == SImode ||
+	       TYPE_MODE(TREE_TYPE(decl)) == DImode )
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	long_rodata_section ();
+          else
+	        long_data_section ();
+      }
+      else
+  	  goto def_sel;
+  }
+ else
+  {
+def_sel:
+#if __ELF__
+           default_elf_select_section (decl, reloc, align);
+#else
+	   default_select_section (decl, reloc, align);
+#endif
+  }
+}
+			
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE

--- gcc-4.1-20050611/gcc/config/h8300/elf.h.orig	2004-07-08
09:10:30.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/h8300/elf.h	2005-06-13
09:42:53.000000000 +0530
@@ -42,4 +42,100 @@ Boston, MA 02111-1307, USA.  */
 #undef LINK_SPEC
 #define LINK_SPEC "%{mh:%{mn:-m h8300hnelf}} %{mh:%{!mn:-m h8300helf}}
%{ms:%{mn:-m h8300snelf}} %{ms:%{!mn:-m h8300self}} %{msx:%{mn:-m
h8300sxnelf;:-m h8300sxelf}}"
 
+#undef  TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION  h8300_select_section
+ 
+#define CHAR_DATA_SECTION_ASM_OP	"\t.section\t.d_char,\"aw\""
+#define SHORT_DATA_SECTION_ASM_OP   	"\t.section\t.d_short,\"aw\""
+#define LONG_DATA_SECTION_ASM_OP        "\t.section\t.d_long,\"aw\""
+#define CHAR_RODATA_SECTION_ASM_OP	"\t.section\t.rod_char,\"ax\""
+#define SHORT_RODATA_SECTION_ASM_OP   	"\t.section\t.rod_short,\"ax\""
+#define LONG_RODATA_SECTION_ASM_OP      "\t.section\t.rod_long,\"ax\""
+
+
+#define EXTRA_SECTIONS in_char_data, in_short_data, in_long_data,
in_char_rodata, in_short_rodata, in_long_rodata
+
+extern void char_data_section(void);
+extern void short_data_section(void);
+extern void long_data_section(void);
+extern void char_rodata_section(void);
+extern void short_rodata_section(void);
+extern void long_rodata_section(void);
+
+#define EXTRA_SECTION_FUNCTIONS
\
+     CHAR_DATA_SECTION_FUNCTION
\
+     SHORT_DATA_SECTION_FUNCTION
\
+     LONG_DATA_SECTION_FUNCTION
\
+     CHAR_RODATA_SECTION_FUNCTION
\
+     SHORT_RODATA_SECTION_FUNCTION
\
+     LONG_RODATA_SECTION_FUNCTION
+
+
+#define CHAR_DATA_SECTION_FUNCTION
\
+void
\
+char_data_section ()
\
+{
\
+  if (in_section != in_char_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", CHAR_DATA_SECTION_ASM_OP);
\
+      in_section = in_char_data;
\
+    }
\
+}
+
+#define SHORT_DATA_SECTION_FUNCTION
\
+void
\
+short_data_section ()
\
+{
\
+  if (in_section != in_short_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", SHORT_DATA_SECTION_ASM_OP);
\
+      in_section = in_short_data;
\
+    }
\
+}
+
+#define LONG_DATA_SECTION_FUNCTION
\
+void
\
+long_data_section ()
\
+{
\
+  if (in_section != in_long_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", LONG_DATA_SECTION_ASM_OP);
\
+      in_section = in_long_data;
\
+    }
\
+}
+		
+#define CHAR_RODATA_SECTION_FUNCTION
\
+void
\
+char_rodata_section ()
\
+{
\
+  if (in_section != in_char_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", CHAR_RODATA_SECTION_ASM_OP);
\
+      in_section = in_char_rodata;
\
+    }
\
+}
+
+#define SHORT_RODATA_SECTION_FUNCTION
\
+void
\
+short_rodata_section ()
\
+{
\
+  if (in_section != in_short_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", SHORT_RODATA_SECTION_ASM_OP);
\
+      in_section = in_short_rodata;
\
+    }
\
+}
+
+#define LONG_RODATA_SECTION_FUNCTION
\
+void
\
+long_rodata_section ()
\
+{
\
+  if (in_section != in_long_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", LONG_RODATA_SECTION_ASM_OP);
\
+      in_section = in_long_rodata;
\
+    }
\
+}
+
+
 #endif /* h8300/elf.h */

--- gcc-4.1-20050611/gcc/config/h8300/h8300.opt.orig	2005-03-17
21:29:08.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/h8300/h8300.opt	2005-06-07
16:14:20.000000000 +0530
@@ -61,3 +61,7 @@ Enable the normal mode
 malign-300
 Target RejectNegative Mask(ALIGN_300)
 Use H8/300 alignment rules
+
+msort-data
+Target RejectNegative Mask(SORT_DATA)
+Generate separate sections for variables with different data types

--- gcc-4.1-20050611/gcc/doc/invoke.texi.orig	2005-06-02
22:43:26.000000000 +0530
+++ gcc-4.1-20050611/gcc/doc/invoke.texi	2005-06-09
10:06:52.000000000 +0530
@@ -485,7 +485,7 @@ Objective-C and Objective-C++ Dialects}.
 -mcpu=@var{cpu}}
 
 @emph{H8/300 Options}
-@gccoptlist{-mrelax  -mh  -ms  -mn  -mint32  -malign-300}
+@gccoptlist{-mrelax  -mh  -ms  -mn  -mint32  -malign-300 -msort-data}
 
 @emph{HPPA Options}
 @gccoptlist{-march=@var{architecture-type} @gol
@@ -8470,6 +8470,13 @@ The default for the H8/300H and H8S is t
 byte boundaries.
 @option{-malign-300} causes them to be aligned on 2 byte boundaries.
 This option has no effect on the H8/300.
+
+@item -msort-data
+@opindex msort-data
+Generate separate sections for initialized global variables with
different data types.
+Arrays are also treated same way. All characters will go in .d_char
section, 
+short integers in .d_short section, long integers in .d_long section,
read only
+characters will go in .rod_char section, read only short integers will
go in
+.rod_short section and read only long integers will go in .rod_long
section.
+The default is not to sort variables as per data type.
 @end table
 
 @node HPPA Options

==============================End Of Patch==============================

Regards,
Anil Paranjpe
KPIT Cummins InfoSystems Ltd.
Pune, India

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Free download of GNU based tool-chains for Renesas' SH and H8 Series.
The following site also offers free technical support to its users. 
Visit http://www.kpitgnutools.com for details. 
Latest versions of KPIT GNU tools were released on June 1, 2005.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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