This is the mail archive of the
mailing list for the GCC project.
Re: making sizeof(void*) different from sizeof(void(*)())
Peter Bigot a écrit:
Georg-Johann Lay <email@example.com> wrote:
Peter Bigot a écrit:
The MSP430's split address space and ISA make it expensive to place
data above the 64 kB boundary, but cheap to place code there. So I'm
looking for a way to use HImode for data pointers, but PSImode for
function pointers. If gcc supports this, it's not obvious how.
I get partway there with FUNCTION_MODE and some hacks for the case
where the called object is a symbol, but not when it's a
pointer-to-function data object.
I don't think it's a good solution to use different pointer sizes.
You will run into all sorts of trouble -- both in the application and
Seems to be true in gcc at least. In C, I thought void* and void(*)()
were so fundamentally incompatible that it was perfectly legitimate to
have them be different sizes. (It was memory models on the DEC Alpha
a decode or more ago that I recall as having that feature.)
Most such compilers introduce restrictions to the C language and/or
introduce non-standard extensions like, e.g near, far, huge.
Are there really no gcc back-ends that take advantage of this?
Some define function attributeslike new/far/long_call/longcall,
but they serve different purposes, i.e. treat cases where jump targets
of direct jumps are out of scope or respective machine instruction.
Besides that, named address spaces are for data, not for functions.
And they are supported for C only, not for C++, Objective-C, etc.
In that case, I'll ignore them and move to using variable and function
Attributes are too weak. You can use it to tag a symbol, but it won't
get you big pointers for indirect calls.
It just seemed nice that it was possible to adapt the
pointer mode based on the address space; it'd be nicer if it could be
modified based on the full type, though. TARGET_TYPE_POINTER_MODE
Yes. However, GCC development always focused on the upper end of
supported hardware: 64-bit systems, vectorizing, SIMD, ...
There are just few developers that extend the lower end toward small,
embedded systems and their needs, or add language extentions to
better support that end.
The only candidate solution I've seen (and haven't yet tried) is to
somehow assign all functions to be in a special named address space
and use TARGET_ADDR_SPACE_POINTER_MODE to override the normal use of
ptr_mode in build_pointer_type.
I haven't been able to identify an existing back-end that has such a
case, though I'd swear I've seen memory models like this for some
other processor in the past.
Could somebody suggest a workable solution for 4.7.x?
AVR has similar problems to solve, see
On AVR, the problem only arises for functions outside 128 KiB
because instructions are always 2-byte aligned. Consequently,
function pointers hold word-addresses.
An easy solution would be to align function entry points and
labels of computed and non-local goto to 2^n bytes. That way
16-bit pointers can target addresses in 2^n * 64 KiB.
Other approach is linker stubs as mantioned in the link above.
MSP430 has direct support for calling with a 20-bit pointer, so going
through an indirection step is suboptimal. Also, a memory model
As some point you will have to pay if the hardware exceeds the
implementation. As indirect calls are less common than direct ones,
there is not too much overhead; just one jump.
Aligning will add average cost of 7.5 bytes per aligned label,
provided instructions may start at any byte address.
If instructions are naturally 2-byte aligned, you just pay expected
6 bytes per aligned label.
So you can easily calculate a reasonable overhead of jump pads
against and weight against different label alignments.
supporting 16-bit data pointers and 20-bit code pointers is standard
for commercial compilers for MSP430, so I'm a bit surprised at the
possibility that gcc wouldn't support it. I assumed I just wasn't
finding the right tickle-points.