+2004-08-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_asm_output_aligned_bss, pa_asm_output_aligned_common,
+ pa_asm_output_aligned_local): New functions.
+ * pa-protos.h: Add prototypes for pa_asm_output_aligned_bss,
+ pa_asm_output_aligned_common and pa_asm_output_aligned_local.
+ * pa-pro-end.h (ASM_OUTPUT_ALIGNED_COMMON): Use
+ pa_asm_output_aligned_common.
+ (ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
+ * pa.h (ASM_OUTPUT_ALIGNED_BSS): New macro.
+ (ASM_OUTPUT_ALIGNED_COMMON): Use pa_asm_output_aligned_common.
+ (ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
+ * pa64-hpux.h (MAX_OFILE_ALIGNMENT): New macro.
+ (ASM_OUTPUT_ALIGNED_COMMON): Use pa_asm_output_aligned_common.
+ (ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
+ * som.h (MAX_OFILE_ALIGNMENT): Provide maximum alignment of global
+ common data.
+
2004-08-05 Andrew Pinski <apinski@apple.com>
* objc/objc-act.c (build_objc_string_object): Mark the address
/* Definitions of target machine for GNU compiler, for PRO.
- Copyright (C) 1996, 1997, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#undef STARTFILE_SPEC
#define STARTFILE_SPEC ""
-/* The following two macros are identical to the ones in pa.h. We need
- to override the macros in elfos.h on the rtems and pro ports. */
-
-/* This says how to output an assembler line to define a global common symbol
- with size SIZE (in bytes) and alignment ALIGN (in bits). */
-
+/* We need to override the following two macros defined in elfos.h since
+ the .comm directive has a different syntax and it can't be used for
+ local common symbols. */
#undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- MAX ((unsigned HOST_WIDE_INT)(SIZE), \
- ((unsigned HOST_WIDE_INT)(ALIGNED) / BITS_PER_UNIT)));}
-
-/* This says how to output an assembler line to define a local common symbol
- with size SIZE (in bytes) and alignment ALIGN (in bits). */
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
#undef ASM_OUTPUT_ALIGNED_LOCAL
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- fprintf ((FILE), "\t.align %d\n", ((ALIGNED) / BITS_PER_UNIT)); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- (unsigned HOST_WIDE_INT)(SIZE));}
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+ pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
#endif
+/* Miscellaneous functions in pa.c. */
#ifdef TREE_CODE
extern int reloc_needed (tree);
#ifdef RTX_CODE
extern bool pa_return_in_memory (tree, tree);
#endif /* TREE_CODE */
+extern void pa_asm_output_aligned_bss (FILE *, const char *,
+ unsigned HOST_WIDE_INT,
+ unsigned int);
+extern void pa_asm_output_aligned_common (FILE *, const char *,
+ unsigned HOST_WIDE_INT,
+ unsigned int);
+extern void pa_asm_output_aligned_local (FILE *, const char *,
+ unsigned HOST_WIDE_INT,
+ unsigned int);
+
/* Functions in varasm.c used by pa.c. */
extern void readonly_data (void);
extern void one_only_readonly_data_section (void);
}
#endif
+/* This function places uninitialized global data in the bss section.
+ The ASM_OUTPUT_ALIGNED_BSS macro needs to be defined to call this
+ function on the SOM port to prevent uninitialized global data from
+ being placed in the data section. */
+
+void
+pa_asm_output_aligned_bss (FILE *stream,
+ const char *name,
+ unsigned HOST_WIDE_INT size,
+ unsigned int align)
+{
+ bss_section ();
+ fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+
+#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
+ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
+#endif
+
+#ifdef ASM_OUTPUT_SIZE_DIRECTIVE
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+#endif
+
+ fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+ ASM_OUTPUT_LABEL (stream, name);
+ fprintf (stream, "\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
+}
+
+/* Both the HP and GNU assemblers under HP-UX provide a .comm directive
+ that doesn't allow the alignment of global common storage to be directly
+ specified. The SOM linker aligns common storage based on the rounded
+ value of the NUM_BYTES parameter in the .comm directive. It's not
+ possible to use the .align directive as it doesn't affect the alignment
+ of the label associated with a .comm directive. */
+
+void
+pa_asm_output_aligned_common (FILE *stream,
+ const char *name,
+ unsigned HOST_WIDE_INT size,
+ unsigned int align)
+{
+ bss_section ();
+
+ assemble_name (stream, name);
+ fprintf (stream, "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n",
+ MAX (size, align / BITS_PER_UNIT));
+}
+
+/* We can't use .comm for local common storage as the SOM linker effectively
+ treats the symbol as universal and uses the same storage for local symbols
+ with the same name in different object files. The .block directive
+ reserves an uninitialized block of storage. However, it's not common
+ storage. Fortunately, GCC never requests common storage with the same
+ name in any given translation unit. */
+
+void
+pa_asm_output_aligned_local (FILE *stream,
+ const char *name,
+ unsigned HOST_WIDE_INT size,
+ unsigned int align)
+{
+ bss_section ();
+ fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+
+#ifdef LOCAL_ASM_OP
+ fprintf (stream, "%s", LOCAL_ASM_OP);
+ assemble_name (stream, name);
+ fprintf (stream, "\n");
+#endif
+
+ ASM_OUTPUT_LABEL (stream, name);
+ fprintf (stream, "\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
+}
+
/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
use in fmpysub instructions. */
int
fprintf (FILE, "\t.blockz "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
(unsigned HOST_WIDE_INT)(SIZE))
+/* This says how to output an assembler line to define an uninitialized
+ global variable with size SIZE (in bytes) and alignment ALIGN (in bits).
+ This macro exists to properly support languages like C++ which do not
+ have common data. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ pa_asm_output_aligned_bss (FILE, NAME, SIZE, ALIGN)
+
/* This says how to output an assembler line to define a global common symbol
with size SIZE (in bytes) and alignment ALIGN (in bits). */
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- MAX ((unsigned HOST_WIDE_INT)(SIZE), \
- ((unsigned HOST_WIDE_INT)(ALIGNED) / BITS_PER_UNIT)));}
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
/* This says how to output an assembler line to define a local common symbol
- with size SIZE (in bytes) and alignment ALIGN (in bits). */
+ with size SIZE (in bytes) and alignment ALIGN (in bits). This macro
+ controls how the assembler definitions of uninitialized static variables
+ are output. */
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- fprintf ((FILE), "\t.align %d\n", ((ALIGNED) / BITS_PER_UNIT)); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- (unsigned HOST_WIDE_INT)(SIZE));}
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+ pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
+
#define ASM_PN_FORMAT "%s___%lu"
#define MD_STARTFILE_PREFIX_1 "/opt/langtools/lib/pa20_64/"
#endif
+/* This macro specifies the biggest alignment supported by the object
+ file format of this machine.
+
+ The .align directive in the HP assembler allows alignments up to
+ 4096 bytes. However, the maximum alignment of a global common symbol
+ is 16 bytes using HP ld. For consistency, we use the same limit
+ with GNU ld. */
+#undef MAX_OFILE_ALIGNMENT
+#define MAX_OFILE_ALIGNMENT \
+ (TREE_PUBLIC (decl) && DECL_COMMON (decl) ? 128 : 32768)
+
/* Due to limitations in the target structure, it isn't currently possible
to dynamically switch between the GNU and HP assemblers. */
#undef TARGET_GAS
#define HP_FINI_ARRAY_SECTION_ASM_OP "\t.section\t.fini"
#define GNU_FINI_ARRAY_SECTION_ASM_OP "\t.section\t.fini_array"
+/* We need to override the following two macros defined in elfos.h since
+ the .comm directive has a different syntax and it can't be used for
+ local common symbols. */
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
-do { \
- bss_section (); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- MAX ((unsigned HOST_WIDE_INT)(SIZE), \
- ((unsigned HOST_WIDE_INT)(ALIGN) / BITS_PER_UNIT))); \
-} while (0)
+ pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
-do { \
- bss_section (); \
- fprintf ((FILE), "\t.align %d\n", ((ALIGN) / BITS_PER_UNIT)); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- (unsigned HOST_WIDE_INT)(SIZE)); \
-} while (0)
+ pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
/* The define in pa.h doesn't work with the alias attribute. The
default is ok with the following define for GLOBAL_ASM_OP. */
(*p++) (); \
} while (0)
-/* The .align directive in the HP assembler allows up to a 32 alignment. */
-#define MAX_OFILE_ALIGNMENT 32768
+/* This macro specifies the biggest alignment supported by the object
+ file format of this machine.
+
+ The .align directive in the HP assembler allows alignments up to 4096
+ bytes. However, the maximum alignment of a global common symbol is 8
+ bytes for objects smaller than the page size (4096 bytes). For larger
+ objects, the linker provides an alignment of 32 bytes. */
+#define MAX_OFILE_ALIGNMENT \
+ (TREE_PUBLIC (decl) && DECL_COMMON (decl) \
+ ? (host_integerp (DECL_SIZE_UNIT (decl), 1) >= 4096 ? 256 : 64) \
+ : 32768)
/* The SOM linker hardcodes paths into binaries. As a result, dotdots
must be removed from library prefixes to prevent binaries from depending