[arm] Tweak C++ guard variables
Paul Brook
paul@codesourcery.com
Thu Jun 24 18:45:00 GMT 2004
The patch below changes guard variables for static one-time construction in
line with the arm c++ eabi.
It consists of two changes:
- The guard variable is a (32-bit) int, not long long.
- It sets/tests the least significant bit, rather than the first byte.
Technically the g++ and libstdc++ changes are independent because the compiler
doesn't use the helper function, but it makes sense to keep them in sync.
I've enabled the changes unconditionally (on arm targets). I'm not sure if
this is desirable, or if they should only be enables when an eabi based abi
is used.
I'm also going to be making similar changes for array cookies.
Tested on i686-linux and cross to arm-none-elf.
Ok?
Paul
2004-06-24 Paul Brook <paul@codesourcery.com>
gcc/
* target-def.h (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT,
TARGET_CXX): Define.
(TARGET_INITIALIZER): Use TARGET_CXX.
* target.h (struct gcc_target): Add struct cxx.
* targhooks.h (default_cxx_guard_type): Add prototype.
* targhooks.c (default_cxx_guard_type): New function.
* config/arm/arm.c (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT):
Define.
(arm_cxx_guard_type, arm_cxx_guard_mask_bit): New functions.
gcc/cp/
* decl2.c (get_guard): Call targetm.cxx.guard_type.
(get_guard_bits, get_guard_cond): Call targetm.cxx.guard_mask_bit.
libstdc++/
* libsupc++/cxxabi.h: Define __ARM_EABI__
(__guard): Use it.
* libsupc++/guard.h (__cxa_guard_acquire, __cxa_guard_release): Ditto.
Index: gcc/target-def.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/target-def.h,v
retrieving revision 1.80
diff -u -p -r1.80 target-def.h
--- gcc/target-def.h 20 Jun 2004 08:34:44 -0000 1.80
+++ gcc/target-def.h 24 Jun 2004 13:08:15 -0000
@@ -390,6 +390,22 @@ Foundation, 59 Temple Place - Suite 330,
#define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 0
#endif
+
+/* C++ specific. */
+#ifndef TARGET_CXX_GUARD_TYPE
+#define TARGET_CXX_GUARD_TYPE default_cxx_guard_type
+#endif
+
+#ifndef TARGET_CXX_GUARD_MASK_BIT
+#define TARGET_CXX_GUARD_MASK_BIT hook_bool_void_false
+#endif
+
+#define TARGET_CXX \
+ { \
+ TARGET_CXX_GUARD_TYPE, \
+ TARGET_CXX_GUARD_MASK_BIT \
+ }
+
/* The whole shebang. */
#define TARGET_INITIALIZER \
{ \
@@ -435,6 +451,7 @@ Foundation, 59 Temple Place - Suite 330,
TARGET_BUILTIN_SETJMP_FRAME_VALUE, \
TARGET_MD_ASM_CLOBBERS, \
TARGET_CALLS, \
+ TARGET_CXX, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
Index: gcc/target.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/target.h,v
retrieving revision 1.92
diff -u -p -r1.92 target.h
--- gcc/target.h 20 Jun 2004 08:34:44 -0000 1.92
+++ gcc/target.h 24 Jun 2004 14:14:53 -0000
@@ -476,6 +476,14 @@ struct gcc_target
tree *post_p);
} calls;
+ /* Functions specific to the C++ frontend. */
+ struct cxx {
+ /* Return the integer type used for guard variables. */
+ tree (*guard_type) (void);
+ /* Return true if only the low bit of the guard should be tested. */
+ bool (*guard_mask_bit) (void);
+ } cxx;
+
/* Leave the boolean fields at the end. */
/* True if arbitrary sections are supported. */
Index: gcc/targhooks.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/targhooks.c,v
retrieving revision 2.21
diff -u -p -r2.21 targhooks.c
--- gcc/targhooks.c 24 Jun 2004 06:10:35 -0000 2.21
+++ gcc/targhooks.c 24 Jun 2004 14:21:46 -0000
@@ -135,3 +135,11 @@ hook_bool_CUMULATIVE_ARGS_true (CUMULATI
{
return true;
}
+
+
+/* The generic C++ ABI specifies this is a 64-bit value. */
+tree
+default_cxx_guard_type (void)
+{
+ return long_long_integer_type_node;
+}
Index: gcc/targhooks.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/targhooks.h,v
retrieving revision 2.12
diff -u -p -r2.12 targhooks.h
--- gcc/targhooks.h 2 Mar 2004 22:32:26 -0000 2.12
+++ gcc/targhooks.h 24 Jun 2004 11:54:05 -0000
@@ -32,3 +32,4 @@ extern bool hook_bool_CUMULATIVE_ARGS_fa
extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+extern tree default_cxx_guard_type (void);
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.366
diff -u -p -r1.366 arm.c
--- gcc/config/arm/arm.c 24 Jun 2004 11:01:56 -0000 1.366
+++ gcc/config/arm/arm.c 24 Jun 2004 13:21:09 -0000
@@ -162,6 +162,9 @@ static bool arm_promote_prototypes (tree
static bool arm_default_short_enums (void);
static bool arm_align_anon_bitfield (void);
+static tree arm_cxx_guard_type (void);
+static bool arm_cxx_guard_mask_bit (void);
+
/* Initialize the GCC target structure. */
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -264,6 +267,12 @@ static bool arm_align_anon_bitfield (voi
#undef TARGET_ALIGN_ANON_BITFIELD
#define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
+#undef TARGET_CXX_GUARD_TYPE
+#define TARGET_CXX_GUARD_TYPE arm_cxx_guard_type
+
+#undef TARGET_CXX_GUARD_MASK_BIT
+#define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -14506,3 +14515,15 @@ arm_align_anon_bitfield (void)
{
return TARGET_AAPCS_BASED;
}
+
+static tree
+arm_cxx_guard_type (void)
+{
+ return integer_type_node;
+}
+
+static bool
+arm_cxx_guard_mask_bit (void)
+{
+ return TRUE;
+}
Index: gcc/cp/decl2.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/cp/decl2.c,v
retrieving revision 1.719
diff -u -p -r1.719 decl2.c
--- gcc/cp/decl2.c 24 Jun 2004 06:48:43 -0000 1.719
+++ gcc/cp/decl2.c 24 Jun 2004 13:25:38 -0000
@@ -1823,7 +1823,7 @@ get_guard (tree decl)
/* We use a type that is big enough to contain a mutex as well
as an integer counter. */
- guard_type = long_long_integer_type_node;
+ guard_type = targetm.cxx.guard_type ();
guard = build_decl (VAR_DECL, sname, guard_type);
/* The guard should have the same linkage as what it guards. */
@@ -1847,15 +1847,18 @@ get_guard (tree decl)
static tree
get_guard_bits (tree guard)
{
- /* We only set the first byte of the guard, in order to leave room
- for a mutex in the high-order bits. */
- guard = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (guard)),
- guard);
- guard = build1 (NOP_EXPR,
- build_pointer_type (char_type_node),
- guard);
- guard = build1 (INDIRECT_REF, char_type_node, guard);
+ if (!targetm.cxx.guard_mask_bit ())
+ {
+ /* We only set the first byte of the guard, in order to leave room
+ for a mutex in the high-order bits. */
+ guard = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (guard)),
+ guard);
+ guard = build1 (NOP_EXPR,
+ build_pointer_type (char_type_node),
+ guard);
+ guard = build1 (INDIRECT_REF, char_type_node, guard);
+ }
return guard;
}
@@ -1870,6 +1873,16 @@ get_guard_cond (tree guard)
/* Check to see if the GUARD is zero. */
guard = get_guard_bits (guard);
+
+ /* Mask off all but the low bit. */
+ if (targetm.cxx.guard_mask_bit ())
+ {
+ guard_value = integer_one_node;
+ if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
+ guard_value = convert (TREE_TYPE (guard), guard_value);
+ guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value);
+ }
+
guard_value = integer_zero_node;
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
guard_value = convert (TREE_TYPE (guard), guard_value);
Index: libstdc++-v3/libsupc++/cxxabi.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/cxxabi.h,v
retrieving revision 1.16
diff -u -p -r1.16 cxxabi.h
--- libstdc++-v3/libsupc++/cxxabi.h 22 May 2004 21:07:28 -0000 1.16
+++ libstdc++-v3/libsupc++/cxxabi.h 24 Jun 2004 14:32:52 -0000
@@ -44,6 +44,11 @@
#include <stddef.h>
+/* ??? We should probably define this in the compiler. */
+#if defined(__arm__) && !defined(__ARM_EABI__)
+#define __ARM_EABI__
+#endif
+
#ifdef __cplusplus
namespace __cxxabiv1
{
@@ -105,7 +110,11 @@ namespace __cxxabiv1
void (*__dealloc) (void*, size_t));
// The ABI requires a 64-bit type.
+#ifdef __ARM_EABI__
+ typedef int __guard;
+#else
__extension__ typedef int __guard __attribute__((mode (__DI__)));
+#endif
int
__cxa_guard_acquire(__guard*);
Index: libstdc++-v3/libsupc++/guard.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/guard.cc,v
retrieving revision 1.1
diff -u -p -r1.1 guard.cc
--- libstdc++-v3/libsupc++/guard.cc 25 Nov 2002 23:17:31 -0000 1.1
+++ libstdc++-v3/libsupc++/guard.cc 24 Jun 2004 13:13:36 -0000
@@ -35,13 +35,21 @@ namespace __cxxabiv1
extern "C"
int __cxa_guard_acquire (__guard *g)
{
+#ifdef __ARM_EABI__
+ return !(*g & 1);
+#else
return !*(char *)(g);
+#endif
}
extern "C"
void __cxa_guard_release (__guard *g)
{
+#ifdef __ARM_EABI__
+ *g = 1;
+#else
*(char *)g = 1;
+#endif
}
extern "C"
More information about the Libstdc++
mailing list