diff mbox

[AArch64,TLSLE,3/3] Implement local executable mode for all memory model

Message ID n99fv3f5oo1.fsf@arm.com
State New
Headers show

Commit Message

Jiong Wang Aug. 19, 2015, 2:21 p.m. UTC
Marcus Shawcroft writes:

> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>
>> 2015-05-14  Jiong Wang  <jiong.wang@arm.com>
>> gcc/
>>   * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>>   * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>>   sequences.
>>   (tlsle_<mode>): New define_insn.
>>   (tlsle_movsym_<mode>): Ditto.
>>   * config/aarch64/constraints.md (Uta): New constraint.
>>   (Utb): Ditto.
>>   (Utc): Ditto.
>>   (Utd): Ditto.
>>
>> gcc/testsuite/
>>   * gcc.target/aarch64/tlsle.c: New test source.
>>   * gcc.target/aarch64/tlsle12.c: New testcase.
>>   * gcc.target/aarch64/tlsle24.c: New testcase.
>>   * gcc.target/aarch64/tlsle32.c: New testcase.
>>
>
>
>   case SYMBOL_TLSLE:
> -  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
> +  if (aarch64_tls_size <= 12)
> +    /* Make sure TLS offset fit into 12bit.  */
> +    asm_fprintf (asm_out_file, ":tprel_lo12:");
> +  else
> +    asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>    break;
>
> Use the existing classify_symbol mechanism we use throughout the
> aarch64 backend.  Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
> and introduce the 3 missing flavours then use the symbol
> classification to control behaviour such as this modifier selection.

Done.

classified TLS symbol into the following sub-types according to the value of tls size.

 SYMBOL_TLSLE12
 SYMBOL_TLSLE24
 SYMBOL_TLSLE32
 SYMBOL_TLSLE48

And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
only supported in binutils since 2015-03-04 as PR gas/17843. So I
adjusted tlsle32.c to make it robust by detecting whether there is such
binutils support.

OK for trunk?

2015-08-19  Marcus Shawcroft  <marcus.shawcroft@arm.com>
            Jiong Wang  <jiong.wang@arm.com>
gcc/
  * config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
  tls size for tiny, small, large memory model.
  (aarch64_load_symref_appropriately): Support new symbol types.
  (aarch64_expand_mov_immediate): Likewise.
  (aarch64_print_operand): Likewise.
  (aarch64_classify_tls_symbol): Likewise.
  * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
  (aarch64_symbol_type): Likewise.
  * config/aarch64/aarch64.md (tlsle): Deleted.
  (tlsle12_<mode>): New define_insn.
  (tlsle24_<mode>): Likewise.
  (tlsle32_<mode>): Likewise.
  (tlsle48_<mode>): Likewise.
  * doc/sourcebuild.texi (AArch64-specific attributes): Document
  "aarch64_tlsle32".

gcc/testsuite/
  * lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
  New test directive.
  * gcc.target/aarch64/tlsle_1.x: New test source.
  * gcc.target/aarch64/tlsle12.c: New testcase.
  * gcc.target/aarch64/tlsle24.c: New testcase.
  * gcc.target/aarch64/tlsle32.c: New testcase.

Comments

Marcus Shawcroft Aug. 25, 2015, 9:48 a.m. UTC | #1
> 2015-08-19  Marcus Shawcroft  <marcus.shawcroft@arm.com>
>             Jiong Wang  <jiong.wang@arm.com>
> gcc/
>   * config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
>   tls size for tiny, small, large memory model.
>   (aarch64_load_symref_appropriately): Support new symbol types.
>   (aarch64_expand_mov_immediate): Likewise.
>   (aarch64_print_operand): Likewise.
>   (aarch64_classify_tls_symbol): Likewise.
>   * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
>   (aarch64_symbol_type): Likewise.
>   * config/aarch64/aarch64.md (tlsle): Deleted.
>   (tlsle12_<mode>): New define_insn.
>   (tlsle24_<mode>): Likewise.
>   (tlsle32_<mode>): Likewise.
>   (tlsle48_<mode>): Likewise.
>   * doc/sourcebuild.texi (AArch64-specific attributes): Document
>   "aarch64_tlsle32".
>
> gcc/testsuite/
>   * lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
>   New test directive.
>   * gcc.target/aarch64/tlsle_1.x: New test source.
>   * gcc.target/aarch64/tlsle12.c: New testcase.
>   * gcc.target/aarch64/tlsle24.c: New testcase.
>   * gcc.target/aarch64/tlsle32.c: New testcase.
> --
>
OK /Marcus
Christophe Lyon Aug. 27, 2015, 7:44 a.m. UTC | #2
On 19 August 2015 at 16:21, Jiong Wang <jiong.wang@arm.com> wrote:
>
> Marcus Shawcroft writes:
>
>> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>>
>>> 2015-05-14  Jiong Wang  <jiong.wang@arm.com>
>>> gcc/
>>>   * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>>>   * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>>>   sequences.
>>>   (tlsle_<mode>): New define_insn.
>>>   (tlsle_movsym_<mode>): Ditto.
>>>   * config/aarch64/constraints.md (Uta): New constraint.
>>>   (Utb): Ditto.
>>>   (Utc): Ditto.
>>>   (Utd): Ditto.
>>>
>>> gcc/testsuite/
>>>   * gcc.target/aarch64/tlsle.c: New test source.
>>>   * gcc.target/aarch64/tlsle12.c: New testcase.
>>>   * gcc.target/aarch64/tlsle24.c: New testcase.
>>>   * gcc.target/aarch64/tlsle32.c: New testcase.
>>>
>>
>>
>>   case SYMBOL_TLSLE:
>> -  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>> +  if (aarch64_tls_size <= 12)
>> +    /* Make sure TLS offset fit into 12bit.  */
>> +    asm_fprintf (asm_out_file, ":tprel_lo12:");
>> +  else
>> +    asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>    break;
>>
>> Use the existing classify_symbol mechanism we use throughout the
>> aarch64 backend.  Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
>> and introduce the 3 missing flavours then use the symbol
>> classification to control behaviour such as this modifier selection.
>
> Done.
>
> classified TLS symbol into the following sub-types according to the value of tls size.
>
>  SYMBOL_TLSLE12
>  SYMBOL_TLSLE24
>  SYMBOL_TLSLE32
>  SYMBOL_TLSLE48
>
> And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
> utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
> only supported in binutils since 2015-03-04 as PR gas/17843. So I
> adjusted tlsle32.c to make it robust by detecting whether there is such
> binutils support.
>

Hi,

I'm (still) using binutils-2.25, and I can see that 2 of these new
tests (tlsle12_1.c and tlsle24_1.c) fail at execution time on
aarch64*-none-elf targets.
Can you adjust the testcase?

Thanks

Christophe.

> OK for trunk?
>
> 2015-08-19  Marcus Shawcroft  <marcus.shawcroft@arm.com>
>             Jiong Wang  <jiong.wang@arm.com>
> gcc/
>   * config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
>   tls size for tiny, small, large memory model.
>   (aarch64_load_symref_appropriately): Support new symbol types.
>   (aarch64_expand_mov_immediate): Likewise.
>   (aarch64_print_operand): Likewise.
>   (aarch64_classify_tls_symbol): Likewise.
>   * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
>   (aarch64_symbol_type): Likewise.
>   * config/aarch64/aarch64.md (tlsle): Deleted.
>   (tlsle12_<mode>): New define_insn.
>   (tlsle24_<mode>): Likewise.
>   (tlsle32_<mode>): Likewise.
>   (tlsle48_<mode>): Likewise.
>   * doc/sourcebuild.texi (AArch64-specific attributes): Document
>   "aarch64_tlsle32".
>
> gcc/testsuite/
>   * lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
>   New test directive.
>   * gcc.target/aarch64/tlsle_1.x: New test source.
>   * gcc.target/aarch64/tlsle12.c: New testcase.
>   * gcc.target/aarch64/tlsle24.c: New testcase.
>   * gcc.target/aarch64/tlsle32.c: New testcase.
> --
> Regards,
> Jiong
>
Jiong Wang Aug. 27, 2015, 8:35 a.m. UTC | #3
Christophe Lyon writes:

> On 19 August 2015 at 16:21, Jiong Wang <jiong.wang@arm.com> wrote:
>>
>> Marcus Shawcroft writes:
>>
>>> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>>>
>>>> 2015-05-14  Jiong Wang  <jiong.wang@arm.com>
>>>> gcc/
>>>>   * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>>>>   * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>>>>   sequences.
>>>>   (tlsle_<mode>): New define_insn.
>>>>   (tlsle_movsym_<mode>): Ditto.
>>>>   * config/aarch64/constraints.md (Uta): New constraint.
>>>>   (Utb): Ditto.
>>>>   (Utc): Ditto.
>>>>   (Utd): Ditto.
>>>>
>>>> gcc/testsuite/
>>>>   * gcc.target/aarch64/tlsle.c: New test source.
>>>>   * gcc.target/aarch64/tlsle12.c: New testcase.
>>>>   * gcc.target/aarch64/tlsle24.c: New testcase.
>>>>   * gcc.target/aarch64/tlsle32.c: New testcase.
>>>>
>>>
>>>
>>>   case SYMBOL_TLSLE:
>>> -  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>> +  if (aarch64_tls_size <= 12)
>>> +    /* Make sure TLS offset fit into 12bit.  */
>>> +    asm_fprintf (asm_out_file, ":tprel_lo12:");
>>> +  else
>>> +    asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>>    break;
>>>
>>> Use the existing classify_symbol mechanism we use throughout the
>>> aarch64 backend.  Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
>>> and introduce the 3 missing flavours then use the symbol
>>> classification to control behaviour such as this modifier selection.
>>
>> Done.
>>
>> classified TLS symbol into the following sub-types according to the value of tls size.
>>
>>  SYMBOL_TLSLE12
>>  SYMBOL_TLSLE24
>>  SYMBOL_TLSLE32
>>  SYMBOL_TLSLE48
>>
>> And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
>> utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
>> only supported in binutils since 2015-03-04 as PR gas/17843. So I
>> adjusted tlsle32.c to make it robust by detecting whether there is such
>> binutils support.
>>
>
> Hi,
>
> I'm (still) using binutils-2.25, and I can see that 2 of these new
> tests (tlsle12_1.c and tlsle24_1.c) fail at execution time on
> aarch64*-none-elf targets.

Christophe,

Those relocation types required by tls-size 12 & 24 are supported by
binutils-2.25 already, and you have passed compilation and failed at
exectuion, so there do have something wrong I guess.

Either the generated instruction sequence or the bare-metal environment.

One thing strange to me is those testcases are guarded by:

  /* { dg-require-effective-target tls_native } */

while for bare-metal environment, normally you don't have tls_native
support right? then these testcases should have been marked as
unsupported otherwise they will generate native tls instruction
sequences while the bare-metal runtime environment may don't support
initialize tp register etc, thus caused the exectuion error.

Could you please double check this? thanks

Regards,
Jiong
Christophe Lyon Aug. 27, 2015, 9:22 a.m. UTC | #4
On 27 August 2015 at 10:35, Jiong Wang <jiong.wang@arm.com> wrote:
>
> Christophe Lyon writes:
>
>> On 19 August 2015 at 16:21, Jiong Wang <jiong.wang@arm.com> wrote:
>>>
>>> Marcus Shawcroft writes:
>>>
>>>> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>>>>
>>>>> 2015-05-14  Jiong Wang  <jiong.wang@arm.com>
>>>>> gcc/
>>>>>   * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>>>>>   * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>>>>>   sequences.
>>>>>   (tlsle_<mode>): New define_insn.
>>>>>   (tlsle_movsym_<mode>): Ditto.
>>>>>   * config/aarch64/constraints.md (Uta): New constraint.
>>>>>   (Utb): Ditto.
>>>>>   (Utc): Ditto.
>>>>>   (Utd): Ditto.
>>>>>
>>>>> gcc/testsuite/
>>>>>   * gcc.target/aarch64/tlsle.c: New test source.
>>>>>   * gcc.target/aarch64/tlsle12.c: New testcase.
>>>>>   * gcc.target/aarch64/tlsle24.c: New testcase.
>>>>>   * gcc.target/aarch64/tlsle32.c: New testcase.
>>>>>
>>>>
>>>>
>>>>   case SYMBOL_TLSLE:
>>>> -  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>>> +  if (aarch64_tls_size <= 12)
>>>> +    /* Make sure TLS offset fit into 12bit.  */
>>>> +    asm_fprintf (asm_out_file, ":tprel_lo12:");
>>>> +  else
>>>> +    asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>>>    break;
>>>>
>>>> Use the existing classify_symbol mechanism we use throughout the
>>>> aarch64 backend.  Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
>>>> and introduce the 3 missing flavours then use the symbol
>>>> classification to control behaviour such as this modifier selection.
>>>
>>> Done.
>>>
>>> classified TLS symbol into the following sub-types according to the value of tls size.
>>>
>>>  SYMBOL_TLSLE12
>>>  SYMBOL_TLSLE24
>>>  SYMBOL_TLSLE32
>>>  SYMBOL_TLSLE48
>>>
>>> And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
>>> utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
>>> only supported in binutils since 2015-03-04 as PR gas/17843. So I
>>> adjusted tlsle32.c to make it robust by detecting whether there is such
>>> binutils support.
>>>
>>
>> Hi,
>>
>> I'm (still) using binutils-2.25, and I can see that 2 of these new
>> tests (tlsle12_1.c and tlsle24_1.c) fail at execution time on
>> aarch64*-none-elf targets.
>
> Christophe,
>
> Those relocation types required by tls-size 12 & 24 are supported by
> binutils-2.25 already, and you have passed compilation and failed at
> exectuion, so there do have something wrong I guess.
>
> Either the generated instruction sequence or the bare-metal environment.
>
> One thing strange to me is those testcases are guarded by:
>
>   /* { dg-require-effective-target tls_native } */
>
> while for bare-metal environment, normally you don't have tls_native
> support right? then these testcases should have been marked as
> unsupported otherwise they will generate native tls instruction
> sequences while the bare-metal runtime environment may don't support
> initialize tp register etc, thus caused the exectuion error.
>
> Could you please double check this? thanks
>

Well, the "tls_native" check passes (there is no "emutls" string in
the generated assembly).
This BTW, does not involve the binutils, since it only check the
assembly output.

Could it be a configure error instead? (where GCC wouldn't notice that
it shouldn't generate such relocations)
I can see it uses tprel_hi12 and tprel_lo12_nc.


> Regards,
> Jiong
>
Jiong Wang Aug. 27, 2015, 9:35 a.m. UTC | #5
Christophe Lyon writes:

> On 27 August 2015 at 10:35, Jiong Wang <jiong.wang@arm.com> wrote:
>>
>> Christophe Lyon writes:
>>
>>> On 19 August 2015 at 16:21, Jiong Wang <jiong.wang@arm.com> wrote:
>>>>
>>>> Marcus Shawcroft writes:
>>>>
>>>>> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>>>>>
>>>>>> 2015-05-14  Jiong Wang  <jiong.wang@arm.com>
>>>>>> gcc/
>>>>>>   * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>>>>>>   * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>>>>>>   sequences.
>>>>>>   (tlsle_<mode>): New define_insn.
>>>>>>   (tlsle_movsym_<mode>): Ditto.
>>>>>>   * config/aarch64/constraints.md (Uta): New constraint.
>>>>>>   (Utb): Ditto.
>>>>>>   (Utc): Ditto.
>>>>>>   (Utd): Ditto.
>>>>>>
>>>>>> gcc/testsuite/
>>>>>>   * gcc.target/aarch64/tlsle.c: New test source.
>>>>>>   * gcc.target/aarch64/tlsle12.c: New testcase.
>>>>>>   * gcc.target/aarch64/tlsle24.c: New testcase.
>>>>>>   * gcc.target/aarch64/tlsle32.c: New testcase.
>>>>>>
>>>>>
>>>>>
>>>>>   case SYMBOL_TLSLE:
>>>>> -  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>>>> +  if (aarch64_tls_size <= 12)
>>>>> +    /* Make sure TLS offset fit into 12bit.  */
>>>>> +    asm_fprintf (asm_out_file, ":tprel_lo12:");
>>>>> +  else
>>>>> +    asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
>>>>>    break;
>>>>>
>>>>> Use the existing classify_symbol mechanism we use throughout the
>>>>> aarch64 backend.  Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
>>>>> and introduce the 3 missing flavours then use the symbol
>>>>> classification to control behaviour such as this modifier selection.
>>>>
>>>> Done.
>>>>
>>>> classified TLS symbol into the following sub-types according to the value of tls size.
>>>>
>>>>  SYMBOL_TLSLE12
>>>>  SYMBOL_TLSLE24
>>>>  SYMBOL_TLSLE32
>>>>  SYMBOL_TLSLE48
>>>>
>>>> And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
>>>> utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
>>>> only supported in binutils since 2015-03-04 as PR gas/17843. So I
>>>> adjusted tlsle32.c to make it robust by detecting whether there is such
>>>> binutils support.
>>>>
>>>
>>> Hi,
>>>
>>> I'm (still) using binutils-2.25, and I can see that 2 of these new
>>> tests (tlsle12_1.c and tlsle24_1.c) fail at execution time on
>>> aarch64*-none-elf targets.
>>
>> Christophe,
>>
>> Those relocation types required by tls-size 12 & 24 are supported by
>> binutils-2.25 already, and you have passed compilation and failed at
>> exectuion, so there do have something wrong I guess.
>>
>> Either the generated instruction sequence or the bare-metal environment.
>>
>> One thing strange to me is those testcases are guarded by:
>>
>>   /* { dg-require-effective-target tls_native } */
>>
>> while for bare-metal environment, normally you don't have tls_native
>> support right? then these testcases should have been marked as
>> unsupported otherwise they will generate native tls instruction
>> sequences while the bare-metal runtime environment may don't support
>> initialize tp register etc, thus caused the exectuion error.
>>
>> Could you please double check this? thanks
>>
>
> Well, the "tls_native" check passes (there is no "emutls" string in
> the generated assembly).
> This BTW, does not involve the binutils, since it only check the
> assembly output.
>
> Could it be a configure error instead? (where GCC wouldn't notice that
> it shouldn't generate such relocations)

to me, it's more like this. native tls is enabled on a no such support
platform.

I am trying to setup a bare-metal environment for reproducing. I was
testing on linux environment.
Jiong Wang Aug. 27, 2015, 10:03 a.m. UTC | #6
Jiong Wang writes:
>>>
>>> Those relocation types required by tls-size 12 & 24 are supported by
>>> binutils-2.25 already, and you have passed compilation and failed at
>>> exectuion, so there do have something wrong I guess.
>>>
>>> Either the generated instruction sequence or the bare-metal environment.
>>>
>>> One thing strange to me is those testcases are guarded by:
>>>
>>>   /* { dg-require-effective-target tls_native } */
>>>
>>> while for bare-metal environment, normally you don't have tls_native
>>> support right? then these testcases should have been marked as
>>> unsupported otherwise they will generate native tls instruction
>>> sequences while the bare-metal runtime environment may don't support
>>> initialize tp register etc, thus caused the exectuion error.
>>>
>>> Could you please double check this? thanks
>>>
>>
>> Well, the "tls_native" check passes (there is no "emutls" string in
>> the generated assembly).
>> This BTW, does not involve the binutils, since it only check the
>> assembly output.
>>
>> Could it be a configure error instead? (where GCC wouldn't notice that
>> it shouldn't generate such relocations)
>
> to me, it's more like this. native tls is enabled on a no such support
> platform.
>
> I am trying to setup a bare-metal environment for reproducing. I was
> testing on linux environment.

Finished test on my local aarch64-none-elf bare-metal. they are marked
as unsupported correctly. gcc is doing correct configuration on my
environment. looks like somehow gcc is doing wrong tls enable on your
bare-metal platform.

UNSUPPORTED: gcc.target/aarch64/tlsdesc_hoist.c
UNSUPPORTED: gcc.target/aarch64/tlsle12_1.c
UNSUPPORTED: gcc.target/aarch64/tlsle24_1.c
UNSUPPORTED: gcc.target/aarch64/tlsle32_1.c
Christophe Lyon Aug. 27, 2015, 1:14 p.m. UTC | #7
On 27 August 2015 at 12:03, Jiong Wang <jiong.wang@arm.com> wrote:
>
> Jiong Wang writes:
>>>>
>>>> Those relocation types required by tls-size 12 & 24 are supported by
>>>> binutils-2.25 already, and you have passed compilation and failed at
>>>> exectuion, so there do have something wrong I guess.
>>>>
>>>> Either the generated instruction sequence or the bare-metal environment.
>>>>
>>>> One thing strange to me is those testcases are guarded by:
>>>>
>>>>   /* { dg-require-effective-target tls_native } */
>>>>
>>>> while for bare-metal environment, normally you don't have tls_native
>>>> support right? then these testcases should have been marked as
>>>> unsupported otherwise they will generate native tls instruction
>>>> sequences while the bare-metal runtime environment may don't support
>>>> initialize tp register etc, thus caused the exectuion error.
>>>>
>>>> Could you please double check this? thanks
>>>>
>>>
>>> Well, the "tls_native" check passes (there is no "emutls" string in
>>> the generated assembly).
>>> This BTW, does not involve the binutils, since it only check the
>>> assembly output.
>>>
>>> Could it be a configure error instead? (where GCC wouldn't notice that
>>> it shouldn't generate such relocations)
>>
>> to me, it's more like this. native tls is enabled on a no such support
>> platform.
>>
>> I am trying to setup a bare-metal environment for reproducing. I was
>> testing on linux environment.
>
> Finished test on my local aarch64-none-elf bare-metal. they are marked
> as unsupported correctly. gcc is doing correct configuration on my
> environment. looks like somehow gcc is doing wrong tls enable on your
> bare-metal platform.
>
I checked libgcc's configure output and it answers "no" to the
question "whether the thread-local storage support is from emutls"

What is the result in your case?

And before that 'assembler supports thread-local storage' is yes, too.

> UNSUPPORTED: gcc.target/aarch64/tlsdesc_hoist.c
> UNSUPPORTED: gcc.target/aarch64/tlsle12_1.c
> UNSUPPORTED: gcc.target/aarch64/tlsle24_1.c
> UNSUPPORTED: gcc.target/aarch64/tlsle32_1.c
> --
> Regards,
> Jiong
>
Jiong Wang Aug. 27, 2015, 1:35 p.m. UTC | #8
Christophe Lyon writes:

> On 27 August 2015 at 12:03, Jiong Wang <jiong.wang@arm.com> wrote:
>>
>> Jiong Wang writes:
>>>>>
>>>>> Those relocation types required by tls-size 12 & 24 are supported by
>>>>> binutils-2.25 already, and you have passed compilation and failed at
>>>>> exectuion, so there do have something wrong I guess.
>>>>>
>>>>> Either the generated instruction sequence or the bare-metal environment.
>>>>>
>>>>> One thing strange to me is those testcases are guarded by:
>>>>>
>>>>>   /* { dg-require-effective-target tls_native } */
>>>>>
>>>>> while for bare-metal environment, normally you don't have tls_native
>>>>> support right? then these testcases should have been marked as
>>>>> unsupported otherwise they will generate native tls instruction
>>>>> sequences while the bare-metal runtime environment may don't support
>>>>> initialize tp register etc, thus caused the exectuion error.
>>>>>
>>>>> Could you please double check this? thanks
>>>>>
>>>>
>>>> Well, the "tls_native" check passes (there is no "emutls" string in
>>>> the generated assembly).
>>>> This BTW, does not involve the binutils, since it only check the
>>>> assembly output.
>>>>
>>>> Could it be a configure error instead? (where GCC wouldn't notice that
>>>> it shouldn't generate such relocations)
>>>
>>> to me, it's more like this. native tls is enabled on a no such support
>>> platform.
>>>
>>> I am trying to setup a bare-metal environment for reproducing. I was
>>> testing on linux environment.
>>
>> Finished test on my local aarch64-none-elf bare-metal. they are marked
>> as unsupported correctly. gcc is doing correct configuration on my
>> environment. looks like somehow gcc is doing wrong tls enable on your
>> bare-metal platform.
>>
> I checked libgcc's configure output and it answers "no" to the
> question "whether the thread-local storage support is from emutls"
>
> What is the result in your case?
>
> And before that 'assembler supports thread-local storage' is yes, too.

configure:4849: checking whether the target assembler supports thread-local storage
...
configure:4867: result: yes

configure:4877: checking whether the thread-local storage support is from emutls
...
configure:4898: result: yes

That's my log which means native tls disabled as we are using emutls. A
double check shows my bare-metal environment is passing --disable-tls
explicitly when configuring gcc.

A further look at the gcc code shows gcc decides whether to use native
tls or emultls based on targetm.have_tls which is assigned to the value
HAVE_AS_TLS.

And HAVE_AS_TLS is defined during configure by simply assemble a .s
includs some simple instruction sequences contains tls specific
stuff.

So gcc is making the decision purely on static check, this make sense to
me, as it's hard or impossible to make runtime check because you only
have binutils that time as toolchain build steps is normally
binutils->gcc->libc->g++.

I think you need to pass "--disable-tls" to your bare-metal gcc
configuration, as gcc do needs user's help here as it doesn't understand
runtime features.

Above solution is only wrong if your bare-metal do support "tp" based
native tls mechanism which I think largely not.


>
>> UNSUPPORTED: gcc.target/aarch64/tlsdesc_hoist.c
>> UNSUPPORTED: gcc.target/aarch64/tlsle12_1.c
>> UNSUPPORTED: gcc.target/aarch64/tlsle24_1.c
>> UNSUPPORTED: gcc.target/aarch64/tlsle32_1.c
>> --
>> Regards,
>> Jiong
>>
Christophe Lyon Aug. 27, 2015, 1:45 p.m. UTC | #9
On 27 August 2015 at 15:35, Jiong Wang <jiong.wang@arm.com> wrote:
>
> Christophe Lyon writes:
>
>> On 27 August 2015 at 12:03, Jiong Wang <jiong.wang@arm.com> wrote:
>>>
>>> Jiong Wang writes:
>>>>>>
>>>>>> Those relocation types required by tls-size 12 & 24 are supported by
>>>>>> binutils-2.25 already, and you have passed compilation and failed at
>>>>>> exectuion, so there do have something wrong I guess.
>>>>>>
>>>>>> Either the generated instruction sequence or the bare-metal environment.
>>>>>>
>>>>>> One thing strange to me is those testcases are guarded by:
>>>>>>
>>>>>>   /* { dg-require-effective-target tls_native } */
>>>>>>
>>>>>> while for bare-metal environment, normally you don't have tls_native
>>>>>> support right? then these testcases should have been marked as
>>>>>> unsupported otherwise they will generate native tls instruction
>>>>>> sequences while the bare-metal runtime environment may don't support
>>>>>> initialize tp register etc, thus caused the exectuion error.
>>>>>>
>>>>>> Could you please double check this? thanks
>>>>>>
>>>>>
>>>>> Well, the "tls_native" check passes (there is no "emutls" string in
>>>>> the generated assembly).
>>>>> This BTW, does not involve the binutils, since it only check the
>>>>> assembly output.
>>>>>
>>>>> Could it be a configure error instead? (where GCC wouldn't notice that
>>>>> it shouldn't generate such relocations)
>>>>
>>>> to me, it's more like this. native tls is enabled on a no such support
>>>> platform.
>>>>
>>>> I am trying to setup a bare-metal environment for reproducing. I was
>>>> testing on linux environment.
>>>
>>> Finished test on my local aarch64-none-elf bare-metal. they are marked
>>> as unsupported correctly. gcc is doing correct configuration on my
>>> environment. looks like somehow gcc is doing wrong tls enable on your
>>> bare-metal platform.
>>>
>> I checked libgcc's configure output and it answers "no" to the
>> question "whether the thread-local storage support is from emutls"
>>
>> What is the result in your case?
>>
>> And before that 'assembler supports thread-local storage' is yes, too.
>
> configure:4849: checking whether the target assembler supports thread-local storage
> ...
> configure:4867: result: yes
>
> configure:4877: checking whether the thread-local storage support is from emutls
> ...
> configure:4898: result: yes
>
> That's my log which means native tls disabled as we are using emutls. A
> double check shows my bare-metal environment is passing --disable-tls
> explicitly when configuring gcc.
>
> A further look at the gcc code shows gcc decides whether to use native
> tls or emultls based on targetm.have_tls which is assigned to the value
> HAVE_AS_TLS.
>
> And HAVE_AS_TLS is defined during configure by simply assemble a .s
> includs some simple instruction sequences contains tls specific
> stuff.
>
> So gcc is making the decision purely on static check, this make sense to
> me, as it's hard or impossible to make runtime check because you only
> have binutils that time as toolchain build steps is normally
> binutils->gcc->libc->g++.
>
> I think you need to pass "--disable-tls" to your bare-metal gcc
> configuration, as gcc do needs user's help here as it doesn't understand
> runtime features.
>
Thanks for looking at that. Indeed, I do not pass --disable-tls, I relied on
configure to do-the-right-thing.

I'll make that change.

> Above solution is only wrong if your bare-metal do support "tp" based
> native tls mechanism which I think largely not.

I'm using the classical newlib.

>
>>
>>> UNSUPPORTED: gcc.target/aarch64/tlsdesc_hoist.c
>>> UNSUPPORTED: gcc.target/aarch64/tlsle12_1.c
>>> UNSUPPORTED: gcc.target/aarch64/tlsle24_1.c
>>> UNSUPPORTED: gcc.target/aarch64/tlsle32_1.c
>>> --
>>> Regards,
>>> Jiong
>>>
>
> --
> Regards,
> Jiong
>
diff mbox

Patch

From bd5c221101a9cf241c1f4d117c643e3a5c7e344d Mon Sep 17 00:00:00 2001
From: Jiong Wang <jiong.wang@arm.com>
Date: Wed, 19 Aug 2015 14:15:01 +0100
Subject: [PATCH 3/3] 3

---
 gcc/config/aarch64/aarch64-protos.h        |  6 +++
 gcc/config/aarch64/aarch64.c               | 66 ++++++++++++++++++++++++++----
 gcc/config/aarch64/aarch64.md              | 56 +++++++++++++++++--------
 gcc/testsuite/gcc.target/aarch64/tlsle12.c |  8 ++++
 gcc/testsuite/gcc.target/aarch64/tlsle24.c |  9 ++++
 gcc/testsuite/gcc.target/aarch64/tlsle32.c | 10 +++++
 gcc/testsuite/gcc.target/aarch64/tlsle_1.x | 14 +++++++
 gcc/testsuite/lib/target-supports.exp      | 17 ++++++++
 8 files changed, 161 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle12.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle24.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle32.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle_1.x

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index daa45bf..09d83e3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -74,7 +74,10 @@  enum aarch64_symbol_context
    SYMBOL_SMALL_TLSGD
    SYMBOL_SMALL_TLSDESC
    SYMBOL_SMALL_GOTTPREL
+   SYMBOL_TLSLE12
    SYMBOL_TLSLE24
+   SYMBOL_TLSLE32
+   SYMBOL_TLSLE48
    Each of these represents a thread-local symbol, and corresponds to the
    thread local storage relocation operator for the symbol being referred to.
 
@@ -111,7 +114,10 @@  enum aarch64_symbol_type
   SYMBOL_SMALL_GOTTPREL,
   SYMBOL_TINY_ABSOLUTE,
   SYMBOL_TINY_GOT,
+  SYMBOL_TLSLE12,
   SYMBOL_TLSLE24,
+  SYMBOL_TLSLE32,
+  SYMBOL_TLSLE48,
   SYMBOL_FORCE_TO_MEM
 };
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 87f8d96..9a1e53b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1115,14 +1115,43 @@  aarch64_load_symref_appropriately (rtx dest, rtx imm,
 	return;
       }
 
+    case SYMBOL_TLSLE12:
     case SYMBOL_TLSLE24:
+    case SYMBOL_TLSLE32:
+    case SYMBOL_TLSLE48:
       {
+	machine_mode mode = GET_MODE (dest);
 	rtx tp = aarch64_load_tp (NULL);
 
-	if (GET_MODE (dest) != Pmode)
-	  tp = gen_lowpart (GET_MODE (dest), tp);
+	if (mode != Pmode)
+	  tp = gen_lowpart (mode, tp);
+
+	switch (type)
+	  {
+	  case SYMBOL_TLSLE12:
+	    emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si)
+			(dest, tp, imm));
+	    break;
+	  case SYMBOL_TLSLE24:
+	    emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si)
+			(dest, tp, imm));
+	  break;
+	  case SYMBOL_TLSLE32:
+	    emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si)
+			(dest, imm));
+	    emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+			(dest, dest, tp));
+	  break;
+	  case SYMBOL_TLSLE48:
+	    emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si)
+			(dest, imm));
+	    emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+			(dest, dest, tp));
+	    break;
+	  default:
+	    gcc_unreachable ();
+	  }
 
-	emit_insn (gen_tlsle (dest, tp, imm));
 	set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
 	return;
       }
@@ -1677,7 +1706,10 @@  aarch64_expand_mov_immediate (rtx dest, rtx imm)
 
 	case SYMBOL_SMALL_ABSOLUTE:
 	case SYMBOL_TINY_ABSOLUTE:
+	case SYMBOL_TLSLE12:
 	case SYMBOL_TLSLE24:
+	case SYMBOL_TLSLE32:
+	case SYMBOL_TLSLE48:
 	  aarch64_load_symref_appropriately (dest, imm, sty);
 	  return;
 
@@ -4593,6 +4625,10 @@  aarch64_print_operand (FILE *f, rtx x, char code)
 	  asm_fprintf (asm_out_file, ":gottprel_lo12:");
 	  break;
 
+	case SYMBOL_TLSLE12:
+	  asm_fprintf (asm_out_file, ":tprel_lo12:");
+	  break;
+
 	case SYMBOL_TLSLE24:
 	  asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
 	  break;
@@ -7514,20 +7550,27 @@  initialize_aarch64_tls_size (struct gcc_options *opts)
   switch (opts->x_aarch64_cmodel_var)
     {
     case AARCH64_CMODEL_TINY:
-      /* The maximum TLS size allowed under tiny is 1M.  */
-      if (aarch64_tls_size > 20)
-	aarch64_tls_size = 20;
+      /* Both the default and maximum TLS size allowed under tiny is 1M which
+	 needs two instructions to address, so we clamp the size to 24.  */
+      if (aarch64_tls_size == 0 || aarch64_tls_size > 24)
+	aarch64_tls_size = 24;
       break;
     case AARCH64_CMODEL_SMALL:
       /* The maximum TLS size allowed under small is 4G.  */
       if (aarch64_tls_size > 32)
 	aarch64_tls_size = 32;
+      /* Default tls size be 16M.  */
+      else if (aarch64_tls_size == 0)
+	aarch64_tls_size = 24;
       break;
     case AARCH64_CMODEL_LARGE:
       /* The maximum TLS size allowed under large is 16E.
 	 FIXME: 16E should be 64bit, we only support 48bit offset now.  */
       if (aarch64_tls_size > 48)
 	aarch64_tls_size = 48;
+      /* Default tls size be 16M.  */
+      else if (aarch64_tls_size == 0)
+	aarch64_tls_size = 24;
       break;
     default:
       gcc_unreachable ();
@@ -8717,7 +8760,16 @@  aarch64_classify_tls_symbol (rtx x)
       return SYMBOL_SMALL_GOTTPREL;
 
     case TLS_MODEL_LOCAL_EXEC:
-      return SYMBOL_TLSLE24;
+      if (aarch64_tls_size == 12)
+	return SYMBOL_TLSLE12;
+      else if (aarch64_tls_size == 24)
+	return SYMBOL_TLSLE24;
+      else if (aarch64_tls_size == 32)
+	return SYMBOL_TLSLE32;
+      else if (aarch64_tls_size == 48)
+	return SYMBOL_TLSLE48;
+      else
+	gcc_unreachable ();
 
     case TLS_MODEL_EMULATED:
     case TLS_MODEL_NONE:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 35255e9..89fff15 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -117,7 +117,10 @@ 
     UNSPEC_ST4_LANE
     UNSPEC_TLS
     UNSPEC_TLSDESC
-    UNSPEC_TLSLE
+    UNSPEC_TLSLE12
+    UNSPEC_TLSLE24
+    UNSPEC_TLSLE32
+    UNSPEC_TLSLE48
     UNSPEC_USHL_2S
     UNSPEC_VSTRUCTDUMMY
     UNSPEC_SP_SET
@@ -4512,31 +4515,48 @@ 
    (set_attr "length" "8")]
 )
 
-(define_expand "tlsle"
-  [(set (match_operand 0 "register_operand" "=r")
-        (unspec [(match_operand 1 "register_operand" "r")
-                   (match_operand 2 "aarch64_tls_le_symref" "S")]
-                   UNSPEC_TLSLE))]
+(define_insn "tlsle12_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+	(unspec:P [(match_operand:P 1 "register_operand" "r")
+		   (match_operand 2 "aarch64_tls_le_symref" "S")]
+		   UNSPEC_TLSLE12))]
   ""
-{
-  machine_mode mode = GET_MODE (operands[0]);
-  emit_insn ((mode == DImode
-	      ? gen_tlsle_di
-	      : gen_tlsle_si) (operands[0], operands[1], operands[2]));
-  DONE;
-})
+  "add\\t%<w>0, %<w>1, #%L2";
+  [(set_attr "type" "alu_sreg")
+   (set_attr "length" "4")]
+)
 
-(define_insn "tlsle_<mode>"
+(define_insn "tlsle24_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
-        (unspec:P [(match_operand:P 1 "register_operand" "r")
-                   (match_operand 2 "aarch64_tls_le_symref" "S")]
-		   UNSPEC_TLSLE))]
+	(unspec:P [(match_operand:P 1 "register_operand" "r")
+		   (match_operand 2 "aarch64_tls_le_symref" "S")]
+		   UNSPEC_TLSLE24))]
   ""
   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
-  [(set_attr "type" "alu_sreg")
+  [(set_attr "type" "multiple")
    (set_attr "length" "8")]
 )
 
+(define_insn "tlsle32_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+	(unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+		   UNSPEC_TLSLE32))]
+  ""
+  "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
+  [(set_attr "type" "multiple")
+   (set_attr "length" "8")]
+)
+
+(define_insn "tlsle48_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+	(unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+		   UNSPEC_TLSLE48))]
+  ""
+  "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
+  [(set_attr "type" "multiple")
+   (set_attr "length" "12")]
+)
+
 (define_insn "tlsdesc_small_<mode>"
   [(set (reg:PTR R0_REGNUM)
         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle12.c b/gcc/testsuite/gcc.target/aarch64/tlsle12.c
new file mode 100644
index 0000000..846aa98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle12.c
@@ -0,0 +1,8 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=12 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle24.c b/gcc/testsuite/gcc.target/aarch64/tlsle24.c
new file mode 100644
index 0000000..e8b14ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle24.c
@@ -0,0 +1,9 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=24 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12_nc" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_hi12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle32.c b/gcc/testsuite/gcc.target/aarch64/tlsle32.c
new file mode 100644
index 0000000..edc06ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle32.c
@@ -0,0 +1,10 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-require-effective-target aarch64_tlsle32 } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=32 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_g1" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_g0_nc" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle_1.x b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x
new file mode 100644
index 0000000..d92281b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x
@@ -0,0 +1,14 @@ 
+void abort (void);
+
+__thread int t0 = 0x10;
+__thread int t1 = 0x10;
+
+int
+main (int argc, char **argv)
+{
+  if (t0 != t1)
+    abort ();
+
+  return  0;
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 1988301..70576b3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -957,6 +957,23 @@  proc check_effective_target_aarch64_small_fpic { } {
     }
 }
 
+# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
+# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
+# in binutils since 2015-03-04 as PR gas/17843.
+#
+# This test directive make sure binutils support all features needed by TLS LE
+# under -mtls-size=32 on AArch64.
+
+proc check_effective_target_aarch64_tlsle32 { } {
+    if { [istarget aarch64*-*-*] } {
+	return [check_no_compiler_messages aarch64_tlsle32 object {
+	    void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
+	}]
+    } else {
+	return 0
+    }
+}
+
 # Return 1 if -shared is supported, as in no warnings or errors
 # emitted, 0 otherwise.
 
-- 
1.9.1