Re: A83: Ti8xcc [82/83/83+/85/86]


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

Re: A83: Ti8xcc [82/83/83+/85/86]




On Thu, 26 Oct 2000, Henk Poley wrote:

It looks like this message will be even longer than yours.

Before I begin to respond, I'd like to point out that none of the Z80
compilers for the calculators come close to hand-written assembly code in
their code generation.  So, it's clearly still best to use assembly
language.

> Well, let me see some examples...

OK.  Since the examples will be fairly long, I'll put them at the end.

> The next thing, I agree that TISCO generates the best code, but:
> 
> 1. TISCO hasn't got any compiler-sources with it, Ti8xcc does have these.
> (TISCO is made back in 1998 so big chance that the sources have been
> deleted in the mean time). I think this is a major disadvantage.

Right.  The lack of source code is a big problem if anyone wants to make
major changes to the compiler.  However, if anyone plans to be making
large efforts to the compiler, I don't think that the TI8XCC source is the
best place to start, because of disadvantages like poor code generation,
lack of structs, and limiting to one level of indirection.

Instead, if a major effort is to be made, the best place to start would be
with GCC.  Since GCC doesn't already support the Z80, this will take more
effort than was needed to make the 68K TI-GCC.  However, GCC has now been
ported to one 8-bit processor (AVR), so all the foundation work for
getting it run on an 8-bit processor has been done; all that's left is to
make Z80 CPU definition tables (basically, just a symbolic list of all the
instructions and what they do) and probably to write some new code
generation strategies.  This is of course a major undertaking (as GCC is a
very complex program) but it will undoubtedly produce a better compiler
than we'd get just be making a few enhancements to the compilers that
already exist.

Besides, it may very well be possible to get the TISCO source code anyway,
as you have mentioned below.

> 2. TISCO is made for the Ti-86 only, Ti8xcc is for the 86 and 83. It has a
> more modular approach in the include files, so it can be easely ported to
> the other calcs. I even think that without altering the source code it is
> impossible to use TISCO for another calc type (it only uses the Ti86xxx.inc
> files), although there is a quick hack for that (incs.tis).

I don't think targetting TISCO to another calculator will really be very
hard at all.  Even if we can't change the compiler source code, it would
not be very hard to write another program which will read in the output of
TISCO, and replace the top of it with stuff appropriate for another
calculator.

> 3. TISCO uses a sort of mixed language, some Small-C, some C, and some
> C++. very confusing sometimes, although it can be usefull. Ti8xcc holds
> straight to the Small-C definitions (I think).

Is that really a good thing?

I don't think it is, because I consider Small-C language very limited.  It
is true that the TISCO language has some problems, but at least it support
things like structures.  The only C++ characteristic (that I've
noticed) is the ability to use // for a comment, which doesn't really
confuse things that much.

> 4. TISCO doesn't have good docs about how to use "inline assembly". How to
> recieve/return variables in embeded asm. Ti8xcc does have these docs. (by
> reading the includes from TISCO you can found it out yourself)

No problem there.

> 5. TISCO is built like an advanced assembler. Most instructions are not
> 'C', but more some other name for a (couple of) assembler instructions.
> Ti8xcc is a 'true' Small-C compiler.

I don't really know exactly what you mean, but I'm fairly sure I don't
agree.

For one thing, I don't see that value of being a 'true' Small-C compiler,
since Small-C is such a limited language as it is.

As far as TISCO instructions just representing a couple of assembler
instructions, it probably seems that way because TISCO simply converts a C
statement into a few instructions, while Small-C makes many instructions
for every statement, even very simple ones!

The following statement is quite valid in TISCO.  If you think this is
not 'C' but just some other name for a (couple of) assembler instructions,
then you should just compare it with Small-C's complexity.

v = var2->next->next->data->d;

Where everything involved is a structure containing the member being
used.  Right here we have dereferenced pointers 4 times in a single
instructions, using data items of three different types.  This is by no
means the work of an advanced assembler.

> 6. Ti8xcc peephole optimizer can be 'changed' (new optimizations can be
> added), the one on TISCO is only accesible via the source code (which we
> don't have)

Right, but it would take *a lot* of work adding optimizations to fix all
the terrible code generation and make it anywhere near TISCO.

> 7. BLA++ and BLA-- can only be used isolated in TISCO... Which means that
> you can't increment a variable in a formula, you have to use another line
> of code to do that.

Which is really a rather minor annoyance, compared to having no structures
and terrible code generation.

> 8. nearly all of TISCO is not finished, Ti8xcc is a bit more like a
> 'comercial' compiler.

Oh yeah, we need to think of ourselves as 'commerical' to get anything
done.  Whether or not it is 'finished' isn't what's important (in my
opinion), but rather the quality of the current version is what matters.

> 9. Ti8xcc is NOT BETA (TISCO has the version number 0.0 hehehe...)

Yes, but do version numbers, presence/absence of 'beta' really mean that
much?  Not really.  Different programmers number things different
ways; some people will always call the first version 1.0, even if it
doesn't work well.  Others spend a long time in the 0.x stage (there are
plenty of high-quality calculator programs out there with 0.x version
numbers).

========== NOW FOR THE EXAMPLES =========

In addition to TISCO and TI8XCC, I'm also throwing in TCC.  This is a
compiler which is TI86-only and doesn't support structures, but otherwise
supports a syntax close to C.

Since none of the compilers do highly complex optimizations, mostly jsut
line-by-line translation, it's not terribly important to use complex
examples (which also would be much too large for any of you to be likely
to read).  Since using global variables is much more efficient than using
local variables on the Z80, I'll use them always.

I'll use the same program for all compilers, excepting minor changes for
the slightly different syntaxes.  Also, headers have been left out to save
space.

I have actually tested larger programs than those shown here, but the
relative quality of the various compilers was about the same, so I won't
waste even more space on this list posting any of them.

==== C code for TI8XCC

char x, y, z;

main ()
{
    x--;
    if (x == y)
        x = z;    
}

==== Assembly output from TI8XCC

main:
;{
;x--;
	ld	a,(x)	;static
	call	_sxt
	dec	hl
	ld	a,l
	ld	(x),a
	inc	hl
;if (x == y)
	ld	a,(x)	;static
	call	_sxt
	push	hl
	ld	a,(y)	;static
	call	_sxt
	pop	de
	call	_eq
	ld	a,h
	or	l
	jp	z,_2
;x = z;
	ld	a,(z)	;static
	call	_sxt
	ld	a,l
	ld	(x),a
;}
_2:
_1:
	ret

==== Commentary on TI8XCC results

I think the length of this code speaks for itself.  If it takes 6 lines of
code, including a function call, to subtract one from a byte in memory,
something is definitely wrong.  Remember that the time taken in the
functions causes this code to be much slower than it would appear if you
just compared length with other routines.

Critical flaws are, of course, that it tries to make everything into a
16-bit value, even though unnecessary, and also calls functions repeatedly
(of course, putting the code inline would waste space, but the actions the
functions perform aren't needed at all).  For the comparison, it actually
calls a function which generates a truth value and then tests if that is
zero (of course, generating truth values is needed in some cases, but
clearly not here!).

This could certainly be improved a lot by adding peephole
optimizations.  But, it wouldn't be easy, because there are many different
patterns of code that need to be improved, and you have to distinguish
between cases this overhead is unneeded (most of the time) and the few
cases where it's needed.

Lastly, I did check to make sure that the final output was the same
whether or not I used the switches to generate a listing, so this is the
same code as when run in normal mode.

==== C code for TISCO

char x, y, z;

void main ()
{
    x--;
    if (x == y) {
        x = z;
    }
}

==== Assembly output of TISCO

_main:

 ;      test.c       5:     x--;
	ld     hl, _x
	dec    (hl)
 ;      test.c       6:     if (x == y) {
	ld     a, (_x)
	ld     b, a
	ld     a, (_y)
	cp     b
	jr     nz, L505856
 ;      test.c       7:         x = z;
	ld     a, (_z)
	ld     hl, _x
	ld     (hl), a

L505856:

L442688:
	ret    

==== Commentary on TISCO results

This is much better; the body of the function only uses half as many
instructions as TI8XCC does, and no function calls or arithmetic on 16-bit
values.  So TISCO code is clearly much smaller and faster than TI8XCC
code.

Of course, this still could be done a little better in assembly, but this
code is at least decent.

==== C code for TCC

unsigned char x, y, z;

int main ()
{
    x--;
    if (x == y) {
        x = z;
    }
}

==== Assembly output of TCC

F1: ;main
; x--
	ld hl,$8002
	push hl
	pop hl
	ld d,0
	ld a,(hl)
	ld e,a
	push de
	dec e
	push hl
	pop hl
	ld a,e
	ld (hl),a
	pop hl
; if (x == y)
	ld hl,$8002
	push hl
	pop hl
	ld a,(hl)
	ld e,a
	ld d,0
	push de
	ld hl,$8003
	push hl
	pop hl
	ld a,(hl)
	ld e,a
	ld d,0
	push de
	pop hl
	ld e,l
	pop hl
	ld a,l
	call eq
	push hl
	pop hl
	ld a,l
	or a
	jr NZ,LB1
	jp LB0
LB1:
; x = z
	ld hl,$8002
	push hl
	ld hl,$8004
	push hl
	pop hl
	ld a,(hl)
	ld e,a
	ld d,0
	push de
	pop hl
	ld e,l
	pop hl
	ld a,e
	ld (hl),a
	push de
	pop hl
LB0:
	ret

==== Commentary on TCC results

OK, this code is obviously the most bloated of all.  However, it may not
really be slower than the TI8XCC code, because it doesn't make all the
time-consuming function calls that TI8XCC does.

It's worth noting that in many other cases (though not this one), TCC will
generate *much worse* code than this if signed variables are used.

I do see one good use of this compiler, however.  If you want to keep your
program's workings secret so that nobody will be able to modify it, then
this compiler is the one for you; anyone who wants to edit your program
will probably run away screaming after seeing such code.




References: