This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[arm] EABI object attributes.
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 3 Nov 2006 17:47:37 +0000
- Subject: [arm] EABI object attributes.
The patch below makes gcc output assembly directives to set object
attributes on EABI based targets. Omitting these attributes makes them assume
their default values, some of which are incompatible with what we actually
generate. An EABI compliant linker could legitimately refuse to link such
objects.
This means EABI targets require an assembler that understands these directives
(2.17 should be sufficient). I discussed this offline with Richard Earnshaw,
and we agree this is reasonable.
Legacy ABI (-elf and -linux) targets are not effected.
Tested on arm-none-eabi.
This is a merge from branches/csl/sourcerygxx-4_1.
Applied to mainline.
Paul
2006-11-03 Paul Brook <paul@codesourcery.com>
* config/arm/arm.c (arm_file_start): New function.
(TARGET_ASM_FILE_START): Define.
(arm_default_cpu): New variable.
(arm_override_options): Set arm_default_cpu.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c (revision 118458)
+++ gcc/config/arm/arm.c (working copy)
@@ -154,6 +154,7 @@ static void arm_encode_section_info (tre
#endif
static void arm_file_end (void);
+static void arm_file_start (void);
#ifdef AOF_ASSEMBLER
static void aof_globalize_label (FILE *, const char *);
@@ -202,6 +203,9 @@ static bool arm_tls_symbol_p (rtx x);
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START arm_file_start
+
#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END arm_file_end
@@ -390,6 +394,9 @@ rtx arm_compare_op0, arm_compare_op1;
/* The processor for which instructions should be scheduled. */
enum processor_type arm_tune = arm_none;
+/* The default processor used if not overriden by commandline. */
+static enum processor_type arm_default_cpu = arm_none;
+
/* Which floating point model to use. */
enum arm_fp_model arm_fp_model;
@@ -1020,8 +1027,9 @@ arm_override_options (void)
insn_flags = sel->flags;
}
sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
+ arm_default_cpu = (enum processor_type) (sel - all_cores);
if (arm_tune == arm_none)
- arm_tune = (enum processor_type) (sel - all_cores);
+ arm_tune = arm_default_cpu;
}
/* The processor for which we should tune should now have been
@@ -14413,6 +14421,105 @@ arm_asm_output_labelref (FILE *stream, c
}
static void
+arm_file_start (void)
+{
+ int val;
+
+ if (TARGET_BPABI)
+ {
+ const char *fpu_name;
+ if (arm_select[0].string)
+ asm_fprintf (asm_out_file, "\t.cpu %s\n", arm_select[0].string);
+ else if (arm_select[1].string)
+ asm_fprintf (asm_out_file, "\t.arch %s\n", arm_select[1].string);
+ else
+ asm_fprintf (asm_out_file, "\t.cpu %s\n",
+ all_cores[arm_default_cpu].name);
+
+ if (TARGET_SOFT_FLOAT)
+ {
+ if (TARGET_VFP)
+ fpu_name = "softvfp";
+ else
+ fpu_name = "softfpa";
+ }
+ else
+ {
+ switch (arm_fpu_arch)
+ {
+ case FPUTYPE_FPA:
+ fpu_name = "fpa";
+ break;
+ case FPUTYPE_FPA_EMU2:
+ fpu_name = "fpe2";
+ break;
+ case FPUTYPE_FPA_EMU3:
+ fpu_name = "fpe3";
+ break;
+ case FPUTYPE_MAVERICK:
+ fpu_name = "maverick";
+ break;
+ case FPUTYPE_VFP:
+ if (TARGET_HARD_FLOAT)
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 27, 3\n");
+ if (TARGET_HARD_FLOAT_ABI)
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 28, 1\n");
+ fpu_name = "vfp";
+ break;
+ default:
+ abort();
+ }
+ }
+ asm_fprintf (asm_out_file, "\t.fpu %s\n", fpu_name);
+
+ /* Some of these attributes only apply when the corresponding features
+ are used. However we don't have any easy way of figuring this out.
+ Conservatively record the setting that would have been used. */
+
+ /* Tag_ABI_PCS_wchar_t. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 18, %d\n",
+ (int)WCHAR_TYPE_SIZE / BITS_PER_UNIT);
+
+ /* Tag_ABI_FP_rounding. */
+ if (flag_rounding_math)
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 19, 1\n");
+ if (!flag_unsafe_math_optimizations)
+ {
+ /* Tag_ABI_FP_denomal. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 20, 1\n");
+ /* Tag_ABI_FP_exceptions. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 21, 1\n");
+ }
+ /* Tag_ABI_FP_user_exceptions. */
+ if (flag_signaling_nans)
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 22, 1\n");
+ /* Tag_ABI_FP_number_model. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 23, %d\n",
+ flag_finite_math_only ? 1 : 3);
+
+ /* Tag_ABI_align8_needed. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 24, 1\n");
+ /* Tag_ABI_align8_preserved. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 25, 1\n");
+ /* Tag_ABI_enum_size. */
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 26, %d\n",
+ flag_short_enums ? 1 : 2);
+
+ /* Tag_ABI_optimization_goals. */
+ if (optimize_size)
+ val = 4;
+ else if (optimize >= 2)
+ val = 2;
+ else if (optimize)
+ val = 1;
+ else
+ val = 6;
+ asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val);
+ }
+ default_file_start();
+}
+
+static void
arm_file_end (void)
{
int regno;