[gnu.gcc] Problems porting GCC to the EBCP

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