# HG changeset patch # User mir3636 # Date 1540430467 -32400 # Node ID d34655255c7895bb2bda172bd81b508e25028727 # Parent e108057fa461d2c2bb4852fa71b069540a637a7c# Parent 84e7813d76e95210763b10d5b6c894ed89b7a0b4 update gcc-8.2 diff -r 84e7813d76e9 -r d34655255c78 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,10 @@ +syntax: glob + +*.o +*.s +.*.swp +.*.swo +GTAGS +GRTAGS +GSYMS +GPATH diff -r 84e7813d76e9 -r d34655255c78 .hgtags --- a/.hgtags Thu Oct 25 07:37:49 2018 +0900 +++ b/.hgtags Thu Oct 25 10:21:07 2018 +0900 @@ -1,5 +1,3 @@ -a06113de4d676b497759e6a9bf820a208b02e09b gcc-4.4.0 -855418dad1a3a87de4782b8184eef35cd8812e23 gcc-4.4.2 -ae3a4bfb450bd98011c4167c72bb1d5ad73cdd51 gcc-4.4.3 77e2b8dfacca7d714bc9daeb6169b88f9d7c35eb gcc-4.4.5 b7f97abdc51746370aa15065311ea13e56c08d1f gcc-4.6-20100522 +4d6300120c296e398e8730ef2f5be373b75650ca cbc-gcc-4.6.0 diff -r 84e7813d76e9 -r d34655255c78 .hgtags.orig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgtags.orig Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,1 @@ +77e2b8dfacca7d714bc9daeb6169b88f9d7c35eb gcc-4.4.5 diff -r 84e7813d76e9 -r d34655255c78 CbC-DEVEL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-DEVEL Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,25 @@ +GCC 4.4.3 -> 4.5.0 へのアップデートの作業メモ + +オリジナルのgcc-core 4.5.0と mergeして、衝突は全て解決 + +make時にエラー,未解決 -> (CbC-MAKELOG にログがのってます) +関数/マクロの引数構成に変更 +) build_decl,c_finish_stmt_expr,, -> locationの追加 +) buid_modify_expr, build_external_ref -> 色々変更 + +# GCCのソース中の用法を見る。コメントを読む。 +# locationに関しては間違っても動く。 + +全てc-parser.c のcbc拡張の古い部分の変更 + +-- + +cbc-goto.hでエラー(消された関数を使用) -> targetm.calls.promote_funciton_return(funtype) + + gcc/ChangeLog より -- + (expand_call): When making sibcall decisions, use promote_function_mode. + Below, remove an if for targetm.calls.promote_function_return and + and use promote_function_mode. + -- + + diff -r 84e7813d76e9 -r d34655255c78 CbC-INSTALL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-INSTALL Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,238 @@ + + * CbC on GCCのインストール方法 + +まずはMercurialリポジトリから取得 + hg clone ssh://one@firefly.cr/hg/CbC/GCC cbc-gcc +ビルド用ディレクトリへ + mkdir build-gcc; cd build-gcc +コンフィギュア +一般的には以下のconfigureでビルドできる + ../cbc-gcc/configure CFLAGS="-g3 -O0" + --prefix=$PWD/INSTALL_DIR --disable-nls \ + --disable-bootstrap --enable-languages=c \ + --enable-checking=tree,rtl,assert,types + + -g3: + gdbでmacroの展開を可能にする + -O0: + gdbでトレースしやすいように、最適化をカット + --prefix: + インストールするベースディレクトリ + --enbale-checking: + デバグ用の指定、browse_treeやdebug_rtx、assertもこれでonになる + --disable-bootstrap: + 通常、GCCは3回ビルドされる。それを最初の1回だけに限定 + --disable-nls: + gettextのl10nをoffにしよう + --enable-language: + 使用する言語 c|c++|ada ... もちろんCbCはcだけ + これもcbcを使えるようにしたい +ビルド +make && make install + + * test + +gcc はできないので、cc1 をそのまま使います。 + + % gcc/cc1 -O3 ../cbc-gcc/CbC-examples/conv1.c + + -O3 は必須。そうでないと正しくコンパイルされません。 + + % gcc ../cbc-gcc/CbC-examples/conv1.s + % ./a.out 0 + #0193:720 + % ./a.out 1 + #0103:719 + % ./a.out 2 + #0132:470 + % ./a.out 3 + #0165:720 + + + + * PowerPC Macでのインストール + +最新のlibgmp, libmpfrをインストール +[gmp] + ./configure --enable-cxx --build=powerpc-apple-darwin9 --host=powerpc-apple-darwin9 + make && make install +[mpfr] + ./configure --build=powerpc-apple-darwin9 --host=powerpc-apple-darwin9 + make && make install +[CbC on GCC] + ../cbc-gcc/configure CFLAGS="-g3 -O0" --with-gmp=/usr/local + --with-mpfr=/usr/local --prefix=$PWD/INSTALL_DIR \ + --disable-nls --disable-bootstrap --enable-languages=c \ + --enable-checking=tree,rtl,assert,types + make && make install +もちろんインストール場所によってprefixは変更しよう + + + + + * PS3でのビルド + SPU + $ ../GCC/configure CFLAGS='-g -O0' --prefix=$PWD/INSTALL_DIR + --disable-nls --disable-shared --disable-threads + --enable-checking=tree,rtl,assert --with-system-zlib + --with-newlib --enable-languages=c + --enable-version-specific-runtime-libs --disable-libssp + --program-prefix=cbc-spu- --target=spu --disable-bootstrap + $ make && make install + $ cd INSTALL_DIR; ln -s /usr/spu; cd .. + で、動作確認のあと + $ sudo make prefix=/usr/local/cbc install + $ cd /usr/local/cbc; ln -s /usr/spu; cd - + + PPU + $ ../GCC/configure --prefix=$PWD/INSTALL_DIR + --host=ppc64-redhat-linux --build=ppc64-redhat-linux + --target=ppc64-redhat-linux --program-prefix=cbc- --disable-bootstrap + --enable-checking=tree,rtl,assert --disable-nls --enable-shared + --enable-thread=posix --enable-languages=c --with-system-zlib + --enable-__cxa_atexit --disable-libunwind-exceptions --disable-dssi + --enable-plugin --with-long-double-128 --with-gnu-as + --with-as=/usr/bin/as --with-gnu-ld --with-ld=/usr/bin/ld + --with-cpu=default32 + $ make && make install + 動作確認 + $ make prefix=/usr/local/cbc install + + + + * 琉球大学総合情報センターのSolarisサーバでのビルド (sparc) + +なぜかデフォルトのgccが自分のライブラリすら見てくれないのでパスを指定 + export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/gcc:$HOME/opt/lib + export LIBRARY_PATH=/usr/local/lib:/usr/local/lib/gcc:$HOME/opt/lib +gmpのインストール + ./configure --prefix=$HOME/opt \ + --build=sparc-sun-solaris \ + --host=sparc-sun-solaris + make + make check + make install +libmpfrのインストール + ./configure --prefix=$HOME/opt/ \ + --with-gmp=$HOME/opt + --build=sparc-sun-solaris \ + --host=sparc-sun-solaris + make + make check + make install + # sparc-sun-solaris2.10の方がいいかもしれない +CbCをインストール + ../CbCGCC/configure --prefix=$PWD/INSTALL_DIR --disable-nls \ + --disable-bootstrap --enable-languages=c \ + --with-gmp=$HOME/opt --with-mpfr=$HOME/opt \ + --build=sparc-sun-solaris2.10 --target=sparc-sun-solaris2.10 \ + --host=sparc-sun-solaris2.10 --enable-shared \ + --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld + make + make install +ビルドは可能。 +ただし、実行は不能 goto cs();すら動かない +config/sparc/sparc.cのoutput_sibcall()でエラーが出る +gdbがインストールされてないので詳細は未調査 +もしかしてsibcallってあまり実装されてないんじゃ… + + + +___________________________________________________________ + PS3用のクロスコンパイラの作成 +----------------------------------------------------------- + +PS3でのGCCのビルドはメモリが少なすぎるためか、insn-*.cのコンパイルに膨 +大な時間がかかってしまう。 +なので別のマシンからPS3をターゲットとしたクロスコンパイラを作成する。 +ただしこれはCbConGCCの開発のためと考えた方が良い。実際にCbC言語を使っ +たプログラムをPS3で開発する際はちゃんとPS3上にノンクロスコンパイラを作 +成しよう。時間はかかるがビルドは可能。 + + * 必要なもの + o binutilsのソース + o gccのソース + o ターゲットマシンのlib*.{a,so}類 + o ターゲットマシンの.hファイル + ~/PS3CROSSにクロスコンパイラ環境を整えるとする + ~/PS3CROSS/cross-tools: クロスコンパイルに使うツールのインストール先 + ~/PS3CROSS/sources: ソース置き場、出来上がったら消してもいいよ + ~/PS3CROSS/target-env: ターゲット環境(libやinclude)が入ったディレクトリ + + * 準備 + $ CROSS=$HOME/PS3CROSS + $ cd $CROSS + $ mkdir sources cross-tools target-env + $ cd sources + $ wget ... binutilsとかgccのソースをダウンロード + + * binutilsのビルド + $ tar xvf binutils..tar.gz + $ mkdir PS3-binutils-build; cd !#1 + $ ../binutils-.../configure --prefix=$CROSS/cross-tools \ + --with-lib-path=$CROSS/target-env \ + --hosti686-pc-linux-gnu --build=i686-pc-linux-gnu \ + --target=ppc64-redhat-linux --enable-64-bit-bfd \ + --disable-nls --enable-shared --with-sysroot + $ make && make install + + * ターゲットマシンの環境をコピーする + $ cd $CROSS/target-env + $ mkdir include lib lib64 + $ ln -s . usr + ## 必要なライブラリはすべてコピー + $ cd lib + $ rsync -avl 'charles.cr:/lib/libc[.-_]*' ./ + $ rsync -avl 'charles.cr:/usr/lib/libc[.-_]*' ./ + $ rsync -avl 'charles.cr:/usr/lib/crt*' ./ + $ rsync -avl 'charles.cr:/lib/ld*' ./ + $ cd ../lib64 + $ ..... + ## ヘッダは軽いので全部コピー + $ cd ../include + $ rsync -avl 'charles.cr:/usr/include/*' ./ + + * GCCのビルド + $ cd $CROSS/sources + $ mkdir PS3-gcc-build; cd !#1 + $ ../.../configure --prefix=$CROSS/cross-tools + --host=i686-pc-linux-gnu --target=ppc64-redhat-linux + --with-sysroot=$CROSS/target-env --disable-nls + --disable-shared --disable-threads + --enable-languages=c --without-headers + --disable-bootstrap + $ make all-gcc + $ make ## エラーで終わるけど気にするな + $ make install-gcc + $ make install-target-libgcc + + * テスト + $ cat >test.c < + int + main(int argc, char **argv) + { + int a=0; + int i; + for (i=0; i<10; i++) { + a = i; + } + printf("hello world\n"); + printf("a = %d\n", a); + return a; + } + EOF + $ $CROSS/cross-tools/bin/gcc -m32 test.c -o test32 + $ $CROSS/cross-tools/bin/gcc -m64 test.c -o test64 + $ file test32 test64 + test32: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped + test64: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped + $ scp test{32,64} PS3Machine: + PS3Machine $ ./test32 + + + + + + + diff -r 84e7813d76e9 -r d34655255c78 CbC-REPOSITORY --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-REPOSITORY Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,57 @@ + + * CbC/GCCのリポジトリ管理方法 + +Continuation based C のGCC実装用には二つのリポジトリを仕様する + + o CbC/GCC + 実際にCbCを実装したGCCの本体 + o CbC/GCC_original + オリジナルのGCC。本家のgcc-core-4.x.yをそのままリポジトリ化。 + +GCC_origのほうはGCCがリリースされる度にバージョンアップさせ、コミットする。 +さらにその変更をCbC用のGCCリポジトリにpushする + + 本家 + release GCC_orig GCC + | | | + | 4.4.0 4.4.0-cbc + 4.4.1 up | | + | --> 4.4.1 push | + | | --> 4.4.1-cbc + | | | + 4.4.2 up | | + | --> 4.4.2 push | + | | --> 4.4.2-cbc + | | | + + + * 本家GCCのニューリリース時の対応 + +GCC_originalをアップデート + $ cd $HOME + $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.4.1/gcc-core-4.x.y.tar.gz + $ tar xvf gcc-core-4.x.y.tar.gz + $ cd gcc-4.x.y + $ cd ${HG_REPO}/CbC/GCC_original + $ rm -rf * + $ mv ${HOME}/gcc-4.4.1/* ./ + $ hg commit + +GCC_originalが最新のGCCになったら、その変更をGCCにpushする +GCC_originalからGCCへのpush + $ cd ${HOME} + $ mkdir workspace;cd workspace # 作業ディレクトリ作成 + $ hg clone ${HG}/one/CbC/GCC # CbC用のGCCをクローン + $ cd GCC + $ hg incoming ${HG}/one/CbC/GCC_original # チェック + $ hg pull ${HG}/one/CbC/GCC_original # pull + +この時点で、場合によっては衝突が起こる。ほとんどはgcc/calls.cの中だと +思われる。また、expand_call関数が大幅に変更されたならgcc/cbc-goto.hも +同じように書き換える必要があるかもしれない。 +がんばって動くまで修正したら + $ hg commit + $ hg push ${HG}/one/CbC/GCC # push +これで最新版に更新される + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/Makefile Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,11 @@ +TEST = arg.exe conv1.exe fact-a.exe goto.exe loto6.exe stack1.exe test02.exe test05.exe test1.exe test2.exe test_cs.exe test_csp1.exe test_env.exe test_func2code.exe test_para2.exe test_para3.exe test_para4.exe test_para.exe test_tree.exe tmp1.exe tmp2.exe tmp4.exe tmpa.exe too-long-argument.exe + +.SUFFIXES: .exe + +.c.exe : + ${CBC_COMPILER} $(CFLAGS) -o $@ $< + +test : $(TEST) + for exe in ${TEST} ; do \ + ./$${exe} ; \ + done diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/arg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/arg.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,112 @@ +#include "stdio.h" + +#define __environment _CbC_environment +#define __return _CbC_return + + +struct arg { + int a0;int a1;int a2;int a3;int a4; +}; + +extern void exit(int); + +void *exit_env; +__code (*exit___code)(); + +#ifndef __llvm__ +__code carg2(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(int, void*),void *env); +__code cargs(struct arg args0,__code exit1(int, void*),void *env); +__code carg4(struct arg args0,struct arg args1,int i, int j,int k,int l); +__code carg5(struct arg args0,struct arg args1,int i, int j,int k,int l); +__code carg6(int i, int j,int k,int l,struct arg args0); +#endif + +__code carg1(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(int, void*),void *env) +{ + printf("#0017:arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1==exit___code,env==exit_env); + goto carg2(arg1,arg2,arg3,arg4,arg0,exit1,env); +} + +__code carg2(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(int, void*),void *env) +{ + struct arg args0; + printf("#0024:arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1==exit___code,env==exit_env ); + args0.a0 = arg0; + args0.a1 = arg1; + args0.a2 = arg2; + args0.a3 = arg3; + args0.a4 = arg4; + goto cargs(args0,exit1,env); +} + +__code cargs(struct arg args0,__code exit1(int, void*),void *env) +{ + printf("#0035:args: %d %d %d %d %d : %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4, + exit1==exit___code,env==exit_env); + // goto exit1(321),env; + goto (*exit1)(0,env); +} + + +__code carg3(struct arg args0,struct arg args1,int i, int j,int k,int l) +{ + printf("#0045:args3: %d %d %d %d %d : %x %x %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,i,j,k,l); + printf("#0047:args3: args0 %d %d %d %d %d : args1 %d %d %d %d %d : %x %x %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4, + args1.a0,args1.a1,args1.a2,args1.a3,args1.a4, + i,j,k,l); + if (args0.a0==args1.a0) exit(0); + goto carg4(args0,args1,j,k,l,i); +} + +__code carg4(struct arg args0,struct arg args1,int i, int j,int k,int l) +{ + printf("#0057:args4: %d %d %d %d %d : %x %x %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,i,j,k,l); + goto carg5(args1,args0,j,k,l,i); +} + +__code carg5(struct arg args0,struct arg args1,int i, int j,int k,int l) +{ + printf("#0064:args5: %d %d %d %d %d : %x %x %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,i,j,k,l); + goto carg6(i,j,k,l,args0); +} + +__code carg6(int i, int j,int k,int l,struct arg args0) +{ + printf("#0071:args6: %d %d %d %d %d : %x %x %x %x\n", + args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,i,j,k,l); + goto carg3(args0,args0,i,j,k,l); +} + +int main1(int n) +{ + goto carg1(0,1,2,3,4,exit___code=__return,exit_env=__environment); + return n; +} + +struct arg a00; +struct arg a01; + +int main( int ac, char *av[]) +{ + int n; + n = main1(123); + printf("#0089:321=%d\n",n); + + a00.a0 = 11; + a00.a1 = 22; + a00.a2 = 33; + a00.a3 = 44; + a00.a4 = 55; + a01.a0 = 66; + a01.a1 = 77; + a01.a2 = 88; + a01.a3 = 99; + a01.a4 = 10; + goto carg3(a00,a01,1,2,3,4); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/code_segment_pointer_check/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/Makefile Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,25 @@ + +CbCC=../../../build_cbc44/INSTALL_DIR/bin/gcc + +#CC=gcc +CC=../../../build_cbc44/INSTALL_DIR/bin/gcc + + +# fastcall版では-O0,-O2は動作確認、-O3以上はだめ +CFLAGS=-g -O2 -fomit-frame-pointer +#CFLAGS=-g -O0 + +.SUFFIXES: .cbc .o + +all: code_segment_pointer_check2 + +.cbc.o: + $(CbCC) $(CFLAGS) -c -o $@ $< + +code_segment_pointer_check2: code_segment_pointer_check2.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s code_segment_pointer_check2 + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/code_segment_pointer_check/code_segment_check.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_check.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,57 @@ +#include +#include +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(1), ## args) + +/* + * コードセグメント間の遷移をテスト + * + */ + +__code end (int a); +__code cs0a (int a, double b, int c, float d, char e); +__code cs1a (char e, int a, double b, int c, float d); +__code cs2a (float d, char e, int a, double b, int c); +__code cs3a (int c, float d, char e, int a, double b); +__code cs4a (double b, int c, float d, char e, int a); +int main (); + +__code end(int a) { + dprint("exit code is %d\n",a); + exit(a); +} + +int i=0; +__code cs0a(int a, double b, int c, float d, char e) { + if ( i++ >= 10 ) { + dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto end((int)(a*b*c*d*e)); + } + goto cs1a(e, a, b, c, d); +} +__code cs1a(char e, int a, double b, int c, float d) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs2a(d, e, a, b, c); +} +__code cs2a(float d, char e, int a, double b, int c) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs3a(c, d, e, a, b); +} +__code cs3a(int c, float d, char e, int a, double b) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs4a(b, c, d, e, a); +} +__code cs4a(double b, int c, float d, char e, int a) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs0a(a, b, c, d, e); +} + +__code starter(int a, double b, int c, float d, char e) { + dprint("exit code is expected to %d\n",(int)(a*b*c*d*e)); + dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs0a(a,b,c,d,e); +} +int main() { + goto starter(11, 22.2, 33, 44.44, 55); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/code_segment_pointer_check/code_segment_pointer_check.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,120 @@ +#include +#include +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(0), ## args) + +/* + * コードセグメント間の遷移で + * + * + * + */ + +__code schedule (); +__code cs0a (); +__code cs1a (int a); +__code cs2a (int a, double b); +__code cs3a (int a, double b, int c); +__code cs4a (int a, double b, int c, float d); +__code cs0b (); +__code cs1b (int a); +__code cs2b (int a, double b); +__code cs3b (int a, double b, int c); +__code cs4b (int a, double b, int c, float d); + +/* defined in file code_segment_pointer_check.cbc at offset 1649 */ +int main (); + +__code end(int a) { + dprint("exit with code %d\n",a); + exit(a); +} + +__code (*cs0) (); +__code (*cs1) (int); +__code (*cs2) (int, double); +__code (*cs3) (int, double, int); +__code (*cs4) (int, double, int, float); +int i=0; +__code schedule() { + dprint("i=%d\n",i); + if ( i>=100 ) { + goto end(0); + } + switch (i++%5) { + case 0: + goto cs0(); + case 1: + goto cs1(i); + case 2: + goto cs2(i, i*1.3); + case 3: + goto cs3(i, i*1.3, 20*i); + case 4: + goto cs4(i, i*1.3, 20*i, i*0.8); + default: + exit(0); + } + dprint("code unreachable!\n"); +} + +__code cs0a() { + dprint("no args\n"); + cs0 = cs0b; + goto schedule(); +} +__code cs1a(int a) { + dprint("int a=%d\n", a); + cs1 = cs1b; + goto schedule(); +} +__code cs2a(int a, double b) { + dprint("int a=%d, double b=%lf\n", a, b); + cs2 = cs2b; + goto schedule(); +} +__code cs3a(int a, double b, int c) { + dprint("int a=%d, double b=%lf, int c=%d\n", a, b, c); + cs3 = cs3b; + goto schedule(); +} +__code cs4a(int a, double b, int c, float d) { + dprint("int a=%d, double b=%lf, int c=%d, float d=%f\n", a, b, c, d); + cs4 = cs4b; + goto schedule(); +} + +__code cs0b() { + dprint("no args\n"); + cs0 = cs0a; + goto schedule(); +} +__code cs1b(int a) { + dprint("int a=%d\n", a); + cs1 = cs1a; + goto schedule(); +} +__code cs2b(int a, double b) { + dprint("int a=%d, double b=%lf\n", a, b); + cs2 = cs2a; + goto schedule(); +} +__code cs3b(int a, double b, int c) { + dprint("int a=%d, double b=%lf, int c=%d\n", a, b, c); + cs3 = cs3a; + goto schedule(); +} +__code cs4b(int a, double b, int c, float d) { + dprint("int a=%d, double b=%lf, int c=%d, float d=%f\n", a, b, c, d); + cs4 = cs4a; + goto schedule(); +} + +int main() { + cs0 = cs0a; + cs1 = cs1a; + cs2 = cs2a; + cs3 = cs3a; + cs4 = cs4a; + goto schedule(); +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,655 @@ +#include +#include +#include"code_segment_pointer_check2.h" +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(0), ## args) + +/* + * コードセグメント間の遷移をチェック + * + */ + +typedef __code (*CODEP)(int,int,int,int,int,int); +extern CODEP csps[]; +CODEP csps[] = { + //cs0,cs1 + cs0,cs1,cs2,cs3,cs4,cs5,cs6,cs7,cs8,cs9, + cs10,cs11,cs12,cs13,cs14,cs15,cs16,cs17,cs18,cs19, + cs20,cs21,cs22,cs23,cs24,cs25,cs26,cs27,cs28,cs29, + cs30,cs31,cs32,cs33,cs34,cs35,cs36,cs37,cs38,cs39, + cs40,cs41,cs42,cs43,cs44,cs45,cs46,cs47,cs48,cs49, + cs50,cs51,cs52,cs53,cs54,cs55,cs56,cs57,cs58,cs59, + cs60,cs61,cs62,cs63,cs64,cs65,cs66,cs67,cs68,cs69, + cs70,cs71,cs72,cs73,cs74,cs75,cs76,cs77,cs78,cs79, + cs80,cs81,cs82,cs83,cs84,cs85,cs86,cs87,cs88,cs89, + cs90,cs91,cs92,cs93,cs94,cs95,cs96,cs97,cs98,cs99, + cs100,cs101,cs102,cs103,cs104,cs105,cs106,cs107,cs108,cs109, + cs110,cs111,cs112,cs113,cs114,cs115,cs116,cs117,cs118,cs119 +}; + +__code end(int a, int b, int c, int d, int e) { + dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + exit(a); +} + +__code schedule(int i, int a, int b, int c, int d, int e) { + //CODEP p; + //p = csps[i%120]; + + if ( i>=1000 ) { + goto end(a, b, c, d, e); + } + + dprint("i=%d\n", i); + goto csps[i%120](i+1, a, b, c, d, e); + + dprint("code unreachable!\n"); +} + +int main() { + goto schedule(0, 11,22,33,44,55); +} + + + +/* created by script make_permutations.py. */ + +__code cs0(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,c,d,e); +} + +__code cs1(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,c,d,e); +} + +__code cs2(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,a,d,e); +} + +__code cs3(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,d,a,e); +} + +__code cs4(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,d,e,a); +} + +__code cs5(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,b,d,e); +} + +__code cs6(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,b,d,e); +} + +__code cs7(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,a,d,e); +} + +__code cs8(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,d,a,e); +} + +__code cs9(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,d,e,a); +} + +__code cs10(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,d,b,e); +} + +__code cs11(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,d,b,e); +} + +__code cs12(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,a,b,e); +} + +__code cs13(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,b,a,e); +} + +__code cs14(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,b,e,a); +} + +__code cs15(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,d,e,b); +} + +__code cs16(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,d,e,b); +} + +__code cs17(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,a,e,b); +} + +__code cs18(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,e,a,b); +} + +__code cs19(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,e,b,a); +} + +__code cs20(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,d,c,e); +} + +__code cs21(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,d,c,e); +} + +__code cs22(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,a,c,e); +} + +__code cs23(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,c,a,e); +} + +__code cs24(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,c,e,a); +} + +__code cs25(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,b,c,e); +} + +__code cs26(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,b,c,e); +} + +__code cs27(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,a,c,e); +} + +__code cs28(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,c,a,e); +} + +__code cs29(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,c,e,a); +} + +__code cs30(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,c,b,e); +} + +__code cs31(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,c,b,e); +} + +__code cs32(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,a,b,e); +} + +__code cs33(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,b,a,e); +} + +__code cs34(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,b,e,a); +} + +__code cs35(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,c,e,b); +} + +__code cs36(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,c,e,b); +} + +__code cs37(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,a,e,b); +} + +__code cs38(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,e,a,b); +} + +__code cs39(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,e,b,a); +} + +__code cs40(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,d,e,c); +} + +__code cs41(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,d,e,c); +} + +__code cs42(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,a,e,c); +} + +__code cs43(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,e,a,c); +} + +__code cs44(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,e,c,a); +} + +__code cs45(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,b,e,c); +} + +__code cs46(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,b,e,c); +} + +__code cs47(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,a,e,c); +} + +__code cs48(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,e,a,c); +} + +__code cs49(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,e,c,a); +} + +__code cs50(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,e,b,c); +} + +__code cs51(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,e,b,c); +} + +__code cs52(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,a,b,c); +} + +__code cs53(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,b,a,c); +} + +__code cs54(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,b,c,a); +} + +__code cs55(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,e,c,b); +} + +__code cs56(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,e,c,b); +} + +__code cs57(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,a,c,b); +} + +__code cs58(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,c,a,b); +} + +__code cs59(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,c,b,a); +} + +__code cs60(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,c,e,d); +} + +__code cs61(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,c,e,d); +} + +__code cs62(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,a,e,d); +} + +__code cs63(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,e,a,d); +} + +__code cs64(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,e,d,a); +} + +__code cs65(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,b,e,d); +} + +__code cs66(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,b,e,d); +} + +__code cs67(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,a,e,d); +} + +__code cs68(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,e,a,d); +} + +__code cs69(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,e,d,a); +} + +__code cs70(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,e,b,d); +} + +__code cs71(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,e,b,d); +} + +__code cs72(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,a,b,d); +} + +__code cs73(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,b,a,d); +} + +__code cs74(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,b,d,a); +} + +__code cs75(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,e,d,b); +} + +__code cs76(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,e,d,b); +} + +__code cs77(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,a,d,b); +} + +__code cs78(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,d,a,b); +} + +__code cs79(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,d,b,a); +} + +__code cs80(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,e,c,d); +} + +__code cs81(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,e,c,d); +} + +__code cs82(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,a,c,d); +} + +__code cs83(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,c,a,d); +} + +__code cs84(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,c,d,a); +} + +__code cs85(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,b,c,d); +} + +__code cs86(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,b,c,d); +} + +__code cs87(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,a,c,d); +} + +__code cs88(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,c,a,d); +} + +__code cs89(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,c,d,a); +} + +__code cs90(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,c,b,d); +} + +__code cs91(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,c,b,d); +} + +__code cs92(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,a,b,d); +} + +__code cs93(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,b,a,d); +} + +__code cs94(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,b,d,a); +} + +__code cs95(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,c,d,b); +} + +__code cs96(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,c,d,b); +} + +__code cs97(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,a,d,b); +} + +__code cs98(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,d,a,b); +} + +__code cs99(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,d,b,a); +} + +__code cs100(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,e,d,c); +} + +__code cs101(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,e,d,c); +} + +__code cs102(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,a,d,c); +} + +__code cs103(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,d,a,c); +} + +__code cs104(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,d,c,a); +} + +__code cs105(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,b,d,c); +} + +__code cs106(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,b,d,c); +} + +__code cs107(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,a,d,c); +} + +__code cs108(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,d,a,c); +} + +__code cs109(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,d,c,a); +} + +__code cs110(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,d,b,c); +} + +__code cs111(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,d,b,c); +} + +__code cs112(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,a,b,c); +} + +__code cs113(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,b,a,c); +} + +__code cs114(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,b,c,a); +} + +__code cs115(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,d,c,b); +} + +__code cs116(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,d,c,b); +} + +__code cs117(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,a,c,b); +} + +__code cs118(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,c,a,b); +} + +__code cs119(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,c,b,a); +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.h Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,369 @@ +/* defined in file code_segment_pointer_check2.cbc at offset 987 */ +__code end (int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1102 */ +__code schedule (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1345 */ +int main (); + +/* defined in file code_segment_pointer_check2.cbc at offset 1398 */ +__code cs0 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1542 */ +__code cs1 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1686 */ +__code cs2 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1830 */ +__code cs3 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1974 */ +__code cs4 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2118 */ +__code cs5 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2262 */ +__code cs6 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2406 */ +__code cs7 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2550 */ +__code cs8 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2694 */ +__code cs9 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2838 */ +__code cs10 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2983 */ +__code cs11 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3128 */ +__code cs12 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3273 */ +__code cs13 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3418 */ +__code cs14 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3563 */ +__code cs15 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3708 */ +__code cs16 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3853 */ +__code cs17 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3998 */ +__code cs18 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4143 */ +__code cs19 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4288 */ +__code cs20 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4433 */ +__code cs21 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4578 */ +__code cs22 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4723 */ +__code cs23 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4868 */ +__code cs24 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5013 */ +__code cs25 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5158 */ +__code cs26 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5303 */ +__code cs27 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5448 */ +__code cs28 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5593 */ +__code cs29 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5738 */ +__code cs30 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5883 */ +__code cs31 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6028 */ +__code cs32 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6173 */ +__code cs33 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6318 */ +__code cs34 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6463 */ +__code cs35 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6608 */ +__code cs36 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6753 */ +__code cs37 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6898 */ +__code cs38 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7043 */ +__code cs39 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7188 */ +__code cs40 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7333 */ +__code cs41 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7478 */ +__code cs42 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7623 */ +__code cs43 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7768 */ +__code cs44 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7913 */ +__code cs45 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8058 */ +__code cs46 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8203 */ +__code cs47 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8348 */ +__code cs48 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8493 */ +__code cs49 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8638 */ +__code cs50 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8783 */ +__code cs51 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8928 */ +__code cs52 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9073 */ +__code cs53 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9218 */ +__code cs54 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9363 */ +__code cs55 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9508 */ +__code cs56 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9653 */ +__code cs57 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9798 */ +__code cs58 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9943 */ +__code cs59 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10088 */ +__code cs60 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10233 */ +__code cs61 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10378 */ +__code cs62 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10523 */ +__code cs63 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10668 */ +__code cs64 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10813 */ +__code cs65 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10958 */ +__code cs66 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11103 */ +__code cs67 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11248 */ +__code cs68 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11393 */ +__code cs69 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11538 */ +__code cs70 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11683 */ +__code cs71 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11828 */ +__code cs72 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11973 */ +__code cs73 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12118 */ +__code cs74 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12263 */ +__code cs75 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12408 */ +__code cs76 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12553 */ +__code cs77 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12698 */ +__code cs78 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12843 */ +__code cs79 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12988 */ +__code cs80 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13133 */ +__code cs81 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13278 */ +__code cs82 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13423 */ +__code cs83 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13568 */ +__code cs84 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13713 */ +__code cs85 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13858 */ +__code cs86 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14003 */ +__code cs87 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14148 */ +__code cs88 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14293 */ +__code cs89 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14438 */ +__code cs90 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14583 */ +__code cs91 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14728 */ +__code cs92 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14873 */ +__code cs93 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15018 */ +__code cs94 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15163 */ +__code cs95 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15308 */ +__code cs96 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15453 */ +__code cs97 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15598 */ +__code cs98 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15743 */ +__code cs99 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15888 */ +__code cs100 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16034 */ +__code cs101 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16180 */ +__code cs102 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16326 */ +__code cs103 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16472 */ +__code cs104 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16618 */ +__code cs105 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16764 */ +__code cs106 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16910 */ +__code cs107 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17056 */ +__code cs108 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17202 */ +__code cs109 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17348 */ +__code cs110 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17494 */ +__code cs111 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17640 */ +__code cs112 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17786 */ +__code cs113 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17932 */ +__code cs114 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18078 */ +__code cs115 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18224 */ +__code cs116 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18370 */ +__code cs117 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18516 */ +__code cs118 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18662 */ +__code cs119 (int i, int a, int b, int c, int d, int e); + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/conv1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv1.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,246 @@ +#include "stdio.h" + +extern int atoi (const char *); + +static int loop; + +#if 1 // def __micro_c__ +#define CC_ONLY 0 +#else +#define CC_ONLY 1 +#endif + +/* classical function call case (0) */ +int g0(int); +int h0(int); + +int +f0(int i) { + int k,j; + k = 3+i; + j = g0(i+3); + return k+4+j; +} + +int +g0(int i) { + return h0(i+4)+i; +} + +int +h0(int i) { + return i+4; +} + +#if !CC_ONLY + +/* straight conversion case (1) */ + +typedef void *stack; + +struct cont_interface { // General Return Continuation + __code (*ret)(int, void *); +}; + +#ifndef __llvm__ +__code f_g0(int i,int k,stack sp); +__code f_g1(int j,stack sp); +__code g(int i,stack sp); +__code h(int i,stack sp); +__code f2(int i,char *sp); +__code g2(int i,int k,int j,char *sp); +__code h2(int i,int k,char *sp); +__code main_return2(int i,stack sp); +__code g2_1(int k,int i,stack *sp); +__code h2_11(int i,int k,stack *sp); +#endif + +__code f(int i,stack sp) { + int k,j; + k = 3+i; + goto f_g0(i,k,sp); +} + +struct f_g0_interface { // Specialized Return Continuation + __code (*ret)(int, void *); + int i_,k_,j_; +}; + +__code f_g1(int j,stack sp); + +__code f_g0(int i,int k,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = f_g1; + c->k_ = k; + c->i_ = i; + + goto g(i+3,sp); +} + +__code f_g1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int k = c->k_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(k+4+j,sp); +} + +__code g_h1(int j,stack sp); + +__code g(int i,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = g_h1; + c->i_ = i; + + goto h(i+3,sp); +} + +__code g_h1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int i = c->i_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(j+i,sp); +} + +__code h(int i,stack sp) { + struct f_g0_interface *c = (struct f_g0_interface *)sp; + goto (c->ret)(i+4,sp); +} + +struct main_continuation { // General Return Continuation + __code (*ret)(int, void*); + __code (*main_ret)(int, void*); + void *env; +}; + +__code main_return(int i,stack sp) { + if (loop-->0) + goto f(233,sp); + printf("#0103:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimzation without stack continuation (2) */ + +__code f2(int i,char *sp) { + int k,j; + k = 3+i; + goto g2(i,k,i+3,sp); +} + +__code g2(int i,int k,int j,char *sp) { + j = j+4; + goto h2(i,k+4+j,sp); +} + +__code h2_1(int i,int k,int j,char *sp) { + goto main_return2(i+j,sp); +} + +__code h2(int i,int k,char *sp) { + goto h2_1(i,k,i+4,sp); +} + +__code main_return2(int i,stack sp) { + if (loop-->0) + goto f2(233,sp); + printf("#0132:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimizaed case (3) */ + +__code f2_1(int i,stack *sp) { + int k,j; + k = 3+i; + goto g2_1(k,i+3,sp); +} + +__code g2_1(int k,int i,stack *sp) { + goto h2_11(k,i+4,sp); +} + +__code f2_0_1(int k,int j,stack *sp); +__code h2_1_1(int i,int k,int j,stack *sp) { + goto f2_0_1(k,i+j,sp); +} + +__code h2_11(int i,int k,stack *sp) { + goto h2_1_1(i,k,i+4,sp); +} + +__code f2_0_1(int k,int j,stack *sp) { + goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp); +} + +__code main_return2_1(int i,stack sp) { + if (loop-->0) + goto f2_1(233,sp); + printf("#0165:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +#define STACK_SIZE 2048 +char main_stack[STACK_SIZE]; +#define stack_last (main_stack+STACK_SIZE) + +#endif + +#define LOOP_COUNT 10000000 + +int +main(int ac,char *av[]) +{ +#if !CC_ONLY + struct main_continuation *cont; + stack sp = stack_last; +#endif + int sw; + int j; + if (ac==2) sw = atoi(av[1]); + else sw=3; + + if (sw==0) { + for(loop=0;loopret = main_return; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f(233,sp); + } else if (sw==2) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2(233,sp); + } else if (sw==3) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2_1; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2_1(233,sp); +#endif + } +return 0; +} + +/* end */ diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/fact-a.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/fact-a.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,36 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include "stdio.h" + +__code factorial(int n,int result,int orig,__code(*print)(),__code(*exit1)(), void *exit1env) +{ + if (n<0) { + printf("#0008:err %d!\n",n); + goto (*exit1)(0,exit1env); + } + if (n==0) + goto (*print)(n,result,orig,print,exit1,exit1env); + else { + result *= n; + n--; + goto factorial(n,result,orig,print,exit1,exit1env); + } +} + +__code print(int n,int result,int orig,__code(*print)(),__code (*exit1)(),void*exit1env); + +int main( int ac, char *av[]) +{ + int n; + // n = atoi(av[1]); + n = 10; + goto factorial(n,1,n,print,__return,__environment); +} + +__code print(int n,int result,int orig,__code(*print)(),__code (*exit1)(),void*exit1env) +{ + printf("#0032:%d! = %d\n",orig, result); + goto (*exit1)(0,exit1env); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/goto.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/goto.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,96 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +extern int printf(const char *,...); + +__code (*conv)(int,__code (*)()); +__code a2(int i,__code conv()); +__code a3(int i,__code conv()); +__code a4(int i,__code conv()); +__code a5(int i,__code conv()); +__code a6(); +__code a7(); +__code a8(); +__code a9(); + +char* print_conv(__code conv()); + +__code (*exit0)(int,void*); +void *env; + +__code +a2(int i,__code conv()) +{ + printf("#0023:a2 %d %s\n",i,print_conv(conv)); + goto conv(i+1,a4); +} + +__code +a3(int i,__code (*conv)()) +{ + printf("#0030:a3 %d %s\n",i,print_conv(conv)); + goto conv(i+1,a5); +} + +__code +a4(int i,__code conv()) +{ + printf("#0037:a4 %d %s\n",i,print_conv(conv)); + goto (*conv)(i+1,a6); +} + +__code +a5(int i,__code (*conv)()) +{ + printf("#0044:a5 %d %s\n",i,print_conv(conv)); + goto (*conv)(i+1,i+2,i+3,a7); +} + +__code +a6(int i,int j,int k,__code conv()) +{ + printf("#0051:a6 %d %s\n",i,print_conv(conv)); + goto conv(i+1,j,k,a8); +} + +__code +a7(int i,int j,int k,__code (*conv)()) +{ + printf("#0058:a7 %d %s\n",i,print_conv(conv)); + goto conv(i+1,j,k,a9); +} + +__code +a8(int i,int j,int k,__code conv()) +{ + printf("#0065:a8 %d %s\n",i,print_conv(conv)); + goto (*conv)(i+1,j,k,exit0); +} + +__code +a9(int i,int j,int k,__code (*conv)()) +{ + printf("#0072:a9 %d %s\n",i,print_conv(conv)); + goto (*conv)(0,env); +} + +int main(int ac,char *av[]) { + exit0 = __return; + env = __environment; + conv = a2; + goto conv(1,a3); +} + +char* +print_conv(__code conv()) +{ + if(conv==a2) return "a2"; + if(conv==a3) return "a3"; + if(conv==a4) return "a4"; + if(conv==a5) return "a5"; + if(conv==a6) return "a6"; + if(conv==a7) return "a7"; + if(conv==a8) return "a8"; + if(conv==a9) return "a9"; + else return "xx"; +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/loto6.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/loto6.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,82 @@ +/* + * Nov 10, 2009 + * created by gongo. + * + * Nov 10, 2009 + * modified by kent. + */ + +#include +#include +#include +#include + +void (*ret)(int, void*); +void *env; + + +__code +print(int *numbers) +{ + printf("%d-%d-%d-%d-%d-%d\n", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4], numbers[5]); + free(numbers); + goto ret(0, env); +} + + __code +take(int *array, int size, int length) +{ + int *taked = (int*)malloc(sizeof(int)*length); + + memcpy(taked, array, sizeof(int)*length); + free(array); + + goto print(taked); +} + +__code +shuffle(int *array, int size, int idx) +{ + int j = random() % size; + int tmp = array[idx]; + array[idx] = array[j]; + array[j] = tmp; + + if (++idx < size) { + goto shuffle(array, size, idx); + } else { + goto take(array, size, 6); + } +} + +__code +range_loop(int *array, int idx, int from, int to, int step, int size) +{ + array[idx] = from; + + if (from+step > to) { + goto shuffle(array, size, 0); + } else { + goto range_loop(array, idx+1, from+step, to, step, size); + } +} + +__code +range(int from, int to, int step) +{ + int size = (to-from+1)/step; + int *array = (int*)malloc(sizeof(int)*size); + + goto range_loop(array, 0, from, to, step, size); +} + +int +main() +{ + srand(time(NULL)); + ret = _CbC_return; + env = _CbC_environment; + + goto range(1, 43, 1); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/Makefile Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,39 @@ + +CbCC=../../BUILD/INSTALL_DIR/bin/gcc + +#CC=gcc +#CC=../../../build_gcc/INSTALL_DIR/bin/gcc +CC=../../BUILD/INSTALL_DIR/bin/gcc + +HEADERMAKER=../../CbC-scripts/make_headers.py2 + +# fastcall版では-O0,-O2は動作確認、-O3以上はだめ +#CFLAGS=-g -O2 -fomit-frame-pointer +#CFLAGS=-g -O2 +CFLAGS=-g -O0 +#CFLAGS=-g -Os # an error occurred. + +.SUFFIXES: .cbc .o + +all: quicksort_cbc quicksort_c quicksort_cbc2 + +.cbc.o: + $(CbCC) $(CFLAGS) -c -o $@ $< +.cbc.h: + $(HEADERMAKER) $^ > $@ + +quicksort_cbc.o: quicksort_cbc.h +quicksort_cbc2.o: quicksort_cbc2.h +quicksort_test.o: quicksort_test.h + +quicksort_cbc: quicksort_cbc.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ +quicksort_cbc2: quicksort_cbc2.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ + +quicksort_c: quicksort_c.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s quicksort_c quicksort_cbc quicksort_cbc2 diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/benchmark.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/benchmark.sh Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,45 @@ +#!/usr/bin/env zsh + +time=/usr/bin/time +QS=./quicksort_cbc +size=10000000 +seed=123456789 +num=10 + + +max=0 +min=99999 +count=0 +amount=0 + +echo "size of array = $size" +while [[ $count -lt $num ]]; do + echo "$time -p $QS -n $size -s $seed 2>&1 >& - |grep '^user'|tr -s \" \"|cut -f2 -d\" \" " + usertime=$( $time -p $QS -n $size -s $seed 2>&1 >& - |grep '^user'|tr -s " "|cut -f2 -d" ") + #usertime=$(printf "%d" $usertime) + echo $usertime + + amount=$(($usertime+$amount)) + if [[ $usertime -lt $min ]]; then + min=$usertime + fi + if [[ $usertime -gt $max ]]; then + max=$usertime + fi + #seed=$seed[1,-2] + seed=$(($seed+10)) + count=$(($count+1)) +done + +echo "amount time = $amount" +echo "maxtime = $max" +echo "mintime = $min" + +amount=$(($amount - $max - $min)) +echo "amount time - mintime - maxtime = $amount" +count=$(($count-2)) +echo "count = $count" +averagetime=$(($amount/($count))) +echo "average time = $averagetime" + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/mc/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/mc/Makefile Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,39 @@ + +CbCC=../../../../device/mc + +#CC=gcc +CC=../../../../build_gcc/INSTALL_DIR/bin/gcc + +HEADERMAKER=../../../CbC-scripts/make_headers.py2 + +CFLAGS=-g -Wall + +.SUFFIXES: .cbc .o .s .c + +all: quicksort_cbc quicksort_c quicksort_cbc2 + +quicksort_c.c quicksort_cbc.cbc quicksort_cbc2.cbc quicksort_test.cbc benchmark.sh: + ln -s ../$@ + +.s.o: + $(CC) -c -o $@ $< +.cbc.s: + $(CbCC) $< +.cbc.h: + $(HEADERMAKER) $^ > $@ + +quicksort_cbc.o: quicksort_cbc.h +quicksort_cbc2.o: quicksort_cbc2.h +quicksort_test.o: quicksort_test.h + +quicksort_cbc: quicksort_cbc.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ +quicksort_cbc2: quicksort_cbc2.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ + +quicksort_c: quicksort_c.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s quicksort_c quicksort_cbc quicksort_cbc2 diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/quicksort_cbc.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_cbc.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,244 @@ +#include +#include +#include + +typedef void *stack; +typedef struct { + int size; + void *interface; + __code (*ret)(void*, stack) ; +} frame, *framep; + +/* quickstart main routine. */ +typedef struct { + int *v; + int s; + int e; +} QS_IF ; +typedef __code (*RET)(void*); + +#include"quicksort_cbc.h" + +/* for check. */ +void *mustbefreed; + +__code returner(stack sp) +{ + framep fp = (framep)sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +__code quicksort_start(void *arg, stack sp) +{ + QS_IF *recvif = arg; + int a,b,c,p; + a = recvif->v[recvif->s]; + b = recvif->v[recvif->e]; + c = recvif->v[(recvif->s+recvif->e)/2]; + + //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); + if (recvif->e <= recvif->s) goto returner(sp); + + if (a < b) { + if (b < c) + p = b; + else if (a < c) + p = c; + else + p = a; + } else { + if (a < c) + p = a; + else if (b < c) + p = c; + else + p = b; + } + + goto quicksort_divider (recvif, recvif->s, recvif->e, p, sp); +} +/* main routine end. */ + +/* divide routine. */ +__code quicksort_divider(QS_IF *recvif, int s, int e, int p, stack sp) +{ + goto quicksort_divider_s(recvif, s, e, p, sp); +} +__code quicksort_divider_s(QS_IF *recvif, int s, int e, int p, stack sp) +{ + if (recvif->v[s]v[e]) { + e--; + goto quicksort_divider_e(recvif, s, e, p, sp); + } else + goto quicksort_swapper(recvif, s, e, p, sp); +} +__code quicksort_swapper(QS_IF *recvif, int s, int e, int p, stack sp) +{ + if (sv[s]; + recvif->v[s] = recvif->v[e]; + recvif->v[e] = tmp; + goto quicksort_divider(recvif, s+1, e-1, p, sp); + } else { + goto quicksort_treecall(recvif, s, e, sp); + } +} +/* divide routin end. */ + + +/* recursive call routine. */ +__code quicksort_treecall(QS_IF *recvif, int s, int e, stack sp) +{ + framep fp; + QS_IF *outif; + + /* interface for first quicksort_start this segment directly jump to. */ + outif = (sp-=sizeof(QS_IF)); + outif->v = recvif->v; + outif->s = recvif->s; + outif->e = e; + fp = (sp-=sizeof(frame)); + fp->ret = quicksort_start; + fp->interface = recvif; + fp->size = sizeof(frame)+sizeof(QS_IF); + + /* recvif is used by second quicksort_start. */ + recvif->s = e+1; + goto quicksort_start(outif, sp); +} +/* recursive call routine end. */ + +#define STACK_SIZE 10240 + +typedef struct { + __code (*ret)(void*); + void *ret_arg; + stack *sp; +} QS_FINISH; +__code +quicksort(int *v, int s, int e, RET ret, void *arg ) +{ + framep fp; + stack sp0, sp; + sp0 = mustbefreed = malloc(STACK_SIZE); + sp = sp0 + STACK_SIZE; + QS_FINISH *finish_if; + QS_IF *outif; + + /* interface for quicksort_finish. */ + finish_if = (sp -= sizeof(QS_FINISH)); + finish_if->ret = ret; + finish_if->ret_arg = arg; + finish_if->sp = sp0; + + /* interface for quicksort_start. */ + outif = (sp -= sizeof(QS_IF)); + outif->v = v; + outif->s = s; + outif->e = e; + /* frame for quicksort_finish. */ + fp = (sp -= sizeof(frame)); + fp->ret = quicksort_finish; + fp->interface = finish_if; + fp->size = sizeof(frame)+sizeof(QS_IF); + + goto quicksort_start(outif, sp); +} +__code +quicksort_finish(void *arg, stack sp) +{ + QS_FINISH interface; + interface = *(QS_FINISH*)arg; + //assert((void*)interface.sp==(void*)mustbefreed); + free(interface.sp); + goto interface.ret(interface.ret_arg); +} + + + +#if 0 +void +quicksort_c(int *v, int s0, int e0, stack sp) +{ + int p; + int s=s0, e=e0; + if (e<=s) return; + + //p = (v[s]+v[(s+e)/2]+v[e])/3; + p = mid_point(v[s],v[e],v[(s+e)/2]); + + while (1) { + while (v[s]ret = caller_finish; + fp->interface = NULL; + fp->size = sizeof(*outif)+sizeof(frame); + + goto quicksort_start(outif, sp); +} +__code caller_finish0(void *arg, stack sp) +{ +} + +__code __returner0(void *arg , stack sp) +{ + framep fp = sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +#endif + + + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/quicksort_cbc2.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_cbc2.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,159 @@ +#include +#include +#include + +typedef struct { + int *v; + int s; + int e; +} QS_IF; + +typedef void *stack; +typedef __code (*RET)(QS_IF, stack); +typedef struct { + int size; + QS_IF interface; + RET ret; +} frame, *framep; + +typedef __code (*RETTYPE)(void*); +typedef struct { + RETTYPE ret; + void *ret_arg; + stack *sp; +} QS_FINISH; +#define STACK_SIZE 10240 + +#include"quicksort_cbc2.h" + +__code returner(stack sp) +{ + framep fp = (framep)sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +__code quicksort_start(QS_IF recvif, stack sp) +{ + int a,b,c,p; + a = recvif.v[recvif.s]; + b = recvif.v[recvif.e]; + c = recvif.v[(recvif.s+recvif.e)/2]; + + //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); + if (recvif.e <= recvif.s) goto returner(sp); + + if (a < b) { + if (b < c) + p = b; + else if (a < c) + p = c; + else + p = a; + } else { + if (a < c) + p = a; + else if (b < c) + p = c; + else + p = b; + } + + goto quicksort_divider (recvif, recvif.s, recvif.e, p, sp); +} +/* main routine end. */ + +/* divide routine. */ +__code quicksort_divider(QS_IF recvif, int s, int e, int p, stack sp) +{ + goto quicksort_divider_s(recvif, s, e, p, sp); +} +__code quicksort_divider_s(QS_IF recvif, int s, int e, int p, stack sp) +{ + if (recvif.v[s]ret = quicksort_start; + fp->size = sizeof(frame); + fp->interface.v = recvif.v; + fp->interface.s = e+1; + fp->interface.e = recvif.e; + + /* recvif is used by second quicksort_start. */ + recvif.e = e; + goto quicksort_start(recvif, sp); +} +/* recursive call routine end. */ + +__code +quicksort(int *v, int s, int e, RETTYPE ret, void *arg ) +{ + framep fp; + stack sp0, sp; + sp0 = malloc(STACK_SIZE); + printf("allocate a stack %p\n", sp0); + sp = sp0 + STACK_SIZE; + QS_FINISH *finish_if; + + /* interface for quicksort_finish. */ + finish_if = (sp -= sizeof(*finish_if)); + finish_if->ret = ret; + finish_if->ret_arg = arg; + finish_if->sp = sp0; + + /* interface for quicksort_start. */ + /* frame for quicksort_finish. */ + fp = (sp -= sizeof(frame)); + fp->ret = quicksort_finish; + fp->size = sizeof(frame); + fp->interface.v = v; + fp->interface.s = s; + fp->interface.e = e; + + goto quicksort_start(fp->interface, sp); +} +__code +quicksort_finish(QS_IF recvif, stack sp) +{ + QS_FINISH *interface = (QS_FINISH*)sp; + free(interface->sp); + printf("free the stack %p\n", interface->sp); + goto interface->ret(interface->ret_arg); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/quicksort/quicksort_test.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_test.cbc Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#include"quicksort_test.h" + +extern __code quicksort(int *,int,int, __code (*)(void*), void*); + + +void +random_initialize(int *v, int size, int min, int max) +{ + int i; + int diff = max-min+1; + + for (i=0; i v[i+1]) + return 0; + } + return 1; +} + +__code +exit0(void *arg) +{ + int *v = arg; + int b; + //print_array(arg, size); + b = check_sort(arg, size); + if (b) { + printf("sorting successful!\n"); + exit(EXIT_SUCCESS); + } else { + printf("sorting failure! \n"); + exit(EXIT_FAILURE); + } +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/regexp/dfareg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/regexp/dfareg.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,182 @@ +#include + +#include + +__code state_20_21(char* s); +__code state_1(char* s); +__code state_3_8_9_13_23_24(char* s); +__code state_6_7(char* s); +__code state_2_3_9_13_23_24_25(char* s); +__code state_10_11(char* s); +__code state_18_19(char* s); +__code state_4_5(char* s); +__code state_14_15(char* s); +__code state_3_9_13_22_23_24(char* s); +__code state_3_9_12_13_23_24(char* s); +__code state_16_17(char* s); +__code accept(); +__code reject(); + +int main(int argc, char* argv[]) { + if (argc == 1) { + printf("usage: %s text\n", argv[0]); + exit(0); +} + + puts("regexp: P(erl|HP|ython)*"); + puts("number of state: 12"); + printf("string: %s\n", argv[1]); + goto state_1(argv[1]); + return 0; +} + +__code state_20_21(char* s) { + switch(*s++) { + case 'n': + goto state_3_9_13_22_23_24(s); + break; + default: goto reject(); + } +} + +__code state_1(char* s) { + switch(*s++) { + case 'P': + goto state_2_3_9_13_23_24_25(s); + break; + default: goto reject(); + } +} + +__code state_3_8_9_13_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_6_7(char* s) { + switch(*s++) { + case 'l': + goto state_3_8_9_13_23_24(s); + break; + default: goto reject(); + } +} + +__code state_2_3_9_13_23_24_25(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_10_11(char* s) { + switch(*s++) { + case 'P': + goto state_3_9_12_13_23_24(s); + break; + default: goto reject(); + } +} + +__code state_18_19(char* s) { + switch(*s++) { + case 'o': + goto state_20_21(s); + break; + default: goto reject(); + } +} + +__code state_4_5(char* s) { + switch(*s++) { + case 'r': + goto state_6_7(s); + break; + default: goto reject(); + } +} + +__code state_14_15(char* s) { + switch(*s++) { + case 't': + goto state_16_17(s); + break; + default: goto reject(); + } +} + +__code state_3_9_13_22_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_3_9_12_13_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_16_17(char* s) { + switch(*s++) { + case 'h': + goto state_18_19(s); + break; + default: goto reject(); + } +} + + +__code accept() { + printf("\nstring matches regexp. \n\n"); +} + + +__code reject() { + printf("\nstring does not match regexp. \n\n"); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/regexp/dfareg.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/regexp/dfareg.py Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,414 @@ +#!/usr/bin/env python + +import copy +import sys + +class NondeterministicFiniteAutomaton(object): + def __init__(self, transition, start, accepts, map_): + self.transition = transition + self.start = start + self.accepts = accepts + self.map = map_ + + def epsilonExpand(self, set_): + que = set(set_) + done = set() + while que: + stat = que.pop() + nexts = self.transition(stat, "") + done.add(stat) + for nextStat in nexts: + if not nextStat in done: que.add(nextStat) + return frozenset(done) + +class DeterministicFiniteAutomaton(object): + def __init__(self, transition, start, accepts, map_): + self.transition = transition + self.start = start + self.accepts = accepts + self.map = map_ + def getRuntime(self): + return DFARuntime(self) + +class DFARuntime(object): + def __init__(self, DFA): + self.DFA = DFA + self.curState = self.DFA.start + + def doTransition(self, char): + self.curState = self.DFA.transition( + self.curState, char) + + def isAcceptState(self): + return self.curState in self.DFA.accepts + + def doesAccept(self, input): + for alphabet in input: + self.doTransition(alphabet) + return self.isAcceptState() + +class Token(object): + CHARACTER = 0 + OPE_UNION = 1 + OPE_STAR = 2 + LPAREN = 3 + RPAREN = 4 + EOF = 5 + + def __init__(self, value, kind): + self.value = value + self.kind = kind + + +class Lexer(object): + def __init__(self, str): + self.stringList = list(str) + + def scan(self): + if not self.stringList: + return Token(None, Token.EOF) + + ch = self.stringList.pop(0) + if ch == '\\': + return Token(self.stringList.pop(0), Token.CHARACTER) + elif ch == '|': + return Token(ch, Token.OPE_UNION) + elif ch == '(': + return Token(ch, Token.LPAREN) + elif ch == ')': + return Token(ch, Token.RPAREN) + elif ch == '*': + return Token(ch, Token.OPE_STAR) + else: + return Token(ch, Token.CHARACTER) + +""" + Context-free Grammer: + (A) expression -> subexpr EOF + (B) subexpr -> seq '|' subexpr | seq + (C) seq -> subseq | '' + (D) subseq -> star subseq | star + (E) star -> factor '*' | factor + (F) factor -> '(' subexpr ')' | CHARACTER +""" + +class Parser(object): + def __init__(self, lexer): + self.lexer = lexer + self.look = None + self.move() + + def match(self, tag): + if self.look.kind != tag: + raise Exeption("syntax error") + self.move() + + def move(self): + self.look = self.lexer.scan() + + def factor(self): + if self.look.kind == Token.LPAREN: + # factor -> '(' subexpr ')' + self.match(Token.LPAREN) + node = self.subexpr() + self.match(Token.RPAREN) + return node + else: + # factor -> CHARACTER + node = Character(self.look.value) + self.match(Token.CHARACTER) + return node + + def star(self): + # star -> factor '*' | factor + node = self.factor() + if self.look.kind == Token.OPE_STAR: + self.match(Token.OPE_STAR) + node = Star(node) + return node + + def seq(self): + if self.look.kind == Token.LPAREN \ + or self.look.kind == Token.CHARACTER: + # seq -> subseq + return self.subseq() + else: + # seq -> '' + return Character("") + + def subseq(self): + node1 = self.star() + if self.look.kind == Token.LPAREN \ + or self.look.kind == Token.CHARACTER: + # subseq -> star subseq + node2 = self.subseq() + node = Concat(node1, node2) + return node + else: + # subseq -> star + return node1 + + def subexpr(self): + node1 = self.seq() + if self.look.kind == Token.OPE_UNION: + self.match(Token.OPE_UNION) + # subexpr -> seq '|' subexpr + node2 = self.subexpr() + node = Union(node1, node2) + return node + else: + # subexpr -> seq + return node1 + + def expression(self): + # expression -> subexpr EOF + node = self.subexpr() + self.match(Token.EOF) + + # Create TREE, NFA + context = Context() + fragment = node.assemble(context) + return fragment.build() + +class Context(object): + def __init__(self): + self.stateCount = 0 + + def newState(self): + self.stateCount += 1 + return self.stateCount + +class NFAFragment(object): + def __init__(self): + self.start = None # integer + self.accepts = None # frozenset + self.map = dict() # transition + + def connect(self, from_, char, to): + slot = self.map.setdefault((from_, char), set()) + slot.add(to) + + def newSkelton(self): + # copy fragment (self), and it return + newFrag = NFAFragment(); + newFrag.map = copy.deepcopy(self.map) + return newFrag + + def __or__(self, frag): + newFrag = self.newSkelton() + for k, v in frag.map.iteritems(): + newFrag.map[k] = v.copy() + return newFrag + + def build(self): + map_ = self.map + def transition(state, char): + return frozenset(map_.get((state, char), [])) + + return NondeterministicFiniteAutomaton( + transition, + self.start, + self.accepts, + self.map + ) + +class Character(object): + def __init__(self, char): + self.char = char + + def assemble(self, context): + frag = NFAFragment() + s1 = context.newState() + s2 = context.newState() + frag.connect(s1, self.char, s2) + frag.start = s1 + frag.accepts = frozenset([s2]) + return frag + +class Union(object): + def __init__(self, op1, op2): + self.op1 = op1 + self.op2 = op2 + + def assemble(self, context): + frag1 = self.op1.assemble(context) + frag2 = self.op2.assemble(context) + frag = frag1 | frag2 + s = context.newState() + frag.connect(s, "", frag1.start) + frag.connect(s, "", frag2.start) + frag.start = s + frag.accepts = frag1.accepts | frag2.accepts + return frag + +class Concat(object): + def __init__(self, op1, op2): + self.op1 = op1 + self.op2 = op2 + + def assemble(self, context): + frag1 = self.op1.assemble(context) + frag2 = self.op2.assemble(context) + frag = frag1 | frag2 + + for state in frag1.accepts: + frag.connect(state, "", frag2.start) + + frag.start = frag1.start + frag.accepts = frag2.accepts + return frag + +class Star(object): + def __init__(self, op): + self.op = op + + def assemble(self, context): + fragOrig = self.op.assemble(context) + frag = fragOrig.newSkelton() + + for state in fragOrig.accepts: + frag.connect(state, "", fragOrig.start) + + s = context.newState() + frag.connect(s, "", fragOrig.start) + frag.start = s + frag.accepts = fragOrig.accepts | frozenset([s]) + return frag + +class NonDisjoinSets(object): + def __init__(self, sub): + self.sub = sub + def __contains__(self, a_set): + return a_set & self.sub + +def nfa2dfa(nfa): + def transition(set_, alpha): + ret = set() + for elem in set_: + ret |= nfa.transition(elem, alpha) + return nfa.epsilonExpand(frozenset(ret)) + + def stateSetTransition(stateSet, char): + trans = set() + for state in stateSet: + t = nfa.map.setdefault((state, char), None) + if not t == None: trans.update(nfa.epsilonExpand(t)) + return frozenset(trans) + + map_ = dict() + que = set(frozenset([nfa.epsilonExpand(set([nfa.start]))])) + done = set() + + while que: + stateSet = que.pop() + + for state in stateSet: + for k, v in nfa.map.iteritems(): + if state == k[0] and k[1] != '': + slot = map_.setdefault((stateSet, k[1]), set()) + slot.update(nfa.epsilonExpand(v)) + + done.add(stateSet) + + for v in map_.itervalues(): + if not v in done: + que.add(frozenset(v)) + + return DeterministicFiniteAutomaton( + transition, + nfa.epsilonExpand(frozenset([nfa.start])), + NonDisjoinSets(nfa.accepts), + map_ + ) + +# emit CbC-souce, from dfa +def dfa2CbC(dfa, regexp): + + # return state name from set + def set2name(set_): + l = list(set_) + l.sort() + return '_'.join(str(x) for x in l) + + funcMap = dict() + funcMap[dfa.start] = set() + + # dfa.map => {(frozenset([1, 15]), 'd'): frozenset([16]), ....} + # : frozenset(1, 15) x 'd' -> frozenset([16]) + + for v in dfa.map.itervalues(): + funcMap[frozenset(v)] = set() + + for key in dfa.map.iterkeys(): + slot = funcMap.setdefault(key[0], set()) + slot.add(key[1]) + + # emit cbc code + print "#include \n" + print "#include \n" + for k in funcMap.iterkeys(): + print '__code state_' + set2name(k) + "(char* s);" + print '__code accept();' + print '__code reject();' + print """ +int main(int argc, char* argv[]) { +\tif (argc == 1) { +\t\tprintf(\"usage: %%s text\\n\", argv[0]); +\t\texit(0); +} + +\tputs(\"regexp: %s\"); +\tputs(\"number of state: %d\"); +\tprintf(\"string: %%s\\n\", argv[1]); +\tgoto state_%s(argv[1]); +\treturn 0; +}\n""" % (regexp, len(funcMap), set2name(dfa.start)) + + for k, v in funcMap.iteritems(): + print '__code state_' + set2name(k) + "(char* s) {" + print "\tswitch(*s++) {" + for case in v: + print "\t\tcase '%c': " % (case) + print "\t\t\tgoto state_%s(s);\n\t\t\tbreak;" % set2name(dfa.map[(frozenset(k), case)]) + if k in dfa.accepts: print "\t\tcase '\\0': goto accept();\n\t\t\tbreak;" + print "\t\tdefault: goto reject();\n\t}" + print "}\n" + + print """ +__code accept() { +\tprintf(\"\\nstring matches regexp. \\n\\n\"); +}\n""" + print """ +__code reject() { +\tprintf(\"\\nstring does not match regexp. \\n\\n\"); +}\n""" + +class Regexp(object): + def __init__(self, regexp): + self.regexp = regexp + self.nfa = None + self.dfa = None + self._compile() + + def _compile(self): + lexer_ = Lexer(self.regexp) + parser_ = Parser(lexer_) + self.nfa = parser_.expression() + self.dfa = nfa2dfa(self.nfa) + + def emitCbC(self): + dfa2CbC(self.dfa, self.regexp) + + def matches(self, string): + runtime = self.dfa.getRuntime() + return runtime.doesAccept(string) + +def compile(regexp): + return Regexp(regexp) + +def main(argv): + if len(argv) == 1 : exit("usage: dfareg.py regexp [> file]") + r = compile(argv[1]) + r.emitCbC() + +if __name__ == '__main__' : main(sys.argv) diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/stack1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/stack1.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,127 @@ +/* + test for CbC converted __code from C + */ + +//#include +#define NULL 0 +extern int printf(const char*, ...); + +extern void *malloc(size_t); + +typedef void *stack; + +void *stack0; /* size of void* == 1 */ + +struct cont_save { /* General Return Continuation */ + __code (*ret)(); +}; + + __code g(int,void *); + __code f_g0(int ,int ,void *); + __code f_g1(int,void *); + __code print(int i,int j,__code (*exit1)(),void*exit1env); + +struct f_g0_save { /* Specialized Return Continuation */ + __code (*ret)(); + int ii,kk,jj; +}; + +__code g(int i,void *sp) { + goto (* ((struct cont_save *)sp)->ret)(i+4,sp); +} + +__code __attribute__ ((fastcall)) f_g1(int j,void *sp) { /* Continuation */ + int k; + struct f_g0_save *c; + + c = sp; + k = c->kk; + sp += sizeof(struct f_g0_save); + goto (* ((struct cont_save *)sp)->ret)(k+4+j,sp); +} + +__code f(int i,void *sp) { + int k,j; + struct f_g0_save *c; +printf("#0042:f 0 sp: %x\n",sp-stack0); + + k = 3+i; + +printf("#0046:f 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f_g0_save); +printf("#0048:f 2 sp: %x\n",sp-stack0); + c = sp; + c->kk = k; + c->ii = i; + c->jj = j; + c->ret = f_g1; + goto g(i,sp); +} + + + +struct f0_save { /* Specialized Return Continuation */ + __code (*ret)(); + __code (*exit1)(); + void *exit1env; + int jj; +}; + +__code f1(int i,void *sp) ; +__code f0(int i,int j,__code(*exit2)(), void *exit2env,void *sp) +{ + struct f0_save *c; + printf("#0070:f0 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f0_save); + printf("#0072:f0 2 sp: %x\n",sp-stack0); + c = sp; + c->jj = j; + c->exit1 = exit2; + c->exit1env = exit2env; + c->ret = f1; + printf("#0078:f0 3 sp: %x\n",sp-stack0); + goto f(i,sp); +} + +__code f1(int i,void *sp) { + int j; + int *exit2env; + __code (*exit2)(); + struct f0_save *c; + + c = sp; + j = c->jj; + exit2 = c->exit1; + exit2env = c->exit1env; + + sp += sizeof(struct f0_save); + goto print(i,j,exit2,exit2env); +} + +int main(int ac, char*av[]){ + main0(ac,av); +} + +int main0( int ac, char *av[]) +{ + int i,j; + int *sp; + + // i = atoi(av[1]); + i = 1; + stack0 = ((char *)malloc(1024)+1024); + sp = stack0; + j = i; + + printf("#0108:sp: %x %x\n",sp-(int*)stack0,sizeof(*stack0)); + //goto f0(i,j,_CbC_return,_CbC_environment,sp); + goto f0(i,j,NULL,NULL,sp); +} + +__code print(int i,int j,__code (*exit1)(),void*exit1env) +{ + printf("#0114:%d %d\n",i,j); + //goto (*exit1)(0),exit1env; + exit(0); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test02.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test02.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,23 @@ +#include +extern int printf(const char*, ...); + +__code test_code(void){ + printf("\t\ttest_code: return 10\n"); + return; +} + +__code test_goto(int a){ + printf("\ttest_goto: a = %d\n", a); + //return test_code(); + goto test_code(); +} + +int main(int argc, char **argv){ + int ret=0; + printf("test code\n"); + test_goto(20); + printf("main: ret = %d\n", ret); + + return 0; +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test05.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test05.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,59 @@ +//#include +extern int printf(const char*, ...); +#define dprint(f, args...) \ + printf("in %s: "f, __FUNCTION__, ## args) + +__code caller (int a); +void f01 (int a); +void f02 (int a, float b); +__code cs01 (int a); +__code cs02 (int a, float b); +int main (); + + +int g=0; +void (*funcp)(int); +__code (*csp)(int); + +__code caller(int a) { + f01(a+2); + f02(a+3, 13.2); + funcp(a+4); + goto csp(a+4); + dprint("\n"); +} + +__code end() { + dprint("\n"); + exit(0); +} + +void f01(int a) { + dprint("%d\n", a); + g += a; + return ; +} +void f02(int a, float b) { + dprint("%d, %f\n", a, b); + g -= a; + g += b*0.3; + return ; +} +__code cs01(int a) { + dprint("%d\n", a); + g += a; + goto end() ; +} +__code cs02(int a, float b) { + dprint("%d, %f\n", a, b); + g -= a; + g += b*0.3; + goto end() ; +} + +int main() { + funcp = f01; + csp = cs01; + caller(10); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test1.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,125 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +/* + test for CbC converted __code from C + */ + +#include + +extern void *malloc(size_t); + +typedef void *stack; + +void *stack0; /* size of void* == 1 */ + +struct cont_save { /* General Return Continuation */ + __code (*ret)(); +}; + +/* + __code g(int,void *); + __code f_g0(int ,int ,void *); + __code f_g1(int,void *); +*/ + +struct f_g0_save { /* Specialized Return Continuation */ + __code (*ret)(); + int ii,kk,jj; +}; + +__code g(int i,void *sp) { + goto (* ((struct cont_save *)sp)->ret)(i+4,sp); +} + +__code f_g1(int j,void *sp) { /* Continuation */ + int k; + struct f_g0_save *c; + + c = sp; + k = c->kk; + sp += sizeof(struct f_g0_save); + goto (* ((struct cont_save *)sp)->ret)(k+4+j,sp); +} + +__code f(int i,void *sp) { + int k,j; + struct f_g0_save *c; +printf("#0047:f 0 sp: %x\n",sp-stack0); + + k = 3+i; + +printf("#0051:f 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f_g0_save); +printf("#0053:f 2 sp: %x\n",sp-stack0); + c = sp; + c->kk = k; + c->ii = i; + c->jj = j; + c->ret = f_g1; + goto g(i,sp); +} + + + +struct f0_save { /* Specialized Return Continuation */ + __code (*ret)(); + __code (*exit1)(); + void *exit1env; + int jj; +}; + +__code f1(int i,void *sp) ; +__code f0(int i,int j,__code(*exit2)(), void *exit2env,void *sp) +{ + struct f0_save *c; + printf("#0075:f0 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f0_save); + printf("#0077:f0 2 sp: %x\n",sp-stack0); + c = sp; + c->jj = j; + c->exit1 = exit2; + c->exit1env = exit2env; + c->ret = f1; + printf("#0083:f0 3 sp: %x\n",sp-stack0); + goto f(i,sp); +} + +__code print(int i,int j,__code (*exit1)(),void*exit1env); + +__code f1(int i,void *sp) { + int j; + int *exit2env; + __code (*exit2)(); + struct f0_save *c; + + c = sp; + j = c->jj; + exit2 = c->exit1; + exit2env = c->exit1env; + + sp += sizeof(struct f0_save); + goto print(i,j,exit2,exit2env); +} + +int main( int ac, char *av[]) +{ + int i,j; + int *sp; + + // i = atoi(av[1]); + i = 1; + stack0 = ((char *)malloc(1024)+1024); + sp = stack0; + j = i; + + printf("#0115:sp: %x %x\n",sp-(int*)stack0,sizeof(*stack0)); + goto f0(i,j,__return,__environment,sp); +} + +__code print(int i,int j,__code (*exit1)(),void*exit1env) +{ + printf("#0121:%d %d\n",i,j); + goto (*exit1)(0,exit1env); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test2.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,45 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include +int sender_bit; + +__code (*ret)(int,void *); +void *env; + +struct packet { + int bit; + char *msg; + __code (*next)(); +}; + +__code print_struct(struct packet pkt) +{ + printf("#0017:bit: %d\n", pkt.bit); + printf("#0018:message: %s\n", pkt.msg); + goto ret(0, env); +} + +__code initSender(int init_bit, struct packet pkt) +{ + sender_bit = init_bit; + pkt.next = print_struct; + printf("#0026:initSender bit: %d\n", pkt.bit); + printf("#0027:initSender message: %s\n", pkt.msg); + printf("#0028:sender_bit: %d\n", sender_bit); + goto print_struct(pkt); +} + +int main(void) +{ + struct packet pkt; + pkt.bit = 1; + pkt.msg = "hogehoge"; + pkt.next = initSender; + ret = __return; + env = __environment; + printf("#0040:main bit: %d\n", pkt.bit); + printf("#0041:main message: %s\n", pkt.msg); + goto initSender(0, pkt); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_cs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_cs.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,45 @@ +//#include +//#include + +extern int printf(const char*, ...); + +__code cs_exit(int , double , char ); +__code cs1(int, int, int, int); +__code cs2(double, double, int, double); +void test_goto(void); + +int main(int argc, char **argv){ + printf("main start\n"); + //goto cs2(2.22, 3.33, 4, 5.55); + test_goto(); + return 0; +} + +void test_goto(){ + goto cs1(10, 20, 30, 40); +} + +__code cs1(int a, int b, int c, int d){ + printf("%4d, %4d, %4d, %4d\n", a, b, c, d); + a += 40, b += 40, c += 40, d += 40; + goto cs2((double)a, (double)b, c, (double)d); +} + +__code cs2(double a, double b, int c, double d){ + printf("%4d, %4d, %4d, %4d\n", (int)a, (int)b, (int)c, (int)d); + a += 40, b += 40, c += 40, d += 40; + goto cs_exit((int)a, b, (char)c); +} + +__code cs_exit(int a, double b, char c){ + printf("%4d, %4d, %4d\n", (int)a, (int)b, (int)c); + printf("cs_exit was called!\n"); + exit(0); +} + + +void caller(int a, double b){ + cs2(b,20.0,a, 40.4); + cs1(10,20,30, 40); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_csp1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_csp1.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,60 @@ +#include +#include + +//static __code (*csp)(int, int, int, int); + +__code cs_end (int a); +__code cs0 (int a, int b, int c, int d); +void* freturn (); +__code cs_goto (int a, int b, int c, int d); +int function (double a, float b, int c); +int main (int argc, char **argv); + + +__code cs_goto(int a, int b, int c, int d){ + __code (*csp)(int, int, int, int); + csp = freturn(); + printf("csp = %x.\n", csp); + + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + //printf("cs_goto : a-4=%d, a-8=%d, a-12=%d, a-16=%d.\n", *(&a-4), *(&a-8), *(&a-12), *(&a-16)); + //printf("cs_goto : cs0(a, b, c, d)\n"); +#ifdef INDIRECT + goto csp(b+a, d+b, a+c, c+d); +#else + goto cs0(b+a, d+b, a+c, c+d); +#endif +} + +__code cs_end(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); + goto cs_end(a); +} + +__code cs0(int a, int b, int c, int d){ + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_cs0 : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + goto cs_end( (int)(20*a + 30*b + 40*c + 50*d) ); +} + + +void* freturn(){ + return cs0; +} + +int function(double a, float b, int c){ + + printf("function:\n"); + printf("a=%lf, b=%f, c=%d\n", a, b, c); + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(10, 20, 30, 40); +} + +int main(int argc, char **argv){ + //csp = cs0; + function(10.01, 20.02, 30); + return 0; +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_func2code.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_func2code.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,43 @@ +#include +#include + +#define DEBUG 1 +#ifdef DEBUG + #define log(f, args...) \ + fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) +#else + #define log(f, args...) ; +#endif + +__code +exitter(int a) +{ + exit(0); +} + +__code +cs0(int x, int y) +{ + log("x = %d, y = %d.\n", x, y); + log("will exit with code %d.\n", x*y); + goto exitter(x*y); +} + +void +continuation(int a) +{ + log("go code segment cs0\n"); + goto cs0(a, a*20); + log("Error: continuation reachs bad region.\n"); +} + +int +main(int argc, char **argv) +{ + int a; + if (argc>2) { + a = atoi(argv[1]); + } + + continuation(20); +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_para.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,26 @@ +#include +#include + +__code cs_exit(int a){ + printf("cs_exit was called: a=%d.\n", a); + exit(a); +} + +__code cs0(int a, double b, int c, int d){ + printf("cs0 was called: a=%d, b=%lf, c=%d, d=%d.\n", a, b, c, d); + goto cs_exit( (int)(20*a + 4.4*b + 2022/c + 28*d) ); +} + + +__code cs_goto(){ + goto cs0(11, 22.2, 33, 44); +} + +int main(int argc, char **argv){ + + printf("it is in main.\n"); + goto cs_goto(); + return 0; +} + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_para2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para2.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,40 @@ +#include +#include + +__code cs_end(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); +} + +__code cs0(int a, int b, int c, int d); + +__code cs_goto(int a, int b, int c, int d){ + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_goto : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + //printf("cs_goto : a-4=%d, a-8=%d, a-12=%d, a-16=%d.\n", *(&a-4), *(&a-8), *(&a-12), *(&a-16)); + //printf("cs_goto : cs0(a, b, c, d)\n"); + goto cs0(b, c, d, a); +} + +__code cs0(int a, int b, int c, int d){ + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_cs0 : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + goto cs_end( (int)(20*a + 30*b + 40*c + 50*d) ); +} + + +int function(double a, float b, int c){ + + //printf("function:\n"); + //printf("a=%lf, b=%f, c=%d\n", a, b, c); + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(10, 20, 30, 40); +} + +int main(int argc, char **argv){ + + function(10.01, 20.02, 30); + return 0; +} + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_para3.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para3.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,83 @@ +#include +#include + +struct abc { + int a; + double b; + char c; + double *d; +}; + +struct def { + int d; + struct abc e; + struct abc *f; +}; + +void print_abc(struct abc a){ + printf("\tstruct abc:\n"); + printf("\ta=%d, b=%lf, c=%d, d=%p\n", a.a, a.b, a.c, a.d); +} +void print_def(struct def b){ + printf("\tstruct def:\n"); + printf("\td=%d, f=%p\n", b.d, b.f); + print_abc(b.e); +} + +__code cs_exit(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); +} + +__code cs0(struct abc a, struct def b, int c){ + printf("cs0 :\n"); + printf("c=%d\n", c); + print_abc(a); + print_def(b); + goto cs_exit( c*a.a+b.e.c ); +} + + +__code cs_goto(int c, struct abc a, struct def b){ + printf("cs_goto :\n"); + printf("c=%d\n", c); + print_abc(a); + print_def(b); + goto cs0(a, b, c); +} + +int function(){ + struct abc A; + struct def B; + A.a = 10, A.b = 20.02, A.c = '\0', A.d = 0xad; + B.d = 30, B.f = 0xbf; + B.e.a = 50, B.e.b = 60.06, B.e.c = '\1', B.e.d = 0xed; + + printf("function :\n"); + print_abc(A); + print_def(B); + //printf("20*%d + 30*%d + 40*%d + 50*%d =\n", a, b, c, d); + goto cs_goto(100, A, B); + return 0; +} + +int main(int argc, char **argv){ + struct abc A; + struct def B; + //int a=10, b=20, c=30, d=40, e=50, f=60, g=70; + A.a = 10, A.b = 20.02, A.c = '\0', A.d = 0xad; + B.d = 30, B.f = 0xbf; + B.e.a = 50, B.e.b = 60.06, B.e.c = '\1', B.e.d = 0xed; + + /* + printf("main :\n"); + print_abc(A); + print_def(B); + //printf("20*%d + 30*%d + 40*%d + 50*%d =\n", a, b, c, d); + goto cs_goto(100, A, B); + */ + function(); + return 0; +} + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_para4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para4.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,76 @@ +//#include +//#include + +extern int printf(const char*, ...); + +#define DPRINT 1 +#define NOINLINE __attribute__((noinline)) + +extern __code cs_goto(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); +extern __code cs0(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); + +__code (*csp)(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); + +__code NOINLINE cs_exit(int a){ + int b = 20 * a + 3; + printf("cs_exit : a=%d. b=%d\n", a, b); + exit(a); +} + +__code NOINLINE cs0(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2){ +#if DPRINT + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +#endif + goto cs_exit( (int)(10*a + 10*b + 10*i2 + 10*j2) ); +} + +__code NOINLINE cs_goto(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2){ +#if DPRINT + printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +#endif + goto cs0(b, c, d, e, f, g, h, i, j, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, a); +} + +int function(double l, float m, int n){ + int a=10, b=20, c=30, d=40, e=50, f=60, g=70, h=80, i=90, j=100; + int a2=110, b2=120, c2=130, d2=140, e2=150, f2=160, g2=170, h2=180, i2=190, j2=200; + +#if DPRINT + printf("function: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("function: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); + //printf("l=%lf, m=%f, n=%d\n", l, m, n); +#endif + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(a, b, c, d, e, f, g, h, i, j, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +} + + +int main(int argc, char **argv){ + + //printf("main :\n"); + /* + printf("main : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("main : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); + */ + //csp = cs0; + function(10.01, 20.02, 30); + return 0; +} + + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/test_tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_tree.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,56 @@ +//#include +extern int printf(const char*, ...); +extern void exit(int); +double test(char, char, int, double); +__code cs(int , double , char ); +void testvoid(double a); +int testint(double a); + +__code cs(int a, double b, char c){ + printf("__code cs was called.\n"); + printf("a = %d, b = %lf, c = %d\n", a, b, c); + exit(0); +} +__code cs1(int a, double b, char c, int d){ + printf("__code cs1 was called.\n"); + printf("a = %d, b = %lf, c = %d, d = %d\n", a, b, c, d); + exit(0); +} + +int main(int argc, char **argv){ + double t; + //goto cs(2, 10.2, 2); + + t = test('a', 'b', 10, 2.5); + printf("t = %lf\n", t); + testvoid(2.22); + testint(2.22); + + printf("test_goto\n"); + goto test_goto1(10, 20, 30.3); + return 0; +} +void test0(){ + exit(0); +} + +void testvoid(double a){ + return ; +} +int testint(double a){ + int b; + b = (a*100-a) +2; + return 1; +} + +double test(char c, char l, int a, double d){ + return (double)a*d+c+l; +} + +void test_goto(int a, int b, double c){ + goto cs(2, 10.2, 3); +} +__code test_goto1(int a, int b, double c){ + goto cs1(2, 10.2, 3, 4); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/tmp1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/tmp1.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,102 @@ +/* easy test */ +#define __environment _CbC_environment +#define __return _CbC_return + + +extern int printf(const char *,...); + +#if 0 //currently gcc version dose not support void type full continuation. + +__code code0(int ac,char *av[],__code (*ret)(void*)); +__code code1(int ac,char *av[],__code (*exit)(void*)); +__code code3(char a,char b,int c,int d,int e,int f); +__code code4(char a,char b,int c,int d,int e,int f); + +__code (*ret)(void *); +void *env; +__code exit1(void *); + +void main0(ac,av) +int ac; +char *av[]; +{ + ret = __return; + env = __environment; + printf("#0017:main0 %d start.\n",ac); + if (ac>=1) + goto code0(ac,av,__return); + goto code1(ac,av,exit1); + // not reached. (warning?) + printf("#0022:main0 %d end.\n",ac); +} + +__code exit1(void *env) +{ + // exit(0); + goto code3(0,1,2,3,4,5); +} + +__code code3(a,b,c,d,e,f) +char a,b; +int c,d,e,f; +{ + printf("#0035:code3: %d %d %d %d %d %d\n",a,b,c,d,e,f); + if(a<10) + goto code3(a+1,b,c,d,e,f); + else + goto code4(a+3,b+3,c+3,d+3,e+3,f+3); +} + +__code code4(a,b,c,d,e,f) +char a,b; +int c,d,e,f; +{ + int i=1,j=2; + printf("#0047:code4: %d %d %d %d %d %d\n",a,b,c,d,e,f); + if(a<20) // cyclic binary dependency + goto code3(a+b,b+c,c+d,d+e,e+f,f+a); + else if(a<30) + goto code3(a,b,c,d,e,f); + else if(a<40) // cyclic dependency + goto code3(b,c,a,e,f,d); + else if(a<50) + goto code4(a+i,b+j,c+i,d+3,e+3,f+3); + else goto ret(env); +} + +__code code0(ac,av,ret) +int ac; +char *av[]; +__code (*ret)(void *env); +{ + goto code1(ac,av,ret); +} + +__code code1(ac,av,exit) +int ac; +__code (*exit)(void*); +char *av[]; +{ + __code (*f)(void *); + printf("#0073:code1: %d\n",ac); + f = exit; + if (ac>3) + goto code1(ac,av,f); + else if (ac>2) + goto code1(ac,av,f); + else + goto (*f)(env); +} + +#endif + +int main(int ac,char *av[]) +{ +// main0(1,av); + printf("#0087:main continue.\n"); +// main0(0,av); + printf("#0089:main end.\n"); +return 0; +} + +/* end */ diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/tmp2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/tmp2.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,48 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include "stdio.h" + +int main0(int ac,char *av[]); +__code code0(char *av[],__code (*ret)(int, void*),void *retenv); +__code code1(char *av[],__code (*ret)(int, void*),void *retenv); + +int +main(ac,av) +int ac; +char *av[]; +{ + int i; + i=main0(ac,av); + fprintf(stdout,"#0012:1: %s %d\n",av[0],i); + return 0; +} + +int +main0(ac,av) +int ac; +char *av[]; +{ + fprintf(stdout,"#0021:2: %s\n",av[0]); + goto code0(av,_CbC_return,_CbC_environment); +} + +__code code0(av,ret,retenv) +char *av[]; +__code (*ret)(int, void*); +void *retenv; +{ + char *p; + p = av[0]; + fprintf(stdout,"#0032:3: %s\n",p); + goto code1(av,ret,retenv); +} + +__code code1(av,ret,retenv) +char *av[]; +__code (*ret)(int, void*); +void *retenv; +{ + fprintf(stdout,"#0041:4: %s\n",av[0]); + goto (*ret)(1234,retenv); +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/tmp4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/tmp4.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,66 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include "stdio.h" + +int main0(int ac, char *av[]); +__code code0( int i,int j,int k, char *av[], __code (*ret)(), void *retenv); +__code code1( int i,int j,int k, char *av[], __code (*ret)(), void *retenv); +__code code2( int i,int j,int k, char *av[], __code (*ret)(), void *retenv); + +int +main(ac,av) +int ac; +char *av[]; +{ + int i; + i=main0(ac,av); + fprintf(stdout,"#0012:1: %s %d\n",av[0]+2,i); + return 0; +} + +int +main0(ac,av) +int ac; +char *av[]; +{ + int i,j,k; + i=123; + j=456; + k=789; + fprintf(stdout,"#0025:2: %s\n",av[0]+2); + goto code0(i,j,k,av,__return,__environment); +} + +__code code0(i,j,k,av,ret,retenv) +int i,j,k; +char *av[]; +__code (*ret)(); +void *retenv; +{ + char *p; + p = av[0]+2; + fprintf(stdout,"#0037:3: i=%d j=%d k=%d av[0]=%s p=%s\n",i,j,k,av[0]+2,p); + goto code1(i,j,k,av,ret,retenv); +} + +__code code1(i,j,k,av,ret,retenv) +int i,j,k; +char *av[]; +__code (*ret)(); +void *retenv; +{ + fprintf(stdout,"#0047:4: %s\n",av[0]+2); + goto code2(i,j,k,av,ret,retenv); +} + +__code code2(i,j,k,av,ret,retenv) +int i,j,k; +char *av[]; +__code (*ret)(); +void *retenv; +{ + fprintf(stdout,"#0057:5: %s\n",av[0]+2); + fprintf(stdout,"#0058:5: i=%d j=%d k=%d\n",i,j,k); + goto (*ret)(1234,retenv); +} diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/tmpa.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/tmpa.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,49 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include + +struct enemy{ + int charno; // image number + float x; // x location + float y; // y location + int ap; // armor point +}; +void +print_param(struct enemy *e) +{ + printf("#0014:charno:%d x,y:%f,%f hp:%d\n", + e->charno,e->x,e->y,e->ap); +} + +typedef struct{ + char dest; + int VF01[4]; + __code (*ret)(); + void *env; +} interface; + +__code a0(interface a) { + printf("#0026:%d\n",a.dest); + goto a.ret(0,a.env); +} + + +int main(int argc,char *argv[]) +{ + struct enemy e; +#if 0 + interface args = {15,{0,0,0,0},return,environment}; +#else + interface args = {15,{0,0,0,0},0,0}; + args.ret = __return; + args.env = __environment; +#endif + + e.charno=5; e.x=50.0; e.y=30.0; e.ap=100; + print_param(&e); + + printf("#0045:%d %d\n",args.VF01[2],args.VF01[1]); + goto a0(args); +} + diff -r 84e7813d76e9 -r d34655255c78 CbC-examples/too-long-argument.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/too-long-argument.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,104 @@ +#define __environment _CbC_environment +#define __return _CbC_return + +#include + +#undef WRONGNUMBER + +typedef __code +(*CCC)( int f1,int f2,int f3,int f4,int f5,int f6,int f7,int f8,int f9,int fa,int fb,int fc,int fd,int fe,int ff, + __code(*ret)(int,void *), + void *env); + +__code +tcode2( int f1,int f2,int f3,int f4,int f5,int f6,int f7,int f8,int f9,int fa,int fb,int fc,int fd,int fe,int ff, + __code(*ret)(int,void *), + void *env) +{ +fprintf(stdout,"#0017:tcode2: f1=%d,f2=%d,f3=%d,f4=%d,f5=%d,f6=%d,f7=%d,f8=%d,f9=%d,fa=%d,fb=%d,fc=%d,fd=%d,fe=%d,ff=%d\n", +f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff); + goto ret(0,env); +} + +__code +tcode1(f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff,ret,env) + int f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff; + __code(*ret)(int,void *); + void *env; +{ +fprintf(stdout,"#0028:tcode1: f1=%d,f2=%d,f3=%d,f4=%d,f5=%d,f6=%d,f7=%d,f8=%d,f9=%d,fa=%d,fb=%d,fc=%d,fd=%d,fe=%d,ff=%d\n", +f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff); + goto ret(0,env); +} + +__code +tcode4(int x,int y,CCC junction,__code(*ret)(int,void *),void *env) +{ +#ifdef WRONGNUMBER + goto junction(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,ret,env); +#else + goto junction(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,ret,env); +#endif +} + +__code +tcode0(int x,int y,__code(*junction)(int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,__code(*)(int, void *),void *),__code(*ret)(int,void *),void *env) +{ +#ifdef WRONGNUMBER + goto junction(0,1,2,3,4,5,6,7,8,9,10,11,12,13,ret,env); +#else + goto junction(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,ret,env); +#endif +} + +int +main0() +{ +#ifdef WRONGNUMBER + goto tcode2(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + __return,__environment); +#else + goto tcode2(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14, + __return,__environment); +#endif +} + +int +main1() +{ +#ifdef WRONGNUMBER + goto tcode1(0,1,2,3,4,5,6,7,8,9,10,11,12,13, + __return,__environment); +#else + goto tcode1(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14, + __return,__environment); +#endif +} + +int +main2() +{ + goto tcode0(0,1,tcode1,__return,__environment); +} + +int +main4() +{ + goto tcode4(0,1,tcode2,__return,__environment); +} + +int +main() +{ + printf("#0092:main4\n"); + main4(); + printf("#0094:main2\n"); + main2(); + printf("#0096:main0\n"); + main0(); + printf("#0098:main1\n"); + main1(); +return 0; +} + +// diff -r 84e7813d76e9 -r d34655255c78 CbC-implemantation.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-implemantation.ja Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,207 @@ + + + GCC への CbC コンパイル機能の実装について + + +___________________________________________________________ + Code Segmentの実装 +----------------------------------------------------------- + +Code SegmentをC言語に組み込む。 +コンパイラとしては単なるvoidの関数として扱い、parse treeにcode +segmentであることのフラグを追加する。 + + * 予約語''__code``の追加 + c-common.cで定義されているc_common_reswords配列に追加 + { "__code", RID_CbC_CODE, 0} # D_CONLYも入れるか? + + * treeの生成関数 + 関数の型を表すtreeはbuild_funciton_type関数で生成されるが、code + segmentではこれを使えない。build_function_typeはhash管理でまったく同 + じ引数型、返り値型を持つものは同じオブジェクトを使うから。 + なのでbuild_code_segment_typeでこの代わりを行う。 + # 本当はbuild_function_typeのhashにcbcフラグも含める方がいいかもし + # れない。 + この関数は主にgrokdeclaratorから呼ばれる + + * cbc_set_codesegment関数 + Undocumented. + でも今は意味なかったような… + + + +___________________________________________________________ + goto文の実装 +----------------------------------------------------------- + +CbCについて重要な構文''goto cs(a, b, c);``を実装する。 +c-parser.c内の c_parser_statement_after_labels()関数における巨大なスイ +ッチ文のcase RID_GOTOのコードを修正する。 + + * アイデア + 全てのgoto文を単なる関数呼び出しとその後のリターン文と解釈することで + tail callを可能にする。 + 次のgoto文は + goto cs(a); + このparse treeでもこの様に解釈される + cs(a); + return; + + * Parser側での修正 + + オリジナルC言語のパース方法 + 1. gotoに続くトークンがCPP_NAME + 通常のgoto文として処理 + 2. gotoに続くトークンが'*` + computed gotoとして処理 + see "GCC Manual" Sec 6.3. (not internals Manual) + これを以下の様に変更する + + CbCでのパース方法 + 1. gotoに続くトークンがCPP_NAME && CPP_NAMEに次ぐトークンが';` + 通常のgoto文として処理 + 2. gotoに続くトークンが'*` + computed gotoとして処理 + 3. それ以外 + CbCのgotoとして処理 + + 処理内容 + 1. gotoトークンに続く文を関数呼び出しとみて + c_parser_expr_no_commas()関数を使ってパース、treeを取得 + # これで(*csp)(a)などにも対応できる + 2. 取得したtreeがCALL_EXPRでなければエラー + 3. treeにCbC_GOTOのフラグを立てる + 4. treeにTAILCALLのフラグを立てる + 5. add_stmt + 6. return文のtreeを生成 + + * RTL expansion + + 通常のCALL_EXPRを解析するexpand_callを一部修正する。この関数の途中か + らでexpand_cbc_goto関数に切り替えてRTLの生成はそこで全てを請け負う。 + 本来expand_callではtreeにsibcallフラグが立っていても、生成の過程で不 + 可能と検知するとsibcallを中断して通常のcallになるが、cbc_expand_call + では無理やりsibcallにする。 + + expand_callでの修正内容 + Undocumented. + expand_cbc_gotoの処理内容 + Undocumented. + +___________________________________________________________ + goto文における並列代入の実装 Nov 26, 2009 +----------------------------------------------------------- + +c-parser.c: c_parser_statement_after_labels()における goto文のパースの +段階で全ての引数を一時変数に代入する形に変更する。 +もちろんこれだけで並列代入ができる分けではないが、おそらくGCCの最適化 +機構でできると考える。 + + 1. c_parser_expr_no_commasでCALL_EXPRを取得 + 2. 全ての引数に対して一時変数を作成 + 3. それぞれを代入 + 4. CALL_EXPRの引数を一時変数に置き換え + 2-4の処理をcbc_replace_argumentsで行う。 + + + +___________________________________________________________ + return擬似変数の実装 +----------------------------------------------------------- + +___________________________________________________________ + environmentの実装 +----------------------------------------------------------- + + + + + + + + + + + + + + + + + +___________________________________________ + * goto文における並列代入実装について考える +------------------------------------------- + +Nov 26, 2009 +c-parser.c: c_parser_statement_after_labels()における goto文のパースの +段階で全ての引数を一時変数に代入する形に変更する。 +もちろんこれだけで並列代入ができる分けではないが、おそらくGCCの最適化 +機構でできると考える。 + + 1. c_parser_expr_no_commasでCALL_EXPRを取得 + 2. 全ての引数に対して一時変数を作成 build_decl? + 名前なしでできるか? + 3. それぞれを代入 + 4. CALL_EXPRの引数を一時変数に置き換え + 5. expand_callでの実装を元に戻す? + 現状のままでも動きはするはず +引数のタイプ + 関数 + o ADDR_EXPR + o PARM_DECL, VAR_DECL, + other + o *_EXPR + o PARM_DECL, VAR_DECL, + +実装の準備 + o CALL_EXPRから引数リストを取得 + DECL_ARGUMENTS(fundecl) + tree args = DECL_ARGUMENTS (fndecl); + for (; args; args = TREE_CHAIN (args)) + { + tree type = TREE_TYPE (args); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + DECL_ARG_TYPE (args) = integer_type_node; + } + o 名前なしの変数作成 + var = build_decl(VAR_DECL, NULL_TREE, TYPE); + DECL_ARTIFICIAL (val) = 1; + o 代入文 + build_modify_expr (loc, TO_EXPR, NOP_EXPR, FROM_EXPR) + o Constantなら一時変数いらない + もしくはcallerの引数と同じ場合にのみ一時変数を使うか + o CALL_EXPRは取得後に引数を変えても大丈夫なのか? + o expand_callでのstore_one_arg, check_sibcall_argument_overlapの動作 + +実装に邪魔ないくつかの関数の解析 + o mem_overlaps_already_clobbered_arg_p(addr, size) + 指定したメモリ[addr,addr+size]範囲がすでに前の引数格納によって上書 + きされていないかをチェックする。 + 引数範囲を1byte毎にbitmapの1bitに表し、上書きされた場所は1がセット + されている。それにかぶるとNG. + また、addrが動的(esp+eaxなど)ならNG. + o sotre_one_args() +この実装ではexpand_cbc_gotoをいじらない事にした + + + + * DEBUG手法 + + gccコマンドではなくcc1コマンドに対してgdbを起動 + $ ls + GCC/ build-test/ test/ + $ cd test + $ gdb ../build-test/gcc/cc1 + + treeの表示 + (gdb) p browse_tree (exp) <== expはtree構造体 + + rtxの表示 + (gdb) p debug_rtx (exp) <== expはrtx構造体 + + browse_treeはtree, debug_rtxはrtxをconfigureの + --enable-checkingで指定している必要がある + + diff -r 84e7813d76e9 -r d34655255c78 CbC-memo.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-memo.ja Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,912 @@ +GCC7 + /gcc/c-decl.c + gcc/c-family/c-common.c + gcc/c-family/c-common.h + gcc/c-family/c-pretty-print.c + gcc/c-parser.c + gcc/c-tree.h + gcc/c-typeck.c + gcc/calls.c + gcc/cbc-tree.h + gcc/cfgexpand.c + gcc/config/i386/i386.c + gcc/config/i386/i386.md + gcc/config/rs6000/rs6000.md + gcc/configure.a + gcc/function.c + gcc/gcc.c + gcc/gimple.c + gcc/gimple.h + gcc/gimplify.c + gcc/passes.c + gcc/tree-ssa-operands.c + gcc/tree.c + gcc/tree.h +GCC + + + + +[[configureオプションの追加]] +$ cd gcc +$ vi configure.ac + ... +$ autoheader-2.59 # versionはconfigure.acの中に書いてある奴に合わせる +$ autoconf-2.59 +$ vi Makefile.in +これでconfigureスクリプトが完成するが、このautoconfはtarボールでは成功しない +svnリポジトリからチェックアウトしないと必要な関数が定義されてないのでエラーになる +なのでチェックアウトしたものでconfigureを生成したあと、それだけコピーしてこればOK +TOPディレクトリでは +$ autogen Makefile.def +$ autoconf-2.59 +ただしこれを使うことはないと思われる? + + +[[fastcall i386]] +1: %ecx +2: %edx +3: (%esp) +4: 4(%esp) +5: 8(%esp) + +__attribute__((noreturn)): 今のところこれでは問題が出ない +__attribute__((fastcall)): こっちはいろいろ問題あり + + +fastcallで起こる問題: +せっかく計算したebpが上書きされてしまっている +ecxに退避してそこにjmpすれば動く (これを直にかける?) +expand_cbc_gotoを直す必要がある +08048714 : +8048714: 53 push %ebx +8048715: 83 ec 28 sub $0x28,%esp +8048718: 89 4c 24 0c mov %ecx,0xc(%esp) +804871c: 8b 44 24 0c mov 0xc(%esp),%eax +8048720: 89 44 24 1c mov %eax,0x1c(%esp) +8048724: 8b 44 24 1c mov 0x1c(%esp),%eax +8048728: 8b 00 mov (%eax),%eax +804872a: 01 44 24 0c add %eax,0xc(%esp) +804872e: 8b 44 24 1c mov 0x1c(%esp),%eax +8048732: 8b 58 08 mov 0x8(%eax),%ebx +8048735: 8b 44 24 1c mov 0x1c(%esp),%eax +8048739: 8b 40 04 mov 0x4(%eax),%eax +804873c: 8b 54 24 0c mov 0xc(%esp),%edx +8048740: 89 c1 mov %eax,%ecx +8048742: 83 c4 28 add $0x28,%esp +8048745: 5b pop %ebx +8048746: ff e3 jmp *%ebx +これを手動で直すと-O0でも-O2でも動くことが確認できた + + + + + +**PROJECT CVS** +firefly.cr:~one/CVS_DB/CbC_Project/GCC + +-checkout + cvs co CbC_project/GCC +-commit + cvs commit +-import from 3rdparty source + tar xzvf gcc-xxx.tgz + cd gcc-xxx + cvs import -ko -m ".." CbC/project/GCC FSF_GCC REL_4_x_y +-merge + cd /temp + cvs checkout -jREL_4_2_1 -jREL_xxx CbC_project/GCC + もしくはすでに本流をcheckoutしているディレクトリで + cvs update -jREL_4_2_1 -jREL_4_2_2 でもできる? (4_2_2に移行時はこれをしたけど...まだ分かんない ) + cvs update -jREL_4_2_2 -jREL_4_2_3 + + +コンパイル時に実行されるプログラムは主に3つ +省略すると +cc1, as, collect2 +/usr/libexec/gcc/i386/redhat-linux/4.1.1/cc1 test.c -o test.s +as -o test.o test.s +/usr/libexec/gcc/i386/redhat/linux/4.1.1/collect2 ..... test.o + +cc1とcollect2は +gcc-core-4.2.0/gcc/内でコンパイルされるもの。 +必要なのはcc1だ。 + + + +CbCの実装 + tail callを使う。 + +tail call +関数の末尾呼び出しを最適化して、callでなくjmpで関数に飛ぶようになる。 +gcc -O1 -foptimize-sibling-calls か +gcc -O2 でコンパイルすればこの最適化が行われる。 + +最適化条件? (構造体未確認) +(推測!!) + 返り値が同じ + 呼ばれる関数の引数サイズが呼び出し側関数の引数サイズより小さい + +expand_gimple_basic_blockでstatement毎にRTLに変換されているが、 +ほとんどのstmtはexpand_expr_stmtに送られるけど、 +tail call の場合は expand_gimple_tailcallに直接送られる + + +**TEST BUILD** +mkdir build-test +cd build-test +../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/installed --enable-checking=tree,rtl,assert +デバグのため、下の(a)を実行 +make +make install # これまでしないと処理系によってはerrorがいくつか... + +(a). 全てのMakefileの-O2 を -O0 に変更 viで :%s/-O2/-O0/gってとこか? + どうやら --prefix=...って、ちゃんとしないといけない? + stdio.hをインクルードしてるとエラーが出る。 + これはオレが失敗したのか?それともconfigureが悪いのか? + +$ CFLAGS="-O0 -gdwarf-2 -g3" ../GCC/configure ... + + +stdio.hをインクルードしたらerrorが出る問題 +firefly: --prefix=$PWD/USR-LOCALあり、別ディレクトリ + preinstall: NG postinstall: OK installed: OK +firefly: --prefixなし、別ディレクトリ + preinstall: NG postinstall: ?? +firefly: --prefixあり、同ディレクトリ + preinstall: NG postinstall: OK installed: OK +firefly(nativePkg): --prefixなし、別ディレクトリ + preinstall: NG + +chani: --prefix=$PWD/installedあり、同ディレクトリ + preinstall: OK +chani(nativePkg): --prefixなし、別ディレクトリ + preinstall: OK + + + +$PWD/installed/bin/gcc -O2 .... +$PWD/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 -O2 test01.c +browse_tree (tree) +debug_rtx(rtl) + + + +**GCC DEBUG** +gdb $BUILD-TEST/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 +プログラム内で +p browse_tree (current_function_decl) + + + + + +cc1 +main.c, toplev.c, + +main() in main.c + +toplev_main() in toplev.c + general_init(argv[0]) + signal設定 + init_gcc() + decode_options(argc, argv) + randomize() + do_compile() in toplev.c + timevar_start(TV_TOTAL) + process_options() + compile_file() + +struct lang_hooks lang_hooks +この構造体にパーサ等の関数ポインタが含まれている。 +これはlanghooks-def.hでLANG_HOOKS_INITIALIZERが定義されているが、 +言語ごとの定義はcならc-objc-common.hで、各メンバの定義が入れ替えられる。 + +options +decode_options -O?などのオプションを処理 + handle_options その他のオプションを順番に走査 + コンパイル対象のファイル名を main_input_filenameに入れる + -で始まる引数があればhandle_optionを呼ぶ + handle_option オプションを処理する + + +compile_file() + lang_hooks.parse_file() == c_common_parse_file + c_parse_file() in c-parser.c Parse a single source file. + c_parser_translation_unit() in c-parser.c + c_parser_external_declaration() + + +c_parser_external_declaration() in c-parser.c +CPPのtokenはここで処理して通常のはc_parser_declaration_or_fndefに渡す + +全体を通して、c_parser *parserという変数が関数の第一引数に渡される。 +これがファイルをparseする際の状態を保持しているっぽい + +c_parser_declaration_or_fndef() +こいつがglobalな関数、変数の宣言を処理する。 + c_parser_declspecs() 基本type (int, char, strcut...) + declspecs_add_scspec(specs, tree) extern,inline,staticなどのstorageをspecsにおさめる(specsのフラグをたてる) + declspecs_add_type(specs, c_typespec t) int, char, longなど第2引数が型名、第1引数にそれを格納 + finish_declspecs() Complexやunsignedなどの後に来る型名の処理? + shadow_tag(specs) 名前無しのstructやunionを処理。 + c_parser_declarator() 名前の前の*の処理 + c_parser_direct_declarator() idを取得 + c_parser_direct_declarator_inner() idの後の[]や()をパース + c_parser_parms_declarator() 引数リストもしくはidリスト(これはoldSTYLEのため) + c_parser_parms_list_declarator() + c_parser_parameter_declaration() + 通常の変数なら + start_decl() + start_init() c_parser_initializer() finish_init() + finish_decl() + + 関数パラメータ + start_function() 関数のdeclaration treeを作成する + treeはcurrent_function_declに保存 + old-styleパラメータ(while c_parser_declaration_or_fndef(parser, f, f, t, f) + fnbody = c_parser_compound_statement(parser) 関数本体の定義 + add_stmt(fnbody) fnbodyを専用のstatement listに追加する gimplifyに使われる? + finish_function() + current_function_declからfndeclを取得 + ...(fndecl) = pop_stmt_list(....(fndecl)) statement listからbodyを取得しfndeclにつなげる + c_genericize(fndecl) convert LD-tree to LI-tree + c_gimple_diagnostics_recursively(fndecl) + cgraph_finalize_function(fndecl,false) ファイルにアセンブラを出力? + cgraph_assemble_pending_functions() in cgraphunit.c + +関数とcode segment +code segmentはパース中の型はcts_CbC_codeとしてdeclspecsに保持している +finish_declspecsにおいて、treeを構成する際に型をvoid_type_nodeで格納 +このvoid_typeになんらかのフラグをつける?それともfunction_typeにつける? + + + +IDの取得 +c_parser_declarator() 名前の前の*の処理 + c_parser_direct_declarator() id or (.id)をパース + c_parser_direct_declarator_inner() idの後の[]や()をパース fnTreeを生成 + c_parser_parms_declarator() 型なしidリスト(これはoldSTYLEのため) + c_parser_parms_list_declarator() 型付き引数リストのパース 可変長かもみる + c_parser_parameter_declaration() + build_function_declarator() パースした引数とdelcで関数の宣言をつくる + c_declarator->u.arg_infoに引数を保持 + + +**expand_* treeをパースしてRTLを出力する +tree_expand_cfg() + expand_used_vars() + expand_function_start(current_function_decl) + cfunの値を設定して行く + assign_parms() + ここでcfun->args_sizeが設定されている + expand_gimple_basic_block() in for-loop + expand_expr_stmt() in stmt.c + expand_expr() in expr.h + expand_expr_real() expr.c + expand_expr_real_1() + +expand_expr_real_1() expr.c:8210 + expand_mult() expmed.c + expand_binop() optabs.c + GEN_FCN (icode) (temp, xop0, xop1); + 下の感じのRTLが返される + (set (reg:DF 67) (mult:DF (reg:DF 66) (reg/v:DF 64 [ d ]))) + が、この関数が返すのは (reg:DF 67)だけ + emit_insn(rtx) + RTLをDL-listに追加する. rtxはinsnでなければinsnでラッピングされる + + +**PASS LIST** +関数ごとに出力する場合、 +cgraph_assemble_pending_functions() flag_unit_at_a_timeが真なら実行 + cgraph_expand_function() + tree_rest_of_compilation + execute_pass_list + +まとめて出力する場合 +compile_file + lang_hooks.decls.final_write_globals = c_write_global_declarations flag_unit_at_a_timeが偽なら実行 + cgraph_optimize + cgraph_expand_all_functions + cgraph_expand_function + +GIMPLE treeから RTL への変換 +pass.execute = tree_expand_cfg() + +RTLからアセンブラへの変換pass final.cで定義 +pass_final.execute == rest_of_handle_final in final.c + + +最終的な RTL=>"文字列" 変換する pass +execute_one_pass() + rest_of_handle_final() + assemble_start_function() + final_start_function() + final() # insnリストを出力 + final_scan_insn() # 与えられたinsnのアセンブラを出力 + recog_memoized() # insn_data[code]のcode 決定 + get_insn_template() # 出力するアセンブラのchar*文字列を返す + output_asm_insn() # 文字列の%..を修正してファイルに出力 + final_end_function() + assemble_end_function() + +RTLの仮想レジスタを物理レジスタに置き換える pass +execute_one_pass() + instantiate_virtual_regs() + instantiate_virtual_regs_in_insn() for each instruction + extract_insn() + recog_memoized() + insn_extract() +ppcではこのrecog_memoizedで-1しか返ってこないことで落ちる + +下のmdのmatch_operand 0がaddressにしか対応してないのが問題だと思う +;; sibling call patterns +(define_expand "sibcall" + [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (use (reg:SI LR_REGNO)) + (return)])] + "" + " + { + #if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[0] = machopic_indirect_call_target (operands[0]); + #endif + + gcc_assert (GET_CODE (operands[0]) == MEM); + gcc_assert (GET_CODE (operands[1]) == CONST_INT); + + operands[0] = XEXP (operands[0], 0); + }") + + +targetm.asm_outから出力 +ターゲットマシンによってtargetm構造体の内容が変わる。 + + + +/* In all nodes that are expressions, this is the data type of the expression. + In POINTER_TYPE nodes, this is the type that the pointer points to. + In ARRAY_TYPE nodes, this is the type of the elements. + In VECTOR_TYPE nodes, this is the type of the elements. */ +#define TREE_TYPE(NODE) ((NODE)->common.type) // in tree.h +このnodeの型を表す(functionなら関数の型、pointerならそいつのさしている型.. + +/* The tree-code says what kind of node it is. + Codes are defined in tree.def. */ +#define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code) // in tree.h +このnodeがどんなtreeなのかを表す + + + +c_parser_compound_statement() + c_begin_compound_stmt() + c_parser_compund_statement_nostart() __label__, lvarの処理 + c_parser_statement_after_labels() + c_end_compound_stmt() + +c_parser_if_statement() +c_parser_do_statement() + +c_parser_paren_condition() ifやwhileの'()'の中をparseする + + +parse expressions + +c_parser_unary_expression() increment,decrement, &, *ポインタ、アドレスの処理 +c_parser_postfix_expression() 数字や変数、文字列などの処理(TCCのunary()か) +c_parser_postfix_expression_after_primary() 変数とかの後ろの'[]'や'()'の処理(関数や配列の添字) + + +c_parser_* Cのパーサ +build_* treeの生成 (Cパーサから呼ばれる) +expand_* tree(gimple)のパーサ +emit_* rtlの生成 (treeパーサから呼ばれる) + + + + +宣言時の新しい識別子 +token->type==CPP_NAME +build_id_declarator + XOBNEWを使って parser_obstackに作られる => gcc_obstack_init in default.h +変数名等を格納するc_declaratorはparser_obstack上に作られ、 + + +tree.def +tree.[ch] + +union tree_node GTY((ptr_alias (union lang_tree_node), + desc ("tree_node_structure (&%h)"))) +{ + struct tree_common GTY ((tag ("IS_COMMON"))) common; + struct tree_int_cst GTY ((tag ("IS_INT_CST"))) common; + struct tree_real_cst GTY ((tag ("IS_REAL_CST"))) common; + .. + .. +}; +c-tree.h: +struct c_expr{ + tree value; + enum tree_code original_code; +} + + +tokenizer + +c_parser_peek_token() int c-parser.c 現在参照すべきtoken を返す + c_lex_one_token() in c-parser.c + c_lex_with_flags() in c-lex.c + cpp_get_token() in libcpp(macro.c) +c_parser_next_token_is( parser, token0) tokenを取得し、それがtoken0ならtrue +c_parser_consume_token( parser) 次のtokenを取ってくる + +parser->tokens[0,1] (c_token) +この[0]に現在のtokenの情報がある。 +[1]はnext? +新たなtokenはlibcppのcpp_get_tokenによって取得する。 + +cppでは'!'や'*'などの一つ一つのtokenとなんらかの文字列を返す +予約語等の処理はgccがやる. +token +struct c_token{ + enum cpp_ttype type: 8; /* libcppで得られるtokenのtype, '<','==', name, '['などなど */ + enum c_id_kind id_kind: 8; /* type==CPP=NAMEの時のみ */ + enum rid keyword: 8; /* Cの予約語(int, if, typedef, gotoなど) */ + pragma_kind: 7; + in_systemheader: 1; + tree value; + location_t location; +} +enum cpp_ttype in libcpp/include/cpplib.h +{ + TTYPE_TABLE ==>> CPP_EQ, CPP_NOT, ... , CPP_NAME, ..., CPP_PADDING, + N_TTYPES, + + /* Positions in the table. */ + CPP_LAST_EQ = CPP_LSHIFT, + CPP_FIRST_DIGRAPH = CPP_HASH, + CPP_LAST_PUNCTUATOR= CPP_ATSIGN, + CPP_LAST_CPP_OP = CPP_LESS_EQ +}; +本来予約語もCPP_NAMEに含まれるが、無理矢理CPP_KEYWORDを作っている +CPP_KEYWORDはc-parser.cで独自に定義、N_TTYPES+1 +typedef enum c_id_kind { + C_ID_ID, /* An ordinary identifier. */ + C_ID_TYPENAME, /* An identifier declared as a typedef name. */ + C_ID_CLASSNAME, /* An identifier declared as an Objective-C class name. */ + C_ID_NONE /* Not an identifier. */ +} c_id_kind; + + +enum c_declarator_kind { /* in c-tree.h */ + cdk_id, /* An identifier. */ + cdk_function, /* A function. */ + cdk_array, /* An array. */ + cdk_pointer, /* A pointer. */ + cdk_attrs /* Parenthesized declarator with nested attributes. */ +}; +struct c_declarator { /* in c-tree.h */ + enum c_declarator_kind kind; /* The kind of declarator. */ + struct c_declarator *declarator; /* Except for cdk_id, the contained declarator. For cdk_id, NULL. */ + location_t id_loc; /* Currently only set for cdk_id. */ + union { + tree id; /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract declarator. */ + struct c_arg_info *arg_info; /* For functions. */ + struct { /* For arrays. */ + tree dimen; /* The array dimension, or NULL for [] and [*]. */ + int quals; /* The qualifiers inside []. */ + tree attrs; /* The attributes (currently ignored) inside []. */ + BOOL_BITFIELD static_p : 1; /* Whether [static] was used. */ + BOOL_BITFIELD vla_unspec_p : 1; /* Whether [*] was used. */ + } array; + int pointer_quals; /* For pointers, the qualifiers on the pointer type. */ + tree attrs; /* For attributes. */ + } u; +}; + +/* A type specifier keyword "void", "_Bool", "char", "int", "float", + "double", or none of these. */ +enum c_typespec_keyword { //でも使われてるのはdeclspec + cts_none, + cts_void, + cts_CbC_code, いる? + cts_bool, + cts_char, + cts_int, + cts_float, + cts_double, + cts_dfloat32, + cts_dfloat64, + cts_dfloat128 +}; +enum c_typespec_kind { + ctsk_resword, + ctsk_tagref, + ctsk_tagfirstref, + /* A definition of a tag such as "struct foo { int a; }". */ + ctsk_tagdef, + ctsk_typedef, + ctsk_objc, + ctsk_typeof +}; +struct c_typespec { + enum c_typespec_kind kind; + tree spec; +}; +struct c_declspecs { /* c-tree.c */ + /* The type specified, if a single type specifier such as a struct, + union or enum specifier, typedef name or typeof specifies the + whole type, or NULL_TREE if none or a keyword such as "void" or + "char" is used. Does not include qualifiers. */ + tree type; + /* The attributes from a typedef decl. */ + tree decl_attr; + /* When parsing, the attributes. Outside the parser, this will be + NULL; attributes (possibly from multiple lists) will be passed + separately. */ + tree attrs; + /* Any type specifier keyword used such as "int", not reflecting + modifiers such as "short", or cts_none if none. */ + enum c_typespec_keyword typespec_word; + /* The storage class specifier, or csc_none if none. */ + enum c_storage_class storage_class; + BOOL_BITFIELD declspecs_seen_p : 1; + BOOL_BITFIELD type_seen_p : 1; + BOOL_BITFIELD typedef_p : 1; + BOOL_BITFIELD default_int_p; + BOOL_BITFIELD long_p : 1; + BOOL_BITFIELD long_long_p : 1; + BOOL_BITFIELD short_p : 1; + BOOL_BITFIELD signed_p : 1; + : +} + + + + +**TAIL CALL OPTIMIZATION** +execute_tail_calls in tree-tailcall.c + tree_optimize_tail_calls_1(true) + たいした調査もせず、簡単にフラグCALL_EXPR_TAILCALLをたててるだけ。 + +expand_call 1834-3115 in calls.c + initialize_argument_information(); + 引数処理 + 引数をレジスタやスタックのどこに保存するかを決める + tree actparmsで示された引数をargs, args_sizeに格納する + 1011行目 We can't use sibcalls if a callee-copied argument is stored in the current function's frame. + if statement 2200行目: try_tail_call=0 + targetm.function_ok?for?sibcall(fndecl, exp) + args_size.constant > (current_function_args_size - current_function_pretend_args_size) + emit_call_1(); + SIBLING_CALL_P(..) = ( (ecf_flag & ECF_SIBLING) != 0); + +expand_callでtailcall可能かどうかの判定を詳しく行っているようだ +bool try_tail_call = CALL_EXPR_TAILCALL(exp); +2252あたりのfor文が怪しいが、900行ある。 + +2252 in calls.c +for(pass = try_tail_call ? 0:1; pass<2; pass++) 2253-3087 +2回ループ。 +1回目はtailcall用。 +2回目は普通のcalling +生成後にどちらかを選ぶ? +2227 args_size.constant > (current_function_args_size - current_function_pretend_args_size) + + hard_function_value + check_sibcall_argument_overlap + prepare_call_address + load_register_parameters + + + +Language Dependent Tree + v +GENERIC + v +GIMPLE + +GENERIC trees + LD trees + v +GIMPLE + + +**RTL** +RTL expression + クラス: RTX_OBJ, RTX_CONST_OBJ, _COMPARE _COMM_COMPARE _UNARY ... in rtx.def + オペランド: e(expression), i(integer), w, s, E, ... + +RTLへのアクセス +GET_CODE (RTX) (enum rtx_code) (RTX)->code + RTXのコード(種類)を返す +GET_RTX_CLASS (code) + このrtxコードのクラスを返す +GET_RTX_LENGTH (code) + このrtxコードのオペランドの数を返す +GET_RTX_FORMAT (code) + オペランドの種類を文字列で返す + i.e. "iuuBieieee" on CALL_INSN +XEXP(RTX, N) X->u.fld[N].rt_rtx + RTX のN番目のオペランドをexpressionとして取得する +XINT(RTX, N) X->u.fld[N].rt_int + RTX のN番目のオペランドをintegerとして取得する +XVEC(RTX, N) X->u.fld[N].rt_rtvec + RTX のN番目のオペランドをrtvectorとして取得する + XVECEXP(RTX, N, M) XVEC(RTX,N)->elem[M] + RTX のN番目のオペランドをrtvectorとし、その M番目の要素を返す + XVECLEN(RTX, N) XVEC(RTX,N)->num_elem + RTX のN番目のオペランドをrtvectorとし、そのサイズを返す + +struct rtvec_def GTY(()) { + int num_elem; /* number of elements */ + rtx GTY ((length ("%h.num_elem"))) elem[1]; +}; + + +typedef struct trx_def *rtx; //gcc/coretypes.h +struct rtx_def; //gcc/rtl.h +struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), + chain_prev ("RTX_PREV (&%h)"))) +{ + /* The kind of expression this is. */ + ENUM_BITFIELD(rtx_code) code: 16; + + /* The kind of value the expression has. */ + ENUM_BITFIELD(machine_mode) mode : 8; + + /* 1 in a MEM if we should keep the alias set for this mem unchanged + when we access a component. + 1 in a CALL_INSN if it is a sibling call. + 1 in a SET that is for a return. + In a CODE_LABEL, part of the two-bit alternate entry field. */ + unsigned int jump : 1; + /* In a CODE_LABEL, part of the two-bit alternate entry field. + 1 in a MEM if it cannot trap. */ + unsigned int call : 1; + /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere. + 1 in a SUBREG if it references an unsigned object whose mode has been + from a promoted to a wider mode. + 1 in a SYMBOL_REF if it addresses something in the per-function + constants pool. + 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call. + 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */ + unsigned int unchanging : 1; + /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile. + 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE + if it has been deleted. + 1 in a REG expression if corresponds to a variable declared by the user, + 0 for an internally generated temporary. + 1 in a SUBREG with a negative value. + 1 in a LABEL_REF or in a REG_LABEL note for a non-local label. + In a SYMBOL_REF, this flag is used for machine-specific purposes. */ + unsigned int volatil : 1; + /* 1 in a MEM referring to a field of an aggregate. + 0 if the MEM was a variable or the result of a * operator in C; + 1 if it was the result of a . or -> operator (on a struct) in C. + 1 in a REG if the register is used only in exit code a loop. + 1 in a SUBREG expression if was generated from a variable with a + promoted mode. + 1 in a CODE_LABEL if the label is used for nonlocal gotos + and must not be deleted even if its count is zero. + 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled + together with the preceding insn. Valid only within sched. + 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and + from the target of a branch. Valid from reorg until end of compilation; + cleared before used. */ + unsigned int in_struct : 1; + /* At the end of RTL generation, 1 if this rtx is used. This is used for + copying shared structure. See `unshare_all_rtl'. + In a REG, this is not needed for that purpose, and used instead + in `leaf_renumber_regs_insn'. + 1 in a SYMBOL_REF, means that emit_library_call + has used it as the function. */ + unsigned int used : 1; + /* 1 in an INSN or a SET if this rtx is related to the call frame, + either changing how we compute the frame address or saving and + restoring registers in the prologue and epilogue. + 1 in a REG or MEM if it is a pointer. + 1 in a SYMBOL_REF if it addresses something in the per-function + constant string pool. */ + unsigned frame_related : 1; + /* 1 in a REG or PARALLEL that is the current function's return value. + 1 in a MEM if it refers to a scalar. + 1 in a SYMBOL_REF for a weak symbol. */ + unsigned return_val : 1; + + /* The first element of the operands of this rtx. + The number of operands and their types are controlled + by the `code' field, according to rtl.def. */ + union u { + rtunion fld[1]; + HOST_WIDE_INT hwint[1]; + struct block_symbol block_sym; + struct real_value rv; + } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; +}; + + +FUNCTION_TYPEの実態はtree_type +make_node_stat(FUNCTION_TYPE)で作成される + TREE_TYPE + TYPE_ARG_TYPES ->type.values + TYPE_UID ->type.uid + TYPE_ALIGN ->type.align + TYPE_USER_ALIGN ->type.user_align + TYPE_MAIN_VARIANT ->type.main_variant + TYPE_ATTRIBUTES ->type.attributes + +こいつの lang_flag_6 ビットフィールドをcode segmentかどうかのフラグとする。 +#define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type.lang_flag_5) //tree.h +#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 (TYPE) //c-tree.h +code segmentを作ったらCbC_IS_CODE_SEGMENT(type) = 1 でセット できる? + + + + + + +**GENERIC TREE** +関数の型 + + unit size + align 64 symtab 0 alias set -1 precision 64 + pointer_to_this > + QI + size constant invariant 8> + unit size constant invariant 1> + align 8 symtab 0 alias set -1 + arg-types > + +関数の引数 + + unit size + align 32 .... + chain > + +配列 + + BLK + size constant invariant 320> + unit size constant invariant 40> + align 32 symtab 0 alias set -1 + domain unit size + align 32 symtab 0 alias set -1 precision 32 min max > + SI size unit size + align 32 symtab 0 alias set -1 precision 32 min max >> + +関数呼び出し + + side-effects arg 0 + unsigned SI + size + unit size + align 32 symtab 0 alias set -1> + constant invariant + arg 0 + addressable used public external decl_5 QI defer-output file test_tree.c line 2>> + arg 1 + chain + chain + chain + constant invariant 2.5e+0>>>>>> + + +build_function_call(tree fndecl, tree exprlist) +FUNCTION_DECLとEXPRのリストからCALL_EXPRを作って返す + +convert_arguments(arglist, params, function, fundecl); +check_function_arguments(); + + +配列の作り方 +icst : INTEGER_CST +itype: INTEGER_TYPE + +icst = build_int_cst (NULL_TREE, size-1); +itype = build_index_type (icst); +array = build_array_type + +//build_range_type(size_type, integer_zero_node, exp) + + + +**PPC** +http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/ASMIntroduction/chapter_1_section_1.html +http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-SW17 +http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html +http://www.freescale.co.jp/pdf/MPCFPE32BJ_R1a.pdf +http://www.nk.rim.or.jp/~jun/ppcasm/ppcasm01.html + + + + + +**ソースコード読み会 準備** +cd ~/public_html +mkdir gcc; cd gcc +checkout CbC_project/GCC; CbC_project/GCC +./configure --... +make +gtags +htags -Ffx -t 'GCC source tour' +cd ../../ +tar -czv CbC_project --exclude **/CVS -f GCC-source-....tar.gz + + + +normal tail call +(call_insn/j 24 23 0 (parallel [ + (call (mem:SI (symbol_ref:SI ("cs0") [flags 0x403] ) [0 S4 A8]) + (const_int 256 [0x100])) + (use (const_int 0 [0x0])) + (use (reg:SI 125)) + (return) + ]) -1 (nil) + (expr_list:REG_EH_REGION (const_int 0 [0x0]) + (nil)) + (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) + (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) + (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) + (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) + (nil)))))) + +indirect tail call +(call_insn/j 25 24 0 (parallel [ + (call (mem:SI (reg/f:SI 129) [0 S4 A8]) + (const_int 256 [0x100])) + (use (const_int 0 [0x0])) + (use (reg:SI 130)) + (return) + ]) -1 (nil) + (nil) + (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) + (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) + (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) + (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) + (nil)))))) + + + +CFLAGS='-O0 -gdwarf-2 -g3' ../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/INSTALL-DIR --enable-checking=tree,rtl,assert --disable-shared --disable-threads --with-headers --with-system-zlib --with-newlib --enable-version-specific-runtime-libs --disable-libssp --target=spu + +../toolchain/gcc/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --disable-shared --disable-threads --disable-checking --with-headers --with-system-zlib --with-newlib --enable-languages=c,c++,fortran --disable-nls --enable-version-specific-runtime-libs --disable-libssp --program-prefix=spu- --target=spu + + + + +$ cvs checkout CbC_project/GCC +$ mkdir tmp; cd tmp +$ wget http://www.bsc.es/projects/deepcomputing/linuxoncell/cellsimulator/sdk3.0/SRPMS/spu-gcc-4.1.1-107.src.rpm +$ rpm2cpio spu-gcc--4.1.1-107.src.rpm | cpio -i -v +$ tar xjvf gcc-r886.tar.bz2 +$ cat *.diff | patch -d ../CbC_project/GCC -p2 +$ cp toolchain/gcc/config.sub ../CbC_project/GCC/ +$ cp toolchain/gcc/gcc/config.gcc ../CbC_project/GCC/gcc/ +$ cd ../CbC_project/GCC +$ + + +change bit_merge to vec_merge in gcc/config/spu/spu.md +split0_completed; in recog.c, rtl.h, final.c +SPU_FLOAT_FORMAT +: diff -r 84e7813d76e9 -r d34655255c78 CbC-scripts/make_headers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-scripts/make_headers.py Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,124 @@ +#!/usr/bin/env python3.0 + + +import sys +import re +import getopt + +reserved_words = [ "if", "for", "switch", "return", "while", "else", ] + +PATTERN = "([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^{/;]*)\)\s*\{" +# TODO: 関数パラメータ内にコメントがあると正しく動かない! +# TODO: int * const * とか大丈夫? +PROG = re.compile(PATTERN, re.S) + +omit_static=False +add_extern="" + +def truncate_comments(data): + pass + +def check_reserved_word(decl): + """ return true if decl's type and name is not reserved word. """ + + if decl["name"] in reserved_words or decl["type"] in reserved_words: + return False + return True + +def read_decls(file): + declarators = [] + + # open the file and read all lines into a string. + try: + fo = open(file, 'r') + lines = fo.readlines() + data = "".join(lines) + truncate_comments(data) + except IOError: + print("cannot read file %s" % file) + return None + + # find all matched strings. + # moiter is iterator of MatchObject. + moiter = PROG.finditer(data) + for mo in moiter: + tmp = { "type": mo.group(1), + "name": mo.group(2), + "parms": mo.group(3), + "offset": mo.start() } + if check_reserved_word(tmp): + declarators.append(tmp) + + return declarators + +def debug_print(decl): + for (key,value) in list(decl.items()): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print("Type:\t{0:s}".format(decl["type"])) + print("Name:\t{0:s}".format(decl["name"])) + print("Params:\t{0:s}".format(decl["parms"])) + print("offset:\t{0:d}".format(decl["offset"])) + print("") + +def format_print(decl, file): + for (key,value) in list(decl.items()): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print("/* defined in file {0:s} at offset {1:d} */".format(file,decl["offset"])) + print("{3:s}{0:s} {1:s} ({2:s});".format(decl["type"],decl["name"],decl["parms"], add_extern)) + print("") + +def getoptions(): + global omit_static, add_extern + + try: + opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ]) + except getopt.GetoptError as err: + print(err) + usage() + sys.exit(2) + + for opt,a in opts: + if opt in ("-s", "--omit-static"): + omit_static=True + elif opt in ("-e", "--add-extern"): + add_extern="extern " + else: + print("unhandled option {0}".format(opt)) + usage() + + return args + +def usage(): + print( """\ +Usage: {0:s} OPION... [FILE]... +OPTIONS: + -s, --omit-static omit static functions + -e, --add-extern add extern to all function declarations + """.format(sys.argv[0])) + +def main(): + + # option handling. + args = getoptions() + + for file in args: + # read function declaration from each file. + decls = read_decls(file) + if decls==None or len(decls)==0: + # no function found. + print("{0} have no function definition!".format(file)) + continue + + for decl in decls: + if omit_static and 0 <= decl["type"].find("static"): + # static function is ignored. + continue + #debug_print(decl) + format_print(decl, file) + +main() + diff -r 84e7813d76e9 -r d34655255c78 CbC-scripts/make_headers.py2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-scripts/make_headers.py2 Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import re +import getopt + +reserved_words = [ "if", "for", "switch", "return", "while", "else", ] + +PATTERN = r"([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^\{/;]*)\)\s*\{" +#PATTERN = r"([a-zA-Z_]\w*)\s+([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{" +#PATTERN = r"((?:[a-zA-Z_]\w*)\s+)+?([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{" +# TODO: 関数パラメータ内にコメントがあると正しく動かない! +PROG = re.compile(PATTERN, re.S) + +omit_static=False +add_extern="" + +def truncate_comments(data): + pass + +def check_reserved_word(decl): + """ return true if decl's type and name is not reserved word. """ + + if decl["name"] in reserved_words or decl["type"] in reserved_words: + return False + return True + +def read_decls(file): + declarators = [] + + # open the file and read all lines into a string. + try: + fo = open(file, 'r') + lines = fo.readlines() + data = "".join(lines) + truncate_comments(data) + except IOError: + print "cannot read file %s" % file + return None + + # find all matched strings. + # moiter is iterator of MatchObject. + moiter = PROG.finditer(data) + for mo in moiter: + tmp = { "type": mo.group(1), + "name": mo.group(2), + "parms": mo.group(3), + "offset": mo.start() } + if check_reserved_word(tmp): + declarators.append(tmp) + + return declarators + +def debug_print(decl): + for (key,value) in decl.items(): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print "Type:\t%s" % decl["type"] + print "Name:\t%s" % decl["name"] + print "Params:\t%s" % decl["parms"] + print "offset:\t%d" % decl["offset"] + print "" + #s = "%s %s ( %s );" % (decl["type"], decl["name"], decl["parms"]) + #print s, "/* offset: %d */" % decl["offset"] + +def format_print(decl, file): + for (key,value) in decl.items(): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print "/* defined in file %s at offset %d */" % (file,decl["offset"]) + print "%s%s %s (%s);" % (add_extern, decl["type"],decl["name"],decl["parms"]) + print "" + +def getoptions(): + global omit_static, add_extern + + try: + opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ]) + except getopt.GetoptError: + print(err) + usage() + sys.exit(2) + + for opt,a in opts: + if opt in ("-s", "--omit-static"): + omit_static=True + elif opt in ("-e", "--add-extern"): + add_extern="extern " + else: + print("unhandled option {0}".format(opt)) + usage() + + return args + +def usage(): + print( """\ +Usage: {0:s} OPION... [FILE]... +OPTIONS: + -s, --omit-static omit static functions + -e, --add-extern add extern to all function declarations + """.format(sys.argv[0])) + +def main(): + # option handling. + args = getoptions() + + for file in args: + # read function declaration from each file. + decls = read_decls(file) + if decls==None or len(decls)==0: + # no function found. + print "%s have no function definition!" % file + continue + + for decl in decls: + if omit_static and 0 <= decl["type"].find("static"): + # static function is ignored. + continue + #debug_print(decl) + format_print(decl, file) + +main() + diff -r 84e7813d76e9 -r d34655255c78 configure diff -r 84e7813d76e9 -r d34655255c78 gcc/ChangeLog.CbC --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/ChangeLog.CbC Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,69 @@ +2009-08-20 Shinji KONO + + どうも、goto hoge(0),env; で、env を渡すのがよろしくない。 + goto hoge(0,env); + と言う形にして、hoge 側で env を設定するのはどうか? + + __code main_return2_1(int i,stack sp) { + goto (( (struct main_continuation *)sp)->main_ret)(0), + ((struct main_continuation *)sp)->env; + } + + を、 + + __code main_return2_1(int i,stack sp) { + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); + } + という形にする。 + + そうすれば、goto 文は、かなり簡単になる。 + +2009-08-20 Shinji KONO + +以下のようにすれば良いらしい... いっそ #define でも出来るが。 + + extern int printf(const char *, ...); + + void g( void (*ret)(int retval_,void *f) , void *fp) { + printf("g: fp = 0x%x\n",__builtin_frame_address(0)); + (*ret)(5,fp); + } + + int f() + { + + int retval = 1; + void (*ret)(int retval_,void *fp) ; + + ret = ({ + __label__ exit0; + volatile static flag = 0; + void __return_func(int retval_,void *fp) { + retval = retval_; + goto exit0; + } + if (flag) { + exit0: + printf("f1: fp = 0x%x\n",__builtin_frame_address(0)); + return retval; + } + __return_func; + }); + + printf("f0: fp = 0x%x\n",__builtin_frame_address(0)); + + g(ret,__builtin_frame_address(0)); + + printf("bad\n"); + + return retval; + } + + + int + main() + { + printf("%d\n",f()); + } + diff -r 84e7813d76e9 -r d34655255c78 gcc/Makefile.in diff -r 84e7813d76e9 -r d34655255c78 gcc/aclocal.m4 diff -r 84e7813d76e9 -r d34655255c78 gcc/c-family/c-common.c --- a/gcc/c-family/c-common.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c-family/c-common.c Thu Oct 25 10:21:07 2018 +0900 @@ -374,6 +374,10 @@ { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY }, { "__builtin_call_with_static_chain", RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY }, +#ifndef noCbC + /* CbC project */ + { "__code", RID_CbC_CODE, 0 }, +#endif { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY }, { "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY }, { "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY }, @@ -386,6 +390,11 @@ { "__complex__", RID_COMPLEX, 0 }, { "__const", RID_CONST, 0 }, { "__const__", RID_CONST, 0 }, +#ifndef noCbC + /* CbC project */ + { "_CbC_environment", RID_CbC_ENV, 0 }, + { "_CbC_return", RID_CbC_RET, 0 }, +#endif { "__decltype", RID_DECLTYPE, D_CXXONLY }, { "__direct_bases", RID_DIRECT_BASES, D_CXXONLY }, { "__extension__", RID_EXTENSION, 0 }, diff -r 84e7813d76e9 -r d34655255c78 gcc/c-family/c-common.h --- a/gcc/c-family/c-common.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c-family/c-common.h Thu Oct 25 10:21:07 2018 +0900 @@ -198,6 +198,10 @@ RID_AT_INTERFACE, RID_AT_IMPLEMENTATION, +#ifndef noCbC + /* Continuation based C */ + RID_CbC_CODE, RID_CbC_ENV, RID_CbC_RET, +#endif /* Named address support, mapping the keyword to a particular named address number. Named address space 0 is reserved for the generic address. If there are more than 254 named addresses, the addr_space_t type will need diff -r 84e7813d76e9 -r d34655255c78 gcc/c-family/c-pretty-print.c --- a/gcc/c-family/c-pretty-print.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c-family/c-pretty-print.c Thu Oct 25 10:21:07 2018 +0900 @@ -29,6 +29,9 @@ #include "intl.h" #include "tree-pretty-print.h" #include "selftest.h" +#ifndef noCbC +#include "../c/cbc-tree.h" +#endif /* The pretty-printer code is primarily designed to closely follow (GNU) C and C++ grammars. That is to be contrasted with spaghetti diff -r 84e7813d76e9 -r d34655255c78 gcc/c/c-decl.c --- a/gcc/c/c-decl.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c/c-decl.c Thu Oct 25 10:21:07 2018 +0900 @@ -57,6 +57,12 @@ #include "c-family/name-hint.h" #include "c-family/known-headers.h" #include "c-family/c-spellcheck.h" +#ifndef noCbC +#include "cbc-tree.h" +tree cbc_env; +tree cbc_return_f; +location_t cbc_return; +#endif /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -3381,8 +3387,13 @@ /* Generate an implicit declaration for identifier FUNCTIONID at LOC as a function of type int (). */ +#ifndef noCbC +tree +implicitly_declare (location_t loc, tree functionid, int fun) +#else tree implicitly_declare (location_t loc, tree functionid) +#endif { struct c_binding *b; tree decl = NULL_TREE; @@ -3472,7 +3483,12 @@ } /* Not seen before. */ +#ifndef noCbC + decl = build_decl (loc, FUNCTION_DECL, functionid, + fun==RID_CbC_CODE?build_function_type (void_type_node, NULL_TREE):default_function_type); +#else decl = build_decl (loc, FUNCTION_DECL, functionid, default_function_type); +#endif DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; C_DECL_IMPLICIT (decl) = 1; @@ -6492,6 +6508,14 @@ } type_quals = TYPE_UNQUALIFIED; +#ifndef noCbC + if ( declspecs->typespec_word == cts_CbC_code ) + { + type = build_code_segment_type (type, arg_types); + } + else +#endif + type = build_function_type (type, arg_types); declarator = declarator->declarator; @@ -8723,6 +8747,61 @@ return tree_cons (decl, value, NULL_TREE); } +#ifndef noCbC +#define CbC_STACK_SIZE (1024 * 8) +static void cbc_set_codesegment(tree fndecl){ + tree args; + tree *nextp; + int padding_size = CbC_STACK_SIZE; + + nextp = & TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + for (args = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); args; + args = TREE_CHAIN (args)) + { + tree type = args ? TREE_VALUE (args) : 0; + tree type_size; + unsigned int size; + + if (type == void_type_node) + break; + + type_size = TYPE_SIZE (type); + size = TREE_INT_CST_LOW (type_size); + padding_size -= size; + + nextp = & TREE_CHAIN(args); + } + + /* error check. */ + if (padding_size<0) + { + error ("CbC: too many arguments on code segment %qE", fndecl); + return ; + } + else if (padding_size==0) + return ; + +#if 0 + /* itype is integer_type that means last index. */ + icst = build_int_cst (NULL_TREE, padding_size-1); + itype = build_index_type (icst); + + /* create array_type node. */ + padding_array = build_array_type (integer_type_node, itype); + + /* add array_type to this function's argument list + before void_type_node. */ + if (!args) + args = build_tree_list(NULL_TREE, void_type_node); + list = build_tree_list(NULL_TREE, padding_array); + TREE_CHAIN(list) = args; + *nextp = list; +#endif + + return ; +} +#endif + /* Create the FUNCTION_DECL for a function definition. DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of @@ -8756,6 +8835,16 @@ decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, &attributes, NULL, NULL, DEPRECATED_NORMAL); +#ifndef noCbC + cbc_return_f = NULL_TREE; + cbc_env = NULL_TREE; + if ( declspecs->typespec_word == cts_CbC_code ) + { + cbc_set_codesegment(decl1); + } + +#endif + invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1); /* If the declarator is not suitable for a function definition, @@ -10097,6 +10186,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_int_n) error_at (loc, ("both % and %<__int%d%> in " @@ -10154,6 +10249,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_int_n) error_at (loc, ("both % and %<__int%d%> in " @@ -10215,6 +10316,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_bool) error_at (loc, ("both % and %<_Bool%> in " @@ -10267,6 +10374,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_bool) error_at (loc, ("both % and %<_Bool%> in " @@ -10318,6 +10431,13 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif + else if (specs->typespec_word == cts_bool) error_at (loc, ("both % and %<_Bool%> in " @@ -10544,6 +10664,32 @@ specs->locations[cdw_typespec] = loc; } return specs; +#ifndef noCbC + case RID_CbC_CODE: + if (specs->long_p) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->short_p) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->signed_p) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->unsigned_p) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->complex_p) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else + specs->typespec_word = cts_CbC_code; + return specs; +#endif case RID_BOOL: if (!in_system_header_at (loc)) pedwarn_c90 (loc, OPT_Wpedantic, @@ -11116,6 +11262,9 @@ /* Type to be filled in later. */ break; case cts_void: +#ifndef noCbC + case cts_CbC_code: +#endif gcc_assert (!specs->long_p && !specs->short_p && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); diff -r 84e7813d76e9 -r d34655255c78 gcc/c/c-parser.c --- a/gcc/c/c-parser.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c/c-parser.c Thu Oct 25 10:21:07 2018 +0900 @@ -68,6 +68,9 @@ #include "intl.h" #include "c-family/name-hint.h" #include "tree-iterator.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif /* We need to walk over decls with incomplete struct/union/enum types after parsing the whole translation unit. @@ -505,6 +508,9 @@ case RID_SAT: case RID_AUTO_TYPE: case RID_ALIGNAS: +#ifndef noCbC + case RID_CbC_CODE: +#endif return true; default: if (keyword >= RID_FIRST_INT_N @@ -682,6 +688,9 @@ case RID_ALIGNAS: case RID_ATOMIC: case RID_AUTO_TYPE: +#ifndef noCbC + case RID_CbC_CODE: +#endif return true; default: if (token->keyword >= RID_FIRST_INT_N @@ -2771,6 +2780,27 @@ declspecs_add_type (loc, specs, t); c_parser_consume_token (parser); break; +#ifndef noCbC + case RID_CbC_CODE: + if (!typespec_ok) + goto out; + attrs_ok = true; + seen_type = true; + if (c_dialect_objc ()) + parser->objc_need_raw_identifier = true; + t.kind = ctsk_resword; + t.spec = c_parser_peek_token (parser)->value; + declspecs_add_type (loc, specs, t); +#ifdef TARGET_64BIT + if(!TARGET_64BIT) { + attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); + declspecs_add_attrs(loc, specs, attrs); + } +#endif + + c_parser_consume_token (parser); + break; +#endif case RID_ENUM: if (!typespec_ok) goto out; @@ -5395,10 +5425,49 @@ which is not enclosed in braces and has an else clause. This is used to implement -Wparentheses. */ +static tree +cbc_replace_arguments (location_t loc, tree call) +{ + tree arg; + tree fn; + tree tmp_decl; + int i=0; + call_expr_arg_iterator iter; + + fn = CALL_EXPR_FN (call); + if ( TREE_CODE (fn)==PARM_DECL || !TREE_CONSTANT (fn) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(fn)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, fn, NULL_TREE)); + CALL_EXPR_FN (call) = tmp_decl; + } + + FOR_EACH_CALL_EXPR_ARG (arg, iter, call) + { + /* if ( !CONSTANT_CLASS_P (arg) && !VAR_OR_FUNCTION_DECL_P (arg) ) */ + if ( TREE_CODE (arg)==PARM_DECL || !TREE_CONSTANT (arg) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(arg)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, arg, NULL_TREE)); + CALL_EXPR_ARG (call, i) = tmp_decl; + } + i++; + } + + return call; +} + static void c_parser_statement_after_labels (c_parser *parser, bool *if_p, vec *chain) { +#ifndef noCbC + struct c_expr expr; +#endif location_t loc = c_parser_peek_token (parser)->location; tree stmt = NULL_TREE; bool in_if_block = parser->in_if_block; @@ -5434,8 +5503,14 @@ break; case RID_GOTO: c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_NAME)) - { +#ifndef noCbC + if ( c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON ) + { +#else + if (c_parser_next_token_is (parser, CPP_NAME)) + { +#endif stmt = c_finish_goto_label (loc, c_parser_peek_token (parser)->value); c_parser_consume_token (parser); @@ -5450,7 +5525,40 @@ stmt = c_finish_goto_ptr (loc, val.value); } else - c_parser_error (parser, "expected identifier or %<*%>"); +#ifndef noCbC + { + if (c_parser_next_token_is (parser, CPP_NAME)) + { + tree id = c_parser_peek_token (parser)->value; + location_t loc = c_parser_peek_token (parser)->location; + /** build_external_ref (id,RID_CbC_CODE , loc); **/ + build_external_ref (loc, id, RID_CbC_CODE, &expr.original_type); + } + expr = c_parser_expr_no_commas (parser, NULL); + if (TREE_CODE(expr.value) == CALL_EXPR ) + { + location_t loc = c_parser_peek_token (parser)->location; + cbc_replace_arguments (loc, expr.value); + + TREE_TYPE(expr.value) = void_type_node; + /*tree env = NULL_TREE;**/ + CbC_IS_CbC_GOTO (expr.value) = 1; + CALL_EXPR_TAILCALL (expr.value) = 1; + add_stmt(expr.value); + bool warn_return_type_save = warn_return_type; + bool flag_isoc99_save = flag_isoc99; + warn_return_type = false; + flag_isoc99 = false; + stmt = c_finish_return(loc, NULL_TREE, NULL_TREE); /* stmt = c_finish_return (0); */ + warn_return_type = warn_return_type_save; + flag_isoc99 = flag_isoc99_save; + } + else + c_parser_error (parser, "expected code segment jump or %<*%>"); + } +#else + c_parser_error (parser, "expected identifier or %<*%>"); +#endif goto expect_semicolon; case RID_CONTINUE: c_parser_consume_token (parser); @@ -7846,6 +7954,138 @@ Classname . identifier */ +static void +cbc_finish_labeled_goto (location_t loc, tree label, tree retval) +{ + /* add statement below. + * + * if (0) { + * _cbc_exit0: + * return retval; + * } + */ + tree tlab; + tree cond; + + cond = integer_zero_node; + tree block_outside = c_begin_compound_stmt (false); + tree block_inside = c_begin_compound_stmt (false); + + tree stmt = c_begin_compound_stmt (true); + tlab = define_label (loc, label); + gcc_assert (tlab); + decl_attributes (&tlab, NULL_TREE, 0); + TREE_USED (tlab) = 1; + /* add_stmt (LABEL_EXPR) */ + add_stmt (build_stmt (loc, LABEL_EXPR, tlab)); + + /* add_stmt (RETURN_EXPR) */ + tree ret = c_finish_return (loc, retval, retval); + DECL_READ_P(retval) = 1; // (NODE)->decl_common.decl_read_flag = 1; + // TREE_USED(ret) = 1; + tree stmt_body = c_end_compound_stmt (loc, stmt, true); + + /* add_stmt (STATEMENT_LIST) : STATEMENT_LIST -> LABEL_EXPR -> RETURN_EXPR */ + add_stmt (stmt_body); + + tree body = c_end_compound_stmt (loc, block_inside, false); + + /* add_stmt (COND_EXPR) */ + c_finish_if_stmt (loc, cond, body, NULL_TREE); + + /* add_stmt (BIND_EXPR) : BIND_EXPR -> COND_EXPR -> STATEMENT_LIST */ + tree bind = c_end_compound_stmt (loc, block_outside, false); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + + TREE_USED (retval) = 1; + +} +static tree +cbc_finish_nested_function (location_t loc, tree label, tree retval_decl) +{ + + /* add statement below. + * void ___cbc_internal_return(int _retval, void *_envp){ + * retval = _retval; + * goto exit0; + * } + */ + /* TODO: + * retval(lhs)のTREE_DECLを引数から取得するように + * int _retvalパラメータのタイプはretvalに合わせる + */ + + tree fnbody; + tree _retval_decl, _envp_decl; + struct c_declarator *declarator; + //tree ident; + struct c_arg_info *args; + struct c_declspecs *specs; + struct c_typespec t; + { + push_scope (); + declare_parm_level (); + /*tree retval_type = TREE_TYPE(retval_decl);*/ + + _retval_decl = build_decl (loc, PARM_DECL, get_identifier ("_retval"), TREE_TYPE(retval_decl)); + DECL_SOURCE_LOCATION (_retval_decl) = loc; + DECL_ARTIFICIAL (_retval_decl) = 1; + DECL_ARG_TYPE (_retval_decl) = TREE_TYPE(retval_decl); + pushdecl (_retval_decl); + finish_decl (_retval_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + _envp_decl = build_decl (loc, PARM_DECL, get_identifier ("_envp"), ptr_type_node); + DECL_SOURCE_LOCATION (_envp_decl) = loc; + DECL_ARTIFICIAL (_envp_decl) = 1; + DECL_ARG_TYPE (_envp_decl) = ptr_type_node; + pushdecl (_envp_decl); + finish_decl (_envp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + + args = get_parm_info(false, NULL); + pop_scope(); + } + + t.kind = ctsk_resword; + t.spec = get_identifier("void"); + specs = build_null_declspecs(); + declspecs_add_type (loc, specs, t); + finish_declspecs (specs); + + /* make nested function. */ + declarator = build_id_declarator (get_identifier ("_cbc_internal_return")); + declarator = build_function_declarator (args, declarator); + + c_push_function_context (); + + if (!start_function (specs, declarator, NULL_TREE)) + { + c_pop_function_context(); + gcc_assert (0); + } + store_parm_decls (); + + + /* start compound statement. */ + tree cstmt = c_begin_compound_stmt (true); + + add_stmt (build_modify_expr (loc, retval_decl, NULL_TREE, NOP_EXPR, loc, _retval_decl, NULL_TREE)); + tree stmt = c_finish_goto_label (loc, label); + + /* end compound statement. */ + fnbody = c_end_compound_stmt (loc, cstmt, true); + TREE_SIDE_EFFECTS (cstmt) = 1; + + /* finish declaration of nested function. */ + tree decl = current_function_decl; + add_stmt (fnbody); + finish_function (); + c_pop_function_context (); + + add_stmt (build_stmt (loc, DECL_EXPR, decl)); + return decl; + +} + static struct c_expr c_parser_postfix_expression (c_parser *parser) { @@ -8991,6 +9231,92 @@ set_c_expr_source_range (&expr, loc, close_loc); } break; +#ifndef noCbC + case RID_CbC_ENV: + { + c_parser_consume_token (parser); + /* get value of %ebp. */ + /*tree env_tree = build_external_ref ( + get_identifier ("__builtin_frame_address"), 0, + c_parser_peek_token (parser)->location);*/ + loc = c_parser_peek_token (parser)->location; + tree env_tree = build_external_ref (loc, + get_identifier ("__builtin_frame_address"), 0, &expr.original_type); + expr.value = build_function_call(loc, env_tree, + build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0))); + expr.original_code = ERROR_MARK; + + } + break; + case RID_CbC_RET: + case RID_RETURN: + + { + /* + ({ + __label__ _cbc_exit0; + int retval; // should be thread local + void _cbc_internal_return(int retval_, void *_envp){ + retval = retval_; + goto _cbc_exit0; + } + if (0) { + _cbc_exit0: + return retval; + } + _cbc_internal_return; + }); + */ + tree value, stmt, label, tlab, decl; + c_parser_consume_token (parser); + + stmt = c_begin_stmt_expr (); + cbc_return_f = c_parser_peek_token (parser)->value; + location_t location = c_parser_peek_token (parser)->location; + + /* create label. (__label__ _cbc_exit0;) */ + label = get_identifier ("_cbc_exit0"); + tlab = declare_label (label); + C_DECLARED_LABEL_FLAG (tlab) = 1; + add_stmt (build_stmt (location, DECL_EXPR, tlab)); + + /* declare retval. (int retval;) */ + tree decl_cond = + build_decl (location, VAR_DECL, get_identifier ("retval"), + TREE_TYPE (TREE_TYPE (current_function_decl))); + TREE_STATIC (decl_cond) = 1; + TREE_USED (decl_cond) = 1; + + /* Use thread-local */ + //DECL_TLS_MODEL (decl_cond) = decl_default_tls_model (decl_cond); + set_decl_tls_model (decl_cond, decl_default_tls_model (decl_cond)); + DECL_NONLOCAL (decl_cond) = 1; + DECL_ARTIFICIAL (decl_cond) = 1; + add_stmt (build_stmt(location, DECL_EXPR, pushdecl (decl_cond))); + + /* define nested function. */ + decl = + cbc_finish_nested_function (location, label, decl_cond); + TREE_USED(decl) = 1; + TREE_LANG_FLAG_5(decl) = 1; + + /* define if-ed goto label and return statement. */ + cbc_finish_labeled_goto (location, label, decl_cond); + + /* get pointer to nested function. */ + //value = build_addr (decl , current_function_decl); + value = build_addr (decl); + TREE_USED (current_function_decl) = 1; + SET_EXPR_LOCATION (value, location); + add_stmt (value); + + TREE_SIDE_EFFECTS (stmt) = 1; + expr.value = c_finish_stmt_expr (location, stmt); + expr.original_code = ERROR_MARK; + } + + break; +#endif //noCbC case RID_GENERIC: expr = c_parser_generic_selection (parser); break; diff -r 84e7813d76e9 -r d34655255c78 gcc/c/c-tree.h --- a/gcc/c/c-tree.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c/c-tree.h Thu Oct 25 10:21:07 2018 +0900 @@ -238,6 +238,9 @@ cts_float, cts_int_n, cts_double, +#ifndef noCbC + cts_CbC_code, +#endif cts_dfloat32, cts_dfloat64, cts_dfloat128, @@ -558,7 +561,11 @@ struct c_declspecs *, tree, tree *); extern tree groktypename (struct c_type_name *, tree *, bool *); extern tree grokparm (const struct c_parm *, tree *); +#ifndef noCbC +extern tree implicitly_declare (location_t, tree, int); +#else extern tree implicitly_declare (location_t, tree); +#endif extern void keep_next_level (void); extern void pending_xref_error (void); extern void c_push_function_context (void); diff -r 84e7813d76e9 -r d34655255c78 gcc/c/c-typeck.c --- a/gcc/c/c-typeck.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/c/c-typeck.c Thu Oct 25 10:21:07 2018 +0900 @@ -52,6 +52,9 @@ #include "stringpool.h" #include "attribs.h" #include "asan.h" +#ifndef noCbC + #include "cbc-tree.h" +#endif /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ @@ -494,6 +497,9 @@ /* Function types: prefer the one that specified arg types. If both do, merge the arg types. Also merge the return types. */ { +#ifndef noCbC + int is_code_segment = CbC_IS_CODE_SEGMENT(t1); +#endif tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); @@ -510,12 +516,20 @@ /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == NULL_TREE) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t2)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); } if (TYPE_ARG_TYPES (t2) == NULL_TREE) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t1)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); @@ -607,6 +621,11 @@ parm_done: ; } +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, newargs); + else +#endif + t1 = build_function_type (valtype, newargs); t1 = qualify_type (t1, t2); } @@ -2757,7 +2776,11 @@ } else if (fun) /* Implicit function declaration. */ +#ifndef noCbC + ref = implicitly_declare (loc, id, fun); +#else ref = implicitly_declare (loc, id); +#endif else if (decl == error_mark_node) /* Don't complain about something that's already been complained about. */ @@ -3552,8 +3575,13 @@ } gcc_assert (parmnum == vec_safe_length (values)); - - if (typetail != NULL_TREE && TREE_VALUE (typetail) != void_type_node) +#ifndef noCbC + if (typetail != 0 && TREE_VALUE (typetail) != void_type_node + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(fundecl)) ) + && !(fundecl&&CbC_IS_CODE_SEGMENT(fundecl)) ) +#else + if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) +#endif { error_at (loc, "too few arguments to function %qE", function); inform_declaration (fundecl); diff -r 84e7813d76e9 -r d34655255c78 gcc/c/cbc-tree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/c/cbc-tree.h Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,14 @@ +/* #define CbC_PRETENDED_STACK_SIZE 256 */ +#define CbC_PRETENDED_STACK_SIZE 1024 + +/* Set if the fntype is code segment on CbC language. */ +/* flag3,5,6 has been used by c-tree.h */ +#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 ( FUNCTION_TYPE_CHECK(TYPE)) + +/* Set if the CALL_EXPR NODE is goto statement on CbC language. */ +#define CbC_IS_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) +#define CALL_EXPR_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) + +extern tree cbc_return_f; +extern tree cbc_env; +extern location_t cbc_return; diff -r 84e7813d76e9 -r d34655255c78 gcc/calls.c --- a/gcc/calls.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/calls.c Thu Oct 25 10:21:07 2018 +0900 @@ -119,6 +119,9 @@ word-sized pseudos we made. */ rtx *aligned_regs; int n_aligned_regs; +#ifndef noCbC +rtx exprs; +#endif }; /* A vector of one char per byte of stack space. A byte if nonzero if @@ -3066,6 +3069,10 @@ return true; } +#ifndef noCbC +#include "c/cbc-tree.h" +#endif + /* If X is a likely-spilled register value, copy it to a pseudo register and return that register. Return X otherwise. */ @@ -3610,8 +3617,15 @@ pushed these optimizations into -O2. Don't try if we're already expanding a call, as that means we're an argument. Don't try if there's cleanups, as we know there's code to follow the call. */ + + // -O2オプションがないときも末尾最適化が行われるように(Code Segmentのみ) + if (currently_expanding_call++ != 0 +#ifndef noCbC + || ((!fntype|| !CbC_IS_CODE_SEGMENT (fntype)) && (!flag_optimize_sibling_calls && !CALL_FROM_THUNK_P (exp))) +#else || (!flag_optimize_sibling_calls && !CALL_FROM_THUNK_P (exp)) +#endif || args_size.var || dbg_cnt (tail_call) == false) try_tail_call = 0; @@ -3632,7 +3646,11 @@ /* Check if caller and callee disagree in promotion of function return value. */ - if (try_tail_call) +#ifndef noCbC + if (try_tail_call && (!fntype|| !CbC_IS_CODE_SEGMENT (fntype))) +#else + if (try_tail_call) +#endif { machine_mode caller_mode, caller_promoted_mode; machine_mode callee_mode, callee_promoted_mode; @@ -3676,6 +3694,56 @@ preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; +#ifndef noCbC + if ( fntype + && CbC_IS_CbC_GOTO (exp) // it's better? than CALL_EXPR_TAILCALL() + //&& CALL_EXPR_TAILCALL(exp) + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl)) + ) + { + + args_size.constant = CbC_PRETENDED_STACK_SIZE; + // try_tail_callを矯正的に立たせて末尾最適化を必ずうように変更 + // -> expand_cbc_gotは不要に。 + /* return expand_cbc_goto(exp, target, fndecl, funtype, fntype, + * addr, ignore, flags, num_actuals, args, &args_size, + * args_so_far, + * old_stack_level, reg_parm_stack_space, old_pending_adj, + * preferred_stack_boundary, preferred_unit_stack_boundary, + * structure_value_addr, old_inhibit_defer_pop); */ + } + else if ( CbC_IS_CbC_GOTO (exp) ) + { + // TODO: 関数からコードセグメントへの遷移 + /* + if (fndecl) + { + char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning(0, "no warning: code segment `%s' has been called from a function.", name_callee); + } + else + { + warning(0, "no warning: unnamed code segment has been called from a function."); + } + */ + args_size.constant = CbC_PRETENDED_STACK_SIZE; + } + else if ( fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) ) + { + // 警告コードセグメントを関数呼び出し + //char *name= IDENTIFIER_POINTER(DECL_NAME(fndecl)); + //warning (0, "code segment `%s' has been \"called\" instead \"goto\".", name); + } + else if (CbC_IS_CODE_SEGMENT(TREE_TYPE (current_function_decl)) ) + { + // code segment内部からの関数呼び出し。なんも問題ない。 + //warning (0, "no warning: normal call from a code segment."); + } +#endif + + // when tail call optimization flag was down, warn about them. + // and flag it to force a tail call optimize. + /* We want to make two insn chains; one for a sibling call, the other for a normal call. We will select one of the two chains after initial RTL generation is complete. */ @@ -3742,16 +3810,31 @@ adjusted_args_size = args_size; /* Compute the actual size of the argument block required. The variable - and constant sizes must be combined, the size may have to be rounded, - and there may be a minimum required size. When generating a sibcall - pattern, do not round up, since we'll be re-using whatever space our - caller provided. */ + and constant sizes must be combined, the size may have to be rounded, + and there may be a minimum required size. When generating a sibcall + pattern, do not round up, since we'll be re-using whatever space our + caller provided. */ +#ifndef noCbC + if ( fntype && CbC_IS_CODE_SEGMENT(fntype) ) + { + unadjusted_args_size = args_size.constant; + adjusted_args_size.constant = CbC_PRETENDED_STACK_SIZE; + compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } + else +#endif + { unadjusted_args_size - = compute_argument_block_size (reg_parm_stack_space, - &adjusted_args_size, - fndecl, fntype, - (pass == 0 ? 0 - : preferred_stack_boundary)); + = compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } old_stack_allocated = stack_pointer_delta - pending_stack_adjust; @@ -4527,9 +4610,13 @@ /* If something prevents making this a sibling call, zero out the sequence. */ - if (sibcall_failure) +#ifndef noCbC + if ((!fntype || !CbC_IS_CODE_SEGMENT (fntype)) && sibcall_failure) +#else + if (sibcall_failure) +#endif tail_call_insns = NULL; - else + else break; } @@ -4542,6 +4629,17 @@ } else { + +#ifndef noCbC + if (fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl))) + { + location_t loc = EXPR_LOCATION (exp); + const char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning_at (loc, 0, "transition to code segment \"%s\" with CbC goto, but tail call optimization was cut.", + name_callee); + } +#endif emit_insn (normal_call_insns); if (try_tail_call) /* Ideally we'd emit a message for all of the ways that it could diff -r 84e7813d76e9 -r d34655255c78 gcc/cbc-tree-debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/cbc-tree-debug.c Thu Oct 25 10:21:07 2018 +0900 @@ -0,0 +1,49 @@ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "c-tree.h" + + +tree +_TREE_TYPE (tree t) +{ + return TREE_TYPE (t); +} + +enum tree_code +_TREE_CODE (tree t) +{ + return TREE_CODE (t); +} + +tree +_TREE_CHAIN (tree t) +{ + return TREE_CHAIN (t); +} + +tree +_DECL_NAME (tree t) +{ + return DECL_NAME (t); +} + +tree +_CALL_EXPR_FN (tree t) +{ + return CALL_EXPR_FN (t); +} + +tree +_CALL_EXPR_ARGS (tree t) +{ + return CALL_EXPR_ARGS (t); +} + +tree +_CALL_EXPR_ARG (tree t, int i) +{ + return CALL_EXPR_ARG (t, i); +} diff -r 84e7813d76e9 -r d34655255c78 gcc/cfgexpand.c --- a/gcc/cfgexpand.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/cfgexpand.c Thu Oct 25 10:21:07 2018 +0900 @@ -67,6 +67,9 @@ #include "tree-ssa-live.h" #include "tree-outof-ssa.h" #include "cfgloop.h" +#ifndef noCbC +#include "c/cbc-tree.h" +#endif #include "insn-attr.h" /* For INSN_SCHEDULING. */ #include "stringpool.h" #include "attribs.h" diff -r 84e7813d76e9 -r d34655255c78 gcc/config.in diff -r 84e7813d76e9 -r d34655255c78 gcc/config/i386/i386.c --- a/gcc/config/i386/i386.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/config/i386/i386.c Thu Oct 25 10:21:07 2018 +0900 @@ -27993,6 +27993,18 @@ fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr)); } +#ifndef noCbC + if (pop + && sibcall + && !( GET_CODE (fnaddr) == MEM + && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) ) + { + rtx eax = gen_rtx_REG (Pmode, AX_REG); + eax = copy_to_suggested_reg (XEXP (fnaddr, 0), eax, Pmode); + fnaddr = gen_rtx_MEM (QImode, eax); + } +#endif + call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1); if (retval) diff -r 84e7813d76e9 -r d34655255c78 gcc/config/i386/i386.md --- a/gcc/config/i386/i386.md Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/config/i386/i386.md Thu Oct 25 10:21:07 2018 +0900 @@ -12752,6 +12752,21 @@ (match_dup 4))) (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) +(define_expand "sibcall_value_pop" + [(parallel [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "" "") + (match_operand:SI 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 4 "" "")))])] + "!TARGET_64BIT" +{ + ix86_expand_call (operands[0], operands[1], operands[2], + operands[3], operands[4], 1); + DONE; +}) + + ;; Call subroutine returning any type. (define_expand "untyped_call" diff -r 84e7813d76e9 -r d34655255c78 gcc/config/rs6000/rs6000.md --- a/gcc/config/rs6000/rs6000.md Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/config/rs6000/rs6000.md Thu Oct 25 10:21:07 2018 +0900 @@ -11141,6 +11141,144 @@ b%T1" [(set_attr "type" "branch")]) +<<<<<<< local +======= +(define_insn "*sibcall_value_nonlocal_aix32" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (use (reg:SI LR_REGNO)) + (return)] + "TARGET_32BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "b %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_value_nonlocal_aix64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (use (reg:SI LR_REGNO)) + (return)] + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "b %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "")) + (use (match_operand 2 "immediate_operand" "O,n")) + (use (reg:SI LR_REGNO)) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4) + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + if (DEFAULT_ABI == ABI_V4 && flag_pic) + { + gcc_assert (!TARGET_SECURE_PLT); + return \"b %z0@plt\"; + } + else + return \"b %z0\"; +}" + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + + +;; added by kent. +;; for indirect sibcalls of Continuation based C. +;; this is based on call_indirect_nonlocal_sysv" +(define_insn "*sibcall_indirect_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) + (match_operand 1 "" "g,g,g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) + (use (reg:SI LR_REGNO)) + (return)] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + /* + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + */ + + return "b%T0"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + + + + +(define_expand "sibcall_value" + [(parallel [(set (match_operand 0 "register_operand" "") + (call (mem:SI (match_operand 1 "address_operand" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (use (reg:SI LR_REGNO)) + (return)])] + "" + " +{ +#if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[1] = machopic_indirect_call_target (operands[1]); +#endif + + gcc_assert (GET_CODE (operands[1]) == MEM); + gcc_assert (GET_CODE (operands[2]) == CONST_INT); + + operands[1] = XEXP (operands[1], 0); +}") + +(define_insn "*sibcall_value_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" ""))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (reg:SI LR_REGNO)) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4) + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + if (DEFAULT_ABI == ABI_V4 && flag_pic) + { + gcc_assert (!TARGET_SECURE_PLT); + return \"b %z1@plt\"; + } + else + return \"b %z1\"; +}" + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +>>>>>>> other (define_expand "sibcall_epilogue" [(use (const_int 0))] "" diff -r 84e7813d76e9 -r d34655255c78 gcc/configure diff -r 84e7813d76e9 -r d34655255c78 gcc/configure.ac --- a/gcc/configure.ac Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/configure.ac Thu Oct 25 10:21:07 2018 +0900 @@ -577,6 +577,7 @@ rtlflag) ac_rtlflag_checking=1 ;; runtime) ac_runtime_checking=1 ;; tree) ac_tree_checking=1 ;; + macrofunc) ac_macrofunc_checking=1 ;; types) ac_types_checking=1 ;; valgrind) ac_valgrind_checking=1 ;; *) AC_MSG_ERROR(unknown check category $check) ;; @@ -628,13 +629,24 @@ ]) TREECHECKING=yes fi +if test x$ac_macrofunc_checking != x ; then + AC_DEFINE(ENABLE_TREE_CHECKING, 1, +[Define if you want all operations on trees (the basic data + ]) + MACROFUNC=cbc-tree-debug.o +fi if test x$ac_types_checking != x ; then AC_DEFINE(ENABLE_TYPES_CHECKING, 1, [Define if you want all gimple types to be verified after gimplifiation. This is cheap. ]) fi +<<<<<<< local AC_SUBST(TREECHECKING) +======= +AC_SUBST(TREEBROWSER) +AC_SUBST(MACROFUNC) +>>>>>>> other if test x$ac_rtl_checking != x ; then AC_DEFINE(ENABLE_RTL_CHECKING, 1, [Define if you want all operations on RTL (the basic data structure diff -r 84e7813d76e9 -r d34655255c78 gcc/function.c --- a/gcc/function.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/function.c Thu Oct 25 10:21:07 2018 +0900 @@ -80,6 +80,8 @@ #include "gimple.h" #include "options.h" + + /* So we can assign to cfun in this file. */ #undef cfun @@ -3539,6 +3541,10 @@ } } +#ifndef noCbC +#include "c/cbc-tree.h" +#endif + /* Assign RTL expressions to the function's parameters. This may involve copying them into registers and using those registers as the DECL_RTL. */ @@ -3688,6 +3694,11 @@ set_parm_rtl (result, x); } +#ifndef noCbC + if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) + all.stack_args_size.constant = CbC_PRETENDED_STACK_SIZE; +#endif + /* We have aligned all the args, so add space for the pretend args. */ crtl->args.pretend_args_size = all.pretend_args_size; all.stack_args_size.constant += all.extra_pretend_bytes; diff -r 84e7813d76e9 -r d34655255c78 gcc/gcc.c --- a/gcc/gcc.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/gcc.c Thu Oct 25 10:21:07 2018 +0900 @@ -1307,6 +1307,9 @@ {".go", "#Go", 0, 1, 0}, /* Next come the entries for C. */ {".c", "@c", 0, 0, 1}, +#ifndef noCbC + {".cbc", "@c", 0, 1, 1}, +#endif {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ diff -r 84e7813d76e9 -r d34655255c78 gcc/gimple.c --- a/gcc/gimple.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/gimple.c Thu Oct 25 10:21:07 2018 +0900 @@ -44,7 +44,9 @@ #include "stringpool.h" #include "attribs.h" #include "asan.h" - +#ifndef noCbC +#include "c/cbc-tree.h" +#endif /* All the tuples have their operand vector (if present) at the very bottom of the structure. Therefore, the offset required to find the @@ -384,6 +386,9 @@ gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); gimple_call_set_nothrow (call, TREE_NOTHROW (t)); gimple_call_set_by_descriptor (call, CALL_EXPR_BY_DESCRIPTOR (t)); +#ifndef noCbC + gimple_call_set_cbc_goto (call, CALL_EXPR_CbC_GOTO (t)); +#endif gimple_set_no_warning (call, TREE_NO_WARNING (t)); if (fnptrtype) @@ -2291,6 +2296,10 @@ gimple_call_copy_flags (new_stmt, stmt); gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); +#ifndef noCbC + gimple_call_set_cbc_goto (new_stmt, gimple_call_cbc_goto_p (stmt)); +#endif + gimple_set_modified (new_stmt, true); return new_stmt; diff -r 84e7813d76e9 -r d34655255c78 gcc/gimple.h --- a/gcc/gimple.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/gimple.h Thu Oct 25 10:21:07 2018 +0900 @@ -148,6 +148,9 @@ GF_CALL_MUST_TAIL_CALL = 1 << 9, GF_CALL_BY_DESCRIPTOR = 1 << 10, GF_CALL_NOCF_CHECK = 1 << 11, +#ifndef noCbC + GF_CALL_CBC_GOTO = 1 << 5, +#endif GF_OMP_PARALLEL_COMBINED = 1 << 0, GF_OMP_PARALLEL_GRID_PHONY = 1 << 1, GF_OMP_TASK_TASKLOOP = 1 << 0, @@ -3213,6 +3216,21 @@ s->subcode &= ~GF_CALL_TAILCALL; } +#ifndef noCbC +/* If CBCGOTO_P is true, mark call statement S as being a cbc goto + (i.e., a call just before the exit of a function). These calls are + candidate for tail call optimization. */ + +static inline void +gimple_call_set_cbc_goto (gimple *s, bool cbcgoto_p) +{ + GIMPLE_CHECK (s, GIMPLE_CALL); + if (cbcgoto_p) + s->subcode |= GF_CALL_CBC_GOTO; + else + s->subcode &= ~GF_CALL_CBC_GOTO; +} +#endif /* Return true if GIMPLE_CALL S is marked as a tail call. */ @@ -3233,6 +3251,17 @@ s->subcode &= ~GF_CALL_MUST_TAIL_CALL; } +#ifndef noCbC +/* Return true if GIMPLE_CALL S is marked as a cbc goto. */ + +static inline bool +gimple_call_cbc_goto_p (gimple *s) +{ + GIMPLE_CHECK (s, GIMPLE_CALL); + return (s->subcode & GF_CALL_CBC_GOTO) != 0; +} +#endif + /* Return true if call statement has been marked as requiring tail call optimization. */ diff -r 84e7813d76e9 -r d34655255c78 gcc/gimplify.c --- a/gcc/gimplify.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/gimplify.c Thu Oct 25 10:21:07 2018 +0900 @@ -68,6 +68,10 @@ /* Hash set of poisoned variables in a bind expr. */ static hash_set *asan_poisoned_variables = NULL; +#include "tree-pass.h" +#ifndef noCbC +#include "c/cbc-tree.h" +#endif enum gimplify_omp_var_data { @@ -1504,7 +1508,16 @@ return GS_ALL_DONE; } - if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) + if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) +#ifndef noCbC + || ( ret_expr + && TREE_CODE(ret_expr)==CALL_EXPR + && CbC_IS_CbC_GOTO(ret_expr) + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl))) + && !(current_function_decl&&CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)))) + //&& !(current_function_decl&&CbC_IS_CODE_SEGMENT(current_function_decl))) +#endif + ) result_decl = NULL_TREE; else { diff -r 84e7813d76e9 -r d34655255c78 gcc/ipa-inline.c --- a/gcc/ipa-inline.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/ipa-inline.c Thu Oct 25 10:21:07 2018 +0900 @@ -120,6 +120,7 @@ #include "stringpool.h" #include "attribs.h" #include "asan.h" +#include "c/cbc-tree.h" typedef fibonacci_heap edge_heap_t; typedef fibonacci_node edge_heap_node_t; @@ -2202,9 +2203,20 @@ { int *num_calls = (int *)data; bool callee_removed = false; - +#ifndef noCbC + bool tail_call_f = false; + if (node->callees) { + if (node->callees->call_stmt) { + if (node->callees->call_stmt->vdef) + tail_call_f = gimple_call_tail_p (as_a (node->callees->call_stmt->vdef->ssa_name.def_stmt)); + } + } + while (node->callers && !node->global.inlined_to && !tail_call_f) + { +#else while (node->callers && !node->global.inlined_to) { +#endif struct cgraph_node *caller = node->callers->caller; if (!can_inline_edge_p (node->callers, true) @@ -2229,7 +2241,6 @@ node->callers->caller->name (), ipa_fn_summaries->get (node->callers->caller)->size); } - /* Remember which callers we inlined to, delaying updating the overall summary. */ callers->add (node->callers->caller); diff -r 84e7813d76e9 -r d34655255c78 gcc/passes.c diff -r 84e7813d76e9 -r d34655255c78 gcc/tree-ssa-operands.c --- a/gcc/tree-ssa-operands.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/tree-ssa-operands.c Thu Oct 25 10:21:07 2018 +0900 @@ -30,7 +30,9 @@ #include "stmt.h" #include "print-tree.h" #include "dumpfile.h" - +#ifndef noCbC + #include "c/cbc-tree.h" +#endif /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt diff -r 84e7813d76e9 -r d34655255c78 gcc/tree.c --- a/gcc/tree.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/tree.c Thu Oct 25 10:21:07 2018 +0900 @@ -106,6 +106,10 @@ #undef DEFTREECODE #undef END_OF_BASE_TREE_CODES +#ifndef noCbC +#include "c/cbc-tree.h" +#endif + /* Each tree code class has an associated string representation. These must correspond to the tree_code_class entries. */ @@ -7969,6 +7973,28 @@ return type; } +#ifndef noCbC +tree +build_code_segment_type (tree value_type, tree arg_types) +{ + tree t; + hashval_t hashcode = 0; + + gcc_assert (TREE_CODE (value_type) == VOID_TYPE); + + /* Make a node of the sort we want. */ + t = make_node (FUNCTION_TYPE); + TREE_TYPE (t) = value_type; + TYPE_ARG_TYPES (t) = arg_types; + + CbC_IS_CODE_SEGMENT (t) = 1; + + if (!COMPLETE_TYPE_P (t)) + layout_type (t); + return t; +} +#endif + /* Computes the canonical argument types from the argument type list ARGTYPES. diff -r 84e7813d76e9 -r d34655255c78 gcc/tree.h --- a/gcc/tree.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/tree.h Thu Oct 25 10:21:07 2018 +0900 @@ -4236,6 +4236,10 @@ extern bool vec_member (const_tree, vec *); extern tree chain_index (int, tree); +#ifndef noCbC +extern tree build_code_segment_type (tree, tree); +#endif + /* Arguments may be null. */ extern int tree_int_cst_equal (const_tree, const_tree); @@ -4956,6 +4960,9 @@ extern location_t tree_nonartificial_location (tree); extern tree block_ultimate_origin (const_tree); extern tree get_binfo_at_offset (tree, poly_int64, tree); +#ifndef noCbC +extern tree build_addr (tree); +#endif extern bool virtual_method_call_p (const_tree); extern tree obj_type_ref_class (const_tree ref); extern bool types_same_for_odr (const_tree type1, const_tree type2,