This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

Re: [PATCH 6/10, GAS/ARM] Rework Tag_CPU_arch build attribute value selection


On 21/06/17 16:04, Thomas Preudhomme wrote:
> Alright, here's the updated description and patch to address your
> comments: the description explains the testsuite expectation change and
> the code contains updated comment to explain the ordering of entries in
> cpu_arch_ver.
> 
> 
> === Context ===
> 
> This patch is part of a patch series to add support for ARMv8-R
> architecture. Its purpose is to rework the Tag_CPU_arch build attribute
> value selection to (i) match architecture or CPU if specified by user
> without any need for hack and (ii) match an architecture with all the
> features used if in autodetection mode or return an error.
> 
> === Motivation ===
> 
> Currently, Tag_CPU_arch build attribute value selection assumes that an
> architecture is always a superset of architectures released earlier. As
> such, the logic is to browse architectures in chronological order of
> release and selecting the Tag_CPU_arch value of the last one to
> contribute a feature used[1]/requested[2] not contributed by earlier
> architectures.
> 
> [1] in case of autodetection mode
> [2] otherwise, ie. in case of -mcpu/-march or associated directives
> 
> This logic fails the two objectives mentionned in the Context section.
> First, due to the assumption it does an architecture can be selected
> while not having all the features used/requested which fails the second
> objective. Second, not doing an exact match when an architecture or CPU
> is selected by the user means the wrong value is chosen when a later
> architecture provides a subset of the feature bits of an earlier
> architecture. This is the case for the implementation of ARMv8-R (see
> later patch).
> 
> An added benefit of this patch is that it is possible to easily generate
> more consistent build attribute by setting the feature bits from the
> architecture matched in aeabi_set_public_attributes in autodetection
> mode. This is better done as a separate patch because lots of testcase'
> expected results must then be updated accordingly.
> 
> === Patch description ===
> 
> The patch changes the main logic for Tag_CPU_arch and Tag_CPU_arch_profile
> values selection to:
> - look for an exact match in case an architecture or CPU was specified
>   on the command line or in a directive
> - select the first released architecture that provides a superset of the
>   feature used in the autodetection case
> - select the most featureful architecture in case of -march=all
> The array cpu_arch_ver is updated to include all architectures in order
> to make the first point work.
> 
> Note that when looking for an exact match, the architecture with
> selected extension is tried first and then only the architecture. This
> is because some architectures are exactly equivalent to an earlier
> architecture with its extensions selected. ARMv6S-M (= ARMv6-M + OS
> extension) and ARMv6KZ (ARMv6K + security extension) are two such
> examples.
> 
> Other adjustments are also necessary in aeabi_set_public_attributes to
> make this change work.
> 
> 1) The logic to set Tag_ARM_ISA_use and Tag_THUMB_ISA_use must check the
> absence of feature bit used/requested to decide whether to give the
> default value for empty files (see EABI attribute defaults test). It was
> previously checking that arch == 0 which would only happen if no feature
> bit could be matched by any architecture, ie there is no feature bit to
> match.
> 
> 2) A fallback to a superset match must exist when no_cpu_selected ()
> returns true. This is because aeabi_set_public_attributes is called
> again after relaxation and at this point selected_cpu is set from the
> previous execution of that function. There is therefore no way to check
> whether the user specified an architecture or CPU.
> 
> 3) Tag_CPU_arch lines are removed from expected output when the
> detected architecture should be pre-ARMv4, since 0 is the Tag_CPU_arch
> value for pre-ARMv4 architectures and default value for an absent entry
> is 0.
> 

OK.

R.

> On 21/06/17 15:40, Richard Earnshaw (lists) wrote:
>> On 21/06/17 15:39, Thomas Preudhomme wrote:
>>> Hi Richard,
>>>
>>> On 21/06/17 15:33, Richard Earnshaw (lists) wrote:
>>>> On 21/06/17 11:12, Thomas Preudhomme wrote:
>>>>> Hi,
>>>>>
>>>>> === Context ===
>>>>>
>>>>> This patch is part of a patch series to add support for ARMv8-R
>>>>> architecture. Its purpose is to rework the Tag_CPU_arch build
>>>>> attribute
>>>>> value selection to (i) match architecture or CPU if specified by user
>>>>> without any need for hack and (ii) match an architecture with all the
>>>>> features used if in autodetection mode or return an error.
>>>>>
>>>>> === Motivation ===
>>>>>
>>>>> Currently, Tag_CPU_arch build attribute value selection assumes
>>>>> that an
>>>>> architecture is always a superset of architectures released
>>>>> earlier. As
>>>>> such, the logic is to browse architectures in chronological order of
>>>>> release and selecting the Tag_CPU_arch value of the last one to
>>>>> contribute a feature used[1]/requested[2] not contributed by earlier
>>>>> architectures.
>>>>>
>>>>> [1] in case of autodetection mode
>>>>> [2] otherwise, ie. in case of -mcpu/-march or associated directives
>>>>>
>>>>> This logic fails the two objectives mentionned in the Context section.
>>>>> First, due to the assumption it does an architecture can be selected
>>>>> while not having all the features used/requested which fails the
>>>>> second
>>>>> objective. Second, not doing an exact match when an architecture or
>>>>> CPU
>>>>> is selected by the user means the wrong value is chosen when a later
>>>>> architecture provides a subset of the feature bits of an earlier
>>>>> architecture. This is the case for the implementation of ARMv8-R (see
>>>>> later patch).
>>>>>
>>>>> An added benefit of this patch is that it is possible to easily
>>>>> generate
>>>>> more consistent build attribute by setting the feature bits from the
>>>>> architecture matched in aeabi_set_public_attributes in autodetection
>>>>> mode. This is better done as a separate patch because lots of
>>>>> testcase'
>>>>> expected results must then be updated accordingly.
>>>>>
>>>>> === Patch description ===
>>>>>
>>>>> The patch changes the main logic for Tag_CPU_arch and
>>>>> Tag_CPU_arch_profile
>>>>> values selection to:
>>>>> - look for an exact match in case an architecture or CPU was specified
>>>>>   on the command line or in a directive
>>>>> - select the first released architecture that provides a superset
>>>>> of the
>>>>>   feature used in the autodetection case
>>>>> - select the most featureful architecture in case of -march=all
>>>>> The array cpu_arch_ver is updated to include all architectures in
>>>>> order
>>>>> to make the first point work.
>>>>>
>>>>> Note that when looking for an exact match, the architecture with
>>>>> selected extension is tried first and then only the architecture. This
>>>>> is because some architectures are exactly equivalent to an earlier
>>>>> architecture with its extensions selected. ARMv6S-M (= ARMv6-M + OS
>>>>> extension) and ARMv6KZ (ARMv6K + security extension) are two such
>>>>> examples.
>>>>>
>>>>> Other adjustments are also necessary in aeabi_set_public_attributes to
>>>>> make this change work.
>>>>>
>>>>> 1) The logic to set Tag_ARM_ISA_use and Tag_THUMB_ISA_use must
>>>>> check the
>>>>> absence of feature bit used/requested to decide whether to give the
>>>>> default value for empty files (see EABI attribute defaults test).
>>>>> It was
>>>>> previously checking that arch == 0 which would only happen if no
>>>>> feature
>>>>> bit could be matched by any architecture, ie there is no feature
>>>>> bit to
>>>>> match.
>>>>>
>>>>> 2) A fallback to a superset match must exist when no_cpu_selected ()
>>>>> returns true. This is because aeabi_set_public_attributes is called
>>>>> again after relaxation and at this point selected_cpu is set from the
>>>>> previous execution of that function. There is therefore no way to
>>>>> check
>>>>> whether the user specified an architecture or CPU.
>>>>>
>>>>> ChangeLog entries are as follow:
>>>>>
>>>>> *** gas/ChangeLog ***
>>>>>
>>>>> 2017-06-13  Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>>>>
>>>>>     * config/tc-arm.c (fpu_any): Defined from FPU_ANY.
>>>>>     (cpu_arch_ver): Add all architectures and sort by release date.
>>>>>     (have_ext_for_needed_feat_p): New.
>>>>>     (get_aeabi_cpu_arch_from_fset): New.
>>>>>     (aeabi_set_public_attributes): Call above function to determine
>>>>>     Tag_CPU_arch and Tag_CPU_arch_profile values.  Adapt
>>>>> Tag_ARM_ISA_use
>>>>>     and Tag_THUMB_ISA_use selection logic to check absence of feature
>>>>> bit
>>>>>     accordingly.
>>>>>     * testsuite/gas/arm/attr-march-armv1.d: Fix expected Tag_CPU_arch
>>>>> build
>>>>>     attribute value.
>>>>>     * testsuite/gas/arm/attr-march-armv2.d: Likewise.
>>>>>     * testsuite/gas/arm/attr-march-armv2a.d: Likewise.
>>>>>     * testsuite/gas/arm/attr-march-armv2s.d: Likewise.
>>>>>     * testsuite/gas/arm/attr-march-armv3.d: Likewise.
>>>>>     * testsuite/gas/arm/attr-march-armv3m.d: Likewise.
>>>>>     * testsuite/gas/arm/pr12198-2.d: Likewise.
>>>>>
>>>>> *** include/ChangeLog ***
>>>>>
>>>>> 2017-01-26  Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>>>>
>>>>>     * opcode/arm.h (FPU_ANY): New macro.
>>>>>
>>>>> === Testing ===
>>>>>
>>>>> Testsuite shows no regression when run for arm-none-eabi targets.
>>>>>
>>>>> Is this ok for master branch?
>>>>>
>>>>
>>>> I have two issues with this patch...
>>>>
>>>> 1)
>>>>> +/* Mapping from CPU features to EABI CPU arch values.  Table must be
>>>> sorted
>>>>> +   chronologically for architectures, with an exception for
>>>>> ARMv6-M and
>>>>> +   ARMv6S-M due to legacy reasons.  No new architecture should have a
>>>>> +   special case.  */
>>>>
>>>> This comment warrants some justification.  We should explain that the
>>>> reason for maintaining chronological order is to avoid the build
>>>> attributes of object files changing as new variant architectures get
>>>> added.
>>>
>>> Indeed. I'll improve the comments in code and cover letter for that
>>> patch.
>>>
>>>>
>>>> 2)
>>>>>  File Attributes
>>>>>    Tag_CPU_name: "1"
>>>>> -  Tag_CPU_arch: v4
>>>>>    Tag_ARM_ISA_use: Yes
>>>>
>>>> I think we should always emit a Tag_CPU_arch directive.  It's wrong to
>>>> assume that the consumer of an object file will be able to deduce the
>>>> base architecture from a simple CPU name - especially an odd-ball one
>>>> like '1' which isn't an official product name.
>>>>
>>>> Tag_CPU_arch = v4 is probably the right thing to emit here - we don't
>>>> have tags for architectures older than that.
>>>
>>> The document "Addenda to, and Errata in, the ABI® for the ARM
>>> Architecture"(document ID: ARM IHI 0045D) issue E r2.10 says that a
>>> value of 0 is for pre-v4 architectures. Since 0 is the default value
>>> this at least follows the documentation.
>>>
>>
>> Ah, ok, so it 'does' have an architecture.  Ignore that then.
>>
>> R.
>>
>>> Best regards,
>>>
>>> Thomas
>>
> 
> 06_rework_Tag_CPU_arch_selection_logic.patch
> 
> 
> diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
> index a62c5f29d98d27fcfb8d4860a46993efdc33bed7..7767aa6dddc0b39431c4ac28549b1a62954f0035 100644
> --- a/gas/config/tc-arm.c
> +++ b/gas/config/tc-arm.c
> @@ -240,6 +240,7 @@ static const arm_feature_set arm_ext_v8_3 =
>    ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A);
>  
>  static const arm_feature_set arm_arch_any = ARM_ANY;
> +static const arm_feature_set fpu_any = FPU_ANY;
>  static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
>  static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
>  static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
> @@ -26558,30 +26559,61 @@ typedef struct
>    arm_feature_set flags;
>  } cpu_arch_ver_table;
>  
> -/* Mapping from CPU features to EABI CPU arch values.  As a general rule, table
> -   must be sorted least features first but some reordering is needed, eg. for
> -   Thumb-2 instructions to be detected as coming from ARMv6T2.  */
> +/* Mapping from CPU features to EABI CPU arch values.  Table must be sorted
> +   chronologically for architectures, with an exception for ARMv6-M and
> +   ARMv6S-M due to legacy reasons.  No new architecture should have a
> +   special case.  This allows for build attribute selection results to be
> +   stable when new architectures are added.  */
>  static const cpu_arch_ver_table cpu_arch_ver[] =
>  {
> +    {0, ARM_ARCH_V1},
> +    {0, ARM_ARCH_V2},
> +    {0, ARM_ARCH_V2S},
> +    {0, ARM_ARCH_V3},
> +    {0, ARM_ARCH_V3M},
> +    {1, ARM_ARCH_V4xM},
>      {1, ARM_ARCH_V4},
> +    {2, ARM_ARCH_V4TxM},
>      {2, ARM_ARCH_V4T},
> +    {3, ARM_ARCH_V5xM},
>      {3, ARM_ARCH_V5},
> +    {3, ARM_ARCH_V5TxM},
>      {3, ARM_ARCH_V5T},
> +    {4, ARM_ARCH_V5TExP},
>      {4, ARM_ARCH_V5TE},
>      {5, ARM_ARCH_V5TEJ},
>      {6, ARM_ARCH_V6},
> -    {9, ARM_ARCH_V6K},
>      {7, ARM_ARCH_V6Z},
> +    {7, ARM_ARCH_V6KZ},
> +    {9, ARM_ARCH_V6K},
> +    {8, ARM_ARCH_V6T2},
> +    {8, ARM_ARCH_V6KT2},
> +    {8, ARM_ARCH_V6ZT2},
> +    {8, ARM_ARCH_V6KZT2},
> +
> +    /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
> +       always selected build attributes to match those of ARMv6-M
> +       (resp. ARMv6S-M).  However, due to these architectures being a strict
> +       subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
> +       would be selected when fully respecting chronology of architectures.
> +       It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
> +       move them before ARMv7 architectures.  */
>      {11, ARM_ARCH_V6M},
>      {12, ARM_ARCH_V6SM},
> -    {8, ARM_ARCH_V6T2},
> -    {10, ARM_ARCH_V7VE},
> +
> +    {10, ARM_ARCH_V7},
> +    {10, ARM_ARCH_V7A},
>      {10, ARM_ARCH_V7R},
>      {10, ARM_ARCH_V7M},
> +    {10, ARM_ARCH_V7VE},
> +    {13, ARM_ARCH_V7EM},
>      {14, ARM_ARCH_V8A},
> +    {14, ARM_ARCH_V8_1A},
> +    {14, ARM_ARCH_V8_2A},
> +    {14, ARM_ARCH_V8_3A},
>      {16, ARM_ARCH_V8M_BASE},
>      {17, ARM_ARCH_V8M_MAIN},
> -    {0, ARM_ARCH_NONE}
> +    {-1, ARM_ARCH_NONE}
>  };
>  
>  /* Set an attribute if it has not already been set by the user.  */
> @@ -26603,18 +26635,162 @@ aeabi_set_attribute_string (int tag, const char *value)
>      bfd_elf_add_proc_attr_string (stdoutput, tag, value);
>  }
>  
> +/* Return whether features in the *NEEDED feature set are available via
> +   extensions for the architecture whose feature set is *ARCH_FSET.  */
> +static bfd_boolean
> +have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
> +			    const arm_feature_set *needed)
> +{
> +  int i, nb_allowed_archs;
> +  arm_feature_set ext_fset;
> +  const struct arm_option_extension_value_table *opt;
> +
> +  ext_fset = arm_arch_none;
> +  for (opt = arm_extensions; opt->name != NULL; opt++)
> +    {
> +      /* Extension does not provide any feature we need.  */
> +      if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
> +	continue;
> +
> +      nb_allowed_archs =
> +	sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
> +      for (i = 0; i < nb_allowed_archs; i++)
> +	{
> +	  /* Empty entry.  */
> +	  if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
> +	    break;
> +
> +	  /* Extension is available, add it.  */
> +	  if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
> +	    ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
> +	}
> +    }
> +
> +  /* Can we enable all features in *needed?  */
> +  return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
> +}
> +
> +/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
> +   a given architecture feature set *ARCH_EXT_FSET including extension feature
> +   set *EXT_FSET.  Selection logic used depend on EXACT_MATCH:
> +   - if true, check for an exact match of the architecture modulo extensions;
> +   - otherwise, select build attribute value of the first superset
> +     architecture released so that results remains stable when new architectures
> +     are added.
> +   For -march/-mcpu=all the build attribute value of the most featureful
> +   architecture is returned.  Tag_CPU_arch_profile result is returned in
> +   PROFILE.  */
> +static int
> +get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
> +			      const arm_feature_set *ext_fset,
> +			      char *profile, int exact_match)
> +{
> +  arm_feature_set arch_fset;
> +  const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
> +
> +  /* Select most featureful architecture with all its extensions if building
> +     for -march=all as the feature sets used to set build attributes.  */
> +  if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
> +    {
> +      /* Force revisiting of decision for each new architecture.  */
> +      gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8M_MAIN);
> +      *profile = 'A';
> +      return TAG_CPU_ARCH_V8;
> +    }
> +
> +  ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
> +
> +  for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
> +    {
> +      arm_feature_set known_arch_fset;
> +
> +      ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
> +      if (exact_match)
> +	{
> +	  /* Base architecture match user-specified architecture and
> +	     extensions, eg. ARMv6S-M matching -march=armv6-m+os.  */
> +	  if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
> +	    {
> +	      p_ver_ret = p_ver;
> +	      goto found;
> +	    }
> +	  /* Base architecture match user-specified architecture only
> +	     (eg. ARMv6-M in the same case as above).  Record it in case we
> +	     find a match with above condition.  */
> +	  else if (p_ver_ret == NULL
> +		   && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
> +	    p_ver_ret = p_ver;
> +	}
> +      else
> +	{
> +
> +	  /* Architecture has all features wanted.  */
> +	  if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
> +	    {
> +	      arm_feature_set added_fset;
> +
> +	      /* Compute features added by this architecture over the one
> +		 recorded in p_ver_ret.  */
> +	      if (p_ver_ret != NULL)
> +		ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
> +				   p_ver_ret->flags);
> +	      /* First architecture that match incl. with extensions, or the
> +		 only difference in features over the recorded match is
> +		 features that were optional and are now mandatory.  */
> +	      if (p_ver_ret == NULL
> +		  || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
> +		{
> +		  p_ver_ret = p_ver;
> +		  goto found;
> +		}
> +	    }
> +	  else if (p_ver_ret == NULL)
> +	    {
> +	      arm_feature_set needed_ext_fset;
> +
> +	      ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
> +
> +	      /* Architecture has all features needed when using some
> +		 extensions.  Record it and continue searching in case there
> +		 exist an architecture providing all needed features without
> +		 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
> +		 OS extension).  */
> +	      if (have_ext_for_needed_feat_p (&known_arch_fset,
> +					      &needed_ext_fset))
> +		p_ver_ret = p_ver;
> +	    }
> +	}
> +    }
> +
> +  if (p_ver_ret == NULL)
> +    return -1;
> +
> +found:
> +  /* Tag_CPU_arch_profile.  */
> +  if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
> +      || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
> +      || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
> +	  && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
> +    *profile = 'A';
> +  else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
> +    *profile = 'R';
> +  else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
> +    *profile = 'M';
> +  else
> +    *profile = '\0';
> +  return p_ver_ret->val;
> +}
> +
>  /* Set the public EABI object attributes.  */
>  static void
>  aeabi_set_public_attributes (void)
>  {
> -  int arch;
>    char profile;
> +  int arch = -1;
>    int virt_sec = 0;
>    int fp16_optional = 0;
> -  arm_feature_set flags;
> -  arm_feature_set tmp;
> -  arm_feature_set arm_arch_v8m_base = ARM_ARCH_V8M_BASE;
> -  const cpu_arch_ver_table *p;
> +  int skip_exact_match = 0;
> +  arm_feature_set flags, flags_arch, flags_ext;
>  
>    /* Autodetection mode, choose the architecture based the instructions
>       actually used.  */
> @@ -26647,45 +26823,29 @@ aeabi_set_public_attributes (void)
>    /* Allow the user to override the reported architecture.  */
>    if (object_arch)
>      {
> -      ARM_CLEAR_FEATURE (flags, flags, arm_arch_any);
> -      ARM_MERGE_FEATURE_SETS (flags, flags, *object_arch);
> +      ARM_CLEAR_FEATURE (flags_arch, *object_arch, fpu_any);
> +      flags_ext = arm_arch_none;
>      }
> -
> -  tmp = flags;
> -  arch = 0;
> -  for (p = cpu_arch_ver; p->val; p++)
> +  else
>      {
> -      if (ARM_CPU_HAS_FEATURE (tmp, p->flags))
> -	{
> -	  arch = p->val;
> -	  ARM_CLEAR_FEATURE (tmp, tmp, p->flags);
> -	}
> -    }
> -
> -  /* The table lookup above finds the last architecture to contribute
> -     a new feature.  Unfortunately, Tag13 is a subset of the union of
> -     v6T2 and v7-M, so it is never seen as contributing a new feature.
> -     We can not search for the last entry which is entirely used,
> -     because if no CPU is specified we build up only those flags
> -     actually used.  Perhaps we should separate out the specified
> -     and implicit cases.  Avoid taking this path for -march=all by
> -     checking for contradictory v7-A / v7-M features.  */
> -  if (arch == TAG_CPU_ARCH_V7
> -      && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
> -      && ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m)
> -      && ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp))
> -    arch = TAG_CPU_ARCH_V7E_M;
> -
> -  ARM_CLEAR_FEATURE (tmp, flags, arm_arch_v8m_base);
> -  if (arch == TAG_CPU_ARCH_V8M_BASE && ARM_CPU_HAS_FEATURE (tmp, arm_arch_any))
> -    arch = TAG_CPU_ARCH_V8M_MAIN;
> -
> -  /* In cpu_arch_ver ARMv8-A is before ARMv8-M for atomics to be detected as
> -     coming from ARMv8-A.  However, since ARMv8-A has more instructions than
> -     ARMv8-M, -march=all must be detected as ARMv8-A.  */
> -  if (arch == TAG_CPU_ARCH_V8M_MAIN
> -      && ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
> -    arch = TAG_CPU_ARCH_V8;
> +      ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
> +      flags_ext = dyn_mcpu_ext_opt ? *dyn_mcpu_ext_opt : arm_arch_none;
> +      skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
> +    }
> +
> +  /* When this function is run again after relaxation has happened there is no
> +     way to determine whether an architecture or CPU was specified by the user:
> +     - selected_cpu is set above for relaxation to work;
> +     - march_cpu_opt is not set if only -mcpu or .cpu is used;
> +     - mcpu_cpu_opt is set to arm_arch_any for autodetection.
> +     Therefore, if not in -march=all case we first try an exact match and fall
> +     back to autodetection.  */
> +  if (!skip_exact_match)
> +    arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
> +  if (arch == -1)
> +    arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
> +  if (arch == -1)
> +    as_bad (_("no architecture contains all the instructions used\n"));
>  
>    /* Tag_CPU_name.  */
>    if (selected_cpu_name[0])
> @@ -26708,18 +26868,6 @@ aeabi_set_public_attributes (void)
>    aeabi_set_attribute_int (Tag_CPU_arch, arch);
>  
>    /* Tag_CPU_arch_profile.  */
> -  if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
> -      || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
> -      || (ARM_CPU_HAS_FEATURE (flags, arm_ext_atomics)
> -	  && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only)))
> -    profile = 'A';
> -  else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
> -    profile = 'R';
> -  else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_m))
> -    profile = 'M';
> -  else
> -    profile = '\0';
> -
>    if (profile != '\0')
>      aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
>  
> @@ -26727,14 +26875,15 @@ aeabi_set_public_attributes (void)
>    if (dyn_mcpu_ext_opt && ARM_CPU_HAS_FEATURE (*dyn_mcpu_ext_opt, arm_ext_dsp))
>      aeabi_set_attribute_int (Tag_DSP_extension, 1);
>  
> +  ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
>    /* Tag_ARM_ISA_use.  */
>    if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
> -      || arch == 0)
> +      || ARM_FEATURE_ZERO (flags_arch))
>      aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
>  
>    /* Tag_THUMB_ISA_use.  */
>    if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
> -      || arch == 0)
> +      || ARM_FEATURE_ZERO (flags_arch))
>      {
>        int thumb_isa_use;
>  
> diff --git a/gas/testsuite/gas/arm/attr-march-armv1.d b/gas/testsuite/gas/arm/attr-march-armv1.d
> index ac6597743ea4c9e408f656d0b264052a17ae0a66..d9730b5d58bd50c69293926c67f0340dd95e4a02 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv1.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv1.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "1"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/gas/testsuite/gas/arm/attr-march-armv2.d b/gas/testsuite/gas/arm/attr-march-armv2.d
> index 0b574efbbbc59d111232000ddb2e8003419cd6d5..39e337192957a82718da5bbd137ee3fe546a3fe0 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv2.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv2.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "2"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/gas/testsuite/gas/arm/attr-march-armv2a.d b/gas/testsuite/gas/arm/attr-march-armv2a.d
> index 387e4a318041428cb07c914a9980ee4fe5604d80..2c4dd620d3d690474ebb862b1ac340f24d3500de 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv2a.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv2a.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "2A"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/gas/testsuite/gas/arm/attr-march-armv2s.d b/gas/testsuite/gas/arm/attr-march-armv2s.d
> index 3bd06e62f070e1433671bbf2e7a3b6ab0cbf9ce3..dfd17d2b37716ac2d5d167020e0fb957b81b2f85 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv2s.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv2s.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "2S"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/gas/testsuite/gas/arm/attr-march-armv3.d b/gas/testsuite/gas/arm/attr-march-armv3.d
> index 13d5d183946d099a10d3f026d2f1d4aae878cea9..988f896529370f353e2f64d1f56f703c12408eed 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv3.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv3.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "3"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/gas/testsuite/gas/arm/attr-march-armv3m.d b/gas/testsuite/gas/arm/attr-march-armv3m.d
> index 4e2439972d84ea0e385f1b6d1fc24326505eacf0..c946b37177a91bdbae616094cb5671bdc26bd8cf 100644
> --- a/gas/testsuite/gas/arm/attr-march-armv3m.d
> +++ b/gas/testsuite/gas/arm/attr-march-armv3m.d
> @@ -8,5 +8,4 @@
>  Attribute Section: aeabi
>  File Attributes
>    Tag_CPU_name: "3M"
> -  Tag_CPU_arch: v4
>    Tag_ARM_ISA_use: Yes
> diff --git a/include/opcode/arm.h b/include/opcode/arm.h
> index bb68a78154a41d577ffa293b19b951dcd7085247..5691a85545cf924383f9c73d9ce9a97a3a835cdf 100644
> --- a/include/opcode/arm.h
> +++ b/include/opcode/arm.h
> @@ -285,6 +285,7 @@
>  #define ARM_ARCH_NONE	ARM_FEATURE_LOW (0, 0)
>  #define FPU_NONE	ARM_FEATURE_LOW (0, 0)
>  #define ARM_ANY		ARM_FEATURE (-1, -1, 0)	/* Any basic core.  */
> +#define FPU_ANY		ARM_FEATURE_COPROC (-1) /* Any FPU.  */
>  #define ARM_FEATURE_ALL	ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features.  */
>  #define FPU_ANY_HARD	ARM_FEATURE_COPROC (FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
>  /* Extensions containing some Thumb-2 instructions.  If any is present, Thumb
> 


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