* Backend Stack-/Framepointer
@ 2006-01-15 11:27 Frank Riese
2006-01-15 18:38 ` Ian Lance Taylor
0 siblings, 1 reply; 3+ messages in thread
From: Frank Riese @ 2006-01-15 11:27 UTC (permalink / raw)
To: gcc-help
Hi,
I'm writing a backend for gcc (gcc 4.0.2) for a target machine that neither
has its stack pointer accessible through any register visible to GCC nor does
it have a seperate frame pointer. The only instructions to access the stack I
have on that machine are PUSH and POP.
I have thought about using one of the general purpose registers to substitute
for the stackpointer as the machine has a simple load/store architecture
where I can LOAD and STORE a word at an address specified in a register and
thus do my own POP and PUSH through LOAD and STORE. However, this seemed a
blind alley because the only way to return from a function on that machine is
through a RET instruction that takes the instruction pointer to return to
from that internal stack.
My Problem is that GCC keeps generating code like this (obtained from gcc -dP)
where it tries to access the stack pointer like a hardware register and
expects a frame pointer:
example function:
int foo (short i) {
i = 100;
return i+50;
}
(insn 3 6 4 (set (reg/f:HI 3 R[3] [15])
(reg/f:HI 6 BP)) 22 {movhi} (nil) <-- frame pointer access
(nil))
(insn 9 4 29 (set (mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])
(const_int 100 [0x64])) 5 {*zykluno.md:37} (nil)
(nil))
(insn 29 9 11 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])) 22 {movhi} (nil)
(nil))
(insn 11 29 12 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(plus:HI (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(const_int 50 [0x32]))) 27 {addhi3} (nil)
(nil))
(insn/f 31 30 32 (set (reg/f:HI 7 SP)
(reg/f:HI 6 BP)) 22 {movhi} (nil)
(nil))
(jump_insn 32 31 33 (return) 7 {return} (nil)
(nil))
If compiled with -fomit-frame-pointer:
(insn 29 6 3 (set (reg/f:HI 3 R[3] [15])
(reg/f:HI 7 SP)) 22 {movhi} (nil) <-- stack pointer access
(nil))
(insn 3 29 4 (set (reg/f:HI 3 R[3] [15])
(plus:HI (reg/f:HI 3 R[3] [15])
(const_int 13 [0xd]))) 27 {addhi3} (nil)
(nil))
(insn 9 4 30 (set (mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])
(const_int 100 [0x64])) 5 {*zykluno.md:37} (nil)
(nil))
(insn 30 9 11 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])) 22 {movhi} (nil)
(nil))
(insn 11 30 12 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(plus:HI (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(const_int 50 [0x32]))) 27 {addhi3} (nil)
(nil))
(jump_insn 32 31 33 (return) 7 {return} (nil)
(nil))
I've tried to eliminate the frame pointer wherever possible by defining the
following in <machine.h>:
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
#define CAN_ELIMINATE(FROM, TO) 1
This did not seem to have helped as I still get the unwanted access to the
frame pointer as in the first code above.
Could I be missing instructions in <machine>.md? I have defined the following
instructions but GCC only seems to use PSH:
(define_insn "pushhi1"
[(match_operand:HI 0 "register_operand" "")]
""
"PSH %0"
)
(define_insn "pushsi1"
[(match_operand:SI 0 "general_operand" "")]
""
"PSH %0"
)
(define_insn "pophi1"
[(match_operand:HI 0 "general_operand" "")]
""
"POP %0"
)
(define_insn "popsi1"
[(match_operand:SI 0 "register_operand" "")]
""
"POP %0"
)
I have read most of the documentation about backends under
http://gcc.gnu.org/onlinedocs/gccint/ and had a look at other backend.
However, I haven't been able to come up with any solution yet on how to write
a backend for such a machine.
I would be eternally grateful if someone could provide me with pointers to
resources where I can find out more, to what I've overlooked or has a
solution.
I hope I have posted everything of relevance to my problem. If you need
anything else, please don't hesitate to ask.
Thanks,
Frank
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Backend Stack-/Framepointer
2006-01-15 11:27 Backend Stack-/Framepointer Frank Riese
@ 2006-01-15 18:38 ` Ian Lance Taylor
0 siblings, 0 replies; 3+ messages in thread
From: Ian Lance Taylor @ 2006-01-15 18:38 UTC (permalink / raw)
To: Frank Riese; +Cc: gcc-help
Frank Riese <hippo@informatik.uni-bremen.de> writes:
This question is more appropriate for gcc@gcc.gnu.org than for
gcc-help.
> I'm writing a backend for gcc (gcc 4.0.2) for a target machine that neither
> has its stack pointer accessible through any register visible to GCC nor does
> it have a seperate frame pointer. The only instructions to access the stack I
> have on that machine are PUSH and POP.
gcc needs general access to some sort of stack frame. It can't work
on a machine which doesn't provide that.
> I have thought about using one of the general purpose registers to substitute
> for the stackpointer as the machine has a simple load/store architecture
> where I can LOAD and STORE a word at an address specified in a register and
> thus do my own POP and PUSH through LOAD and STORE. However, this seemed a
> blind alley because the only way to return from a function on that machine is
> through a RET instruction that takes the instruction pointer to return to
> from that internal stack.
Using a different register as the stack pointer is the way to go.
Don't get tied up with the fact that RET doesn't use that stack. Just
use two stacks: one for the call sequence, and one for stack frame
used for local variables.
The main drawback is that it will be rather difficult to implement
setjmp/longjmp, and unwinding the stack for exceptions. Those are
going to be very difficult to implement on your processor now matter
how you do it, since they require the ability to set the stack pointer
to an arbitrary position higher on the call stack.
Ian
^ permalink raw reply [flat|nested] 3+ messages in thread
* Backend Stack-/Framepointer
@ 2006-01-15 11:23 Frank Riese
0 siblings, 0 replies; 3+ messages in thread
From: Frank Riese @ 2006-01-15 11:23 UTC (permalink / raw)
To: gcc-help
[-- Attachment #1: Type: text/plain, Size: 4190 bytes --]
Hi,
I'm writing a backend for gcc (gcc 4.0.2) for a target machine that neither
has its stack pointer accessible through any register visible to GCC nor does
it have a seperate frame pointer. The only instructions to access the stack I
have on that machine are PUSH and POP.
I have thought about using one of the general purpose registers to substitute
for the stackpointer as the machine has a simple load/store architecture
where I can LOAD and STORE a word at an address specified in a register and
thus do my own POP and PUSH through LOAD and STORE. However, this seemed a
blind alley because the only way to return from a function on that machine is
through a RET instruction that takes the instruction pointer to return to
from that internal stack.
My Problem is that GCC keeps generating code like this (obtained from gcc -dP)
where it tries to access the stack pointer like a hardware register and
expects a frame pointer:
example function:
int foo (short i) {
i = 100;
return i+50;
}
(insn 3 6 4 (set (reg/f:HI 3 R[3] [15])
(reg/f:HI 6 BP)) 22 {movhi} (nil) <-- frame pointer access
(nil))
(insn 9 4 29 (set (mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])
(const_int 100 [0x64])) 5 {*zykluno.md:37} (nil)
(nil))
(insn 29 9 11 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])) 22 {movhi} (nil)
(nil))
(insn 11 29 12 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(plus:HI (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(const_int 50 [0x32]))) 27 {addhi3} (nil)
(nil))
(insn/f 31 30 32 (set (reg/f:HI 7 SP)
(reg/f:HI 6 BP)) 22 {movhi} (nil)
(nil))
(jump_insn 32 31 33 (return) 7 {return} (nil)
(nil))
If compiled with -fomit-frame-pointer:
(insn 29 6 3 (set (reg/f:HI 3 R[3] [15])
(reg/f:HI 7 SP)) 22 {movhi} (nil) <-- stack pointer access
(nil))
(insn 3 29 4 (set (reg/f:HI 3 R[3] [15])
(plus:HI (reg/f:HI 3 R[3] [15])
(const_int 13 [0xd]))) 27 {addhi3} (nil)
(nil))
(insn 9 4 30 (set (mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])
(const_int 100 [0x64])) 5 {*zykluno.md:37} (nil)
(nil))
(insn 30 9 11 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(mem/i:HI (reg/f:HI 3 R[3] [15]) [0 i+0 S2 A16])) 22 {movhi} (nil)
(nil))
(insn 11 30 12 (set (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(plus:HI (reg:HI 3 R[3] [orig:13 D.1079 ] [13])
(const_int 50 [0x32]))) 27 {addhi3} (nil)
(nil))
(jump_insn 32 31 33 (return) 7 {return} (nil)
(nil))
I've tried to eliminate the frame pointer wherever possible by defining the
following in <machine.h>:
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
#define CAN_ELIMINATE(FROM, TO) 1
This did not seem to have helped as I still get the unwanted access to the
frame pointer as in the first code above.
Could I be missing instructions in <machine>.md? I have defined the following
instructions but GCC only seems to use PSH:
(define_insn "pushhi1"
[(match_operand:HI 0 "register_operand" "")]
""
"PSH %0"
)
(define_insn "pushsi1"
[(match_operand:SI 0 "general_operand" "")]
""
"PSH %0"
)
(define_insn "pophi1"
[(match_operand:HI 0 "general_operand" "")]
""
"POP %0"
)
(define_insn "popsi1"
[(match_operand:SI 0 "register_operand" "")]
""
"POP %0"
)
I have read most of the documentation about backends under
http://gcc.gnu.org/onlinedocs/gccint/ and had a look at other backend.
However, I haven't been able to come up with any solution yet on how to write
a backend for such a machine.
I would be eternally grateful if someone could provide me with pointers to
resources where I can find out more, to what I've overlooked or has a
solution.
I hope I have posted everything of relevance to my problem. If you need
anything else, please don't hesitate to ask.
Thanks,
Frank
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-01-15 18:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-15 11:27 Backend Stack-/Framepointer Frank Riese
2006-01-15 18:38 ` Ian Lance Taylor
-- strict thread matches above, loose matches on Subject: below --
2006-01-15 11:23 Frank Riese
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).