[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[M16C-dev] Re: Binutils + GCC port
Dr. Manuel Kessler
[M16C-dev] Re: Binutils + GCC port
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
> 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
> 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
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
Thanks anyway for your valuable comment.