Last update: December 29th 2014

C99C - C99 Compiler and Optimizers

The C99C compiler for the PC and optimizers are part of the development environment of the TI994W emulator and can be found in the utility (TI994W/UTL/) directory.

Introduction

This page gives a description of the C99 Compiler environment I use on my PC for creating programs for the TI99/4A home computer. The C99 compiler with the C99 optimizers, Xa99 cross assembler and L99 linker forms a simple environment. The optimizers were written to be able to create and shrink programs like DM2K and DU2K so that programs like this can be used on a standard TI99/4A.

C99C - C Compiler

C99C is the PC version of the C99C compiler for the TI99/4A home computer written by Clint Pulley (R2 is from arround 88/04/05).

    Usage: C99 inputfile outputfile [errorfile] [/tp]
    
    Options:
        /t        Keep original C-source line as comment in assembler code
        /p        Generate inline push-code
        
The C99 compiler generates ready to assemble code wich can be linked together with supplied libraries (like CSUP, file-IO etc) or your own created libraries to an running editor/assembler option 5 program for the TI99/4A.



C99O - C Optimizer

The C99O optimizer is the PC version of the optimizer originally supplied by the first version of the C99 compiler. This program started as a version for for the Geneve to run under MDOS and more and more optimizations where added over the years. Everytime I studied the assembler code created I saw something new to optimize.

    *c99 optimizer v4.5/g

    Usage: C99O inputfile outputfile

The original version of C99O only optimized code for simple assignment statements like A=B but this version of C990 optimizes every obvious assembler code that looks like it can be done simpler, like A=B&C, A=B|C, switch(A), if (A==B), etc, etc, etc. Using this optimizer results in a smaller (and faster) program.

Here below you will see some examples how C99C code is optimized by C99O:

    C99C                               C99O
    =========================          =========================
    *key=10;
     MOV 14,8                          LI 8,10
     AI 8,12                           MOV 8,@12(14)
     BL 15
     LI 8,10
     MOV *14+,9
     MOV 8,*9
    
    *switch(key)
     MOV 14,8                          MOV @12(14),8
     AI 8,12                           B @C$6
     MOV *8,8
     B @C$6
    
    *Qftype = Qfparm & M_FTYP;
     MOV @QFPARM,8                     MOV @QFPARM,8
     BL 15                             ANDI 8,15
     LI 8,15                           MOV 8,@QFTYPE
     INV *14
     SZC *14+,8
     MOV 8,@QFTYPE
    
    *Qfparm = Qftype | Qfprot | Qfslct;
     MOV @QFTYPE,8                     MOV @QFTYPE,8
     BL 15                             SOC @QFPROT,8
     MOV @QFPROT,8                     SOC @QFSLCT,8
     SOC *14+,8                        MOV 8,@QFPARM
     BL 15
     MOV @QFSLCT,8
     SOC *14+,8
     MOV 8,@QFPARM
    
    *newname[0] = 0;
     MOV 14,8                          MOV 14,8
     BL 15                             MOV 8,9
     S 8,8                             S 8,8
     A *14+,8                          MOVB *10,*9
     BL 15
     S 8,8
     MOV *14+,9
     MOVB *10,*9

C99X - X File Optimizer

The C99X - X File Optimizer replaces calls to standard C-functions like gets(), puts(), putchar(), locate(), poll() and tscrn() and all string and memory funtions like strcpy(), strlen(), strcat(), strcmp(), memset(), memcpy() for witch the arguments are placed on the C-stack first to the functions XGETS(), XPUTS(), XPUTC(), XLOCAT(), XPOLL(), XTSRCN(), XSCPY(), XSLEN(), XSCAT(), XSCMP(), XMSET(), XMCPY(), XMMOV() if possible but arguments are placed in registers. The code for placing the arguments on the C- stack is removed together with the code (or instruction) to clean-up the C- stack. I found that the first thing these standard C-functions do is reading the values from the C-stack and placing them in registers making the code (IMHO) for placing the arguments on the stack and cleaning the stack unnecessary. Replacing these function calls can only succeed if the arguments are in their most simple form, like FUNCTION(A,B) and not like FUNCTION(A+B,C*D). To use this optimizer an updated CSUP (CSUPTI_V7) must be used. Using this optimizer results in a smaller (and faster) program.

    *c99 x-optimizer v1.4/g

    Usage: C99X inputfile outputfile


Here below you will see some examples how C99C code is optimized by C99X:

    C99C                               C99X
    =========================          =========================
    *locate(ypos,1);
     MOV @YPOS,8                       MOV @YPOS,1
     BL 15                             LI 0,1
     LI 8,1                            BL *12
     BL 15                             DATA XLOCAT
     BL *12
     DATA LOCATE
     AI 14,4

    *locate(y,x);
     MOV @58(14),8                     MOV @58(14),1
     BL 15                             MOV @62-2(14),0
     MOV @62(14),8                     BL *12
     BL 15                             DATA XLOCAT
     BL *12
     DATA LOCATE
     AI 14,4

    *putchar('>');
     LI 8,62                           LI 1,62
     BL 15                             BL *12
     BL *12                            DATA XPUTC
     DATA PUTCHA
     INCT 14

    *strcpy(Srcfil,Src);
     LI 8,SRCFIL                       LI 1,SRCFIL
     BL 15                             LI 2,SRC   
     LI 8,SRC                          BL *12     
     BL 15                             DATA XSCPY 
     BL *12
     DATA STRCPY
     AI 14,4

   *strcat(Srcfil,Pfname);
    LI 8,SRCFIL                        LI 0,SRCFIL  
    BL 15                              MOV @PFNAME,1
    MOV @PFNAME,8                      BL *12       
    BL 15                              DATA XSCAT   
    BL *12
    DATA STRCAT
    AI 14,4

C99F - Function Call Optimizer

The C99F - Function Call Optimizer replaces the code for storing function arguments on the C-stack for code that store the arguments in registers (R0-R8) and a call to a function (FARG#1 through FAARG#8) that will store all these register values on the C-stack. This optimization can only succeed for functions with 1 through 8 arguments and the arguments are in their most simple form, like FUNCTION(A,B) and not like FUNCTION(A+B,C*D). To use this optimizer the library FNCARG must be linked.
The C99F optimizer also optimizes compare instuctions by replacing a branch to a compare subroutine by a TMS9900 compare instruction wherever possible. The C99F optimizer checks if the destination of the jump is within some amount of instructions. Using this optimizer and library results in a smaller (and not necessary faster) program.

    *c99 f-optimizer v1.3/g

    Usage: C99F inputfile outputfile


Here below you will see some examples how C99C code is optimized by C99F:

    C99C                               C99F
    =========================          =========================
    *setkbm(5);
     LI 8,5                            LI 8,5
     BL 15                             BL @FARG#1
     BL *12                            DATA SETKBM
     DATA SETKBM                       INCT 14
     INCT 14

    *getfps(FilesP, pFile);
     MOV @FILESP,8                     MOV @FILESP,7
     BL 15                             MOV @PFILE,8
     MOV @PFILE,8                      BL @FARG#2
     BL 15                             DATA GETFPS
     BL *12                            AI 14,4
     DATA GETFPS
     AI 14,4

    *key = answer("Exit program? ([y],n) ",0);
     MOV 14,8                         MOV 14,6
     AI 8,12                          AI 6,12
     BL 15                            LI 7,C$1
     LI 8,C$1                         S 8,8
     BL 15                            BL @FARG#3
     S 8,8                            DATA ANSWER
     BL 15                            AI 14,4
     BL *12                           MOV *14+,9
     DATA ANSWER                      MOV 8,*9
     AI 14,4
     MOV *14+,9
     MOV 8,*9

    *if (Qftype<=FT_SUB) [Label C$20 within range for sure]
     MOV @QFTYPE,8                    MOV @QFTYPE,8
     BL 15                            CI 8,6
     LI 8,6                           JGT C$20
     BL @C$LE
     JNE $+6
     B @C$20

    *if (Qftype<=FT_SUB) [Label C$8 maybe out of range]
     MOV @QFTYPE,8                    MOV @QFTYPE,8
     BL 15                            CI 8,6
     LI 8,6                           JLT $+8
     BL @C$LE                         JEQ $+6
     JNE $+6                          B @C$8
     B @C$8

C99M - Move Instruction Optimizer

The C99M - Move Instruction Optimizer is capable in optimizing certain MOV instructions in the assembler code as generated by the C99O optimizer. Using this optimizer results in a smaller (and faster) program.

    *c99 m-optimizer v1.1/g

    Usage: C99M inputfile outputfile


Here below you will see some examples how C99C code is optimized by C99O and c99O code code is optimized by C99M:

    C99C                               C99O                               C99M
    =========================          =========================          =========================
    *for (...; ...; i=i+1)
     MOV 14,8                          MOV 14,8                           MOV 14,9
     BL 15                             BL 15                              MOV *9,8
     MOV 14,8                          MOV @2(14),8                       AI 8,1
     INCT 8                            AI 8,1                             MOV 8,*9
     MOV *8,8                          MOV *14+,9
     BL 15                             MOV 8,*9
     LI 8,1
     A *14+,8
     MOV *14+,9
     MOV 8,*9

    *sx = x+p;
     MOV 14,8                          MOV 14,8                           MOV 14,9
     AI 8,10                           AI 8,10                            AI 9,10
     BL 15                             BL 15                              MOV @24(14),8
     MOV 14,8                          MOV @26(14),8                      A @4(14),8
     AI 8,26                           A @8-2(14),8                       MOV 8,*9
     MOV *8,8                          MOV *14+,9
     BL 15                             MOV 8,*9
     MOV 14,8
     AI 8,8
     MOV *8,8
     A *14+,8
     MOV *14+,9
     MOV 8,*9





[EOF]