Some chips (such as SiWx917 from Silicon Labs) have slow data bus access. The -mslow-flash-data option generates appropriate code for these chips by disabling literal pools. However, the current implementation completely prevents TLS (Thread Local Storage) variables from working, since ARM does not provide relocations to encode TLS variables directly into instructions - they require literal pools.
This change relaxes the -mslow-flash-data constraint to allow literal pools specifically for TLS accesses. While this results in slower TLS access (hence a warning is emitted), it is preferable to a hard error that prevents TLS usage entirely. With -mpure-code, literal pools remain completely disabled and TLS access still results in an error. Signed-off-by: Jérôme Pouiller <[email protected]> --- gcc/config/arm/arm.cc | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index a8ab7a4fb82..ff99b3aafb5 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -8704,6 +8704,19 @@ arm_legitimate_address_outer_p (machine_mode mode, rtx x, RTX_CODE outer, return 0; } +/* Return nonzero if literal pool is allowed for the constant X. + With -mslow-flash-data, literal pools are allowed specifically for TLS + access. With -mpure-code, literal pools are never allowed. */ +static int +arm_literal_pool_allowed_p (rtx x) +{ + if (!arm_disable_literal_pool) + return 1; + if (target_slow_flash_data && tls_mentioned_p (x)) + return 1; + return 0; +} + /* Return true if we can avoid creating a constant pool entry for x. */ static bool can_avoid_literal_pool_for_label_p (rtx x) @@ -8723,8 +8736,9 @@ can_avoid_literal_pool_for_label_p (rtx x) (set (reg r0) (mem (reg r0))). No extra register is required, and (mem (reg r0)) won't cause the use of literal pools. */ - if (arm_disable_literal_pool && SYMBOL_REF_P (x) - && CONSTANT_POOL_ADDRESS_P (x)) + if (SYMBOL_REF_P (x) + && CONSTANT_POOL_ADDRESS_P (x) + && !arm_literal_pool_allowed_p (get_pool_constant (x))) return 1; return 0; } @@ -9093,7 +9107,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p) else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x) && SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x) && !flag_pic - && !arm_disable_literal_pool) + && arm_literal_pool_allowed_p (get_pool_constant (x))) return 1; /* This is PC relative data after arm_reorg runs. */ @@ -9159,7 +9173,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p) && GET_MODE_SIZE (mode) == 4 && SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x) - && !arm_disable_literal_pool + && arm_literal_pool_allowed_p (get_pool_constant (x)) && ! (flag_pic && symbol_mentioned_p (get_pool_constant (x)) && ! pcrel_constant_p (get_pool_constant (x)))) @@ -9695,10 +9709,11 @@ arm_tls_referenced_p (rtx x) { /* ARM currently does not provide relocations to encode TLS variables into AArch32 instructions, only data, so there is no way to - currently implement these if a literal pool is disabled. */ - if (arm_disable_literal_pool) + currently implement these if a literal pool is disabled. + With -mslow-flash-data, we allow TLS by using the literal pool. */ + if (target_pure_code) sorry ("accessing thread-local storage is not currently supported " - "with %<-mpure-code%> or %<-mslow-flash-data%>"); + "with %<-mpure-code%>"); return true; } @@ -18264,7 +18279,7 @@ static void push_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc, machine_mode mode, rtx value) { - gcc_assert (!arm_disable_literal_pool); + gcc_assert (arm_literal_pool_allowed_p (value)); Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix)); fix->insn = insn; @@ -19602,7 +19617,7 @@ arm_reorg (void) /* Make sure we do not attempt to create a literal pool even though it should no longer be necessary to create any. */ - if (arm_disable_literal_pool) + if (target_pure_code) return ; minipool_fix_head = minipool_fix_tail = NULL; -- 2.47.3
