This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [RFC PATCH, binutils, ARM 4/11, ping] Use getters/setters to access ARM branch type
- From: Nick Clifton <nickc at redhat dot com>
- To: Thomas Preudhomme <thomas dot preudhomme at foss dot arm dot com>, binutils at sourceware dot org
- Date: Tue, 5 Apr 2016 11:05:17 +0100
- Subject: Re: [RFC PATCH, binutils, ARM 4/11, ping] Use getters/setters to access ARM branch type
- Authentication-results: sourceware.org; auth=none
- References: <004c01d13d57$975ae2a0$c610a7e0$ at foss dot arm dot com> <1744390 dot rRxysHBH6A at e108577-lin> <56FBE5A6 dot 5030306 at redhat dot com> <32442566 dot GSo4DN4Amp at e108577-lin>
Hi Thomas,
>>>> -#define ARM_SYM_BRANCH_TYPE(SYM) \
>>>> - ((enum arm_st_branch_type) (SYM)->st_target_internal)
>>>> +#define ARM_GET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL) \
>>>> + ((enum arm_st_branch_type) ((SYM_TARGET_INTERNAL) & 3))
>>>> +#define ARM_SET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL,TYPE) \
>>>> + ((SYM_TARGET_INTERNAL) = ((SYM_TARGET_INTERNAL) & ~3) | ((TYPE) & 3))
>>
>> It occurs to me that an out-of-range value for the TYPE parameter to the
>> ARM_SET_SYM_BRANCH_TYPE macro ought to be flagged as an error, and not
>> silently truncated. You could probably let the compiler's enum checking do
>> this...
>
> Any advice on how to catch any growth in terms of enum size? The point is for
> later commit [1] to start using currently unused bits but we need to make sure
> these new macros are updated if branch type enum increase in size.
>
> [1] https://sourceware.org/ml/binutils/2016-03/msg00379.html
How about this ? It is a bit complicated because I could not find a way to use
the compiler's enum checking to verify the bitfield size, so I had to use assertions
instead. Still I think that it should work, and be relatively simple to extend as
necessary.
Cheers
Nick
enum arm_st_branch_type
{
ST_BRANCH_TO_ARM = 0,
ST_BRANCH_TO_THUMB,
ST_BRANCH_LONG,
ST_BRANCH_UNKNOWN,
ST_BRANCH_ENUM_SIZE
};
#define NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS 3
#define CMSE_BITFIELD (NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS + 1)
#define ENUM_ARM_ST_BRANCH_BITMASK ((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) - 1)
#define ARM_CMSE_SPCL_BITMASK (1 << CMSE_BITFIELD)
#define ARM_SYM_BRANCH_TYPE(SYM) \
ARM_GET_SYM_BRANCH_TYPE ((SYM)->st_target_internal)
#define ARM_GET_SYM_BRANCH_TYPE(STI) \
((enum arm_st_branch_type) (STI & ENUM_ARM_ST_BRANCH_BITMASK))
#ifdef BFD_ASSERT
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE) \
do \
{ \
unsigned typ = (TYPE); \
BFD_ASSERT (typ <= ST_BRANCH_ENUM_SIZE); \
BFD_ASSERT ((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) >= ST_BRANCH_ENUM_SIZE); \
(STI) &= ~ ENUM_ARM_ST_BRANCH_BITMASK; \
(STI) |= typ & ENUM_ARM_ST_BRANCH_BITMASK; \
} \
while (0)
#else
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE) \
do \
{ \
unsigned typ = (TYPE); \
(STI) &= ~ ENUM_ARM_ST_BRANCH_BITMASK; \
(STI) |= typ & ENUM_ARM_ST_BRANCH_BITMASK; \
} \
while (0)
#endif
/* Get or set whether a symbol is a special symbol of an entry function of
CMSE secure code. */
#define ARM_GET_SYM_CMSE_SPCL(STI) \
(((STI) & ARM_CMSE_SPCL_BITMASK) ? 1 : 0)
#define ARM_SET_SYM_CMSE_SPCL(STI) \
do \
{ \
(STI) |= ARM_CMSE_SPCL_BITMASK; \
} \
while (0)