From 48528842bd79cb2e2a1d478b1d90d748377bb76c Mon Sep 17 00:00:00 2001 From: Ramana Radhakrishnan Date: Tue, 23 Apr 2019 10:03:41 +0000 Subject: [PATCH] re PR target/89093 (C++ exception handling clobbers d8 VFP register) PR target/89093 * config/arm/arm.c (aapcs_vfp_is_call_or_return_candidate): Diagnose if used with general-regs-only. (arm_conditional_register_usage): Don't add non-general regs if general-regs-only. (arm_valid_target_attribute_rec): Handle general-regs-only. * config/arm/arm.h (TARGET_HARD_FLOAT): Return false if general-regs-only. (TARGET_HARD_FLOAT_SUB): Define. (TARGET_SOFT_FLOAT): Define as negation of TARGET_HARD_FLOAT_SUB. (TARGET_REALLY_IWMMXT): Add && !TARGET_GENERAL_REGS_ONLY. (TARGET_REALLY_IWMMXT2): Likewise. * config/arm/arm.opt: Add -mgeneral-regs-only. * doc/extend.texi: Document ARM general-regs-only target. * doc/invoke.texi: Document ARM -mgeneral-regs-only. libgcc/ * config/arm/pr-support.c: Add #pragma GCC target("general-regs-only"). * config/arm/unwind-arm.c: Likewise. * unwind-c.c (PERSONALITY_FUNCTION): Add general-regs-only target attribute for ARM. libobjc/ * exception.c (PERSONALITY_FUNCTION): Add general-regs-only target attribute for ARM. libphobos/ * libdruntime/gcc/deh.d: Import gcc.attribute. (personality_fn_attributes): New enum. (scanLSDA, CONTINUE_UNWINDING, gdc_personality, __gdc_personality): Add @personality_fn_attributes. libstdc++-v3/ * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Add general-regs-only target attribute for ARM. Co-Authored-By: Bernd Edlinger Co-Authored-By: Jakub Jelinek From-SVN: r270504 --- gcc/ChangeLog | 20 ++++++++++++++++++++ gcc/config/arm/arm.c | 10 +++++++++- gcc/config/arm/arm.h | 18 +++++++++++++----- gcc/config/arm/arm.opt | 4 ++++ gcc/doc/extend.texi | 9 +++++++++ gcc/doc/invoke.texi | 7 +++++++ libgcc/ChangeLog | 10 ++++++++++ libgcc/config/arm/pr-support.c | 1 + libgcc/config/arm/unwind-arm.c | 1 + libgcc/unwind-c.c | 1 + libobjc/ChangeLog | 8 ++++++++ libobjc/exception.c | 1 + libphobos/ChangeLog | 10 ++++++++++ libphobos/libdruntime/gcc/deh.d | 13 +++++++++++++ libstdc++-v3/ChangeLog | 8 ++++++++ libstdc++-v3/libsupc++/eh_personality.cc | 1 + 16 files changed, 116 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d032754399..185cf518746 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2019-04-23 Ramana Radhakrishnan + Bernd Edlinger + Jakub Jelinek + + PR target/89093 + * config/arm/arm.c (aapcs_vfp_is_call_or_return_candidate): Diagnose + if used with general-regs-only. + (arm_conditional_register_usage): Don't add non-general regs if + general-regs-only. + (arm_valid_target_attribute_rec): Handle general-regs-only. + * config/arm/arm.h (TARGET_HARD_FLOAT): Return false if + general-regs-only. + (TARGET_HARD_FLOAT_SUB): Define. + (TARGET_SOFT_FLOAT): Define as negation of TARGET_HARD_FLOAT_SUB. + (TARGET_REALLY_IWMMXT): Add && !TARGET_GENERAL_REGS_ONLY. + (TARGET_REALLY_IWMMXT2): Likewise. + * config/arm/arm.opt: Add -mgeneral-regs-only. + * doc/extend.texi: Document ARM general-regs-only target. + * doc/invoke.texi: Document ARM -mgeneral-regs-only. + 2019-04-23 Bin Cheng PR tree-optimization/90078 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 731150d7c18..45abcd89963 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6112,6 +6112,11 @@ aapcs_vfp_is_call_or_return_candidate (enum arm_pcs pcs_variant, return false; *base_mode = new_mode; + + if (TARGET_GENERAL_REGS_ONLY) + error ("argument of type %qT not permitted with -mgeneral-regs-only", + type); + return true; } @@ -28404,7 +28409,7 @@ arm_conditional_register_usage (void) } } - if (TARGET_REALLY_IWMMXT) + if (TARGET_REALLY_IWMMXT && !TARGET_GENERAL_REGS_ONLY) { regno = FIRST_IWMMXT_GR_REGNUM; /* The 2002/10/09 revision of the XScale ABI has wCG0 @@ -30878,6 +30883,9 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) else if (!strcmp (q, "arm")) opts->x_target_flags &= ~MASK_THUMB; + else if (!strcmp (q, "general-regs-only")) + opts->x_target_flags |= MASK_GENERAL_REGS_ONLY; + else if (!strncmp (q, "fpu=", 4)) { int fpu_index; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 7adafead0f2..4866e1e4b7d 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -122,12 +122,18 @@ extern tree arm_fp16_type_node; #define TARGET_32BIT_P(flags) (TARGET_ARM_P (flags) || TARGET_THUMB2_P (flags)) /* Run-time Target Specification. */ -/* Use hardware floating point instructions. */ -#define TARGET_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT \ +/* Use hardware floating point instructions. -mgeneral-regs-only prevents +the use of floating point instructions and registers but does not prevent +emission of floating point pcs attributes. */ +#define TARGET_HARD_FLOAT_SUB (arm_float_abi != ARM_FLOAT_ABI_SOFT \ && bitmap_bit_p (arm_active_target.isa, \ isa_bit_vfpv2) \ && TARGET_32BIT) -#define TARGET_SOFT_FLOAT (!TARGET_HARD_FLOAT) + +#define TARGET_HARD_FLOAT (TARGET_HARD_FLOAT_SUB \ + && !TARGET_GENERAL_REGS_ONLY) + +#define TARGET_SOFT_FLOAT (!TARGET_HARD_FLOAT_SUB) /* User has permitted use of FP instructions, if they exist for this target. */ #define TARGET_MAYBE_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT) @@ -135,8 +141,10 @@ extern tree arm_fp16_type_node; #define TARGET_HARD_FLOAT_ABI (arm_float_abi == ARM_FLOAT_ABI_HARD) #define TARGET_IWMMXT (arm_arch_iwmmxt) #define TARGET_IWMMXT2 (arm_arch_iwmmxt2) -#define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_32BIT) -#define TARGET_REALLY_IWMMXT2 (TARGET_IWMMXT2 && TARGET_32BIT) +#define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_32BIT \ + && !TARGET_GENERAL_REGS_ONLY) +#define TARGET_REALLY_IWMMXT2 (TARGET_IWMMXT2 && TARGET_32BIT \ + && !TARGET_GENERAL_REGS_ONLY) #define TARGET_IWMMXT_ABI (TARGET_32BIT && arm_abi == ARM_ABI_IWMMXT) #define TARGET_ARM (! TARGET_THUMB) #define TARGET_EITHER 1 /* (TARGET_ARM | TARGET_THUMB) */ diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt index 94c68753c24..9067d491b9c 100644 --- a/gcc/config/arm/arm.opt +++ b/gcc/config/arm/arm.opt @@ -302,3 +302,7 @@ When linking for big-endian targets, generate a legacy BE32 format image. mbranch-cost= Target RejectNegative Joined UInteger Var(arm_branch_cost) Init(-1) Cost to assume for a branch insn. + +mgeneral-regs-only +Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Save +Generate code which uses the core registers only (r0-r14). diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0bb1fd23686..91679e8b9ba 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4190,6 +4190,15 @@ into the @code{sjli} table needs to be passed as argument. These function attributes are supported for ARM targets: @table @code + +@item general-regs-only +@cindex @code{general-regs-only} function attribute, ARM +Indicates that no floating-point or Advanced SIMD registers should be +used when generating code for this function. If the function explicitly +uses floating-point code, then the compiler gives an error. This is +the same behavior as that of the command-line option +@option{-mgeneral-regs-only}. + @item interrupt @cindex @code{interrupt} function attribute, ARM Use this attribute to indicate diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f4aa9e53de8..29585cf15aa 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -674,6 +674,7 @@ Objective-C and Objective-C++ Dialects}. -mabi=@var{name} @gol -mapcs-stack-check -mno-apcs-stack-check @gol -mapcs-reentrant -mno-apcs-reentrant @gol +-mgeneral-regs-only @gol -msched-prolog -mno-sched-prolog @gol -mlittle-endian -mbig-endian @gol -mbe8 -mbe32 @gol @@ -17068,6 +17069,12 @@ the hard-float and soft-float ABIs are not link-compatible; you must compile your entire program with the same ABI, and link with a compatible set of libraries. +@item -mgeneral-regs-only +@opindex mgeneral-regs-only +Generate code which uses only the general-purpose registers. This will prevent +the compiler from using floating-point and Advanced SIMD registers but will not +impose any restrictions on the assembler. + @item -mlittle-endian @opindex mlittle-endian Generate code for a processor running in little-endian mode. This is diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index de8d56a2ee7..30e4da4277e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,13 @@ +2019-04-23 Ramana Radhakrishnan + Bernd Edlinger + Jakub Jelinek + + PR target/89093 + * config/arm/pr-support.c: Add #pragma GCC target("general-regs-only"). + * config/arm/unwind-arm.c: Likewise. + * unwind-c.c (PERSONALITY_FUNCTION): Add general-regs-only target + attribute for ARM. + 2019-04-15 Monk Chiang * config/nds32/linux-unwind.h (SIGRETURN): Remove. diff --git a/libgcc/config/arm/pr-support.c b/libgcc/config/arm/pr-support.c index ed557394e9f..bcf9b288fe9 100644 --- a/libgcc/config/arm/pr-support.c +++ b/libgcc/config/arm/pr-support.c @@ -21,6 +21,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ +#pragma GCC target ("general-regs-only") #include "unwind.h" /* We add a prototype for abort here to avoid creating a dependency on diff --git a/libgcc/config/arm/unwind-arm.c b/libgcc/config/arm/unwind-arm.c index 00e183d325d..9ba73e72a2a 100644 --- a/libgcc/config/arm/unwind-arm.c +++ b/libgcc/config/arm/unwind-arm.c @@ -21,6 +21,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ +#pragma GCC target ("general-regs-only") #include "unwind.h" /* Misc constants. */ diff --git a/libgcc/unwind-c.c b/libgcc/unwind-c.c index 3e55cda7f7b..859735a3325 100644 --- a/libgcc/unwind-c.c +++ b/libgcc/unwind-c.c @@ -106,6 +106,7 @@ PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *); _Unwind_Reason_Code +__attribute__((target ("general-regs-only"))) PERSONALITY_FUNCTION (_Unwind_State state, struct _Unwind_Exception * ue_header, struct _Unwind_Context * context) diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index 90cf92331e9..48e21e5b21c 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,11 @@ +2019-04-23 Ramana Radhakrishnan + Bernd Edlinger + Jakub Jelinek + + PR target/89093 + * exception.c (PERSONALITY_FUNCTION): Add general-regs-only target + attribute for ARM. + 2019-03-06 Uroš Bizjak * encoding.c (DFmode): #undef before #define. diff --git a/libobjc/exception.c b/libobjc/exception.c index b96630c75ee..3c078c04126 100644 --- a/libobjc/exception.c +++ b/libobjc/exception.c @@ -220,6 +220,7 @@ get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i) while (0) _Unwind_Reason_Code +__attribute__((target ("general-regs-only"))) PERSONALITY_FUNCTION (_Unwind_State state, struct _Unwind_Exception *ue_header, struct _Unwind_Context *context) diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 4f158776e23..74c9c88730d 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,13 @@ +2019-04-23 Ramana Radhakrishnan + Bernd Edlinger + Jakub Jelinek + + PR target/89093 + * libdruntime/gcc/deh.d: Import gcc.attribute. + (personality_fn_attributes): New enum. + (scanLSDA, CONTINUE_UNWINDING, gdc_personality, __gdc_personality): + Add @personality_fn_attributes. + 2019-04-20 Iain Buclaw PR d/89293 diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index c04dc21263b..ee301b2a3ba 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -28,6 +28,7 @@ import gcc.unwind; import gcc.unwind.pe; import gcc.builtins; import gcc.config; +import gcc.attribute; extern(C) { @@ -519,10 +520,19 @@ extern(C) void _d_throw(Throwable object) terminate("unwind error", __LINE__); } +static if (GNU_ARM_EABI_Unwinder) +{ + enum personality_fn_attributes = attribute("target", ("general-regs-only")); +} +else +{ + enum personality_fn_attributes = ""; +} /** * Read and extract information from the LSDA (.gcc_except_table section). */ +@personality_fn_attributes _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class exceptionClass, _Unwind_Action actions, _Unwind_Exception* unwindHeader, _Unwind_Context* context, _Unwind_Word cfa, @@ -772,6 +782,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, * Called when the personality function has found neither a cleanup or handler. * To support ARM EABI personality routines, that must also unwind the stack. */ +@personality_fn_attributes _Unwind_Reason_Code CONTINUE_UNWINDING(_Unwind_Exception* unwindHeader, _Unwind_Context* context) { static if (GNU_ARM_EABI_Unwinder) @@ -814,6 +825,7 @@ else static if (GNU_ARM_EABI_Unwinder) { pragma(mangle, PERSONALITY_FUNCTION) + @personality_fn_attributes extern(C) _Unwind_Reason_Code gdc_personality(_Unwind_State state, _Unwind_Exception* unwindHeader, _Unwind_Context* context) @@ -873,6 +885,7 @@ else } } +@personality_fn_attributes private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions, _Unwind_Exception_Class exceptionClass, _Unwind_Exception* unwindHeader, diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2533fe81f6c..e222cb30de9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2019-04-23 Ramana Radhakrishnan + Bernd Edlinger + Jakub Jelinek + + PR target/89093 + * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Add + general-regs-only target attribute for ARM. + 2019-04-23 Jonathan Wakely PR libstdc++/87431 diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index d1cc6225742..35e4e461d69 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -343,6 +343,7 @@ extern "C" #endif _Unwind_Reason_Code #ifdef __ARM_EABI_UNWINDER__ +__attribute__((target ("general-regs-only"))) PERSONALITY_FUNCTION (_Unwind_State state, struct _Unwind_Exception* ue_header, struct _Unwind_Context* context) -- 2.30.2