├── .gitignore ├── Makefile ├── alias.c ├── av.c ├── bug.c ├── cp.c ├── cse.c ├── datatypes ├── datatypes.h ├── dtconv.h ├── dtgen.c ├── dtswap32f.c ├── dtswap32t.c ├── dtswap64f.c └── dtswap64t.c ├── declaration.c ├── doc ├── errors.texi ├── interface.texi ├── ucpp.texi ├── vbcc.texi ├── vbcc_main.texi ├── vbccalpha.texi ├── vbccc16x.texi ├── vbcchc12.texi ├── vbcci386.texi ├── vbccm68k.texi ├── vbccppc.texi ├── vbccvidcore.texi ├── vc.texi ├── vclib.texi ├── vprof.texi └── vsc.texi ├── dwarf2.c ├── errors.h ├── flow.c ├── frontend └── vc.c ├── ic.c ├── icn.c ├── loop.c ├── machines ├── alpha │ ├── machine.c │ ├── machine.dt │ ├── machine.h │ ├── schedule.c │ └── schedule.h ├── bi386 │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── c16x │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── generic │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── hc12 │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── i386 │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── m68k │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── m68ks │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── ppc │ ├── machine.c │ ├── machine.dt │ ├── machine.h │ ├── schedule.c │ └── schedule.h ├── qnice │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── vidcore │ ├── machine.c │ ├── machine.dt │ └── machine.h └── z │ ├── machine.c │ ├── machine.dt │ └── machine.h ├── main.c ├── mbasic.c ├── minicomp.c ├── minicomp.h ├── minicomp.tab.c ├── minicompg.tab.c ├── minicomplexer.c ├── misra_errors.h ├── opt.c ├── opt.h ├── osek_supp.h ├── osekrm.c ├── parse_expr.c ├── pp.c ├── pptst.h ├── preproc.c ├── rd.c ├── regs.c ├── statements.c ├── supp.c ├── supp.h ├── t1.h ├── t2.h ├── tasm.c ├── tt.h ├── type_expr.c ├── ucpp ├── README ├── assert.c ├── cpp.c ├── cpp.h ├── eval.c ├── hash.c ├── hash.h ├── lexer.c ├── macro.c ├── mem.c ├── mem.h ├── sample.c ├── tune.h └── ucppi.h ├── vars.c ├── vbc.h ├── vbcc_cpp.h ├── vbpp.h ├── vprof └── vprof.c └── vsc ├── vsc.c └── vsc.h /.gitignore: -------------------------------------------------------------------------------- 1 | machines/*/dt.[ch] 2 | bin/* 3 | *.o 4 | doc/*.html 5 | doc/vbcc.aux 6 | doc/vbcc.cp 7 | doc/vbcc.fn 8 | doc/vbcc.ky 9 | doc/vbcc.log 10 | doc/vbcc.pdf 11 | doc/vbcc.pg 12 | doc/vbcc.toc 13 | doc/vbcc.tp 14 | doc/vbcc.vr 15 | -------------------------------------------------------------------------------- /bug.c: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (loop.c) V0.8 */ 2 | /* schleifenorientierte Optimierungen */ 3 | 4 | #include "opt.h" 5 | 6 | static char FILE_[]=__FILE__; 7 | 8 | #define MOVE_IC 1 9 | #define MOVE_COMP 2 10 | 11 | /* Liste, in die ICs eingetragen werden, die aus Schleifen */ 12 | /* gezogen werden sollen. */ 13 | struct movlist{ 14 | struct movlist *next; 15 | struct IC *IC; 16 | struct flowgraph *target_fg; 17 | int flags; 18 | }; 19 | 20 | struct movlist *first_mov,*last_mov; 21 | 22 | int report_weird_code,report_suspicious_loops; 23 | 24 | /* Bitvektoren fuer schleifeninvariante ICs */ 25 | bvtype *invariant,*inloop,*moved,*moved_completely; 26 | bvtype *fg_tmp; 27 | bvtype *not_movable; 28 | size_t bsize; 29 | 30 | 31 | /* Liste, in die ICs fuer strength-reduction eingetragen */ 32 | /* werden. */ 33 | struct srlist{ 34 | struct srlist *next; 35 | struct IC *ind_var; 36 | struct IC *IC; 37 | struct flowgraph *target_fg; 38 | /* Hilfsvariable, falls eine aequivalente Operation schon reduziert */ 39 | /* wurde. */ 40 | struct Var *hv; 41 | }; 42 | 43 | struct srlist *first_sr,*last_sr; 44 | 45 | /* Liste, in die Daten fuer loop-unrolling eingetragen werden. */ 46 | struct urlist{ 47 | int flags; 48 | long total,unroll; 49 | struct IC *cmp,*branch,*ind; 50 | struct flowgraph *start,*head; 51 | struct urlist *next; 52 | } *first_ur; 53 | 54 | #define UNROLL_COMPLETELY 1 55 | #define UNROLL_MODULO 2 56 | #define UNROLL_INVARIANT 4 57 | #define UNROLL_REVERSE 8 58 | #define IND_ONLY_COUNTS 16 59 | #define MULTIPLE_EXITS 32 60 | 61 | /* Hier werden Induktionsvariablen vermerkt */ 62 | struct IC **ind_vars; 63 | 64 | static struct flowgraph *first_fg; 65 | 66 | 67 | void calc_movable(struct flowgraph *start,struct flowgraph *end) 68 | /* Berechnet, welche Definitionen nicht aus der Schleife start-end */ 69 | /* verschoben werden duerfen. Eine Def. p von z darf nur verschoben */ 70 | /* werden, wenn keine andere Def. von p existiert und alle */ 71 | /* Verwendungen von z nur von p erreicht werden. */ 72 | /* Benutzt rd_defs. */ 73 | { 74 | struct flowgraph *g;struct IC *p; 75 | int i,j,k,d; 76 | bvtype *changed_vars; 77 | if(DEBUG&1024) printf("calculating not_movable for blocks %d to %d\n",start->index,end->index); 78 | if(0/*!(optflags&1024)*/){ 79 | memset(not_movable,UCHAR_MAX,dsize); 80 | return; 81 | } 82 | memset(not_movable,0,dsize); 83 | changed_vars=mymalloc(vsize); 84 | memset(changed_vars,0,vsize); 85 | for(i=0;ivtyp->flags&VOLATILE) BSET(changed_vars,i); 87 | if(ivtyp->next||(vilist[i]->vtyp->next->flags&VOLATILE)) BSET(changed_vars,i+vcount-rcount); 89 | } 90 | } 91 | for(g=start;g;g=g->normalout){ 92 | if(!g->rd_in) ierror(0); 93 | memcpy(rd_defs,g->rd_in,dsize); 94 | for(p=g->start;p;p=p->next){ 95 | for(j=0;jchange_cnt;j++){ 96 | i=p->change_list[j].v->index; 97 | if(p->change_list[j].flags&DREFOBJ) i+=vcount-rcount; 98 | if(i>=vcount) continue; 99 | if(BTST(changed_vars,i)||(q1typ(p)&VOLATILE)||(q2typ(p)&VOLATILE)||(ztyp(p)&VOLATILE)){ 100 | bvunite(not_movable,var_defs[i],dsize); 101 | }else{ 102 | BSET(changed_vars,i); 103 | } 104 | } 105 | for(k=0;kuse_cnt;k++){ 106 | i=p->use_list[k].v->index; 107 | if(p->use_list[k].flags&DREFOBJ) i+=vcount-rcount; 108 | if(i>=vcount) continue; 109 | for(d=-1,j=1;j<=dcount;j++){ 110 | if(BTST(rd_defs,j)&&BTST(var_defs[i],j)){ 111 | if(d>=0){ /* mehr als eine Def. */ 112 | bvunite(not_movable,var_defs[i],dsize); 113 | d=-1;break; 114 | }else d=j; 115 | } 116 | if(BTST(rd_defs,UNDEF(j))&&BTST(var_defs[i],UNDEF(j))){ 117 | bvunite(not_movable,var_defs[i],dsize); 118 | d=-1;break; 119 | } 120 | } 121 | } 122 | /* Das hier, um rd_defs zu aktualisieren. */ 123 | rd_change(p); 124 | if(p==g->end) break; 125 | } 126 | if(g==end) break; 127 | } 128 | free(changed_vars); 129 | } 130 | 131 | -------------------------------------------------------------------------------- /datatypes/datatypes.h: -------------------------------------------------------------------------------- 1 | /* elementary data types currently known to vbcc */ 2 | 3 | /* unsigned 8bit byte */ 4 | "S8BU", "standard unsigned 8bit byte", 5 | 6 | /* signed 8bit byte */ 7 | "S8BS", "standard 2-complement 8bit byte", 8 | 9 | /* typical unsigned integers, big-endian */ 10 | "S16BUBE", "standard 8bit-byte-based unsigned 16bit word, big-endian", 11 | "S32BUBE", "standard 8bit-byte-based unsigned 32bit word, big-endian", 12 | "S64BUBE", "standard 8bit-byte-based unsigned 64bit byte, big-endian", 13 | 14 | /* typical unsigned integers, little-endian */ 15 | "S16BULE", "standard 8bit-byte-based unsigned 16bit word, little-endian", 16 | "S32BULE", "standard 8bit-byte-based unsigned 32bit word, little-endian", 17 | "S64BULE", "standard 8bit-byte-based unsigned 64bit byte, little-endian", 18 | 19 | /* typical signed integers, big-endian */ 20 | "S16BSBE", "standard 8bit-byte-based 2-complement 16bit word, big-endian", 21 | "S32BSBE", "standard 8bit-byte-based 2-complement 32bit word, big-endian", 22 | "S64BSBE", "standard 8bit-byte-based 2-complement 64bit word, big-endian", 23 | 24 | /* typical signed integers, little-endian */ 25 | "S16BSLE", "standard 8bit-byte-based 2-complement 16bit word, little-endian", 26 | "S32BSLE", "standard 8bit-byte-based 2-complement 32bit word, little-endian", 27 | "S64BSLE", "standard 8bit-byte-based 2-complement 64bit word, little-endian", 28 | 29 | /* typical IEEE-floats, big-endian */ 30 | "S32BIEEEBE", "standard 8bit-byte-based 32bit IEEE floating-point, big-endian", 31 | "S64BIEEEBE", "standard 8bit-byte-based 64bit IEEE floating-point, big-endian", 32 | 33 | /* typical IEEE-floats, little-endian */ 34 | "S32BIEEELE", "standard 8bit-byte-based 32bit IEEE floating-point, little-endian", 35 | "S64BIEEELE", "standard 8bit-byte-based 64bit IEEE floating-point, little-endian", 36 | 37 | -------------------------------------------------------------------------------- /datatypes/dtconv.h: -------------------------------------------------------------------------------- 1 | "S16BSBE","S16BSLE","dtswap16f.c","dtswap16t.c",2, 2 | "S16BUBE","S16BULE","dtswap16f.c","dtswap16t.c",2, 3 | "S32BSBE","S32BSLE","dtswap32f.c","dtswap32t.c",4, 4 | "S32BUBE","S32BULE","dtswap32f.c","dtswap32t.c",4, 5 | "S64BSBE","S64BSLE","dtswap64f.c","dtswap64t.c",8, 6 | "S64BUBE","S64BULE","dtswap64f.c","dtswap64t.c",8, 7 | "S32BIEEEBE","S32BIEEELE","dtswap32f.c","dtswap32t.c",4, 8 | "S64BIEEEBE","S64BIEEELE","dtswap64f.c","dtswap64t.c",8, 9 | "S16BSLE","S16BSBE","dtswap16f.c","dtswap16t.c",2, 10 | "S16BULE","S16BUBE","dtswap16f.c","dtswap16t.c",2, 11 | "S32BSLE","S32BSBE","dtswap32f.c","dtswap32t.c",4, 12 | "S32BULE","S32BUBE","dtswap32f.c","dtswap32t.c",4, 13 | "S64BSLE","S64BSBE","dtswap64f.c","dtswap64t.c",8, 14 | "S64BULE","S64BUBE","dtswap64f.c","dtswap64t.c",8, 15 | "S32BIEEELE","S32BIEEEBE","dtswap32f.c","dtswap32t.c",4, 16 | "S64BIEEELE","S64BIEEEBE","dtswap64f.c","dtswap64t.c",8, 17 | 18 | -------------------------------------------------------------------------------- /datatypes/dtswap32f.c: -------------------------------------------------------------------------------- 1 | from) 2 | { 3 | DTTTYPE to; 4 | unsigned char *fp=((unsigned char *)&from)+3,*tp=(unsigned char *)&to; 5 | *tp++=*fp--; 6 | *tp++=*fp--; 7 | *tp++=*fp--; 8 | *tp++=*fp--; 9 | return to; 10 | } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /datatypes/dtswap32t.c: -------------------------------------------------------------------------------- 1 | from) 2 | { 3 | DTFTYPE to; 4 | unsigned char *fp=((unsigned char *)&from)+3,*tp=(unsigned char *)&to; 5 | *tp++=*fp--; 6 | *tp++=*fp--; 7 | *tp++=*fp--; 8 | *tp++=*fp--; 9 | return to; 10 | } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /datatypes/dtswap64f.c: -------------------------------------------------------------------------------- 1 | from) 2 | { 3 | DTTTYPE to; 4 | unsigned char *fp=((unsigned char *)&from)+7,*tp=(unsigned char *)&to; 5 | *tp++=*fp--; 6 | *tp++=*fp--; 7 | *tp++=*fp--; 8 | *tp++=*fp--; 9 | *tp++=*fp--; 10 | *tp++=*fp--; 11 | *tp++=*fp--; 12 | *tp++=*fp--; 13 | return to; 14 | } 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /datatypes/dtswap64t.c: -------------------------------------------------------------------------------- 1 | from) 2 | { 3 | DTFTYPE to; 4 | unsigned char *fp=((unsigned char *)&from)+7,*tp=(unsigned char *)&to; 5 | *tp++=*fp--; 6 | *tp++=*fp--; 7 | *tp++=*fp--; 8 | *tp++=*fp--; 9 | *tp++=*fp--; 10 | *tp++=*fp--; 11 | *tp++=*fp--; 12 | *tp++=*fp--; 13 | return to; 14 | } 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/ucpp.texi: -------------------------------------------------------------------------------- 1 | vbcc contains the C preprocessor ucpp by Thomas Pornin. 2 | 3 | Attached is the copyright notice from the ucpp-distribution (note that 4 | apart from ucpp no other part of this distribution falls under this 5 | license). 6 | 7 | 8 | Volker Barthelmann vb@compilers.de 9 | 10 | 11 | -------------- 12 | 13 | /* 14 | * (c) Thomas Pornin 1999, 2000 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions 18 | * are met: 19 | * 1. Redistributions of source code must retain the above copyright 20 | * notice, this list of conditions and the following disclaimer. 21 | * 2. Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the distribution. 24 | * 4. The name of the authors may not be used to endorse or promote 25 | * products derived from this software without specific prior written 26 | * permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 29 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 34 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 35 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 37 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 38 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | * 40 | */ 41 | -------------------------------------------------------------------------------- /doc/vbccalpha.texi: -------------------------------------------------------------------------------- 1 | This chapter documents the Backend for the DEC Alpha processor family. 2 | 3 | @section Additional options for this version 4 | 5 | This backend provides the following additional options: 6 | 7 | @table @option 8 | 9 | 10 | @item -merge-constants 11 | Place identical floating point constants at the same 12 | memory location. This can reduce program size and increase 13 | compilation time. 14 | 15 | @item -const-in-data 16 | By default constant data will be placed in the code 17 | section (and therefore is accessable with faster pc-relative 18 | addressing modes). Using this option it will be placed in the 19 | data section. 20 | Note that on operating systems with memory protection this 21 | option will disable write-protection of constant data. 22 | 23 | @item -no-builtins 24 | Do not replace certain builtin functions by inline code. 25 | This may be useful if you use this code generator with 26 | another frontend than vbcc. 27 | stdarg.h will not work with -no-builtins. 28 | 29 | @item -stabs 30 | Generate stabs debug infos (if -g is specified) rather than 31 | DWARF2 which is the default. Consider this obsolete. 32 | 33 | @end table 34 | 35 | @section ABI 36 | 37 | 38 | This backend supports the following registers: 39 | 40 | @itemize @minus 41 | @item @code{$0} through @code{$31} for the general purpose registers and 42 | @item @code{$f0} through @code{$f31} for the floating point registers. 43 | @end itemize 44 | 45 | The current version generates assembly output for use with the GNU 46 | assembler. The generated code should work on systems with 21064, 47 | 21066, 21164 and higher Alpha CPUs. 48 | 49 | The registers @code{$0-$8, $16-$28, $f0, $f1} and @code{$f10-$f30} 50 | are used as scratch registers (i.e. they can be destroyed in function 51 | calls), all other registers are preserved. Of course @code{$31} and 52 | @code{$f31} cannot be used. 53 | 54 | The first 6 function arguments which have arithmetic or pointer types 55 | are passed in registers @code{$16/$f16} through @code{$21/$f21}. 56 | 57 | Integers and pointers are returned in @code{$0}, floats and doubles in 58 | @code{$f0}. 59 | All other types are returned by passing the function the address 60 | of the result as a hidden argument - so when you call such a function 61 | without a proper declaration in scope you can expect a crash. 62 | 63 | The elementary data types are represented like: 64 | 65 | @example 66 | type size in bits alignment in bytes 67 | 68 | char 8 1 69 | short 16 2 70 | int 32 4 71 | long 64 8 72 | long long 64 8 73 | all pointers 64 8 74 | float 32 4 75 | double 64 8 76 | @end example 77 | 78 | @section Predefined Macros 79 | 80 | This backend defines the following macros: 81 | 82 | @table @code 83 | @item __ALPHA__ 84 | 85 | @end table 86 | 87 | 88 | @section Stdarg 89 | 90 | A possible could look like this: 91 | 92 | @example 93 | 94 | typedef struct @{ 95 | char *regbase; 96 | char *membase; 97 | int arg; 98 | @} va_list; 99 | 100 | char *__va_start(void); 101 | int __va_fixargs(void); 102 | 103 | #define va_start(vl,dummy) \ 104 | (vl.arg=__va_fixargs(),vl.regbase=__va_start(),vl.membase=vl.regbase+(6-vl.arg)*16) 105 | 106 | #define va_end(vl) (vl.regbase=vl.membase=0) 107 | 108 | #define __va_size(type) ((sizeof(type)+7)/8*8) 109 | #define va_arg(vl,type) \ 110 | ( \ 111 | ((__typeof(type)&15)<=10&&++vl.arg<=6) ? \ 112 | ( \ 113 | ((__typeof(type)&15)>=6&&(__typeof(type)&15)<=8) ? \ 114 | (vl.regbase+=16,*(type *)(vl.regbase-8)) \ 115 | : \ 116 | (vl.regbase+=16,*(type *)(vl.regbase-16)) \ 117 | ) \ 118 | : \ 119 | (vl.membase+=__va_size(type),*(type *)(vl.membase-__va_size(type))) \ 120 | ) 121 | 122 | @end example 123 | 124 | 125 | @section Known problems 126 | 127 | @itemize @minus 128 | @item generated code is rather poor 129 | @item several other problems 130 | @end itemize 131 | 132 | 133 | -------------------------------------------------------------------------------- /doc/vbccc16x.texi: -------------------------------------------------------------------------------- 1 | This chapter documents the Backend for the c16x/st10 microcontroller family. 2 | 3 | @section Additional options for this version 4 | 5 | This backend provides the following additional options: 6 | 7 | @table @option 8 | 9 | @item -merge-constants 10 | Place identical floating point constants at the same 11 | memory location. This can reduce program size and increase 12 | compilation time. 13 | 14 | @item -const-in-data 15 | By default constant data will be placed in a read-only 16 | section. Using this option it will be placed in the 17 | data section. 18 | 19 | @item -no-delayed-popping 20 | By default arguments of function calls are not always popped 21 | from the stack immediately after the call, so that the 22 | arguments of several calls may be popped at once. 23 | With this option vbcc can be forced to pop them after every 24 | function call. 25 | This may simplify debugging and very slightly reduce the 26 | stack size needed by the compiled program. 27 | 28 | @item -no-peephole 29 | Do not perform peephole-optimizations. 30 | 31 | @item -tasking 32 | Produce output for the Tasking assembler. 33 | 34 | @item -mtiny 35 | Assume all functions are within one code-segment. 36 | Shorter instructions for calling functions are used and 37 | function-pointers will be only 2 bytes long. 38 | This results in shorter and faster code. 39 | 40 | @item -mlarge 41 | All objects which are not explicitly qualified are assumed 42 | to be far (i.e. they may be in different segments but must 43 | not cross one segment-boundary). The default pointer size 44 | will be 4. 45 | 46 | @item -mhuge 47 | All objects which are not explicitly qualified are assumed 48 | to be huge (i.e. they may be in different segments and may 49 | cross segment-boundaries). The default pointer size will 50 | be 4. 51 | 52 | @item -int32 53 | Do not use. 54 | @end table 55 | 56 | @section ABI 57 | 58 | This backend supports the following registers: 59 | 60 | @itemize @minus 61 | @item @code{R0} through @code{R15} for the general purpose registers 62 | @end itemize 63 | 64 | Additionally, the register pairs 65 | @code{R2/R3, R3/R4, R4/R5, R6/R7, R7/R8, R8/R9, R12/R13, R13/R14,} 66 | and @code{R15/R15} 67 | are available. 68 | 69 | @code{R1, R11} and @code{R12} are reserved by the backend. 70 | 71 | The current version generates assembly output for use with the vasm 72 | assembler. Optionally, assembly code for the Tasking 73 | assembler can be generated. 74 | The default memory model corresponds to the Tasking small-memory 75 | model with 16bit data-pointers and 32bit function-pointers. 76 | However, the @code{DPPx} registers have to be set up in a way to 77 | create a linear 16bit address space (i.e. @code{DPPx=x}). 78 | The generated code should work on systems with c161, c163, c164, c165 79 | and c167 microcontrollers as well as ST10 derivates. Old versions like 80 | the c166 are not supported 81 | 82 | The registers @code{R1-R5} and @code{R10-R15} are used as scratch registers (i.e. they 83 | can be destroyed in function calls), all other registers are preserved. 84 | 85 | @code{R0} is used as user stack pointer. Automatic variables and temporaries 86 | are put on the user stack. Return addresses are pushed on the system 87 | stack. 88 | 89 | The first 4 function arguments which have integer or pointer types 90 | are passed in registers @code{R12} through @code{R15}. 91 | 92 | Integers and pointers are returned in @code{R4/R5}. 93 | All other types are returned by passing the function the address 94 | of the result as a hidden argument - so when you call such a function 95 | without a proper declaration in scope you can expect a crash. 96 | 97 | The elementary data types are represented like: 98 | 99 | @example 100 | type size in bits alignment in bytes 101 | 102 | char 8 1 103 | short 16 2 104 | int 16 2 105 | long 32 2 106 | long long n/a n/a 107 | near pointers 16 2 108 | far pointers 32 2 109 | huge pointers 32 2 110 | float n/a n/a 111 | double n/a n/a 112 | @end example 113 | 114 | 115 | @section Target-specific variable-attributes 116 | 117 | The c16x-backend offers the following variable attributes: 118 | 119 | @table @code 120 | 121 | @item __interrupt 122 | Return with rfi rather than blr. 123 | @code{MDL/MDH} will be saved, however it is recommended 124 | to switch to a new register bank as the gprs are 125 | not saved. 126 | Also, @code{DPP0-DPP3} are not saved (the compiler does not 127 | use them). 128 | 129 | @item __interrupt() 130 | Like @code{__interrupt}, but also places a jump-instruction 131 | to the interrupt service at the corresponding vector table 132 | address (needs support from library and linker file). 133 | 134 | @item __section() 135 | Place this object/function in section . 136 | 137 | @item __rbank() 138 | Switch to another register-bank for this function. 139 | @end table 140 | 141 | 142 | @section Target-specific type-attributes 143 | 144 | The c16x-backend offers the following type attributes: 145 | 146 | @table @code 147 | @item __near 148 | Object resides within the same segment. 149 | 150 | @item __far 151 | Object may reside in a different segment, but does not cross 152 | a segment-boundary. 153 | 154 | @item __huge 155 | Object may reside in a different segment and may cross a 156 | segment-boundary 157 | 158 | @item __section() 159 | Place this function or object in section . 160 | 161 | @item __sfr() 162 | Used to declare a special function register at . 163 | 164 | Example: 165 | @example 166 | __sfr(0xff10) volatile unsigned int PSW; 167 | @end example 168 | 169 | @item __esfr() 170 | The same for extended special function registers. 171 | 172 | @item __sfrbit(,) 173 | Declare a single bit in the bit-addressable area. 174 | 175 | Example: 176 | @example 177 | __sfr(0xff10,11) volatile __bit IEN; 178 | @end example 179 | 180 | @item __esfrbit(,) 181 | The same for the extended bit-addressable area. 182 | 183 | @end table 184 | 185 | @section Target-specific types 186 | 187 | The c16x-backend offers the following additional types: 188 | 189 | @table @code 190 | @item __bit 191 | A single bit in the bit-addressable inernal RAM-area. 192 | Only static and external variables may use this type. 193 | It is not allowed for auto or register storage-class. 194 | Also, arrays of bits, pointers to bits or bits within 195 | aggregates are not allowed. 196 | Conversion of a bit to an integral type yields 0 if the 197 | bit is cleared and 1 if it is set.. 198 | Conversion of an integral type to a bit clears the bit if 199 | the integer is equal to 0 and sets it otherwise. 200 | @end table 201 | 202 | @section Predefined Macros 203 | 204 | This backend defines the following macros: 205 | 206 | @table @code 207 | @item __C16X__ 208 | @item __C167__ 209 | @item __ST10__ 210 | @end table 211 | 212 | 213 | 214 | @section Stack 215 | 216 | If the @option{-stack-check} option is used, every function-prologue will 217 | call the function @code{__stack_check} with the stacksize needed by this 218 | function in register @code{R1}. This function has to consider its own 219 | stacksize and must restore all registers. 220 | 221 | Only stack-checking of the user-stack is supported. Checking the 222 | system-stack is supported by hardware. 223 | 224 | 225 | 226 | @section Stdarg 227 | 228 | A possible could look like this: 229 | 230 | @example 231 | typedef char *va_list; 232 | 233 | va_list __va_start(void); 234 | 235 | #define __va_rounded_size(__TYPE) \ 236 | (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 237 | 238 | #define va_start(__AP,__LA) (__AP=__va_start()) 239 | 240 | #define va_arg(__AP, __TYPE) \ 241 | (__AP = ((char *) (__AP) + __va_rounded_size (__TYPE)), \ 242 | *((__TYPE *)((__AP) - __va_rounded_size (__TYPE)))) 243 | 244 | #define va_end(__AP) ((__AP) = 0) 245 | @end example 246 | 247 | 248 | @section Known Problems 249 | 250 | @itemize @minus 251 | @item no floating-point 252 | @item huge-pointers are sometimes derferenced as far-pointers 253 | @item addressing-modes sometimes ignore huge 254 | @item initialized data is placed in RAM, bits are not initialized 255 | @item struct-copy only works with near-pointers 256 | @item near/far-conversion assumes DPP0-DPP3 linear 257 | @end itemize 258 | 259 | -------------------------------------------------------------------------------- /doc/vbcchc12.texi: -------------------------------------------------------------------------------- 1 | This chapter documents the Backend for the 68hc12 microcontroller family. 2 | 3 | Note that this backend is not done! 4 | 5 | @section Additional options for this version 6 | 7 | This backend provides the following additional options: 8 | 9 | @table @option 10 | 11 | @item -merge-constants 12 | Place identical floating point constants at the same 13 | memory location. This can reduce program size and increase 14 | compilation time. 15 | 16 | @item -const-in-data 17 | By default constant data will be placed in a read-only 18 | section. Using this option it will be placed in the 19 | data section. 20 | 21 | @item -no-delayed-popping 22 | By default arguments of function calls are not always popped 23 | from the stack immediately after the call, so that the 24 | arguments of several calls may be popped at once. 25 | With this option vbcc can be forced to pop them after every 26 | function call. 27 | This may simplify debugging and very slightly reduce the 28 | stack size needed by the compiled program. 29 | 30 | @item -no-peephole 31 | Do not perform peephole-optimizations. 32 | 33 | @item -mem-cse 34 | Try to hold values loaded from memory in registers and 35 | reuse them. Due to the small register-set of the hc12 36 | this is disabled by default as it increases register- 37 | pressure and tends to spill to the stack. 38 | @end table 39 | 40 | @section ABI 41 | 42 | The current version generates assembly output for use with the GNU 43 | assembler using the non-banked model. 44 | 45 | This backend supports the following registers: 46 | 47 | @itemize @minus 48 | @item @code{d} for the accumulator (also used for byte, i.e. @code{a}) 49 | @item @code{x} for index register x 50 | @item @code{y} for index register y 51 | @item @code{sp} for the stack-pointer 52 | @end itemize 53 | 54 | All registers are scratch (i.e. caller-save). 55 | 56 | The first function arguments which has integer or pointer types 57 | is passed in the accumulator @code{d} or the register pair @code{d/x}. 58 | The 59 | remaining arguments are passed on the stack. 60 | 61 | Integers and pointers are returned in @code{d} or @code{d/x}. 62 | All other types are returned by passing the function the address 63 | of the result as a hidden argument - so when you call such a function 64 | without a proper declaration in scope you can expect a crash. 65 | 66 | The elementary data types are represented like: 67 | @example 68 | type size in bits alignment in bytes 69 | 70 | char 8 1 71 | short 16 2 72 | int 16 2 73 | long currently not supported 74 | near pointers 16 2 75 | far pointers currently not supported 76 | huge pointers currently not supported 77 | float currently not supported 78 | double currently not supported 79 | @end example 80 | 81 | 82 | @section Target-specific variable-attributes 83 | 84 | The hc12-backend offers the following variable attributes: 85 | 86 | @table @code 87 | @item __interrupt 88 | Return with @code{rfi} rather than @code{blr}. 89 | 90 | @item __section("name","attr") 91 | Place this function/object in section "section" 92 | with attributes "attr". 93 | @end table 94 | 95 | @section Predefined Macros 96 | 97 | This backend defines the following macros: 98 | 99 | @table @code 100 | @item __HC12__ 101 | 102 | @end table 103 | 104 | @section Stack 105 | 106 | If the @option{-stack-check} option is used, every function-prologue will 107 | call the function @code{__stack_check} with the stacksize needed by this 108 | function in register @code{y}. This function has to consider its own 109 | stacksize and must restore all registers. 110 | 111 | 112 | @section Stdarg 113 | 114 | To be written... 115 | 116 | 117 | @section Known Problems 118 | 119 | @itemize @minus 120 | @item this backend is far from done... 121 | @end itemize 122 | 123 | 124 | -------------------------------------------------------------------------------- /doc/vbcci386.texi: -------------------------------------------------------------------------------- 1 | This chapter documents the Backend for the Intel i386 processor family. 2 | 3 | @section Additional options for this version 4 | 5 | This backend provides the following additional options: 6 | 7 | @table @option 8 | 9 | @item -longalign 10 | Align multibyte-values on 4-byte-boundaries. Needed by some 11 | operating systems. 12 | 13 | @item -elf 14 | Do not use a '_'-prefix in front of external identifiers. 15 | Use a '.'-prefix for label names. 16 | 17 | @item -merge-constants 18 | Place identical floating point constants at the same 19 | memory location. This can reduce program size and increase 20 | compilation time. 21 | 22 | @item -const-in-data 23 | By default constant data will be placed in a read-only 24 | section. Using this option it will be placed in the data section 25 | Note that on operating systems with memory protection this 26 | option will disable write-protection of constant data. 27 | 28 | @item -no-delayed-popping 29 | By default arguments of function calls are not always popped 30 | from the stack immediately after the call, so that the 31 | arguments of several calls may be popped at once. 32 | With this option vbcc can be forced to pop them after every 33 | function call. 34 | This may simplify debugging and very slightly reduce the 35 | stack size needed by the compiled program. 36 | 37 | @item -safe-fp 38 | Do not use the floating-point-stack for register variables. 39 | At the moment this is necessary as vbcci386 still has problems 40 | in some cases otherwise. 41 | @end table 42 | 43 | 44 | @section ABI 45 | 46 | This backend supports the following registers: 47 | 48 | @itemize @minus 49 | @item @code{%eax, %ebx, %ecx, %edx} 50 | @item @code{%esi, %edi, %ebp, %esp} 51 | @end itemize 52 | 53 | (And @code{%st(0)-%st(7)} for the floating point stack but these must not 54 | bes used for register variables because they cannot be handled like 55 | normal registers.) 56 | 57 | The current version generates assembly output for use with the GNU 58 | assembler. The generated code should work on systems with Intel 80386 59 | or higher CPUs with FPU and compatible chips. 60 | 61 | The registers @code{%eax, %ecx} and @code{%edx} (as well as the floating point stack) 62 | are used as scratch registers (i.e. they can be destroyed in function 63 | calls), all other registers are preserved. 64 | 65 | All elementary types up to 4 bytes are returned in register @code{%eax} 66 | Floating point values are returned in %st(0). 67 | All other types are returned by passing the function the address 68 | of the result as a hidden argument - so when you call such a function 69 | without a proper declaration in scope you can expect a crash. 70 | 71 | @code{vbcc} uses @code{%eax, %ebx, %ecx, %edx, %esi, %edi, %ebp} and the floating point 72 | stack for temporary results and register variables. Local variables 73 | are created on the stack and addressed via @code{%esp}. 74 | 75 | The elementary data types are represented like: 76 | 77 | @example 78 | type size in bits alignment in bytes (-longalign) 79 | 80 | char 8 1 (1) 81 | short 16 2 (4) 82 | int 32 2 (4) 83 | long 32 2 (4) 84 | long long n/a n/a 85 | all pointers 32 2 (4) 86 | float 32 2 (4) 87 | double 64 2 (4) 88 | @end example 89 | 90 | @section Predefined Macros 91 | 92 | This backend defines the following macros: 93 | 94 | @table @code 95 | @item __I386__ 96 | @item __X86__ 97 | 98 | @end table 99 | 100 | 101 | @section Stdarg 102 | 103 | A possible could look like this: 104 | 105 | @example 106 | typedef unsigned char *va_list; 107 | 108 | #define va_start(ap, lastarg) ((ap) = (va_list)(&lastarg + 1)) 109 | #define va_arg(ap, type) ((ap) += \ 110 | (sizeof(type) 45 | 46 | Set the limit (in number of intermediate code instructions) 47 | for the length of code-sequences considered for conditional 48 | execution (default: 2). 49 | 50 | 51 | @end table 52 | 53 | @section ABI 54 | 55 | This backend supports the following registers: 56 | 57 | @itemize @minus 58 | @item @code{r0} through @code{r31} for the general purpose registers 59 | @end itemize 60 | 61 | Additionally, the register pairs @code{r0/r1} @code{r2/r3, r4/r5, r6/r7, r8/r9, 62 | r10/r11, r12/r13, r14/r15, 63 | r16/r17, r18/r19, r20/r21, r22/r23} are 64 | available. 65 | 66 | @code{r14, r15, r24-r31} are currently reserved by the 67 | backend. 68 | 69 | 70 | 71 | The current version generates assembly output for use with @file{vasm}. 72 | 73 | 74 | The registers r0-r5 and r14-r15 are used as scratch registers 75 | (i.e. they can be destroyed in function calls), all other registers are 76 | preserved. r25 is the stack-pointer. 77 | 78 | The first 6 function arguments which have integer, float32 or pointer types 79 | are passed in registers r0 through r5. All other arguments 80 | are passed on the stack. 81 | 82 | Integers, float32 and pointers are returned in r0. 83 | All other types are returned by passing the function the address 84 | of the result as a hidden argument - so when you call such a function 85 | without a proper declaration in scope you can expect a crash. 86 | 87 | The elementary data types are represented like: 88 | 89 | @example 90 | type size in bits alignment in bytes 91 | 92 | char 8 1 93 | short 16 2 94 | int 32 4 95 | long 32 4 96 | long long 64 8 not yet supported 97 | all pointers 32 4 98 | float 32 4 99 | double 64 (32) 4 100 | long double 64 (32) 4 101 | @end example 102 | 103 | @section Target-specific variable-attributes 104 | 105 | The vidcore-backend offers the following variable-attributes: 106 | 107 | @table @code 108 | 109 | @item __section("name","attr") 110 | Place this function/object in section "name" with 111 | attributes "attr". 112 | @end table 113 | 114 | 115 | @section Target-specific pragmas 116 | 117 | The vidcore-backend offers the following #pragmas: 118 | 119 | @table @code 120 | 121 | @item none at the moment... 122 | 123 | @end table 124 | 125 | @section Predefined Macros 126 | 127 | This backend defines the following macros: 128 | 129 | @table @code 130 | @item __VIDEOCORE__ 131 | 132 | @item __SHORT_DOUBLE__ (if -short-double is used) 133 | @end table 134 | 135 | @section Stdarg 136 | 137 | stdarg-implementation is not yet fully working. One restriction is that 138 | when calling a varargs function, the prototype must be in scope (this is 139 | ISO C conforming). Another one is that the stdarg-macros only work as 140 | long as all fixed arguments are passed in registers. 141 | 142 | This will be fixed in the future. 143 | 144 | 145 | @section Known problems 146 | 147 | @itemize @minus 148 | @item no support for long long 149 | @item no support for 64bit floating point 150 | @item stdarg problems mentioned above 151 | @item suboptimal code quality 152 | @item ... 153 | @end itemize 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /doc/vc.texi: -------------------------------------------------------------------------------- 1 | This chapter describes @command{vc}, the frontend for vbcc. It knows how 2 | to deal with different file types and optimization settings and will 3 | call the compiler, assembler and linker. 4 | It is not recommended to call the different translation-phases directly. 5 | @command{vc} provides an easy-to-use interface which is mostly compatible to 6 | Unix @command{cc}. 7 | 8 | @section Usage 9 | 10 | The general syntax for calling @command{vc} 11 | 12 | @example 13 | @command{vc [options] file1 file2 ...} 14 | @end example 15 | 16 | processes all files according to their suffix and links all objects 17 | together (unless any of @option{-E}, @option{-S}, @option{-c} is specified). 18 | The following file types are recognized: 19 | 20 | @table @file 21 | @item .c 22 | C source 23 | @item .i 24 | already preprocessed C source 25 | @item .scs 26 | assembly source to be fed to the scheduler 27 | @item .asm 28 | @item .s 29 | assembly source 30 | @item .obj 31 | @item .o 32 | object file 33 | @end table 34 | 35 | Usually pattern matching is supported - however this depends on the 36 | port and the host system. 37 | 38 | The options recognized by @command{vc} are: 39 | 40 | @table @option 41 | 42 | @item -v 43 | Verbose mode. Prints all commands before executing them. 44 | 45 | @item -vv 46 | Very verbose. Displays some internals as well. 47 | 48 | @item -Ox 49 | Sets the optimization level.@* 50 | -O0 is equivalent to -O=0.@* 51 | -O will activate some optimizations (at the moment -O=991).@* 52 | -O2 will activate most optimizations (at the moment -O=1023 -schedule).@* 53 | -O3 will activate all optimizations (at the moment -O=~0 -schedule).@* 54 | -O4 will activate full cross-module-optimization.@* 55 | 56 | Also, -O3 will activate cross-module-optimizations. All source 57 | files specified on the command line will be passed to the compiler 58 | at once. Only one assembly/object-file will be produced (by default 59 | the name is the name of the first source file with corresponding 60 | suffix). 61 | 62 | When compiling with -O4 and -c vbcc will not produce real object 63 | files but special files containing all necessary information to 64 | defer optimization and code-generation to link-time. This is 65 | useful to provide all files of a project to the optimizer and 66 | make full use of cross-module optimizations. 67 | Note that you must use vc to do the linking. vc will detect and 68 | handle these files correctly. They can not be linked directly. 69 | Also, make sure to pass all relevant compiler options also to 70 | the linker-command. 71 | 72 | Higher values may or may not activate even more optimizations. 73 | The default is -O=1. 74 | It is also possible to specify an exact value with -O=n. 75 | However, I do not recommend this unless you know exactly what 76 | you are doing. 77 | 78 | @item -o file 79 | Save the target as @file{file} (default for executables is 80 | @file{a.out}). 81 | 82 | @item -E 83 | Save the preprocessed C sources with .i suffix. 84 | 85 | @item -S 86 | Do not assemble. Save the compiled files with .asm suffix. 87 | 88 | @item -SCS 89 | Do not schedule. Save the compiled files with .scs suffix. 90 | 91 | @item -c 92 | Do not link. Save the compiled files with .o suffix. 93 | 94 | @item -k 95 | Keep all intermediate files. By default all generated files 96 | except the source files and the targets are deleted. 97 | 98 | @item -Dstr 99 | @code{#define} a preprocessor symbol, e.g. -DAMIGA or -DCPU=68000. 100 | The former syntax is equivalent to: 101 | @example 102 | #define AMIGA 1 103 | @end example 104 | The latter form is equivalent to: 105 | @example 106 | #define CPU 68000 107 | @end example 108 | 109 | @item -Ipath 110 | Add @file{path} to the include-search-path. 111 | 112 | @item -lulib 113 | Link with library @file{ulib}. 114 | 115 | @item -Lpath 116 | Add @file{path} to the library-search-path. 117 | This is passed through to the linker. 118 | 119 | @item -static 120 | Instruct the linker to link against static libraries. 121 | This may override the default to link against dynamic 122 | libraries first. 123 | 124 | @item -nostdlib 125 | Do not link with standard-startup/libraries. Useful only 126 | for people who know what they are doing. 127 | 128 | @item -notmpfile 129 | Do not use names from tmpnam() for temporary files. 130 | 131 | @item -schedule 132 | Invoke the instruction-scheduler, if available. 133 | 134 | @item +file 135 | Use @file{file} as config-file. 136 | 137 | @end table 138 | 139 | 140 | All other options are passed through to @command{vbcc}. 141 | 142 | 143 | 144 | 145 | 146 | @section Configuration 147 | 148 | @command{vc} needs a config file to know how to call all the translation 149 | phases (compiler, assembler, linker). Unless a different file is 150 | specified using the @option{+}-option, it will look for a file 151 | @file{vc.config} (@file{vc.cfg} for DOS/Windows). 152 | 153 | On AmigaOS @command{vc} will search in the current 154 | directory, in @file{ENV:} and @file{VBCC:}. 155 | 156 | On Unix @command{vc} will search in the current directory followed 157 | by @file{/etc/}. 158 | 159 | On DOS/Windows it will search in the current directory. 160 | 161 | If the config file was not found in the default search-paths and 162 | an environment variable @env{$VBCC} is set, @command{vc} will also look 163 | in @env{$VBCC}@file{/config}. 164 | 165 | Once a config file is found, it will 166 | be treated as a collection of additional command line arguments. Every 167 | line of the file will be used as one argument. So no quoting shall be 168 | used and furthermore must each argument be placed on its own line. 169 | 170 | 171 | The following options can be used to tell @command{vc} how to call the 172 | translation phases (they will usually be contained in the config-file): 173 | 174 | @table @option 175 | 176 | @item -pp=string 177 | The preprocessor will be called like in 178 | @code{printf(string,opts,infile,outfile)}, e.g. the default for @command{vcpp} 179 | searching the includes in @file{vinclude:} and defining @code{__STDC__}) 180 | is @option{-pp=vcpp -Ivinclude: -D__STDC__=1 %s %s %s}. 181 | Note that there is an internal preprocessor, called 182 | @command{ucpp}, since V0.8, you usually don't need this 183 | option any more. 184 | 185 | @item -cc=string 186 | For the compiler. Note that you cannot use @command{vc} to call 187 | another compiler than @command{vbcc}. But you can call different 188 | versions of @command{vbcc} this way, e.g.: 189 | @option{-cc=vbccm68k -quiet} or 190 | @option{-cc=vbcci386 -quiet} 191 | 192 | @item -isc=string 193 | The same for the scheduler, e.g.: 194 | @option{-isc=vscppc -quiet %s %s} 195 | Omit, if there is no scheduler for the architecture. 196 | 197 | @item -as=string 198 | The same for the assembler, e.g.: 199 | @option{-as=vasmm68k_mot -quiet -Fhunk -phxass -opt-pea -opt-clr %s -o %s} or 200 | @option{-as=as %s -o %s} 201 | 202 | @item -rm=string 203 | This is the string for the delete command and takes only 204 | one argument, e.g. 205 | @option{-rm=delete quiet %s} or 206 | @option{-rm=rm %s} 207 | 208 | @item -ld=string 209 | This is for the linker and takes three arguments. The first 210 | one are the object files (separated by spaces), the second 211 | one the user specified libraries and the last one the name 212 | of the resulting executable. 213 | This has to link with proper startup-code and c-libraries, 214 | e.g.: 215 | @option{-ld=vlink -x -Bstatic -Cvbcc -nostdlib -Lvlibos3: vlibos3:startup.o %s %s -lvc -o %s} or 216 | @option{-ld=ld /usr/lib/crt0.o %s %s -lc -o %s} 217 | 218 | @item -l2=string 219 | The same like -ld, but standard-startup and -libraries should 220 | not be linked; used when -nostdlib is specified. 221 | 222 | @item -ldnodb=string 223 | This option string is inserted in the linker command before 224 | specifying the libraries, whenever an executable without 225 | debugging information and symbols should be created (AKA 226 | as a 'stripped' executable). 227 | 228 | @item -ldstatic=string 229 | This option string is inserted in the linker command before 230 | specifying the libraries when static linking was requested 231 | with option @option{-static}. 232 | 233 | @end table 234 | 235 | All those strings should tell the command to omit any output apart from 236 | error messages if possible. However for every of those options there 237 | exists one with an additional @samp{v}, i.e. @option{-ppv=}, @option{-asv=}, etc. which should 238 | produce some output, if possible. 239 | If vc is invoked with the @option{-vv} option the verbose commands will be called, 240 | if not the quiet ones will be used. 241 | 242 | @table @samp 243 | @item -ul=string 244 | Format for additional libraries specified with @option{-l}. 245 | The result of @code{printf(string,lib)} will be added to the 246 | command invoking the linker. Examples are: 247 | @option{-ul=vlib:%s.lib} or @option{-ul=-l%s} 248 | 249 | @end table 250 | 251 | -------------------------------------------------------------------------------- /doc/vprof.texi: -------------------------------------------------------------------------------- 1 | 2 | INTRODUCTION 3 | 4 | vprof is a portable utility to visualize the profiling informations, 5 | which are usually stored in the file "mon.out". 6 | It shows the percentage of total time spent in a function, the 7 | total time in seconds, the number of function calls and the time 8 | by call in ms. 9 | 10 | 11 | LEGAL 12 | 13 | vprof is freeware. 14 | 15 | 16 | USAGE 17 | 18 | vprof [mon.out] 19 | 20 | If the profiling file has another name than "mon.out", you may 21 | specify it as an argument to vprof. 22 | 23 | Some vbcc code generators are able to create profiling information 24 | by compiling with the -prof option (vbccm68k, for example). 25 | 26 | 27 | BUGS 28 | 29 | The percentage column is still not working and will always 30 | display "n.a.". 31 | 32 | 33 | Frank Wille frank@phoenix.owl.de 34 | -------------------------------------------------------------------------------- /doc/vsc.texi: -------------------------------------------------------------------------------- 1 | vsc - scheduler for vbcc (c) in 1997-99 by Volker Barthelmann 2 | 3 | 4 | @section Introduction 5 | 6 | vsc is an instruction-scheduler which reorders the assembly output of 7 | vbcc and tries to improve performance of the generated code by avoiding 8 | pipeline stalls etc. 9 | 10 | Like the compiler vbcc it is split into a target independent and a 11 | target dependent part. However there may be code-generators for vbcc 12 | which do not have a corresponding scheduler. 13 | 14 | This document only deals with the target independent parts of vsc. 15 | Be sure to read all the documents for your machine. 16 | 17 | 18 | @section Usage 19 | 20 | Usually @command{vsc} will be called by a frontend. However if you call it 21 | directly, it has to be done like this: 22 | 23 | @example 24 | vsc [options] input-file output-file 25 | @end example 26 | 27 | The following options are supported: 28 | 29 | @table @option 30 | @item -quiet 31 | Do not print the copyright notice. 32 | 33 | @item -debug= 34 | Set debug-level to . 35 | @end table 36 | 37 | 38 | Note that depending on the target @command{vbcc} may insert hints into the 39 | generated code to tell vsc what CPU to schedule for. Code 40 | scheduled for a certain CPU may run much slower on slightly different 41 | CPUs. Therefore it is especially important to specify the correct 42 | target-CPU when compiling. 43 | 44 | 45 | @section Known problems 46 | 47 | @itemize @minus 48 | @item works only on basic-blocks 49 | @end itemize 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /ic.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kusma/vbcc/191c0da6d49759e88b27e236d9d929645502da3f/ic.c -------------------------------------------------------------------------------- /machines/alpha/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSLE S16BSBE 4 | S16BULE S16BUBE 5 | S32BSLE S32BSBE 6 | S32BULE S32BUBE 7 | S64BSLE S64BSBE 8 | S64BULE S64BUBE 9 | S64BSLE S64BSBE 10 | S64BULE S64BUBE 11 | S32BIEEELE 12 | S64BIEEELE 13 | S64BIEEELE 14 | S64BULE S64BUBE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/alpha/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for a DEC Alpha */ 2 | 3 | #include "dt.h" 4 | 5 | /* This struct can be used to implement machine-specific */ 6 | /* addressing-modes. */ 7 | /* Not used in this code-generrator. */ 8 | struct AddressingMode{ 9 | int flags; 10 | int base; 11 | int align; 12 | long offset; 13 | }; 14 | 15 | /* The number of registers of the target machine. */ 16 | #define MAXR 64 17 | 18 | /* Number of commandline-options the code-generator accepts. */ 19 | #define MAXGF 10 20 | 21 | /* If this is set to zero vbcc will not generate ICs where the */ 22 | /* target operand is the same as the 2nd source operand. */ 23 | /* This can sometimes simplify the code-generator, but usually */ 24 | /* the code is better if the code-generator allows it. */ 25 | #define USEQ2ASZ 1 26 | 27 | /* This specifies the smallest integer type that can be added to a */ 28 | /* pointer. */ 29 | #define MINADDI2P LONG 30 | 31 | /* If the bytes of an integer are ordered most significant byte */ 32 | /* byte first and then decreasing set BIGENDIAN to 1. */ 33 | #define BIGENDIAN 0 34 | 35 | /* If the bytes of an integer are ordered lest significant byte */ 36 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 37 | #define LITTLEENDIAN 1 38 | 39 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 40 | 41 | /* If switch-statements should be generated as a sequence of */ 42 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 43 | /* This can yield better code on some machines. */ 44 | #define SWITCHSUBS 1 45 | 46 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 47 | /* with length known at compile-time will be inlined using an */ 48 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 49 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 50 | #define INLINEMEMCPY 1024 51 | 52 | /* Parameters are sometimes passed in registers without __reg. */ 53 | #define HAVE_REGPARMS 1 54 | 55 | /* Parameters on the stack should be pushed in order rather than */ 56 | /* in reverse order. */ 57 | #define ORDERED_PUSH 1 58 | 59 | /* Structure for reg_parm(). */ 60 | struct reg_handle{ 61 | int nextr; 62 | }; 63 | 64 | /* size of buffer for asm-output */ 65 | #define EMIT_BUF_LEN 1024 /* should be enough */ 66 | /* number of asm-output lines buffered */ 67 | #define EMIT_BUF_DEPTH 4 68 | 69 | /* We have no asm_peephole to optimize assembly-output */ 70 | #define HAVE_TARGET_PEEPHOLE 0 71 | -------------------------------------------------------------------------------- /machines/alpha/schedule.c: -------------------------------------------------------------------------------- 1 | #include "vsc.h" 2 | 3 | char tg_copyright[]="Alpha scheduler V0.0 (c) in 1997 by Volker Barthelmann"; 4 | 5 | int sched_init(void) 6 | { 7 | return 1; 8 | } 9 | void sched_cleanup(void) 10 | { 11 | } 12 | int sched_info(struct sinfo *p) 13 | { 14 | char buf[20];int q1,q2,z,i; 15 | if(sscanf(p->txt,"$C%d:",&i)==1){ 16 | p->label=i; 17 | p->flags=LABEL; 18 | return 1; 19 | } 20 | /* lda $r1,imm($r2) */ 21 | if(sscanf(p->txt,"lda $%d,%d($%d)",&z,&i,&q1)==3){ 22 | p->latency=1; 23 | BSET(p->pipes,0); 24 | BSET(p->pipes,1); 25 | BSET(p->uses,q1); 26 | BSET(p->modifies,z); 27 | return 1; 28 | } 29 | /* lda $r1,... */ 30 | if(sscanf(p->txt,"lda $%d,",&z)==1){ 31 | BSET(p->pipes,0); 32 | BSET(p->pipes,1); 33 | BSET(p->modifies,z); 34 | return 1; 35 | } 36 | /* op $r1,$r2,$r3 */ 37 | if(sscanf(p->txt,"%19s $%d,$%d,$%d",buf,&q1,&q2,&z)==4){ 38 | p->latency=1; 39 | BSET(p->pipes,0); 40 | BSET(p->pipes,1); 41 | BSET(p->uses,q1); 42 | BSET(p->uses,q2); 43 | BSET(p->modifies,z); 44 | return 1; 45 | } 46 | /* op $r1,$r2 */ 47 | if(sscanf(p->txt,"%19s $%d,$%d",buf,&q1,&z)==3){ 48 | p->latency=1; 49 | BSET(p->pipes,0); 50 | BSET(p->pipes,1); 51 | BSET(p->uses,q1); 52 | BSET(p->modifies,z); 53 | return 1; 54 | } 55 | /* op $r1,imm,$r2 */ 56 | if(sscanf(p->txt,"%19s $%d,%d,$%d",buf,&q1,&i,&z)==4){ 57 | p->latency=1; 58 | BSET(p->pipes,0); 59 | BSET(p->pipes,1); 60 | BSET(p->uses,q1); 61 | BSET(p->modifies,z); 62 | return 1; 63 | } 64 | /* op $fr1,$fr2,$fr3 */ 65 | if(sscanf(p->txt,"%19s $f%d,$f%d,$f%d",buf,&q1,&q2,&z)==4){ 66 | p->latency=1; 67 | BSET(p->pipes,2); 68 | BSET(p->pipes,3); 69 | BSET(p->uses,q1+32); 70 | BSET(p->uses,q2+32); 71 | BSET(p->modifies,z+32); 72 | return 1; 73 | } 74 | /* load/store $r1,c($r2) */ 75 | if(sscanf(p->txt,"%19s $%d,%d($%d)",buf,&z,&i,&q1)==4){ 76 | p->latency=3; 77 | BSET(p->pipes,0); 78 | BSET(p->uses,q1); 79 | if(*buf=='l'){ 80 | BSET(p->pipes,1); 81 | BSET(p->modifies,z); 82 | BSET(p->uses,MEM); 83 | }else{ 84 | BSET(p->uses,z); 85 | BSET(p->modifies,MEM); 86 | } 87 | return 1; 88 | } 89 | /* load/store $fr1,c($r2) */ 90 | if(sscanf(p->txt,"%19s $f%d,%d($%d)",buf,&z,&i,&q1)==4){ 91 | p->latency=3; 92 | BSET(p->pipes,0); 93 | BSET(p->uses,q1); 94 | if(*buf=='l'){ 95 | BSET(p->pipes,1); 96 | BSET(p->modifies,z+32); 97 | BSET(p->uses,MEM); 98 | }else{ 99 | BSET(p->uses,z+32); 100 | BSET(p->modifies,MEM); 101 | } 102 | return 1; 103 | } 104 | p->flags=BARRIER; 105 | return 1; 106 | } 107 | -------------------------------------------------------------------------------- /machines/alpha/schedule.h: -------------------------------------------------------------------------------- 1 | 2 | #define PIPES 4 3 | #define REGS 64 4 | 5 | -------------------------------------------------------------------------------- /machines/bi386/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S32BSBE S32BSLE 6 | S32BUBE S32BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S32BIEEEBE 10 | S64BIEEEBE 11 | S32BUBE S32BULE 12 | 13 | 14 | -------------------------------------------------------------------------------- /machines/bi386/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for an Intel 386 or higher. */ 2 | 3 | #include "dt.h" 4 | 5 | #define BEI386 6 | 7 | /* This struct can be used to implement machine-specific */ 8 | /* addressing-modes. */ 9 | /* Not used in this code-generrator. */ 10 | struct AddressingMode{ 11 | int never_used; 12 | }; 13 | 14 | /* The number of registers of the target machine. */ 15 | #define MAXR 16 16 | 17 | /* Number of commandline-options the code-generator accepts. */ 18 | #define MAXGF 10 19 | 20 | /* If this is set to zero vbcc will not generate ICs where the */ 21 | /* target operand is the same as the 2nd source operand. */ 22 | /* This can sometimes simplify the code-generator, but usually */ 23 | /* the code is better if the code-generator allows it. */ 24 | #define USEQ2ASZ 0 25 | 26 | /* This specifies the smallest integer type that can be added to a */ 27 | /* pointer. */ 28 | #define MINADDI2P INT 29 | 30 | /* If the bytes of an integer are ordered most significant byte */ 31 | /* byte first and then decreasing set BIGENDIAN to 1. */ 32 | #ifdef BEI386 33 | #define BIGENDIAN 1 34 | #else 35 | #define BIGENDIAN 0 36 | #endif 37 | 38 | /* If the bytes of an integer are ordered lest significant byte */ 39 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 40 | #ifdef BEI386 41 | #define LITTLEENDIAN 0 42 | #else 43 | #define LITTLEENDIAN 1 44 | #endif 45 | 46 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 47 | 48 | /* If switch-statements should be generated as a sequence of */ 49 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 50 | /* This can yield better code on some machines. */ 51 | #define SWITCHSUBS 0 52 | 53 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 54 | /* with length known at compile-time will be inlined using an */ 55 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 56 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 57 | #define INLINEMEMCPY 1024 58 | 59 | 60 | -------------------------------------------------------------------------------- /machines/c16x/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSLE S16BSBE 4 | S16BULE S16BUBE 5 | S16BSLE S16BSBE 6 | S16BULE S16BUBE 7 | S32BSLE S32BSBE 8 | S32BULE S32BUBE 9 | S64BSLE S64BSBE 10 | S64BULE S64BUBE 11 | S32BIEEELE 12 | S64BIEEELE 13 | S64BIEEELE 14 | S16BULE S16BUBE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/c16x/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for SAB c16x 16bit microcontrollers.*/ 2 | 3 | #include "dt.h" 4 | 5 | /* We have extended types! What we have to do to support them: */ 6 | /* - #define HAVE_EXT_TYPES 7 | - #undef all standard types 8 | - #define all standard types plus new types 9 | - write eval_const and insert_const 10 | - write typedefs for zmax and zumax 11 | - write typname[] 12 | - write conv_typ() 13 | - optionally #define ISPOINTER, ISARITH, ISINT etc. 14 | - optionally #define HAVE_TGT_PRINTVAL and write printval 15 | - optionally #define POINTER_TYPE 16 | - optionally #define HAVE_TGT_FALIGN and write falign 17 | - optionally #define HAVE_TGT_SZOF and write szof 18 | - optionally add functions for attribute-handling 19 | */ 20 | #define HAVE_EXT_TYPES 1 21 | 22 | #define HAVE_TGT_PRINTVAL 23 | 24 | #undef CHAR 25 | #undef SHORT 26 | #undef INT 27 | #undef LONG 28 | #undef LLONG 29 | #undef FLOAT 30 | #undef DOUBLE 31 | #undef LDOUBLE 32 | #undef VOID 33 | #undef POINTER 34 | #undef ARRAY 35 | #undef STRUCT 36 | #undef UNION 37 | #undef ENUM 38 | #undef FUNKT 39 | #undef BOOL 40 | #undef MAXINT 41 | #undef MAX_TYPE 42 | 43 | #define BIT 1 44 | #define CHAR 2 45 | #define SHORT 3 46 | #define INT 4 47 | #define LONG 5 48 | #define LLONG 6 49 | #define FLOAT 7 50 | #define DOUBLE 8 51 | #define LDOUBLE 9 52 | #define VOID 10 53 | #define NPOINTER 11 54 | #define FPOINTER 12 55 | #define HPOINTER 13 56 | #define ARRAY 14 57 | #define STRUCT 15 58 | #define UNION 16 59 | #define ENUM 17 60 | #define FUNKT 18 61 | #define BOOL 19 62 | 63 | #define MAXINT 20 64 | 65 | #define MAX_TYPE MAXINT 66 | 67 | #define POINTER_TYPE(x) pointer_type(x) 68 | extern int pointer_type(); 69 | #define ISPOINTER(x) ((x&NQ)>=NPOINTER&&(x&NQ)<=HPOINTER) 70 | #define ISSCALAR(x) ((x&NQ)>=BIT&&(x&NQ)<=HPOINTER) 71 | #define ISINT(x) ((x&NQ)>=BIT&&(x&NQ)<=LLONG) 72 | #define PTRDIFF_T(x) ((x)==HPOINTER?LONG:INT) 73 | 74 | typedef zllong zmax; 75 | typedef zullong zumax; 76 | 77 | union atyps{ 78 | zchar vchar; 79 | zuchar vuchar; 80 | zshort vshort; 81 | zushort vushort; 82 | zint vint; 83 | zuint vuint; 84 | zlong vlong; 85 | zulong vulong; 86 | zllong vllong; 87 | zullong vullong; 88 | zmax vmax; 89 | zumax vumax; 90 | zfloat vfloat; 91 | zdouble vdouble; 92 | zldouble vldouble; 93 | }; 94 | 95 | /* This struct can be used to implement machine-specific */ 96 | /* addressing-modes. */ 97 | /* Not used in this code-generrator. */ 98 | struct AddressingMode{ 99 | int flags; 100 | int base; 101 | long offset; 102 | struct Var *v; 103 | }; 104 | 105 | /* This type will be added to every IC. Can be used by the cg. */ 106 | #define HAVE_EXT_IC 1 107 | struct ext_ic { 108 | int flags; 109 | int r; 110 | long offset; 111 | }; 112 | 113 | /* The number of registers of the target machine. */ 114 | #define MAXR 25 115 | 116 | /* Number of commandline-options the code-generator accepts. */ 117 | #define MAXGF 10 118 | 119 | /* If this is set to zero vbcc will not generate ICs where the */ 120 | /* target operand is the same as the 2nd source operand. */ 121 | /* This can sometimes simplify the code-generator, but usually */ 122 | /* the code is better if the code-generator allows it. */ 123 | #define USEQ2ASZ 1 124 | 125 | /* This specifies the smallest integer type that can be added to a */ 126 | /* pointer. */ 127 | #define MINADDI2P INT 128 | 129 | /* If the bytes of an integer are ordered most significant byte */ 130 | /* byte first and then decreasing set BIGENDIAN to 1. */ 131 | #define BIGENDIAN 0 132 | 133 | /* If the bytes of an integer are ordered lest significant byte */ 134 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 135 | #define LITTLEENDIAN 1 136 | 137 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 138 | 139 | /* If switch-statements should be generated as a sequence of */ 140 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 141 | /* This can yield better code on some machines. */ 142 | #define SWITCHSUBS 0 143 | 144 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 145 | /* with length known at compile-time will be inlined using an */ 146 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 147 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 148 | #define INLINEMEMCPY 1024 149 | 150 | #define HAVE_REGPARMS 1 151 | 152 | struct reg_handle { 153 | int gpr; 154 | }; 155 | 156 | /* We use unsigned int as size_t rather than unsigned long which */ 157 | /* is the default setting. */ 158 | #define HAVE_INT_SIZET 1 159 | 160 | /* We have register pairs. */ 161 | #define HAVE_REGPAIRS 1 162 | 163 | /* We keep track of all registers modified by a function. */ 164 | #define HAVE_REGS_MODIFIED 1 165 | 166 | #define HAVE_TARGET_RALLOC 1 167 | #define cost_load_reg(r,v) 4 168 | #define cost_save_reg(r,v) 4 169 | #define cost_move_reg(i,j) 2 170 | #define cost_pushpop_reg(r) 2 171 | 172 | /* size of buffer for asm-output */ 173 | #define EMIT_BUF_LEN 1024 /* should be enough */ 174 | /* number of asm-output lines buffered */ 175 | #define EMIT_BUF_DEPTH 4 176 | 177 | /* We have asm_peephole to optimize assembly-output */ 178 | #define HAVE_TARGET_PEEPHOLE 1 179 | 180 | /* We have some target-specific variable attributes. */ 181 | #define HAVE_TARGET_ATTRIBUTES 1 182 | 183 | /* We use builtin libcalls for some operations */ 184 | #define HAVE_LIBCALLS 1 185 | -------------------------------------------------------------------------------- /machines/generic/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S32BSBE S32BSLE 6 | S32BUBE S32BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S32BUBE S32BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/generic/machine.h: -------------------------------------------------------------------------------- 1 | /* Example backend for vbcc, it models a generic 32bit RISC or CISC 2 | CPU. 3 | 4 | Configurable at build-time are: 5 | - number of (32bit) general-purpose-registers 6 | - number of (64bit) floating-point-registers 7 | - number of (8bit) condition-code-registers 8 | - mechanism for stack-arguments (moving ot fixed sp) 9 | 10 | It allows to select as run-time-options: 11 | - two- or three-address code 12 | - memory operands or load-store-architecture 13 | - number of register-arguments 14 | - number of caller-save-registers 15 | */ 16 | 17 | /* buil-time configurable options: */ 18 | #define NUM_GPRS 32 19 | #define NUM_FPRS 32 20 | #define NUM_CCRS 8 21 | #define FIXED_SP 1 22 | 23 | #include "dt.h" 24 | 25 | /* internally used by the backend */ 26 | #define FIRST_GPR 1 27 | #define LAST_GPR (FIRST_GPR+NUM_GPRS-1) 28 | #define FIRST_FPR (LAST_GPR+1) 29 | #define LAST_FPR (FIRST_FPR+NUM_FPRS-1) 30 | #define FIRST_CCR (LAST_FPR+1) 31 | #define LAST_CCR (FIRST_CCR+NUM_CCRS-1) 32 | 33 | /* This struct can be used to implement machine-specific */ 34 | /* addressing-modes. */ 35 | /* Currently possible are (const,gpr) and (gpr,gpr) */ 36 | struct AddressingMode{ 37 | int flags; 38 | int base; 39 | long offset; 40 | }; 41 | 42 | /* The number of registers of the target machine. */ 43 | #define MAXR NUM_GPRS+NUM_FPRS+NUM_CCRS 44 | 45 | /* Number of commandline-options the code-generator accepts. */ 46 | #define MAXGF 20 47 | 48 | /* If this is set to zero vbcc will not generate ICs where the */ 49 | /* target operand is the same as the 2nd source operand. */ 50 | /* This can sometimes simplify the code-generator, but usually */ 51 | /* the code is better if the code-generator allows it. */ 52 | #define USEQ2ASZ 1 53 | 54 | /* This specifies the smallest integer type that can be added to a */ 55 | /* pointer. */ 56 | #define MINADDI2P INT 57 | 58 | /* If the bytes of an integer are ordered most significant byte */ 59 | /* byte first and then decreasing set BIGENDIAN to 1. */ 60 | #define BIGENDIAN 1 61 | 62 | /* If the bytes of an integer are ordered lest significant byte */ 63 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 64 | #define LITTLEENDIAN 0 65 | 66 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 67 | 68 | /* If switch-statements should be generated as a sequence of */ 69 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 70 | /* This can yield better code on some machines. */ 71 | #define SWITCHSUBS 0 72 | 73 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 74 | /* with length known at compile-time will be inlined using an */ 75 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 76 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 77 | #define INLINEMEMCPY 1024 78 | 79 | /* Parameters are sometimes passed in registers without __reg. */ 80 | #define HAVE_REGPARMS 1 81 | 82 | /* Parameters on the stack should be pushed in order rather than */ 83 | /* in reverse order. */ 84 | #define ORDERED_PUSH FIXED_SP 85 | 86 | /* Structure for reg_parm(). */ 87 | struct reg_handle{ 88 | unsigned long gregs; 89 | unsigned long fregs; 90 | }; 91 | 92 | /* We have some target-specific variable attributes. */ 93 | #define HAVE_TARGET_ATTRIBUTES 94 | 95 | /* We have target-specific pragmas */ 96 | #define HAVE_TARGET_PRAGMAS 97 | 98 | /* We keep track of all registers modified by a function. */ 99 | #define HAVE_REGS_MODIFIED 1 100 | 101 | /* We have a implement our own cost-functions to adapt 102 | register-allocation */ 103 | #define HAVE_TARGET_RALLOC 1 104 | #define cost_move_reg(x,y) 1 105 | #define cost_load_reg(x,y) 2 106 | #define cost_save_reg(x,y) 2 107 | #define cost_pushpop_reg(x) 3 108 | 109 | /* size of buffer for asm-output, this can be used to do 110 | peephole-optimizations of the generated assembly-output */ 111 | #define EMIT_BUF_LEN 1024 /* should be enough */ 112 | /* number of asm-output lines buffered */ 113 | #define EMIT_BUF_DEPTH 4 114 | 115 | /* We have no asm_peephole to optimize assembly-output */ 116 | #define HAVE_TARGET_PEEPHOLE 0 117 | 118 | /* we do not have a mark_eff_ics function, this is used to prevent 119 | optimizations on code which can already be implemented by efficient 120 | assembly */ 121 | #undef HAVE_TARGET_EFF_IC 122 | 123 | /* we only need the standard data types (no bit-types, different pointers 124 | etc.) */ 125 | #undef HAVE_EXT_TYPES 126 | #undef HAVE_TGT_PRINTVAL 127 | 128 | /* we do not need extra elements in the IC */ 129 | #undef HAVE_EXT_IC 130 | 131 | /* we do not use unsigned int as size_t (but unsigned long, the default) */ 132 | #undef HAVE_INT_SIZET 133 | 134 | /* we do not need register-pairs */ 135 | #undef HAVE_REGPAIRS 136 | 137 | 138 | /* do not create CONVERT ICs from integers smaller than int to floats */ 139 | #define MIN_INT_TO_FLOAT_TYPE INT 140 | 141 | /* do not create CONVERT ICs from floats to ints smaller than int */ 142 | #define MIN_FLOAT_TO_INT_TYPE INT 143 | 144 | /* do not create CONVERT_ICs from floats to unsigned integers */ 145 | #define AVOID_FLOAT_TO_UNSIGNED 1 146 | 147 | /* do not create CONVERT_ICs from unsigned integers to floats */ 148 | #define AVOID_UNSIGNED_TO_FLOAT 1 149 | -------------------------------------------------------------------------------- /machines/hc12/machine.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kusma/vbcc/191c0da6d49759e88b27e236d9d929645502da3f/machines/hc12/machine.c -------------------------------------------------------------------------------- /machines/hc12/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S16BSBE S16BSLE 6 | S16BUBE S16BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S16BUbE S16BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/hc12/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for Motorola 68hc12 16bit microcontrollers.*/ 2 | 3 | #include "dt.h" 4 | 5 | /* We have extended types! What we have to do to support them: */ 6 | /* - #define HAVE_EXT_TYPES 7 | - #undef all standard types 8 | - #define all standard types plus new types 9 | - write eval_const and insert_const 10 | - write typedefs for zmax and zumax 11 | - write typname[] 12 | - write conv_typ() 13 | - optionally #define ISPOINTER, ISARITH, ISINT etc. 14 | - optionally #define HAVE_TGT_PRINTVAL and write printval 15 | - optionally #define POINTER_TYPE 16 | - optionally #define HAVE_TGT_FALIGN and write falign 17 | - optionally #define HAVE_TGT_SZOF and write szof 18 | - optionally add functions for attribute-handling 19 | */ 20 | #define HAVE_EXT_TYPES 1 21 | 22 | #define HAVE_TGT_PRINTVAL 23 | 24 | #undef CHAR 25 | #undef SHORT 26 | #undef INT 27 | #undef LONG 28 | #undef LLONG 29 | #undef FLOAT 30 | #undef DOUBLE 31 | #undef LDOUBLE 32 | #undef VOID 33 | #undef POINTER 34 | #undef ARRAY 35 | #undef STRUCT 36 | #undef UNION 37 | #undef ENUM 38 | #undef FUNKT 39 | #undef MAXINT 40 | #undef MAX_TYPE 41 | 42 | #define BIT 1 43 | #define CHAR 2 44 | #define SHORT 3 45 | #define INT 4 46 | #define LONG 5 47 | #define LLONG 6 48 | #define FLOAT 7 49 | #define DOUBLE 8 50 | #define LDOUBLE 9 51 | #define VOID 10 52 | #define NPOINTER 11 53 | #define FPOINTER 12 54 | #define HPOINTER 13 55 | #define ARRAY 14 56 | #define STRUCT 15 57 | #define UNION 16 58 | #define ENUM 17 59 | #define FUNKT 18 60 | 61 | #define MAXINT 19 62 | 63 | #define MAX_TYPE MAXINT 64 | 65 | #define POINTER_TYPE(x) pointer_type(x) 66 | extern int pointer_type(); 67 | #define ISPOINTER(x) ((x&NQ)>=NPOINTER&&(x&NQ)<=HPOINTER) 68 | #define ISSCALAR(x) ((x&NQ)>=BIT&&(x&NQ)<=HPOINTER) 69 | #define ISINT(x) ((x&NQ)>=BIT&&(x&NQ)<=LLONG) 70 | #define PTRDIFF_T(x) ((x)==HPOINTER?LONG:INT) 71 | 72 | typedef zllong zmax; 73 | typedef zullong zumax; 74 | 75 | union atyps{ 76 | zchar vchar; 77 | zuchar vuchar; 78 | zshort vshort; 79 | zushort vushort; 80 | zint vint; 81 | zuint vuint; 82 | zlong vlong; 83 | zulong vulong; 84 | zllong vllong; 85 | zullong vullong; 86 | zmax vmax; 87 | zumax vumax; 88 | zfloat vfloat; 89 | zdouble vdouble; 90 | zldouble vldouble; 91 | }; 92 | 93 | /* This struct can be used to implement machine-specific */ 94 | /* addressing-modes. */ 95 | /* Not used in this code-generrator. */ 96 | struct AddressingMode{ 97 | int flags; 98 | int base; 99 | long offset; 100 | struct Var *v; 101 | }; 102 | 103 | /* This type will be added to every IC. Can be used by the cg. */ 104 | #define HAVE_EXT_IC 1 105 | struct ext_ic { 106 | int flags; 107 | int r; 108 | long offset; 109 | }; 110 | 111 | /* The number of registers of the target machine. */ 112 | #define MAXR 4 113 | 114 | /* Number of commandline-options the code-generator accepts. */ 115 | #define MAXGF 10 116 | 117 | /* If this is set to zero vbcc will not generate ICs where the */ 118 | /* target operand is the same as the 2nd source operand. */ 119 | /* This can sometimes simplify the code-generator, but usually */ 120 | /* the code is better if the code-generator allows it. */ 121 | #define USEQ2ASZ 1 122 | 123 | /* This specifies the smallest integer type that can be added to a */ 124 | /* pointer. */ 125 | #define MINADDI2P CHAR 126 | 127 | /* If the bytes of an integer are ordered most significant byte */ 128 | /* byte first and then decreasing set BIGENDIAN to 1. */ 129 | #define BIGENDIAN 1 130 | 131 | /* If the bytes of an integer are ordered lest significant byte */ 132 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 133 | #define LITTLEENDIAN 0 134 | 135 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 136 | 137 | /* If switch-statements should be generated as a sequence of */ 138 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 139 | /* This can yield better code on some machines. */ 140 | #define SWITCHSUBS 1 141 | 142 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 143 | /* with length known at compile-time will be inlined using an */ 144 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 145 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 146 | #define INLINEMEMCPY 1024 147 | 148 | #define HAVE_REGPARMS 1 149 | 150 | struct reg_handle { 151 | int gpr; 152 | }; 153 | 154 | /* We use unsigned int as size_t rather than unsigned long which */ 155 | /* is the default setting. */ 156 | #define HAVE_INT_SIZET 1 157 | 158 | /* We have register pairs. */ 159 | #define HAVE_REGPAIRS 0 160 | 161 | /* We keep track of all registers modified by a function. */ 162 | #define HAVE_REGS_MODIFIED 1 163 | 164 | #define HAVE_TARGET_RALLOC 1 165 | #define cost_load_reg(r,v) 4 166 | #define cost_save_reg(r,v) 4 167 | #define cost_move_reg(i,j) 2 168 | #define cost_pushpop_reg(r) 2 169 | 170 | /* size of buffer for asm-output */ 171 | #define EMIT_BUF_LEN 1024 /* should be enough */ 172 | /* number of asm-output lines buffered */ 173 | #define EMIT_BUF_DEPTH 4 174 | 175 | /* We have asm_peephole to optimize assembly-output */ 176 | #define HAVE_TARGET_PEEPHOLE 1 177 | 178 | /* We have some target-specific variable attributes. */ 179 | #define HAVE_TARGET_ATTRIBUTES 1 180 | 181 | /* We use builtin libcalls for some operations */ 182 | #define HAVE_LIBCALLS 1 183 | 184 | /* We prefer BNE rather than BGT. */ 185 | #define HAVE_WANTBNE 1 186 | -------------------------------------------------------------------------------- /machines/i386/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSLE S16BSBE 4 | S16BULE S16BUBE 5 | S32BSLE S32BSBE 6 | S32BULE S32BUBE 7 | S32BSLE S32BSBE 8 | S32BULE S32BUBE 9 | S64BSLE S64BSBE 10 | S64BULE S64BUBE 11 | S32BIEEELE 12 | S64BIEEELE 13 | S64BIEEELE 14 | S32BULE S32BUBE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/i386/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for an Intel 386 or higher. */ 2 | 3 | #include "dt.h" 4 | 5 | /* We have extended types! What we have to do to support them: */ 6 | /* - #define HAVE_EXT_TYPES 7 | - #undef all standard types 8 | - #define all standard types plus new types 9 | - write eval_const and insert_const 10 | - write typedefs for zmax and zumax 11 | - write typname[] 12 | - write conv_typ() 13 | - optionally #define ISPOINTER, ISARITH, ISINT etc. 14 | - optionally #define HAVE_TGT_PRINTVAL and write printval 15 | - optionally #define POINTER_TYPE 16 | - optionally #define HAVE_TGT_FALIGN and write falign 17 | - optionally #define HAVE_TGT_SZOF and write szof 18 | - optionally add functions for attribute-handling 19 | */ 20 | #define HAVE_EXT_TYPES 1 21 | 22 | #define HAVE_TGT_PRINTVAL 23 | 24 | #undef CHAR 25 | #undef SHORT 26 | #undef INT 27 | #undef LONG 28 | #undef LLONG 29 | #undef FLOAT 30 | #undef DOUBLE 31 | #undef LDOUBLE 32 | #undef VOID 33 | #undef POINTER 34 | #undef ARRAY 35 | #undef STRUCT 36 | #undef UNION 37 | #undef ENUM 38 | #undef FUNKT 39 | #undef MAXINT 40 | #undef MAX_TYPE 41 | 42 | #define CHAR 1 43 | #define SHORT 2 44 | #define BSHORT 3 45 | #define INT 4 46 | #define BINT 5 47 | #define LONG 6 48 | #define BLONG 7 49 | #define LLONG 8 50 | #define BLLONG 9 51 | #define FLOAT 10 52 | #define BFLOAT 11 53 | #define DOUBLE 12 54 | #define BDOUBLE 13 55 | #define LDOUBLE 14 56 | #define BLDOUBLE 15 57 | #define VOID 16 58 | #define POINTER 17 59 | #define BPOINTER 18 60 | #define ARRAY 19 61 | #define STRUCT 20 62 | #define UNION 21 63 | #define ENUM 22 64 | #define FUNKT 23 65 | 66 | #define MAXINT 24 /* should not be accesible to application */ 67 | 68 | #define MAX_TYPE MAXINT 69 | 70 | #define ISPOINTER(x) ((x&NQ)==POINTER||(x&NQ)==BPOINTER) 71 | #define ISSCALAR(x) ((x&NQ)>=CHAR&&(x&NQ)<=BPOINTER) 72 | #define ISINT(x) ((x&NQ)>=CHAR&&(x&NQ)<=BLLONG) 73 | 74 | typedef zllong zmax; 75 | typedef zullong zumax; 76 | 77 | union atyps{ 78 | zchar vchar; 79 | zuchar vuchar; 80 | zshort vshort; 81 | zushort vushort; 82 | zint vint; 83 | zuint vuint; 84 | zlong vlong; 85 | zulong vulong; 86 | zllong vllong; 87 | zullong vullong; 88 | zmax vmax; 89 | zumax vumax; 90 | zfloat vfloat; 91 | zdouble vdouble; 92 | zldouble vldouble; 93 | }; 94 | 95 | /* This struct can be used to implement machine-specific */ 96 | /* addressing-modes. */ 97 | /* Not used in this code-generrator. */ 98 | struct AddressingMode{ 99 | int mode; 100 | int base; 101 | int idx; 102 | int scal; 103 | zmax offset; 104 | struct Var *v; 105 | }; 106 | 107 | /* The number of registers of the target machine. */ 108 | #define MAXR 18 109 | 110 | /* Number of commandline-options the code-generator accepts. */ 111 | #define MAXGF 10 112 | 113 | /* If this is set to zero vbcc will not generate ICs where the */ 114 | /* target operand is the same as the 2nd source operand. */ 115 | /* This can sometimes simplify the code-generator, but usually */ 116 | /* the code is better if the code-generator allows it. */ 117 | #define USEQ2ASZ 1 118 | 119 | /* This specifies the smallest integer type that can be added to a */ 120 | /* pointer. */ 121 | #define MINADDI2P INT 122 | #define MAXADDI2P LONG 123 | 124 | /* If the bytes of an integer are ordered most significant byte */ 125 | /* byte first and then decreasing set BIGENDIAN to 1. */ 126 | #define BIGENDIAN 0 127 | 128 | /* If the bytes of an integer are ordered lest significant byte */ 129 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 130 | #define LITTLEENDIAN 1 131 | 132 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 133 | 134 | /* If switch-statements should be generated as a sequence of */ 135 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 136 | /* This can yield better code on some machines. */ 137 | #define SWITCHSUBS 0 138 | 139 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 140 | /* with length known at compile-time will be inlined using an */ 141 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 142 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 143 | #define INLINEMEMCPY 1024 144 | 145 | /* We keep track of all registers modified by a function. */ 146 | #define HAVE_REGS_MODIFIED 1 147 | 148 | /* size of buffer for asm-output */ 149 | #define EMIT_BUF_LEN 1024 /* should be enough */ 150 | /* number of asm-output lines buffered */ 151 | #define EMIT_BUF_DEPTH 4 152 | 153 | /* We have no asm_peephole to optimize assembly-output */ 154 | #define HAVE_TARGET_PEEPHOLE 0 155 | 156 | #define JUMP_TABLE_DENSITY 0.8 157 | #define JUMP_TABLE_LENGTH 4 158 | 159 | /* We use builtin libcalls for some operations */ 160 | #define HAVE_LIBCALLS 1 161 | 162 | /* support for variable-length arrays */ 163 | #define ALLOCVLA_REG 1 164 | #define ALLOCVLA_INLINEASM "\tsubl\t%eax,%esp\n\tandl\t$-5,%esp\n\tmovl\t%esp,%eax" 165 | /* TODO: find a better solution some time */ 166 | #define FREEVLA_REG 0 167 | #define FREEVLA_INLINEASM "\tmovl\t(%esp),%esp\n\tsubl\t$4,%esp" 168 | #define OLDSPVLA_INLINEASM "\tmovl\t%esp,%eax" 169 | #define FPVLA_REG 7 170 | 171 | /* do not create CONVERT_ICs from floats to unsigned integers */ 172 | #define AVOID_FLOAT_TO_UNSIGNED 1 173 | 174 | /* do not create CONVERT_ICs from unsigned integers to floats */ 175 | #define AVOID_UNSIGNED_TO_FLOAT 1 176 | -------------------------------------------------------------------------------- /machines/m68k/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S32BSBE S32BSLE 6 | S32BUBE S32BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S32BUBE S32BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/m68k/machine.h: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (m68k/machine.h) $Revision: 1.9 $ */ 2 | 3 | #include "dt.h" 4 | 5 | /* This struct can be used to implement machine-specific */ 6 | /* addressing-modes. */ 7 | typedef struct AddressingMode{ 8 | int basereg; 9 | long dist; 10 | int skal; 11 | int dreg; 12 | } AddressingMode; 13 | 14 | /* The number of registers of the target machine. */ 15 | #define MAXR 28 16 | 17 | /* Number of commandline-options the code-generator accepts. */ 18 | #define MAXGF 30 19 | 20 | /* If this is set to zero vbcc will not generate ICs where the */ 21 | /* target operand is the same as the 2nd source operand. */ 22 | /* This can sometimes simplify the code-generator, but usually */ 23 | /* the code is better if the code-generator allows it. */ 24 | #define USEQ2ASZ 1 25 | 26 | /* This specifies the smallest integer type that can be added to a */ 27 | /* pointer. */ 28 | extern int MINADDI2P; 29 | 30 | /* This specifies the smallest unsigned type that can be added to a */ 31 | /* pointer. */ 32 | #define MINADDUI2P (UNSIGNED|INT) 33 | 34 | 35 | /* This specifies the biggest integer type that can be added to a */ 36 | /* pointer. */ 37 | #define MAXADDI2P LONG 38 | 39 | /* If the bytes of an integer are ordered most significant byte */ 40 | /* byte first and then decreasing set BIGENDIAN to 1. */ 41 | #define BIGENDIAN 1 42 | 43 | /* If the bytes of an integer are ordered lest significant byte */ 44 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 45 | #define LITTLEENDIAN 0 46 | 47 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 48 | 49 | /* If switch-statements should be generated as a sequence of */ 50 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 51 | /* This can yield better code on some machines. */ 52 | #define SWITCHSUBS 1 53 | 54 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 55 | /* with length known at compile-time will be inlined using an */ 56 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 57 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 58 | #define INLINEMEMCPY 256 59 | 60 | /* We have some target-specific variable attributes. */ 61 | #define HAVE_TARGET_ATTRIBUTES 1 62 | 63 | /* We keep track of all registers modified by a function. */ 64 | #define HAVE_REGS_MODIFIED 1 65 | 66 | #define HAVE_TARGET_RALLOC 1 67 | #define cost_move_reg(x,y) 1 68 | #define cost_load_reg(x,y) 2 69 | #define cost_save_reg(x,y) 2 70 | #define cost_pushpop_reg(x) 2 71 | 72 | /* size of buffer for asm-output */ 73 | #define EMIT_BUF_LEN 1024 /* should be enough */ 74 | /* number of asm-output lines buffered */ 75 | #define EMIT_BUF_DEPTH 4 76 | 77 | /* We have no asm_peephole to optimize assembly-output */ 78 | #define HAVE_TARGET_PEEPHOLE 1 79 | 80 | /* we have a mark_eff_ics function */ 81 | #define HAVE_TARGET_EFF_IC 1 82 | 83 | /* we have register-pairs */ 84 | #define HAVE_REGPAIRS 1 85 | 86 | #define HAVE_REGPARMS 1 87 | 88 | struct reg_handle { 89 | int dr,ar,fr; 90 | }; 91 | 92 | 93 | #define JUMP_TABLE_DENSITY 0.8 94 | #define JUMP_TABLE_LENGTH 8 95 | 96 | /* support for variable-length arrays */ 97 | #define ALLOCVLA_REG 9 98 | #define ALLOCVLA_INLINEASM "\taddq.l\t#3,d0\n\tand.b\t#252,d0\n\tsub.l\td0,a7\n\tmove.l\ta7,d0" 99 | #define FREEVLA_REG 0 100 | /* TODO: find a better solution some time */ 101 | #define FREEVLA_INLINEASM "\tmove.l\t(a7),a7\n\tsubq.l\t#4,a7" 102 | #define OLDSPVLA_INLINEASM "\tmove.l\ta7,d0" 103 | #define FPVLA_REG 6 104 | 105 | /* We use builtin libcalls for some operations */ 106 | #define HAVE_LIBCALLS 1 107 | 108 | /* We have target-specific pragmas */ 109 | #define HAVE_TARGET_PRAGMAS 110 | 111 | /* We have a target-specific add_var hook */ 112 | #define HAVE_TARGET_VARHOOK 113 | -------------------------------------------------------------------------------- /machines/m68ks/machine.c: -------------------------------------------------------------------------------- 1 | /* Code generator for Motorola 680x0 CPUs. Supports 68000-68060+68881/2 */ 2 | /* and ColdFire. */ 3 | /* PhxAss and the GNU assembler is supported. */ 4 | 5 | /* stub for ST version with 16bit int */ 6 | 7 | #include "machines/m68k/machine.c" 8 | -------------------------------------------------------------------------------- /machines/m68ks/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S16BSBE S16BSLE 6 | S16BUBE S16BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S32BUBE S32BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/m68ks/machine.h: -------------------------------------------------------------------------------- 1 | /* Code generator for Motorola 680x0 CPUs. Supports 68000-68060+68881/2 */ 2 | /* and ColdFire. */ 3 | /* PhxAss and the GNU assembler is supported. */ 4 | 5 | /* stub for ST version with 16bit int */ 6 | 7 | #define M68K_16BIT_INT 8 | 9 | #define PTRDIFF_T(x) LONG 10 | 11 | #include "dt.h" 12 | #include "../m68k/machine.h" 13 | -------------------------------------------------------------------------------- /machines/ppc/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S32BSBE S32BSLE 6 | S32BUBE S32BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S32BUBE S32BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/ppc/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for a PowerPC */ 2 | 3 | #include "dt.h" 4 | 5 | /* This struct can be used to implement machine-specific */ 6 | /* addressing-modes. */ 7 | /* Not used in this code-generrator. */ 8 | struct AddressingMode{ 9 | int flags; 10 | int base; 11 | long offset; 12 | }; 13 | 14 | /* The number of registers of the target machine. */ 15 | #define MAXR 87 16 | 17 | /* Number of commandline-options the code-generator accepts. */ 18 | #define MAXGF 30 19 | 20 | /* If this is set to zero vbcc will not generate ICs where the */ 21 | /* target operand is the same as the 2nd source operand. */ 22 | /* This can sometimes simplify the code-generator, but usually */ 23 | /* the code is better if the code-generator allows it. */ 24 | #define USEQ2ASZ 1 25 | 26 | /* This specifies the smallest integer type that can be added to a */ 27 | /* pointer. */ 28 | #define MINADDI2P INT 29 | 30 | /* This specifies the largest integer type that can be added to a */ 31 | /* pointer. */ 32 | #define MAXADDI2P LONG 33 | 34 | /* If the bytes of an integer are ordered most significant byte */ 35 | /* byte first and then decreasing set BIGENDIAN to 1. */ 36 | #define BIGENDIAN 1 37 | 38 | /* If the bytes of an integer are ordered lest significant byte */ 39 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 40 | #define LITTLEENDIAN 0 41 | 42 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 43 | 44 | /* If switch-statements should be generated as a sequence of */ 45 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 46 | /* This can yield better code on some machines. */ 47 | #define SWITCHSUBS 0 48 | 49 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 50 | /* with length known at compile-time will be inlined using an */ 51 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 52 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 53 | #define INLINEMEMCPY 256 54 | 55 | /* Parameters are sometimes passed in registers without __reg. */ 56 | #define HAVE_REGPARMS 1 57 | 58 | /* Parameters on the stack should be pushed in order rather than */ 59 | /* in reverse order. */ 60 | #define ORDERED_PUSH 1 61 | 62 | /* Structure for reg_parm(). */ 63 | struct reg_handle{ 64 | unsigned long gregs; 65 | unsigned long fregs; 66 | }; 67 | 68 | /* We have some target-specific variable attributes. */ 69 | #define HAVE_TARGET_ATTRIBUTES 70 | 71 | /* We have target-specific pragmas */ 72 | #define HAVE_TARGET_PRAGMAS 73 | 74 | /* We keep track of all registers modified by a function. */ 75 | #define HAVE_REGS_MODIFIED 1 76 | 77 | #define HAVE_TARGET_RALLOC 1 78 | #define cost_move_reg(x,y) 1 79 | #define cost_load_reg(x,y) 2 80 | #define cost_save_reg(x,y) 2 81 | #define cost_pushpop_reg(x) 3 82 | 83 | /* size of buffer for asm-output */ 84 | #define EMIT_BUF_LEN 1024 /* should be enough */ 85 | /* number of asm-output lines buffered */ 86 | #define EMIT_BUF_DEPTH 4 87 | 88 | /* We have no asm_peephole to optimize assembly-output */ 89 | #define HAVE_TARGET_PEEPHOLE 0 90 | 91 | /* we have a mark_eff_ics function */ 92 | #define HAVE_TARGET_EFF_IC 1 93 | 94 | /* we have register-pairs */ 95 | #define HAVE_REGPAIRS 1 96 | 97 | #define JUMP_TABLE_DENSITY 0.8 98 | #define JUMP_TABLE_LENGTH 12 99 | 100 | /* This type will be added to every IC. Can be used by the cg. */ 101 | #define HAVE_EXT_IC 1 102 | struct ext_ic { 103 | int setcc; 104 | }; 105 | 106 | /* OSEK support */ 107 | #define HAVE_OSEK 1 108 | 109 | /* We use builtin libcalls for some operations */ 110 | #define HAVE_LIBCALLS 1 111 | 112 | /* support for variable-length arrays */ 113 | #define ALLOCVLA_REG 4 114 | #if 0 115 | #define ALLOCVLA_INLINEASM "\tlwz\t0,0(1)\n"\ 116 | "\taddi\t3,3,7\n"\ 117 | "\tsrwi\t3,3,3\n"\ 118 | "\tslwi\t3,3,3\n"\ 119 | "\tneg\t11,3\n"\ 120 | "\tsub\t3,1,3\n"\ 121 | "\tsubi\t11,11,8\n"\ 122 | "\tstwux\t0,1,11" 123 | #endif 124 | #define ALLOCVLA_INLINEASM "\tlwz\t0,0(1)\n"\ 125 | "\tneg\t3,3\n"\ 126 | "\tsrwi\t3,3,3\n"\ 127 | "\tslwi\t3,3,3\n"\ 128 | "\tstwux\t0,1,3\n"\ 129 | "\taddi\t3,1,____fo" 130 | #define FREEVLA_REG 6 131 | #define FREEVLA_INLINEASM "\tlwz\t0,0(1)\n"\ 132 | "\tmr\t1,5\n"\ 133 | "\tstw\t0,0(1)" 134 | #define OLDSPVLA_INLINEASM "\tmr\t3,1" 135 | #define FPVLA_REG 32 136 | -------------------------------------------------------------------------------- /machines/ppc/schedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vscppc 3 | * 4 | * vbcc PowerPC scheduler 5 | * (C)1998 by Frank Wille 6 | * 7 | * vscppc is freeware and part of the portable and retargetable ANSI C 8 | * compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann. 9 | * vscppc may be freely redistributed as long as no modifications are 10 | * made and nothing is charged for it. Non-commercial usage is allowed 11 | * without any restrictions. 12 | * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE 13 | * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR. 14 | * 15 | * History: 16 | * V0.3 20-Jul-98 17 | * Differentiation between 603 and 604. Now, scheduling takes 18 | * place with regard to the real PowerPC architecture. 19 | * V0.1 10-Jul-98 20 | * vscppc seems to be stable enough, after some tests. 21 | * However, it still needs a lot of fine tuning. 22 | * A differentiation between the PPC CPUs (603e, 604e) is missing. 23 | * V0.0 09-Jul-98 24 | * File created. 25 | * 26 | */ 27 | 28 | #define PIPES 7 /* the max. number of pipes, as required by the 604 */ 29 | 30 | /* Pipe Names 603 */ 31 | #define BPU 0 /* Branch Prediction Unit */ 32 | #define SRU 1 /* Special Reg. Unit */ 33 | #define IU 2 /* Integer Unit */ 34 | #define FPU 5 /* Floating Point Unit */ 35 | #define LSU 6 /* Load Store Unit */ 36 | 37 | /* Pipe Names 604 */ 38 | #define CRU 1 /* Condition Register Unit */ 39 | #define SCIU1 2 /* Single Cycle Integer Unit #1 */ 40 | #define SCIU2 3 /* Single Cycle Integer Unit #2 */ 41 | #define MCIU 4 /* Multiple Cycle Integer Unit */ 42 | 43 | 44 | #define REGS 76 /* 32 GPR, 32 FPR, 8 CCR, LR, CTR, XER, FPSCR */ 45 | 46 | /* REG-offsets */ 47 | #define GPR 0 48 | #define FPR 32 49 | #define CCR 64 50 | #define XER 72 51 | #define CTR 73 52 | #define LR 74 53 | #define FPSCR 75 54 | -------------------------------------------------------------------------------- /machines/qnice/machine.dt: -------------------------------------------------------------------------------- 1 | S16BSLE S16BSBE 2 | S16BULE S16BUBE 3 | S16BSLE S16BSBE 4 | S16BULE S16BUBE 5 | S16BSLE S16BSBE 6 | S16BULE S16BUBE 7 | S32BSLE S32BSBE 8 | S32BULE S32BUBE 9 | S64BSLE S64BSBE 10 | S64BULE S64BUBE 11 | S32BIEEELE 12 | S64BIEEELE 13 | S64BIEEELE 14 | S16BULE S16BUBE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/qnice/machine.h: -------------------------------------------------------------------------------- 1 | /* Example of a code-generator for qnice cpu.*/ 2 | 3 | #include "dt.h" 4 | 5 | /* We have extended types! What we have to do to support them: */ 6 | /* - #define HAVE_EXT_TYPES 7 | - #undef all standard types 8 | - #define all standard types plus new types 9 | - write eval_const and insert_const 10 | - write typedefs for zmax and zumax 11 | - write typname[] 12 | - write conv_typ() 13 | - optionally #define ISPOINTER, ISARITH, ISINT etc. 14 | - optionally #define HAVE_TGT_PRINTVAL and write printval 15 | - optionally #define POINTER_TYPE 16 | - optionally #define HAVE_TGT_FALIGN and write falign 17 | - optionally #define HAVE_TGT_SZOF and write szof 18 | - optionally add functions for attribute-handling 19 | */ 20 | #define HAVE_EXT_TYPES 1 21 | 22 | #define HAVE_TGT_PRINTVAL 23 | 24 | #undef CHAR 25 | #undef SHORT 26 | #undef INT 27 | #undef LONG 28 | #undef LLONG 29 | #undef FLOAT 30 | #undef DOUBLE 31 | #undef LDOUBLE 32 | #undef VOID 33 | #undef POINTER 34 | #undef ARRAY 35 | #undef STRUCT 36 | #undef UNION 37 | #undef ENUM 38 | #undef FUNKT 39 | #undef BOOL 40 | #undef MAXINT 41 | #undef MAX_TYPE 42 | 43 | #define BIT 1 44 | #define CHAR 2 45 | #define SHORT 3 46 | #define INT 4 47 | #define LONG 5 48 | #define LLONG 6 49 | #define FLOAT 7 50 | #define DOUBLE 8 51 | #define LDOUBLE 9 52 | #define VOID 10 53 | #define NPOINTER 11 54 | #define FPOINTER 12 55 | #define HPOINTER 13 56 | #define ARRAY 14 57 | #define STRUCT 15 58 | #define UNION 16 59 | #define ENUM 17 60 | #define FUNKT 18 61 | #define BOOL 19 62 | 63 | #define MAXINT 20 64 | 65 | #define MAX_TYPE MAXINT 66 | 67 | #define POINTER_TYPE(x) pointer_type(x) 68 | extern int pointer_type(); 69 | #define ISPOINTER(x) ((x&NQ)>=NPOINTER&&(x&NQ)<=HPOINTER) 70 | #define ISSCALAR(x) ((x&NQ)>=BIT&&(x&NQ)<=HPOINTER) 71 | #define ISINT(x) ((x&NQ)>=BIT&&(x&NQ)<=LLONG) 72 | #define PTRDIFF_T(x) ((x)==HPOINTER?LONG:INT) 73 | 74 | typedef zllong zmax; 75 | typedef zullong zumax; 76 | 77 | union atyps{ 78 | zchar vchar; 79 | zuchar vuchar; 80 | zshort vshort; 81 | zushort vushort; 82 | zint vint; 83 | zuint vuint; 84 | zlong vlong; 85 | zulong vulong; 86 | zllong vllong; 87 | zullong vullong; 88 | zmax vmax; 89 | zumax vumax; 90 | zfloat vfloat; 91 | zdouble vdouble; 92 | zldouble vldouble; 93 | }; 94 | 95 | /* This struct can be used to implement machine-specific */ 96 | /* addressing-modes. */ 97 | struct AddressingMode{ 98 | int flags; 99 | int base; 100 | }; 101 | 102 | /* This type will be added to every IC. Can be used by the cg. */ 103 | #define HAVE_EXT_IC 0 104 | struct ext_ic { 105 | int flags; 106 | int r; 107 | long offset; 108 | }; 109 | 110 | /* The number of registers of the target machine. */ 111 | #define MAXR 22 112 | 113 | /* Number of commandline-options the code-generator accepts. */ 114 | #define MAXGF 20 115 | 116 | /* If this is set to zero vbcc will not generate ICs where the */ 117 | /* target operand is the same as the 2nd source operand. */ 118 | /* This can sometimes simplify the code-generator, but usually */ 119 | /* the code is better if the code-generator allows it. */ 120 | #define USEQ2ASZ 1 121 | 122 | /* This specifies the smallest integer type that can be added to a */ 123 | /* pointer. */ 124 | #define MINADDI2P CHAR 125 | 126 | /* If the bytes of an integer are ordered most significant byte */ 127 | /* byte first and then decreasing set BIGENDIAN to 1. */ 128 | #define BIGENDIAN 0 129 | 130 | /* If the bytes of an integer are ordered lest significant byte */ 131 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 132 | #define LITTLEENDIAN 1 133 | 134 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 135 | 136 | /* If switch-statements should be generated as a sequence of */ 137 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 138 | /* This can yield better code on some machines. */ 139 | #define SWITCHSUBS 0 140 | 141 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 142 | /* with length known at compile-time will be inlined using an */ 143 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 144 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 145 | #define INLINEMEMCPY 1024 146 | 147 | #define HAVE_REGPARMS 1 148 | 149 | struct reg_handle { 150 | int gpr; 151 | }; 152 | 153 | /* We use unsigned int as size_t rather than unsigned long which */ 154 | /* is the default setting. */ 155 | #define HAVE_INT_SIZET 1 156 | 157 | /* We have register pairs. */ 158 | #define HAVE_REGPAIRS 1 159 | 160 | /* We keep track of all registers modified by a function. */ 161 | #define HAVE_REGS_MODIFIED 1 162 | 163 | #define HAVE_TARGET_RALLOC 1 164 | #define cost_load_reg(r,v) 4 165 | #define cost_save_reg(r,v) 4 166 | #define cost_move_reg(i,j) 2 167 | #define cost_pushpop_reg(r) 2 168 | 169 | /* size of buffer for asm-output */ 170 | #define EMIT_BUF_LEN 1024 /* should be enough */ 171 | /* number of asm-output lines buffered */ 172 | #define EMIT_BUF_DEPTH 4 173 | 174 | /* We have asm_peephole to optimize assembly-output */ 175 | #define HAVE_TARGET_PEEPHOLE 1 176 | 177 | /* We have some target-specific variable attributes. */ 178 | #define HAVE_TARGET_ATTRIBUTES 1 179 | 180 | /* We use builtin libcalls for some operations */ 181 | #define HAVE_LIBCALLS 1 182 | 183 | #define HAVE_WANTBNE 1 184 | 185 | #define HAVE_POF2OPT 1 186 | -------------------------------------------------------------------------------- /machines/vidcore/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSBE S16BSLE 4 | S16BUBE S16BULE 5 | S32BSBE S32BSLE 6 | S32BUBE S32BULE 7 | S32BSBE S32BSLE 8 | S32BUBE S32BULE 9 | S64BSBE S64BSLE 10 | S64BUBE S64BULE 11 | S32BIEEEBE 12 | S64BIEEEBE 13 | S64BIEEEBE 14 | S32BUBE S32BULE 15 | 16 | 17 | -------------------------------------------------------------------------------- /machines/vidcore/machine.h: -------------------------------------------------------------------------------- 1 | /* Backend for VideoCore IV 2 | (c) in 2013 by Volker Barthelmann 3 | */ 4 | 5 | /* buil-time configurable options: */ 6 | #define NUM_GPRS 48 7 | 8 | #include "dt.h" 9 | 10 | 11 | /* This struct can be used to implement machine-specific */ 12 | /* addressing-modes. */ 13 | /* Currently possible are (const,gpr) and (gpr,gpr) */ 14 | struct AddressingMode{ 15 | int flags; 16 | int base; 17 | long offset; 18 | }; 19 | 20 | /* The number of registers of the target machine. */ 21 | #define MAXR 48 22 | 23 | /* Number of commandline-options the code-generator accepts. */ 24 | #define MAXGF 20 25 | 26 | /* If this is set to zero vbcc will not generate ICs where the */ 27 | /* target operand is the same as the 2nd source operand. */ 28 | /* This can sometimes simplify the code-generator, but usually */ 29 | /* the code is better if the code-generator allows it. */ 30 | #define USEQ2ASZ 0 31 | 32 | /* This specifies the smallest integer type that can be added to a */ 33 | /* pointer. */ 34 | #define MINADDI2P INT 35 | 36 | /* This specifies the smallest integer type that can be added to a */ 37 | /* pointer. */ 38 | #define MAXADDI2P INT 39 | 40 | /* If the bytes of an integer are ordered most significant byte */ 41 | /* byte first and then decreasing set BIGENDIAN to 1. */ 42 | #define BIGENDIAN 0 43 | 44 | /* If the bytes of an integer are ordered lest significant byte */ 45 | /* byte first and then increasing set LITTLEENDIAN to 1. */ 46 | #define LITTLEENDIAN 1 47 | 48 | /* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */ 49 | 50 | /* If switch-statements should be generated as a sequence of */ 51 | /* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */ 52 | /* This can yield better code on some machines. */ 53 | #define SWITCHSUBS 1 54 | 55 | /* In optimizing compilation certain library memcpy/strcpy-calls */ 56 | /* with length known at compile-time will be inlined using an */ 57 | /* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */ 58 | /* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */ 59 | #define INLINEMEMCPY 1024 60 | 61 | /* Parameters are sometimes passed in registers without __reg. */ 62 | #define HAVE_REGPARMS 1 63 | 64 | /* Parameters on the stack should be pushed in order rather than */ 65 | /* in reverse order. */ 66 | #undef ORDERED_PUSH 67 | 68 | /* Structure for reg_parm(). */ 69 | struct reg_handle{ 70 | unsigned long gregs; 71 | }; 72 | 73 | /* We have some target-specific variable attributes. */ 74 | #define HAVE_TARGET_ATTRIBUTES 75 | 76 | /* We have target-specific pragmas */ 77 | #define HAVE_TARGET_PRAGMAS 78 | 79 | /* We keep track of all registers modified by a function. */ 80 | #define HAVE_REGS_MODIFIED 1 81 | 82 | /* We have a implement our own cost-functions to adapt 83 | register-allocation */ 84 | #define HAVE_TARGET_RALLOC 1 85 | #define cost_move_reg(x,y) 1 86 | #define cost_load_reg(x,y) 2 87 | #define cost_save_reg(x,y) 2 88 | #define cost_pushpop_reg(x) 3 89 | 90 | /* size of buffer for asm-output, this can be used to do 91 | peephole-optimizations of the generated assembly-output */ 92 | #define EMIT_BUF_LEN 1024 /* should be enough */ 93 | /* number of asm-output lines buffered */ 94 | #define EMIT_BUF_DEPTH 4 95 | 96 | /* We have no asm_peephole to optimize assembly-output */ 97 | #define HAVE_TARGET_PEEPHOLE 0 98 | 99 | /* we do not have a mark_eff_ics function, this is used to prevent 100 | optimizations on code which can already be implemented by efficient 101 | assembly */ 102 | #undef HAVE_TARGET_EFF_IC 103 | 104 | /* we only need the standard data types (no bit-types, different pointers 105 | etc.) */ 106 | #undef HAVE_EXT_TYPES 107 | #undef HAVE_TGT_PRINTVAL 108 | 109 | /* we do not need extra elements in the IC */ 110 | #undef HAVE_EXT_IC 111 | 112 | /* we do use unsigned int as size_t (but unsigned long, the default) */ 113 | #define HAVE_INT_SIZET 1 114 | 115 | /* we need register-pairs */ 116 | #define HAVE_REGPAIRS 1 117 | 118 | 119 | /* do not create CONVERT ICs from integers smaller than int to floats */ 120 | #define MIN_INT_TO_FLOAT_TYPE INT 121 | 122 | /* do not create CONVERT ICs from floats to ints smaller than int */ 123 | #define MIN_FLOAT_TO_INT_TYPE INT 124 | 125 | /* do not create CONVERT_ICs from floats to unsigned integers */ 126 | #define AVOID_FLOAT_TO_UNSIGNED 1 127 | 128 | /* do not create CONVERT_ICs from unsigned integers to floats */ 129 | #define AVOID_UNSIGNED_TO_FLOAT 0 130 | 131 | #define HAVE_LIBCALLS 1 132 | -------------------------------------------------------------------------------- /machines/z/machine.dt: -------------------------------------------------------------------------------- 1 | S8BS 2 | S8BU 3 | S16BSLE S16BSBE 4 | S16BULE S16BUBE 5 | S16BSLE S16BSBE 6 | S16BULE S16BUBE 7 | S32BSLE S32BSBE 8 | S32BULE S32BUBE 9 | S64BSLE S64BSBE 10 | S64BULE S64BUBE 11 | S32BIEEEBE S32BIEEELE 12 | S64BIEEEBE S64BIEEELE 13 | S64BIEEEBE S64BIEEELE 14 | S16BULE S16BUBE 15 | -------------------------------------------------------------------------------- /machines/z/machine.h: -------------------------------------------------------------------------------- 1 | /* Z-machine code generator 2 | * David Given 3 | */ 4 | 5 | #include "dt.h" 6 | 7 | /* Machine specific addressing-modes. Not used. */ 8 | 9 | struct AddressingMode{ 10 | int never_used; 11 | }; 12 | 13 | /* The number of registers we support. We don't really have any, but we 14 | * use local variables instead; we have 14. 15 | */ 16 | 17 | #define MAXR 14 18 | 19 | /* Number of command-line options we accept. */ 20 | 21 | #define MAXGF 6 22 | 23 | /* If this is set to zero vbcc will not generate ICs where the target operand 24 | * is the same as the 2nd source operand. This can sometimes simplify the 25 | * code-generator, but usually the code is better if the code-generator allows 26 | * it. 27 | */ 28 | 29 | #define USEQ2ASZ 1 30 | 31 | /* The smallest and largest integer type that can be added to a pointer. */ 32 | 33 | #define MINADDI2P INT 34 | #define MAXADDI2P INT 35 | 36 | /* Big-endian? */ 37 | 38 | #define BIGENDIAN 1 39 | 40 | /* Little-endian? */ 41 | 42 | #define LITTLEENDIAN 0 43 | 44 | /* If switch-statements should be generated as a sequence of SUB,TST,BEQ ICs 45 | * rather than COMPARE,BEQ ICs set this to 1. This can yield better code on 46 | * some machines. 47 | */ 48 | 49 | #define SWITCHSUBS 0 50 | 51 | /* In optimizing compilation certain library memcpy/strcpy-calls with length 52 | * known at compile-time will be inlined using an ASSIGN-IC if the size is less 53 | * or equal to INLINEMEMCPY. The type used for the ASSIGN-IC will be 54 | * UNSIGNED|CHAR. On the Z-machine, memcpy can be done in `hardware' with the 55 | * @copy_table opcode, so always inline them if possible. 56 | */ 57 | 58 | #define INLINEMEMCPY 65536 59 | 60 | /* Do we want to pass parameters to functions in registers? */ 61 | 62 | #define HAVE_REGPARMS 1 63 | 64 | /* If so, how many? Max 7 due to the architecture, but one is always xp. */ 65 | 66 | #define NUM_REGPARMS 6 67 | 68 | /* This structure is used to keep track of where register parameters go. */ 69 | 70 | struct reg_handle { 71 | int reg; 72 | }; 73 | 74 | /* Do we want to use zuint for size_t rather than the default zulong? */ 75 | 76 | #define HAVE_INT_SIZET 1 77 | 78 | /* size of buffer for asm-output */ 79 | #define EMIT_BUF_LEN 1024 /* should be enough */ 80 | /* number of asm-output lines buffered */ 81 | #define EMIT_BUF_DEPTH 4 82 | -------------------------------------------------------------------------------- /mbasic.c: -------------------------------------------------------------------------------- 1 | /* Test-language for vbcc. */ 2 | 3 | #include "supp.h" 4 | 5 | #include 6 | #include 7 | 8 | struct Var *fv; 9 | 10 | struct Typ tint,mfunc; 11 | struct struct_declaration msd; /* initialized to zero */ 12 | 13 | FILE *file; 14 | char *next; 15 | 16 | struct obj expression(),factor(),scalar(); 17 | 18 | void raus(void) 19 | { 20 | while(fv){ 21 | struct Var *m=fv->next; 22 | free(fv); 23 | fv=m; 24 | } 25 | while(first_ic){ 26 | struct IC *m=first_ic->next; 27 | free(first_ic); 28 | first_ic=m; 29 | } 30 | exit(0); 31 | } 32 | void add_IC(struct IC *new) 33 | { 34 | new->next=0; 35 | new->prev=last_ic; 36 | new->change_cnt=new->use_cnt=0; 37 | new->change_list=new->use_list=0; 38 | new->line=0; 39 | new->file=0; 40 | new->q1.am=new->q2.am=new->z.am=0; 41 | if(!last_ic){ 42 | first_ic=new; 43 | }else{ 44 | last_ic->next=new; 45 | } 46 | last_ic=new; 47 | } 48 | struct Var *add_var(char *name,struct Typ *t,int sc) 49 | { 50 | struct Var *v=mymalloc(sizeof(*v)); 51 | v->vtyp=t; 52 | v->storage_class=sc; 53 | v->reg=0; 54 | v->identifier=name; 55 | v->offset=max_offset; 56 | if(sc==AUTO) max_offset=zmadd(max_offset,sizetab[t->flags&NQ]); 57 | v->priority=1; 58 | v->flags=0; 59 | v->next=fv; 60 | v->clist=0; 61 | v->fi=0; 62 | v->inline_copy=0; 63 | v->nesting=1; 64 | fv=v; 65 | return v; 66 | } 67 | struct Var *add_tmp_var(struct Typ *t) 68 | { 69 | return add_var(empty,t,AUTO); 70 | } 71 | struct Var *get_var(char *name) 72 | { 73 | struct Var *v;char *buf; 74 | puts("getvar"); 75 | for(v=fv;v;v=v->next){ 76 | if(!strcmp(name,v->identifier)) return v; 77 | } 78 | buf=mymalloc(strlen(name)+1); 79 | strcpy(buf,name); 80 | return add_var(buf,&tint,AUTO); 81 | } 82 | 83 | char *identifier(void) 84 | { 85 | static char id[1024]; 86 | char *s=id; 87 | puts("identifier"); 88 | while(isalnum(*next)) *s++=*next++; 89 | puts("done"); 90 | return id; 91 | } 92 | struct obj scalar(void) 93 | { 94 | struct obj o; 95 | zmax val; 96 | puts("scalar"); 97 | if(isdigit(*next)){ 98 | o.flags=KONST; 99 | val=l2zm(0L); 100 | while(isdigit(*next)){ 101 | val=zmmult(val,l2zm(10L)); 102 | val=zmadd(val,l2zm((long)(*next-'0'))); 103 | next++; 104 | } 105 | o.val.vint=zm2zi(val); 106 | return o; 107 | } 108 | if(*next=='('){ 109 | next++; 110 | o=expression(); 111 | next++; 112 | return o; 113 | } 114 | o.flags=VAR; 115 | o.val.vmax=l2zm(0L); 116 | o.v=get_var(identifier()); 117 | return o; 118 | } 119 | struct obj factor(void) 120 | { 121 | struct obj o; 122 | struct IC *new; 123 | puts("factor"); 124 | o=scalar(); 125 | while(*next=='*'||*next=='/'){ 126 | new=new_IC(); 127 | if(*next=='*') new->code=MULT; else new->code=DIV; 128 | next++; 129 | new->typf=INT; 130 | new->q1=o; 131 | new->q2=scalar(); 132 | o.flags=VAR; 133 | o.v=add_tmp_var(&tint); 134 | o.val.vmax=l2zm(0L); 135 | new->z=o; 136 | add_IC(new); 137 | } 138 | return o; 139 | } 140 | struct obj expression(void) 141 | { 142 | struct obj o; 143 | struct IC *new; 144 | puts("expression"); 145 | o=factor(); 146 | while(*next=='+'||*next=='-'){ 147 | new=new_IC(); 148 | if(*next=='+') new->code=ADD; else new->code=SUB; 149 | next++; 150 | new->typf=INT; 151 | new->q1=o; 152 | new->q2=factor(); 153 | o.flags=VAR; 154 | o.v=add_tmp_var(&tint); 155 | o.val.vmax=l2zm(0L); 156 | new->z=o; 157 | add_IC(new); 158 | } 159 | return o; 160 | } 161 | void compile(void) 162 | { 163 | struct IC *new; 164 | char line[1024],*s; 165 | struct obj o,last; 166 | puts("compile"); 167 | while(fgets(line,1023,file)){ 168 | next=line; 169 | s=identifier(); 170 | if(*next=='='){ 171 | struct Var *v=get_var(s); 172 | next++; 173 | o=expression(); 174 | new=new_IC(); 175 | new->code=ASSIGN; 176 | new->typf=INT; 177 | new->q1=o; 178 | new->z.flags=VAR; 179 | new->z.v=v; 180 | new->z.val.vmax=l2zm(0L); 181 | new->q2.flags=0; 182 | new->q2.val.vmax=sizetab[INT]; 183 | last=new->z; 184 | add_IC(new); 185 | continue; 186 | } 187 | } 188 | new=new_IC(); 189 | new->code=SETRETURN; 190 | new->typf=INT; 191 | new->q1=last; 192 | new->q2.flags=new->z.flags=0; 193 | new->q2.val.vmax=sizetab[INT]; 194 | new->z.reg=freturn(&tint); 195 | if(!new->z.reg) puts("problem!"); 196 | add_IC(new); 197 | } 198 | void error(int n,...) 199 | { 200 | printf("error %d\n",n); 201 | raus(); 202 | } 203 | void savescratch() 204 | {} 205 | 206 | main(int argc,char **argv) 207 | { 208 | struct Var *main; 209 | max_offset=l2zm(0L); 210 | if(!init_cg()) raus(); 211 | tint.flags=INT; 212 | tint.next=0; 213 | mfunc.flags=FUNKT; 214 | mfunc.next=∭ 215 | mfunc.exact=&msd; 216 | main=add_var("main",&mfunc,EXTERN); 217 | file=fopen(argv[1],"r"); 218 | if(!file) {printf("Error opening file\n");raus();} 219 | compile(); 220 | scanf("%ld",&optflags); 221 | pric(stdout,first_ic); 222 | vl1=vl3=0; 223 | vl2=fv; 224 | optimize(optflags,main); 225 | pric(stdout,first_ic); 226 | gen_code(stdout,first_ic,main,max_offset); 227 | raus(); 228 | } 229 | 230 | -------------------------------------------------------------------------------- /minicomp.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "supp.h" 8 | 9 | extern FILE *infile; 10 | #define MAXLEN 1024 11 | extern char tkname[MAXLEN]; 12 | extern int label; 13 | extern int nesting; 14 | extern int local_offset,parm_offset,framesize; 15 | 16 | #define REAL DOUBLE 17 | #define FUNCTION FUNKT 18 | 19 | #define YYERROR_VERBOSE 1 20 | 21 | enum nodeflags { 22 | NVARIABLE,NNUMBER,NADD,NMUL,NSUB,NDIV,NINDEX, 23 | NEQUALS,NLT,NGT,NLEQ,NGEQ,NNEQ,NAND,NOR, 24 | NI2R,NR2I,NASSGN,NCALL,NARG 25 | }; 26 | 27 | extern char *nodename[]; 28 | 29 | typedef struct Typ type; 30 | 31 | typedef struct obj operand; 32 | 33 | typedef struct var { 34 | int nesting; 35 | char *name; 36 | struct Typ *type; 37 | struct var *next; 38 | int offset; 39 | struct Var *vbccvar; 40 | } var; 41 | 42 | #define MAXNESTING 128 43 | extern var *first_var[128]; 44 | 45 | typedef struct { 46 | int flags; 47 | char *name; 48 | } *stype; 49 | 50 | typedef struct mnode { 51 | enum nodeflags flags; 52 | struct mnode *left,*right; 53 | type *type; 54 | var *var; 55 | int ivalue; 56 | double rvalue; 57 | } node; 58 | 59 | void enter_block(void); 60 | void leave_block(void); 61 | void enter_func(char *,type *); 62 | void leave_func(void); 63 | var *find_var(char *,int); 64 | var *add_var(char *,type *); 65 | var *new_temp(int); 66 | char *add_string(char *); 67 | void error(int,...); 68 | void *getmem(size_t); 69 | node *number_node(void); 70 | node *var_node(void); 71 | node *conv_tree(node *,int); 72 | node *binary_node(enum nodeflags,node *,node *); 73 | void print_tree(node *); 74 | void simplify_tree(node *); 75 | void free_tree(node *); 76 | type *new_type(int); 77 | type *new_array(type *,node *); 78 | void return_statement(node *); 79 | void while_statement(node *); 80 | void while_end(void); 81 | void if_statement(node *); 82 | void if_end(void); 83 | void if_else(void); 84 | void assign_statement(node *,node *); 85 | void push_int(int); 86 | int pop_int(void); 87 | void push_name(char *); 88 | char *pop_name(void); 89 | operand *gen_tree(node *); 90 | void gen_cond(node *,int,int); 91 | void gen_label(int); 92 | int push_arg(node *); 93 | void gen_global(char *,int); 94 | -------------------------------------------------------------------------------- /minicomplexer.c: -------------------------------------------------------------------------------- 1 | 2 | FILE *infile; 3 | static int cur_char=' '; 4 | 5 | char tkname[MAXLEN]; 6 | 7 | int yylex() 8 | { 9 | char *p=tkname; 10 | int tmp; 11 | 12 | while(isspace(cur_char)) 13 | cur_char=getc(infile); 14 | 15 | if(isdigit(cur_char)){ 16 | do{ 17 | *p++=cur_char; 18 | cur_char=getc(infile); 19 | }while(isdigit(cur_char)); 20 | if(cur_char=='.'){ 21 | *p++=cur_char; 22 | cur_char=getc(infile); 23 | while(isdigit(cur_char)){ 24 | *p++=cur_char; 25 | cur_char=getc(infile); 26 | } 27 | } 28 | *p++=0; 29 | return TKNUMBER; 30 | } 31 | if(isalpha(cur_char)){ 32 | do{ 33 | *p++=cur_char; 34 | cur_char=getc(infile); 35 | }while(isalnum(cur_char)); 36 | *p++=0; 37 | if(!strcmp(tkname,"int")) 38 | return TKINT; 39 | if(!strcmp(tkname,"real")) 40 | return TKREAL; 41 | if(!strcmp(tkname,"if")) 42 | return TKIF; 43 | if(!strcmp(tkname,"else")) 44 | return TKELSE; 45 | if(!strcmp(tkname,"while")) 46 | return TKWHILE; 47 | if(!strcmp(tkname,"return")) 48 | return TKRETURN; 49 | return TKIDENTIFIER; 50 | } 51 | tmp=cur_char; 52 | cur_char=getc(infile); 53 | if(tmp=='!'&&cur_char=='='){ 54 | cur_char=getc(infile); 55 | return TKNEQ; 56 | } 57 | if(tmp=='<'&&cur_char=='='){ 58 | cur_char=getc(infile); 59 | return TKLEQ; 60 | } 61 | if(tmp=='>'&&cur_char=='='){ 62 | cur_char=getc(infile); 63 | return TKGEQ; 64 | } 65 | if(tmp=='&'&&cur_char=='&'){ 66 | cur_char=getc(infile); 67 | return TKAND; 68 | } 69 | if(tmp=='|'&&cur_char=='|'){ 70 | cur_char=getc(infile); 71 | return TKOR; 72 | } 73 | if(tmp==':'&&cur_char=='='){ 74 | cur_char=getc(infile); 75 | return TKASSIGN; 76 | } 77 | return tmp; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /misra_errors.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kusma/vbcc/191c0da6d49759e88b27e236d9d929645502da3f/misra_errors.h -------------------------------------------------------------------------------- /opt.h: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (opt.h) $Revision: 1.2 $ */ 2 | 3 | #include "supp.h" 4 | 5 | extern int gchanged; /* Merker, ob Optimierungslauf etwas geaendert hat */ 6 | extern int norek; /* diese Funktion wird nicht rekursiv auf */ 7 | extern int nocall; /* diese Funktion kehrt nicht zum Caller zurueck */ 8 | extern int inr; /* number of num_Vars iteration */ 9 | 10 | /* temporary fuer verschiedene Bitvektoren */ 11 | extern bvtype *tmp; 12 | 13 | /* fuer aktive Variablen */ 14 | extern Var **vilist; 15 | extern unsigned int vcount; /* 0..vcount-rcount-1: vars, vcount-rcount..vcount: DREFOBJs */ 16 | extern unsigned int rcount; 17 | extern size_t vsize; 18 | extern bvtype *av_globals,*av_address,*av_statics,*av_drefs; 19 | extern int report_dead_statements; 20 | 21 | /* fuer verfuegbare Definitionen */ 22 | extern unsigned int dcount; 23 | extern size_t dsize; 24 | extern IC **dlist; 25 | extern bvtype **var_defs,**var_undefs; 26 | extern bvtype **defs_kill,**defs_gen; 27 | extern bvtype *rd_defs,*rd_tmp; 28 | extern bvtype *rd_matrix; 29 | #define UNDEF(x) (x+dcount) 30 | 31 | /* fuer verfuegbare Ausdruecke */ 32 | extern IC **elist; 33 | extern unsigned int ecount; 34 | extern size_t esize; 35 | extern bvtype *ae_globals,*ae_address,*ae_statics,*ae_drefs; 36 | 37 | /* fuer verfuegbare Kopien */ 38 | extern unsigned int ccount; 39 | extern size_t csize; 40 | extern IC **clist; 41 | 42 | /* fuer frequency-reduction */ 43 | extern bvtype *inloop,*invariant; 44 | 45 | /* alle Assignments, globaler oder Adr. fuer propagation etc. */ 46 | extern bvtype *cp_globals,*cp_address,*cp_statics,*cp_drefs,*cp_act,*cp_dest; 47 | /* alle Kopieranweisungen, die eine best. Variable als Quelle haben */ 48 | extern bvtype **copies; 49 | 50 | extern int have_alias; 51 | extern int static_cse,dref_cse; 52 | 53 | typedef struct flowgraph{ 54 | IC *start,*end; 55 | struct flowgraph *normalout,*branchout; 56 | struct flowlist *in; 57 | int index; 58 | /* Letzter Block der Schleife, falls Block Start einer Schleife ist */ 59 | struct flowgraph *loopend; 60 | /* Anzahl Funktionsaufrufe im Block/der Schleife */ 61 | int calls,loop_calls; 62 | /* Bitvektoren fuer aktive Variablen, reaching-definitions, 63 | available-expressions und available-copies */ 64 | bvtype *av_in,*av_out,*av_gen,*av_kill; 65 | bvtype *rd_in,*rd_out,*rd_gen,*rd_kill; 66 | bvtype *ae_in,*ae_out,*ae_gen,*ae_kill; 67 | bvtype *cp_in,*cp_out,*cp_gen,*cp_kill; 68 | /* points-to-info */ 69 | bvtype **pt; 70 | /* Registervariablen */ 71 | Var *regv[MAXR+1]; 72 | /* Merker, ob Register gebraucht wurde; MACR+1 Bits */ 73 | bvtype regused[RSIZE/sizeof(bvtype)]; 74 | #ifdef ALEX_REG 75 | int loop_depth; /* schleifentiefe des blocks. Wird nur fuer echte Schleifen gezaehlt. */ 76 | #endif 77 | } flowgraph; 78 | 79 | extern unsigned int basic_blocks; 80 | 81 | typedef struct flowlist{ 82 | flowgraph *graph; 83 | struct flowlist *next; 84 | } flowlist; 85 | 86 | int compare_const(union atyps *q1,union atyps *q2,int t); 87 | int compare_objs(obj *o1,obj *o2,int t); 88 | void simple_regs(void); 89 | void load_simple_reg_parms(void); 90 | void remove_IC_fg(flowgraph *g,IC *p); 91 | 92 | extern int lastlabel; 93 | 94 | flowgraph *new_flowgraph(void); 95 | flowgraph *construct_flowgraph(void); 96 | void print_av(bvtype *bitvector); 97 | void print_rd(bvtype *bitvector); 98 | void print_ae(bvtype *bitvector); 99 | void print_cp(bvtype *bitvector); 100 | void print_flowgraph(flowgraph *g); 101 | void free_flowgraph(flowgraph *g); 102 | void num_vars(void); 103 | void print_vi(void); 104 | void av_change(IC *p,bvtype *use,bvtype *def); 105 | void av_update(IC *,bvtype *); 106 | void active_vars(flowgraph *fg); 107 | int dead_assignments(flowgraph *fg); 108 | void insert_IC(IC *p,IC *new); 109 | void insert_IC_fg(flowgraph *fg,IC *p,IC *new); 110 | void insert_allocreg(flowgraph *fg,IC *p,int code,int reg); 111 | void used_objects(Var *); 112 | void used_clist(type *,const_list *); 113 | 114 | extern Var *lregv[MAXR+1],*first_const,*last_const; 115 | extern flowgraph *lfg; 116 | 117 | extern int report_weird_code,report_suspicious_loops,pointer_call; 118 | 119 | int replace_local_reg(obj *); 120 | void local_regs(flowgraph *); 121 | void local_combine(flowgraph *); 122 | void create_const_vars(flowgraph *); 123 | void free_const_vars(void); 124 | void loop_regs(flowgraph *,int); 125 | void block_regs(flowgraph *); 126 | void insert_saves(flowgraph *); 127 | flowgraph *jump_optimization(void); 128 | void num_defs(void); 129 | void reaching_definitions(flowgraph *); 130 | void rd_change(IC *); 131 | void calc(int c,int t,union atyps *q1,union atyps *q2,union atyps *z,IC *p); 132 | int fold(IC *p); 133 | int peephole(void); 134 | int propagate(IC *p,obj *o,int replace,int global); 135 | int constant_propagation(flowgraph *fg,int global); 136 | int compare_exp(const void *a1,const void *a2); 137 | void num_exp(void); 138 | void available_expressions(flowgraph *fg); 139 | void available_copies(flowgraph *fg); 140 | int cse(flowgraph *fg,int global); 141 | void num_copies(void); 142 | int copy_propagation(flowgraph *fg,int global); 143 | int loops(flowgraph *fg,int mode); 144 | flowgraph *create_loop_headers(flowgraph *fg,int av); 145 | flowgraph *create_loop_footers(flowgraph *fg,int av); 146 | void insert_regs(flowgraph *fg); 147 | void recalc_offsets(flowgraph *fg); 148 | void optimize(long flags,Var *function); 149 | int loop_optimizations(flowgraph *fg); 150 | void ic_uses(IC *p,bvtype *result); 151 | void ic_changes(IC *p,bvtype *result); 152 | void create_alias(flowgraph *fg); 153 | void free_alias(flowgraph *fg); 154 | void update_alias(Var *old,Var *new); 155 | void print_pt(bvtype **); 156 | void free_pt(bvtype **); 157 | #define CALC_CALLS 1 158 | #define CALC_USES 2 159 | #define CALC_CHANGES 4 160 | void calc_finfo(Var *,int); 161 | -------------------------------------------------------------------------------- /osek_supp.h: -------------------------------------------------------------------------------- 1 | /* used for special operating system support */ 2 | extern bvtype task_preempt_regs[],task_schedule_regs[]; 3 | typedef struct tasklist { 4 | struct Var *v; 5 | int prio; 6 | int taskid; 7 | enum {NON_PREEMPTIVE=1,DOES_BLOCK=2,CALLS_SCHED=4,ISR=8} flags; 8 | bvtype context[BVSIZE(MAXR+1)/sizeof(bvtype)]; 9 | bvtype preempt_context[BVSIZE(MAXR+1)/sizeof(bvtype)]; 10 | bvtype schedule_context[BVSIZE(MAXR+1)/sizeof(bvtype)]; 11 | bvtype unsaved_context[BVSIZE(MAXR+1)/sizeof(bvtype)]; 12 | } tasklist; 13 | 14 | -------------------------------------------------------------------------------- /osekrm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define BSIZE 4196 6 | char buf[BSIZE]; 7 | 8 | int main() 9 | { 10 | int nest=0; 11 | while(fgets(buf,BSIZE,stdin)){ 12 | if(nest==0){ 13 | fputs(buf,stdout); 14 | if(!strncmp(buf,"#if HAVE_OSEK",12)||!strncmp(buf,"#ifdef HAVE_MISRA",17)||!strncmp(buf,"#ifdef HAVE_ECPP",16)) 15 | nest++; 16 | }else{ 17 | if(!strncmp(buf,"#endif",6)) 18 | nest--; 19 | if(!strncmp(buf,"#if",3)) 20 | nest++; 21 | if(nest==1&&!strncmp(buf,"#else",5)) 22 | fputs("illegal #else found",stderr); 23 | if(nest==1&&!strncmp(buf,"#elif",5)) 24 | fputs("illegal #elif found",stderr); 25 | if(nest==0) 26 | fputs(buf,stdout); 27 | else 28 | puts("/* removed */"); 29 | } 30 | } 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /pptst.h: -------------------------------------------------------------------------------- 1 | test 2 | hello 3 | con\ 4 | catenated 5 | not\ 6 | concatenated 7 | ??= 8 | ??( 9 | ??/ 10 | ??) 11 | ??' 12 | ??< 13 | ??! 14 | ??> 15 | ??- 16 | From standard: printf("Eh???/n"); 17 | con??/ 18 | catenated with trigraph 19 | 20 | # /* */ define fail succeed 21 | fail 22 | #undef fail 23 | #define fail succeed 24 | fail 25 | 26 | #define x(a,b) a+b 27 | 28 | x(12 29 | 23 30 | , 31 | 34 32 | 45 33 | ) 34 | 35 | -------------------------------------------------------------------------------- /t1.h: -------------------------------------------------------------------------------- 1 | /* $Revision: 1.2 $ */ 2 | 3 | #include "t2.h" 4 | 5 | -------------------------------------------------------------------------------- /t2.h: -------------------------------------------------------------------------------- 1 | t2 is here 2 | 3 | -------------------------------------------------------------------------------- /tasm.c: -------------------------------------------------------------------------------- 1 | /* Test-language for vbcc. */ 2 | 3 | #include "supp.h" 4 | 5 | struct Var *fv; 6 | 7 | struct Typ tint,mfunc; 8 | struct struct_declaration msd; /* initialized to zero */ 9 | 10 | void raus(void) 11 | { 12 | while(fv){ 13 | struct Var *m=fv->next; 14 | free(fv); 15 | fv=m; 16 | } 17 | while(first_ic){ 18 | struct IC *m=first_ic->next; 19 | free(first_ic); 20 | first_ic=m; 21 | } 22 | exit(0); 23 | } 24 | void add_IC(struct IC *new) 25 | { 26 | new->next=0; 27 | new->prev=last_ic; 28 | new->change_cnt=new->use_cnt=0; 29 | new->change_list=new->use_list=0; 30 | new->line=0; 31 | new->file=0; 32 | if(!last_ic){ 33 | first_ic=new; 34 | }else{ 35 | last_ic->next=new; 36 | } 37 | last_ic=new; 38 | } 39 | struct Var *add_var(char *name,struct Typ *t,int sc) 40 | { 41 | struct Var *v=mymalloc(sizeof(*v)); 42 | v->vtyp=t; 43 | v->storage_class=sc; 44 | v->reg=0; 45 | v->identifier=name; 46 | v->offset=max_offset; 47 | if(sc==AUTO) max_offset=zmadd(max_offset,sizetab[t->flags&NQ]); 48 | v->priority=1; 49 | v->flags=0; 50 | v->next=fv; 51 | v->clist=0; 52 | v->fi=0; 53 | v->inline_copy=0; 54 | fv=v; 55 | return v; 56 | } 57 | struct Var *add_tmp_var(struct Typ *t) 58 | { 59 | return add_var(empty,t,AUTO); 60 | } 61 | struct Var *get_var(char *name) 62 | { 63 | struct Var *v;char *buf; 64 | for(v=fv;v;v=v->next){ 65 | if(!strcmp(name,v->identifier)) return v; 66 | } 67 | buf=mymalloc(strlen(name)+1); 68 | strcpy(buf,name); 69 | return add_var(buf,&tint,AUTO); 70 | } 71 | 72 | void read_ics() 73 | { 74 | char s[400],q1[100],q2[100],z[100],op; 75 | struct IC *new; 76 | gets(s); 77 | while(sscanf(s,"%99s = %99s %c %99s",z,q1,&op,q2)==4){ 78 | new=new_IC(); 79 | switch(op){ 80 | case '+': new->code=ADD;break; 81 | case '*': new->code=MULT;break; 82 | case '-': new->code=SUB;break; 83 | case '/': new->code=DIV;break; 84 | default: return; 85 | } 86 | new->typf=INT; 87 | new->q1.flags=new->q2.flags=new->z.flags=VAR; 88 | new->q1.am=new->q2.am=new->z.am=0; 89 | new->q1.val.vmax=l2zm(0L); 90 | new->q2.val.vmax=l2zm(0L); 91 | new->z.val.vmax=l2zm(0L); 92 | new->q1.v=get_var(q1); 93 | new->q2.v=get_var(q2); 94 | new->z.v=get_var(z); 95 | add_IC(new); 96 | gets(s); 97 | } 98 | } 99 | void error(int n,...) 100 | { 101 | printf("error %d\n",n); 102 | raus(); 103 | } 104 | void savescratch() 105 | {} 106 | 107 | main() 108 | { 109 | struct Var *main; 110 | max_offset=l2zm(0L); 111 | if(!init_cg()) raus(); 112 | tint.flags=INT; 113 | tint.next=0; 114 | mfunc.flags=FUNKT; 115 | mfunc.next=∭ 116 | mfunc.exact=&msd; 117 | main=add_var("main",&mfunc,EXTERN); 118 | read_ics(); 119 | printf("optflags: "); 120 | scanf("%ld",&optflags); 121 | pric(stdout,first_ic); 122 | vl1=vl3=0; 123 | vl2=fv; 124 | optimize(optflags,main); 125 | pric(stdout,first_ic); 126 | gen_code(stdout,first_ic,main,max_offset); 127 | raus(); 128 | } 129 | -------------------------------------------------------------------------------- /tt.h: -------------------------------------------------------------------------------- 1 | test1 2 | test2 3 | 4 | -------------------------------------------------------------------------------- /type_expr.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kusma/vbcc/191c0da6d49759e88b27e236d9d929645502da3f/type_expr.c -------------------------------------------------------------------------------- /ucpp/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kusma/vbcc/191c0da6d49759e88b27e236d9d929645502da3f/ucpp/README -------------------------------------------------------------------------------- /ucpp/assert.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Thomas Pornin 1999, 2000 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 4. The name of the authors may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "ucppi.h" 36 | #include "mem.h" 37 | #include "hash.h" 38 | #include "tune.h" 39 | 40 | /* 41 | * Assertion support. Each assertion is indexed by its predicate, and 42 | * the list of 'questions' which yield a true answer. 43 | */ 44 | 45 | static struct HT *assertions; 46 | 47 | static struct assert *new_assertion(void) 48 | { 49 | struct assert *a = getmem(sizeof(struct assert)); 50 | 51 | a->nbval = 0; 52 | return a; 53 | } 54 | 55 | static void del_assertion(void *va) 56 | { 57 | struct assert *a = va; 58 | size_t i, j; 59 | 60 | if (a->name) freemem(a->name); 61 | for (i = 0; i < a->nbval; i ++) { 62 | for (j = 0; j < a->val[i].nt; j ++) 63 | if (S_TOKEN(a->val[i].t[j].type)) 64 | freemem(a->val[i].t[j].name); 65 | if (a->val[i].nt) freemem(a->val[i].t); 66 | } 67 | if (a->nbval) freemem(a->val); 68 | } 69 | 70 | /* 71 | * print the contents of a token list 72 | */ 73 | static void print_token_fifo(struct token_fifo *tf) 74 | { 75 | size_t i; 76 | 77 | for (i = 0; i < tf->nt; i ++) 78 | if (ttMWS(tf->t[i].type)) fputc(' ', emit_output); 79 | else fputs(token_name(tf->t + i), emit_output); 80 | } 81 | 82 | /* 83 | * print all assertions related to a given name 84 | */ 85 | static void print_assert(void *va) 86 | { 87 | struct assert *a = va; 88 | size_t i; 89 | 90 | for (i = 0; i < a->nbval; i ++) { 91 | fprintf(emit_output, "#assert %s(", a->name); 92 | print_token_fifo(a->val + i); 93 | fprintf(emit_output, ")\n"); 94 | } 95 | } 96 | 97 | /* 98 | * compare two token_fifo, return 0 if they are identical, 1 otherwise. 99 | * All whitespace tokens are considered identical, but sequences of 100 | * whitespace are not shrinked. 101 | */ 102 | int cmp_token_list(struct token_fifo *f1, struct token_fifo *f2) 103 | { 104 | size_t i; 105 | 106 | if (f1->nt != f2->nt) return 1; 107 | for (i = 0; i < f1->nt; i ++) { 108 | if (ttMWS(f1->t[i].type) && ttMWS(f2->t[i].type)) continue; 109 | if (f1->t[i].type != f2->t[i].type) return 1; 110 | if (f1->t[i].type == MACROARG 111 | && f1->t[i].line != f2->t[i].line) return 1; 112 | if (S_TOKEN(f1->t[i].type) 113 | && strcmp(f1->t[i].name, f2->t[i].name)) return 1; 114 | } 115 | return 0; 116 | } 117 | 118 | /* 119 | * for #assert 120 | * Assertions are not part of the ISO-C89 standard, but they are sometimes 121 | * encountered, for instance in Solaris standard include files. 122 | */ 123 | int handle_assert(struct lexer_state *ls) 124 | { 125 | int ina = 0, ltww; 126 | struct token t; 127 | struct token_fifo *atl = 0; 128 | struct assert *a; 129 | int ret = -1; 130 | long l = ls->line; 131 | int nnp; 132 | size_t i; 133 | 134 | while (!next_token(ls)) { 135 | if (ls->ctok->type == NEWLINE) break; 136 | if (ttMWS(ls->ctok->type)) continue; 137 | if (ls->ctok->type == NAME) { 138 | if (!(a = getHT(assertions, &(ls->ctok->name)))) { 139 | a = new_assertion(); 140 | a->name = sdup(ls->ctok->name); 141 | ina = 1; 142 | } 143 | goto handle_assert_next; 144 | } 145 | error(l, "illegal assertion name for #assert"); 146 | goto handle_assert_warp_ign; 147 | } 148 | goto handle_assert_trunc; 149 | 150 | handle_assert_next: 151 | while (!next_token(ls)) { 152 | if (ls->ctok->type == NEWLINE) break; 153 | if (ttMWS(ls->ctok->type)) continue; 154 | if (ls->ctok->type != LPAR) { 155 | error(l, "syntax error in #assert"); 156 | goto handle_assert_warp_ign; 157 | } 158 | goto handle_assert_next2; 159 | } 160 | goto handle_assert_trunc; 161 | 162 | handle_assert_next2: 163 | atl = getmem(sizeof(struct token_fifo)); 164 | atl->art = atl->nt = 0; 165 | for (nnp = 1, ltww = 1; nnp && !next_token(ls);) { 166 | if (ls->ctok->type == NEWLINE) break; 167 | if (ltww && ttMWS(ls->ctok->type)) continue; 168 | ltww = ttMWS(ls->ctok->type); 169 | if (ls->ctok->type == LPAR) nnp ++; 170 | else if (ls->ctok->type == RPAR) { 171 | if (!(-- nnp)) goto handle_assert_next3; 172 | } 173 | t.type = ls->ctok->type; 174 | if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name); 175 | aol(atl->t, atl->nt, t, TOKEN_LIST_MEMG); 176 | } 177 | goto handle_assert_trunc; 178 | 179 | handle_assert_next3: 180 | while (!next_token(ls) && ls->ctok->type != NEWLINE) { 181 | if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) { 182 | warning(l, "trailing garbage in #assert"); 183 | } 184 | } 185 | if (atl->nt && ttMWS(atl->t[atl->nt - 1].type) && (-- atl->nt) == 0) 186 | freemem(atl->t); 187 | if (atl->nt == 0) { 188 | error(l, "void assertion in #assert"); 189 | freemem(atl); 190 | return ret; 191 | } 192 | for (i = 0; i < a->nbval && cmp_token_list(atl, a->val + i); i ++); 193 | if (i != a->nbval) { 194 | /* we already have it */ 195 | ret = 0; 196 | goto handle_assert_error; 197 | } 198 | 199 | /* This is a new assertion. Let's keep it. */ 200 | aol(a->val, a->nbval, *atl, TOKEN_LIST_MEMG); 201 | if (ina) putHT(assertions, a); 202 | if (emit_assertions) { 203 | fprintf(emit_output, "#assert %s(", a->name); 204 | print_token_fifo(atl); 205 | fputs(")\n", emit_output); 206 | } 207 | return 0; 208 | 209 | handle_assert_trunc: 210 | error(l, "unfinished #assert"); 211 | handle_assert_error: 212 | if (atl && atl->nt) { 213 | for (i = 0; i < atl->nt; i ++) 214 | if (S_TOKEN(atl->t[i].type)) freemem(atl->t[i].name); 215 | freemem(atl->t); 216 | } 217 | return ret; 218 | handle_assert_warp_ign: 219 | while (!next_token(ls) && ls->ctok->type != NEWLINE); 220 | return ret; 221 | } 222 | 223 | /* 224 | * for #unassert 225 | */ 226 | int handle_unassert(struct lexer_state *ls) 227 | { 228 | int ltww; 229 | struct token t; 230 | struct token_fifo *atl = 0; 231 | struct assert *a; 232 | int ret = -1; 233 | long l = ls->line; 234 | int nnp; 235 | size_t i; 236 | 237 | while (!next_token(ls)) { 238 | if (ls->ctok->type == NEWLINE) break; 239 | if (ttMWS(ls->ctok->type)) continue; 240 | if (ls->ctok->type == NAME) { 241 | if (!(a = getHT(assertions, &(ls->ctok->name)))) { 242 | ret = 0; 243 | goto handle_unassert_warp; 244 | } 245 | goto handle_unassert_next; 246 | } 247 | error(l, "illegal assertion name for #unassert"); 248 | goto handle_unassert_warp; 249 | } 250 | goto handle_unassert_trunc; 251 | 252 | handle_unassert_next: 253 | while (!next_token(ls)) { 254 | if (ls->ctok->type == NEWLINE) break; 255 | if (ttMWS(ls->ctok->type)) continue; 256 | if (ls->ctok->type != LPAR) { 257 | error(l, "syntax error in #unassert"); 258 | goto handle_unassert_warp; 259 | } 260 | goto handle_unassert_next2; 261 | } 262 | if (emit_assertions) fprintf(emit_output, "#unassert %s\n", a->name); 263 | delHT(assertions, a); 264 | return 0; 265 | 266 | handle_unassert_next2: 267 | atl = getmem(sizeof(struct token_fifo)); 268 | atl->art = atl->nt = 0; 269 | for (nnp = 1, ltww = 1; nnp && !next_token(ls);) { 270 | if (ls->ctok->type == NEWLINE) break; 271 | if (ltww && ttMWS(ls->ctok->type)) continue; 272 | ltww = ttMWS(ls->ctok->type); 273 | if (ls->ctok->type == LPAR) nnp ++; 274 | else if (ls->ctok->type == RPAR) { 275 | if (!(-- nnp)) goto handle_unassert_next3; 276 | } 277 | t.type = ls->ctok->type; 278 | if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name); 279 | aol(atl->t, atl->nt, t, TOKEN_LIST_MEMG); 280 | } 281 | goto handle_unassert_trunc; 282 | 283 | handle_unassert_next3: 284 | while (!next_token(ls) && ls->ctok->type != NEWLINE) { 285 | if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) { 286 | warning(l, "trailing garbage in #unassert"); 287 | } 288 | } 289 | if (atl->nt && ttMWS(atl->t[atl->nt - 1].type) && (-- atl->nt) == 0) 290 | freemem(atl->t); 291 | if (atl->nt == 0) { 292 | error(l, "void assertion in #unassert"); 293 | freemem(atl); 294 | return ret; 295 | } 296 | for (i = 0; i < a->nbval && cmp_token_list(atl, a->val + i); i ++); 297 | if (i != a->nbval) { 298 | /* we have it, undefine it */ 299 | if (i < (a->nbval - 1)) 300 | mmvwo(a->val + i, a->val + i + 1, (a->nbval - i - 1) 301 | * sizeof(struct token_fifo)); 302 | a->nbval --; 303 | if (emit_assertions) { 304 | fprintf(emit_output, "#unassert %s(", a->name); 305 | print_token_fifo(atl); 306 | fputs(")\n", emit_output); 307 | } 308 | } 309 | ret = 0; 310 | goto handle_unassert_finish; 311 | 312 | handle_unassert_trunc: 313 | error(l, "unfinished #unassert"); 314 | handle_unassert_finish: 315 | if (atl && atl->nt) { 316 | for (i = 0; i < atl->nt; i ++) 317 | if (S_TOKEN(atl->t[i].type)) freemem(atl->t[i].name); 318 | freemem(atl->t); 319 | } 320 | return ret; 321 | handle_unassert_warp: 322 | while (!next_token(ls) && ls->ctok->type != NEWLINE); 323 | return ret; 324 | } 325 | 326 | /* 327 | * Add the given assertion (as string). 328 | */ 329 | int make_assertion(char *aval) 330 | { 331 | struct lexer_state lls; 332 | size_t n = strlen(aval) + 1; 333 | char *c = sdup(aval); 334 | int ret; 335 | 336 | *(c + n - 1) = '\n'; 337 | init_buf_lexer_state(&lls, 0); 338 | lls.flags = DEFAULT_LEXER_FLAGS; 339 | lls.input = 0; 340 | lls.input_string = (unsigned char *)c; 341 | lls.pbuf = 0; 342 | lls.ebuf = n; 343 | lls.line = -1; 344 | ret = handle_assert(&lls); 345 | freemem(c); 346 | free_lexer_state(&lls); 347 | return ret; 348 | } 349 | 350 | /* 351 | * Remove the given assertion (as string). 352 | */ 353 | int destroy_assertion(char *aval) 354 | { 355 | struct lexer_state lls; 356 | size_t n = strlen(aval) + 1; 357 | char *c = sdup(aval); 358 | int ret; 359 | 360 | *(c + n - 1) = '\n'; 361 | init_buf_lexer_state(&lls, 0); 362 | lls.flags = DEFAULT_LEXER_FLAGS; 363 | lls.input = 0; 364 | lls.input_string = (unsigned char *)c; 365 | lls.pbuf = 0; 366 | lls.ebuf = n; 367 | lls.line = -1; 368 | ret = handle_unassert(&lls); 369 | freemem(c); 370 | free_lexer_state(&lls); 371 | return ret; 372 | } 373 | 374 | /* 375 | * initialize the assertion table 376 | */ 377 | void init_assertions(void) 378 | { 379 | if (assertions) killHT(assertions); 380 | assertions = newHT(128, cmp_struct, hash_struct, del_assertion); 381 | } 382 | 383 | /* 384 | * retrieve an assertion from the hash table 385 | */ 386 | struct assert *get_assertion(char *name) 387 | { 388 | return getHT(assertions, &name); 389 | } 390 | 391 | /* 392 | * print already defined assertions 393 | */ 394 | void print_assertions(void) 395 | { 396 | scanHT(assertions, print_assert); 397 | } 398 | -------------------------------------------------------------------------------- /ucpp/cpp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Thomas Pornin 1999, 2000 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 4. The name of the authors may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #ifndef UCPP__CPP__ 31 | #define UCPP__CPP__ 32 | 33 | /* 34 | * Uncomment the following if you want ucpp to use externally provided 35 | * error-reporting functions (ucpp_warning(), ucpp_error() and ucpp_ouch()) 36 | */ 37 | /* #define NO_UCPP_ERROR_FUNCTIONS */ 38 | 39 | /* 40 | * Tokens (do not change the order unless checking operators_name[] in cpp.c) 41 | * 42 | * It is important that the token NONE is 0 43 | * Check the STRING_TOKEN macro 44 | */ 45 | #define CPPERR 512 46 | enum { 47 | NONE, /* whitespace */ 48 | NEWLINE, /* newline */ 49 | COMMENT, /* comment */ 50 | NUMBER, /* number constant */ 51 | NAME, /* identifier */ 52 | BUNCH, /* non-C characters */ 53 | PRAGMA, /* a #pragma directive */ 54 | CONTEXT, /* new file or #line */ 55 | STRING, /* constant "xxx" */ 56 | CHAR, /* constant 'xxx' */ 57 | SLASH, /* / */ 58 | ASSLASH, /* /= */ 59 | MINUS, /* - */ 60 | MMINUS, /* -- */ 61 | ASMINUS, /* -= */ 62 | ARROW, /* -> */ 63 | PLUS, /* + */ 64 | PPLUS, /* ++ */ 65 | ASPLUS, /* += */ 66 | LT, /* < */ 67 | LEQ, /* <= */ 68 | LSH, /* << */ 69 | ASLSH, /* <<= */ 70 | GT, /* > */ 71 | GEQ, /* >= */ 72 | RSH, /* >> */ 73 | ASRSH, /* >>= */ 74 | ASGN, /* = */ 75 | SAME, /* == */ 76 | #ifdef CAST_OP 77 | CAST, /* => */ 78 | #endif 79 | NOT, /* ~ */ 80 | NEQ, /* != */ 81 | AND, /* & */ 82 | LAND, /* && */ 83 | ASAND, /* &= */ 84 | OR, /* | */ 85 | LOR, /* || */ 86 | ASOR, /* |= */ 87 | PCT, /* % */ 88 | ASPCT, /* %= */ 89 | STAR, /* * */ 90 | ASSTAR, /* *= */ 91 | CIRC, /* ^ */ 92 | ASCIRC, /* ^= */ 93 | LNOT, /* ! */ 94 | ASNOT, /* ~= */ 95 | LBRA, /* { */ 96 | RBRA, /* } */ 97 | LBRK, /* [ */ 98 | RBRK, /* ] */ 99 | LPAR, /* ( */ 100 | RPAR, /* ) */ 101 | COMMA, /* , */ 102 | QUEST, /* ? */ 103 | SEMIC, /* ; */ 104 | COLON, /* : */ 105 | DOT, /* . */ 106 | MDOTS, /* ... */ 107 | SHARP, /* # */ 108 | DSHARP, /* ## */ 109 | 110 | OPT_NONE, /* optional space to separate tokens in text output */ 111 | 112 | DIGRAPH_TOKENS, /* there begin digraph tokens */ 113 | 114 | /* for DIG_*, do not change order, unless checking undig() in cpp.c */ 115 | DIG_LBRK, /* <: */ 116 | DIG_RBRK, /* :> */ 117 | DIG_LBRA, /* <% */ 118 | DIG_RBRA, /* %> */ 119 | DIG_SHARP, /* %: */ 120 | DIG_DSHARP, /* %:%: */ 121 | 122 | DIGRAPH_TOKENS_END, /* digraph tokens end here */ 123 | 124 | LAST_MEANINGFUL_TOKEN, /* reserved words will go there */ 125 | 126 | MACROARG, /* special token for representing macro arguments */ 127 | 128 | UPLUS = CPPERR, /* unary + */ 129 | UMINUS /* unary - */ 130 | }; 131 | 132 | #include 133 | #include 134 | #include "tune.h" 135 | 136 | struct token { 137 | int type; 138 | long line; 139 | char *name; 140 | }; 141 | 142 | struct token_fifo { 143 | struct token *t; 144 | size_t nt, art; 145 | }; 146 | 147 | struct lexer_state { 148 | /* input control */ 149 | FILE *input; 150 | #ifndef NO_UCPP_BUF 151 | unsigned char *input_buf; 152 | #ifdef UCPP_MMAP 153 | int from_mmap; 154 | unsigned char *input_buf_sav; 155 | #endif 156 | #endif 157 | unsigned char *input_string; 158 | size_t ebuf; 159 | size_t pbuf; 160 | int lka[2]; 161 | int nlka; 162 | int macfile; 163 | int last; 164 | int discard; 165 | unsigned long utf8; 166 | unsigned char copy_line[COPY_LINE_LENGTH]; 167 | int cli; 168 | 169 | /* output control */ 170 | 171 | FILE *output; 172 | struct token_fifo *output_fifo, *toplevel_of; 173 | #ifndef NO_UCPP_BUF 174 | unsigned char *output_buf; 175 | #endif 176 | size_t sbuf; 177 | 178 | /* token control */ 179 | struct token *ctok; 180 | struct token *save_ctok; 181 | int tknl; 182 | int ltwnl; 183 | int pending_token; 184 | #ifdef INMACRO_FLAG 185 | int inmacro; 186 | long macro_count; 187 | #endif 188 | 189 | /* lexer options */ 190 | long line; 191 | long oline; 192 | unsigned long flags; 193 | long count_trigraphs; 194 | struct garbage_fifo *gf; 195 | int ifnest; 196 | int condnest; 197 | int condcomp; 198 | int condmet; 199 | unsigned long condf[2]; 200 | }; 201 | 202 | /* 203 | * Flags for struct lexer_state 204 | */ 205 | /* warning flags */ 206 | #define WARN_STANDARD 0x000001UL /* emit standard warnings */ 207 | #define WARN_ANNOYING 0x000002UL /* emit annoying warnings */ 208 | #define WARN_TRIGRAPHS 0x000004UL /* warn when trigraphs are used */ 209 | #define WARN_TRIGRAPHS_MORE 0x000008UL /* extra-warn for trigraphs */ 210 | #define WARN_PRAGMA 0x000010UL /* warn for pragmas in non-lexer mode */ 211 | 212 | /* error flags */ 213 | #define FAIL_SHARP 0x000020UL /* emit errors on rogue '#' */ 214 | #define CCHARSET 0x000040UL /* emit errors on non-C characters */ 215 | 216 | /* emission flags */ 217 | #define DISCARD_COMMENTS 0x000080UL /* discard comments from text output */ 218 | #define CPLUSPLUS_COMMENTS 0x000100UL /* understand C++-like comments */ 219 | #define LINE_NUM 0x000200UL /* emit #line directives in output */ 220 | #define GCC_LINE_NUM 0x000400UL /* same as #line, with gcc-syntax */ 221 | 222 | /* language flags */ 223 | #define HANDLE_ASSERTIONS 0x000800UL /* understand assertions */ 224 | #define HANDLE_PRAGMA 0x001000UL /* emit PRAGMA tokens in lexer mode */ 225 | #define MACRO_VAARG 0x002000UL /* understand macros with '...' */ 226 | #define UTF8_SOURCE 0x004000UL /* identifiers are in UTF8 encoding */ 227 | #define HANDLE_TRIGRAPHS 0x008000UL /* handle trigraphs */ 228 | 229 | /* global ucpp behaviour */ 230 | #define LEXER 0x010000UL /* behave as a lexer */ 231 | #define KEEP_OUTPUT 0x020000UL /* emit the result of preprocessing */ 232 | #define COPY_LINE 0x040000UL /* make a copy of the parsed line */ 233 | 234 | /* internal flags */ 235 | #define READ_AGAIN 0x080000UL /* emit again the last token */ 236 | #define TEXT_OUTPUT 0x100000UL /* output text */ 237 | 238 | /* 239 | * Public function prototypes 240 | */ 241 | 242 | #ifndef NO_UCPP_BUF 243 | void flush_output(struct lexer_state *); 244 | #endif 245 | 246 | void init_assertions(void); 247 | int make_assertion(char *); 248 | int destroy_assertion(char *); 249 | void print_assertions(void); 250 | 251 | void init_macros(void); 252 | int define_macro(struct lexer_state *, char *); 253 | int undef_macro(struct lexer_state *, char *); 254 | void print_defines(void); 255 | 256 | void set_init_filename(char *, int); 257 | void init_cpp(void); 258 | void init_include_path(char *[]); 259 | void init_lexer_state(struct lexer_state *); 260 | void init_lexer_mode(struct lexer_state *); 261 | void free_lexer_state(struct lexer_state *); 262 | int lex(struct lexer_state *); 263 | int check_cpp_errors(struct lexer_state *); 264 | void add_incpath(char *); 265 | void init_tables(int); 266 | void enter_file(struct lexer_state *, unsigned long); 267 | int cpp(struct lexer_state *); 268 | 269 | #ifdef UCPP_MMAP 270 | FILE *fopen_mmap_file(char *); 271 | void set_input_file(struct lexer_state *, FILE *); 272 | #endif 273 | 274 | struct stack_context { 275 | char *long_name, *name; 276 | long line; 277 | }; 278 | struct stack_context *report_context(void); 279 | 280 | extern int no_special_macros, system_macros, 281 | emit_dependencies, emit_defines, emit_assertions; 282 | extern int c99_compliant, c99_hosted; 283 | extern FILE *emit_output; 284 | extern char *current_filename, *current_long_filename; 285 | extern char *operators_name[]; 286 | extern struct protect { 287 | char *macro; 288 | int state; 289 | struct found_file *ff; 290 | } protect_detect; 291 | 292 | void ucpp_ouch(char *, ...); 293 | void ucpp_error(long, char *, ...); 294 | void ucpp_warning(long, char *, ...); 295 | 296 | extern int *transient_characters; 297 | 298 | /* 299 | * Errors from CPPERR_EOF and above are not real erros, only show-stoppers. 300 | * Errors below CPPERR_EOF are real ones. 301 | */ 302 | #define CPPERR_NEST 900 303 | #define CPPERR_EOF 1000 304 | 305 | /* 306 | * This macro tells whether the name field of a given token type is 307 | * relevant, or not. Irrelevant name field means that it might point 308 | * to outerspace. 309 | */ 310 | #ifdef SEMPER_FIDELIS 311 | #define STRING_TOKEN(x) ((x) == NONE || ((x) >= COMMENT && (x) <= CHAR)) 312 | #else 313 | #define STRING_TOKEN(x) ((x) >= NUMBER && (x) <= CHAR) 314 | #endif 315 | 316 | #endif 317 | -------------------------------------------------------------------------------- /ucpp/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic hash table routines. 3 | * (c) Thomas Pornin 1998, 1999, 2000 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 4. The name of the authors may not be used to endorse or promote 14 | * products derived from this software without specific prior written 15 | * permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | #include 32 | #include "hash.h" 33 | #include "mem.h" 34 | 35 | /* 36 | * hash_string() is a sample hash function for strings 37 | */ 38 | int hash_string(char *s) 39 | { 40 | unsigned char h = 0; 41 | 42 | for (; *s; s ++) h ^= (unsigned char)(*s); 43 | return ((int)h); 44 | } 45 | 46 | /* 47 | * struct hash_item is the basic data type to internally handle hash tables 48 | */ 49 | struct hash_item { 50 | void *data; 51 | struct hash_item *next; 52 | }; 53 | 54 | /* 55 | * This function adds an entry to the struct hash_item list 56 | */ 57 | static struct hash_item *add_entry(struct hash_item *blist, void *data) 58 | { 59 | struct hash_item *t = getmem(sizeof(struct hash_item)); 60 | 61 | t->data = data; 62 | t->next = blist; 63 | return t; 64 | } 65 | 66 | /* 67 | * This function finds a struct hash_item in a list, using the 68 | * comparison function provided as cmpdata (*cmpdata() returns 69 | * non-zero if the two parameters are to be considered identical). 70 | * 71 | * It returns 0 if the item is not found. 72 | */ 73 | static struct hash_item *get_entry(struct hash_item *blist, void *data, 74 | int (*cmpdata)(void *, void *)) 75 | { 76 | while (blist) { 77 | if ((*cmpdata)(data, blist->data)) return blist; 78 | blist = blist->next; 79 | } 80 | return 0; 81 | } 82 | 83 | /* 84 | * This function acts like get_entry but deletes the found item, using 85 | * the provided function deldata(); it returns 0 if the given data was 86 | * not found. 87 | */ 88 | static struct hash_item *del_entry(struct hash_item *blist, void *data, 89 | int (*cmpdata)(void *, void *), void (*deldata)(void *)) 90 | { 91 | struct hash_item *prev = 0, *save = blist; 92 | 93 | while (blist) { 94 | if ((*cmpdata)(data, blist->data)) { 95 | (*deldata)(blist->data); 96 | if (prev) prev->next = blist->next; 97 | if (save == blist) save = blist->next; 98 | freemem(blist); 99 | return save; 100 | } 101 | prev = blist; 102 | blist = blist->next; 103 | } 104 | return 0; 105 | } 106 | 107 | /* 108 | * This function creates a new hashtable, with the hashing and comparison 109 | * functions given as parameters 110 | */ 111 | struct HT *newHT(int n, int (*cmpdata)(void *, void *), int (*hash)(void *), 112 | void (*deldata)(void *)) 113 | { 114 | struct HT *t = getmem(sizeof(struct HT)); 115 | int i; 116 | 117 | t->lists = getmem(n * sizeof(struct hash_item *)); 118 | for (i = 0; i < n; i ++) t->lists[i] = 0; 119 | t->nb_lists = n; 120 | t->cmpdata = cmpdata; 121 | t->hash = hash; 122 | t->deldata = deldata; 123 | return t; 124 | } 125 | 126 | /* 127 | * This function adds a new entry in the hashtable ht; it returns 0 128 | * on success, or a pointer to the already present item otherwise. 129 | */ 130 | void *putHT(struct HT *ht, void *data) 131 | { 132 | int h; 133 | struct hash_item *d; 134 | 135 | h = ((*(ht->hash))(data)) % ht->nb_lists; 136 | if ((d = get_entry(ht->lists[h], data, ht->cmpdata))) 137 | return d->data; 138 | ht->lists[h] = add_entry(ht->lists[h], data); 139 | return 0; 140 | } 141 | 142 | /* 143 | * This function adds a new entry in the hashtable ht, even if an equal 144 | * entry is already there. Exercise caution ! 145 | * The new entry will "hide" the old one, which means that the new will be 146 | * found upon lookup/delete, not the old one. 147 | */ 148 | void *forceputHT(struct HT *ht, void *data) 149 | { 150 | int h; 151 | 152 | h = ((*(ht->hash))(data)) % ht->nb_lists; 153 | ht->lists[h] = add_entry(ht->lists[h], data); 154 | return 0; 155 | } 156 | 157 | /* 158 | * This function finds the entry corresponding to *data in the 159 | * hashtable ht (using the comparison function given as argument 160 | * to newHT) 161 | */ 162 | void *getHT(struct HT *ht, void *data) 163 | { 164 | int h; 165 | struct hash_item *t; 166 | 167 | h = ((*(ht->hash))(data)) % ht->nb_lists; 168 | if ((t = get_entry(ht->lists[h], data, ht->cmpdata)) == 0) 169 | return 0; 170 | return (t->data); 171 | } 172 | 173 | /* 174 | * This function finds and delete the entry corresponding to *data 175 | * in the hashtable ht (using the comparison function given as 176 | * argument to newHT). 177 | */ 178 | 179 | int delHT(struct HT *ht, void *data) 180 | { 181 | int h; 182 | 183 | h = ((*(ht->hash))(data)) % ht->nb_lists; 184 | ht->lists[h] = del_entry(ht->lists[h], data, ht->cmpdata, ht->deldata); 185 | return 1; 186 | } 187 | 188 | /* 189 | * This function duplicates a given hash table; the data is not copied 190 | */ 191 | struct HT *copyHT(struct HT *ht) 192 | { 193 | struct HT *nht = newHT(ht->nb_lists, ht->cmpdata, ht->hash, 194 | ht->deldata); 195 | struct hash_item *t; 196 | int i, j; 197 | 198 | for (i = 0; i < nht->nb_lists; i ++) { 199 | j = 0; 200 | t = ht->lists[i]; 201 | while (t) { 202 | t = t->next; 203 | j ++; 204 | } 205 | if (j != 0) { 206 | nht->lists[i] = getmem(j * sizeof(struct hash_item)); 207 | mmv(nht->lists[i], ht->lists[i], 208 | j * sizeof(struct hash_item)); 209 | } 210 | } 211 | return nht; 212 | } 213 | 214 | /* 215 | * This function completely eradicates from memory a given hash table, 216 | * releasing all objects 217 | */ 218 | void killHT(struct HT *ht) 219 | { 220 | int i; 221 | struct hash_item *t, *n; 222 | 223 | for (i = 0; i < ht->nb_lists; i ++) for (t = ht->lists[i]; t;) { 224 | n = t->next; 225 | (*(ht->deldata))(t->data); 226 | freemem(t); 227 | t = n; 228 | } 229 | freemem(ht); 230 | } 231 | 232 | /* 233 | * This function stores a backup of the hash table, for context stacking 234 | */ 235 | void saveHT(struct HT *ht, void **buffer) 236 | { 237 | struct hash_item **b = (struct hash_item **)buffer; 238 | int i; 239 | 240 | for (i = 0; i < ht->nb_lists; i ++) b[i] = ht->lists[i]; 241 | } 242 | 243 | /* 244 | * This function restores the saved state of the hash table. 245 | * Do NOT use if some of the entries that were present before the backup 246 | * have been removed (even temporarily). 247 | */ 248 | void restoreHT(struct HT *ht, void **buffer) 249 | { 250 | struct hash_item **b = (struct hash_item **)buffer; 251 | int i; 252 | 253 | for (i = 0; i < ht->nb_lists; i ++) { 254 | struct hash_item *t = ht->lists[i], *n; 255 | 256 | while (t != b[i]) { 257 | n = t->next; 258 | (*(ht->deldata))(t->data); 259 | freemem(t); 260 | t = n; 261 | } 262 | ht->lists[i] = b[i]; 263 | } 264 | } 265 | 266 | /* 267 | * This function scans the whole table and calls the given function on 268 | * each entry. 269 | */ 270 | void scanHT(struct HT *ht, void (*action)(void *)) 271 | { 272 | int i; 273 | 274 | for (i = 0; i < ht->nb_lists; i ++) { 275 | struct hash_item *t = ht->lists[i]; 276 | 277 | while (t) { 278 | (*action)(t->data); 279 | t = t->next; 280 | } 281 | } 282 | } 283 | 284 | /* 285 | * The two following fonctions are generic for storing structures 286 | * uniquely identified by their name, which must be the first 287 | * field of the structure. 288 | */ 289 | int hash_struct(void *m) 290 | { 291 | char *n = *(char **)m; 292 | 293 | return hash_string(n) & 127; 294 | } 295 | 296 | int cmp_struct(void *m1, void *m2) 297 | { 298 | char *n1 = *(char **)m1, *n2 = *(char **)m2; 299 | 300 | return !strcmp(n1, n2); 301 | } 302 | -------------------------------------------------------------------------------- /ucpp/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Thomas Pornin 1998, 1999, 2000 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 4. The name of the authors may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #ifndef UCPP__HASH__ 31 | #define UCPP__HASH__ 32 | 33 | struct hash_item; 34 | 35 | struct HT { 36 | struct hash_item **lists; 37 | int nb_lists; 38 | int (*cmpdata)(void *, void *); 39 | int (*hash)(void *); 40 | void (*deldata)(void *); 41 | }; 42 | 43 | int hash_string(char *); 44 | struct HT *newHT(int, int (*)(void *, void *), int (*)(void *), 45 | void (*)(void *)); 46 | void *putHT(struct HT *, void *); 47 | void *forceputHT(struct HT *, void *); 48 | void *getHT(struct HT *, void *); 49 | int delHT(struct HT *, void *); 50 | struct HT *copyHT(struct HT *); 51 | void killHT(struct HT *); 52 | void saveHT(struct HT *, void **); 53 | void restoreHT(struct HT *, void **); 54 | void scanHT(struct HT *, void (*)(void *)); 55 | int hash_struct(void *); 56 | int cmp_struct(void *, void *); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ucpp/mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory manipulation routines 3 | * (c) Thomas Pornin 1998, 1999, 2000 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 4. The name of the authors may not be used to endorse or promote 14 | * products derived from this software without specific prior written 15 | * permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | #include "mem.h" 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef AUDIT 37 | void die(void) 38 | { 39 | abort(); 40 | } 41 | 42 | static void suicide(unsigned long e) 43 | { 44 | fprintf(stderr, "ouch: Schrodinger's beef is not dead ! %lx\n", e); 45 | die(); 46 | } 47 | #else 48 | void die(void) 49 | { 50 | exit(1); 51 | } 52 | #endif 53 | 54 | #if defined AUDIT || defined MEM_CHECK 55 | /* 56 | * This function is equivalent to a malloc(), but will display an error 57 | * message and exit if the wanted memory is not available 58 | */ 59 | void *getmem(size_t x) 60 | { 61 | void *m; 62 | 63 | #ifdef AUDIT 64 | m = malloc(x + 8); 65 | #else 66 | m = malloc(x); 67 | #endif 68 | if (m == 0) { 69 | fprintf(stderr, "ouch: malloc() failed\n"); 70 | die(); 71 | } 72 | #ifdef AUDIT 73 | *((unsigned long *)m) = 0xdeadbeefUL; 74 | return (void *)(((char *)m) + 8); 75 | #else 76 | return m; 77 | #endif 78 | } 79 | #endif 80 | 81 | /* 82 | * This function is equivalent to a realloc(); if the realloc() call 83 | * fails, it will try a malloc() and a memcpy(). If not enough memory is 84 | * available, the program exits with an error message 85 | */ 86 | void *incmem(void *m, size_t x, size_t nx) 87 | { 88 | void *nm; 89 | 90 | #ifdef AUDIT 91 | m = (void *)(((char *)m) - 8); 92 | if (*((unsigned long *)m) != 0xdeadbeefUL) 93 | suicide(*((unsigned long *)m)); 94 | x += 8; nx += 8; 95 | #endif 96 | if (!(nm = realloc(m, nx))) { 97 | if (x > nx) x = nx; 98 | nm = getmem(nx); 99 | memcpy(nm, m, x); 100 | /* free() and not freemem(), because of the Schrodinger beef */ 101 | free(m); 102 | } 103 | #ifdef AUDIT 104 | return (void *)(((char *)nm) + 8); 105 | #else 106 | return nm; 107 | #endif 108 | } 109 | 110 | #ifdef AUDIT 111 | /* 112 | * This function frees the given block 113 | */ 114 | void freemem(void *x) 115 | { 116 | #ifdef AUDIT 117 | void *y = (void *)(((char *)x) - 8); 118 | 119 | if ((*((unsigned long *)y)) != 0xdeadbeefUL) 120 | suicide(*((unsigned long *)y)); 121 | *((unsigned long *)y) = 0xfeedbabeUL; 122 | free(y); 123 | #else 124 | free(x); 125 | #endif 126 | } 127 | #endif 128 | 129 | #ifdef AUDIT 130 | /* 131 | * This function copies n bytes from src to dest 132 | */ 133 | void *mmv(void *dest, void *src, size_t n) 134 | { 135 | return memcpy(dest, src, n); 136 | } 137 | 138 | /* 139 | * This function copies n bytes from src to dest 140 | */ 141 | void *mmvwo(void *dest, void *src, size_t n) 142 | { 143 | return memmove(dest, src, n); 144 | } 145 | #endif 146 | 147 | /* 148 | * This function creates a new char * and fills it with a copy of src 149 | */ 150 | char *sdup(char *src) 151 | { 152 | size_t n = 1 + strlen(src); 153 | char *x = getmem(n); 154 | 155 | mmv(x, src, n); 156 | return x; 157 | } 158 | -------------------------------------------------------------------------------- /ucpp/mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Thomas Pornin 1998, 1999, 2000 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 4. The name of the authors may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #ifndef UCPP__MEM__ 31 | #define UCPP__MEM__ 32 | 33 | #include 34 | 35 | void die(void); 36 | void *incmem(void *, size_t, size_t); 37 | char *sdup(char *); 38 | 39 | #if defined AUDIT || defined MEM_CHECK 40 | void *getmem(size_t); 41 | #else 42 | #define getmem malloc 43 | #endif 44 | 45 | #ifdef AUDIT 46 | void freemem(void *); 47 | #else 48 | #define freemem free 49 | #endif 50 | 51 | #ifdef AUDIT 52 | void *mmv(void *, void *, size_t); 53 | void *mmvwo(void *, void *, size_t); 54 | #else 55 | #define mmv memcpy 56 | #define mmvwo memmove 57 | #endif 58 | 59 | /* 60 | * this macro adds the object obj at the end of the array list, handling 61 | * memory allocation when needed; ptr contains the number of elements in 62 | * the array, and memg is the granularity of memory allocations (a power 63 | * of 2 is recommanded, for optimization reasons) 64 | * 65 | * list and ptr may be updated, and thus need to be lvalues 66 | */ 67 | #define aol(list,ptr,obj,memg) do { \ 68 | if (((ptr) % (memg)) == 0) { \ 69 | if ((ptr) != 0) { \ 70 | (list) = incmem((list), (ptr) * sizeof(obj), \ 71 | ((ptr) + (memg)) * sizeof(obj)); \ 72 | } else { \ 73 | (list) = getmem((memg) * sizeof(obj)); \ 74 | } \ 75 | } \ 76 | (list)[(ptr) ++] = (obj); \ 77 | } while (0) 78 | 79 | /* 80 | * bol() does the same as aol(), but adds the new item at the beginning 81 | * of the list; beware, the computational cost is greater. 82 | */ 83 | #define bol(list,ptr,obj,memg) do { \ 84 | if (((ptr) % (memg)) == 0) { \ 85 | if ((ptr) != 0) { \ 86 | (list) = incmem((list), (ptr) * sizeof(obj), \ 87 | ((ptr) + (memg)) * sizeof(obj)); \ 88 | } else { \ 89 | (list) = getmem((memg) * sizeof(obj)); \ 90 | } \ 91 | } \ 92 | if ((ptr) != 0) \ 93 | mmvwo((list) + 1, (list), (ptr) * sizeof(obj)); \ 94 | (ptr) ++; \ 95 | (list)[0] = (obj); \ 96 | } while (0) 97 | 98 | /* 99 | * mbol() does the same as bol(), but adds the new item at the given 100 | * emplacement; bol() is equivalent to mbol with 0 as last argument. 101 | */ 102 | #define mbol(list,ptr,obj,memg,n) do { \ 103 | if (((ptr) % (memg)) == 0) { \ 104 | if ((ptr) != 0) { \ 105 | (list) = incmem((list), (ptr) * sizeof(obj), \ 106 | ((ptr) + (memg)) * sizeof(obj)); \ 107 | } else { \ 108 | (list) = getmem((memg) * sizeof(obj)); \ 109 | } \ 110 | } \ 111 | if ((ptr) > n) \ 112 | mmvwo((list) + n + 1, (list) + n, \ 113 | ((ptr) - n) * sizeof(obj)); \ 114 | (ptr) ++; \ 115 | (list)[n] = (obj); \ 116 | } while (0) 117 | 118 | /* 119 | * this macro adds the object obj at the end of the array list, doubling 120 | * the size of list when needed; as for aol(), ptr and list must be 121 | * lvalues, and so must be llng 122 | */ 123 | 124 | #define wan(list,ptr,obj,llng) do { \ 125 | if ((ptr) == (llng)) { \ 126 | (llng) += (llng); \ 127 | (list) = incmem((list), (ptr) * sizeof(obj), \ 128 | (llng) * sizeof(obj)); \ 129 | } \ 130 | (list)[(ptr) ++] = (obj); \ 131 | } while (0) 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /ucpp/sample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample code showing how to use ucpp as an integrated lexer. 3 | * This file is public domain. 4 | */ 5 | 6 | /* 7 | * This is an example of how to use ucpp as a preprocessor and lexer 8 | * into another project. The steps are those described in ucpp README 9 | * file. To use this code, compile the ucpp source files with 10 | * STAND_ALONE not defined, and link them with this code. The resulting 11 | * binary will take a C source file as standard input, preprocess it, 12 | * and output each non-whitespace token on stdout, with its numerical 13 | * value (defined as an enum in cpp.h) and its contents. This code 14 | * defines no system include path. 15 | * 16 | * This code supposes that the ucpp files are compiled with PRAGMA_TOKENIZE 17 | * enabled (see the tune.h file). 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include "mem.h" 24 | #include "cpp.h" 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | int i, r; 29 | struct lexer_state ls; 30 | 31 | /* step 1 */ 32 | init_cpp(); 33 | 34 | /* step 2 */ 35 | no_special_macros = 0; 36 | emit_defines = emit_assertions = 0; 37 | 38 | /* step 3 -- with assertions */ 39 | init_tables(1); 40 | 41 | /* step 4 -- no default include path */ 42 | init_include_path(0); 43 | 44 | /* step 5 -- no need to reset the two emit_* variables set in 2 */ 45 | emit_dependencies = 0; 46 | 47 | /* step 6 -- we work with stdin, this is not a real filename */ 48 | set_init_filename("[stdin]", 0); 49 | 50 | /* step 7 -- we make sure that assertions are on, and pragma are 51 | handled */ 52 | init_lexer_state(&ls); 53 | init_lexer_mode(&ls); 54 | ls.flags |= HANDLE_ASSERTIONS | HANDLE_PRAGMA | LINE_NUM; 55 | 56 | /* step 8 -- input is from stdin */ 57 | ls.input = stdin; 58 | 59 | /* step 9 -- we do not have any macro to define, but we add any 60 | argument as an include path */ 61 | for (i = 1; i < argc; i ++) add_incpath(argv[i]); 62 | 63 | /* step 10 -- we are a lexer and we want CONTEXT tokens */ 64 | enter_file(&ls, ls.flags); 65 | 66 | /* read tokens until end-of-input is reached -- errors (non-zero 67 | return values different from CPPERR_EOF) are ignored */ 68 | while ((r = lex(&ls)) < CPPERR_EOF) { 69 | if (r) { 70 | /* error condition -- no token was retrieved */ 71 | continue; 72 | } 73 | /* we print each token: its numerical value, and its 74 | string content; if this is a PRAGMA token, the 75 | string content is in fact a compressed token list, 76 | that we uncompress and print. */ 77 | if (ls.ctok->type == PRAGMA) { 78 | unsigned char *c = (unsigned char *)(ls.ctok->name); 79 | 80 | printf("line %ld: <#pragma>\n", ls.line); 81 | for (; *c; c ++) { 82 | int t = *c; 83 | 84 | if (STRING_TOKEN(t)) { 85 | printf(" <%2d> ", t); 86 | for (c ++; *c != PRAGMA_TOKEN_END; 87 | c ++) putchar(*c); 88 | putchar('\n'); 89 | } else { 90 | printf(" <%2d> `%s'\n", t, 91 | operators_name[t]); 92 | } 93 | } 94 | } else if (ls.ctok->type == CONTEXT) { 95 | printf("new context: file '%s', line %ld\n", 96 | ls.ctok->name, ls.ctok->line); 97 | } else if (ls.ctok->type == NEWLINE) { 98 | printf("[newline]\n"); 99 | } else { 100 | printf("line %ld: <%2d> `%s'\n", ls.ctok->line, 101 | ls.ctok->type, 102 | STRING_TOKEN(ls.ctok->type) ? ls.ctok->name 103 | : operators_name[ls.ctok->type]); 104 | } 105 | } 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /ucpp/ucppi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Thomas Pornin 1999, 2000 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 4. The name of the authors may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #ifndef UCPP__UCPPI__ 31 | #define UCPP__UCPPI__ 32 | 33 | #include "cpp.h" 34 | #include "tune.h" 35 | 36 | /* 37 | * A macro represented in a compact form; simple tokens are represented 38 | * by one byte, containing their number. Tokens with a string value are 39 | * followed by the value (string finished by a 0). Macro arguments are 40 | * followed by the argument number (in one byte -- thus implying a hard 41 | * limit of 254 arguments (number 255 is for __VA_ARGS__). 42 | */ 43 | struct comp_token_fifo { 44 | size_t length; 45 | size_t rp; 46 | unsigned char *t; 47 | }; 48 | 49 | /* These declarations are used only internally by ucpp */ 50 | 51 | /* 52 | * S_TOKEN(x) checks whether x is a token type with an embedded string 53 | * ttMWS(x) checks whether x is macro whitespace (space, comment...) 54 | * ttWHI(x) checks whether x is whitespace (MWS or newline) 55 | */ 56 | #define S_TOKEN(x) STRING_TOKEN(x) 57 | #define ttMWS(x) ((x) == NONE || (x) == COMMENT || (x) == OPT_NONE) 58 | #define ttWHI(x) (ttMWS(x) || (x) == NEWLINE) 59 | 60 | /* 61 | * Function prototypes 62 | */ 63 | /* 64 | * from lexer.c 65 | */ 66 | #define init_cppm ucpp_init_cppm 67 | #define put_char ucpp_put_char 68 | #define discard_char ucpp_discard_char 69 | #define next_token ucpp_next_token 70 | #define grap_char ucpp_grap_char 71 | #define space_char ucpp_space_char 72 | 73 | void init_cppm(void); 74 | void put_char(struct lexer_state *, unsigned char); 75 | void discard_char(struct lexer_state *); 76 | int next_token(struct lexer_state *); 77 | int grap_char(struct lexer_state *); 78 | int space_char(int); 79 | 80 | /* 81 | * from assert.c 82 | */ 83 | struct assert { 84 | char *name; /* this must be the first field */ 85 | size_t nbval; 86 | struct token_fifo *val; 87 | }; 88 | 89 | #define cmp_token_list ucpp_cmp_token_list 90 | #define handle_assert ucpp_handle_assert 91 | #define handle_unassert ucpp_handle_unassert 92 | #define get_assertion ucpp_get_assertion 93 | 94 | int cmp_token_list(struct token_fifo *, struct token_fifo *); 95 | int handle_assert(struct lexer_state *); 96 | int handle_unassert(struct lexer_state *); 97 | struct assert *get_assertion(char *); 98 | 99 | /* 100 | * from macro.c 101 | */ 102 | struct macro { 103 | char *name; /* this must be the first field */ 104 | int narg; 105 | char **arg; 106 | int nest; 107 | int vaarg; 108 | #ifdef LOW_MEM 109 | struct comp_token_fifo cval; 110 | #else 111 | struct token_fifo val; 112 | #endif 113 | }; 114 | 115 | #define print_token ucpp_print_token 116 | #define handle_define ucpp_handle_define 117 | #define handle_undef ucpp_handle_undef 118 | #define handle_ifdef ucpp_handle_ifdef 119 | #define handle_ifndef ucpp_handle_ifndef 120 | #define substitute_macro ucpp_substitute_macro 121 | #define get_macro ucpp_get_macro 122 | #define dsharp_lexer ucpp_dsharp_lexer 123 | #define compile_time ucpp_compile_time 124 | #define compile_date ucpp_compile_date 125 | #define compile_adate ucpp_compile_adate 126 | #ifdef PRAGMA_TOKENIZE 127 | #define tokenize_lexer ucpp_tokenize_lexer 128 | #endif 129 | 130 | void print_token(struct lexer_state *, struct token *, long); 131 | int handle_define(struct lexer_state *); 132 | int handle_undef(struct lexer_state *); 133 | int handle_ifdef(struct lexer_state *); 134 | int handle_ifndef(struct lexer_state *); 135 | int substitute_macro(struct lexer_state *, struct macro *, 136 | struct token_fifo *, int, int, long); 137 | struct macro *get_macro(char *); 138 | 139 | extern struct lexer_state dsharp_lexer; 140 | extern char compile_time[], compile_date[], compile_adate[]; 141 | #ifdef PRAGMA_TOKENIZE 142 | extern struct lexer_state tokenize_lexer; 143 | #endif 144 | 145 | /* 146 | * from eval.c 147 | */ 148 | #define strtoconst ucpp_strtoconst 149 | #define eval_expr ucpp_eval_expr 150 | #define eval_line ucpp_eval_line 151 | 152 | unsigned long strtoconst(char *); 153 | unsigned long eval_expr(struct token_fifo *, int *, int); 154 | extern long eval_line; 155 | 156 | #define eval_exception ucpp_eval_exception 157 | 158 | #ifdef POSIX_JMP 159 | #define JMP_BUF sigjmp_buf 160 | #define catch(x) sigsetjmp((x), 0) 161 | #define throw(x) siglongjmp((x), 1) 162 | #else 163 | #define JMP_BUF jmp_buf 164 | #define catch(x) setjmp((x)) 165 | #define throw(x) longjmp((x), 1) 166 | #endif 167 | extern JMP_BUF eval_exception; 168 | 169 | /* 170 | * from cpp.c 171 | */ 172 | #define token_name ucpp_token_name 173 | #define throw_away ucpp_throw_away 174 | #define garbage_collect ucpp_garbage_collect 175 | #define init_buf_lexer_state ucpp_init_buf_lexer_state 176 | #ifdef PRAGMA_TOKENIZE 177 | #define compress_token_list ucpp_compress_token_list 178 | #endif 179 | 180 | char *token_name(struct token *); 181 | void throw_away(struct garbage_fifo *, char *); 182 | void garbage_collect(struct garbage_fifo *); 183 | void init_buf_lexer_state(struct lexer_state *, int); 184 | #ifdef PRAGMA_TOKENIZE 185 | struct comp_token_fifo compress_token_list(struct token_fifo *); 186 | #endif 187 | 188 | #define ouch ucpp_ouch 189 | #define error ucpp_error 190 | #define warning ucpp_warning 191 | 192 | #endif 193 | -------------------------------------------------------------------------------- /vars.c: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (vars.c) $Revision: 1.29 $ */ 2 | #include "vbc.h" 3 | #ifdef AMIGA 4 | static const char *__ver="$VER: vbcc 0.9g (20.09.2019)\r\n"; 5 | long __stack=65536; 6 | #endif 7 | char *s,*ident; 8 | char number[MAXI],buff[MAXI]; 9 | tunit *first_tunit,*last_tunit; 10 | struct_declaration *first_sd[MAXN],*last_sd[MAXN],*merk_sdf,*merk_sdl; 11 | struct_identifier *first_si[MAXN],*last_si[MAXN],*merk_sif,*merk_sil; 12 | identifier_list *first_ilist[MAXN],*last_ilist[MAXN],*merk_ilistf,*merk_ilistl; 13 | llist *first_llist,*last_llist; 14 | int nesting; 15 | hashtable *hash_ext; 16 | Var *first_var[MAXN],*last_var[MAXN],*merk_varf,*merk_varl,*first_ext,*last_ext; 17 | Var *block_vla[MAXN]; 18 | llist *vladeflabels[MAXN],*vlajmplabels[MAXN]; 19 | vlaadjust_list *vlaadjusts[MAXN]; 20 | rpair rp; 21 | FILE *out,*ic1,*ic2,*ppout,*cmdfile; 22 | int c99; 23 | int opencl; 24 | int disallow_statics; 25 | int header_cnt; 26 | int wpo,wpo_key; 27 | FILE *input_wpo; 28 | int nocode,dontdelete; 29 | int const_expr,for_decl; 30 | int registerpri=200,currentpri,looppri=10; 31 | int return_value,break_label,switch_typ,switch_count,switch_act; 32 | int pointer_call; 33 | int softfloat; 34 | int ecpp; 35 | type *return_typ; 36 | Var *return_var; 37 | zmax local_offset[MAXN]; 38 | int c_flags[MAXCF]={ 39 | VALFLAG,STRINGFLAG,0,0, 40 | VALFLAG,0,0,0, 41 | VALFLAG,FUNCFLAG,FUNCFLAG,VALFLAG, 42 | VALFLAG,0,0,0, 43 | 0,0,0,0, 44 | 0,0,0,0,0, 45 | VALFLAG,0,0,0,0, 46 | 0,VALFLAG,0,0,0,STRINGFLAG,0, 47 | VALFLAG,VALFLAG,0,VALFLAG,0, 48 | FUNCFLAG,FUNCFLAG,FUNCFLAG,0, 49 | 0,0,0,0, 50 | 0,0,0,VALFLAG 51 | }; 52 | char *c_flags_name[MAXCF]={ 53 | "O","o","ic1","ic2", 54 | "debug","noasm","quiet","ansi", 55 | "maxerrors","dontwarn","warn","maxoptpasses", 56 | "inline-size","+","cpp-comments","no-trigraphs", 57 | "no-inline-peephole","final","E","dontkeep-initialized-data", 58 | "strip-path","fp-associative","iso","no-alias-opt","no-multiple-ccs", 59 | "unroll-size","double-push","speed","size","unroll-all", 60 | "stack-check","inline-depth","g","c99","wpo","cmd","noitra", 61 | "misra","coloring","dmalloc","disable","soft-float", 62 | "misrawarn","misradontwarn","reserve-reg","ecpp", 63 | "short-push","unsigned-char","opencl","no-include-stack", 64 | "deps","deps-for-libs","no-cpp-warn","hash-size" 65 | }; 66 | union ppi c_flags_val[MAXCF]; 67 | char *inname; 68 | char **target_macros; 69 | Var *regsbuf[MAXR+1]; 70 | int regbnesting[MAXR+1]; 71 | const_list *first_clist,*last_clist; 72 | int afterlabel; 73 | terr_out err_out[]={ 74 | #include "errors.h" 75 | "",0 76 | }; 77 | int err_num=sizeof(err_out)/sizeof(err_out[0])-1; 78 | 79 | tmisra_err_out misra_err_out[]={ 80 | #include "misra_errors.h" 81 | 0,0,"",0 82 | }; 83 | 84 | #ifdef HAVE_ECPP 85 | struct_declaration *current_class=0; 86 | type *current_func=0; 87 | ecpp_dtor_list *ecpp_dlist[MAXN]; 88 | #endif 89 | 90 | char *cur_func="shouldn't happen!"; 91 | char *copyright="vbcc V0.9g (c) in 1995-2019 by Volker Barthelmann"; 92 | -------------------------------------------------------------------------------- /vbc.h: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (vbc.h) $Revision: 1.16 $ */ 2 | 3 | #include "supp.h" 4 | 5 | #define eval_constn(a) eval_const(&a->val,a->ntyp->flags) 6 | 7 | typedef struct identifier_list{ 8 | char *identifier; 9 | int length; 10 | struct identifier_list *next; 11 | } identifier_list; 12 | typedef struct struct_identifier{ 13 | /* int flags;*/ 14 | char *identifier; 15 | struct struct_declaration *sd; 16 | struct struct_identifier *next; 17 | } struct_identifier; 18 | 19 | #ifndef NODES 20 | #error wrong node 21 | typedef struct node{ 22 | int flags,lvalue,sidefx; 23 | type *ntyp; 24 | struct node *left; 25 | struct node *right; 26 | struct argument_list *alist; 27 | char *identifier; 28 | union atyps val; 29 | struct obj o; 30 | } node; 31 | 32 | typedef node *np; 33 | 34 | #define NODES sizeof(node) 35 | #endif 36 | 37 | typedef struct argument_list{ 38 | np arg; 39 | struct argument_list *next; 40 | struct IC *pushic; 41 | } argument_list; 42 | 43 | 44 | #define MAXI 512 /* maximale Laenge von Identifiers in Bytes */ 45 | #define MAXN 128 /* maximale Verschachtelung von Bloecken */ 46 | 47 | extern struct tunit *first_tunit,*last_tunit; 48 | extern type *arith_typ(type*,type *); 49 | extern void insert_constn(np); 50 | extern int int_erw(int); 51 | extern int type_expression(np,type *), 52 | compatible_types(type *,type *,int), 53 | compare_sd(struct struct_declaration *,struct struct_declaration *); 54 | #if HAVE_AOS4 55 | extern int aos4_attr(type *,char *); 56 | #endif 57 | extern np identifier_expression(void),constant_expression(void),string_expression(void), 58 | postfix_expression(void),unary_expression(void),cast_expression(void), 59 | multiplicative_expression(void),additive_expression(void), 60 | shift_expression(void),relational_expression(void),equality_expression(void), 61 | and_expression(void),exclusive_or_expression(void), 62 | inclusive_or_expression(void),logical_and_expression(void), 63 | logical_or_expression(void),conditional_expression(void), 64 | assignment_expression(void),expression(void),primary_expression(void); 65 | extern struct argument_list *argument_list_expression(void); 66 | extern struct const_list *cl_from_string(char *start, char *end); 67 | 68 | extern np new_node(void); 69 | 70 | /* puh */ 71 | extern int is_keyword(char *); 72 | extern void pre(FILE *,np),pra(FILE *,struct argument_list *); 73 | extern void free_expression(np),free_alist(struct argument_list *); 74 | extern void cpbez(char *m,int ckw),cpnum(char *m),killsp(void); 75 | extern void copy_token(/*no prototype because cpp.h not always included*/); 76 | extern void push_token(/*no prototype because cpp.h not always included*/); 77 | extern void next_token(void); 78 | extern struct struct_declaration *add_sd(struct struct_declaration *,int); 79 | extern void add_sl(struct struct_declaration *,struct struct_list (*)[]); 80 | extern void free_sd(struct struct_declaration *); 81 | extern void prl(FILE *,struct struct_declaration *); 82 | extern char *add_identifier(char *,int); 83 | extern type *declarator(type *),*direct_declarator(type *), 84 | *pointer(type *),*declaration_specifiers(void); 85 | extern int declaration(int),type_uncomplete(type *); 86 | extern struct const_list *initialization(type *,int,int,int,struct struct_declaration *,struct const_list *); 87 | extern void init_local_compound(struct Var *); 88 | extern zmax init_dyn_sz,init_const_sz; 89 | extern int init_dyn_cnt,init_const_cnt; 90 | extern struct struct_declaration *find_struct(char *,int); 91 | extern void add_struct_identifier(char *,struct struct_declaration *); 92 | extern void free_si(struct struct_identifier *); 93 | extern char *ident; 94 | extern char number[MAXI],buff[MAXI]; 95 | extern struct struct_declaration *first_sd[MAXN],*last_sd[MAXN],*merk_sdf,*merk_sdl; 96 | extern struct struct_identifier *first_si[MAXN],*last_si[MAXN],*merk_sif,*merk_sil; 97 | extern struct identifier_list *first_ilist[MAXN],*last_ilist[MAXN],*merk_ilistf,*merk_ilistl; 98 | extern void free_ilist(struct identifier_list *); 99 | extern int nesting; 100 | extern hashtable *hash_ext; 101 | extern struct Var *first_var[MAXN],*last_var[MAXN],*merk_varf,*merk_varl,*first_ext,*last_ext; 102 | extern struct Var *block_vla[MAXN]; 103 | extern struct llist *vladeflabels[MAXN],*vlajmplabels[MAXN]; 104 | extern struct vlaadjust_list *vlaadjusts[MAXN]; 105 | extern void freevl(void); 106 | extern void clearvl(void); 107 | extern void free_var(struct Var *); 108 | extern void var_declaration(void); 109 | extern int storage_class_specifiers(void); 110 | extern void enter_block(void),leave_block(void); 111 | extern struct Var *find_var(char *,int); 112 | extern struct Var *find_ext_var(char *); 113 | extern struct Var *add_var(char *,type *,int,struct const_list *); 114 | extern void fi_from_attr(struct Var *); 115 | 116 | extern int usz; 117 | 118 | extern int c99; 119 | extern int opencl; 120 | extern int disallow_statics; 121 | extern int header_cnt; 122 | extern int softfloat; 123 | #define MAGIC_WPO 123 124 | extern int wpo,wpo_key; 125 | extern FILE *input_wpo; 126 | 127 | extern void gen_IC(np,int,int),convert(np,int),gen_label(int); 128 | extern void gen_test(struct obj *,int,int,int); 129 | extern void savescratch(int,struct IC *,int,struct obj *); 130 | typedef struct regargs_list{ 131 | struct regargs_list *next; 132 | struct argument_list *al; 133 | int reg; 134 | struct Var *v; 135 | } regargs_list; 136 | #ifdef HAVE_REGPARMS 137 | extern zmax push_args(struct argument_list *,struct struct_declaration *,int,struct regargs_list **,struct reg_handle *,struct obj *,type *,int,type *); 138 | #else 139 | extern zmax push_args(struct argument_list *,struct struct_declaration *,int,struct regargs_list **); 140 | #endif 141 | extern int allocreg(int,int); 142 | extern void free_reg(int),alloc_hardreg(int); 143 | 144 | extern FILE *out,*ic1,*ic2,*ppout,*cmdfile; 145 | 146 | extern void statement(void),labeled_statement(void),if_statement(void); 147 | extern void switch_statement(void),while_statement(void),for_statement(void); 148 | extern void do_statement(void),goto_statement(void),continue_statement(void); 149 | extern void break_statement(void),return_statement(void); 150 | extern void expression_statement(void),compound_statement(void); 151 | extern void translation_unit(void); 152 | extern int main(int, char *[]); 153 | extern int nocode,dontdelete,registerpri,looppri,currentpri; 154 | extern int no_cast_free; 155 | 156 | extern np makepointer(np); 157 | 158 | typedef struct vlaadjust_list { 159 | struct IC *branch,*first; 160 | struct vlaadjust_list *next; 161 | } vlaadjust_list; 162 | 163 | extern int switch_typ,switch_count,switch_act; 164 | typedef struct llist{ 165 | char *identifier; 166 | int label,flags,switch_count; 167 | struct llist *next; 168 | union atyps val; 169 | } llist; 170 | #define LABELDEFINED 1 171 | #define LABELUSED 2 172 | #define LABELDEFAULT 4 173 | #define LSIZE sizeof(struct llist) 174 | extern struct llist *first_llist,*last_llist; 175 | extern struct llist *find_label(char *),*add_label(char *); 176 | extern void free_llist(struct llist *); 177 | 178 | extern int endok,return_label,return_value,break_label; 179 | extern int const_expr,for_decl; 180 | extern struct Var *return_var; 181 | extern type *return_typ; 182 | extern zmax local_offset[MAXN]; 183 | 184 | extern void scratch_var(struct obj *,int,type *); 185 | extern void get_scratch(struct obj *,int,int,type *); 186 | extern void gen_cond(struct obj *,int,int,int); 187 | 188 | #define MAXCF 60 189 | extern int c_flags[MAXCF]; 190 | extern char *c_flags_name[MAXCF]; 191 | extern union ppi c_flags_val[MAXCF]; 192 | 193 | extern FILE *open_out(char *,char *); 194 | 195 | extern char *inname; 196 | 197 | extern void gen_vars(struct Var *); 198 | 199 | /* Format der Tabelle fuer Fehlermeldungen */ 200 | typedef struct err_out{ 201 | char *text; 202 | int flags; 203 | } terr_out; 204 | 205 | 206 | /* Flags fuer err_out.flags */ 207 | #define ERROR 1 208 | #define WARNING 2 209 | #define ANSIV 4 210 | #define INTERNAL 8 211 | #define FATAL 16 212 | #define MESSAGE 32 213 | #define DONTWARN 64 214 | #define PREPROC 128 215 | #define NOLINE 256 216 | #define INFUNC 512 217 | #define INIC 1024 218 | #define NORAUS 2048 219 | 220 | extern struct err_out err_out[]; 221 | extern int err_num; 222 | 223 | typedef struct misra_err_out{ 224 | int chapter; 225 | int rule; 226 | char *text; 227 | int flags; 228 | } tmisra_err_out; 229 | 230 | extern struct misra_err_out misra_err_out[]; 231 | 232 | #define MISRA 1 233 | #define MISRA_PREPROC 2 234 | #define MISRA_2004 4 235 | #define MISRA_1998 8 236 | 237 | #ifdef HAVE_ECPP 238 | typedef struct ecpp_dtor_list { 239 | struct Var *var; 240 | struct ecpp_dtor_list *next; 241 | } ecpp_dtor_list; 242 | extern struct struct_declaration *current_class; 243 | extern type *current_func; 244 | extern struct ecpp_dtor_list *ecpp_dlist[MAXN]; 245 | struct Var *ecpp_find_ext_var(char *identifier); 246 | struct Var *ecpp_find_var(char *identifier); 247 | struct struct_declaration *ecpp_find_scope(char* nested_name,char** identifier); 248 | struct struct_list *ecpp_find_member(char* identifier,struct struct_declaration *scope,struct struct_declaration** ret_scope,int search_flag); 249 | void ecpp_auto_call_dtors(); 250 | int ecpp_is_friend(struct struct_declaration *class); 251 | #endif 252 | 253 | extern int afterlabel; 254 | 255 | extern int errors; 256 | 257 | extern int float_used; 258 | extern char *cur_func; 259 | extern int line; 260 | extern void free_clist(struct const_list *); 261 | extern struct const_list *first_clist,*last_clist; 262 | extern struct Var *regsbuf[MAXR+1]; 263 | extern int regbnesting[MAXR+1]; 264 | 265 | 266 | -------------------------------------------------------------------------------- /vbcc_cpp.h: -------------------------------------------------------------------------------- 1 | /* $VER: vbcc (vbcc_cpp.h) $Revision: 1.2 $ */ 2 | 3 | 4 | /* fix some name clashes between vbcc and ucpp and include cpp.h */ 5 | /* has to be include prior to other vbcc includes */ 6 | 7 | 8 | #define STRING T_STRING 9 | #define CHAR T_CHAR 10 | #define CAST T_CAST 11 | #define AND T_AND 12 | #define OR T_OR 13 | #define COLON T_COLON 14 | #define LOR T_LOR 15 | #define LAND T_LAND 16 | #define MINUS T_MINUS 17 | 18 | #define NO_UCPP_ERROR_FUNCTIONS 1 19 | #include "ucpp/cpp.h" 20 | 21 | typedef struct token token; 22 | typedef struct lexer_state lexer_state; 23 | typedef struct stack_context stack_context; 24 | 25 | extern token *ctok; 26 | extern lexer_state ls; 27 | 28 | #undef STRING 29 | #undef CHAR 30 | #undef CAST 31 | #undef AND 32 | #undef OR 33 | #undef COLON 34 | #undef LOR 35 | #undef LAND 36 | #undef MINUS 37 | 38 | #define next_token vbcc_next_token 39 | #undef error 40 | 41 | #undef S_TOKEN 42 | #define S_TOKEN(x) ((x) >= NUMBER && (x) <= T_CHAR) 43 | 44 | #define ttMWS(x) ((x) == NONE || (x) == COMMENT || (x) == OPT_NONE) 45 | #define ttWHI(x) (ttMWS(x) || (x) == NEWLINE) 46 | 47 | char *ucpp_token_name(); 48 | -------------------------------------------------------------------------------- /vbpp.h: -------------------------------------------------------------------------------- 1 | #ifndef _VBPP_H 2 | #define _VBPP_H 1 3 | 4 | /* vbpp.h 5 | * last change: 17.08.1995 Thorsten Schaaps 6 | */ 7 | 8 | /* strnode-types */ 9 | #define NORMAL 0 /* anything: brackets,+,-,/,*, etc.. */ 10 | #define PP_IDENT 1 /* possible identifier */ 11 | #define ARGUMENT 2 /* argument: see number */ 12 | #define PP_STR 3 /* strings */ 13 | #define NUMBER 4 /* numbers (123,0x00,0L,..) */ 14 | #define SPACE 5 /* spaces, tabs, etc. */ 15 | #define SPECIAL 6 /* flags=1->#,flags=2->## */ 16 | 17 | /* flags for type==SPECIAL */ 18 | #define NONE 0 19 | #define TOSTRING 1 /* #define t(c) #c */ 20 | #define KILLSPACES 2 /* #define t(a,b) a##b */ 21 | 22 | struct strnode{ 23 | char *str; /* the string =8) ah, you guessed that. */ 24 | int len; /* the length of the string */ 25 | int flags; /* flags: see above */ 26 | int type; /* type: see above */ 27 | int number; /* only valid if type==ARGUMENT */ 28 | struct strnode *prev,*next; /* pointers to previous and next node or NULL */ 29 | }; 30 | 31 | /* Macro-Node-Flags */ 32 | #define FUNCTION 1 /* for macros changing from line to line, e.g. */ 33 | /* __LINE__, __FILE__, __TIME__ etc.. */ 34 | #define PARAMETER 2 /* Macro has arguments */ 35 | #define NODELETE 4 /* Macro cannot be UNDEFined, e.g. __TIME__, */ 36 | /* __DATE__, __STDC__ */ 37 | #define NOREDEF 8 /* Macro cannot be reDEFINED, (s. above, but */ 38 | /* not __STDC__) */ 39 | 40 | /* Function-Numbers for FUNCTION-Macros */ 41 | #define FUNCLINE 1 /* __LINE__ */ 42 | #define FUNCFILE 2 /* __FILE__ */ 43 | #define FUNCDATE 3 /* __DATE__ */ 44 | #define FUNCTIME 4 /* __TIME__ */ 45 | /* __STDC__ is a normal macro, but cannot be deleted */ 46 | 47 | struct mnode{ 48 | char *name; /* name, e.g. SQR */ 49 | char *args; /* arguments, e.g. (x) */ 50 | char *token; /* definition as string, e.g. ((x)*(x)) */ 51 | /* BE CAREFULL: may be NULL in the future */ 52 | struct strnode *tokenlist; /* definition as list */ 53 | int flags; /* flags, see above */ 54 | int numargs; /* number of arguments */ 55 | int funcnum; /* number of function (see above) */ 56 | struct mnode *prev,*next; /* pointers to previos and next node or NULL */ 57 | }; 58 | 59 | /* Return-Codes for ExpandList/ExpandArgMakro/CloneArg-Functions */ 60 | #define OK 0 61 | #define OUT_OF_MEM -1 62 | #define NUM_OF_ARGS -2 63 | #define ARG_EXPECTED -3 64 | 65 | void AddMakroNode(struct mnode **, struct mnode *); 66 | void InsertMakroNode(struct mnode **, struct mnode *, struct mnode *); 67 | void RemMakroNode(struct mnode **, struct mnode *); 68 | struct mnode *FindMakroNode(struct mnode *, char *, int); 69 | void DelMakroNode(struct mnode **, struct mnode *); 70 | void DelMakroList(struct mnode **); 71 | 72 | void AddStrNode(struct strnode **, struct strnode *, char *); 73 | void RemStrNode(struct strnode **, struct strnode *); 74 | /* struct strnode *FindStrNode(struct strnode *, char *, int); */ 75 | void DelStrNode(struct strnode **, struct strnode *); 76 | void DelStrList(struct strnode **); 77 | struct strnode *CloneStrList(struct strnode *, struct strnode *); 78 | struct strnode *DoMakroFunction(struct mnode *); 79 | 80 | struct strnode *Str2List(char *); 81 | int List2Str(struct strnode *, char *, int); 82 | 83 | int ExpandList(struct strnode **); 84 | 85 | struct mnode *ParseIdentifier(char *); 86 | int PreParse(void); 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /vprof/vprof.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vprof 3 | * 4 | * vbcc profiler. Displays the contents of "mon.out" files. 5 | * (C)1998,2010 by Frank Wille 6 | * 7 | * vprof is freeware and part of the portable and retargetable ANSI C 8 | * compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann. 9 | * vprof may be freely redistributed as long as no modifications are 10 | * made and nothing is charged for it. Non-commercial usage is allowed 11 | * without any restrictions. 12 | * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE 13 | * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #define VERSION 0 21 | #define REVISION 2 22 | #define PLEVEL 0 23 | #define DEFAULTNAME "mon.out" 24 | 25 | struct profdata { 26 | char *funcname; 27 | unsigned long ncalls; 28 | unsigned long tottime; 29 | unsigned long loctime; 30 | }; 31 | 32 | 33 | static void show(struct profdata *pdata,int n) 34 | /* write profdata records to stdout */ 35 | { 36 | struct profdata *p; 37 | unsigned long runtime; 38 | int i; 39 | 40 | for (i=0,p=pdata,runtime=0; iloctime; 42 | 43 | printf(" %% total local local total\n" 44 | " time seconds seconds calls ms/call ms/call name\n"); 45 | for (i=0,p=pdata; iloctime/(double)runtime)*100.0, 48 | (double)p->tottime/1000000.0, 49 | (double)p->loctime/1000000.0, 50 | p->ncalls, 51 | ((double)p->loctime/(double)p->ncalls)/1000.0, 52 | ((double)p->tottime/(double)p->ncalls)/1000.0, 53 | p->funcname); 54 | } 55 | } 56 | 57 | 58 | static int cmp_total(const void *pd1,const void *pd2) 59 | { 60 | return ((int)(((struct profdata *)pd2)->loctime - 61 | ((struct profdata *)pd1)->loctime)); 62 | } 63 | 64 | 65 | static void show_local(struct profdata *pd,int n) 66 | /* show profiling data, sorted according to the local time */ 67 | /* spent in each function */ 68 | { 69 | qsort(pd,n,sizeof(struct profdata),cmp_total); 70 | show(pd,n); 71 | } 72 | 73 | 74 | static char *skipname(char *p) 75 | /* skip name and alignment bytes and return pointer to profile data */ 76 | { 77 | int n = strlen(p)+1; 78 | 79 | p += n; 80 | if (n &= 3) 81 | p += 4-n; 82 | return (p); 83 | } 84 | 85 | 86 | int main(int argc,char *argv[]) 87 | { 88 | char *mname; 89 | FILE *fp; 90 | long size,len; 91 | char *buf,*p; 92 | int i,nrecs = 0; 93 | struct profdata *pdata,*pd; 94 | 95 | if (argc >= 2) { 96 | if (*argv[1]=='-' || *argv[1]=='?') { 97 | printf("%s V%d.%d%c (c)1998,2010 by Frank Wille\n" 98 | "Usage:\n %s [mon.out]\n",argv[0], 99 | VERSION,REVISION,PLEVEL?('a'+PLEVEL-1):' ',argv[0]); 100 | exit(1); 101 | } 102 | else 103 | mname = argv[1]; 104 | } 105 | else 106 | mname = DEFAULTNAME; 107 | 108 | if (fp = fopen(mname,"r")) { 109 | /* determine file size */ 110 | fseek(fp,0,SEEK_END); 111 | size = ftell(fp); 112 | fseek(fp,0,SEEK_SET); 113 | if (size < 0) { 114 | fclose(fp); 115 | fprintf(stderr,"%s: Seek error on %s!\n",argv[0],mname); 116 | exit(EXIT_FAILURE); 117 | } 118 | 119 | /* allocate buffer and read file */ 120 | if (!(buf = malloc(size))) { 121 | fclose(fp); 122 | fprintf(stderr,"%s: Not enough memory!\n",argv[0]); 123 | exit(EXIT_FAILURE); 124 | } 125 | if (fread(buf,1,size,fp) != size) { 126 | fclose(fp); 127 | fprintf(stderr,"%s: %s had a read error!\n",argv[0],mname); 128 | exit(EXIT_FAILURE); 129 | } 130 | fclose(fp); 131 | 132 | /* count number of entries in mon.out and allocate profdata array */ 133 | p = buf; 134 | while (p < buf+size) { 135 | nrecs++; 136 | p = skipname(p) + 3*sizeof(unsigned long); 137 | } 138 | if (p!=buf+size || nrecs==0) { 139 | fprintf(stderr,"%s: %s: Corrupted file format.\n",argv[0],mname); 140 | exit(EXIT_FAILURE); 141 | } 142 | if (!(pdata = malloc(nrecs * sizeof(struct profdata)))) { 143 | fprintf(stderr,"%s: Not enough memory!\n",argv[0]); 144 | exit(EXIT_FAILURE); 145 | } 146 | 147 | /* fill profdata array */ 148 | for (i=0,p=buf,pd=pdata; ifuncname = p; 150 | p = skipname(p); 151 | pd->ncalls = *(unsigned long *)p; 152 | pd->tottime = *(unsigned long *)(p+sizeof(unsigned long)); 153 | pd->loctime = *(unsigned long *)(p+2*sizeof(unsigned long)); 154 | p += 3*sizeof(unsigned long); 155 | } 156 | 157 | /* display */ 158 | show_local(pdata,nrecs); 159 | } 160 | else { 161 | fprintf(stderr,"%s: Can't open %s.\n",argv[0],mname); 162 | exit(EXIT_FAILURE); 163 | } 164 | 165 | return 0; 166 | } 167 | -------------------------------------------------------------------------------- /vsc/vsc.c: -------------------------------------------------------------------------------- 1 | /* vsc - portable instruction scheduler for vbcc. */ 2 | /* (c) 1997-99 by Volker Barthelmann. */ 3 | 4 | #include "vsc.h" 5 | 6 | char vs_copyright[]="vsc scheduler V0.1 (c) 1997-99 by Volker Barthelmann"; 7 | 8 | #define MAX_INS 128 9 | #define LINELENGTH 1024 10 | 11 | #ifndef DEBUG 12 | int DEBUG; 13 | #endif 14 | 15 | struct sinfo silist[MAX_INS]; 16 | int si_count; 17 | int done; 18 | 19 | int bvcmp(unsigned char *dest,unsigned char *src,size_t len) 20 | /* vergleicht zwei Bitvektoren */ 21 | { 22 | for(;len>0;len--) 23 | if(*dest++!=*src++) return(0); 24 | return(1); 25 | } 26 | void bvunite(unsigned char *dest,unsigned char *src,size_t len) 27 | /* berechnet Vereinigung zweier Bitvektoren */ 28 | { 29 | for(;len>0;len--) 30 | *dest++|=*src++; 31 | } 32 | void bvintersect(unsigned char *dest,unsigned char *src,size_t len) 33 | /* berechnet Durchschnitt zweier Bitvektoren */ 34 | { 35 | for(;len>0;len--) 36 | *dest++&=*src++; 37 | } 38 | void bvdiff(unsigned char *dest,unsigned char *src,size_t len) 39 | /* berechnet 'Differenz' zweier Bitvektoren */ 40 | { 41 | for(;len>0;len--) 42 | *dest++&=~(*src++); 43 | } 44 | 45 | void raus(void) 46 | { 47 | sched_cleanup(); 48 | if(DEBUG&1) printf("raus\n"); 49 | if(done) 50 | exit(EXIT_SUCCESS); 51 | else 52 | exit(EXIT_FAILURE); 53 | } 54 | void *mymalloc(size_t sz) 55 | { 56 | void *p=malloc(sz); 57 | if(!p){ 58 | puts("Out of memory!"); 59 | raus(); 60 | } 61 | return p; 62 | } 63 | void print_sinfo(void) 64 | { 65 | struct sinfo *p;int i,j; 66 | if(DEBUG&2) 67 | printf("print_sinfo\n"); 68 | else 69 | return; 70 | for(j=0;jtxt); 73 | printf("flags=%u, label=%u latency=%u\n",p->flags,p->label,p->latency); 74 | printf("available pipelines: "); 75 | for(i=0;ipipes,i)) 77 | printf("%d ",i); 78 | printf("\nuses registers (%d=mem): ",MEM); 79 | for(i=0;i<=MEM;i++) 80 | if(BTST(p->uses,i)) 81 | printf("%d ",i); 82 | printf("\nmodifies registers (%d=MEM): ",MEM); 83 | for(i=0;i<=MEM;i++) 84 | if(BTST(p->modifies,i)) 85 | printf("%d ",i); 86 | printf("\n\n"); 87 | } 88 | } 89 | void free_sinfo(void) 90 | { 91 | int j; 92 | for(j=0;j0) printf("latency[%d]=%d\n",i,latency[i]); 108 | } 109 | /* Mark all instructions which are ready. */ 110 | memset(modified,0,REGS_SIZE); 111 | memset(used,0,REGS_SIZE); 112 | for(i=0;i0) k=1; 125 | } 126 | if(!k) silist[i].flags|=READY; 127 | } 128 | } 129 | bvunite(modified,silist[i].modifies,REGS_SIZE); 130 | bvunite(used,silist[i].uses,REGS_SIZE); 131 | } 132 | 133 | /* Fill pipeline slots with ready instructions. */ 134 | for(i=0;isilist[pipes[j]].latency){ 150 | pipes[j]=i; 151 | k=1; 152 | } 153 | } 154 | } 155 | if(DEBUG&4) printf("instructions for cycle %d:\n",cycle); 156 | for(i=0;i=0){ 158 | if(DEBUG&4) printf("%3d: %s",i,silist[pipes[i]].txt); 159 | fprintf(f,"%s",silist[pipes[i]].txt); 160 | silist[pipes[i]].flags|=OUT; 161 | remaining--; 162 | for(j=0;j<=MEM;j++){ 163 | if(BTST(silist[pipes[i]].modifies,j)) latency[j]=silist[pipes[i]].latency; 164 | } 165 | } 166 | } 167 | for(i=0;i<=MEM;i++) 168 | if(latency[i]>0) latency[i]--; 169 | } 170 | } 171 | int main(int argc,char *argv[]) 172 | { 173 | char s[LINELENGTH];int i,quiet=0; 174 | FILE *in,*out; char *inname=0,*outname=0; 175 | for(i=1;i=MAX_INS){ 226 | if(DEBUG&1) printf("MAX_INS reached: %s",silist[si_count].txt); 227 | output_scheduled(out); 228 | free_sinfo(); 229 | si_count=0; 230 | } 231 | } 232 | } 233 | output_scheduled(out); 234 | free_sinfo(); 235 | done=1; 236 | raus(); 237 | } 238 | 239 | 240 | -------------------------------------------------------------------------------- /vsc/vsc.h: -------------------------------------------------------------------------------- 1 | /* vsc portable scheduler (c) 1997-99 by Volker Barthelmann */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define BSET(array,bit) (array)[(bit)/CHAR_BIT]|=1<<((bit)%CHAR_BIT) 9 | #define BCLR(array,bit) (array)[(bit)/CHAR_BIT]&=~(1<<((bit)%CHAR_BIT)) 10 | #define BTST(array,bit) ((array)[(bit)/CHAR_BIT]&(1<<((bit)%CHAR_BIT))) 11 | 12 | /* An instruction with LABEL set is preceded with a numbered label. */ 13 | /* The number is in