m16c-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[M16C-dev] Re: Binutils + GCC port


From: Dr. Manuel Kessler
Subject: [M16C-dev] Re: Binutils + GCC port
Date: Thu, 6 Nov 2003 11:11:47 +0100 (CET)

On Wed, 5 Nov 2003, Grant Edwards wrote:

> On Wed, Nov 05, 2003 at 04:25:28PM +0100, Dr. Manuel Kessler wrote:
>
> > - Support some kind of a HUGE model only, a TINY model only, or both of
> >   them, depending on some command line switch (or maybe even at GCC
> >   compile time). This would be either a severe restriction (TINY) or a
> >   waste (HUGE). In the latter case, the problem is not that hard as
> >   described by Grant (little or no instructions), as pointers can be kept
> >   in A0/A1, and some arithmetic is possible in there (e.g. pointer
> >   increment) with the appropriate size.
>
> Right -- pointer arithmetic would require two instructions:
>
>         ; increment a pointer
>
>         ADD.W #1,A0
>         ADC.W #0,A1

Well, that depends on the specific CPU. You are correct for the /60, /62
/20 etc. series, while for the /80 series (M16C/80 and M32C/8x), A0 and A1
are 24 bit each, such that a single instruction is sufficient.
Furthermore, simple indirect addressing with [A0/A1] works for nearly all
instructions.

> The difficulties I see with 24bit pointers are:
>
>    1) Only one register (A0A1) can be used for indirection.
>       That means doing something like:
>
>         while (count--)
>           *dst++; = *src++;
>
>       Would require that the src/dst pointers be held in two
>       other register pairs, and be transferred into A0A1 every
>       time they need to be de-referenced.  It could be made to
>       work, but the code would be sort of ugly.

Right for the /6x etc series. A #pragma could possibly assert operation in
the lower 16 bit space, simplifying the code a lot. Or both variants could
be generated (for simple cases like that), with a run time check as
selection criterion.

>    2) I don't think you can dereference a 24bit pointer with a
>       small constant offset.  This is used when accessing a
>       field given a pointer to a struct, or when accessing a
>       local variable based on a frame pointer or stack pointer.
>       IOW, it happens a lot in most C code.
>
>       IIRC, You would have to load the pointer into A0/A1, add
>       the field offset to it using ADD and ADC instructions,
>       then dereference it. What would be 1 instruction with a
>       near pointer turns into 5 or 6 with a far pointer.

Again, right for the 6x series, but not the 8x ones.

> Using far pointers all the time could certainly be made to
> work, but it would be ugly.
>
> > Anyway, all pointers are the same size in this case.
>
> > - Enhance GCC to support different pointer sizes, and mark all function
> >   pointers (and possibly void * ?) as far (or FAR, LARGE, whatever). The
> >   correspondance between function and data pointers is seldom used anyway
> >   and could be achieved in the necessary cases via an __attribute__,
> >   inline assembly or some similar mechanism. I am not sure how much effort
> >   this means, or if it is mostly there already.
> > - Keep all pointers at 24 bit (i.e. HUGE model), but use only the lower 16
> >   bit for data access in the opcode generation stage. This might be an
> >   interim solution.
>
> > Speaking for myself, I do not like option #1 and am in favor of #3,
> > provided we do not have to completely rewrite GCC.
>
> I looked at the machine description stuff briefly, and it
> didn't appear that you knew what pointer type you were
> generating code for.  The patterns were matched based on the
> data size and wether the quatity was signed or not.  When I was
> looking at the docs for vbcc, it was apparent in the machine
> description interface that the pointer's type was available to
> the back end, and it was possible to define pointer sizes to be
> different.

Yes, but the selection could be very simple: Choose 24 bit for code
accesses (jumps and branches), but 16 bit for data accesses (load, store,
ALU). Therefore the pattern itself is aware of the necessary size.

>
> One suggestion would be to look at the gcc machine description
> for a harvard architecture CPU like the AVR.  It has separate
> address spaces for data and code. Though they're both the same
> size (16 bits), it would give an idea of how to tell what sort
> of pointer is being dereferenced.

That is certainly a useful idea.

>
> > Otherwise I would prefer #4, which sounds as a reasonable
> > compromise.
> >
> > While binutils does not have to be finished to start the port, at least
> > some assembler seems striclty needed. Is there any available besides the
> > one by Mitsubishi/Renesas under Win**ws? If yes, feel free to start. Any
> > takers?
>
> We've ended up choosing the H8 over the M16C for reasons other
> than gcc support (though that's a happy bonus!), so I probably
> won't be spending much more time with the M16C architecture.

Sorry to hear that. However, I acknowledge the need for a working
solution, and waiting for some unknown time is not a viable approach for
most products.

Thanks anyway for your valuable comment.

Ciao,
        Manuel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]