rcbaem@eutrc3.urc.tue.nl (Ernst <pooh> Mulder) (02/22/90)
The department where I'm on at this moment designed a processor,
they called it the EBCP (EB=name-of-the-department, CP=C-processor).
Since there is no C compiler available for this machine, I choose
for this practical work; I'm making a GCC port for this processor.
The first version I worked with was GCC-1.32, and I _almost_
completed the port. There were a couple of problems however.....
1) The EBCP has FIXED-REGISTERS only. It has two frame-pointers, a
program counter, a stack pointer. It has NO general registers.
Since GCC _loves_ general registers this was quite a problem.
The solution found was this: General registers remain on the
stack-frame, pointed to by the Frame Pointer. The EBCP's
addressing modes are: (for all fixed-registers, ie FP)
FP (reg FP)
FP[#] (mem (plus (reg FP) (#)))
[FP[#]] (mem (mem (plus (reg FP) (#))))
Now GCC has general registers. RO = FP[0]
R1 = FP[4] etc.
2) The stack of this processor is growing UPWARDS! (Pushing something
makes the SP point to a higher address) Therefore the function
arguments reside at negative offsets from the Frame Pointer (FP).
What _should_ happen when calling a function, say 'test(int i, int j)'
is: push j (whatever j is, a register or whatever)
push i
call [test]
sub SP, 8 (assuming i and j are 4 bytes wide)
HOWEVER: When STACK_GROWS_DOWNWARDS is defined, GCC pushes a
function's arguments in reversed order. BUT: When a stack is
defined to grow UPWARDS, GCC pushes j first, and i next! Why
is this? What is the difference? When the first argument to a
function is pushed first, how can the function EVER know where
to find the first argument? To fake GCC into pushing arguments
in reversed order (which should always be, I think, whatever
direction the stack grows in) I defined the macro PUSH_ARGS_
REVERSED. This works.
3) After the FUNCTION_PROLOGUE, the first argument for the function
can be found at FP[-12]. A small picture:
SP ------> |__________|
|__ R3 ____| ^Higher Memory
|__ R2 ____|
(Stack Windowed Regs:) |__ R1 ____|
FP ------> |__ R0 ____|
|_ Prev. FP|
|_ ret-addr|
|_ arg 1 __|
|_ arg 2 __|
---------------------------------
caller data: |__ R2 ____|
|__ R1 ____|
|__ R0 ____| Lower Memory
Every function has as much (stacked) registers as are needed.
FP[-4] points to the previous FP, and thus [FP[-4]] points to
register R0 from the caller, and can be used to pass return
arguments (and pointers to structs)
The first argument can be found at FP[-12], the next at
FP[-16] etc... The problem is, I can't get GCC to do this, it
accesses the first argument at FP[-12], but the next at FP[-8]
etc... I can't get GCC to work with negative offsets.
(FP is defined being the ARG_POINTER_REGNUM)
I thought maybe gcc-1.37 would have solved this problem, but I can't
get it compiled properly. I'm compiling on a Apollo. After compiling
gcc I get this error message:
Undefined Globals:
gen_nop First referenced in stmt.o
insn_operand_address_p First referenced in expr.o
reg_alloc_order First referenced in stmt.o
sdb_begin_function_line First referenced in final.o
setrlimit First referenced in toplev.c
I don't know what causes this. I got my copy of gcc-1.37 from an
anonymous FTP site, maybe someone has modified the source? 'gen_nop'
for instance is not defined in any of the .c/.h files, and really only
used in stmt.c...
QUESTIONS:
Could anyone give me hints on how to make GCC understand how to use
a stack which grows UPWARD?
Why (in GCC) does the order in which arguments are pushed depend on
the direction the stack grows? I really don't understand this.
How can I tell GCC that arguments must be found at negative offsets
from the argument pointer, starting at FIRST_PARM_OFFSET minus the
length of the last argument pushed.
Since these are the only problems remaining for the port to be
finished, I would really really appreciate it if anyone could help me...
I prefer mail directly to me, but I will read this newsgroup too.
Many many thanks if you've read my article all the way
up to this point, and many more thanks to anyone willing
to help!
Ernst Mulder