From 637aeb6b8da36a621cf076068498adc5322be069 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 2 Nov 2020 14:40:10 +0000 Subject: [PATCH] arm: Fix multiple inheritance thunks for thumb-1 with -mpure-code When -mpure-code is used, we cannot load delta from code memory (like we do without -mpure-code). This patch builds the value of mi_delta into r3 with a series of movs/adds/lsls. We also do some cleanup by not emitting the function address and delta via .word directives at the end of the thunk since we don't use them with -mpure-code. No need for new testcases, this bug was already identified by: g++.dg/ipa/pr46287-3.C g++.dg/ipa/pr46984.C g++.dg/opt/thunk1.C g++.dg/torture/pr46287.C g++.dg/torture/pr45699.C 2020-11-02 Christophe Lyon gcc/ * config/arm/arm.c (arm_thumb1_mi_thunk): Build mi_delta in r3 and do not emit function address and delta when -mpure-code is used. --- gcc/config/arm/arm.c | 67 +++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index bfc1249f941..5612d1e7e18 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -28528,9 +28528,19 @@ arm_thumb1_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta, { if (mi_delta > 255) { - fputs ("\tldr\tr3, ", file); - assemble_name (file, label); - fputs ("+4\n", file); + /* With -mpure-code, we cannot load MI_DELTA from the + constant pool: we build it explicitly. */ + if (target_pure_code) + { + thumb1_const_print r3 (file, 3); + thumb1_gen_const_int_1 (r3, mi_delta); + } + else + { + fputs ("\tldr\tr3, ", file); + assemble_name (file, label); + fputs ("+4\n", file); + } asm_fprintf (file, "\t%ss\t%r, %r, r3\n", mi_op, this_regno, this_regno); } @@ -28566,30 +28576,37 @@ arm_thumb1_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta, fputs ("\tpop\t{r3}\n", file); fprintf (file, "\tbx\tr12\n"); - ASM_OUTPUT_ALIGN (file, 2); - assemble_name (file, label); - fputs (":\n", file); - if (flag_pic) + + /* With -mpure-code, we don't need to emit literals for the + function address and delta since we emitted code to build + them. */ + if (!target_pure_code) { - /* Output ".word .LTHUNKn-[3,7]-.LTHUNKPCn". */ - rtx tem = XEXP (DECL_RTL (function), 0); - /* For TARGET_THUMB1_ONLY the thunk is in Thumb mode, so the PC - pipeline offset is four rather than eight. Adjust the offset - accordingly. */ - tem = plus_constant (GET_MODE (tem), tem, - TARGET_THUMB1_ONLY ? -3 : -7); - tem = gen_rtx_MINUS (GET_MODE (tem), - tem, - gen_rtx_SYMBOL_REF (Pmode, - ggc_strdup (labelpc))); - assemble_integer (tem, 4, BITS_PER_WORD, 1); - } - else - /* Output ".word .LTHUNKn". */ - assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1); + ASM_OUTPUT_ALIGN (file, 2); + assemble_name (file, label); + fputs (":\n", file); + if (flag_pic) + { + /* Output ".word .LTHUNKn-[3,7]-.LTHUNKPCn". */ + rtx tem = XEXP (DECL_RTL (function), 0); + /* For TARGET_THUMB1_ONLY the thunk is in Thumb mode, so the PC + pipeline offset is four rather than eight. Adjust the offset + accordingly. */ + tem = plus_constant (GET_MODE (tem), tem, + TARGET_THUMB1_ONLY ? -3 : -7); + tem = gen_rtx_MINUS (GET_MODE (tem), + tem, + gen_rtx_SYMBOL_REF (Pmode, + ggc_strdup (labelpc))); + assemble_integer (tem, 4, BITS_PER_WORD, 1); + } + else + /* Output ".word .LTHUNKn". */ + assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1); - if (TARGET_THUMB1_ONLY && mi_delta > 255) - assemble_integer (GEN_INT(mi_delta), 4, BITS_PER_WORD, 1); + if (TARGET_THUMB1_ONLY && mi_delta > 255) + assemble_integer (GEN_INT (mi_delta), 4, BITS_PER_WORD, 1); + } } else { -- 2.30.2