rcbaem@eutrc3.urc.tue.nl (Ernst <pooh> Mulder) (02/28/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